diff options
62 files changed, 899 insertions, 555 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 1170e5a25..2fe238334 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ ###Changelog +####Version 1.5.0 +* upload files to HTTP host and share them in MUCs. requires new [HttpUploadComponent](https://github.com/siacs/HttpUploadComponent) on server side + ####Version 1.4.5 * fixes to message parser to not display some ejabberd muc status messages diff --git a/build.gradle b/build.gradle index af4edd7f1..ca78ddeac 100644 --- a/build.gradle +++ b/build.gradle @@ -45,8 +45,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 21 - versionCode 75 - versionName "1.4.7 beta3" + versionCode 76 + versionName "1.5.0-beta" } compileOptions { diff --git a/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java b/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java index cba80ba0b..505c4b0f1 100644 --- a/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java +++ b/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java @@ -61,7 +61,7 @@ public class PgpEngine { if (message.trusted() && message.treatAsDownloadable() != Message.Decision.NEVER && manager.getAutoAcceptFileSize() > 0) { - manager.createNewConnection(message); + manager.createNewDownloadConnection(message); } callback.success(message); } diff --git a/src/main/java/eu/siacs/conversations/crypto/sasl/ScramSha1.java b/src/main/java/eu/siacs/conversations/crypto/sasl/ScramSha1.java index 10cd3167e..c95a62df3 100644 --- a/src/main/java/eu/siacs/conversations/crypto/sasl/ScramSha1.java +++ b/src/main/java/eu/siacs/conversations/crypto/sasl/ScramSha1.java @@ -185,7 +185,7 @@ public class ScramSha1 extends SaslMechanism { case RESPONSE_SENT: final String clientCalculatedServerFinalMessage = "v=" + Base64.encodeToString(serverSignature, Base64.NO_WRAP); - if (!clientCalculatedServerFinalMessage.equals(new String(Base64.decode(challenge, Base64.DEFAULT)))) { + if (challenge == null || !clientCalculatedServerFinalMessage.equals(new String(Base64.decode(challenge, Base64.DEFAULT)))) { throw new AuthenticationException("Server final message does not match calculated final message"); } state = State.VALID_SERVER_RESPONSE; diff --git a/src/main/java/eu/siacs/conversations/entities/Downloadable.java b/src/main/java/eu/siacs/conversations/entities/Downloadable.java index bb0ce09c0..56489774b 100644 --- a/src/main/java/eu/siacs/conversations/entities/Downloadable.java +++ b/src/main/java/eu/siacs/conversations/entities/Downloadable.java @@ -1,6 +1,6 @@ package eu.siacs.conversations.entities; -public interface Downloadable { +public interface Transferable { String[] VALID_IMAGE_EXTENSIONS = {"webp", "jpeg", "jpg", "png", "jpe"}; String[] VALID_CRYPTO_EXTENSIONS = {"pgp", "gpg", "otr"}; diff --git a/src/main/java/eu/siacs/conversations/entities/DownloadablePlaceholder.java b/src/main/java/eu/siacs/conversations/entities/DownloadablePlaceholder.java index cce22ea39..e065953ef 100644 --- a/src/main/java/eu/siacs/conversations/entities/DownloadablePlaceholder.java +++ b/src/main/java/eu/siacs/conversations/entities/DownloadablePlaceholder.java @@ -1,10 +1,10 @@ package eu.siacs.conversations.entities; -public class DownloadablePlaceholder implements Downloadable { +public class TransferablePlaceholder implements Transferable { private int status; - public DownloadablePlaceholder(int status) { + public TransferablePlaceholder(int status) { this.status = status; } @Override diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index 078a45659..28ef89df1 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -70,7 +70,7 @@ public class Message extends AbstractEntity { protected String remoteMsgId = null; protected String serverMsgId = null; protected Conversation conversation = null; - protected Downloadable downloadable = null; + protected Transferable transferable = null; private Message mNextMessage = null; private Message mPreviousMessage = null; @@ -308,12 +308,12 @@ public class Message extends AbstractEntity { this.trueCounterpart = trueCounterpart; } - public Downloadable getDownloadable() { - return this.downloadable; + public Transferable getTransferable() { + return this.transferable; } - public void setDownloadable(Downloadable downloadable) { - this.downloadable = downloadable; + public void setTransferable(Transferable transferable) { + this.transferable = transferable; } public boolean equals(Message message) { @@ -364,8 +364,8 @@ public class Message extends AbstractEntity { public boolean mergeable(final Message message) { return message != null && (message.getType() == Message.TYPE_TEXT && - this.getDownloadable() == null && - message.getDownloadable() == null && + this.getTransferable() == null && + message.getTransferable() == null && message.getEncryption() != Message.ENCRYPTION_PGP && this.getType() == message.getType() && //this.getStatus() == message.getStatus() && @@ -471,7 +471,7 @@ public class Message extends AbstractEntity { if (extensionParts.length == 2) { return extensionParts[extensionParts.length - 1]; } else if (extensionParts.length == 3 && Arrays - .asList(Downloadable.VALID_CRYPTO_EXTENSIONS) + .asList(Transferable.VALID_CRYPTO_EXTENSIONS) .contains(extensionParts[extensionParts.length - 1])) { return extensionParts[extensionParts.length -2]; } @@ -517,8 +517,8 @@ public class Message extends AbstractEntity { } else { return Decision.NEVER; } - } else if (Arrays.asList(Downloadable.VALID_IMAGE_EXTENSIONS).contains(extension) - || Arrays.asList(Downloadable.WELL_KNOWN_EXTENSIONS).contains(extension)) { + } else if (Arrays.asList(Transferable.VALID_IMAGE_EXTENSIONS).contains(extension) + || Arrays.asList(Transferable.WELL_KNOWN_EXTENSIONS).contains(extension)) { return Decision.SHOULD; } else { return Decision.NEVER; @@ -539,8 +539,8 @@ public class Message extends AbstractEntity { return params; } params = new FileParams(); - if (this.downloadable != null) { - params.size = this.downloadable.getFileSize(); + if (this.transferable != null) { + params.size = this.transferable.getFileSize(); } if (body == null) { return params; diff --git a/src/main/java/eu/siacs/conversations/entities/Transferable.java b/src/main/java/eu/siacs/conversations/entities/Transferable.java new file mode 100644 index 000000000..56489774b --- /dev/null +++ b/src/main/java/eu/siacs/conversations/entities/Transferable.java @@ -0,0 +1,28 @@ +package eu.siacs.conversations.entities; + +public interface Transferable { + + String[] VALID_IMAGE_EXTENSIONS = {"webp", "jpeg", "jpg", "png", "jpe"}; + String[] VALID_CRYPTO_EXTENSIONS = {"pgp", "gpg", "otr"}; + String[] WELL_KNOWN_EXTENSIONS = {"pdf","m4a","mp3","avi","mp4","apk","vcf"}; + + int STATUS_UNKNOWN = 0x200; + int STATUS_CHECKING = 0x201; + int STATUS_FAILED = 0x202; + int STATUS_OFFER = 0x203; + int STATUS_DOWNLOADING = 0x204; + int STATUS_DELETED = 0x205; + int STATUS_OFFER_CHECK_FILESIZE = 0x206; + int STATUS_UPLOADING = 0x207; + + + boolean start(); + + int getStatus(); + + long getFileSize(); + + int getProgress(); + + void cancel(); +} diff --git a/src/main/java/eu/siacs/conversations/entities/TransferablePlaceholder.java b/src/main/java/eu/siacs/conversations/entities/TransferablePlaceholder.java new file mode 100644 index 000000000..e065953ef --- /dev/null +++ b/src/main/java/eu/siacs/conversations/entities/TransferablePlaceholder.java @@ -0,0 +1,34 @@ +package eu.siacs.conversations.entities; + +public class TransferablePlaceholder implements Transferable { + + private int status; + + public TransferablePlaceholder(int status) { + this.status = status; + } + @Override + public boolean start() { + return false; + } + + @Override + public int getStatus() { + return status; + } + + @Override + public long getFileSize() { + return 0; + } + + @Override + public int getProgress() { + return 0; + } + + @Override + public void cancel() { + + } +} diff --git a/src/main/java/eu/siacs/conversations/http/HttpConnection.java b/src/main/java/eu/siacs/conversations/http/HttpConnection.java index 002611dca..dd8427541 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpConnection.java +++ b/src/main/java/eu/siacs/conversations/http/HttpConnection.java @@ -1,305 +1,204 @@ package eu.siacs.conversations.http; -import android.content.Intent; -import android.net.Uri; -import android.os.SystemClock; +import android.app.PendingIntent; +import android.util.Log; -import org.apache.http.conn.ssl.StrictHostnameVerifier; - -import java.io.BufferedInputStream; import java.io.IOException; +import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; -import java.util.Arrays; -import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLHandshakeException; -import javax.net.ssl.SSLSocketFactory; -import javax.net.ssl.X509TrustManager; import eu.siacs.conversations.Config; -import eu.siacs.conversations.entities.Downloadable; +import eu.siacs.conversations.entities.Account; +import eu.siacs.conversations.entities.Transferable; import eu.siacs.conversations.entities.DownloadableFile; import eu.siacs.conversations.entities.Message; +import eu.siacs.conversations.persistance.FileBackend; import eu.siacs.conversations.services.XmppConnectionService; +import eu.siacs.conversations.ui.UiCallback; import eu.siacs.conversations.utils.CryptoHelper; +import eu.siacs.conversations.utils.Xmlns; +import eu.siacs.conversations.xml.Element; +import eu.siacs.conversations.xmpp.OnIqPacketReceived; +import eu.siacs.conversations.xmpp.jid.Jid; +import eu.siacs.conversations.xmpp.stanzas.IqPacket; -public class HttpConnection implements Downloadable { +public class HttpUploadConnection implements Transferable { private HttpConnectionManager mHttpConnectionManager; private XmppConnectionService mXmppConnectionService; - private URL mUrl; - private Message message; + private boolean canceled = false; + private Account account; private DownloadableFile file; - private int mStatus = Downloadable.STATUS_UNKNOWN; - private boolean acceptedAutomatically = false; - private int mProgress = 0; - private long mLastGuiRefresh = 0; + private Message message; + private URL mGetUrl; + private URL mPutUrl; + + private byte[] key = null; + + private long transmitted = 0; + private long expected = 1; - public HttpConnection(HttpConnectionManager manager) { - this.mHttpConnectionManager = manager; - this.mXmppConnectionService = manager.getXmppConnectionService(); + public HttpUploadConnection(HttpConnectionManager httpConnectionManager) { + this.mHttpConnectionManager = httpConnectionManager; + this.mXmppConnectionService = httpConnectionManager.getXmppConnectionService(); } @Override public boolean start() { - if (mXmppConnectionService.hasInternetConnection()) { - if (this.mStatus == STATUS_OFFER_CHECK_FILESIZE) { - checkFileSize(true); - } else { - new Thread(new FileDownloader(true)).start(); - } - return true; - } else { - return false; - } + return false; } - public void init(Message message) { - this.message = message; - this.message.setDownloadable(this); - try { - mUrl = new URL(message.getBody()); - String[] parts = mUrl.getPath().toLowerCase().split("\\."); - String lastPart = parts.length >= 1 ? parts[parts.length - 1] : null; - String secondToLast = parts.length >= 2 ? parts[parts.length -2] : null; - if ("pgp".equals(lastPart) || "gpg".equals(lastPart)) { - this.message.setEncryption(Message.ENCRYPTION_PGP); - } else if (message.getEncryption() != Message.ENCRYPTION_OTR) { - this.message.setEncryption(Message.ENCRYPTION_NONE); - } - String extension; - if (Arrays.asList(VALID_CRYPTO_EXTENSIONS).contains(lastPart)) { - extension = secondToLast; - } else { - extension = lastPart; - } - message.setRelativeFilePath(message.getUuid()+"."+extension); - this.file = mXmppConnectionService.getFileBackend().getFile(message, false); - String reference = mUrl.getRef(); - if (reference != null && reference.length() == 96) { - this.file.setKey(CryptoHelper.hexToBytes(reference)); - } - - if (this.message.getEncryption() == Message.ENCRYPTION_OTR - && this.file.getKey() == null) { - this.message.setEncryption(Message.ENCRYPTION_NONE); - } - checkFileSize(false); - } catch (MalformedURLException e) { - this.cancel(); - } + @Override + public int getStatus() { + return STATUS_UPLOADING; } - private void checkFileSize(boolean interactive) { - new Thread(new FileSizeChecker(interactive)).start(); + @Override + public long getFileSize() { + return this.file.getExpectedSize(); } - public void cancel() { - mHttpConnectionManager.finishConnection(this); - message.setDownloadable(null); - mXmppConnectionService.updateConversationUi(); + @Override + public int getProgress() { + return (int) ((((double) transmitted) / expected) * 100); } - private void finish() { - Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); - intent.setData(Uri.fromFile(file)); - mXmppConnectionService.sendBroadcast(intent); - message.setDownloadable(null); - mHttpConnectionManager.finishConnection(this); - mXmppConnectionService.updateConversationUi(); - if (acceptedAutomatically) { - mXmppConnectionService.getNotificationService().push(message); - } + @Override + public void cancel() { + this.canceled = true; } - private void changeStatus(int status) { - this.mStatus = status; - mXmppConnectionService.updateConversationUi(); + private void fail() { + mHttpConnectionManager.finishUploadConnection(this); + message.setTransferable(null); + mXmppConnectionService.markMessage(message,Message.STATUS_SEND_FAILED); } - private void setupTrustManager(final HttpsURLConnection connection, - final boolean interactive) { - final X509TrustManager trustManager; - final HostnameVerifier hostnameVerifier; - if (interactive) { - trustManager = mXmppConnectionService.getMemorizingTrustManager(); - hostnameVerifier = mXmppConnectionService - .getMemorizingTrustManager().wrapHostnameVerifier( - new StrictHostnameVerifier()); - } else { - trustManager = mXmppConnectionService.getMemorizingTrustManager() - .getNonInteractive(); - hostnameVerifier = mXmppConnectionService - .getMemorizingTrustManager() - .wrapHostnameVerifierNonInteractive( - new StrictHostnameVerifier()); + public void init(Message message) { + this.message = message; + message.setTransferable(this); + mXmppConnectionService.markMessage(message,Message.STATUS_UNSEND); + this.account = message.getConversation().getAccount(); + this.file = mXmppConnectionService.getFileBackend().getFile(message, false); + this.file.setExpectedSize(this.file.getSize()); + + if (Config.ENCRYPT_ON_HTTP_UPLOADED) { + this.key = new byte[48]; + mXmppConnectionService.getRNG().nextBytes(this.key); + this.file.setKey(this.key); } - try { - final SSLContext sc = SSLContext.getInstance("TLS"); - sc.init(null, new X509TrustManager[]{trustManager}, - mXmppConnectionService.getRNG()); - - final SSLSocketFactory sf = sc.getSocketFactory(); - final String[] cipherSuites = CryptoHelper.getOrderedCipherSuites( - sf.getSupportedCipherSuites()); - if (cipherSuites.length > 0) { - sc.getDefaultSSLParameters().setCipherSuites(cipherSuites); + Jid host = account.getXmppConnection().findDiscoItemByFeature(Xmlns.HTTP_UPLOAD); + IqPacket request = mXmppConnectionService.getIqGenerator().requestHttpUploadSlot(host,file); + mXmppConnectionService.sendIqPacket(account, request, new OnIqPacketReceived() { + @Override + public void onIqPacketReceived(Account account, IqPacket packet) { + if (packet.getType() == IqPacket.TYPE.RESULT) { + Element slot = packet.findChild("slot",Xmlns.HTTP_UPLOAD); + if (slot != null) { + try { + mGetUrl = new URL(slot.findChildContent("get")); + mPutUrl = new URL(slot.findChildContent("put")); + if (!canceled) { + new Thread(new FileUploader()).start(); + } + } catch (MalformedURLException e) { + fail(); + } + } else { + fail(); + } + } else { + fail(); + } } - - connection.setSSLSocketFactory(sf); - connection.setHostnameVerifier(hostnameVerifier); - } catch (final KeyManagementException | NoSuchAlgorithmException ignored) { - } + }); } - private class FileSizeChecker implements Runnable { - - private boolean interactive = false; - - public FileSizeChecker(boolean interactive) { - this.interactive = interactive; - } + private class FileUploader implements Runnable { @Override public void run() { - long size; - try { - size = retrieveFileSize(); - } catch (SSLHandshakeException e) { - changeStatus(STATUS_OFFER_CHECK_FILESIZE); - HttpConnection.this.acceptedAutomatically = false; - HttpConnection.this.mXmppConnectionService.getNotificationService().push(message); - return; - } catch (IOException e) { - cancel(); - return; - } - file.setExpectedSize(size); - if (size <= mHttpConnectionManager.getAutoAcceptFileSize()) { - HttpConnection.this.acceptedAutomatically = true; - new Thread(new FileDownloader(interactive)).start(); - } else { - changeStatus(STATUS_OFFER); - HttpConnection.this.acceptedAutomatically = false; - HttpConnection.this.mXmppConnectionService.getNotificationService().push(message); - } + this.upload(); } - private long retrieveFileSize() throws IOException, - SSLHandshakeException { - changeStatus(STATUS_CHECKING); - HttpURLConnection connection = (HttpURLConnection) mUrl - .openConnection(); - connection.setRequestMethod("HEAD"); - if (connection instanceof HttpsURLConnection) { - setupTrustManager((HttpsURLConnection) connection, interactive); - } - connection.connect(); - String contentLength = connection.getHeaderField("Content-Length"); - if (contentLength == null) { - throw new IOException(); - } - try { - return Long.parseLong(contentLength, 10); - } catch (NumberFormatException e) { - throw new IOException(); + private void upload() { + OutputStream os = null; + InputStream is = null; + HttpURLConnection connection = null; + try { + Log.d(Config.LOGTAG, "uploading to " + mPutUrl.toString()); + connection = (HttpURLConnection) mPutUrl.openConnection(); + if (connection instanceof HttpsURLConnection) { + mHttpConnectionManager.setupTrustManager((HttpsURLConnection) connection, true); + } + connection.setRequestMethod("PUT"); + connection.setFixedLengthStreamingMode((int) file.getExpectedSize()); + connection.setDoOutput(true); + connection.connect(); + os = connection.getOutputStream(); + is = file.createInputStream(); + transmitted = 0; + expected = file.getExpectedSize(); + int count = -1; + byte[] buffer = new byte[4096]; + while (((count = is.read(buffer)) != -1) && !canceled) { + transmitted += count; + os.write(buffer, 0, count); + mXmppConnectionService.updateConversationUi(); + } + os.flush(); + os.close(); + is.close(); + int code = connection.getResponseCode(); + if (code == 200) { + Log.d(Config.LOGTAG, "finished uploading file"); + Message.FileParams params = message.getFileParams(); + if (key != null) { + mGetUrl = new URL(mGetUrl.toString() + "#" + CryptoHelper.bytesToHex(key)); + } + mXmppConnectionService.getFileBackend().updateFileParams(message, mGetUrl); + message.setTransferable(null); + message.setCounterpart(message.getConversation().getJid().toBareJid()); + if (message.getEncryption() == Message.ENCRYPTION_DECRYPTED) { + mXmppConnectionService.getPgpEngine().encrypt(message, new UiCallback<Message>() { + @Override + public void success(Message message) { + mXmppConnectionService.resendMessage(message); } - } - - } - - private class FileDownloader implements Runnable { - - private boolean interactive = false; - public FileDownloader(boolean interactive) { - this.interactive = interactive; - } + @Override + public void error(int errorCode, Message object) { + fail(); + } - @Override - public void run() { - try { - changeStatus(STATUS_DOWNLOADING); - download(); - updateImageBounds(); - finish(); - } catch (SSLHandshakeException e) { - changeStatus(STATUS_OFFER); + @Override + public void userInputRequried(PendingIntent pi, Message object) { + fail(); + } + }); + } else { + mXmppConnectionService.resendMessage(message); + } + } else { + fail(); + } } catch (IOException e) { - cancel(); - } - } - - private void download() throws SSLHandshakeException, IOException { - HttpURLConnection connection = (HttpURLConnection) mUrl - .openConnection(); - if (connection instanceof HttpsURLConnection) { - setupTrustManager((HttpsURLConnection) connection, interactive); - } - connection.connect(); - BufferedInputStream is = new BufferedInputStream( - connection.getInputStream()); - file.getParentFile().mkdirs(); - file.createNewFile(); - OutputStream os = file.createOutputStream(); - if (os == null) { - throw new IOException(); - } - long transmitted = 0; - long expected = file.getExpectedSize(); - int count = -1; - byte[] buffer = new byte[1024]; - while ((count = is.read(buffer)) != -1) { - transmitted += count; - os.write(buffer, 0, count); - updateProgress((int) ((((double) transmitted) / expected) * 100)); + Log.d(Config.LOGTAG, e.getMessage()); + fail(); + } finally { + FileBackend.close(is); + FileBackend.close(os); + if (connection != null) { + connection.disconnect(); + } } - os.flush(); - os.close(); - is.close(); } - - private void updateImageBounds() { - message.setType(Message.TYPE_FILE); - mXmppConnectionService.getFileBackend().updateFileParams(message, mUrl); - mXmppConnectionService.updateMessage(message); - } - - } - - public void updateProgress(int i) { - this.mProgress = i; - if (SystemClock.elapsedRealtime() - this.mLastGuiRefresh > Config.PROGRESS_UI_UPDATE_INTERVAL) { - this.mLastGuiRefresh = SystemClock.elapsedRealtime(); - mXmppConnectionService.updateConversationUi(); - } - } - - @Override - public int getStatus() { - return this.mStatus; - } - - @Override - public long getFileSize() { - if (this.file != null) { - return this.file.getExpectedSize(); - } else { - return 0; - } - } - - @Override - public int getProgress() { - return this.mProgress; } } diff --git a/src/main/java/eu/siacs/conversations/http/HttpConnectionManager.java b/src/main/java/eu/siacs/conversations/http/HttpConnectionManager.java index fc266e7b2..58a6d1e37 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpConnectionManager.java +++ b/src/main/java/eu/siacs/conversations/http/HttpConnectionManager.java @@ -1,11 +1,22 @@ package eu.siacs.conversations.http; +import org.apache.http.conn.ssl.StrictHostnameVerifier; + +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.X509TrustManager; + import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.services.AbstractConnectionManager; import eu.siacs.conversations.services.XmppConnectionService; +import eu.siacs.conversations.utils.CryptoHelper; public class HttpConnectionManager extends AbstractConnectionManager { @@ -13,13 +24,17 @@ public class HttpConnectionManager extends AbstractConnectionManager { super(service); } - private List<HttpConnection> connections = new CopyOnWriteArrayList<>(); + private List<HttpDownloadConnection> downloadConnections = new CopyOnWriteArrayList<>(); private List<HttpUploadConnection> uploadConnections = new CopyOnWriteArrayList<>(); - public HttpConnection createNewConnection(Message message) { - HttpConnection connection = new HttpConnection(this); - connection.init(message); - this.connections.add(connection); + public HttpDownloadConnection createNewDownloadConnection(Message message) { + return this.createNewDownloadConnection(message, false); + } + + public HttpDownloadConnection createNewDownloadConnection(Message message, boolean interactive) { + HttpDownloadConnection connection = new HttpDownloadConnection(this); + connection.init(message,interactive); + this.downloadConnections.add(connection); return connection; } @@ -30,11 +45,46 @@ public class HttpConnectionManager extends AbstractConnectionManager { return connection; } - public void finishConnection(HttpConnection connection) { - this.connections.remove(connection); + public void finishConnection(HttpDownloadConnection connection) { + this.downloadConnections.remove(connection); } public void finishUploadConnection(HttpUploadConnection httpUploadConnection) { this.uploadConnections.remove(httpUploadConnection); } + + public void setupTrustManager(final HttpsURLConnection connection, final boolean interactive) { + final X509TrustManager trustManager; + final HostnameVerifier hostnameVerifier; + if (interactive) { + trustManager = mXmppConnectionService.getMemorizingTrustManager(); + hostnameVerifier = mXmppConnectionService + .getMemorizingTrustManager().wrapHostnameVerifier( + new StrictHostnameVerifier()); + } else { + trustManager = mXmppConnectionService.getMemorizingTrustManager() + .getNonInteractive(); + hostnameVerifier = mXmppConnectionService + .getMemorizingTrustManager() + .wrapHostnameVerifierNonInteractive( + new StrictHostnameVerifier()); + } + try { + final SSLContext sc = SSLContext.getInstance("TLS"); + sc.init(null, new X509TrustManager[]{trustManager}, + mXmppConnectionService.getRNG()); + + final SSLSocketFactory sf = sc.getSocketFactory(); + final String[] cipherSuites = CryptoHelper.getOrderedCipherSuites( + sf.getSupportedCipherSuites()); + if (cipherSuites.length > 0) { + sc.getDefaultSSLParameters().setCipherSuites(cipherSuites); + + } + + connection.setSSLSocketFactory(sf); + connection.setHostnameVerifier(hostnameVerifier); + } catch (final KeyManagementException | NoSuchAlgorithmException ignored) { + } + } } diff --git a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java new file mode 100644 index 000000000..6fcd8c870 --- /dev/null +++ b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java @@ -0,0 +1,269 @@ +package eu.siacs.conversations.http; + +import android.content.Intent; +import android.net.Uri; +import android.os.SystemClock; +import android.util.Log; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Arrays; + +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLHandshakeException; + +import eu.siacs.conversations.Config; +import eu.siacs.conversations.R; +import eu.siacs.conversations.entities.Transferable; +import eu.siacs.conversations.entities.DownloadableFile; +import eu.siacs.conversations.entities.Message; +import eu.siacs.conversations.services.XmppConnectionService; +import eu.siacs.conversations.utils.CryptoHelper; + +public class HttpDownloadConnection implements Transferable { + + private HttpConnectionManager mHttpConnectionManager; + private XmppConnectionService mXmppConnectionService; + + private URL mUrl; + private Message message; + private DownloadableFile file; + private int mStatus = Transferable.STATUS_UNKNOWN; + private boolean acceptedAutomatically = false; + private int mProgress = 0; + private long mLastGuiRefresh = 0; + + public HttpDownloadConnection(HttpConnectionManager manager) { + this.mHttpConnectionManager = manager; + this.mXmppConnectionService = manager.getXmppConnectionService(); + } + + @Override + public boolean start() { + if (mXmppConnectionService.hasInternetConnection()) { + if (this.mStatus == STATUS_OFFER_CHECK_FILESIZE) { + checkFileSize(true); + } else { + new Thread(new FileDownloader(true)).start(); + } + return true; + } else { + return false; + } + } + + public void init(Message message) { + init(message, false); + } + + public void init(Message message, boolean interactive) { + this.message = message; + this.message.setTransferable(this); + try { + mUrl = new URL(message.getBody()); + String[] parts = mUrl.getPath().toLowerCase().split("\\."); + String lastPart = parts.length >= 1 ? parts[parts.length - 1] : null; + String secondToLast = parts.length >= 2 ? parts[parts.length -2] : null; + if ("pgp".equals(lastPart) || "gpg".equals(lastPart)) { + this.message.setEncryption(Message.ENCRYPTION_PGP); + } else if (message.getEncryption() != Message.ENCRYPTION_OTR) { + this.message.setEncryption(Message.ENCRYPTION_NONE); + } + String extension; + if (Arrays.asList(VALID_CRYPTO_EXTENSIONS).contains(lastPart)) { + extension = secondToLast; + } else { + extension = lastPart; + } + message.setRelativeFilePath(message.getUuid()+"."+extension); + this.file = mXmppConnectionService.getFileBackend().getFile(message, false); + String reference = mUrl.getRef(); + if (reference != null && reference.length() == 96) { + this.file.setKey(CryptoHelper.hexToBytes(reference)); + } + + if (this.message.getEncryption() == Message.ENCRYPTION_OTR + && this.file.getKey() == null) { + this.message.setEncryption(Message.ENCRYPTION_NONE); + } + checkFileSize(true); + } catch (MalformedURLException e) { + this.cancel(); + } + } + + private void checkFileSize(boolean interactive) { + new Thread(new FileSizeChecker(interactive)).start(); + } + + public void cancel() { + mHttpConnectionManager.finishConnection(this); + message.setTransferable(null); + mXmppConnectionService.updateConversationUi(); + } + + private void finish() { + Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); + intent.setData(Uri.fromFile(file)); + mXmppConnectionService.sendBroadcast(intent); + message.setTransferable(null); + mHttpConnectionManager.finishConnection(this); + mXmppConnectionService.updateConversationUi(); + if (acceptedAutomatically) { + mXmppConnectionService.getNotificationService().push(message); + } + } + + private void changeStatus(int status) { + this.mStatus = status; + mXmppConnectionService.updateConversationUi(); + } + + private class FileSizeChecker implements Runnable { + + private boolean interactive = false; + + public FileSizeChecker(boolean interactive) { + this.interactive = interactive; + } + + @Override + public void run() { + long size; + try { + size = retrieveFileSize(); + } catch (SSLHandshakeException e) { + changeStatus(STATUS_OFFER_CHECK_FILESIZE); + HttpDownloadConnection.this.acceptedAutomatically = false; + HttpDownloadConnection.this.mXmppConnectionService.getNotificationService().push(message); + return; + } catch (IOException e) { + Log.d(Config.LOGTAG, "io exception in http file size checker: " + e.getMessage()); + if (interactive) { + mXmppConnectionService.showErrorToastInUi(R.string.file_not_found_on_remote_host); + } + cancel(); + return; + } + file.setExpectedSize(size); + if (size <= mHttpConnectionManager.getAutoAcceptFileSize()) { + HttpDownloadConnection.this.acceptedAutomatically = true; + new Thread(new FileDownloader(interactive)).start(); + } else { + changeStatus(STATUS_OFFER); + HttpDownloadConnection.this.acceptedAutomatically = false; + HttpDownloadConnection.this.mXmppConnectionService.getNotificationService().push(message); + } + } + + private long retrieveFileSize() throws IOException { + Log.d(Config.LOGTAG,"retrieve file size. interactive:"+String.valueOf(interactive)); + changeStatus(STATUS_CHECKING); + HttpURLConnection connection = (HttpURLConnection) mUrl.openConnection(); + connection.setRequestMethod("HEAD"); + if (connection instanceof HttpsURLConnection) { + mHttpConnectionManager.setupTrustManager((HttpsURLConnection) connection, interactive); + } + connection.connect(); + String contentLength = connection.getHeaderField("Content-Length"); + if (contentLength == null) { + throw new IOException(); + } + try { + return Long.parseLong(contentLength, 10); + } catch (NumberFormatException e) { + throw new IOException(); + } + } + + } + + private class FileDownloader implements Runnable { + + private boolean interactive = false; + + public FileDownloader(boolean interactive) { + this.interactive = interactive; + } + + @Override + public void run() { + try { + changeStatus(STATUS_DOWNLOADING); + download(); + updateImageBounds(); + finish(); + } catch (SSLHandshakeException e) { + changeStatus(STATUS_OFFER); + } catch (IOException e) { + mXmppConnectionService.showErrorToastInUi(R.string.file_not_found_on_remote_host); + cancel(); + } + } + + private void download() throws SSLHandshakeException, IOException { + HttpURLConnection connection = (HttpURLConnection) mUrl.openConnection(); + if (connection instanceof HttpsURLConnection) { + mHttpConnectionManager.setupTrustManager((HttpsURLConnection) connection, interactive); + } + connection.connect(); + BufferedInputStream is = new BufferedInputStream(connection.getInputStream()); + file.getParentFile().mkdirs(); + file.createNewFile(); + OutputStream os = file.createOutputStream(); + if (os == null) { + throw new IOException(); + } + long transmitted = 0; + long expected = file.getExpectedSize(); + int count = -1; + byte[] buffer = new byte[1024]; + while ((count = is.read(buffer)) != -1) { + transmitted += count; + os.write(buffer, 0, count); + updateProgress((int) ((((double) transmitted) / expected) * 100)); + } + os.flush(); + os.close(); + is.close(); + } + + private void updateImageBounds() { + message.setType(Message.TYPE_FILE); + mXmppConnectionService.getFileBackend().updateFileParams(message, mUrl); + mXmppConnectionService.updateMessage(message); + } + + } + + public void updateProgress(int i) { + this.mProgress = i; + if (SystemClock.elapsedRealtime() - this.mLastGuiRefresh > Config.PROGRESS_UI_UPDATE_INTERVAL) { + this.mLastGuiRefresh = SystemClock.elapsedRealtime(); + mXmppConnectionService.updateConversationUi(); + } + } + + @Override + public int getStatus() { + return this.mStatus; + } + + @Override + public long getFileSize() { + if (this.file != null) { + return this.file.getExpectedSize(); + } else { + return 0; + } + } + + @Override + public int getProgress() { + return this.mProgress; + } +} diff --git a/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java b/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java index d861f6164..dd8427541 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java +++ b/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java @@ -10,9 +10,11 @@ import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; +import javax.net.ssl.HttpsURLConnection; + import eu.siacs.conversations.Config; import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.entities.Downloadable; +import eu.siacs.conversations.entities.Transferable; import eu.siacs.conversations.entities.DownloadableFile; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.persistance.FileBackend; @@ -25,7 +27,7 @@ import eu.siacs.conversations.xmpp.OnIqPacketReceived; import eu.siacs.conversations.xmpp.jid.Jid; import eu.siacs.conversations.xmpp.stanzas.IqPacket; -public class HttpUploadConnection implements Downloadable { +public class HttpUploadConnection implements Transferable { private HttpConnectionManager mHttpConnectionManager; private XmppConnectionService mXmppConnectionService; @@ -74,13 +76,13 @@ public class HttpUploadConnection implements Downloadable { private void fail() { mHttpConnectionManager.finishUploadConnection(this); - message.setDownloadable(null); + message.setTransferable(null); mXmppConnectionService.markMessage(message,Message.STATUS_SEND_FAILED); } public void init(Message message) { this.message = message; - message.setDownloadable(this); + message.setTransferable(this); mXmppConnectionService.markMessage(message,Message.STATUS_UNSEND); this.account = message.getConversation().getAccount(); this.file = mXmppConnectionService.getFileBackend().getFile(message, false); @@ -133,6 +135,9 @@ public class HttpUploadConnection implements Downloadable { try { Log.d(Config.LOGTAG, "uploading to " + mPutUrl.toString()); connection = (HttpURLConnection) mPutUrl.openConnection(); + if (connection instanceof HttpsURLConnection) { + mHttpConnectionManager.setupTrustManager((HttpsURLConnection) connection, true); + } connection.setRequestMethod("PUT"); connection.setFixedLengthStreamingMode((int) file.getExpectedSize()); connection.setDoOutput(true); @@ -159,7 +164,7 @@ public class HttpUploadConnection implements Downloadable { mGetUrl = new URL(mGetUrl.toString() + "#" + CryptoHelper.bytesToHex(key)); } mXmppConnectionService.getFileBackend().updateFileParams(message, mGetUrl); - message.setDownloadable(null); + message.setTransferable(null); message.setCounterpart(message.getConversation().getJid().toBareJid()); if (message.getEncryption() == Message.ENCRYPTION_DECRYPTED) { mXmppConnectionService.getPgpEngine().encrypt(message, new UiCallback<Message>() { diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 72f822ca8..d46ff1950 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -362,7 +362,7 @@ public class MessageParser extends AbstractParser implements } final HttpConnectionManager manager = this.mXmppConnectionService.getHttpConnectionManager(); if (message.trusted() && message.treatAsDownloadable() != Message.Decision.NEVER && manager.getAutoAcceptFileSize() > 0) { - manager.createNewConnection(message); + manager.createNewDownloadConnection(message); } else if (!message.isRead()) { mXmppConnectionService.getNotificationService().push(message); } diff --git a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java index 1b80a00a6..fb61691c2 100644 --- a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java @@ -33,7 +33,7 @@ import android.webkit.MimeTypeMap; import eu.siacs.conversations.Config; import eu.siacs.conversations.R; -import eu.siacs.conversations.entities.Downloadable; +import eu.siacs.conversations.entities.Transferable; import eu.siacs.conversations.entities.DownloadableFile; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.services.XmppConnectionService; @@ -80,7 +80,7 @@ public class FileBackend { if (path.startsWith("/")) { return new DownloadableFile(path); } else { - if (Arrays.asList(Downloadable.VALID_IMAGE_EXTENSIONS).contains(extension)) { + if (Arrays.asList(Transferable.VALID_IMAGE_EXTENSIONS).contains(extension)) { return new DownloadableFile(getConversationsFileDirectory() + path); } else { return new DownloadableFile(getConversationsImageDirectory() + path); @@ -235,6 +235,8 @@ public class FileBackend { } else { throw new FileCopyException(R.string.error_out_of_memory); } + } catch (NullPointerException e) { + throw new FileCopyException(R.string.error_io_exception); } finally { close(os); close(is); diff --git a/src/main/java/eu/siacs/conversations/services/NotificationService.java b/src/main/java/eu/siacs/conversations/services/NotificationService.java index 5327bae43..ec68c07a6 100644 --- a/src/main/java/eu/siacs/conversations/services/NotificationService.java +++ b/src/main/java/eu/siacs/conversations/services/NotificationService.java @@ -18,7 +18,6 @@ import android.support.v4.app.NotificationCompat.Builder; import android.support.v4.app.TaskStackBuilder; import android.text.Html; import android.util.DisplayMetrics; -import android.util.Log; import org.json.JSONArray; import org.json.JSONObject; @@ -42,7 +41,6 @@ import eu.siacs.conversations.ui.ManageAccountActivity; import eu.siacs.conversations.ui.TimePreference; import eu.siacs.conversations.utils.GeoHelper; import eu.siacs.conversations.utils.UIHelper; -import eu.siacs.conversations.xmpp.XmppConnection; public class NotificationService { @@ -178,7 +176,7 @@ public class NotificationService { } private void setNotificationColor(final Builder mBuilder) { - mBuilder.setColor(mXmppConnectionService.getResources().getColor(R.color.primary)); + mBuilder.setColor(mXmppConnectionService.getResources().getColor(R.color.green500)); } private void updateNotification(final boolean notify) { @@ -301,7 +299,7 @@ public class NotificationService { final ArrayList<Message> tmp = new ArrayList<>(); for (final Message msg : messages) { if (msg.getType() == Message.TYPE_TEXT - && msg.getDownloadable() == null) { + && msg.getTransferable() == null) { tmp.add(msg); } } @@ -333,7 +331,7 @@ public class NotificationService { private Message getImage(final Iterable<Message> messages) { for (final Message message : messages) { if (message.getType() == Message.TYPE_IMAGE - && message.getDownloadable() == null + && message.getTransferable() == null && message.getEncryption() != Message.ENCRYPTION_PGP) { return message; } @@ -344,7 +342,7 @@ public class NotificationService { private Message getFirstDownloadableMessage(final Iterable<Message> messages) { for (final Message message : messages) { if ((message.getType() == Message.TYPE_FILE || message.getType() == Message.TYPE_IMAGE) && - message.getDownloadable() != null) { + message.getTransferable() != null) { return message; } } diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 2fead2380..ee212aed0 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -57,12 +57,11 @@ import eu.siacs.conversations.entities.Blockable; import eu.siacs.conversations.entities.Bookmark; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.Downloadable; -import eu.siacs.conversations.entities.DownloadablePlaceholder; +import eu.siacs.conversations.entities.Transferable; +import eu.siacs.conversations.entities.TransferablePlaceholder; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.MucOptions; import eu.siacs.conversations.entities.MucOptions.OnRenameListener; -import eu.siacs.conversations.entities.Presences; import eu.siacs.conversations.generator.IqGenerator; import eu.siacs.conversations.generator.MessageGenerator; import eu.siacs.conversations.generator.PresenceGenerator; @@ -234,6 +233,8 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa private MessageArchiveService mMessageArchiveService = new MessageArchiveService(this); private OnConversationUpdate mOnConversationUpdate = null; private int convChangedListenerCount = 0; + private OnShowErrorToast mOnShowErrorToast = null; + private int showErrorToastListenerCount = 0; private int unreadCount = -1; private OnAccountUpdate mOnAccountUpdate = null; private OnStatusChanged statusListener = new OnStatusChanged() { @@ -631,7 +632,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } Context context = getApplicationContext(); AlarmManager alarmManager = (AlarmManager) context - .getSystemService(Context.ALARM_SERVICE); + .getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(context, EventReceiver.class); alarmManager.cancel(PendingIntent.getBroadcast(context, 0, intent, 0)); Log.d(Config.LOGTAG, "good bye"); @@ -685,7 +686,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } public void sendMessage(final Message message) { - sendMessage(message,false); + sendMessage(message, false); } private void sendMessage(final Message message, final boolean resend) { @@ -818,7 +819,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } public void resendMessage(final Message message) { - sendMessage(message,true); + sendMessage(message, true); } public void fetchRosterFromServer(final Account account) { @@ -973,7 +974,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa @Override public void onMessageFound(Message message) { if (!getFileBackend().isFileAvailable(message)) { - message.setDownloadable(new DownloadablePlaceholder(Downloadable.STATUS_DELETED)); + message.setTransferable(new TransferablePlaceholder(Transferable.STATUS_DELETED)); } } }); @@ -984,7 +985,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa Message message = conversation.findMessageWithFileAndUuid(uuid); if (message != null) { if (!getFileBackend().isFileAvailable(message)) { - message.setDownloadable(new DownloadablePlaceholder(Downloadable.STATUS_DELETED)); + message.setTransferable(new TransferablePlaceholder(Transferable.STATUS_DELETED)); updateConversationUi(); } return; @@ -1241,6 +1242,32 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } } + public void setOnShowErrorToastListener(OnShowErrorToast onShowErrorToast) { + synchronized (this) { + if (checkListeners()) { + switchToForeground(); + } + this.mOnShowErrorToast = onShowErrorToast; + if (this.showErrorToastListenerCount < 2) { + this.showErrorToastListenerCount++; + } + } + this.mOnShowErrorToast = onShowErrorToast; + } + + public void removeOnShowErrorToastListener() { + synchronized (this) { + this.showErrorToastListenerCount--; + if (this.showErrorToastListenerCount <= 0) { + this.showErrorToastListenerCount = 0; + this.mOnShowErrorToast = null; + if (checkListeners()) { + switchToBackground(); + } + } + } + } + public void setOnAccountListChangedListener(OnAccountUpdate listener) { synchronized (this) { if (checkListeners()) { @@ -1345,7 +1372,8 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa return (this.mOnAccountUpdate == null && this.mOnConversationUpdate == null && this.mOnRosterUpdate == null - && this.mOnUpdateBlocklist == null); + && this.mOnUpdateBlocklist == null + && this.mOnShowErrorToast == null); } private void switchToForeground() { @@ -1671,7 +1699,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa public void changeAffiliationsInConference(final Conversation conference, MucOptions.Affiliation before, MucOptions.Affiliation after) { List<Jid> jids = new ArrayList<>(); for (MucOptions.User user : conference.getMucOptions().getUsers()) { - if (user.getAffiliation() == before) { + if (user.getAffiliation() == before && user.getJid() != null) { jids.add(user.getJid()); } } @@ -2196,6 +2224,13 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa return count; } + + public void showErrorToastInUi(int resId) { + if (mOnShowErrorToast != null) { + mOnShowErrorToast.onShowErrorToast(resId); + } + } + public void updateConversationUi() { if (mOnConversationUpdate != null) { mOnConversationUpdate.onConversationUpdate(); @@ -2529,6 +2564,10 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa public void onPushFailed(); } + public interface OnShowErrorToast { + void onShowErrorToast(int resId); + } + public class XmppConnectionBinder extends Binder { public XmppConnectionService getService() { return XmppConnectionService.this; diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index 770129abc..a488e3f28 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -40,6 +40,7 @@ import eu.siacs.conversations.entities.Blockable; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Message; +import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate; import eu.siacs.conversations.services.XmppConnectionService.OnConversationUpdate; import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate; @@ -48,7 +49,7 @@ import eu.siacs.conversations.utils.ExceptionHelper; import eu.siacs.conversations.xmpp.OnUpdateBlocklist; public class ConversationActivity extends XmppActivity - implements OnAccountUpdate, OnConversationUpdate, OnRosterUpdate, OnUpdateBlocklist { + implements OnAccountUpdate, OnConversationUpdate, OnRosterUpdate, OnUpdateBlocklist, XmppConnectionService.OnShowErrorToast { public static final String ACTION_DOWNLOAD = "eu.siacs.conversations.action.DOWNLOAD"; @@ -373,8 +374,7 @@ public class ConversationActivity extends XmppActivity } else { menuAdd.setVisible(!isConversationsOverviewHideable()); if (this.getSelectedConversation() != null) { - if (this.getSelectedConversation().getLatestMessage() - .getEncryption() != Message.ENCRYPTION_NONE) { + if (this.getSelectedConversation().getNextEncryption(forceEncryption()) != Message.ENCRYPTION_NONE) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { menuSecure.setIcon(R.drawable.ic_lock_white_24dp); } else { @@ -739,14 +739,11 @@ public class ConversationActivity extends XmppActivity break; case R.id.encryption_choice_pgp: if (hasPgp()) { - if (conversation.getAccount().getKeys() - .has("pgp_signature")) { - conversation - .setNextEncryption(Message.ENCRYPTION_PGP); + if (conversation.getAccount().getKeys().has("pgp_signature")) { + conversation.setNextEncryption(Message.ENCRYPTION_PGP); item.setChecked(true); } else { - announcePgp(conversation.getAccount(), - conversation); + announcePgp(conversation.getAccount(),conversation); } } else { showInstallPgpDialog(); @@ -756,16 +753,16 @@ public class ConversationActivity extends XmppActivity conversation.setNextEncryption(Message.ENCRYPTION_NONE); break; } - xmppConnectionService.databaseBackend - .updateConversation(conversation); + xmppConnectionService.databaseBackend.updateConversation(conversation); fragment.updateChatMsgHint(); + invalidateOptionsMenu(); return true; } }); popup.inflate(R.menu.encryption_choices); MenuItem otr = popup.getMenu().findItem(R.id.encryption_choice_otr); - MenuItem none = popup.getMenu().findItem( - R.id.encryption_choice_none); + MenuItem none = popup.getMenu().findItem(R.id.encryption_choice_none); + MenuItem pgp = popup.getMenu().findItem(R.id.encryption_choice_pgp); if (conversation.getMode() == Conversation.MODE_MULTI) { otr.setEnabled(false); } else { @@ -781,12 +778,10 @@ public class ConversationActivity extends XmppActivity otr.setChecked(true); break; case Message.ENCRYPTION_PGP: - popup.getMenu().findItem(R.id.encryption_choice_pgp) - .setChecked(true); + pgp.setChecked(true); break; default: - popup.getMenu().findItem(R.id.encryption_choice_none) - .setChecked(true); + none.setChecked(true); break; } popup.show(); @@ -1271,4 +1266,14 @@ public class ConversationActivity extends XmppActivity public boolean enterIsSend() { return getPreferences().getBoolean("enter_is_send",false); } + + @Override + public void onShowErrorToast(final int resId) { + runOnUiThread(new Runnable() { + @Override + public void run() { + Toast.makeText(ConversationActivity.this,resId,Toast.LENGTH_SHORT).show(); + } + }); + } } diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index a311ef077..587e923aa 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -3,6 +3,7 @@ package eu.siacs.conversations.ui; import android.app.AlertDialog; import android.app.Fragment; import android.app.PendingIntent; +import android.content.ActivityNotFoundException; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; @@ -45,9 +46,9 @@ import eu.siacs.conversations.crypto.PgpEngine; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.Downloadable; +import eu.siacs.conversations.entities.Transferable; import eu.siacs.conversations.entities.DownloadableFile; -import eu.siacs.conversations.entities.DownloadablePlaceholder; +import eu.siacs.conversations.entities.TransferablePlaceholder; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.MucOptions; import eu.siacs.conversations.entities.Presences; @@ -439,14 +440,14 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa MenuItem downloadFile = menu.findItem(R.id.download_file); MenuItem cancelTransmission = menu.findItem(R.id.cancel_transmission); if ((m.getType() == Message.TYPE_TEXT || m.getType() == Message.TYPE_PRIVATE) - && m.getDownloadable() == null + && m.getTransferable() == null && !GeoHelper.isGeoUri(m.getBody()) && m.treatAsDownloadable() != Message.Decision.MUST) { copyText.setVisible(true); } if ((m.getType() != Message.TYPE_TEXT && m.getType() != Message.TYPE_PRIVATE - && m.getDownloadable() == null) + && m.getTransferable() == null) || (GeoHelper.isGeoUri(m.getBody()))) { shareWith.setVisible(true); } @@ -458,11 +459,11 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa || m.treatAsDownloadable() == Message.Decision.MUST) { copyUrl.setVisible(true); } - if (m.getType() == Message.TYPE_TEXT && m.getDownloadable() == null && m.treatAsDownloadable() != Message.Decision.NEVER) { + if (m.getType() == Message.TYPE_TEXT && m.getTransferable() == null && m.treatAsDownloadable() != Message.Decision.NEVER) { downloadFile.setVisible(true); downloadFile.setTitle(activity.getString(R.string.download_x_file,UIHelper.getFileDescriptionString(activity, m))); } - if ((m.getDownloadable() != null && !(m.getDownloadable() instanceof DownloadablePlaceholder)) + if ((m.getTransferable() != null && !(m.getTransferable() instanceof TransferablePlaceholder)) || (m.isFileOrImage() && (m.getStatus() == Message.STATUS_WAITING || m.getStatus() == Message.STATUS_OFFERED))) { cancelTransmission.setVisible(true); @@ -513,7 +514,12 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa } shareIntent.setType(mime); } - activity.startActivity(Intent.createChooser(shareIntent, getText(R.string.share_with))); + try { + activity.startActivity(Intent.createChooser(shareIntent, getText(R.string.share_with))); + } catch (ActivityNotFoundException e) { + //This should happen only on faulty androids because normally chooser is always available + Toast.makeText(activity,R.string.no_application_found_to_open_file,Toast.LENGTH_SHORT).show(); + } } private void copyText(Message message) { @@ -529,7 +535,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa DownloadableFile file = activity.xmppConnectionService.getFileBackend().getFile(message); if (!file.exists()) { Toast.makeText(activity, R.string.file_deleted, Toast.LENGTH_SHORT).show(); - message.setDownloadable(new DownloadablePlaceholder(Downloadable.STATUS_DELETED)); + message.setTransferable(new TransferablePlaceholder(Transferable.STATUS_DELETED)); return; } } @@ -557,13 +563,13 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa private void downloadFile(Message message) { activity.xmppConnectionService.getHttpConnectionManager() - .createNewConnection(message); + .createNewDownloadConnection(message); } private void cancelTransmission(Message message) { - Downloadable downloadable = message.getDownloadable(); - if (downloadable != null) { - downloadable.cancel(); + Transferable transferable = message.getTransferable(); + if (transferable != null) { + transferable.cancel(); } else { activity.xmppConnectionService.markMessage(message, Message.STATUS_SEND_FAILED); } @@ -757,7 +763,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa if (message.getEncryption() == Message.ENCRYPTION_PGP && (message.getStatus() == Message.STATUS_RECEIVED || message .getStatus() >= Message.STATUS_SEND) - && message.getDownloadable() == null) { + && message.getTransferable() == null) { if (!mEncryptedMessages.contains(message)) { mEncryptedMessages.add(message); } diff --git a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java index 934c696f0..7c994c31a 100644 --- a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java @@ -284,6 +284,9 @@ public abstract class XmppActivity extends Activity { if (this instanceof OnUpdateBlocklist) { this.xmppConnectionService.setOnUpdateBlocklistListener((OnUpdateBlocklist) this); } + if (this instanceof XmppConnectionService.OnShowErrorToast) { + this.xmppConnectionService.setOnShowErrorToastListener((XmppConnectionService.OnShowErrorToast) this); + } } protected void unregisterListeners() { @@ -302,6 +305,9 @@ public abstract class XmppActivity extends Activity { if (this instanceof OnUpdateBlocklist) { this.xmppConnectionService.removeOnUpdateBlocklistListener(); } + if (this instanceof XmppConnectionService.OnShowErrorToast) { + this.xmppConnectionService.removeOnShowErrorToastListener(); + } } @Override @@ -328,14 +334,14 @@ public abstract class XmppActivity extends Activity { super.onCreate(savedInstanceState); metrics = getResources().getDisplayMetrics(); ExceptionHelper.init(getApplicationContext()); - mPrimaryTextColor = getResources().getColor(R.color.primarytext); - mSecondaryTextColor = getResources().getColor(R.color.secondarytext); - mColorRed = getResources().getColor(R.color.red); - mColorOrange = getResources().getColor(R.color.orange); - mColorGreen = getResources().getColor(R.color.green); - mPrimaryColor = getResources().getColor(R.color.primary); - mPrimaryBackgroundColor = getResources().getColor(R.color.primarybackground); - mSecondaryBackgroundColor = getResources().getColor(R.color.secondarybackground); + mPrimaryTextColor = getResources().getColor(R.color.black87); + mSecondaryTextColor = getResources().getColor(R.color.black54); + mColorRed = getResources().getColor(R.color.red500); + mColorOrange = getResources().getColor(R.color.orange500); + mColorGreen = getResources().getColor(R.color.green500); + mPrimaryColor = getResources().getColor(R.color.green500); + mPrimaryBackgroundColor = getResources().getColor(R.color.grey50); + mSecondaryBackgroundColor = getResources().getColor(R.color.grey200); this.mTheme = findTheme(); setTheme(this.mTheme); this.mUsingEnterKey = usingEnterKey(); @@ -447,14 +453,11 @@ public abstract class XmppActivity extends Activity { @Override public void success(Account account) { - xmppConnectionService.databaseBackend - .updateAccount(account); + xmppConnectionService.databaseBackend.updateAccount(account); xmppConnectionService.sendPresence(account); if (conversation != null) { - conversation - .setNextEncryption(Message.ENCRYPTION_PGP); - xmppConnectionService.databaseBackend - .updateConversation(conversation); + conversation.setNextEncryption(Message.ENCRYPTION_PGP); + xmppConnectionService.databaseBackend.updateConversation(conversation); } } @@ -716,10 +719,6 @@ public abstract class XmppActivity extends Activity { return this.mColorRed; } - public int getPrimaryColor() { - return this.mPrimaryColor; - } - public int getOnlineColor() { return this.mColorGreen; } diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java index 5cbc73ecd..bfe44326e 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java @@ -21,7 +21,7 @@ import java.util.concurrent.RejectedExecutionException; import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.Downloadable; +import eu.siacs.conversations.entities.Transferable; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.ui.ConversationActivity; import eu.siacs.conversations.ui.XmppActivity; @@ -69,8 +69,8 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> { } if (message.getFileParams().width > 0 - && (message.getDownloadable() == null - || message.getDownloadable().getStatus() != Downloadable.STATUS_DELETED)) { + && (message.getTransferable() == null + || message.getTransferable().getStatus() != Transferable.STATUS_DELETED)) { mLastMessage.setVisibility(View.GONE); imagePreview.setVisibility(View.VISIBLE); activity.loadBitmap(message, imagePreview); diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index 2337c66b8..112818362 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -29,7 +29,7 @@ import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.Downloadable; +import eu.siacs.conversations.entities.Transferable; import eu.siacs.conversations.entities.DownloadableFile; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.Message.FileParams; @@ -99,14 +99,14 @@ public class MessageAdapter extends ArrayAdapter<Message> { } boolean multiReceived = message.getConversation().getMode() == Conversation.MODE_MULTI && message.getMergedStatus() <= Message.STATUS_RECEIVED; - if (message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE || message.getDownloadable() != null) { + if (message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE || message.getTransferable() != null) { FileParams params = message.getFileParams(); if (params.size > (1.5 * 1024 * 1024)) { filesize = params.size / (1024 * 1024)+ " MiB"; } else if (params.size > 0) { filesize = params.size / 1024 + " KiB"; } - if (message.getDownloadable() != null && message.getDownloadable().getStatus() == Downloadable.STATUS_FAILED) { + if (message.getTransferable() != null && message.getTransferable().getStatus() == Transferable.STATUS_FAILED) { error = true; } } @@ -115,7 +115,7 @@ public class MessageAdapter extends ArrayAdapter<Message> { info = getContext().getString(R.string.waiting); break; case Message.STATUS_UNSEND: - Downloadable d = message.getDownloadable(); + Transferable d = message.getTransferable(); if (d!=null) { info = getContext().getString(R.string.sending_file,d.getProgress()); } else { @@ -160,7 +160,7 @@ public class MessageAdapter extends ArrayAdapter<Message> { message.getMergedTimeSent()); if (message.getStatus() <= Message.STATUS_RECEIVED) { if ((filesize != null) && (info != null)) { - viewHolder.time.setText(filesize + " \u00B7 " + info); + viewHolder.time.setText(formatedTime + " \u00B7 " + filesize +" \u00B7 " + info); } else if ((filesize == null) && (info != null)) { viewHolder.time.setText(formatedTime + " \u00B7 " + info); } else if ((filesize != null) && (info == null)) { @@ -482,11 +482,11 @@ public class MessageAdapter extends ArrayAdapter<Message> { } }); - final Downloadable downloadable = message.getDownloadable(); - if (downloadable != null && downloadable.getStatus() != Downloadable.STATUS_UPLOADING) { - if (downloadable.getStatus() == Downloadable.STATUS_OFFER) { + final Transferable transferable = message.getTransferable(); + if (transferable != null && transferable.getStatus() != Transferable.STATUS_UPLOADING) { + if (transferable.getStatus() == Transferable.STATUS_OFFER) { displayDownloadableMessage(viewHolder,message,activity.getString(R.string.download_x_file, UIHelper.getFileDescriptionString(activity, message))); - } else if (downloadable.getStatus() == Downloadable.STATUS_OFFER_CHECK_FILESIZE) { + } else if (transferable.getStatus() == Transferable.STATUS_OFFER_CHECK_FILESIZE) { displayDownloadableMessage(viewHolder, message, activity.getString(R.string.check_x_filesize, UIHelper.getFileDescriptionString(activity, message))); } else { displayInfoMessage(viewHolder, UIHelper.getMessagePreview(activity, message).first); @@ -536,12 +536,14 @@ public class MessageAdapter extends ArrayAdapter<Message> { } public void startDownloadable(Message message) { - Downloadable downloadable = message.getDownloadable(); - if (downloadable != null) { - if (!downloadable.start()) { + Transferable transferable = message.getTransferable(); + if (transferable != null) { + if (!transferable.start()) { Toast.makeText(activity, R.string.not_connected_try_again, Toast.LENGTH_SHORT).show(); } + } else if (message.treatAsDownloadable() != Message.Decision.NEVER) { + activity.xmppConnectionService.getHttpConnectionManager().createNewDownloadConnection(message); } } @@ -592,4 +594,4 @@ public class MessageAdapter extends ArrayAdapter<Message> { protected ImageView contact_picture; protected TextView status_message; } -}
\ No newline at end of file +} diff --git a/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java b/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java index 466bc4098..2dec203d9 100644 --- a/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java @@ -91,7 +91,9 @@ public final class CryptoHelper { } public static String prettifyFingerprint(String fingerprint) { - if (fingerprint.length() < 40) { + if (fingerprint==null) { + return ""; + } else if (fingerprint.length() < 40) { return fingerprint; } StringBuilder builder = new StringBuilder(fingerprint); diff --git a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java index 064263405..5a47bb3c3 100644 --- a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java @@ -132,7 +132,7 @@ public class DNSHelper { } catch (SocketTimeoutException e) { bundle.putString("error", "timeout"); } catch (Exception e) { - Log.d(Config.LOGTAG,e.getMessage()); + e.printStackTrace(); bundle.putString("error", "unhandled"); } return bundle; diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index ddc4781cb..8047993a3 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -1,6 +1,5 @@ package eu.siacs.conversations.utils; -import java.net.URLConnection; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; @@ -10,7 +9,7 @@ import java.util.Locale; import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.Downloadable; +import eu.siacs.conversations.entities.Transferable; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.xmpp.jid.Jid; @@ -142,24 +141,24 @@ public class UIHelper { } public static Pair<String,Boolean> getMessagePreview(final Context context, final Message message) { - final Downloadable d = message.getDownloadable(); + final Transferable d = message.getTransferable(); if (d != null ) { switch (d.getStatus()) { - case Downloadable.STATUS_CHECKING: + case Transferable.STATUS_CHECKING: return new Pair<>(context.getString(R.string.checking_image),true); - case Downloadable.STATUS_DOWNLOADING: + case Transferable.STATUS_DOWNLOADING: return new Pair<>(context.getString(R.string.receiving_x_file, getFileDescriptionString(context,message), d.getProgress()),true); - case Downloadable.STATUS_OFFER: - case Downloadable.STATUS_OFFER_CHECK_FILESIZE: + case Transferable.STATUS_OFFER: + case Transferable.STATUS_OFFER_CHECK_FILESIZE: return new Pair<>(context.getString(R.string.x_file_offered_for_download, getFileDescriptionString(context,message)),true); - case Downloadable.STATUS_DELETED: + case Transferable.STATUS_DELETED: return new Pair<>(context.getString(R.string.file_deleted),true); - case Downloadable.STATUS_FAILED: + case Transferable.STATUS_FAILED: return new Pair<>(context.getString(R.string.file_transmission_failed),true); - case Downloadable.STATUS_UPLOADING: + case Transferable.STATUS_UPLOADING: if (message.getStatus() == Message.STATUS_OFFERED) { return new Pair<>(context.getString(R.string.offering_x_file, getFileDescriptionString(context, message)), true); diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 87dfb897b..35c89b45f 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -366,17 +366,21 @@ public class XmppConnection implements Runnable { } else if (nextTag.isStart("a")) { final Element ack = tagReader.readElement(nextTag); lastPacketReceived = SystemClock.elapsedRealtime(); - final int serverSequence = Integer.parseInt(ack.getAttribute("h")); - if (Config.EXTENDED_SM_LOGGING) { - Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": server acknowledged stanza #" + serverSequence); - } - final String msgId = this.messageReceipts.get(serverSequence); - if (msgId != null) { - if (this.acknowledgedListener != null) { - this.acknowledgedListener.onMessageAcknowledged( - account, msgId); + try { + final int serverSequence = Integer.parseInt(ack.getAttribute("h")); + if (Config.EXTENDED_SM_LOGGING) { + Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": server acknowledged stanza #" + serverSequence); + } + final String msgId = this.messageReceipts.get(serverSequence); + if (msgId != null) { + if (this.acknowledgedListener != null) { + this.acknowledgedListener.onMessageAcknowledged( + account, msgId); + } + this.messageReceipts.remove(serverSequence); } - this.messageReceipts.remove(serverSequence); + } catch (NumberFormatException e) { + Log.d(Config.LOGTAG,account.getJid().toBareJid()+": server send ack without sequence number"); } } else if (nextTag.isStart("failed")) { tagReader.readElement(nextTag); diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java index 8e4282a9d..335347246 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -1,6 +1,5 @@ package eu.siacs.conversations.xmpp.jingle; -import java.net.URLConnection; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; @@ -16,9 +15,9 @@ import android.util.Log; import eu.siacs.conversations.Config; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.Downloadable; +import eu.siacs.conversations.entities.Transferable; import eu.siacs.conversations.entities.DownloadableFile; -import eu.siacs.conversations.entities.DownloadablePlaceholder; +import eu.siacs.conversations.entities.TransferablePlaceholder; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.xml.Element; @@ -29,7 +28,7 @@ import eu.siacs.conversations.xmpp.jingle.stanzas.JinglePacket; import eu.siacs.conversations.xmpp.jingle.stanzas.Reason; import eu.siacs.conversations.xmpp.stanzas.IqPacket; -public class JingleConnection implements Downloadable { +public class JingleConnection implements Transferable { private JingleConnectionManager mJingleConnectionManager; private XmppConnectionService mXmppConnectionService; @@ -43,7 +42,7 @@ public class JingleConnection implements Downloadable { private int ibbBlockSize = 4096; private int mJingleStatus = -1; - private int mStatus = Downloadable.STATUS_UNKNOWN; + private int mStatus = Transferable.STATUS_UNKNOWN; private Message message; private String sessionId; private Account account; @@ -199,8 +198,8 @@ public class JingleConnection implements Downloadable { this.contentCreator = "initiator"; this.contentName = this.mJingleConnectionManager.nextRandomId(); this.message = message; - this.message.setDownloadable(this); - this.mStatus = Downloadable.STATUS_UPLOADING; + this.message.setTransferable(this); + this.mStatus = Transferable.STATUS_UPLOADING; this.account = message.getConversation().getAccount(); this.initiator = this.account.getJid(); this.responder = this.message.getCounterpart(); @@ -256,8 +255,8 @@ public class JingleConnection implements Downloadable { packet.getFrom().toBareJid(), false); this.message = new Message(conversation, "", Message.ENCRYPTION_NONE); this.message.setStatus(Message.STATUS_RECEIVED); - this.mStatus = Downloadable.STATUS_OFFER; - this.message.setDownloadable(this); + this.mStatus = Transferable.STATUS_OFFER; + this.message.setTransferable(this); final Jid from = packet.getFrom(); this.message.setCounterpart(from); this.account = account; @@ -408,7 +407,7 @@ public class JingleConnection implements Downloadable { private void sendAccept() { mJingleStatus = JINGLE_STATUS_ACCEPTED; - this.mStatus = Downloadable.STATUS_DOWNLOADING; + this.mStatus = Transferable.STATUS_DOWNLOADING; mXmppConnectionService.updateConversationUi(); this.mJingleConnectionManager.getPrimaryCandidate(this.account, new OnPrimaryCandidateFound() { @Override @@ -639,7 +638,7 @@ public class JingleConnection implements Downloadable { this.disconnectSocks5Connections(); this.mJingleStatus = JINGLE_STATUS_FINISHED; this.message.setStatus(Message.STATUS_RECEIVED); - this.message.setDownloadable(null); + this.message.setTransferable(null); this.mXmppConnectionService.updateMessage(message); this.mJingleConnectionManager.finishConnection(this); } @@ -716,7 +715,7 @@ public class JingleConnection implements Downloadable { if (this.transport != null && this.transport instanceof JingleInbandTransport) { this.transport.disconnect(); } - this.message.setDownloadable(null); + this.message.setTransferable(null); this.mJingleConnectionManager.finishConnection(this); } @@ -728,7 +727,7 @@ public class JingleConnection implements Downloadable { this.sendCancel(); this.mJingleConnectionManager.finishConnection(this); if (this.responder.equals(account.getJid())) { - this.message.setDownloadable(new DownloadablePlaceholder(Downloadable.STATUS_FAILED)); + this.message.setTransferable(new TransferablePlaceholder(Transferable.STATUS_FAILED)); if (this.file!=null) { file.delete(); } @@ -736,7 +735,7 @@ public class JingleConnection implements Downloadable { } else { this.mXmppConnectionService.markMessage(this.message, Message.STATUS_SEND_FAILED); - this.message.setDownloadable(null); + this.message.setTransferable(null); } } @@ -748,7 +747,7 @@ public class JingleConnection implements Downloadable { } if (this.message != null) { if (this.responder.equals(account.getJid())) { - this.message.setDownloadable(new DownloadablePlaceholder(Downloadable.STATUS_FAILED)); + this.message.setTransferable(new TransferablePlaceholder(Transferable.STATUS_FAILED)); if (this.file!=null) { file.delete(); } @@ -756,7 +755,7 @@ public class JingleConnection implements Downloadable { } else { this.mXmppConnectionService.markMessage(this.message, Message.STATUS_SEND_FAILED); - this.message.setDownloadable(null); + this.message.setTransferable(null); } } this.mJingleConnectionManager.finishConnection(this); diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java index f0cf5d8a7..cadf9df39 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java @@ -9,14 +9,13 @@ import android.annotation.SuppressLint; import android.util.Log; import eu.siacs.conversations.Config; import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.entities.Downloadable; +import eu.siacs.conversations.entities.Transferable; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.services.AbstractConnectionManager; import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.utils.Xmlns; import eu.siacs.conversations.xml.Element; import eu.siacs.conversations.xmpp.OnIqPacketReceived; -import eu.siacs.conversations.xmpp.jid.InvalidJidException; import eu.siacs.conversations.xmpp.jid.Jid; import eu.siacs.conversations.xmpp.jingle.stanzas.JinglePacket; import eu.siacs.conversations.xmpp.stanzas.IqPacket; @@ -59,7 +58,7 @@ public class JingleConnectionManager extends AbstractConnectionManager { } public JingleConnection createNewConnection(Message message) { - Downloadable old = message.getDownloadable(); + Transferable old = message.getTransferable(); if (old != null) { old.cancel(); } diff --git a/src/main/res/drawable/es_slidingpane_shadow.xml b/src/main/res/drawable/es_slidingpane_shadow.xml index 44ffd4ea6..de96e08f4 100644 --- a/src/main/res/drawable/es_slidingpane_shadow.xml +++ b/src/main/res/drawable/es_slidingpane_shadow.xml @@ -2,7 +2,7 @@ <shape xmlns:android="http://schemas.android.com/apk/res/android" > <gradient - android:endColor="@color/divider" + android:endColor="@color/black12" android:startColor="@android:color/transparent" /> <size diff --git a/src/main/res/drawable/grey.xml b/src/main/res/drawable/grey.xml index 96e03d2d9..26986dbe2 100644 --- a/src/main/res/drawable/grey.xml +++ b/src/main/res/drawable/grey.xml @@ -2,6 +2,6 @@ <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > - <solid android:color="@color/divider" /> + <solid android:color="@color/black12" /> </shape>
\ No newline at end of file diff --git a/src/main/res/drawable/infocard_border.xml b/src/main/res/drawable/infocard_border.xml index 7c7ded571..e01e1442a 100644 --- a/src/main/res/drawable/infocard_border.xml +++ b/src/main/res/drawable/infocard_border.xml @@ -1,13 +1,13 @@ <?xml version="1.0" encoding="UTF-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" > - <solid android:color="@color/primarybackground" /> + <solid android:color="@color/grey50" /> <corners android:radius="2dp" /> <stroke android:width="0.5dp" - android:color="@color/divider" > + android:color="@color/black12" > </stroke> <padding diff --git a/src/main/res/drawable/message_border.xml b/src/main/res/drawable/message_border.xml index b463d788e..990d02886 100644 --- a/src/main/res/drawable/message_border.xml +++ b/src/main/res/drawable/message_border.xml @@ -10,6 +10,6 @@ android:right="1.5dp" android:top="1.5dp" /> - <solid android:color="@color/divider" /> + <solid android:color="@color/black12" /> </shape>
\ No newline at end of file diff --git a/src/main/res/drawable/snackbar.xml b/src/main/res/drawable/snackbar.xml index 951d7aee8..2645b1362 100644 --- a/src/main/res/drawable/snackbar.xml +++ b/src/main/res/drawable/snackbar.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" > - <solid android:color="@color/darkbackground" /> + <solid android:color="@color/grey800" /> <corners android:radius="8dip" /> diff --git a/src/main/res/layout-w945dp/fragment_conversations_overview.xml b/src/main/res/layout-w945dp/fragment_conversations_overview.xml index 50039c03a..7ae1788d7 100644 --- a/src/main/res/layout-w945dp/fragment_conversations_overview.xml +++ b/src/main/res/layout-w945dp/fragment_conversations_overview.xml @@ -9,15 +9,15 @@ android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" - android:background="@color/primarybackground" + android:background="@color/grey50" android:orientation="vertical" > <de.timroes.android.listview.EnhancedListView android:id="@+id/list" android:layout_width="fill_parent" android:layout_height="wrap_content" - android:background="@color/primarybackground" - android:divider="@color/divider" + android:background="@color/grey50" + android:divider="@color/black12" android:dividerHeight="1dp" /> </LinearLayout> diff --git a/src/main/res/layout/account_row.xml b/src/main/res/layout/account_row.xml index d39d5e8f4..1d94586ec 100644 --- a/src/main/res/layout/account_row.xml +++ b/src/main/res/layout/account_row.xml @@ -34,7 +34,7 @@ android:layout_height="wrap_content" android:scrollHorizontally="false" android:singleLine="true" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeHeadline" /> <TextView @@ -42,7 +42,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/account_status_unknown" - android:textColor="@color/secondarytext" + android:textColor="@color/black54" android:textSize="?attr/TextSizeBody" android:textStyle="bold" /> </LinearLayout> diff --git a/src/main/res/layout/actionview_search.xml b/src/main/res/layout/actionview_search.xml index cc5fc9d7a..8b657f4a1 100644 --- a/src/main/res/layout/actionview_search.xml +++ b/src/main/res/layout/actionview_search.xml @@ -14,6 +14,8 @@ android:layout_height="wrap_content" android:focusable="true" android:inputType="textEmailAddress|textNoSuggestions" - android:textColor="@color/ondarktext" /> + android:textColor="@color/white" + android:textColorHint="@color/white70" + android:hint="@string/search_for_contacts_or_groups"/> </RelativeLayout>
\ No newline at end of file diff --git a/src/main/res/layout/activity_about.xml b/src/main/res/layout/activity_about.xml index ab0e34eb6..d7d23f0f9 100644 --- a/src/main/res/layout/activity_about.xml +++ b/src/main/res/layout/activity_about.xml @@ -1,7 +1,7 @@ <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:context="eu.siacs.conversations.ui.AboutActivity" - android:background="@color/primarybackground" + android:background="@color/grey50" android:layout_width="fill_parent" android:layout_height="fill_parent"> @@ -15,7 +15,7 @@ android:layout_marginRight="@dimen/activity_horizontal_margin" android:layout_marginTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody" android:typeface="monospace"/> </ScrollView> diff --git a/src/main/res/layout/activity_change_password.xml b/src/main/res/layout/activity_change_password.xml index 28d531c22..1a4d00d81 100644 --- a/src/main/res/layout/activity_change_password.xml +++ b/src/main/res/layout/activity_change_password.xml @@ -2,7 +2,7 @@ <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@color/primarybackground"> + android:background="@color/grey50"> <ScrollView android:layout_width="fill_parent" @@ -22,7 +22,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/current_password" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody"/> <EditText @@ -32,15 +32,15 @@ android:layout_marginBottom="8dp" android:hint="@string/password" android:inputType="textPassword" - android:textColor="@color/primarytext" - android:textColorHint="@color/secondarytext" + android:textColor="@color/black87" + android:textColorHint="@color/black54" android:textSize="?attr/TextSizeBody"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/new_password" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody"/> <EditText @@ -50,15 +50,15 @@ android:layout_marginBottom="8dp" android:hint="@string/password" android:inputType="textPassword" - android:textColor="@color/primarytext" - android:textColorHint="@color/secondarytext" + android:textColor="@color/black87" + android:textColorHint="@color/black54" android:textSize="?attr/TextSizeBody"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/account_settings_confirm_password" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody"/> <EditText @@ -67,8 +67,8 @@ android:layout_height="wrap_content" android:hint="@string/password" android:inputType="textPassword" - android:textColor="@color/primarytext" - android:textColorHint="@color/secondarytext" + android:textColor="@color/black87" + android:textColorHint="@color/black54" android:textSize="?attr/TextSizeBody"/> </LinearLayout> </ScrollView> @@ -94,7 +94,7 @@ android:layout_height="fill_parent" android:layout_marginBottom="7dp" android:layout_marginTop="7dp" - android:background="@color/divider"/> + android:background="@color/black12"/> <Button android:id="@+id/right_button" diff --git a/src/main/res/layout/activity_contact_details.xml b/src/main/res/layout/activity_contact_details.xml index 8a0818462..e1a967c07 100644 --- a/src/main/res/layout/activity_contact_details.xml +++ b/src/main/res/layout/activity_contact_details.xml @@ -2,7 +2,7 @@ <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" - android:background="@color/secondarybackground" > + android:background="@color/grey200" > <LinearLayout android:layout_width="fill_parent" @@ -46,7 +46,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/account_settings_example_jabber_id" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeHeadline" android:textStyle="bold" android:layout_gravity="center_horizontal" /> @@ -71,7 +71,7 @@ android:id="@+id/details_lastseen" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textColor="@color/secondarytext" + android:textColor="@color/black54" android:textSize="?attr/TextSizeBody" android:layout_gravity="center_horizontal" /> </LinearLayout> @@ -90,7 +90,7 @@ android:layout_height="wrap_content" android:layout_marginTop="8dp" android:text="@string/send_presence_updates" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody" /> <CheckBox @@ -98,7 +98,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/receive_presence_updates" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody" /> </LinearLayout> @@ -110,7 +110,7 @@ android:layout_below="@+id/details_jidbox" android:layout_marginTop="32dp" android:text="@string/using_account" - android:textColor="@color/secondarytext" + android:textColor="@color/black54" android:textSize="?attr/TextSizeInfo" /> </RelativeLayout> diff --git a/src/main/res/layout/activity_edit_account.xml b/src/main/res/layout/activity_edit_account.xml index 9c4b0e764..b99e3e7be 100644 --- a/src/main/res/layout/activity_edit_account.xml +++ b/src/main/res/layout/activity_edit_account.xml @@ -3,7 +3,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@color/secondarybackground" > + android:background="@color/grey200" > <ScrollView android:layout_width="fill_parent" @@ -47,7 +47,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/account_settings_jabber_id" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody" /> <AutoCompleteTextView @@ -56,8 +56,8 @@ android:layout_height="wrap_content" android:hint="@string/account_settings_example_jabber_id" android:inputType="textEmailAddress" - android:textColor="@color/primarytext" - android:textColorHint="@color/secondarytext" + android:textColor="@color/black87" + android:textColorHint="@color/black54" android:textSize="?attr/TextSizeBody" /> <TextView @@ -65,7 +65,7 @@ android:layout_height="wrap_content" android:layout_marginTop="8dp" android:text="@string/account_settings_password" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody" /> <EditText @@ -74,8 +74,8 @@ android:layout_height="wrap_content" android:hint="@string/password" android:inputType="textPassword" - android:textColor="@color/primarytext" - android:textColorHint="@color/secondarytext" + android:textColor="@color/black87" + android:textColorHint="@color/black54" android:textSize="?attr/TextSizeBody" /> <CheckBox @@ -84,7 +84,7 @@ android:layout_height="wrap_content" android:layout_marginTop="8dp" android:text="@string/register_account" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody" /> <TextView @@ -92,7 +92,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/account_settings_confirm_password" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody" android:visibility="gone" /> @@ -104,8 +104,8 @@ android:hint="@string/confirm_password" android:inputType="textPassword" android:visibility="gone" - android:textColor="@color/primarytext" - android:textColorHint="@color/secondarytext" + android:textColor="@color/black87" + android:textColorHint="@color/black54" android:textSize="?attr/TextSizeBody" /> </LinearLayout> </RelativeLayout> @@ -137,7 +137,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/server_info_session_established" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody" /> <TextView @@ -145,7 +145,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="right" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody" tools:ignore="RtlHardcoded"/> </TableRow> @@ -166,7 +166,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/server_info_pep" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody" /> <TextView @@ -174,7 +174,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="right" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody" tools:ignore="RtlHardcoded"/> </TableRow> @@ -187,7 +187,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/server_info_blocking" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody" /> <TextView @@ -195,7 +195,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="right" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody" tools:ignore="RtlHardcoded"/> </TableRow> @@ -208,7 +208,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/server_info_stream_management" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody" /> <TextView @@ -216,7 +216,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="right" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody" tools:ignore="RtlHardcoded"/> </TableRow> @@ -229,7 +229,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/server_info_roster_version" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody" /> <TextView @@ -237,7 +237,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="right" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody" tools:ignore="RtlHardcoded"/> </TableRow> @@ -250,7 +250,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/server_info_carbon_messages" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody" /> <TextView @@ -258,7 +258,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="right" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody" tools:ignore="RtlHardcoded"/> </TableRow> @@ -271,7 +271,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/server_info_mam" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody" /> <TextView @@ -279,7 +279,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="right" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody" tools:ignore="RtlHardcoded"/> </TableRow> @@ -292,7 +292,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/server_info_csi" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody" /> <TextView @@ -300,7 +300,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="right" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody" tools:ignore="RtlHardcoded"/> </TableRow> @@ -323,14 +323,14 @@ android:id="@+id/otr_fingerprint" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody" android:typeface="monospace" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textColor="@color/secondarytext" + android:textColor="@color/black54" android:textSize="?attr/TextSizeInfo" android:text="@string/otr_fingerprint"/> </LinearLayout> @@ -368,14 +368,14 @@ android:layout_height="wrap_content" android:layout_weight="1" android:text="@string/cancel" - android:textColor="@color/primarytext" /> + android:textColor="@color/black87" /> <View android:layout_width="1dp" android:layout_height="fill_parent" android:layout_marginBottom="7dp" android:layout_marginTop="7dp" - android:background="@color/divider" /> + android:background="@color/black12" /> <Button android:id="@+id/save_button" @@ -385,7 +385,7 @@ android:layout_weight="1" android:enabled="false" android:text="@string/save" - android:textColor="@color/secondarytext" /> + android:textColor="@color/black54" /> </LinearLayout> </RelativeLayout> diff --git a/src/main/res/layout/activity_muc_details.xml b/src/main/res/layout/activity_muc_details.xml index 7860d89cf..671215eaa 100644 --- a/src/main/res/layout/activity_muc_details.xml +++ b/src/main/res/layout/activity_muc_details.xml @@ -2,7 +2,7 @@ <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" - android:background="@color/secondarybackground"> + android:background="@color/grey200"> <LinearLayout android:layout_width="fill_parent" @@ -26,7 +26,7 @@ android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:text="@string/account_settings_example_jabber_id" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeHeadline" android:textStyle="bold"/> @@ -59,7 +59,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:singleLine="true" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeHeadline"/> <TextView @@ -67,7 +67,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:singleLine="true" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody"/> </LinearLayout> @@ -91,7 +91,7 @@ android:layout_height="wrap_content" android:text="@string/private_conference" android:layout_centerVertical="true" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody" android:layout_alignParentLeft="true" android:layout_toLeftOf="@+id/change_conference_button" @@ -116,7 +116,7 @@ android:layout_gravity="right" android:layout_marginTop="32dp" android:text="@string/using_account" - android:textColor="@color/secondarytext" + android:textColor="@color/black54" android:textSize="?attr/TextSizeInfo"/> </LinearLayout> diff --git a/src/main/res/layout/activity_publish_profile_picture.xml b/src/main/res/layout/activity_publish_profile_picture.xml index fac499bce..4b2497458 100644 --- a/src/main/res/layout/activity_publish_profile_picture.xml +++ b/src/main/res/layout/activity_publish_profile_picture.xml @@ -2,7 +2,7 @@ <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@color/primarybackground" > + android:background="@color/grey50" > <LinearLayout android:id="@+id/account_image_wrapper" @@ -27,7 +27,7 @@ android:layout_below="@id/account_image_wrapper" android:layout_centerHorizontal="true" android:text="@string/touch_to_choose_picture" - android:textColor="@color/secondarytext" /> + android:textColor="@color/black54" /> <TextView android:id="@+id/secondary_hint" @@ -36,7 +36,7 @@ android:layout_below="@id/hint" android:layout_centerHorizontal="true" android:text="@string/or_long_press_for_default" - android:textColor="@color/secondarytext" /> + android:textColor="@color/black54" /> <LinearLayout android:id="@+id/button_bar" @@ -53,14 +53,14 @@ android:layout_height="wrap_content" android:layout_weight="1" android:text="@string/cancel" - android:textColor="@color/primarytext" /> + android:textColor="@color/black87" /> <View android:layout_width="1dp" android:layout_height="fill_parent" android:layout_marginBottom="7dp" android:layout_marginTop="7dp" - android:background="@color/divider" /> + android:background="@color/black12" /> <Button android:id="@+id/publish_button" @@ -70,7 +70,7 @@ android:layout_weight="1" android:enabled="false" android:text="@string/publish" - android:textColor="@color/secondarytext" /> + android:textColor="@color/black54" /> </LinearLayout> <LinearLayout @@ -89,7 +89,7 @@ android:id="@+id/account" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeHeadline" /> <TextView @@ -99,7 +99,7 @@ android:layout_marginTop="8dp" android:minLines="3" android:text="@string/publish_avatar_explanation" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody" /> </LinearLayout> diff --git a/src/main/res/layout/activity_start_conversation.xml b/src/main/res/layout/activity_start_conversation.xml index f9c985292..d55ec196f 100644 --- a/src/main/res/layout/activity_start_conversation.xml +++ b/src/main/res/layout/activity_start_conversation.xml @@ -3,6 +3,6 @@ android:id="@+id/start_conversation_view_pager" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@color/primarybackground" > + android:background="@color/grey50" > </android.support.v4.view.ViewPager>
\ No newline at end of file diff --git a/src/main/res/layout/activity_verify_otr.xml b/src/main/res/layout/activity_verify_otr.xml index 54f9a542b..ab21c693d 100644 --- a/src/main/res/layout/activity_verify_otr.xml +++ b/src/main/res/layout/activity_verify_otr.xml @@ -2,7 +2,7 @@ <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@color/primarybackground"> + android:background="@color/grey50"> <ScrollView android:layout_width="fill_parent" @@ -34,7 +34,7 @@ android:id="@+id/your_fingerprint" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody" android:typeface="monospace"/> @@ -42,7 +42,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/your_fingerprint" - android:textColor="@color/secondarytext" + android:textColor="@color/black54" android:textSize="?attr/TextSizeInfo"/> <TextView @@ -50,7 +50,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="20dp" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody" android:typeface="monospace"/> @@ -59,7 +59,7 @@ android:layout_height="wrap_content" android:layout_marginBottom="20dp" android:text="@string/remote_fingerprint" - android:textColor="@color/secondarytext" + android:textColor="@color/black54" android:textSize="?attr/TextSizeInfo"/> </LinearLayout> @@ -77,7 +77,7 @@ android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:text="@string/verified" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeHeadline" android:textStyle="bold" android:visibility="gone"/> @@ -87,7 +87,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="8dp" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody" android:textStyle="bold" android:visibility="gone"/> @@ -99,8 +99,8 @@ android:layout_marginBottom="8dp" android:hint="@string/shared_secret_hint" android:inputType="textAutoComplete" - android:textColor="@color/primarytext" - android:textColorHint="@color/secondarytext" + android:textColor="@color/black87" + android:textColorHint="@color/black54" android:textSize="?attr/TextSizeBody"/> <EditText @@ -110,8 +110,8 @@ android:layout_marginTop="8dp" android:hint="@string/shared_secret_secret" android:inputType="textPassword" - android:textColor="@color/primarytext" - android:textColorHint="@color/secondarytext" + android:textColor="@color/black87" + android:textColorHint="@color/black54" android:textSize="?attr/TextSizeBody"/> </LinearLayout> </LinearLayout> @@ -137,7 +137,7 @@ android:layout_height="fill_parent" android:layout_marginBottom="7dp" android:layout_marginTop="7dp" - android:background="@color/divider"/> + android:background="@color/black12"/> <Button android:id="@+id/right_button" diff --git a/src/main/res/layout/contact.xml b/src/main/res/layout/contact.xml index 967b7d7c9..d42782dd8 100644 --- a/src/main/res/layout/contact.xml +++ b/src/main/res/layout/contact.xml @@ -29,7 +29,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:singleLine="true" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeHeadline" /> <TextView @@ -37,7 +37,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:singleLine="true" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody" /> <LinearLayout android:id="@+id/tags" @@ -50,7 +50,7 @@ android:id="@+id/key" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeHeadline" android:typeface="monospace" android:visibility="gone" /> diff --git a/src/main/res/layout/contact_key.xml b/src/main/res/layout/contact_key.xml index b7817b383..933b72b45 100644 --- a/src/main/res/layout/contact_key.xml +++ b/src/main/res/layout/contact_key.xml @@ -15,7 +15,7 @@ android:id="@+id/key" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody" android:typeface="monospace" /> @@ -23,7 +23,7 @@ android:id="@+id/key_type" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textColor="@color/secondarytext" + android:textColor="@color/black54" android:textSize="?attr/TextSizeInfo"/> </LinearLayout> diff --git a/src/main/res/layout/conversation_list_row.xml b/src/main/res/layout/conversation_list_row.xml index f6607010a..5f1c5047d 100644 --- a/src/main/res/layout/conversation_list_row.xml +++ b/src/main/res/layout/conversation_list_row.xml @@ -6,13 +6,13 @@ <View android:layout_width="fill_parent" android:layout_height="fill_parent" - android:background="@color/primary"/> + android:background="@color/green500"/> <FrameLayout android:id="@+id/swipeable_item" android:layout_width="fill_parent" android:layout_height="fill_parent" - android:background="@color/primarybackground"> + android:background="@color/grey50"> <RelativeLayout android:layout_width="fill_parent" @@ -44,7 +44,7 @@ android:layout_alignLeft="@+id/conversation_lastwrapper" android:layout_toLeftOf="@+id/conversation_lastupdate" android:singleLine="true" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeHeadline" android:typeface="sans" /> @@ -62,14 +62,14 @@ android:layout_height="wrap_content" android:scrollHorizontally="false" android:singleLine="true" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody" /> <ImageView android:id="@+id/conversation_lastimage" android:layout_width="fill_parent" android:layout_height="36dp" - android:background="@color/primarytext" + android:background="@color/black87" android:scaleType="centerCrop" /> </LinearLayout> @@ -80,7 +80,7 @@ android:layout_alignBaseline="@+id/conversation_name" android:layout_alignParentRight="true" android:gravity="right" - android:textColor="@color/secondarytext" + android:textColor="@color/black54" android:textSize="?attr/TextSizeInfo" /> </RelativeLayout> </RelativeLayout> diff --git a/src/main/res/layout/create_contact_dialog.xml b/src/main/res/layout/create_contact_dialog.xml index 1ab4b6862..6333e340a 100644 --- a/src/main/res/layout/create_contact_dialog.xml +++ b/src/main/res/layout/create_contact_dialog.xml @@ -10,7 +10,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/your_account" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody" /> <Spinner @@ -24,7 +24,7 @@ android:layout_height="wrap_content" android:layout_marginTop="8dp" android:text="@string/account_settings_jabber_id" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody" /> <AutoCompleteTextView @@ -33,7 +33,7 @@ android:layout_height="wrap_content" android:hint="@string/account_settings_example_jabber_id" android:inputType="textEmailAddress" - android:textColor="@color/primarytext" - android:textColorHint="@color/secondarytext" /> + android:textColor="@color/black87" + android:textColorHint="@color/black54" /> </LinearLayout>
\ No newline at end of file diff --git a/src/main/res/layout/fragment_conversation.xml b/src/main/res/layout/fragment_conversation.xml index 5aa7dffab..d0ac6ba7c 100644 --- a/src/main/res/layout/fragment_conversation.xml +++ b/src/main/res/layout/fragment_conversation.xml @@ -3,7 +3,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@color/secondarybackground" > + android:background="@color/grey200" > <ListView android:id="@+id/messages_view" @@ -12,7 +12,7 @@ android:layout_above="@+id/snackbar" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" - android:background="@color/secondarybackground" + android:background="@color/grey200" android:divider="@null" android:dividerHeight="0dp" android:listSelector="@android:color/transparent" @@ -27,7 +27,7 @@ android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" - android:background="@color/primarybackground" > + android:background="@color/grey50" > <eu.siacs.conversations.ui.EditMessage android:id="@+id/textinput" @@ -35,7 +35,7 @@ android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_toLeftOf="@+id/textSendButton" - android:background="@color/primarybackground" + android:background="@color/grey50" android:ems="10" android:imeOptions="flagNoExtractUi|actionSend" android:inputType="textShortMessage|textMultiLine|textCapSentences" @@ -45,7 +45,7 @@ android:paddingLeft="8dp" android:paddingRight="8dp" android:paddingTop="12dp" - android:textColor="@color/primarytext" > + android:textColor="@color/black87" > <requestFocus /> </eu.siacs.conversations.ui.EditMessage> @@ -80,7 +80,7 @@ android:layout_centerVertical="true" android:layout_toLeftOf="@+id/snackbar_action" android:paddingLeft="24dp" - android:textColor="@color/ondarktext" + android:textColor="@color/white" android:textSize="?attr/TextSizeBody" /> <TextView @@ -94,7 +94,7 @@ android:paddingRight="24dp" android:paddingTop="16dp" android:textAllCaps="true" - android:textColor="@color/ondarktext" + android:textColor="@color/white" android:textSize="?attr/TextSizeBody" android:textStyle="bold" /> </RelativeLayout> diff --git a/src/main/res/layout/fragment_conversations_overview.xml b/src/main/res/layout/fragment_conversations_overview.xml index 24c653ae6..2223219a4 100644 --- a/src/main/res/layout/fragment_conversations_overview.xml +++ b/src/main/res/layout/fragment_conversations_overview.xml @@ -7,15 +7,15 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="@dimen/conversations_overview_width" android:layout_height="match_parent" - android:background="@color/primarybackground" + android:background="@color/grey50" android:orientation="vertical" > <de.timroes.android.listview.EnhancedListView android:id="@+id/list" android:layout_width="fill_parent" android:layout_height="wrap_content" - android:background="@color/primarybackground" - android:divider="@color/divider" + android:background="@color/grey50" + android:divider="@color/black12" android:dividerHeight="1dp" /> </LinearLayout> diff --git a/src/main/res/layout/join_conference_dialog.xml b/src/main/res/layout/join_conference_dialog.xml index 95c9d24cb..7609dd0d5 100644 --- a/src/main/res/layout/join_conference_dialog.xml +++ b/src/main/res/layout/join_conference_dialog.xml @@ -10,7 +10,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/your_account" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody" /> <Spinner @@ -24,7 +24,7 @@ android:layout_height="wrap_content" android:layout_marginTop="8dp" android:text="@string/conference_address" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody" /> <AutoCompleteTextView @@ -33,8 +33,8 @@ android:layout_height="wrap_content" android:hint="@string/conference_address_example" android:inputType="textEmailAddress" - android:textColor="@color/primarytext" - android:textColorHint="@color/secondarytext" /> + android:textColor="@color/black87" + android:textColorHint="@color/black54" /> <CheckBox android:id="@+id/bookmark" diff --git a/src/main/res/layout/list_item_tag.xml b/src/main/res/layout/list_item_tag.xml index 7a77f710f..1a6a5576f 100644 --- a/src/main/res/layout/list_item_tag.xml +++ b/src/main/res/layout/list_item_tag.xml @@ -7,7 +7,7 @@ android:paddingLeft="4dp" android:paddingRight="4dp" android:textSize="?attr/TextSizeInfo" - android:textColor="@color/ondarktext" + android:textColor="@color/white" android:textAllCaps="true" android:layout_marginRight="8dp" />
\ No newline at end of file diff --git a/src/main/res/layout/manage_accounts.xml b/src/main/res/layout/manage_accounts.xml index 11ce35b2f..90ca7de04 100644 --- a/src/main/res/layout/manage_accounts.xml +++ b/src/main/res/layout/manage_accounts.xml @@ -3,13 +3,13 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" - android:background="@color/primarybackground" > + android:background="@color/grey50" > <ListView android:id="@+id/account_list" android:layout_width="fill_parent" android:layout_height="wrap_content" - android:divider="@color/divider" + android:divider="@color/black12" android:dividerHeight="1dp" > </ListView> diff --git a/src/main/res/layout/message_received.xml b/src/main/res/layout/message_received.xml index 9fda44cb2..07c515066 100644 --- a/src/main/res/layout/message_received.xml +++ b/src/main/res/layout/message_received.xml @@ -21,7 +21,7 @@ <LinearLayout android:layout_width="wrap_content" android:layout_height="fill_parent" - android:background="@color/primarybackground" + android:background="@color/grey50" android:gravity="center_vertical" android:orientation="vertical" android:paddingBottom="4dp" @@ -34,7 +34,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:adjustViewBounds="true" - android:background="@color/primarytext" + android:background="@color/black87" android:paddingBottom="2dp" android:scaleType="centerCrop" /> @@ -43,7 +43,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:autoLink="web" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody" /> <Button @@ -77,7 +77,7 @@ android:layout_gravity="center_vertical" android:gravity="center_vertical" android:text="@string/sending" - android:textColor="@color/secondarytext" + android:textColor="@color/black54" android:textSize="?attr/TextSizeInfo" /> </LinearLayout> </LinearLayout> diff --git a/src/main/res/layout/message_sent.xml b/src/main/res/layout/message_sent.xml index 0a59c7544..7d9c10fc2 100644 --- a/src/main/res/layout/message_sent.xml +++ b/src/main/res/layout/message_sent.xml @@ -21,7 +21,7 @@ <LinearLayout android:layout_width="wrap_content" android:layout_height="fill_parent" - android:background="@color/primarybackground" + android:background="@color/grey50" android:gravity="center_vertical" android:orientation="vertical" android:paddingBottom="4dp" @@ -34,7 +34,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:adjustViewBounds="true" - android:background="@color/primarytext" + android:background="@color/black87" android:paddingBottom="2dp" android:scaleType="centerCrop" /> @@ -43,7 +43,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:autoLink="web" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody" /> <Button @@ -68,7 +68,7 @@ android:layout_gravity="center_vertical" android:gravity="center_vertical" android:text="@string/sending" - android:textColor="@color/secondarytext" + android:textColor="@color/black54" android:textSize="?attr/TextSizeInfo" /> <ImageView diff --git a/src/main/res/layout/message_status.xml b/src/main/res/layout/message_status.xml index ae44474ff..393b672fb 100644 --- a/src/main/res/layout/message_status.xml +++ b/src/main/res/layout/message_status.xml @@ -29,7 +29,7 @@ android:layout_toEndOf="@+id/message_photo" android:layout_toRightOf="@+id/message_photo" android:text="@string/contact_has_read_up_to_this_point" - android:textColor="@color/secondarytext" + android:textColor="@color/black54" android:textSize="?attr/TextSizeInfo" android:textStyle="italic"/> diff --git a/src/main/res/layout/quickedit.xml b/src/main/res/layout/quickedit.xml index 20a2868ac..ff6b0413a 100644 --- a/src/main/res/layout/quickedit.xml +++ b/src/main/res/layout/quickedit.xml @@ -11,7 +11,7 @@ android:layout_height="wrap_content" android:ems="10" android:inputType="textPersonName" - android:textColor="@color/primarytext" > + android:textColor="@color/black87" > <requestFocus /> </EditText> diff --git a/src/main/res/values-v21/themes.xml b/src/main/res/values-v21/themes.xml index a1f3d0c57..d1679f928 100644 --- a/src/main/res/values-v21/themes.xml +++ b/src/main/res/values-v21/themes.xml @@ -2,8 +2,8 @@ <resources> <style name="ConversationsTheme" parent="@android:style/Theme.Material.Light.DarkActionBar"> - <item name="android:colorPrimary">@color/primary</item> - <item name="android:colorPrimaryDark">@color/primarydark</item> + <item name="android:colorPrimary">@color/green500</item> + <item name="android:colorPrimaryDark">@color/green700</item> <item name="android:colorAccent">@color/accent</item> <item name="TextSizeInfo">12sp</item> diff --git a/src/main/res/values/colors.xml b/src/main/res/values/colors.xml index 753a56df9..3a778a210 100644 --- a/src/main/res/values/colors.xml +++ b/src/main/res/values/colors.xml @@ -1,18 +1,16 @@ <?xml version="1.0" encoding="utf-8"?> <resources> - - <color name="primary" type="color">#ff259b24</color> - <color name="primarydark" type="color">#ff0a7e07</color> - <color name="accent">#ff0091ea</color> - <color name="primarytext" type="color">#de000000</color> - <color name="secondarytext" type="color">#8a000000</color> - <color name="ondarktext" type="color">#fffafafa</color> - <color name="primarybackground" type="color">#fffafafa</color> - <color name="secondarybackground" type="color">#ffeeeeee</color> - <color name="darkbackground" type="color">#ff323232</color> - <color name="divider">#1f000000</color> - <color name="red">#fff44336</color> - <color name="orange">#ffff9800</color> - <color name="green">#ff259b24</color> - + <color name="green500">#ff259b24</color> + <color name="green700">#ff0a7e07</color> + <color name="accent">#ff0091ea</color> + <color name="black87">#de000000</color> + <color name="black54">#8a000000</color> + <color name="black12">#1f000000</color> + <color name="white">#ffffffff</color> + <color name="white70">#b2ffffff</color> + <color name="grey50">#fffafafa</color> + <color name="grey200">#ffeeeeee</color> + <color name="grey800">#ff424242</color> + <color name="red500">#fff44336</color> + <color name="orange500">#ffff9800</color> </resources>
\ No newline at end of file diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 444d9ecf0..d2dfb4f86 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -478,4 +478,6 @@ <string name="none">None</string> <string name="recently_used">Most recently used</string> <string name="choose_quick_action">Choose quick action</string> + <string name="file_not_found_on_remote_host">File not found on remote server</string> + <string name="search_for_contacts_or_groups">Search for contacts or groups</string> </resources> diff --git a/src/main/res/values/styles.xml b/src/main/res/values/styles.xml index b329eee44..b98a37fcb 100644 --- a/src/main/res/values/styles.xml +++ b/src/main/res/values/styles.xml @@ -2,7 +2,7 @@ <style name="Divider"> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">1.5dp</item> - <item name="android:background">@color/divider</item> + <item name="android:background">@color/black12</item> </style> <style name="Tag"> diff --git a/src/main/res/values/themes.xml b/src/main/res/values/themes.xml index 80f2bfe65..5c67203be 100644 --- a/src/main/res/values/themes.xml +++ b/src/main/res/values/themes.xml @@ -38,8 +38,8 @@ </style> <style name="ConversationsActionBar" parent="@android:style/Widget.Holo.Light.ActionBar.Solid.Inverse"> - <item name="android:background">@color/primary</item> - <item name="android:backgroundStacked">@color/primarydark</item> + <item name="android:background">@color/green500</item> + <item name="android:backgroundStacked">@color/green700</item> <item name="android:displayOptions">showHome|homeAsUp|showTitle</item> <item name="android:icon">@android:color/transparent</item> </style> |