diff options
24 files changed, 273 insertions, 210 deletions
diff --git a/res/layout/message_sent.xml b/res/layout/message_sent.xml index 28f3ddc63..e3e9b673e 100644 --- a/res/layout/message_sent.xml +++ b/res/layout/message_sent.xml @@ -45,6 +45,14 @@ android:textColor="@color/primarytext" android:textIsSelectable="true" android:textSize="?attr/TextSizeBody" /> + + <Button + android:id="@+id/download_button" + style="?android:attr/buttonStyleSmall" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/download_image" + android:visibility="gone" /> <LinearLayout android:layout_width="wrap_content" diff --git a/src/eu/siacs/conversations/crypto/PgpEngine.java b/src/eu/siacs/conversations/crypto/PgpEngine.java index 07e8e472c..e5524df51 100644 --- a/src/eu/siacs/conversations/crypto/PgpEngine.java +++ b/src/eu/siacs/conversations/crypto/PgpEngine.java @@ -76,7 +76,8 @@ public class PgpEngine { case OpenPgpApi.RESULT_CODE_ERROR: OpenPgpError error = result .getParcelableExtra(OpenPgpApi.RESULT_ERROR); - Log.d(Config.LOGTAG,"openpgp error: "+error.getMessage()); + Log.d(Config.LOGTAG, + "openpgp error: " + error.getMessage()); callback.error(R.string.openpgp_error, message); return; default: @@ -110,7 +111,8 @@ public class PgpEngine { + ',' + imageWidth + ',' + imageHeight); message.setEncryption(Message.ENCRYPTION_DECRYPTED); PgpEngine.this.mXmppConnectionService - .updateMessage(message);; + .updateMessage(message); + ; callback.success(message); return; case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: diff --git a/src/eu/siacs/conversations/entities/Conversation.java b/src/eu/siacs/conversations/entities/Conversation.java index b4c99dc1a..5f204ec27 100644 --- a/src/eu/siacs/conversations/entities/Conversation.java +++ b/src/eu/siacs/conversations/entities/Conversation.java @@ -68,7 +68,7 @@ public class Conversation extends AbstractEntity { private transient MucOptions mucOptions = null; - //private transient String latestMarkableMessageId; + // private transient String latestMarkableMessageId; private byte[] symmetricKey; @@ -142,8 +142,9 @@ public class Conversation extends AbstractEntity { if (this.messages == null) { return null; } - for(int i = this.messages.size() - 1; i >= 0; --i) { - if (this.messages.get(i).getStatus() <= Message.STATUS_RECEIVED && this.messages.get(i).markable) { + for (int i = this.messages.size() - 1; i >= 0; --i) { + if (this.messages.get(i).getStatus() <= Message.STATUS_RECEIVED + && this.messages.get(i).markable) { if (this.messages.get(i).isRead()) { return null; } else { diff --git a/src/eu/siacs/conversations/entities/Downloadable.java b/src/eu/siacs/conversations/entities/Downloadable.java index c8ee357db..3fc94c58c 100644 --- a/src/eu/siacs/conversations/entities/Downloadable.java +++ b/src/eu/siacs/conversations/entities/Downloadable.java @@ -1,9 +1,19 @@ package eu.siacs.conversations.entities; public interface Downloadable { - + public final String[] VALID_EXTENSIONS = { "webp", "jpeg", "jpg", "png" }; public final String[] VALID_CRYPTO_EXTENSIONS = { "pgp", "gpg", "otr" }; - + + public static final int STATUS_UNKNOWN = 0x200; + public static final int STATUS_CHECKING = 0x201; + public static final int STATUS_FAILED = 0x202; + public static final int STATUS_OFFER = 0x203; + public static final int STATUS_DOWNLOADING = 0x204; + public void start(); + + public int getStatus(); + + public long getFileSize(); } diff --git a/src/eu/siacs/conversations/entities/DownloadableFile.java b/src/eu/siacs/conversations/entities/DownloadableFile.java index 14afc826f..50b00fb87 100644 --- a/src/eu/siacs/conversations/entities/DownloadableFile.java +++ b/src/eu/siacs/conversations/entities/DownloadableFile.java @@ -29,7 +29,7 @@ public class DownloadableFile extends File { private long expectedSize = 0; private String sha1sum; private Key aeskey; - + private byte[] iv = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0xf }; @@ -81,7 +81,7 @@ public class DownloadableFile extends File { public Key getKey() { return this.aeskey; } - + public InputStream createInputStream() { if (this.getKey() == null) { try { diff --git a/src/eu/siacs/conversations/entities/Message.java b/src/eu/siacs/conversations/entities/Message.java index 863288bbc..a256d5150 100644 --- a/src/eu/siacs/conversations/entities/Message.java +++ b/src/eu/siacs/conversations/entities/Message.java @@ -14,10 +14,6 @@ public class Message extends AbstractEntity { public static final String TABLENAME = "messages"; - public static final int STATUS_RECEIVED_CHECKING = -4; - public static final int STATUS_RECEPTION_FAILED = -3; - public static final int STATUS_RECEIVED_OFFER = -2; - public static final int STATUS_RECEIVING = -1; public static final int STATUS_RECEIVED = 0; public static final int STATUS_UNSEND = 1; public static final int STATUS_SEND = 2; @@ -136,8 +132,8 @@ public class Message extends AbstractEntity { if (this.trueCounterpart == null) { return null; } else { - return this.conversation.getAccount().getRoster().getContactFromRoster( - this.trueCounterpart); + return this.conversation.getAccount().getRoster() + .getContactFromRoster(this.trueCounterpart); } } } @@ -147,12 +143,9 @@ public class Message extends AbstractEntity { } public String getReadableBody(Context context) { - if ((encryption == ENCRYPTION_PGP) && (type == TYPE_TEXT)) { + if (encryption == ENCRYPTION_PGP) { return context.getText(R.string.encrypted_message_received) .toString(); - } else if ((encryption == ENCRYPTION_OTR) && (type == TYPE_IMAGE)) { - return context.getText(R.string.encrypted_image_received) - .toString(); } else if (encryption == ENCRYPTION_DECRYPTION_FAILED) { return context.getText(R.string.decryption_failed).toString(); } else if (type == TYPE_IMAGE) { @@ -322,6 +315,8 @@ public class Message extends AbstractEntity { return false; } return (message.getType() == Message.TYPE_TEXT + && this.getDownloadable() == null + && message.getDownloadable() == null && message.getEncryption() != Message.ENCRYPTION_PGP && this.getType() == message.getType() && this.getEncryption() == message.getEncryption() @@ -368,26 +363,34 @@ public class Message extends AbstractEntity { return prev.mergable(this); } } - + public boolean bodyContainsDownloadable() { Contact contact = this.getContact(); - if (contact == null || !contact.trusted()) { + if (status <= STATUS_RECEIVED + && (contact == null || !contact.trusted())) { return false; } try { URL url = new URL(this.getBody()); - if (!url.getProtocol().equalsIgnoreCase("http") && !url.getProtocol().equalsIgnoreCase("https")) { + if (!url.getProtocol().equalsIgnoreCase("http") + && !url.getProtocol().equalsIgnoreCase("https")) { return false; } - if (url.getPath()==null) { + if (url.getPath() == null) { return false; } String[] pathParts = url.getPath().split("/"); String filename = pathParts[pathParts.length - 1]; String[] extensionParts = filename.split("\\."); - if (extensionParts.length == 2 && Arrays.asList(Downloadable.VALID_EXTENSIONS).contains(extensionParts[extensionParts.length -1])) { + if (extensionParts.length == 2 + && Arrays.asList(Downloadable.VALID_EXTENSIONS).contains( + extensionParts[extensionParts.length - 1])) { return true; - } else if (extensionParts.length == 3 && Arrays.asList(Downloadable.VALID_CRYPTO_EXTENSIONS).contains(extensionParts.length -1) && Arrays.asList(Downloadable.VALID_EXTENSIONS).contains(extensionParts[extensionParts.length -2])) { + } else if (extensionParts.length == 3 + && Arrays.asList(Downloadable.VALID_CRYPTO_EXTENSIONS) + .contains(extensionParts.length - 1) + && Arrays.asList(Downloadable.VALID_EXTENSIONS).contains( + extensionParts[extensionParts.length - 2])) { return true; } else { return false; @@ -396,27 +399,23 @@ public class Message extends AbstractEntity { return false; } } - + public ImageParams getImageParams() { ImageParams params = new ImageParams(); - if (body==null) { + if (this.downloadable != null) { + params.size = this.downloadable.getFileSize(); + } + if (body == null) { return params; } String parts[] = body.split(","); - if (parts.length==1) { + if (parts.length == 1) { try { params.size = Long.parseLong(parts[0]); } catch (NumberFormatException e) { params.origin = parts[0]; } - } else if (parts.length == 2) { - params.origin = parts[0]; - try { - params.size = Long.parseLong(parts[1]); - } catch (NumberFormatException e) { - params.size = 0; - } - } else if (parts.length==3) { + } else if (parts.length == 3) { try { params.size = Long.parseLong(parts[0]); } catch (NumberFormatException e) { @@ -452,7 +451,7 @@ public class Message extends AbstractEntity { } return params; } - + public class ImageParams { public long size = 0; public int width = 0; diff --git a/src/eu/siacs/conversations/http/HttpConnection.java b/src/eu/siacs/conversations/http/HttpConnection.java index ff8037fb3..c53b9fd54 100644 --- a/src/eu/siacs/conversations/http/HttpConnection.java +++ b/src/eu/siacs/conversations/http/HttpConnection.java @@ -24,7 +24,8 @@ public class HttpConnection implements Downloadable { private URL mUrl; private Message message; private DownloadableFile file; - private long mPreviousFileSize = Long.MIN_VALUE; + private long mPreviousFileSize = 0; + private int mStatus = Downloadable.STATUS_UNKNOWN; public HttpConnection(HttpConnectionManager manager) { this.mHttpConnectionManager = manager; @@ -33,6 +34,7 @@ public class HttpConnection implements Downloadable { @Override public void start() { + changeStatus(STATUS_DOWNLOADING); new Thread(new FileDownloader()).start(); } @@ -41,43 +43,46 @@ public class HttpConnection implements Downloadable { this.message.setDownloadable(this); try { mUrl = new URL(message.getBody()); - this.file = mXmppConnectionService.getFileBackend().getConversationsFile(message,false); - message.setType(Message.TYPE_IMAGE); - message.setStatus(Message.STATUS_RECEIVED_CHECKING); - mXmppConnectionService.updateConversationUi(); + this.file = mXmppConnectionService.getFileBackend() + .getConversationsFile(message, false); checkFileSize(); } catch (MalformedURLException e) { this.cancel(); } } - + public void init(Message message, URL url) { this.message = message; this.message.setDownloadable(this); this.mUrl = url; - this.file = mXmppConnectionService.getFileBackend().getConversationsFile(message,false); + this.file = mXmppConnectionService.getFileBackend() + .getConversationsFile(message, false); this.mPreviousFileSize = message.getImageParams().size; - message.setType(Message.TYPE_IMAGE); - message.setStatus(Message.STATUS_RECEIVED_CHECKING); - mXmppConnectionService.updateConversationUi(); checkFileSize(); } - + private void checkFileSize() { + changeStatus(STATUS_CHECKING); new Thread(new FileSizeChecker()).start(); } public void cancel() { - mXmppConnectionService.markMessage(message, Message.STATUS_RECEPTION_FAILED); mHttpConnectionManager.finishConnection(this); + message.setDownloadable(null); + message.setBody(mUrl.toString()); + mXmppConnectionService.updateMessage(message); } - + private void finish() { - message.setStatus(Message.STATUS_RECEIVED); - mXmppConnectionService.updateMessage(message); + message.setDownloadable(null); mHttpConnectionManager.finishConnection(this); } + private void changeStatus(int status) { + this.mStatus = status; + mXmppConnectionService.updateConversationUi(); + } + private class FileSizeChecker implements Runnable { @Override @@ -90,21 +95,21 @@ public class HttpConnection implements Downloadable { return; } file.setExpectedSize(size); - message.setBody(mUrl.toString()+","+String.valueOf(size)); - if (size <= mHttpConnectionManager.getAutoAcceptFileSize() || size == mPreviousFileSize) { - mXmppConnectionService.updateMessage(message); + message.setType(Message.TYPE_IMAGE); + if (size <= mHttpConnectionManager.getAutoAcceptFileSize() + || size == mPreviousFileSize) { start(); } else { - message.setStatus(Message.STATUS_RECEIVED_OFFER); - mXmppConnectionService.updateMessage(message); + changeStatus(STATUS_OFFER); } } private long retrieveFileSize() throws IOException { - HttpURLConnection connection = (HttpURLConnection) mUrl.openConnection(); + HttpURLConnection connection = (HttpURLConnection) mUrl + .openConnection(); connection.setRequestMethod("HEAD"); if (connection instanceof HttpsURLConnection) { - + } String contentLength = connection.getHeaderField("Content-Length"); if (contentLength == null) { @@ -118,13 +123,12 @@ public class HttpConnection implements Downloadable { } } - + private class FileDownloader implements Runnable { @Override public void run() { try { - mXmppConnectionService.markMessage(message, Message.STATUS_RECEIVING); download(); updateImageBounds(); finish(); @@ -132,13 +136,15 @@ public class HttpConnection implements Downloadable { cancel(); } } - + private void download() throws IOException { - HttpURLConnection connection = (HttpURLConnection) mUrl.openConnection(); + HttpURLConnection connection = (HttpURLConnection) mUrl + .openConnection(); if (connection instanceof HttpsURLConnection) { - + } - BufferedInputStream is = new BufferedInputStream(connection.getInputStream()); + BufferedInputStream is = new BufferedInputStream( + connection.getInputStream()); OutputStream os = file.createOutputStream(); int count = -1; byte[] buffer = new byte[1024]; @@ -149,17 +155,31 @@ public class HttpConnection implements Downloadable { os.close(); is.close(); } - + private void updateImageBounds() { BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(file.getAbsolutePath(), options); int imageHeight = options.outHeight; int imageWidth = options.outWidth; - message.setBody(mUrl.toString()+","+file.getSize() + ',' + message.setBody(mUrl.toString() + "," + file.getSize() + ',' + imageWidth + ',' + imageHeight); - + mXmppConnectionService.updateMessage(message); + } + + } + + @Override + public int getStatus() { + return this.mStatus; + } + + @Override + public long getFileSize() { + if (this.file != null) { + return this.file.getExpectedSize(); + } else { + return 0; } - } }
\ No newline at end of file diff --git a/src/eu/siacs/conversations/http/HttpConnectionManager.java b/src/eu/siacs/conversations/http/HttpConnectionManager.java index 7393cf36e..011ecc3f5 100644 --- a/src/eu/siacs/conversations/http/HttpConnectionManager.java +++ b/src/eu/siacs/conversations/http/HttpConnectionManager.java @@ -13,24 +13,23 @@ public class HttpConnectionManager extends AbstractConnectionManager { public HttpConnectionManager(XmppConnectionService service) { super(service); } - + private List<HttpConnection> connections = new CopyOnWriteArrayList<HttpConnection>(); - - + public HttpConnection createNewConnection(Message message) { HttpConnection connection = new HttpConnection(this); connection.init(message); this.connections.add(connection); return connection; } - + public HttpConnection createNewConnection(Message message, URL url) { HttpConnection connection = new HttpConnection(this); - connection.init(message,url); + connection.init(message, url); this.connections.add(connection); return connection; } - + public void finishConnection(HttpConnection connection) { this.connections.remove(connection); } diff --git a/src/eu/siacs/conversations/parser/MessageParser.java b/src/eu/siacs/conversations/parser/MessageParser.java index 71346c7a5..486dd3892 100644 --- a/src/eu/siacs/conversations/parser/MessageParser.java +++ b/src/eu/siacs/conversations/parser/MessageParser.java @@ -478,8 +478,9 @@ public class MessageParser extends AbstractParser implements mXmppConnectionService.databaseBackend.createMessage(message); } } - if (message.getStatus() == Message.STATUS_RECEIVED && message.bodyContainsDownloadable()) { - this.mXmppConnectionService.getHttpConnectionManager().createNewConnection(message); + if (message.bodyContainsDownloadable()) { + this.mXmppConnectionService.getHttpConnectionManager() + .createNewConnection(message); } notify = notify && !conversation.isMuted(); if (notify) { diff --git a/src/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/eu/siacs/conversations/persistance/DatabaseBackend.java index 091c00bd4..d90b5c622 100644 --- a/src/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -238,7 +238,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { cursor.close(); return (count > 0); } catch (SQLiteCantOpenDatabaseException e) { - return true; //better safe than sorry + return true; // better safe than sorry } } diff --git a/src/eu/siacs/conversations/persistance/FileBackend.java b/src/eu/siacs/conversations/persistance/FileBackend.java index c8ae657d9..35aa9042b 100644 --- a/src/eu/siacs/conversations/persistance/FileBackend.java +++ b/src/eu/siacs/conversations/persistance/FileBackend.java @@ -70,7 +70,8 @@ public class FileBackend { return getJingleFileLegacy(message, true); } - public DownloadableFile getJingleFileLegacy(Message message, boolean decrypted) { + public DownloadableFile getJingleFileLegacy(Message message, + boolean decrypted) { Conversation conversation = message.getConversation(); String prefix = context.getFilesDir().getAbsolutePath(); String path = prefix + "/" + conversation.getAccount().getJid() + "/" @@ -92,7 +93,8 @@ public class FileBackend { return getConversationsFile(message, true); } - public DownloadableFile getConversationsFile(Message message, boolean decrypted) { + public DownloadableFile getConversationsFile(Message message, + boolean decrypted) { StringBuilder filename = new StringBuilder(); filename.append(Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES).getAbsolutePath()); @@ -144,8 +146,8 @@ public class FileBackend { return this.copyImageToPrivateStorage(message, image, 0); } - private DownloadableFile copyImageToPrivateStorage(Message message, Uri image, - int sampleSize) throws ImageCopyException { + private DownloadableFile copyImageToPrivateStorage(Message message, + Uri image, int sampleSize) throws ImageCopyException { try { InputStream is = context.getContentResolver() .openInputStream(image); diff --git a/src/eu/siacs/conversations/services/AbstractConnectionManager.java b/src/eu/siacs/conversations/services/AbstractConnectionManager.java index a06be826e..676a09c97 100644 --- a/src/eu/siacs/conversations/services/AbstractConnectionManager.java +++ b/src/eu/siacs/conversations/services/AbstractConnectionManager.java @@ -1,17 +1,16 @@ package eu.siacs.conversations.services; - public class AbstractConnectionManager { protected XmppConnectionService mXmppConnectionService; public AbstractConnectionManager(XmppConnectionService service) { this.mXmppConnectionService = service; } - + public XmppConnectionService getXmppConnectionService() { return this.mXmppConnectionService; } - + public long getAutoAcceptFileSize() { String config = this.mXmppConnectionService.getPreferences().getString( "auto_accept_file_size", "524288"); diff --git a/src/eu/siacs/conversations/ui/ConferenceDetailsActivity.java b/src/eu/siacs/conversations/ui/ConferenceDetailsActivity.java index deddcad70..ca3bb4a20 100644 --- a/src/eu/siacs/conversations/ui/ConferenceDetailsActivity.java +++ b/src/eu/siacs/conversations/ui/ConferenceDetailsActivity.java @@ -199,7 +199,8 @@ public class ConferenceDetailsActivity extends XmppActivity { } private void populateView() { - mAccountJid.setText(getString(R.string.using_account,conversation.getAccount().getJid())); + mAccountJid.setText(getString(R.string.using_account, conversation + .getAccount().getJid())); mYourPhoto.setImageBitmap(conversation.getAccount().getImage(this, 48)); setTitle(conversation.getName()); mFullJid.setText(conversation.getContactJid().split("/", 2)[0]); diff --git a/src/eu/siacs/conversations/ui/ContactDetailsActivity.java b/src/eu/siacs/conversations/ui/ContactDetailsActivity.java index 394aab6ee..65bd5cbf1 100644 --- a/src/eu/siacs/conversations/ui/ContactDetailsActivity.java +++ b/src/eu/siacs/conversations/ui/ContactDetailsActivity.java @@ -56,7 +56,8 @@ public class ContactDetailsActivity extends XmppActivity { @Override public void onClick(DialogInterface dialog, int which) { - ContactDetailsActivity.this.xmppConnectionService.deleteContactOnServer(contact); + ContactDetailsActivity.this.xmppConnectionService + .deleteContactOnServer(contact); ContactDetailsActivity.this.finish(); } }; @@ -78,7 +79,8 @@ public class ContactDetailsActivity extends XmppActivity { @Override public void onClick(View v) { - AlertDialog.Builder builder = new AlertDialog.Builder(ContactDetailsActivity.this); + AlertDialog.Builder builder = new AlertDialog.Builder( + ContactDetailsActivity.this); builder.setTitle(getString(R.string.action_add_phone_book)); builder.setMessage(getString(R.string.add_phone_book_text, contact.getJid())); @@ -309,7 +311,8 @@ public class ContactDetailsActivity extends XmppActivity { } else { contactJidTv.setText(contact.getJid()); } - accountJidTv.setText(getString(R.string.using_account,contact.getAccount().getJid())); + accountJidTv.setText(getString(R.string.using_account, contact + .getAccount().getJid())); UIHelper.prepareContactBadge(this, badge, contact, getApplicationContext()); diff --git a/src/eu/siacs/conversations/ui/ConversationActivity.java b/src/eu/siacs/conversations/ui/ConversationActivity.java index 407393872..24ef9a6f7 100644 --- a/src/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/eu/siacs/conversations/ui/ConversationActivity.java @@ -222,7 +222,8 @@ public class ConversationActivity extends XmppActivity implements ab.setDisplayHomeAsUpEnabled(true); ab.setHomeButtonEnabled(true); if (getSelectedConversation().getMode() == Conversation.MODE_SINGLE - || ConversationActivity.this.useSubjectToIdentifyConference()) { + || ConversationActivity.this + .useSubjectToIdentifyConference()) { ab.setTitle(getSelectedConversation().getName()); } else { ab.setTitle(getSelectedConversation().getContactJid() diff --git a/src/eu/siacs/conversations/ui/ConversationFragment.java b/src/eu/siacs/conversations/ui/ConversationFragment.java index 4835636d7..0e71801bd 100644 --- a/src/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/eu/siacs/conversations/ui/ConversationFragment.java @@ -72,8 +72,7 @@ public class ConversationFragment extends Fragment { private boolean messagesLoaded = false; private IntentSender askForPassphraseIntent = null; - - + private ConcurrentLinkedQueue<Message> mEncryptedMessages = new ConcurrentLinkedQueue<Message>(); private boolean mDecryptJobRunning = false; @@ -505,8 +504,8 @@ public class ConversationFragment extends Fragment { private void decryptNext() { Message next = this.mEncryptedMessages.peek(); PgpEngine engine = activity.xmppConnectionService.getPgpEngine(); - - if (next!=null && engine != null && !mDecryptJobRunning) { + + if (next != null && engine != null && !mDecryptJobRunning) { mDecryptJobRunning = true; engine.decrypt(next, new UiCallback<Message>() { @@ -535,7 +534,7 @@ public class ConversationFragment extends Fragment { }); } } - + private void messageSent() { int size = this.messageList.size(); messagesView.setSelection(size - 1); diff --git a/src/eu/siacs/conversations/ui/ManageAccountActivity.java b/src/eu/siacs/conversations/ui/ManageAccountActivity.java index afe9e06e9..5b5b0608f 100644 --- a/src/eu/siacs/conversations/ui/ManageAccountActivity.java +++ b/src/eu/siacs/conversations/ui/ManageAccountActivity.java @@ -70,7 +70,8 @@ public class ManageAccountActivity extends XmppActivity { public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); - ManageAccountActivity.this.getMenuInflater().inflate(R.menu.manageaccounts_context, menu); + ManageAccountActivity.this.getMenuInflater().inflate( + R.menu.manageaccounts_context, menu); AdapterView.AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) menuInfo; this.selectedAccount = accountList.get(acmi.position); if (this.selectedAccount.isOptionSet(Account.OPTION_DISABLED)) { @@ -187,7 +188,8 @@ public class ManageAccountActivity extends XmppActivity { } private void deleteAccount(final Account account) { - AlertDialog.Builder builder = new AlertDialog.Builder(ManageAccountActivity.this); + AlertDialog.Builder builder = new AlertDialog.Builder( + ManageAccountActivity.this); builder.setTitle(getString(R.string.mgmt_account_are_you_sure)); builder.setIconAttribute(android.R.attr.alertDialogIcon); builder.setMessage(getString(R.string.mgmt_account_delete_confirm_text)); diff --git a/src/eu/siacs/conversations/ui/adapter/ConversationAdapter.java b/src/eu/siacs/conversations/ui/adapter/ConversationAdapter.java index f74856b07..6943a85cf 100644 --- a/src/eu/siacs/conversations/ui/adapter/ConversationAdapter.java +++ b/src/eu/siacs/conversations/ui/adapter/ConversationAdapter.java @@ -5,6 +5,7 @@ import java.util.List; import eu.siacs.conversations.Config; import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Conversation; +import eu.siacs.conversations.entities.Downloadable; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.ui.ConversationActivity; import eu.siacs.conversations.ui.XmppActivity; @@ -37,11 +38,11 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> { view = (View) inflater.inflate(R.layout.conversation_list_row, parent, false); } - Conversation conv = getItem(position); + Conversation conversation = getItem(position); if (this.activity instanceof ConversationActivity) { ConversationActivity activity = (ConversationActivity) this.activity; if (!activity.isConversationsOverviewHideable()) { - if (conv == activity.getSelectedConversation()) { + if (conversation == activity.getSelectedConversation()) { view.setBackgroundColor(activity .getSecondaryBackgroundColor()); } else { @@ -53,65 +54,76 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> { } TextView convName = (TextView) view .findViewById(R.id.conversation_name); - if (conv.getMode() == Conversation.MODE_SINGLE + if (conversation.getMode() == Conversation.MODE_SINGLE || activity.useSubjectToIdentifyConference()) { - convName.setText(conv.getName()); + convName.setText(conversation.getName()); } else { - convName.setText(conv.getContactJid().split("/")[0]); + convName.setText(conversation.getContactJid().split("/")[0]); } - TextView convLastMsg = (TextView) view + TextView mLastMessage = (TextView) view .findViewById(R.id.conversation_lastmsg); + TextView mTimestamp = (TextView) view + .findViewById(R.id.conversation_lastupdate); ImageView imagePreview = (ImageView) view .findViewById(R.id.conversation_lastimage); - Message latestMessage = conv.getLatestMessage(); + Message message = conversation.getLatestMessage(); - if (latestMessage.getType() == Message.TYPE_TEXT - || latestMessage.getType() == Message.TYPE_PRIVATE) { - if ((latestMessage.getEncryption() != Message.ENCRYPTION_PGP) - && (latestMessage.getEncryption() != Message.ENCRYPTION_DECRYPTION_FAILED)) { - String body = Config.PARSE_EMOTICONS ? UIHelper - .transformAsciiEmoticons(latestMessage.getBody()) - : latestMessage.getBody(); - convLastMsg.setText(body); - } else { - convLastMsg.setText(R.string.encrypted_message_received); - } - convLastMsg.setVisibility(View.VISIBLE); - imagePreview.setVisibility(View.GONE); - } else if (latestMessage.getType() == Message.TYPE_IMAGE) { - if (latestMessage.getStatus() >= Message.STATUS_RECEIVED) { - convLastMsg.setVisibility(View.GONE); - imagePreview.setVisibility(View.VISIBLE); - activity.loadBitmap(latestMessage, imagePreview); - } else { - convLastMsg.setVisibility(View.VISIBLE); + if (!conversation.isRead()) { + convName.setTypeface(null, Typeface.BOLD); + } else { + convName.setTypeface(null, Typeface.NORMAL); + } + + if (message.getType() == Message.TYPE_IMAGE + || message.getDownloadable() != null) { + Downloadable d = message.getDownloadable(); + if (d != null) { + mLastMessage.setVisibility(View.VISIBLE); imagePreview.setVisibility(View.GONE); - if (latestMessage.getStatus() == Message.STATUS_RECEIVED_OFFER) { - convLastMsg.setText(R.string.image_offered_for_download); - } else if (latestMessage.getStatus() == Message.STATUS_RECEIVING) { - convLastMsg.setText(R.string.receiving_image); + if (conversation.isRead()) { + mLastMessage.setTypeface(null, Typeface.ITALIC); + } else { + mLastMessage.setTypeface(null, Typeface.BOLD_ITALIC); + } + if (d.getStatus() == Downloadable.STATUS_CHECKING) { + mLastMessage.setText(R.string.checking_image); + } else if (d.getStatus() == Downloadable.STATUS_DOWNLOADING) { + mLastMessage.setText(R.string.receiving_image); + } else if (d.getStatus() == Downloadable.STATUS_OFFER) { + mLastMessage.setText(R.string.image_offered_for_download); } else { - convLastMsg.setText(""); + mLastMessage.setText(""); } + } else { + mLastMessage.setVisibility(View.GONE); + imagePreview.setVisibility(View.VISIBLE); + activity.loadBitmap(message, imagePreview); } - } - - if (!conv.isRead()) { - convName.setTypeface(null, Typeface.BOLD); - convLastMsg.setTypeface(null, Typeface.BOLD); } else { - convName.setTypeface(null, Typeface.NORMAL); - convLastMsg.setTypeface(null, Typeface.NORMAL); + if ((message.getEncryption() != Message.ENCRYPTION_PGP) + && (message.getEncryption() != Message.ENCRYPTION_DECRYPTION_FAILED)) { + String body = Config.PARSE_EMOTICONS ? UIHelper + .transformAsciiEmoticons(message.getBody()) : message + .getBody(); + mLastMessage.setText(body); + } else { + mLastMessage.setText(R.string.encrypted_message_received); + } + if (!conversation.isRead()) { + mLastMessage.setTypeface(null, Typeface.BOLD); + } else { + mLastMessage.setTypeface(null, Typeface.NORMAL); + } + mLastMessage.setVisibility(View.VISIBLE); + imagePreview.setVisibility(View.GONE); } - - ((TextView) view.findViewById(R.id.conversation_lastupdate)) - .setText(UIHelper.readableTimeDifference(getContext(), conv - .getLatestMessage().getTimeSent())); + mTimestamp.setText(UIHelper.readableTimeDifference(getContext(), + conversation.getLatestMessage().getTimeSent())); ImageView profilePicture = (ImageView) view .findViewById(R.id.conversation_image); - profilePicture.setImageBitmap(conv.getImage(activity, 56)); + profilePicture.setImageBitmap(conversation.getImage(activity, 56)); return view; } diff --git a/src/eu/siacs/conversations/ui/adapter/KnownHostsAdapter.java b/src/eu/siacs/conversations/ui/adapter/KnownHostsAdapter.java index 2b8ee0484..143dfda12 100644 --- a/src/eu/siacs/conversations/ui/adapter/KnownHostsAdapter.java +++ b/src/eu/siacs/conversations/ui/adapter/KnownHostsAdapter.java @@ -47,11 +47,11 @@ public class KnownHostsAdapter extends ArrayAdapter<String> { @Override protected void publishResults(CharSequence constraint, FilterResults results) { - ArrayList filteredList = (ArrayList)results.values; + ArrayList filteredList = (ArrayList) results.values; if (results != null && results.count > 0) { clear(); for (Object c : filteredList) { - add((String)c); + add((String) c); } notifyDataSetChanged(); } diff --git a/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java index b09f97fc3..efb072922 100644 --- a/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -138,10 +138,6 @@ public class MessageAdapter extends ArrayAdapter<Message> { info = getContext().getString(R.string.send_rejected); error = true; break; - case Message.STATUS_RECEPTION_FAILED: - info = getContext().getString(R.string.reception_failed); - error = true; - break; default: if (multiReceived) { Contact contact = message.getContact(); @@ -230,19 +226,10 @@ public class MessageAdapter extends ArrayAdapter<Message> { viewHolder.messageBody.setVisibility(View.VISIBLE); if (message.getBody() != null) { if (message.getType() != Message.TYPE_PRIVATE) { - if (message.getType() == Message.TYPE_IMAGE) { - String orign = message.getImageParams().origin; - if (orign!=null) { - viewHolder.messageBody.setText(orign); - } else { - viewHolder.messageBody.setText(message.getBody()); - } - } else { - String body = Config.PARSE_EMOTICONS ? UIHelper - .transformAsciiEmoticons(message.getMergedBody()) - : message.getMergedBody(); - viewHolder.messageBody.setText(body); - } + String body = Config.PARSE_EMOTICONS ? UIHelper + .transformAsciiEmoticons(message.getMergedBody()) + : message.getMergedBody(); + viewHolder.messageBody.setText(body); } else { String privateMarker; if (message.getStatus() <= Message.STATUS_RECEIVED) { @@ -347,6 +334,8 @@ public class MessageAdapter extends ArrayAdapter<Message> { viewHolder.contact_picture = (ImageView) view .findViewById(R.id.message_photo); viewHolder.contact_picture.setImageBitmap(getSelfBitmap()); + viewHolder.download_button = (Button) view + .findViewById(R.id.download_button); viewHolder.indicator = (ImageView) view .findViewById(R.id.security_indicator); viewHolder.image = (ImageView) view @@ -366,15 +355,11 @@ public class MessageAdapter extends ArrayAdapter<Message> { .findViewById(R.id.message_box); viewHolder.contact_picture = (ImageView) view .findViewById(R.id.message_photo); - viewHolder.download_button = (Button) view .findViewById(R.id.download_button); - if (item.getConversation().getMode() == Conversation.MODE_SINGLE) { - viewHolder.contact_picture.setImageBitmap(mBitmapCache.get( item.getConversation().getContact(), getContext())); - } viewHolder.indicator = (ImageView) view .findViewById(R.id.security_indicator); @@ -483,14 +468,15 @@ public class MessageAdapter extends ArrayAdapter<Message> { } } - if (item.getType() == Message.TYPE_IMAGE) { - if (item.getStatus() == Message.STATUS_RECEIVING) { + if (item.getType() == Message.TYPE_IMAGE + || item.getDownloadable() != null) { + Downloadable d = item.getDownloadable(); + if (d != null && d.getStatus() == Downloadable.STATUS_DOWNLOADING) { displayInfoMessage(viewHolder, R.string.receiving_image); - } else if (item.getStatus() == Message.STATUS_RECEIVED_CHECKING) { + } else if (d != null + && d.getStatus() == Downloadable.STATUS_CHECKING) { displayInfoMessage(viewHolder, R.string.checking_image); - } else if (item.getStatus() == Message.STATUS_RECEPTION_FAILED) { - displayTextMessage(viewHolder, item); - } else if (item.getStatus() == Message.STATUS_RECEIVED_OFFER) { + } else if (d != null && d.getStatus() == Downloadable.STATUS_OFFER) { viewHolder.image.setVisibility(View.GONE); viewHolder.messageBody.setVisibility(View.GONE); viewHolder.download_button.setVisibility(View.VISIBLE); @@ -499,11 +485,7 @@ public class MessageAdapter extends ArrayAdapter<Message> { @Override public void onClick(View v) { - if (!startDonwloadable(item)) { - activity.xmppConnectionService.markMessage( - item, - Message.STATUS_RECEPTION_FAILED); - } + startDonwloadable(item); } }); } else if ((item.getEncryption() == Message.ENCRYPTION_DECRYPTED) diff --git a/src/eu/siacs/conversations/xmpp/XmppConnection.java b/src/eu/siacs/conversations/xmpp/XmppConnection.java index 54409be45..43614f50d 100644 --- a/src/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/eu/siacs/conversations/xmpp/XmppConnection.java @@ -910,7 +910,7 @@ public class XmppConnection implements Runnable { } public void disconnect(boolean force) { - Log.d(Config.LOGTAG, account.getJid()+": disconnecting"); + Log.d(Config.LOGTAG, account.getJid() + ": disconnecting"); try { if (force) { socket.close(); diff --git a/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java index 4853d75c7..8e4714f4e 100644 --- a/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -34,17 +34,18 @@ public class JingleConnection implements Downloadable { private JingleConnectionManager mJingleConnectionManager; private XmppConnectionService mXmppConnectionService; - public static final int STATUS_INITIATED = 0; - public static final int STATUS_ACCEPTED = 1; - public static final int STATUS_TERMINATED = 2; - public static final int STATUS_CANCELED = 3; - public static final int STATUS_FINISHED = 4; - public static final int STATUS_TRANSMITTING = 5; - public static final int STATUS_FAILED = 99; + protected static final int JINGLE_STATUS_INITIATED = 0; + protected static final int JINGLE_STATUS_ACCEPTED = 1; + protected static final int JINGLE_STATUS_TERMINATED = 2; + protected static final int JINGLE_STATUS_CANCELED = 3; + protected static final int JINGLE_STATUS_FINISHED = 4; + protected static final int JINGLE_STATUS_TRANSMITTING = 5; + protected static final int JINGLE_STATUS_FAILED = 99; private int ibbBlockSize = 4096; - private int status = -1; + private int mJingleStatus = -1; + private int mStatus = -1; private Message message; private String sessionId; private Account account; @@ -76,7 +77,7 @@ public class JingleConnection implements Downloadable { mXmppConnectionService.markMessage(message, Message.STATUS_SEND_FAILED); } - status = STATUS_FAILED; + mJingleStatus = JINGLE_STATUS_FAILED; } } }; @@ -254,13 +255,14 @@ public class JingleConnection implements Downloadable { } public void init(Account account, JinglePacket packet) { - this.status = STATUS_INITIATED; + this.mJingleStatus = JINGLE_STATUS_INITIATED; Conversation conversation = this.mXmppConnectionService .findOrCreateConversation(account, packet.getFrom().split("/", 2)[0], false); this.message = new Message(conversation, "", Message.ENCRYPTION_NONE); + this.message.setStatus(Message.STATUS_RECEIVED); this.message.setType(Message.TYPE_IMAGE); - this.message.setStatus(Message.STATUS_RECEIVED_OFFER); + this.mStatus = Downloadable.STATUS_OFFER; this.message.setDownloadable(this); String[] fromParts = packet.getFrom().split("/", 2); this.message.setPresence(fromParts[1]); @@ -306,6 +308,7 @@ public class JingleConnection implements Downloadable { long size = Long.parseLong(fileSize.getContent()); message.setBody(Long.toString(size)); conversation.getMessages().add(message); + mXmppConnectionService.updateConversationUi(); if (size <= this.mJingleConnectionManager .getAutoAcceptFileSize()) { Log.d(Config.LOGTAG, "auto accepting file from " @@ -370,7 +373,7 @@ public class JingleConnection implements Downloadable { content.socks5transport().setChildren(getCandidatesAsElements()); packet.setContent(content); this.sendJinglePacket(packet); - this.status = STATUS_INITIATED; + this.mJingleStatus = JINGLE_STATUS_INITIATED; } } @@ -383,8 +386,9 @@ public class JingleConnection implements Downloadable { } private void sendAccept() { - status = STATUS_ACCEPTED; - mXmppConnectionService.markMessage(message, Message.STATUS_RECEIVING); + mJingleStatus = JINGLE_STATUS_ACCEPTED; + this.mStatus = Downloadable.STATUS_DOWNLOADING; + mXmppConnectionService.updateConversationUi(); this.mJingleConnectionManager.getPrimaryCandidate(this.account, new OnPrimaryCandidateFound() { @@ -458,7 +462,7 @@ public class JingleConnection implements Downloadable { Content content = packet.getJingleContent(); mergeCandidates(JingleCandidate.parse(content.socks5transport() .getChildren())); - this.status = STATUS_ACCEPTED; + this.mJingleStatus = JINGLE_STATUS_ACCEPTED; mXmppConnectionService.markMessage(message, Message.STATUS_UNSEND); this.connectNextCandidate(); return true; @@ -493,7 +497,8 @@ public class JingleConnection implements Downloadable { } else if (content.socks5transport().hasChild("candidate-error")) { Log.d(Config.LOGTAG, "received candidate error"); this.receivedCandidate = true; - if ((status == STATUS_ACCEPTED) && (this.sentCandidate)) { + if ((mJingleStatus == JINGLE_STATUS_ACCEPTED) + && (this.sentCandidate)) { this.connect(); } return true; @@ -505,7 +510,8 @@ public class JingleConnection implements Downloadable { JingleCandidate candidate = getCandidate(cid); candidate.flagAsUsedByCounterpart(); this.receivedCandidate = true; - if ((status == STATUS_ACCEPTED) && (this.sentCandidate)) { + if ((mJingleStatus == JINGLE_STATUS_ACCEPTED) + && (this.sentCandidate)) { this.connect(); } else { Log.d(Config.LOGTAG, @@ -533,7 +539,7 @@ public class JingleConnection implements Downloadable { this.sendFallbackToIbb(); } } else { - this.status = STATUS_TRANSMITTING; + this.mJingleStatus = JINGLE_STATUS_TRANSMITTING; if (connection.needsActivation()) { if (connection.getCandidate().isOurs()) { Log.d(Config.LOGTAG, "candidate " @@ -620,9 +626,10 @@ public class JingleConnection implements Downloadable { packet.setReason(reason); this.sendJinglePacket(packet); this.disconnect(); - this.status = STATUS_FINISHED; - this.mXmppConnectionService.markMessage(this.message, - Message.STATUS_RECEIVED); + this.mJingleStatus = JINGLE_STATUS_FINISHED; + this.message.setStatus(Message.STATUS_RECEIVED); + this.message.setDownloadable(null); + this.mXmppConnectionService.updateMessage(message); this.mJingleConnectionManager.finishConnection(this); } @@ -692,7 +699,7 @@ public class JingleConnection implements Downloadable { } private void receiveSuccess() { - this.status = STATUS_FINISHED; + this.mJingleStatus = JINGLE_STATUS_FINISHED; this.mXmppConnectionService.markMessage(this.message, Message.STATUS_SEND); this.disconnect(); @@ -700,14 +707,14 @@ public class JingleConnection implements Downloadable { } public void cancel() { - this.status = STATUS_CANCELED; + this.mJingleStatus = JINGLE_STATUS_CANCELED; this.disconnect(); if (this.message != null) { if (this.responder.equals(account.getFullJid())) { - this.mXmppConnectionService.markMessage(this.message, - Message.STATUS_RECEPTION_FAILED); + this.mStatus = Downloadable.STATUS_FAILED; + this.mXmppConnectionService.updateConversationUi(); } else { - if (this.status == STATUS_INITIATED) { + if (this.mJingleStatus == JINGLE_STATUS_INITIATED) { this.mXmppConnectionService.markMessage(this.message, Message.STATUS_SEND_REJECTED); } else { @@ -790,7 +797,7 @@ public class JingleConnection implements Downloadable { .setAttribute("cid", cid); packet.setContent(content); this.sentCandidate = true; - if ((receivedCandidate) && (status == STATUS_ACCEPTED)) { + if ((receivedCandidate) && (mJingleStatus == JINGLE_STATUS_ACCEPTED)) { connect(); } this.sendJinglePacket(packet); @@ -803,7 +810,7 @@ public class JingleConnection implements Downloadable { content.socks5transport().addChild("candidate-error"); packet.setContent(content); this.sentCandidate = true; - if ((receivedCandidate) && (status == STATUS_ACCEPTED)) { + if ((receivedCandidate) && (mJingleStatus == JINGLE_STATUS_ACCEPTED)) { connect(); } this.sendJinglePacket(packet); @@ -817,8 +824,8 @@ public class JingleConnection implements Downloadable { return this.responder; } - public int getStatus() { - return this.status; + public int getJingleStatus() { + return this.mJingleStatus; } private boolean equalCandidateExists(JingleCandidate candidate) { @@ -869,7 +876,7 @@ public class JingleConnection implements Downloadable { } public void start() { - if (status == STATUS_INITIATED) { + if (mJingleStatus == JINGLE_STATUS_INITIATED) { new Thread(new Runnable() { @Override @@ -878,7 +885,21 @@ public class JingleConnection implements Downloadable { } }).start(); } else { - Log.d(Config.LOGTAG, "status (" + status + ") was not ok"); + Log.d(Config.LOGTAG, "status (" + mJingleStatus + ") was not ok"); + } + } + + @Override + public int getStatus() { + return this.mStatus; + } + + @Override + public long getFileSize() { + if (this.file != null) { + return this.file.getExpectedSize(); + } else { + return 0; } } } diff --git a/src/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java b/src/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java index bb3602045..40ccbfe34 100644 --- a/src/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java +++ b/src/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java @@ -154,7 +154,7 @@ public class JingleConnectionManager extends AbstractConnectionManager { public void cancelInTransmission() { for (JingleConnection connection : this.connections) { - if (connection.getStatus() == JingleConnection.STATUS_TRANSMITTING) { + if (connection.getJingleStatus() == JingleConnection.JINGLE_STATUS_TRANSMITTING) { connection.cancel(); } } diff --git a/src/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java b/src/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java index e50169358..cc1e92f62 100644 --- a/src/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java +++ b/src/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java @@ -100,7 +100,8 @@ public class JingleInbandTransport extends JingleTransport { } @Override - public void send(DownloadableFile file, OnFileTransmissionStatusChanged callback) { + public void send(DownloadableFile file, + OnFileTransmissionStatusChanged callback) { this.onFileTransmissionStatusChanged = callback; this.file = file; try { |