refactored file download status. make image http download available for carbon copied (sent) messages as well

This commit is contained in:
iNPUTmice 2014-10-15 19:32:12 +02:00
parent 1927a3d99c
commit cb4069f0f2
24 changed files with 276 additions and 213 deletions

View file

@ -46,6 +46,14 @@
android:textIsSelectable="true" android:textIsSelectable="true"
android:textSize="?attr/TextSizeBody" /> 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 <LinearLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View file

@ -76,7 +76,8 @@ public class PgpEngine {
case OpenPgpApi.RESULT_CODE_ERROR: case OpenPgpApi.RESULT_CODE_ERROR:
OpenPgpError error = result OpenPgpError error = result
.getParcelableExtra(OpenPgpApi.RESULT_ERROR); .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); callback.error(R.string.openpgp_error, message);
return; return;
default: default:
@ -110,7 +111,8 @@ public class PgpEngine {
+ ',' + imageWidth + ',' + imageHeight); + ',' + imageWidth + ',' + imageHeight);
message.setEncryption(Message.ENCRYPTION_DECRYPTED); message.setEncryption(Message.ENCRYPTION_DECRYPTED);
PgpEngine.this.mXmppConnectionService PgpEngine.this.mXmppConnectionService
.updateMessage(message);; .updateMessage(message);
;
callback.success(message); callback.success(message);
return; return;
case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED:

View file

@ -143,7 +143,8 @@ public class Conversation extends AbstractEntity {
return null; return null;
} }
for (int i = this.messages.size() - 1; i >= 0; --i) { 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).getStatus() <= Message.STATUS_RECEIVED
&& this.messages.get(i).markable) {
if (this.messages.get(i).isRead()) { if (this.messages.get(i).isRead()) {
return null; return null;
} else { } else {

View file

@ -5,5 +5,15 @@ public interface Downloadable {
public final String[] VALID_EXTENSIONS = { "webp", "jpeg", "jpg", "png" }; public final String[] VALID_EXTENSIONS = { "webp", "jpeg", "jpg", "png" };
public final String[] VALID_CRYPTO_EXTENSIONS = { "pgp", "gpg", "otr" }; 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 void start();
public int getStatus();
public long getFileSize();
} }

View file

@ -14,10 +14,6 @@ public class Message extends AbstractEntity {
public static final String TABLENAME = "messages"; 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_RECEIVED = 0;
public static final int STATUS_UNSEND = 1; public static final int STATUS_UNSEND = 1;
public static final int STATUS_SEND = 2; public static final int STATUS_SEND = 2;
@ -136,8 +132,8 @@ public class Message extends AbstractEntity {
if (this.trueCounterpart == null) { if (this.trueCounterpart == null) {
return null; return null;
} else { } else {
return this.conversation.getAccount().getRoster().getContactFromRoster( return this.conversation.getAccount().getRoster()
this.trueCounterpart); .getContactFromRoster(this.trueCounterpart);
} }
} }
} }
@ -147,12 +143,9 @@ public class Message extends AbstractEntity {
} }
public String getReadableBody(Context context) { public String getReadableBody(Context context) {
if ((encryption == ENCRYPTION_PGP) && (type == TYPE_TEXT)) { if (encryption == ENCRYPTION_PGP) {
return context.getText(R.string.encrypted_message_received) return context.getText(R.string.encrypted_message_received)
.toString(); .toString();
} else if ((encryption == ENCRYPTION_OTR) && (type == TYPE_IMAGE)) {
return context.getText(R.string.encrypted_image_received)
.toString();
} else if (encryption == ENCRYPTION_DECRYPTION_FAILED) { } else if (encryption == ENCRYPTION_DECRYPTION_FAILED) {
return context.getText(R.string.decryption_failed).toString(); return context.getText(R.string.decryption_failed).toString();
} else if (type == TYPE_IMAGE) { } else if (type == TYPE_IMAGE) {
@ -322,6 +315,8 @@ public class Message extends AbstractEntity {
return false; return false;
} }
return (message.getType() == Message.TYPE_TEXT return (message.getType() == Message.TYPE_TEXT
&& this.getDownloadable() == null
&& message.getDownloadable() == null
&& message.getEncryption() != Message.ENCRYPTION_PGP && message.getEncryption() != Message.ENCRYPTION_PGP
&& this.getType() == message.getType() && this.getType() == message.getType()
&& this.getEncryption() == message.getEncryption() && this.getEncryption() == message.getEncryption()
@ -371,12 +366,14 @@ public class Message extends AbstractEntity {
public boolean bodyContainsDownloadable() { public boolean bodyContainsDownloadable() {
Contact contact = this.getContact(); Contact contact = this.getContact();
if (contact == null || !contact.trusted()) { if (status <= STATUS_RECEIVED
&& (contact == null || !contact.trusted())) {
return false; return false;
} }
try { try {
URL url = new URL(this.getBody()); 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; return false;
} }
if (url.getPath() == null) { if (url.getPath() == null) {
@ -385,9 +382,15 @@ public class Message extends AbstractEntity {
String[] pathParts = url.getPath().split("/"); String[] pathParts = url.getPath().split("/");
String filename = pathParts[pathParts.length - 1]; String filename = pathParts[pathParts.length - 1];
String[] extensionParts = filename.split("\\."); 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; 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; return true;
} else { } else {
return false; return false;
@ -399,6 +402,9 @@ public class Message extends AbstractEntity {
public ImageParams getImageParams() { public ImageParams getImageParams() {
ImageParams params = new ImageParams(); ImageParams params = new ImageParams();
if (this.downloadable != null) {
params.size = this.downloadable.getFileSize();
}
if (body == null) { if (body == null) {
return params; return params;
} }
@ -409,13 +415,6 @@ public class Message extends AbstractEntity {
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
params.origin = parts[0]; 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 { try {
params.size = Long.parseLong(parts[0]); params.size = Long.parseLong(parts[0]);

View file

@ -24,7 +24,8 @@ public class HttpConnection implements Downloadable {
private URL mUrl; private URL mUrl;
private Message message; private Message message;
private DownloadableFile file; private DownloadableFile file;
private long mPreviousFileSize = Long.MIN_VALUE; private long mPreviousFileSize = 0;
private int mStatus = Downloadable.STATUS_UNKNOWN;
public HttpConnection(HttpConnectionManager manager) { public HttpConnection(HttpConnectionManager manager) {
this.mHttpConnectionManager = manager; this.mHttpConnectionManager = manager;
@ -33,6 +34,7 @@ public class HttpConnection implements Downloadable {
@Override @Override
public void start() { public void start() {
changeStatus(STATUS_DOWNLOADING);
new Thread(new FileDownloader()).start(); new Thread(new FileDownloader()).start();
} }
@ -41,10 +43,8 @@ public class HttpConnection implements Downloadable {
this.message.setDownloadable(this); this.message.setDownloadable(this);
try { try {
mUrl = new URL(message.getBody()); mUrl = new URL(message.getBody());
this.file = mXmppConnectionService.getFileBackend().getConversationsFile(message,false); this.file = mXmppConnectionService.getFileBackend()
message.setType(Message.TYPE_IMAGE); .getConversationsFile(message, false);
message.setStatus(Message.STATUS_RECEIVED_CHECKING);
mXmppConnectionService.updateConversationUi();
checkFileSize(); checkFileSize();
} catch (MalformedURLException e) { } catch (MalformedURLException e) {
this.cancel(); this.cancel();
@ -55,29 +55,34 @@ public class HttpConnection implements Downloadable {
this.message = message; this.message = message;
this.message.setDownloadable(this); this.message.setDownloadable(this);
this.mUrl = url; this.mUrl = url;
this.file = mXmppConnectionService.getFileBackend().getConversationsFile(message,false); this.file = mXmppConnectionService.getFileBackend()
.getConversationsFile(message, false);
this.mPreviousFileSize = message.getImageParams().size; this.mPreviousFileSize = message.getImageParams().size;
message.setType(Message.TYPE_IMAGE);
message.setStatus(Message.STATUS_RECEIVED_CHECKING);
mXmppConnectionService.updateConversationUi();
checkFileSize(); checkFileSize();
} }
private void checkFileSize() { private void checkFileSize() {
changeStatus(STATUS_CHECKING);
new Thread(new FileSizeChecker()).start(); new Thread(new FileSizeChecker()).start();
} }
public void cancel() { public void cancel() {
mXmppConnectionService.markMessage(message, Message.STATUS_RECEPTION_FAILED);
mHttpConnectionManager.finishConnection(this); mHttpConnectionManager.finishConnection(this);
message.setDownloadable(null);
message.setBody(mUrl.toString());
mXmppConnectionService.updateMessage(message);
} }
private void finish() { private void finish() {
message.setStatus(Message.STATUS_RECEIVED); message.setDownloadable(null);
mXmppConnectionService.updateMessage(message);
mHttpConnectionManager.finishConnection(this); mHttpConnectionManager.finishConnection(this);
} }
private void changeStatus(int status) {
this.mStatus = status;
mXmppConnectionService.updateConversationUi();
}
private class FileSizeChecker implements Runnable { private class FileSizeChecker implements Runnable {
@Override @Override
@ -90,18 +95,18 @@ public class HttpConnection implements Downloadable {
return; return;
} }
file.setExpectedSize(size); file.setExpectedSize(size);
message.setBody(mUrl.toString()+","+String.valueOf(size)); message.setType(Message.TYPE_IMAGE);
if (size <= mHttpConnectionManager.getAutoAcceptFileSize() || size == mPreviousFileSize) { if (size <= mHttpConnectionManager.getAutoAcceptFileSize()
mXmppConnectionService.updateMessage(message); || size == mPreviousFileSize) {
start(); start();
} else { } else {
message.setStatus(Message.STATUS_RECEIVED_OFFER); changeStatus(STATUS_OFFER);
mXmppConnectionService.updateMessage(message);
} }
} }
private long retrieveFileSize() throws IOException { private long retrieveFileSize() throws IOException {
HttpURLConnection connection = (HttpURLConnection) mUrl.openConnection(); HttpURLConnection connection = (HttpURLConnection) mUrl
.openConnection();
connection.setRequestMethod("HEAD"); connection.setRequestMethod("HEAD");
if (connection instanceof HttpsURLConnection) { if (connection instanceof HttpsURLConnection) {
@ -124,7 +129,6 @@ public class HttpConnection implements Downloadable {
@Override @Override
public void run() { public void run() {
try { try {
mXmppConnectionService.markMessage(message, Message.STATUS_RECEIVING);
download(); download();
updateImageBounds(); updateImageBounds();
finish(); finish();
@ -134,11 +138,13 @@ public class HttpConnection implements Downloadable {
} }
private void download() throws IOException { private void download() throws IOException {
HttpURLConnection connection = (HttpURLConnection) mUrl.openConnection(); HttpURLConnection connection = (HttpURLConnection) mUrl
.openConnection();
if (connection instanceof HttpsURLConnection) { if (connection instanceof HttpsURLConnection) {
} }
BufferedInputStream is = new BufferedInputStream(connection.getInputStream()); BufferedInputStream is = new BufferedInputStream(
connection.getInputStream());
OutputStream os = file.createOutputStream(); OutputStream os = file.createOutputStream();
int count = -1; int count = -1;
byte[] buffer = new byte[1024]; byte[] buffer = new byte[1024];
@ -158,8 +164,22 @@ public class HttpConnection implements Downloadable {
int imageWidth = options.outWidth; int imageWidth = options.outWidth;
message.setBody(mUrl.toString() + "," + file.getSize() + ',' message.setBody(mUrl.toString() + "," + file.getSize() + ','
+ imageWidth + ',' + imageHeight); + 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;
}
}
} }

View file

@ -16,7 +16,6 @@ public class HttpConnectionManager extends AbstractConnectionManager {
private List<HttpConnection> connections = new CopyOnWriteArrayList<HttpConnection>(); private List<HttpConnection> connections = new CopyOnWriteArrayList<HttpConnection>();
public HttpConnection createNewConnection(Message message) { public HttpConnection createNewConnection(Message message) {
HttpConnection connection = new HttpConnection(this); HttpConnection connection = new HttpConnection(this);
connection.init(message); connection.init(message);

View file

@ -478,8 +478,9 @@ public class MessageParser extends AbstractParser implements
mXmppConnectionService.databaseBackend.createMessage(message); mXmppConnectionService.databaseBackend.createMessage(message);
} }
} }
if (message.getStatus() == Message.STATUS_RECEIVED && message.bodyContainsDownloadable()) { if (message.bodyContainsDownloadable()) {
this.mXmppConnectionService.getHttpConnectionManager().createNewConnection(message); this.mXmppConnectionService.getHttpConnectionManager()
.createNewConnection(message);
} }
notify = notify && !conversation.isMuted(); notify = notify && !conversation.isMuted();
if (notify) { if (notify) {

View file

@ -70,7 +70,8 @@ public class FileBackend {
return getJingleFileLegacy(message, true); return getJingleFileLegacy(message, true);
} }
public DownloadableFile getJingleFileLegacy(Message message, boolean decrypted) { public DownloadableFile getJingleFileLegacy(Message message,
boolean decrypted) {
Conversation conversation = message.getConversation(); Conversation conversation = message.getConversation();
String prefix = context.getFilesDir().getAbsolutePath(); String prefix = context.getFilesDir().getAbsolutePath();
String path = prefix + "/" + conversation.getAccount().getJid() + "/" String path = prefix + "/" + conversation.getAccount().getJid() + "/"
@ -92,7 +93,8 @@ public class FileBackend {
return getConversationsFile(message, true); return getConversationsFile(message, true);
} }
public DownloadableFile getConversationsFile(Message message, boolean decrypted) { public DownloadableFile getConversationsFile(Message message,
boolean decrypted) {
StringBuilder filename = new StringBuilder(); StringBuilder filename = new StringBuilder();
filename.append(Environment.getExternalStoragePublicDirectory( filename.append(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES).getAbsolutePath()); Environment.DIRECTORY_PICTURES).getAbsolutePath());
@ -144,8 +146,8 @@ public class FileBackend {
return this.copyImageToPrivateStorage(message, image, 0); return this.copyImageToPrivateStorage(message, image, 0);
} }
private DownloadableFile copyImageToPrivateStorage(Message message, Uri image, private DownloadableFile copyImageToPrivateStorage(Message message,
int sampleSize) throws ImageCopyException { Uri image, int sampleSize) throws ImageCopyException {
try { try {
InputStream is = context.getContentResolver() InputStream is = context.getContentResolver()
.openInputStream(image); .openInputStream(image);

View file

@ -1,6 +1,5 @@
package eu.siacs.conversations.services; package eu.siacs.conversations.services;
public class AbstractConnectionManager { public class AbstractConnectionManager {
protected XmppConnectionService mXmppConnectionService; protected XmppConnectionService mXmppConnectionService;

View file

@ -199,7 +199,8 @@ public class ConferenceDetailsActivity extends XmppActivity {
} }
private void populateView() { 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)); mYourPhoto.setImageBitmap(conversation.getAccount().getImage(this, 48));
setTitle(conversation.getName()); setTitle(conversation.getName());
mFullJid.setText(conversation.getContactJid().split("/", 2)[0]); mFullJid.setText(conversation.getContactJid().split("/", 2)[0]);

View file

@ -56,7 +56,8 @@ public class ContactDetailsActivity extends XmppActivity {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
ContactDetailsActivity.this.xmppConnectionService.deleteContactOnServer(contact); ContactDetailsActivity.this.xmppConnectionService
.deleteContactOnServer(contact);
ContactDetailsActivity.this.finish(); ContactDetailsActivity.this.finish();
} }
}; };
@ -78,7 +79,8 @@ public class ContactDetailsActivity extends XmppActivity {
@Override @Override
public void onClick(View v) { 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.setTitle(getString(R.string.action_add_phone_book));
builder.setMessage(getString(R.string.add_phone_book_text, builder.setMessage(getString(R.string.add_phone_book_text,
contact.getJid())); contact.getJid()));
@ -309,7 +311,8 @@ public class ContactDetailsActivity extends XmppActivity {
} else { } else {
contactJidTv.setText(contact.getJid()); 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, UIHelper.prepareContactBadge(this, badge, contact,
getApplicationContext()); getApplicationContext());

View file

@ -222,7 +222,8 @@ public class ConversationActivity extends XmppActivity implements
ab.setDisplayHomeAsUpEnabled(true); ab.setDisplayHomeAsUpEnabled(true);
ab.setHomeButtonEnabled(true); ab.setHomeButtonEnabled(true);
if (getSelectedConversation().getMode() == Conversation.MODE_SINGLE if (getSelectedConversation().getMode() == Conversation.MODE_SINGLE
|| ConversationActivity.this.useSubjectToIdentifyConference()) { || ConversationActivity.this
.useSubjectToIdentifyConference()) {
ab.setTitle(getSelectedConversation().getName()); ab.setTitle(getSelectedConversation().getName());
} else { } else {
ab.setTitle(getSelectedConversation().getContactJid() ab.setTitle(getSelectedConversation().getContactJid()

View file

@ -73,7 +73,6 @@ public class ConversationFragment extends Fragment {
private IntentSender askForPassphraseIntent = null; private IntentSender askForPassphraseIntent = null;
private ConcurrentLinkedQueue<Message> mEncryptedMessages = new ConcurrentLinkedQueue<Message>(); private ConcurrentLinkedQueue<Message> mEncryptedMessages = new ConcurrentLinkedQueue<Message>();
private boolean mDecryptJobRunning = false; private boolean mDecryptJobRunning = false;

View file

@ -70,7 +70,8 @@ public class ManageAccountActivity extends XmppActivity {
public void onCreateContextMenu(ContextMenu menu, View v, public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) { ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, 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; AdapterView.AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) menuInfo;
this.selectedAccount = accountList.get(acmi.position); this.selectedAccount = accountList.get(acmi.position);
if (this.selectedAccount.isOptionSet(Account.OPTION_DISABLED)) { if (this.selectedAccount.isOptionSet(Account.OPTION_DISABLED)) {
@ -187,7 +188,8 @@ public class ManageAccountActivity extends XmppActivity {
} }
private void deleteAccount(final Account account) { 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.setTitle(getString(R.string.mgmt_account_are_you_sure));
builder.setIconAttribute(android.R.attr.alertDialogIcon); builder.setIconAttribute(android.R.attr.alertDialogIcon);
builder.setMessage(getString(R.string.mgmt_account_delete_confirm_text)); builder.setMessage(getString(R.string.mgmt_account_delete_confirm_text));

View file

@ -5,6 +5,7 @@ import java.util.List;
import eu.siacs.conversations.Config; import eu.siacs.conversations.Config;
import eu.siacs.conversations.R; import eu.siacs.conversations.R;
import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.entities.Downloadable;
import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.Message;
import eu.siacs.conversations.ui.ConversationActivity; import eu.siacs.conversations.ui.ConversationActivity;
import eu.siacs.conversations.ui.XmppActivity; 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, view = (View) inflater.inflate(R.layout.conversation_list_row,
parent, false); parent, false);
} }
Conversation conv = getItem(position); Conversation conversation = getItem(position);
if (this.activity instanceof ConversationActivity) { if (this.activity instanceof ConversationActivity) {
ConversationActivity activity = (ConversationActivity) this.activity; ConversationActivity activity = (ConversationActivity) this.activity;
if (!activity.isConversationsOverviewHideable()) { if (!activity.isConversationsOverviewHideable()) {
if (conv == activity.getSelectedConversation()) { if (conversation == activity.getSelectedConversation()) {
view.setBackgroundColor(activity view.setBackgroundColor(activity
.getSecondaryBackgroundColor()); .getSecondaryBackgroundColor());
} else { } else {
@ -53,65 +54,76 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> {
} }
TextView convName = (TextView) view TextView convName = (TextView) view
.findViewById(R.id.conversation_name); .findViewById(R.id.conversation_name);
if (conv.getMode() == Conversation.MODE_SINGLE if (conversation.getMode() == Conversation.MODE_SINGLE
|| activity.useSubjectToIdentifyConference()) { || activity.useSubjectToIdentifyConference()) {
convName.setText(conv.getName()); convName.setText(conversation.getName());
} else { } 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); .findViewById(R.id.conversation_lastmsg);
TextView mTimestamp = (TextView) view
.findViewById(R.id.conversation_lastupdate);
ImageView imagePreview = (ImageView) view ImageView imagePreview = (ImageView) view
.findViewById(R.id.conversation_lastimage); .findViewById(R.id.conversation_lastimage);
Message latestMessage = conv.getLatestMessage(); Message message = conversation.getLatestMessage();
if (latestMessage.getType() == Message.TYPE_TEXT if (!conversation.isRead()) {
|| 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);
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);
} else {
convLastMsg.setText("");
}
}
}
if (!conv.isRead()) {
convName.setTypeface(null, Typeface.BOLD); convName.setTypeface(null, Typeface.BOLD);
convLastMsg.setTypeface(null, Typeface.BOLD);
} else { } else {
convName.setTypeface(null, Typeface.NORMAL); convName.setTypeface(null, Typeface.NORMAL);
convLastMsg.setTypeface(null, Typeface.NORMAL);
} }
((TextView) view.findViewById(R.id.conversation_lastupdate)) if (message.getType() == Message.TYPE_IMAGE
.setText(UIHelper.readableTimeDifference(getContext(), conv || message.getDownloadable() != null) {
.getLatestMessage().getTimeSent())); Downloadable d = message.getDownloadable();
if (d != null) {
mLastMessage.setVisibility(View.VISIBLE);
imagePreview.setVisibility(View.GONE);
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 {
mLastMessage.setText("");
}
} else {
mLastMessage.setVisibility(View.GONE);
imagePreview.setVisibility(View.VISIBLE);
activity.loadBitmap(message, imagePreview);
}
} else {
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);
}
mTimestamp.setText(UIHelper.readableTimeDifference(getContext(),
conversation.getLatestMessage().getTimeSent()));
ImageView profilePicture = (ImageView) view ImageView profilePicture = (ImageView) view
.findViewById(R.id.conversation_image); .findViewById(R.id.conversation_image);
profilePicture.setImageBitmap(conv.getImage(activity, 56)); profilePicture.setImageBitmap(conversation.getImage(activity, 56));
return view; return view;
} }

View file

@ -138,10 +138,6 @@ public class MessageAdapter extends ArrayAdapter<Message> {
info = getContext().getString(R.string.send_rejected); info = getContext().getString(R.string.send_rejected);
error = true; error = true;
break; break;
case Message.STATUS_RECEPTION_FAILED:
info = getContext().getString(R.string.reception_failed);
error = true;
break;
default: default:
if (multiReceived) { if (multiReceived) {
Contact contact = message.getContact(); Contact contact = message.getContact();
@ -230,19 +226,10 @@ public class MessageAdapter extends ArrayAdapter<Message> {
viewHolder.messageBody.setVisibility(View.VISIBLE); viewHolder.messageBody.setVisibility(View.VISIBLE);
if (message.getBody() != null) { if (message.getBody() != null) {
if (message.getType() != Message.TYPE_PRIVATE) { 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 String body = Config.PARSE_EMOTICONS ? UIHelper
.transformAsciiEmoticons(message.getMergedBody()) .transformAsciiEmoticons(message.getMergedBody())
: message.getMergedBody(); : message.getMergedBody();
viewHolder.messageBody.setText(body); viewHolder.messageBody.setText(body);
}
} else { } else {
String privateMarker; String privateMarker;
if (message.getStatus() <= Message.STATUS_RECEIVED) { if (message.getStatus() <= Message.STATUS_RECEIVED) {
@ -347,6 +334,8 @@ public class MessageAdapter extends ArrayAdapter<Message> {
viewHolder.contact_picture = (ImageView) view viewHolder.contact_picture = (ImageView) view
.findViewById(R.id.message_photo); .findViewById(R.id.message_photo);
viewHolder.contact_picture.setImageBitmap(getSelfBitmap()); viewHolder.contact_picture.setImageBitmap(getSelfBitmap());
viewHolder.download_button = (Button) view
.findViewById(R.id.download_button);
viewHolder.indicator = (ImageView) view viewHolder.indicator = (ImageView) view
.findViewById(R.id.security_indicator); .findViewById(R.id.security_indicator);
viewHolder.image = (ImageView) view viewHolder.image = (ImageView) view
@ -366,15 +355,11 @@ public class MessageAdapter extends ArrayAdapter<Message> {
.findViewById(R.id.message_box); .findViewById(R.id.message_box);
viewHolder.contact_picture = (ImageView) view viewHolder.contact_picture = (ImageView) view
.findViewById(R.id.message_photo); .findViewById(R.id.message_photo);
viewHolder.download_button = (Button) view viewHolder.download_button = (Button) view
.findViewById(R.id.download_button); .findViewById(R.id.download_button);
if (item.getConversation().getMode() == Conversation.MODE_SINGLE) { if (item.getConversation().getMode() == Conversation.MODE_SINGLE) {
viewHolder.contact_picture.setImageBitmap(mBitmapCache.get( viewHolder.contact_picture.setImageBitmap(mBitmapCache.get(
item.getConversation().getContact(), getContext())); item.getConversation().getContact(), getContext()));
} }
viewHolder.indicator = (ImageView) view viewHolder.indicator = (ImageView) view
.findViewById(R.id.security_indicator); .findViewById(R.id.security_indicator);
@ -483,14 +468,15 @@ public class MessageAdapter extends ArrayAdapter<Message> {
} }
} }
if (item.getType() == Message.TYPE_IMAGE) { if (item.getType() == Message.TYPE_IMAGE
if (item.getStatus() == Message.STATUS_RECEIVING) { || item.getDownloadable() != null) {
Downloadable d = item.getDownloadable();
if (d != null && d.getStatus() == Downloadable.STATUS_DOWNLOADING) {
displayInfoMessage(viewHolder, R.string.receiving_image); 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); displayInfoMessage(viewHolder, R.string.checking_image);
} else if (item.getStatus() == Message.STATUS_RECEPTION_FAILED) { } else if (d != null && d.getStatus() == Downloadable.STATUS_OFFER) {
displayTextMessage(viewHolder, item);
} else if (item.getStatus() == Message.STATUS_RECEIVED_OFFER) {
viewHolder.image.setVisibility(View.GONE); viewHolder.image.setVisibility(View.GONE);
viewHolder.messageBody.setVisibility(View.GONE); viewHolder.messageBody.setVisibility(View.GONE);
viewHolder.download_button.setVisibility(View.VISIBLE); viewHolder.download_button.setVisibility(View.VISIBLE);
@ -499,11 +485,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
if (!startDonwloadable(item)) { startDonwloadable(item);
activity.xmppConnectionService.markMessage(
item,
Message.STATUS_RECEPTION_FAILED);
}
} }
}); });
} else if ((item.getEncryption() == Message.ENCRYPTION_DECRYPTED) } else if ((item.getEncryption() == Message.ENCRYPTION_DECRYPTED)

View file

@ -34,17 +34,18 @@ public class JingleConnection implements Downloadable {
private JingleConnectionManager mJingleConnectionManager; private JingleConnectionManager mJingleConnectionManager;
private XmppConnectionService mXmppConnectionService; private XmppConnectionService mXmppConnectionService;
public static final int STATUS_INITIATED = 0; protected static final int JINGLE_STATUS_INITIATED = 0;
public static final int STATUS_ACCEPTED = 1; protected static final int JINGLE_STATUS_ACCEPTED = 1;
public static final int STATUS_TERMINATED = 2; protected static final int JINGLE_STATUS_TERMINATED = 2;
public static final int STATUS_CANCELED = 3; protected static final int JINGLE_STATUS_CANCELED = 3;
public static final int STATUS_FINISHED = 4; protected static final int JINGLE_STATUS_FINISHED = 4;
public static final int STATUS_TRANSMITTING = 5; protected static final int JINGLE_STATUS_TRANSMITTING = 5;
public static final int STATUS_FAILED = 99; protected static final int JINGLE_STATUS_FAILED = 99;
private int ibbBlockSize = 4096; private int ibbBlockSize = 4096;
private int status = -1; private int mJingleStatus = -1;
private int mStatus = -1;
private Message message; private Message message;
private String sessionId; private String sessionId;
private Account account; private Account account;
@ -76,7 +77,7 @@ public class JingleConnection implements Downloadable {
mXmppConnectionService.markMessage(message, mXmppConnectionService.markMessage(message,
Message.STATUS_SEND_FAILED); 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) { public void init(Account account, JinglePacket packet) {
this.status = STATUS_INITIATED; this.mJingleStatus = JINGLE_STATUS_INITIATED;
Conversation conversation = this.mXmppConnectionService Conversation conversation = this.mXmppConnectionService
.findOrCreateConversation(account, .findOrCreateConversation(account,
packet.getFrom().split("/", 2)[0], false); packet.getFrom().split("/", 2)[0], false);
this.message = new Message(conversation, "", Message.ENCRYPTION_NONE); this.message = new Message(conversation, "", Message.ENCRYPTION_NONE);
this.message.setStatus(Message.STATUS_RECEIVED);
this.message.setType(Message.TYPE_IMAGE); this.message.setType(Message.TYPE_IMAGE);
this.message.setStatus(Message.STATUS_RECEIVED_OFFER); this.mStatus = Downloadable.STATUS_OFFER;
this.message.setDownloadable(this); this.message.setDownloadable(this);
String[] fromParts = packet.getFrom().split("/", 2); String[] fromParts = packet.getFrom().split("/", 2);
this.message.setPresence(fromParts[1]); this.message.setPresence(fromParts[1]);
@ -306,6 +308,7 @@ public class JingleConnection implements Downloadable {
long size = Long.parseLong(fileSize.getContent()); long size = Long.parseLong(fileSize.getContent());
message.setBody(Long.toString(size)); message.setBody(Long.toString(size));
conversation.getMessages().add(message); conversation.getMessages().add(message);
mXmppConnectionService.updateConversationUi();
if (size <= this.mJingleConnectionManager if (size <= this.mJingleConnectionManager
.getAutoAcceptFileSize()) { .getAutoAcceptFileSize()) {
Log.d(Config.LOGTAG, "auto accepting file from " Log.d(Config.LOGTAG, "auto accepting file from "
@ -370,7 +373,7 @@ public class JingleConnection implements Downloadable {
content.socks5transport().setChildren(getCandidatesAsElements()); content.socks5transport().setChildren(getCandidatesAsElements());
packet.setContent(content); packet.setContent(content);
this.sendJinglePacket(packet); this.sendJinglePacket(packet);
this.status = STATUS_INITIATED; this.mJingleStatus = JINGLE_STATUS_INITIATED;
} }
} }
@ -383,8 +386,9 @@ public class JingleConnection implements Downloadable {
} }
private void sendAccept() { private void sendAccept() {
status = STATUS_ACCEPTED; mJingleStatus = JINGLE_STATUS_ACCEPTED;
mXmppConnectionService.markMessage(message, Message.STATUS_RECEIVING); this.mStatus = Downloadable.STATUS_DOWNLOADING;
mXmppConnectionService.updateConversationUi();
this.mJingleConnectionManager.getPrimaryCandidate(this.account, this.mJingleConnectionManager.getPrimaryCandidate(this.account,
new OnPrimaryCandidateFound() { new OnPrimaryCandidateFound() {
@ -458,7 +462,7 @@ public class JingleConnection implements Downloadable {
Content content = packet.getJingleContent(); Content content = packet.getJingleContent();
mergeCandidates(JingleCandidate.parse(content.socks5transport() mergeCandidates(JingleCandidate.parse(content.socks5transport()
.getChildren())); .getChildren()));
this.status = STATUS_ACCEPTED; this.mJingleStatus = JINGLE_STATUS_ACCEPTED;
mXmppConnectionService.markMessage(message, Message.STATUS_UNSEND); mXmppConnectionService.markMessage(message, Message.STATUS_UNSEND);
this.connectNextCandidate(); this.connectNextCandidate();
return true; return true;
@ -493,7 +497,8 @@ public class JingleConnection implements Downloadable {
} else if (content.socks5transport().hasChild("candidate-error")) { } else if (content.socks5transport().hasChild("candidate-error")) {
Log.d(Config.LOGTAG, "received candidate error"); Log.d(Config.LOGTAG, "received candidate error");
this.receivedCandidate = true; this.receivedCandidate = true;
if ((status == STATUS_ACCEPTED) && (this.sentCandidate)) { if ((mJingleStatus == JINGLE_STATUS_ACCEPTED)
&& (this.sentCandidate)) {
this.connect(); this.connect();
} }
return true; return true;
@ -505,7 +510,8 @@ public class JingleConnection implements Downloadable {
JingleCandidate candidate = getCandidate(cid); JingleCandidate candidate = getCandidate(cid);
candidate.flagAsUsedByCounterpart(); candidate.flagAsUsedByCounterpart();
this.receivedCandidate = true; this.receivedCandidate = true;
if ((status == STATUS_ACCEPTED) && (this.sentCandidate)) { if ((mJingleStatus == JINGLE_STATUS_ACCEPTED)
&& (this.sentCandidate)) {
this.connect(); this.connect();
} else { } else {
Log.d(Config.LOGTAG, Log.d(Config.LOGTAG,
@ -533,7 +539,7 @@ public class JingleConnection implements Downloadable {
this.sendFallbackToIbb(); this.sendFallbackToIbb();
} }
} else { } else {
this.status = STATUS_TRANSMITTING; this.mJingleStatus = JINGLE_STATUS_TRANSMITTING;
if (connection.needsActivation()) { if (connection.needsActivation()) {
if (connection.getCandidate().isOurs()) { if (connection.getCandidate().isOurs()) {
Log.d(Config.LOGTAG, "candidate " Log.d(Config.LOGTAG, "candidate "
@ -620,9 +626,10 @@ public class JingleConnection implements Downloadable {
packet.setReason(reason); packet.setReason(reason);
this.sendJinglePacket(packet); this.sendJinglePacket(packet);
this.disconnect(); this.disconnect();
this.status = STATUS_FINISHED; this.mJingleStatus = JINGLE_STATUS_FINISHED;
this.mXmppConnectionService.markMessage(this.message, this.message.setStatus(Message.STATUS_RECEIVED);
Message.STATUS_RECEIVED); this.message.setDownloadable(null);
this.mXmppConnectionService.updateMessage(message);
this.mJingleConnectionManager.finishConnection(this); this.mJingleConnectionManager.finishConnection(this);
} }
@ -692,7 +699,7 @@ public class JingleConnection implements Downloadable {
} }
private void receiveSuccess() { private void receiveSuccess() {
this.status = STATUS_FINISHED; this.mJingleStatus = JINGLE_STATUS_FINISHED;
this.mXmppConnectionService.markMessage(this.message, this.mXmppConnectionService.markMessage(this.message,
Message.STATUS_SEND); Message.STATUS_SEND);
this.disconnect(); this.disconnect();
@ -700,14 +707,14 @@ public class JingleConnection implements Downloadable {
} }
public void cancel() { public void cancel() {
this.status = STATUS_CANCELED; this.mJingleStatus = JINGLE_STATUS_CANCELED;
this.disconnect(); this.disconnect();
if (this.message != null) { if (this.message != null) {
if (this.responder.equals(account.getFullJid())) { if (this.responder.equals(account.getFullJid())) {
this.mXmppConnectionService.markMessage(this.message, this.mStatus = Downloadable.STATUS_FAILED;
Message.STATUS_RECEPTION_FAILED); this.mXmppConnectionService.updateConversationUi();
} else { } else {
if (this.status == STATUS_INITIATED) { if (this.mJingleStatus == JINGLE_STATUS_INITIATED) {
this.mXmppConnectionService.markMessage(this.message, this.mXmppConnectionService.markMessage(this.message,
Message.STATUS_SEND_REJECTED); Message.STATUS_SEND_REJECTED);
} else { } else {
@ -790,7 +797,7 @@ public class JingleConnection implements Downloadable {
.setAttribute("cid", cid); .setAttribute("cid", cid);
packet.setContent(content); packet.setContent(content);
this.sentCandidate = true; this.sentCandidate = true;
if ((receivedCandidate) && (status == STATUS_ACCEPTED)) { if ((receivedCandidate) && (mJingleStatus == JINGLE_STATUS_ACCEPTED)) {
connect(); connect();
} }
this.sendJinglePacket(packet); this.sendJinglePacket(packet);
@ -803,7 +810,7 @@ public class JingleConnection implements Downloadable {
content.socks5transport().addChild("candidate-error"); content.socks5transport().addChild("candidate-error");
packet.setContent(content); packet.setContent(content);
this.sentCandidate = true; this.sentCandidate = true;
if ((receivedCandidate) && (status == STATUS_ACCEPTED)) { if ((receivedCandidate) && (mJingleStatus == JINGLE_STATUS_ACCEPTED)) {
connect(); connect();
} }
this.sendJinglePacket(packet); this.sendJinglePacket(packet);
@ -817,8 +824,8 @@ public class JingleConnection implements Downloadable {
return this.responder; return this.responder;
} }
public int getStatus() { public int getJingleStatus() {
return this.status; return this.mJingleStatus;
} }
private boolean equalCandidateExists(JingleCandidate candidate) { private boolean equalCandidateExists(JingleCandidate candidate) {
@ -869,7 +876,7 @@ public class JingleConnection implements Downloadable {
} }
public void start() { public void start() {
if (status == STATUS_INITIATED) { if (mJingleStatus == JINGLE_STATUS_INITIATED) {
new Thread(new Runnable() { new Thread(new Runnable() {
@Override @Override
@ -878,7 +885,21 @@ public class JingleConnection implements Downloadable {
} }
}).start(); }).start();
} else { } 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;
} }
} }
} }

View file

@ -154,7 +154,7 @@ public class JingleConnectionManager extends AbstractConnectionManager {
public void cancelInTransmission() { public void cancelInTransmission() {
for (JingleConnection connection : this.connections) { for (JingleConnection connection : this.connections) {
if (connection.getStatus() == JingleConnection.STATUS_TRANSMITTING) { if (connection.getJingleStatus() == JingleConnection.JINGLE_STATUS_TRANSMITTING) {
connection.cancel(); connection.cancel();
} }
} }

View file

@ -100,7 +100,8 @@ public class JingleInbandTransport extends JingleTransport {
} }
@Override @Override
public void send(DownloadableFile file, OnFileTransmissionStatusChanged callback) { public void send(DownloadableFile file,
OnFileTransmissionStatusChanged callback) {
this.onFileTransmissionStatusChanged = callback; this.onFileTransmissionStatusChanged = callback;
this.file = file; this.file = file;
try { try {