diff options
Diffstat (limited to 'src')
13 files changed, 871 insertions, 515 deletions
diff --git a/src/eu/siacs/conversations/crypto/PgpEngine.java b/src/eu/siacs/conversations/crypto/PgpEngine.java index cfe39e4c..229b4300 100644 --- a/src/eu/siacs/conversations/crypto/PgpEngine.java +++ b/src/eu/siacs/conversations/crypto/PgpEngine.java @@ -2,6 +2,10 @@ package eu.siacs.conversations.crypto; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -13,86 +17,176 @@ import org.openintents.openpgp.util.OpenPgpApi.IOpenPgpCallback; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Message; +import eu.siacs.conversations.services.XmppConnectionService; +import eu.siacs.conversations.xmpp.jingle.JingleFile; import android.app.PendingIntent; import android.content.Intent; +import android.graphics.BitmapFactory; import android.util.Log; public class PgpEngine { private OpenPgpApi api; + private XmppConnectionService mXmppConnectionService; - public PgpEngine(OpenPgpApi api) { + public PgpEngine(OpenPgpApi api, XmppConnectionService service) { this.api = api; + this.mXmppConnectionService = service; } public void decrypt(final Message message, final OnPgpEngineResult callback) { + Log.d("xmppService","decrypting message "+message.getUuid()); Intent params = new Intent(); params.setAction(OpenPgpApi.ACTION_DECRYPT_VERIFY); params.putExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME, message .getConversation().getAccount().getJid()); - InputStream is = new ByteArrayInputStream(message.getBody().getBytes()); - final OutputStream os = new ByteArrayOutputStream(); - api.executeApiAsync(params, is, os, new IOpenPgpCallback() { - - @Override - public void onReturn(Intent result) { - switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, - OpenPgpApi.RESULT_CODE_ERROR)) { - case OpenPgpApi.RESULT_CODE_SUCCESS: - message.setBody(os.toString()); - message.setEncryption(Message.ENCRYPTION_DECRYPTED); - callback.success(); - return; - case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: - callback.userInputRequried((PendingIntent) result - .getParcelableExtra(OpenPgpApi.RESULT_INTENT)); - return; - case OpenPgpApi.RESULT_CODE_ERROR: - callback.error((OpenPgpError) result - .getParcelableExtra(OpenPgpApi.RESULT_ERROR)); - return; - default: - return; + if (message.getType() == Message.TYPE_TEXT) { + InputStream is = new ByteArrayInputStream(message.getBody().getBytes()); + final OutputStream os = new ByteArrayOutputStream(); + api.executeApiAsync(params, is, os, new IOpenPgpCallback() { + + @Override + public void onReturn(Intent result) { + switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, + OpenPgpApi.RESULT_CODE_ERROR)) { + case OpenPgpApi.RESULT_CODE_SUCCESS: + message.setBody(os.toString()); + message.setEncryption(Message.ENCRYPTION_DECRYPTED); + callback.success(); + return; + case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: + callback.userInputRequried((PendingIntent) result + .getParcelableExtra(OpenPgpApi.RESULT_INTENT)); + return; + case OpenPgpApi.RESULT_CODE_ERROR: + callback.error((OpenPgpError) result + .getParcelableExtra(OpenPgpApi.RESULT_ERROR)); + return; + default: + return; + } } + }); + } else if (message.getType() == Message.TYPE_IMAGE) { + try { + final JingleFile inputFile = this.mXmppConnectionService.getFileBackend().getJingleFile(message, false); + final JingleFile outputFile = this.mXmppConnectionService.getFileBackend().getJingleFile(message,true); + outputFile.createNewFile(); + InputStream is = new FileInputStream(inputFile); + OutputStream os = new FileOutputStream(outputFile); + api.executeApiAsync(params, is, os, new IOpenPgpCallback() { + + @Override + public void onReturn(Intent result) { + switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, + OpenPgpApi.RESULT_CODE_ERROR)) { + case OpenPgpApi.RESULT_CODE_SUCCESS: + BitmapFactory.Options options = new BitmapFactory.Options(); + options.inJustDecodeBounds = true; + BitmapFactory.decodeFile(outputFile.getAbsolutePath(),options); + int imageHeight = options.outHeight; + int imageWidth = options.outWidth; + message.setBody(""+outputFile.getSize()+","+imageWidth+","+imageHeight); + message.setEncryption(Message.ENCRYPTION_DECRYPTED); + PgpEngine.this.mXmppConnectionService.updateMessage(message); + PgpEngine.this.mXmppConnectionService.updateUi(message.getConversation(), false); + callback.success(); + return; + case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: + callback.userInputRequried((PendingIntent) result + .getParcelableExtra(OpenPgpApi.RESULT_INTENT)); + return; + case OpenPgpApi.RESULT_CODE_ERROR: + callback.error((OpenPgpError) result + .getParcelableExtra(OpenPgpApi.RESULT_ERROR)); + return; + default: + return; + } + } + }); + } catch (FileNotFoundException e) { + callback.error(new OpenPgpError(0, "file not found: "+e.getMessage())); + } catch (IOException e) { + callback.error(new OpenPgpError(0, "io exception: "+e.getMessage())); } - }); + + } } - public void encrypt(Account account, long keyId, Message message, - final OnPgpEngineResult callback) { - Log.d("xmppService", "called to pgpengine::encrypt"); - long[] keys = { keyId }; + public void encrypt(final Message message,final OnPgpEngineResult callback) { + long[] keys = { message.getConversation().getContact().getPgpKeyId() }; Intent params = new Intent(); params.setAction(OpenPgpApi.ACTION_ENCRYPT); params.putExtra(OpenPgpApi.EXTRA_KEY_IDS, keys); - params.putExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true); - params.putExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME, account.getJid()); - - InputStream is = new ByteArrayInputStream(message.getBody().getBytes()); - ByteArrayOutputStream os = new ByteArrayOutputStream(); - Intent result = api.executeApi(params, is, os); - switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, - OpenPgpApi.RESULT_CODE_ERROR)) { - case OpenPgpApi.RESULT_CODE_SUCCESS: - StringBuilder encryptedMessageBody = new StringBuilder(); - String[] lines = os.toString().split("\n"); - for (int i = 3; i < lines.length - 1; ++i) { - encryptedMessageBody.append(lines[i].trim()); + params.putExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME, message.getConversation().getAccount().getJid()); + + if (message.getType() == Message.TYPE_TEXT) { + params.putExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true); + + InputStream is = new ByteArrayInputStream(message.getBody().getBytes()); + final OutputStream os = new ByteArrayOutputStream(); + api.executeApiAsync(params, is, os, new IOpenPgpCallback() { + + @Override + public void onReturn(Intent result) { + switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, + OpenPgpApi.RESULT_CODE_ERROR)) { + case OpenPgpApi.RESULT_CODE_SUCCESS: + StringBuilder encryptedMessageBody = new StringBuilder(); + String[] lines = os.toString().split("\n"); + for (int i = 3; i < lines.length - 1; ++i) { + encryptedMessageBody.append(lines[i].trim()); + } + message.setEncryptedBody(encryptedMessageBody.toString()); + callback.success(); + break; + case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: + callback.userInputRequried((PendingIntent) result + .getParcelableExtra(OpenPgpApi.RESULT_INTENT)); + break; + case OpenPgpApi.RESULT_CODE_ERROR: + callback.error((OpenPgpError) result + .getParcelableExtra(OpenPgpApi.RESULT_ERROR)); + break; + } + } + }); + } else if (message.getType() == Message.TYPE_IMAGE) { + try { + JingleFile inputFile = this.mXmppConnectionService.getFileBackend().getJingleFile(message, true); + JingleFile outputFile = this.mXmppConnectionService.getFileBackend().getJingleFile(message, false); + outputFile.createNewFile(); + InputStream is = new FileInputStream(inputFile); + OutputStream os = new FileOutputStream(outputFile); + api.executeApiAsync(params, is, os, new IOpenPgpCallback() { + + @Override + public void onReturn(Intent result) { + switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, + OpenPgpApi.RESULT_CODE_ERROR)) { + case OpenPgpApi.RESULT_CODE_SUCCESS: + callback.success(); + break; + case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: + callback.userInputRequried((PendingIntent) result + .getParcelableExtra(OpenPgpApi.RESULT_INTENT)); + break; + case OpenPgpApi.RESULT_CODE_ERROR: + callback.error((OpenPgpError) result + .getParcelableExtra(OpenPgpApi.RESULT_ERROR)); + break; + } + } + }); + } catch (FileNotFoundException e) { + Log.d("xmppService","file not found: "+e.getMessage()); + } catch (IOException e) { + Log.d("xmppService","io exception during file encrypt"); } - message.setEncryptedBody(encryptedMessageBody.toString()); - callback.success(); - return; - case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: - callback.userInputRequried((PendingIntent) result - .getParcelableExtra(OpenPgpApi.RESULT_INTENT)); - return; - case OpenPgpApi.RESULT_CODE_ERROR: - callback.error((OpenPgpError) result - .getParcelableExtra(OpenPgpApi.RESULT_ERROR)); - return; } } - + public long fetchKeyId(Account account, String status, String signature) { if ((signature == null) || (api == null)) { return 0; @@ -130,10 +224,11 @@ public class PgpEngine { return 0; } case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: - Log.d("xmppService","user interaction required"); + Log.d("xmppService","openpgp user interaction requeried"); return 0; case OpenPgpApi.RESULT_CODE_ERROR: - Log.d("xmppService","pgp error"); + Log.d("xmppService","openpgp error: "+((OpenPgpError) result + .getParcelableExtra(OpenPgpApi.RESULT_ERROR)).getMessage()); return 0; } return 0; @@ -174,14 +269,12 @@ public class PgpEngine { }); } - public void hasKey(Account account, long keyId, final OnPgpEngineResult callback) { + public void hasKey(Contact contact, final OnPgpEngineResult callback) { Intent params = new Intent(); params.setAction(OpenPgpApi.ACTION_GET_KEY); - params.putExtra(OpenPgpApi.EXTRA_KEY_ID, keyId); - params.putExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME, account.getJid()); - InputStream is = new ByteArrayInputStream(new byte[0]); - OutputStream os = new ByteArrayOutputStream(); - api.executeApiAsync(params, is, os, new IOpenPgpCallback() { + params.putExtra(OpenPgpApi.EXTRA_KEY_ID, contact.getPgpKeyId()); + params.putExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME, contact.getAccount().getJid()); + api.executeApiAsync(params, null, null, new IOpenPgpCallback() { @Override public void onReturn(Intent result) { @@ -201,4 +294,13 @@ public class PgpEngine { } }); } + + public PendingIntent getIntentForKey(Contact contact) { + Intent params = new Intent(); + params.setAction(OpenPgpApi.ACTION_GET_KEY); + params.putExtra(OpenPgpApi.EXTRA_KEY_ID, contact.getPgpKeyId()); + params.putExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME, contact.getAccount().getJid()); + Intent result = api.executeApi(params, null, null); + return (PendingIntent) result.getParcelableExtra(OpenPgpApi.RESULT_INTENT); + } } diff --git a/src/eu/siacs/conversations/entities/Conversation.java b/src/eu/siacs/conversations/entities/Conversation.java index 0f4d24e5..5674f84a 100644 --- a/src/eu/siacs/conversations/entities/Conversation.java +++ b/src/eu/siacs/conversations/entities/Conversation.java @@ -15,7 +15,6 @@ import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.net.Uri; -import android.util.Log; public class Conversation extends AbstractEntity { @@ -56,7 +55,8 @@ public class Conversation extends AbstractEntity { private transient String otrFingerprint = null; - public int nextMessageEncryption = Message.ENCRYPTION_NONE; + private int nextMessageEncryption = -1; + private String nextMessage; private transient MucOptions mucOptions = null; @@ -237,7 +237,6 @@ public class Conversation extends AbstractEntity { } return this.otrSession; } catch (OtrException e) { - Log.d("xmppServic", "couldnt start otr"); return null; } } @@ -320,4 +319,32 @@ public class Conversation extends AbstractEntity { public String getNextPresence() { return this.nextPresence; } + + public int getLatestEncryption() { + int latestEncryption = this.getLatestMessage().getEncryption(); + if ((latestEncryption == Message.ENCRYPTION_DECRYPTED) || (latestEncryption == Message.ENCRYPTION_DECRYPTION_FAILED)) { + return Message.ENCRYPTION_PGP; + } else { + return latestEncryption; + } + } + + public int getNextEncryption() { + if (this.nextMessageEncryption == -1) { + return this.getLatestEncryption(); + } + return this.nextMessageEncryption; + } + + public void setNextEncryption(int encryption) { + this.nextMessageEncryption = encryption; + } + + public String getNextMessage() { + return this.nextMessage; + } + + public void setNextMessage(String message) { + this.nextMessage = message; + } } diff --git a/src/eu/siacs/conversations/entities/Message.java b/src/eu/siacs/conversations/entities/Message.java index 49ae0265..33f7a8d4 100644 --- a/src/eu/siacs/conversations/entities/Message.java +++ b/src/eu/siacs/conversations/entities/Message.java @@ -1,7 +1,9 @@ package eu.siacs.conversations.entities; +import eu.siacs.conversations.R; import eu.siacs.conversations.xmpp.jingle.JingleConnection; import android.content.ContentValues; +import android.content.Context; import android.database.Cursor; public class Message extends AbstractEntity { @@ -17,7 +19,6 @@ public class Message extends AbstractEntity { public static final int STATUS_SEND = 2; public static final int STATUS_SEND_FAILED = 3; public static final int STATUS_SEND_REJECTED = 4; - public static final int STATUS_PREPARING = 5; public static final int STATUS_OFFERED = 6; public static final int ENCRYPTION_NONE = 0; @@ -104,6 +105,20 @@ public class Message extends AbstractEntity { public String getBody() { return body; } + + public String getReadableBody(Context context) { + if ((encryption == ENCRYPTION_PGP)&&(type == TYPE_TEXT)) { + return ""+context.getText(R.string.encrypted_message_received); + } else if ((encryption == ENCRYPTION_OTR)&&(type == TYPE_IMAGE)) { + return ""+context.getText(R.string.encrypted_image_received); + } else if (encryption == ENCRYPTION_DECRYPTION_FAILED) { + return ""+context.getText(R.string.decryption_failed); + } else if (type == TYPE_IMAGE) { + return ""+context.getText(R.string.image_file); + } else { + return body.trim(); + } + } public long getTimeSent() { return timeSent; diff --git a/src/eu/siacs/conversations/persistance/FileBackend.java b/src/eu/siacs/conversations/persistance/FileBackend.java index c451b906..868e2398 100644 --- a/src/eu/siacs/conversations/persistance/FileBackend.java +++ b/src/eu/siacs/conversations/persistance/FileBackend.java @@ -47,13 +47,22 @@ public class FileBackend { public LruCache<String, Bitmap> getThumbnailCache() { return thumbnailCache; } - + public JingleFile getJingleFile(Message message) { + return getJingleFile(message, true); + } + + public JingleFile getJingleFile(Message message, boolean decrypted) { Conversation conversation = message.getConversation(); String prefix = context.getFilesDir().getAbsolutePath(); String path = prefix + "/" + conversation.getAccount().getJid() + "/" + conversation.getContactJid(); - String filename = message.getUuid() + ".webp"; + String filename; + if ((decrypted)||(message.getEncryption() == Message.ENCRYPTION_NONE)) { + filename = message.getUuid() + ".webp"; + } else { + filename = message.getUuid() + ".webp.pgp"; + } return new JingleFile(path + "/" + filename); } diff --git a/src/eu/siacs/conversations/services/XmppConnectionService.java b/src/eu/siacs/conversations/services/XmppConnectionService.java index 06ba34ab..3581d189 100644 --- a/src/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/eu/siacs/conversations/services/XmppConnectionService.java @@ -47,6 +47,7 @@ import eu.siacs.conversations.xmpp.OnStatusChanged; import eu.siacs.conversations.xmpp.OnTLSExceptionReceived; import eu.siacs.conversations.xmpp.XmppConnection; import eu.siacs.conversations.xmpp.jingle.JingleConnectionManager; +import eu.siacs.conversations.xmpp.jingle.JingleFile; import eu.siacs.conversations.xmpp.jingle.OnJinglePacketReceived; import eu.siacs.conversations.xmpp.jingle.stanzas.JinglePacket; import eu.siacs.conversations.xmpp.stanzas.IqPacket; @@ -92,7 +93,7 @@ public class XmppConnectionService extends Service { private JingleConnectionManager mJingleConnectionManager = new JingleConnectionManager( this); - public OnConversationListChangedListener convChangedListener = null; + private OnConversationListChangedListener convChangedListener = null; private int convChangedListenerCount = 0; private OnAccountListChangedListener accountChangedListener = null; private OnTLSExceptionReceived tlsException = null; @@ -325,7 +326,7 @@ public class XmppConnectionService extends Service { msg = ""; } contact.setPgpKeyId(pgp.fetchKeyId(account,msg,x.getContent())); - Log.d("xmppService","fetched key id for "+contact.getDisplayName()+" was:"+contact.getPgpKeyId()); + Log.d("xmppService",account.getJid()+": fetched key id for "+contact.getJid()+" was:"+contact.getPgpKeyId()); } } replaceContactInConversation(account, @@ -432,7 +433,7 @@ public class XmppConnectionService extends Service { if (this.mPgpEngine == null) { this.mPgpEngine = new PgpEngine(new OpenPgpApi( getApplicationContext(), - pgpServiceConnection.getService())); + pgpServiceConnection.getService()),this); } return mPgpEngine; } else { @@ -445,30 +446,43 @@ public class XmppConnectionService extends Service { return this.fileBackend; } - public void attachImageToConversation(final Conversation conversation, + public Message attachImageToConversation(final Conversation conversation, final String presence, final Uri uri) { + final Message message = new Message(conversation, "",Message.ENCRYPTION_NONE); + message.setPresence(presence); + message.setType(Message.TYPE_IMAGE); + message.setStatus(Message.STATUS_OFFERED); new Thread(new Runnable() { @Override public void run() { - Message message = new Message(conversation, "", - Message.ENCRYPTION_NONE); - message.setPresence(presence); - message.setType(Message.TYPE_IMAGE); - message.setStatus(Message.STATUS_PREPARING); - conversation.getMessages().add(message); - if (convChangedListener != null) { - convChangedListener.onConversationListChanged(); - } getFileBackend().copyImageToPrivateStorage(message, uri); - message.setStatus(Message.STATUS_OFFERED); databaseBackend.createMessage(message); + conversation.getMessages().add(message); if (convChangedListener != null) { convChangedListener.onConversationListChanged(); } sendMessage(message, null); } }).start(); + return message; + } + + public Message attachEncryptedImageToConversation(final Conversation conversation, final String presence, final Uri uri, final OnPgpEngineResult callback) { + Log.d(LOGTAG,"attach encrypted image"); + final Message message = new Message(conversation, "",Message.ENCRYPTION_DECRYPTED); + message.setPresence(presence); + message.setType(Message.TYPE_IMAGE); + message.setStatus(Message.STATUS_OFFERED); + new Thread(new Runnable() { + + @Override + public void run() { + getFileBackend().copyImageToPrivateStorage(message, uri); + getPgpEngine().encrypt(message, callback); + } + }).start(); + return message; } protected Conversation findMuc(String name, Account account) { @@ -754,8 +768,6 @@ public class XmppConnectionService extends Service { addToConversation = true; } else if (message.getEncryption() == Message.ENCRYPTION_PGP) { message.getConversation().endOtrIfNeeded(); - long keyId = message.getConversation().getContact() - .getPgpKeyId(); packet = new MessagePacket(); packet.setType(MessagePacket.TYPE_CHAT); packet.setFrom(message.getConversation().getAccount() @@ -1409,12 +1421,6 @@ public class XmppConnectionService extends Service { }).start(); } - public void updateConversationInGui() { - if (convChangedListener != null) { - convChangedListener.onConversationListChanged(); - } - } - public void sendConversationSubject(Conversation conversation, String subject) { MessagePacket packet = new MessagePacket(); @@ -1480,4 +1486,12 @@ public class XmppConnectionService extends Service { return PreferenceManager .getDefaultSharedPreferences(getApplicationContext()); } + + public void updateUi(Conversation conversation, boolean notify) { + if (convChangedListener != null) { + convChangedListener.onConversationListChanged(); + } else { + UIHelper.updateNotification(getApplicationContext(), getConversations(), conversation, notify); + } + } } diff --git a/src/eu/siacs/conversations/ui/ContactDetailsActivity.java b/src/eu/siacs/conversations/ui/ContactDetailsActivity.java index 1ed3fa13..eaa9b8ee 100644 --- a/src/eu/siacs/conversations/ui/ContactDetailsActivity.java +++ b/src/eu/siacs/conversations/ui/ContactDetailsActivity.java @@ -4,10 +4,14 @@ import java.math.BigInteger; import java.util.Iterator; import java.util.Locale; +import org.openintents.openpgp.util.OpenPgpUtils; + import android.app.AlertDialog; +import android.app.PendingIntent; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; +import android.content.IntentSender.SendIntentException; import android.net.Uri; import android.os.Bundle; import android.provider.ContactsContract.CommonDataKinds; @@ -26,6 +30,7 @@ import android.widget.QuickContactBadge; import android.widget.TextView; import android.widget.Toast; import eu.siacs.conversations.R; +import eu.siacs.conversations.crypto.PgpEngine; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Presences; import eu.siacs.conversations.utils.UIHelper; @@ -252,17 +257,29 @@ public class ContactDetailsActivity extends XmppActivity { key.setText(otrFingerprint); keys.addView(view); } - Log.d("gultsch", "pgp key id " + contact.getPgpKeyId()); if (contact.getPgpKeyId() != 0) { View view = (View) inflater.inflate(R.layout.contact_key, null); TextView key = (TextView) view.findViewById(R.id.key); TextView keyType = (TextView) view.findViewById(R.id.key_type); keyType.setText("PGP Key ID"); - BigInteger bi = new BigInteger("" + contact.getPgpKeyId()); - StringBuilder builder = new StringBuilder(bi.toString(16) - .toUpperCase(Locale.US)); - builder.insert(8, " "); - key.setText(builder.toString()); + key.setText(OpenPgpUtils.convertKeyIdToHex(contact.getPgpKeyId())); + view.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + PgpEngine pgp = activity.xmppConnectionService.getPgpEngine(); + if (pgp!=null) { + PendingIntent intent = pgp.getIntentForKey(contact); + if (intent!=null) { + try { + startIntentSenderForResult(intent.getIntentSender(), 0, null, 0, 0, 0); + } catch (SendIntentException e) { + + } + } + } + } + }); keys.addView(view); } } diff --git a/src/eu/siacs/conversations/ui/ConversationActivity.java b/src/eu/siacs/conversations/ui/ConversationActivity.java index fc19ecc7..234730fc 100644 --- a/src/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/eu/siacs/conversations/ui/ConversationActivity.java @@ -6,21 +6,27 @@ import java.util.ArrayList; import java.util.Hashtable; import java.util.List; +import org.openintents.openpgp.OpenPgpError; + import eu.siacs.conversations.R; +import eu.siacs.conversations.crypto.OnPgpEngineResult; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.utils.ExceptionHelper; import eu.siacs.conversations.utils.UIHelper; +import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.preference.PreferenceManager; import android.app.AlertDialog; import android.app.FragmentTransaction; +import android.app.PendingIntent; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; +import android.content.IntentSender.SendIntentException; import android.content.Intent; import android.content.SharedPreferences; import android.content.res.Resources; @@ -48,6 +54,7 @@ import android.widget.PopupMenu; import android.widget.PopupMenu.OnMenuItemClickListener; import android.widget.TextView; import android.widget.ImageView; +import android.widget.Toast; public class ConversationActivity extends XmppActivity { @@ -58,7 +65,10 @@ public class ConversationActivity extends XmppActivity { public static final int REQUEST_SEND_MESSAGE = 0x75441; public static final int REQUEST_DECRYPT_PGP = 0x76783; - private static final int ATTACH_FILE = 0x48502; + private static final int REQUEST_ATTACH_FILE_DIALOG = 0x48502; + private static final int REQUEST_SEND_PGP_IMAGE = 0x53883; + private static final int REQUEST_ATTACH_FILE = 0x73824; + public static final int REQUEST_ENCRYPT_MESSAGE = 0x378018; protected SlidingPaneLayout spl; @@ -69,6 +79,8 @@ public class ConversationActivity extends XmppActivity { private boolean paneShouldBeOpen = true; private boolean useSubject = true; private ArrayAdapter<Conversation> listAdapter; + + public Message pendingMessage = null; private OnConversationListChangedListener onConvChanged = new OnConversationListChangedListener() { @@ -100,6 +112,7 @@ public class ConversationActivity extends XmppActivity { protected ConversationActivity activity = this; private DisplayMetrics metrics; + private Toast prepareImageToast; public List<Conversation> getConversationList() { return this.conversationList; @@ -166,20 +179,22 @@ public class ConversationActivity extends XmppActivity { Message latestMessage = conv.getLatestMessage(); if (latestMessage.getType() == Message.TYPE_TEXT) { - convLastMsg.setText(conv.getLatestMessage().getBody()); + if ((latestMessage.getEncryption() != Message.ENCRYPTION_PGP)&&(latestMessage.getEncryption() != Message.ENCRYPTION_DECRYPTION_FAILED)) { + convLastMsg.setText(conv.getLatestMessage().getBody()); + } else { + convLastMsg.setText(getText(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_RECIEVED)&&(latestMessage.getStatus() != Message.STATUS_PREPARING)) { + if (latestMessage.getStatus() >= Message.STATUS_RECIEVED) { convLastMsg.setVisibility(View.GONE); imagePreview.setVisibility(View.VISIBLE); loadBitmap(latestMessage, imagePreview); } else { convLastMsg.setVisibility(View.VISIBLE); imagePreview.setVisibility(View.GONE); - if (latestMessage.getStatus() == Message.STATUS_PREPARING) { - convLastMsg.setText(getText(R.string.preparing_image)); - } else if (latestMessage.getStatus() == Message.STATUS_RECEIVED_OFFER) { + if (latestMessage.getStatus() == Message.STATUS_RECEIVED_OFFER) { convLastMsg.setText(getText(R.string.image_offered_for_download)); } else if (latestMessage.getStatus() == Message.STATUS_RECIEVING) { convLastMsg.setText(getText(R.string.receiving_image)); @@ -312,7 +327,96 @@ public class ConversationActivity extends XmppActivity { } return true; } + + private void attachFileDialog() { + selectPresence(getSelectedConversation(), new OnPresenceSelected() { + + @Override + public void onPresenceSelected(boolean success, String presence) { + if (success) { + Intent attachFileIntent = new Intent(); + attachFileIntent.setType("image/*"); + attachFileIntent.setAction(Intent.ACTION_GET_CONTENT); + Intent chooser = Intent.createChooser(attachFileIntent, getString(R.string.attach_file)); + startActivityForResult(chooser, REQUEST_ATTACH_FILE_DIALOG); + } + } + @Override + public void onSendPlainTextInstead() { + + } + },"file"); + } + + private void attachFile() { + final Conversation conversation = getSelectedConversation(); + if (conversation.getNextEncryption() == Message.ENCRYPTION_PGP) { + if (hasPgp()) { + if (conversation.getContact().getPgpKeyId()!=0) { + xmppConnectionService.getPgpEngine().hasKey(conversation.getContact(), new OnPgpEngineResult() { + + @Override + public void userInputRequried(PendingIntent pi) { + ConversationActivity.this.runIntent(pi, REQUEST_ATTACH_FILE); + } + + @Override + public void success() { + attachFileDialog(); + } + + @Override + public void error(OpenPgpError openPgpError) { + // TODO Auto-generated method stub + + } + }); + } else { + final ConversationFragment fragment = (ConversationFragment) getFragmentManager() + .findFragmentByTag("conversation"); + if (fragment != null) { + fragment.showNoPGPKeyDialog(new OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int which) { + conversation.setNextEncryption(Message.ENCRYPTION_NONE); + attachFileDialog(); + } + }); + } + } + } + } else if (getSelectedConversation().getNextEncryption() == Message.ENCRYPTION_NONE) { + attachFileDialog(); + } else { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(getString(R.string.otr_file_transfer)); + builder.setMessage(getString(R.string.otr_file_transfer_msg)); + builder.setNegativeButton(getString(R.string.cancel), null); + if (conversation.getContact().getPgpKeyId()==0) { + builder.setPositiveButton(getString(R.string.send_unencrypted), new OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int which) { + conversation.setNextEncryption(Message.ENCRYPTION_NONE); + attachFile(); + } + }); + } else { + builder.setPositiveButton(getString(R.string.use_pgp_encryption), new OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int which) { + conversation.setNextEncryption(Message.ENCRYPTION_PGP); + attachFile(); + } + }); + } + builder.create().show(); + } + } + @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { @@ -320,25 +424,7 @@ public class ConversationActivity extends XmppActivity { spl.openPane(); break; case R.id.action_attach_file: - selectPresence(getSelectedConversation(), new OnPresenceSelected() { - - @Override - public void onPresenceSelected(boolean success, String presence) { - if (success) { - Intent attachFileIntent = new Intent(); - attachFileIntent.setType("image/*"); - attachFileIntent.setAction(Intent.ACTION_GET_CONTENT); - Intent chooser = Intent.createChooser(attachFileIntent, getString(R.string.attach_file)); - startActivityForResult(chooser, ATTACH_FILE); - } - } - - @Override - public void onSendPlainTextInstead() { - // TODO Auto-generated method stub - - } - },"file"); + attachFile(); break; case R.id.action_add: startActivity(new Intent(this, ContactsActivity.class)); @@ -371,7 +457,7 @@ public class ConversationActivity extends XmppActivity { startActivity(inviteIntent); break; case R.id.action_security: - final Conversation selConv = getSelectedConversation(); + final Conversation conversation = getSelectedConversation(); View menuItemView = findViewById(R.id.action_security); PopupMenu popup = new PopupMenu(this, menuItemView); final ConversationFragment fragment = (ConversationFragment) getFragmentManager() @@ -383,19 +469,25 @@ public class ConversationActivity extends XmppActivity { public boolean onMenuItemClick(MenuItem item) { switch (item.getItemId()) { case R.id.encryption_choice_none: - selConv.nextMessageEncryption = Message.ENCRYPTION_NONE; + conversation.setNextEncryption(Message.ENCRYPTION_NONE); item.setChecked(true); break; case R.id.encryption_choice_otr: - selConv.nextMessageEncryption = Message.ENCRYPTION_OTR; + conversation.setNextEncryption(Message.ENCRYPTION_OTR); item.setChecked(true); break; case R.id.encryption_choice_pgp: - selConv.nextMessageEncryption = Message.ENCRYPTION_PGP; - item.setChecked(true); + if (hasPgp()) { + if (conversation.getAccount().getKeys().has("pgp_signature")) { + conversation.setNextEncryption(Message.ENCRYPTION_PGP); + item.setChecked(true); + } else { + announcePgp(conversation.getAccount(),conversation); + } + } break; default: - selConv.nextMessageEncryption = Message.ENCRYPTION_NONE; + conversation.setNextEncryption(Message.ENCRYPTION_NONE); break; } fragment.updateChatMsgHint(); @@ -403,7 +495,7 @@ public class ConversationActivity extends XmppActivity { } }); popup.inflate(R.menu.encryption_choices); - switch (selConv.nextMessageEncryption) { + switch (conversation.getNextEncryption()) { case Message.ENCRYPTION_NONE: popup.getMenu().findItem(R.id.encryption_choice_none) .setChecked(true); @@ -416,10 +508,6 @@ public class ConversationActivity extends XmppActivity { popup.getMenu().findItem(R.id.encryption_choice_pgp) .setChecked(true); break; - case Message.ENCRYPTION_DECRYPTED: - popup.getMenu().findItem(R.id.encryption_choice_pgp) - .setChecked(true); - break; default: popup.getMenu().findItem(R.id.encryption_choice_none) .setChecked(true); @@ -580,14 +668,57 @@ public class ConversationActivity extends XmppActivity { if (selectedFragment != null) { selectedFragment.hidePgpPassphraseBox(); } - } else if (requestCode == ATTACH_FILE) { - Conversation conversation = getSelectedConversation(); + } else if (requestCode == REQUEST_ATTACH_FILE_DIALOG) { + prepareImageToast = Toast.makeText(getApplicationContext(), getText(R.string.preparing_image), Toast.LENGTH_LONG); + final Conversation conversation = getSelectedConversation(); String presence = conversation.getNextPresence(); - xmppConnectionService.attachImageToConversation(conversation, presence, data.getData()); + if (conversation.getNextEncryption() == Message.ENCRYPTION_NONE) { + prepareImageToast.show(); + xmppConnectionService.attachImageToConversation(conversation, presence, data.getData()); + } else if (conversation.getNextEncryption() == Message.ENCRYPTION_PGP) { + prepareImageToast.show(); + attachPgpFile(conversation,data.getData()); + } else { + Log.d(LOGTAG,"unknown next message encryption: "+conversation.getNextEncryption()); + } + } else if (requestCode == REQUEST_SEND_PGP_IMAGE) { + } else if (requestCode == REQUEST_ATTACH_FILE) { + attachFile(); + } else if (requestCode == REQUEST_ANNOUNCE_PGP) { + announcePgp(getSelectedConversation().getAccount(),getSelectedConversation()); + } else if (requestCode == REQUEST_ENCRYPT_MESSAGE) { + encryptTextMessage(); + } else { + Log.d(LOGTAG,"unknown result code:"+requestCode); } } } + + private void attachPgpFile(Conversation conversation, Uri uri) { + String presence = conversation.getNextPresence(); + pendingMessage = xmppConnectionService.attachEncryptedImageToConversation(conversation, presence, uri, new OnPgpEngineResult() { + + @Override + public void userInputRequried(PendingIntent pi) { + ConversationActivity.this.runIntent(pi, ConversationActivity.REQUEST_SEND_PGP_IMAGE); + } + + @Override + public void success() { + pendingMessage.getConversation().getMessages().add(pendingMessage); + xmppConnectionService.databaseBackend.createMessage(pendingMessage); + xmppConnectionService.sendMessage(pendingMessage, null); + xmppConnectionService.updateUi(pendingMessage.getConversation(), false); + pendingMessage = null; + } + + @Override + public void error(OpenPgpError openPgpError) { + Log.d(LOGTAG,"pgp error"+openPgpError.getMessage()); + } + }); + } public void updateConversationList() { conversationList.clear(); @@ -690,6 +821,15 @@ public class ConversationActivity extends XmppActivity { builder.create().show(); } + public void runIntent(PendingIntent pi, int requestCode) { + try { + this.startIntentSenderForResult(pi.getIntentSender(),requestCode, null, 0, + 0, 0); + } catch (SendIntentException e1) { + Log.d("xmppService","failed to start intent to send message"); + } + } + class BitmapWorkerTask extends AsyncTask<Message, Void, Bitmap> { private final WeakReference<ImageView> imageViewReference; @@ -783,4 +923,36 @@ public class ConversationActivity extends XmppActivity { return bitmapWorkerTaskReference.get(); } } + + public void encryptTextMessage() { + xmppConnectionService.getPgpEngine().encrypt(this.pendingMessage, new OnPgpEngineResult() { + + @Override + public void userInputRequried( + PendingIntent pi) { + activity.runIntent( + pi, + ConversationActivity.REQUEST_SEND_MESSAGE); + } + + @Override + public void success() { + xmppConnectionService.sendMessage(pendingMessage, null); + pendingMessage = null; + ConversationFragment selectedFragment = (ConversationFragment) getFragmentManager() + .findFragmentByTag("conversation"); + if (selectedFragment != null) { + selectedFragment.clearInputField(); + } + } + + @Override + public void error( + OpenPgpError openPgpError) { + // TODO Auto-generated method + // stub + + } + }); + } } diff --git a/src/eu/siacs/conversations/ui/ConversationFragment.java b/src/eu/siacs/conversations/ui/ConversationFragment.java index c2373cf1..6850ac54 100644 --- a/src/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/eu/siacs/conversations/ui/ConversationFragment.java @@ -35,6 +35,8 @@ import android.graphics.Typeface; import android.net.Uri; import android.os.Bundle; import android.preference.PreferenceManager; +import android.text.Editable; +import android.text.Selection; import android.util.DisplayMetrics; import android.util.Log; import android.view.LayoutInflater; @@ -67,7 +69,7 @@ public class ConversationFragment extends Fragment { private String pastedText = null; protected Bitmap selfBitmap; - + private boolean useSubject = true; private IntentSender askForPassphraseIntent = null; @@ -79,10 +81,10 @@ public class ConversationFragment extends Fragment { if (chatMsg.getText().length() < 1) return; Message message = new Message(conversation, chatMsg.getText() - .toString(), conversation.nextMessageEncryption); - if (conversation.nextMessageEncryption == Message.ENCRYPTION_OTR) { + .toString(), conversation.getNextEncryption()); + if (conversation.getNextEncryption() == Message.ENCRYPTION_OTR) { sendOtrMessage(message); - } else if (conversation.nextMessageEncryption == Message.ENCRYPTION_PGP) { + } else if (conversation.getNextEncryption() == Message.ENCRYPTION_PGP) { sendPgpMessage(message); } else { sendPlainTextMessage(message); @@ -129,7 +131,7 @@ public class ConversationFragment extends Fragment { if (conversation.getMode() == Conversation.MODE_MULTI) { chatMsg.setHint(getString(R.string.send_message_to_conference)); } else { - switch (conversation.nextMessageEncryption) { + switch (conversation.getNextEncryption()) { case Message.ENCRYPTION_NONE: chatMsg.setHint(getString(R.string.send_plain_text_message)); break; @@ -139,9 +141,6 @@ public class ConversationFragment extends Fragment { case Message.ENCRYPTION_PGP: chatMsg.setHint(getString(R.string.send_pgp_message)); break; - case Message.ENCRYPTION_DECRYPTED: - chatMsg.setHint(getString(R.string.send_pgp_message)); - break; default: break; } @@ -153,17 +152,13 @@ public class ConversationFragment extends Fragment { ViewGroup container, Bundle savedInstanceState) { final DisplayMetrics metrics = getResources().getDisplayMetrics(); - + this.inflater = inflater; final View view = inflater.inflate(R.layout.fragment_conversation, container, false); chatMsg = (EditText) view.findViewById(R.id.textinput); - - if (pastedText!=null) { - chatMsg.setText(pastedText); - } - + ImageButton sendButton = (ImageButton) view .findViewById(R.id.textSendButton); sendButton.setOnClickListener(this.sendMsgListener); @@ -197,6 +192,155 @@ public class ConversationFragment extends Fragment { } } + private void displayStatus(ViewHolder viewHolder, Message message) { + String filesize = null; + String info = null; + boolean error = false; + if (message.getType() == Message.TYPE_IMAGE) { + String[] fileParams = message.getBody().split(","); + long size = Long.parseLong(fileParams[0]); + filesize = size / 1024 + " KB"; + } + switch (message.getStatus()) { + case Message.STATUS_UNSEND: + info = getString(R.string.sending); + break; + case Message.STATUS_OFFERED: + info = getString(R.string.offering); + break; + case Message.STATUS_SEND_FAILED: + info = getString(R.string.send_failed); + error = true; + break; + case Message.STATUS_SEND_REJECTED: + info = getString(R.string.send_rejected); + error = true; + break; + default: + if ((message.getConversation().getMode() == Conversation.MODE_MULTI) + && (message.getStatus() <= Message.STATUS_RECIEVED)) { + info = message.getCounterpart(); + } + break; + } + if (error) { + viewHolder.time.setTextColor(0xFFe92727); + } else { + viewHolder.time.setTextColor(0xFF8e8e8e); + } + if (message.getEncryption() == Message.ENCRYPTION_NONE) { + viewHolder.indicator.setVisibility(View.GONE); + } else { + viewHolder.indicator.setVisibility(View.VISIBLE); + } + + String formatedTime = UIHelper.readableTimeDifference(message + .getTimeSent()); + if (message.getStatus() <= Message.STATUS_RECIEVED) { + if ((filesize != null) && (info != null)) { + viewHolder.time.setText(filesize + " \u00B7 " + info); + } else if ((filesize == null) && (info != null)) { + viewHolder.time.setText(formatedTime + " \u00B7 " + + info); + } else if ((filesize != null) && (info == null)) { + viewHolder.time.setText(formatedTime + " \u00B7 " + + filesize); + } else { + viewHolder.time.setText(formatedTime); + } + } else { + if ((filesize != null) && (info != null)) { + viewHolder.time.setText(filesize + " \u00B7 " + info); + } else if ((filesize == null) && (info != null)) { + viewHolder.time.setText(info + " \u00B7 " + + formatedTime); + } else if ((filesize != null) && (info == null)) { + viewHolder.time.setText(filesize + " \u00B7 " + + formatedTime); + } else { + viewHolder.time.setText(formatedTime); + } + } + } + + private void displayInfoMessage(ViewHolder viewHolder, int r) { + viewHolder.download_button.setVisibility(View.GONE); + viewHolder.image.setVisibility(View.GONE); + viewHolder.messageBody.setVisibility(View.VISIBLE); + viewHolder.messageBody.setText(getString(r)); + viewHolder.messageBody.setTextColor(0xff33B5E5); + viewHolder.messageBody.setTypeface(null, Typeface.ITALIC); + } + + private void displayDecryptionFailed(ViewHolder viewHolder) { + viewHolder.download_button.setVisibility(View.GONE); + viewHolder.image.setVisibility(View.GONE); + viewHolder.messageBody.setVisibility(View.VISIBLE); + viewHolder.messageBody + .setText(getString(R.string.decryption_failed)); + viewHolder.messageBody.setTextColor(0xFFe92727); + viewHolder.messageBody.setTypeface(null, Typeface.NORMAL); + } + + private void displayTextMessage(ViewHolder viewHolder, String text) { + if (viewHolder.download_button != null) { + viewHolder.download_button.setVisibility(View.GONE); + } + viewHolder.image.setVisibility(View.GONE); + viewHolder.messageBody.setVisibility(View.VISIBLE); + if (text != null) { + viewHolder.messageBody.setText(text.trim()); + } else { + viewHolder.messageBody.setText(""); + } + viewHolder.messageBody.setTextColor(0xff333333); + viewHolder.messageBody.setTypeface(null, Typeface.NORMAL); + } + + private void displayImageMessage(ViewHolder viewHolder, + final Message message) { + if (viewHolder.download_button != null) { + viewHolder.download_button.setVisibility(View.GONE); + } + viewHolder.messageBody.setVisibility(View.GONE); + viewHolder.image.setVisibility(View.VISIBLE); + String[] fileParams = message.getBody().split(","); + if (fileParams.length == 3) { + double target = metrics.density * 288; + int w = Integer.parseInt(fileParams[1]); + int h = Integer.parseInt(fileParams[2]); + int scalledW; + int scalledH; + if (w <= h) { + scalledW = (int) (w / ((double) h / target)); + scalledH = (int) target; + } else { + scalledW = (int) target; + scalledH = (int) (h / ((double) w / target)); + } + viewHolder.image + .setLayoutParams(new LinearLayout.LayoutParams( + scalledW, scalledH)); + } + activity.loadBitmap(message, viewHolder.image); + viewHolder.image.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + Uri uri = Uri + .parse("content://eu.siacs.conversations.images/" + + message.getConversationUuid() + + "/" + + message.getUuid()); + Log.d("xmppService", + "staring intent with uri:" + uri.toString()); + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setDataAndType(uri, "image/*"); + startActivity(intent); + } + }); + } + @Override public View getView(int position, View view, ViewGroup parent) { final Message item = getItem(position); @@ -217,14 +361,18 @@ public class ConversationFragment extends Fragment { R.layout.message_recieved, null); viewHolder.contact_picture = (ImageView) view .findViewById(R.id.message_photo); - - viewHolder.download_button = (Button) view.findViewById(R.id.download_button); - + + 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().getName(useSubject), item - .getConversation().getContact(), + viewHolder.contact_picture + .setImageBitmap(mBitmapCache.get( + item.getConversation().getName( + useSubject), item + .getConversation() + .getContact(), getActivity() .getApplicationContext())); @@ -234,8 +382,10 @@ public class ConversationFragment extends Fragment { viewHolder = null; break; } - viewHolder.indicator = (ImageView) view.findViewById(R.id.security_indicator); - viewHolder.image = (ImageView) view.findViewById(R.id.message_image); + viewHolder.indicator = (ImageView) view + .findViewById(R.id.security_indicator); + viewHolder.image = (ImageView) view + .findViewById(R.id.message_image); viewHolder.messageBody = (TextView) view .findViewById(R.id.message_body); viewHolder.time = (TextView) view @@ -244,156 +394,70 @@ public class ConversationFragment extends Fragment { } else { viewHolder = (ViewHolder) view.getTag(); } - + if (type == RECIEVED) { if (item.getConversation().getMode() == Conversation.MODE_MULTI) { if (item.getCounterpart() != null) { - viewHolder.contact_picture.setImageBitmap(mBitmapCache - .get(item.getCounterpart(), null, + viewHolder.contact_picture + .setImageBitmap(mBitmapCache.get(item + .getCounterpart(), null, getActivity() .getApplicationContext())); } else { - viewHolder.contact_picture.setImageBitmap(mBitmapCache - .get(item.getConversation().getName(useSubject), - null, getActivity() + viewHolder.contact_picture + .setImageBitmap(mBitmapCache.get( + item.getConversation().getName( + useSubject), null, + getActivity() .getApplicationContext())); } } } - - if (item.getEncryption() == Message.ENCRYPTION_NONE) { - viewHolder.indicator.setVisibility(View.GONE); - } else { - viewHolder.indicator.setVisibility(View.VISIBLE); - } - - String filesize = ""; - + if (item.getType() == Message.TYPE_IMAGE) { - String[] fileParams = item.getBody().split(","); - if ((fileParams.length>=1)&&(item.getStatus() != Message.STATUS_PREPARING)) { - long size = Long.parseLong(fileParams[0]); - filesize = size/1024+" KB \u00B7 "; - } - if ((item.getStatus() == Message.STATUS_PREPARING)||(item.getStatus() == Message.STATUS_RECIEVING)) { - viewHolder.image.setVisibility(View.GONE); - viewHolder.messageBody.setVisibility(View.VISIBLE); - if (item.getStatus() == Message.STATUS_PREPARING) { - viewHolder.messageBody.setText(getString(R.string.preparing_image)); - } else if (item.getStatus() == Message.STATUS_RECIEVING) { - viewHolder.download_button.setVisibility(View.GONE); - viewHolder.messageBody.setText(getString(R.string.receiving_image)); - } - viewHolder.messageBody.setTextColor(0xff33B5E5); - viewHolder.messageBody.setTypeface(null,Typeface.ITALIC); + if (item.getStatus() == Message.STATUS_RECIEVING) { + displayInfoMessage(viewHolder, R.string.receiving_image); } else if (item.getStatus() == Message.STATUS_RECEIVED_OFFER) { viewHolder.image.setVisibility(View.GONE); viewHolder.messageBody.setVisibility(View.GONE); viewHolder.download_button.setVisibility(View.VISIBLE); - viewHolder.download_button.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - JingleConnection connection = item.getJingleConnection(); - if (connection!=null) { - connection.accept(); - } else { - Log.d("xmppService","attached jingle connection was null"); - } - } - }); + viewHolder.download_button + .setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + JingleConnection connection = item + .getJingleConnection(); + if (connection != null) { + connection.accept(); + } else { + Log.d("xmppService", + "attached jingle connection was null"); + } + } + }); + } else if ((item.getEncryption() == Message.ENCRYPTION_DECRYPTED) + || (item.getEncryption() == Message.ENCRYPTION_NONE)) { + displayImageMessage(viewHolder, item); + } else if (item.getEncryption() == Message.ENCRYPTION_PGP) { + displayInfoMessage(viewHolder, + R.string.encrypted_message); } else { - viewHolder.messageBody.setVisibility(View.GONE); - viewHolder.image.setVisibility(View.VISIBLE); - if (fileParams.length==3) { - double target = metrics.density * 288; - int w = Integer.parseInt(fileParams[1]); - int h = Integer.parseInt(fileParams[2]); - int scalledW; - int scalledH; - if (w <= h) { - scalledW = (int) (w / ((double) h / target)); - scalledH = (int) target; - } else { - scalledW = (int) target; - scalledH = (int) (h / ((double) w / target)); - } - viewHolder.image.setLayoutParams(new LinearLayout.LayoutParams(scalledW, scalledH)); - } else { - Log.d("xmppService","message body has less than 3 params"); - } - activity.loadBitmap(item, viewHolder.image); - viewHolder.image.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - Uri uri = Uri.parse("content://eu.siacs.conversations.images/"+item.getConversationUuid()+"/"+item.getUuid()); - Log.d("xmppService","staring intent with uri:"+uri.toString()); - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setDataAndType(uri, "image/*"); - startActivity(intent); - } - }); + displayDecryptionFailed(viewHolder); } } else { - viewHolder.image.setVisibility(View.GONE); - viewHolder.messageBody.setVisibility(View.VISIBLE); - String body = item.getBody(); - if (body != null) { - if (item.getEncryption() == Message.ENCRYPTION_PGP) { - viewHolder.messageBody - .setText(getString(R.string.encrypted_message)); - viewHolder.messageBody.setTextColor(0xff33B5E5); - viewHolder.messageBody.setTypeface(null, - Typeface.ITALIC); - } else if (item.getEncryption() == Message.ENCRYPTION_DECRYPTION_FAILED) { - viewHolder.messageBody.setText(getString(R.string.decryption_failed)); - viewHolder.messageBody.setTextColor(0xFFe92727); - viewHolder.messageBody.setTypeface(null,Typeface.NORMAL); - } else { - viewHolder.messageBody.setText(body.trim()); - viewHolder.messageBody.setTextColor(0xff333333); - viewHolder.messageBody.setTypeface(null, - Typeface.NORMAL); - } - } - } - switch (item.getStatus()) { - case Message.STATUS_UNSEND: - viewHolder.time.setTypeface(null, Typeface.ITALIC); - viewHolder.time.setTextColor(0xFF8e8e8e); - viewHolder.time.setText(filesize+"sending\u2026"); - break; - case Message.STATUS_OFFERED: - viewHolder.time.setTypeface(null, Typeface.ITALIC); - viewHolder.time.setTextColor(0xFF8e8e8e); - viewHolder.time.setText(filesize+"offering\u2026"); - break; - case Message.STATUS_SEND_FAILED: - viewHolder.time.setText(filesize+getString(R.string.send_failed) + " \u00B7 " + UIHelper.readableTimeDifference(item - .getTimeSent())); - viewHolder.time.setTextColor(0xFFe92727); - viewHolder.time.setTypeface(null,Typeface.NORMAL); - break; - case Message.STATUS_SEND_REJECTED: - viewHolder.time.setText(filesize+getString(R.string.send_rejected)); - viewHolder.time.setTextColor(0xFFe92727); - viewHolder.time.setTypeface(null,Typeface.NORMAL); - break; - default: - viewHolder.time.setTypeface(null, Typeface.NORMAL); - viewHolder.time.setTextColor(0xFF8e8e8e); - if (item.getConversation().getMode() == Conversation.MODE_SINGLE) { - viewHolder.time.setText(filesize+UIHelper - .readableTimeDifference(item.getTimeSent())); + if (item.getEncryption() == Message.ENCRYPTION_PGP) { + displayInfoMessage(viewHolder, + R.string.encrypted_message); + } else if (item.getEncryption() == Message.ENCRYPTION_DECRYPTION_FAILED) { + displayDecryptionFailed(viewHolder); } else { - viewHolder.time.setText(item.getCounterpart() - + " \u00B7 " - + UIHelper.readableTimeDifference(item - .getTimeSent())); + displayTextMessage(viewHolder, item.getBody()); } - break; } + + displayStatus(viewHolder, item); + return view; } }; @@ -417,43 +481,56 @@ public class ConversationFragment extends Fragment { public void onStart() { super.onStart(); this.activity = (ConversationActivity) getActivity(); - SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity); + SharedPreferences preferences = PreferenceManager + .getDefaultSharedPreferences(activity); this.useSubject = preferences.getBoolean("use_subject_in_muc", true); if (activity.xmppConnectionServiceBound) { this.onBackendConnected(); } } + @Override + public void onStop() { + super.onStop(); + if (this.conversation!=null) { + this.conversation.setNextMessage(chatMsg.getText().toString()); + } + } + public void onBackendConnected() { this.conversation = activity.getSelectedConversation(); if (this.conversation == null) { return; } + if (this.pastedText == null) { + this.chatMsg.setText(conversation.getNextMessage()); + } else { + chatMsg.setText(conversation.getNextMessage() + " " + pastedText); + pastedText = null; + } + int position = chatMsg.length(); + Editable etext = chatMsg.getText(); + Selection.setSelection(etext, position); this.selfBitmap = findSelfPicture(); updateMessages(); - // rendering complete. now go tell activity to close pane if (activity.getSlidingPaneLayout().isSlideable()) { if (!activity.shouldPaneBeOpen()) { activity.getSlidingPaneLayout().closePane(); activity.getActionBar().setDisplayHomeAsUpEnabled(true); - activity.getActionBar().setTitle(conversation.getName(useSubject)); + activity.getActionBar().setTitle( + conversation.getName(useSubject)); activity.invalidateOptionsMenu(); } } - if (queuedPqpMessage != null) { - this.conversation.nextMessageEncryption = Message.ENCRYPTION_PGP; - Message message = new Message(conversation, queuedPqpMessage, - Message.ENCRYPTION_PGP); - sendPgpMessage(message); - } if (conversation.getMode() == Conversation.MODE_MULTI) { activity.xmppConnectionService .setOnRenameListener(new OnRenameListener() { @Override public void onRename(final boolean success) { - activity.xmppConnectionService.updateConversation(conversation); + activity.xmppConnectionService + .updateConversation(conversation); getActivity().runOnUiThread(new Runnable() { @Override @@ -464,7 +541,8 @@ public class ConversationFragment extends Fragment { getString(R.string.your_nick_has_been_changed), Toast.LENGTH_SHORT).show(); } else { - Toast.makeText(getActivity(), + Toast.makeText( + getActivity(), getString(R.string.nick_in_use), Toast.LENGTH_SHORT).show(); } @@ -474,43 +552,44 @@ public class ConversationFragment extends Fragment { }); } } - + private void decryptMessage(final Message message) { - Log.d("xmppService","called to decrypt"); PgpEngine engine = activity.xmppConnectionService.getPgpEngine(); - if (engine!=null) { - engine.decrypt(message,new OnPgpEngineResult() { - + if (engine != null) { + engine.decrypt(message, new OnPgpEngineResult() { + @Override public void userInputRequried(PendingIntent pi) { askForPassphraseIntent = pi.getIntentSender(); pgpInfo.setVisibility(View.VISIBLE); } - + @Override public void success() { - Log.d("xmppService","successfully decrypted"); - activity.xmppConnectionService.databaseBackend.updateMessage(message); + activity.xmppConnectionService.databaseBackend + .updateMessage(message); updateMessages(); } - + @Override public void error(OpenPgpError openPgpError) { - Log.d("xmppService","decryption error"+openPgpError.getMessage()); + Log.d("xmppService", + "decryption error" + openPgpError.getMessage()); message.setEncryption(Message.ENCRYPTION_DECRYPTION_FAILED); - //updateMessages(); + // updateMessages(); } }); } else { - Log.d("xmppService","engine was null"); + pgpInfo.setVisibility(View.VISIBLE); } } - + public void updateMessages() { ConversationActivity activity = (ConversationActivity) getActivity(); if (this.conversation != null) { for (Message message : this.conversation.getMessages()) { - if (message.getEncryption() == Message.ENCRYPTION_PGP) { + if ((message.getEncryption() == Message.ENCRYPTION_PGP) + && (message.getStatus() == Message.STATUS_RECIEVED)) { decryptMessage(message); break; } @@ -520,14 +599,7 @@ public class ConversationFragment extends Fragment { this.messageListAdapter.notifyDataSetChanged(); if (conversation.getMode() == Conversation.MODE_SINGLE) { if (messageList.size() >= 1) { - int latestEncryption = this.conversation.getLatestMessage() - .getEncryption(); - if ((latestEncryption == Message.ENCRYPTION_DECRYPTED)||(latestEncryption == Message.ENCRYPTION_DECRYPTION_FAILED)) { - conversation.nextMessageEncryption = Message.ENCRYPTION_PGP; - } else { - conversation.nextMessageEncryption = latestEncryption; - } - makeFingerprintWarning(latestEncryption); + makeFingerprintWarning(conversation.getLatestEncryption()); } } else { if (conversation.getMucOptions().getError() != 0) { @@ -594,88 +666,61 @@ public class ConversationFragment extends Fragment { } protected void sendPgpMessage(final Message message) { - ConversationActivity activity = (ConversationActivity) getActivity(); + activity.pendingMessage = message; + final ConversationActivity activity = (ConversationActivity) getActivity(); final XmppConnectionService xmppService = activity.xmppConnectionService; final Contact contact = message.getConversation().getContact(); - final Account account = message.getConversation().getAccount(); if (activity.hasPgp()) { if (contact.getPgpKeyId() != 0) { - xmppService.getPgpEngine().hasKey(account,contact.getPgpKeyId(), new OnPgpEngineResult() { - - @Override - public void userInputRequried(PendingIntent pi) { - Log.d("xmppService","hasKey returned user input required"); - try { - getActivity().startIntentSenderForResult(pi.getIntentSender(), - ConversationActivity.REQUEST_SEND_MESSAGE, null, 0, - 0, 0); - } catch (SendIntentException e1) { - Log.d("xmppService","failed to start intent to send message"); - } - } - - @Override - public void success() { - Log.d("xmppService","hasKey returned success"); - xmppService.getPgpEngine().encrypt(account, contact.getPgpKeyId(), message,new OnPgpEngineResult() { - + xmppService.getPgpEngine().hasKey(contact, + new OnPgpEngineResult() { + @Override public void userInputRequried(PendingIntent pi) { - try { - getActivity().startIntentSenderForResult(pi.getIntentSender(), - ConversationActivity.REQUEST_SEND_MESSAGE, null, 0, - 0, 0); - } catch (SendIntentException e1) { - Log.d("xmppService","failed to start intent to send message"); - } + activity.runIntent( + pi, + ConversationActivity.REQUEST_ENCRYPT_MESSAGE); } - + @Override public void success() { - xmppService.sendMessage(message, null); - chatMsg.setText(""); + activity.encryptTextMessage(); } - + @Override public void error(OpenPgpError openPgpError) { - // TODO Auto-generated method stub - + Log.d("xmppService", "openpgp error" + + openPgpError.getMessage()); } }); - } - + + } else { + showNoPGPKeyDialog(new DialogInterface.OnClickListener() { + @Override - public void error(OpenPgpError openPgpError) { - Log.d("xmppService","openpgp error"+openPgpError.getMessage()); + public void onClick(DialogInterface dialog, + int which) { + conversation + .setNextEncryption(Message.ENCRYPTION_NONE); + message.setEncryption(Message.ENCRYPTION_NONE); + xmppService.sendMessage(message, null); + chatMsg.setText(""); } }); - - - - - } else { - AlertDialog.Builder builder = new AlertDialog.Builder( - getActivity()); - builder.setTitle("No openPGP key found"); - builder.setIconAttribute(android.R.attr.alertDialogIcon); - builder.setMessage("There is no openPGP key associated with this contact"); - builder.setNegativeButton("Cancel", null); - builder.setPositiveButton("Send plain text", - new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, - int which) { - conversation.nextMessageEncryption = Message.ENCRYPTION_NONE; - message.setEncryption(Message.ENCRYPTION_NONE); - xmppService.sendMessage(message, null); - chatMsg.setText(""); - } - }); - builder.create().show(); } } } + + public void showNoPGPKeyDialog(DialogInterface.OnClickListener listener) { + AlertDialog.Builder builder = new AlertDialog.Builder( + getActivity()); + builder.setTitle(getString(R.string.no_pgp_key)); + builder.setIconAttribute(android.R.attr.alertDialogIcon); + builder.setMessage(getText(R.string.contact_has_no_pgp_key)); + builder.setNegativeButton(getString(R.string.cancel), null); + builder.setPositiveButton(getString(R.string.send_unencrypted),listener); + builder.create().show(); + } protected void sendOtrMessage(final Message message) { ConversationActivity activity = (ConversationActivity) getActivity(); @@ -684,23 +729,25 @@ public class ConversationFragment extends Fragment { activity.xmppConnectionService.sendMessage(message, null); chatMsg.setText(""); } else { - activity.selectPresence(message.getConversation(), new OnPresenceSelected() { - - @Override - public void onPresenceSelected(boolean success, String presence) { - if (success) { - xmppService.sendMessage(message,presence); - chatMsg.setText(""); - } - } + activity.selectPresence(message.getConversation(), + new OnPresenceSelected() { - @Override - public void onSendPlainTextInstead() { - message.setEncryption(Message.ENCRYPTION_NONE); - xmppService.sendMessage(message,null); - chatMsg.setText(""); - } - },"otr"); + @Override + public void onPresenceSelected(boolean success, + String presence) { + if (success) { + xmppService.sendMessage(message, presence); + chatMsg.setText(""); + } + } + + @Override + public void onSendPlainTextInstead() { + message.setEncryption(Message.ENCRYPTION_NONE); + xmppService.sendMessage(message, null); + chatMsg.setText(""); + } + }, "otr"); } } @@ -724,8 +771,9 @@ public class ConversationFragment extends Fragment { return bitmaps.get(name); } else { Bitmap bm; - if (contact != null){ - bm = UIHelper.getContactPicture(contact, 48, context, false); + if (contact != null) { + bm = UIHelper + .getContactPicture(contact, 48, context, false); } else { bm = UIHelper.getContactPicture(name, 48, context, false); } @@ -735,71 +783,11 @@ public class ConversationFragment extends Fragment { } } - /*class DecryptMessage extends AsyncTask<Message, Void, Boolean> { - - @Override - protected Boolean doInBackground(Message... params) { - final ConversationActivity activity = (ConversationActivity) getActivity(); - askForPassphraseIntent = null; - for (int i = 0; i < params.length; ++i) { - if (params[i].getEncryption() == Message.ENCRYPTION_PGP) { - String body = params[i].getBody(); - String decrypted = null; - if (activity == null) { - return false; - } else if (!activity.xmppConnectionServiceBound) { - return false; - } - try { - decrypted = activity.xmppConnectionService - .getPgpEngine().decrypt(conversation.getAccount(),body); - } catch (UserInputRequiredException e) { - askForPassphraseIntent = e.getPendingIntent() - .getIntentSender(); - activity.runOnUiThread(new Runnable() { - - @Override - public void run() { - pgpInfo.setVisibility(View.VISIBLE); - } - }); - - return false; - - } catch (OpenPgpException e) { - Log.d("gultsch", "error decrypting pgp"); - } - if (decrypted != null) { - params[i].setBody(decrypted); - params[i].setEncryption(Message.ENCRYPTION_DECRYPTED); - activity.xmppConnectionService.updateMessage(params[i]); - } - if (activity != null) { - activity.runOnUiThread(new Runnable() { - - @Override - public void run() { - messageListAdapter.notifyDataSetChanged(); - } - }); - } - } - if (activity != null) { - activity.runOnUiThread(new Runnable() { - - @Override - public void run() { - activity.updateConversationList(); - } - }); - } - } - return true; - } - - }*/ - public void setText(String text) { this.pastedText = text; } + + public void clearInputField() { + this.chatMsg.setText(""); + } } diff --git a/src/eu/siacs/conversations/ui/ManageAccountActivity.java b/src/eu/siacs/conversations/ui/ManageAccountActivity.java index db0a72b6..0a1cb5cd 100644 --- a/src/eu/siacs/conversations/ui/ManageAccountActivity.java +++ b/src/eu/siacs/conversations/ui/ManageAccountActivity.java @@ -38,8 +38,6 @@ import android.widget.ListView; import android.widget.TextView; public class ManageAccountActivity extends XmppActivity { - - public static final int REQUEST_ANNOUNCE_PGP = 0x73731; protected boolean isActionMode = false; protected ActionMode actionMode; @@ -281,7 +279,7 @@ public class ManageAccountActivity extends XmppActivity { } else if (item.getItemId()==R.id.mgmt_account_announce_pgp) { if (activity.hasPgp()) { mode.finish(); - announcePgp(); + announcePgp(selectedAccountForActionMode,null); } } else if (item.getItemId() == R.id.mgmt_otr_key) { AlertDialog.Builder builder = new AlertDialog.Builder(activity); @@ -290,7 +288,10 @@ public class ManageAccountActivity extends XmppActivity { View view = (View) getLayoutInflater().inflate(R.layout.otr_fingerprint, null); if (fingerprintTxt!=null) { TextView fingerprint = (TextView) view.findViewById(R.id.otr_fingerprint); + TextView noFingerprintView = (TextView) view.findViewById(R.id.otr_no_fingerprint); fingerprint.setText(fingerprintTxt); + fingerprint.setVisibility(View.VISIBLE); + noFingerprintView.setVisibility(View.GONE); } builder.setView(view); builder.setPositiveButton("Done", null); @@ -361,33 +362,6 @@ public class ManageAccountActivity extends XmppActivity { } }); } - - private void announcePgp() { - final Account account = selectedAccountForActionMode; - xmppConnectionService.getPgpEngine().generateSignature(account, "online", new OnPgpEngineResult() { - - @Override - public void userInputRequried(PendingIntent pi) { - try { - startIntentSenderForResult(pi.getIntentSender(), REQUEST_ANNOUNCE_PGP, null, 0, 0, 0); - } catch (SendIntentException e) { - Log.d("xmppService","coulnd start intent for pgp anncouncment"); - } - } - - @Override - public void success() { - xmppConnectionService.databaseBackend.updateAccount(account); - xmppConnectionService.sendPgpPresence(account, account.getPgpSignature()); - } - - @Override - public void error(OpenPgpError openPgpError) { - // TODO Auto-generated method stub - - } - }); - } @Override protected void onStop() { @@ -487,8 +461,8 @@ public class ManageAccountActivity extends XmppActivity { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK) { if (requestCode == REQUEST_ANNOUNCE_PGP) { - announcePgp(); - } + announcePgp(selectedAccountForActionMode,null); + } } } } diff --git a/src/eu/siacs/conversations/ui/XmppActivity.java b/src/eu/siacs/conversations/ui/XmppActivity.java index 70c4614d..55dcecc9 100644 --- a/src/eu/siacs/conversations/ui/XmppActivity.java +++ b/src/eu/siacs/conversations/ui/XmppActivity.java @@ -1,28 +1,38 @@ package eu.siacs.conversations.ui; +import org.openintents.openpgp.OpenPgpError; + import eu.siacs.conversations.R; +import eu.siacs.conversations.crypto.OnPgpEngineResult; +import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Conversation; +import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.services.XmppConnectionService.XmppConnectionBinder; import eu.siacs.conversations.utils.ExceptionHelper; import android.app.Activity; import android.app.AlertDialog; +import android.app.PendingIntent; import android.app.AlertDialog.Builder; import android.content.ComponentName; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; +import android.content.IntentSender.SendIntentException; import android.content.Intent; import android.content.ServiceConnection; import android.net.Uri; import android.os.Bundle; import android.os.IBinder; +import android.util.Log; import android.view.MenuItem; import android.view.View; import android.view.inputmethod.InputMethodManager; public abstract class XmppActivity extends Activity { + public static final int REQUEST_ANNOUNCE_PGP = 0x73731; + protected final static String LOGTAG = "xmppService"; public XmppConnectionService xmppConnectionService; @@ -152,4 +162,33 @@ public abstract class XmppActivity extends Activity { | Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(viewConversationIntent); } + + protected void announcePgp(final Account account, final Conversation conversation) { + xmppConnectionService.getPgpEngine().generateSignature(account, "online", new OnPgpEngineResult() { + + @Override + public void userInputRequried(PendingIntent pi) { + try { + startIntentSenderForResult(pi.getIntentSender(), REQUEST_ANNOUNCE_PGP, null, 0, 0, 0); + } catch (SendIntentException e) { + Log.d("xmppService","coulnd start intent for pgp anncouncment"); + } + } + + @Override + public void success() { + xmppConnectionService.databaseBackend.updateAccount(account); + xmppConnectionService.sendPgpPresence(account, account.getPgpSignature()); + if (conversation!=null) { + conversation.setNextEncryption(Message.ENCRYPTION_PGP); + } + } + + @Override + public void error(OpenPgpError openPgpError) { + // TODO Auto-generated method stub + + } + }); + } } diff --git a/src/eu/siacs/conversations/utils/MessageParser.java b/src/eu/siacs/conversations/utils/MessageParser.java index 568386d5..52b18f66 100644 --- a/src/eu/siacs/conversations/utils/MessageParser.java +++ b/src/eu/siacs/conversations/utils/MessageParser.java @@ -77,9 +77,7 @@ public class MessageParser { .sendMessagePacket(outPacket); } } - if (service.convChangedListener!=null) { - service.convChangedListener.onConversationListChanged(); - } + service.updateUi(conversation, false); } else if ((before != after) && (after == SessionStatus.FINISHED)) { conversation.resetOtrSession(); Log.d(LOGTAG,"otr session stoped"); @@ -101,7 +99,7 @@ public class MessageParser { Conversation conversation = service.findOrCreateConversation(account, fromParts[0],true); if (packet.hasChild("subject")) { conversation.getMucOptions().setSubject(packet.findChild("subject").getContent()); - service.updateConversationInGui(); + service.updateUi(conversation, false); return null; } if ((fromParts.length == 1)) { @@ -118,7 +116,6 @@ public class MessageParser { public static Message parseCarbonMessage(MessagePacket packet, Account account, XmppConnectionService service) { - // TODO Auto-generated method stub int status; String fullJid; Element forwarded; diff --git a/src/eu/siacs/conversations/utils/UIHelper.java b/src/eu/siacs/conversations/utils/UIHelper.java index 1c52ff0b..8baa3c25 100644 --- a/src/eu/siacs/conversations/utils/UIHelper.java +++ b/src/eu/siacs/conversations/utils/UIHelper.java @@ -389,7 +389,7 @@ public class UIHelper { context, true)); mBuilder.setContentTitle(conversation.getName(useSubject)); if (notify) { - mBuilder.setTicker(conversation.getLatestMessage().getBody().trim()); + mBuilder.setTicker(conversation.getLatestMessage().getReadableBody(context)); } StringBuilder bigText = new StringBuilder(); List<Message> messages = conversation.getMessages(); @@ -397,10 +397,10 @@ public class UIHelper { for (int i = messages.size() - 1; i >= 0; --i) { if (!messages.get(i).isRead()) { if (i == messages.size() - 1) { - firstLine = messages.get(i).getBody().trim(); + firstLine = messages.get(i).getReadableBody(context); bigText.append(firstLine); } else { - firstLine = messages.get(i).getBody().trim(); + firstLine = messages.get(i).getReadableBody(context); bigText.insert(0, firstLine + "\n"); } } else { @@ -422,7 +422,7 @@ public class UIHelper { names.append(unread.get(i).getName(useSubject)); } style.addLine(Html.fromHtml("<b>" + unread.get(i).getName(useSubject) - + "</b> " + unread.get(i).getLatestMessage().getBody().trim())); + + "</b> " + unread.get(i).getLatestMessage().getReadableBody(context))); } mBuilder.setContentTitle(unread.size() + " unread Conversations"); mBuilder.setContentText(names.toString()); diff --git a/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java index 3a20b87f..3c9120ec 100644 --- a/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -67,7 +67,9 @@ public class JingleConnection { @Override public void onIqPacketReceived(Account account, IqPacket packet) { if (packet.getType() == IqPacket.TYPE_ERROR) { - mXmppConnectionService.markMessage(message, Message.STATUS_SEND_FAILED); + if (initiator.equals(account.getFullJid())) { + mXmppConnectionService.markMessage(message, Message.STATUS_SEND_FAILED); + } status = STATUS_FAILED; } } @@ -81,6 +83,7 @@ public class JingleConnection { sendSuccess(); if (acceptedAutomatically) { message.markUnread(); + JingleConnection.this.mXmppConnectionService.updateUi(message.getConversation(), true); } BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; @@ -91,7 +94,7 @@ public class JingleConnection { mXmppConnectionService.databaseBackend.createMessage(message); mXmppConnectionService.markMessage(message, Message.STATUS_RECIEVED); } - Log.d("xmppService","sucessfully transmitted file. sha1:"+file.getSha1Sum()+" "+message.getBody()); + Log.d("xmppService","sucessfully transmitted file:"+file.getName()+" encryption:"+message.getEncryption()); } }; @@ -226,7 +229,6 @@ public class JingleConnection { this.mergeCandidates(JingleCandidate.parse(content.socks5transport().getChildren())); this.fileOffer = packet.getJingleContent().getFileOffer(); if (fileOffer!=null) { - this.file = this.mXmppConnectionService.getFileBackend().getJingleFile(message); Element fileSize = fileOffer.findChild("size"); Element fileNameElement = fileOffer.findChild("name"); if (fileNameElement!=null) { @@ -243,20 +245,20 @@ public class JingleConnection { } } if (supportedFile) { - this.file.setExpectedSize(Long.parseLong(fileSize.getContent())); - message.setBody(""+this.file.getExpectedSize()); + long size = Long.parseLong(fileSize.getContent()); + message.setBody(""+size); conversation.getMessages().add(message); - if (this.file.getExpectedSize()<=this.mJingleConnectionManager.getAutoAcceptFileSize()) { + if (size<=this.mJingleConnectionManager.getAutoAcceptFileSize()) { Log.d("xmppService","auto accepting file from "+packet.getFrom()); this.acceptedAutomatically = true; this.sendAccept(); } else { message.markUnread(); - Log.d("xmppService","not auto accepting new file offer with size: "+this.file.getExpectedSize()+" allowed size:"+this.mJingleConnectionManager.getAutoAcceptFileSize()); - if (this.mXmppConnectionService.convChangedListener!=null) { - this.mXmppConnectionService.convChangedListener.onConversationListChanged(); - } + Log.d("xmppService","not auto accepting new file offer with size: "+size+" allowed size:"+this.mJingleConnectionManager.getAutoAcceptFileSize()); + this.mXmppConnectionService.updateUi(conversation, true); } + this.file = this.mXmppConnectionService.getFileBackend().getJingleFile(message,false); + this.file.setExpectedSize(size); } else { this.sendCancel(); } @@ -273,7 +275,7 @@ public class JingleConnection { Content content = new Content(this.contentCreator,this.contentName); if (message.getType() == Message.TYPE_IMAGE) { content.setTransportId(this.transportId); - this.file = this.mXmppConnectionService.getFileBackend().getJingleFile(message); + this.file = this.mXmppConnectionService.getFileBackend().getJingleFile(message,false); content.setFileOffer(this.file); this.transportId = this.mJingleConnectionManager.nextRandomId(); content.setTransportId(this.transportId); |