Rework Controller to use new single callback from EAS.

* Use unified callback instead of per-call callbacks
* Remove per-call tag
* Rework MessageView to operate without tag
* Minor cleanups in service side
This commit is contained in:
Andrew Stadler 2009-07-29 17:20:30 -07:00
parent 183e4a7a85
commit ea69fc40d7
8 changed files with 89 additions and 133 deletions

View File

@ -53,6 +53,7 @@ public class Controller {
private Context mContext;
private Context mProviderContext;
private MessagingController mLegacyController;
private ServiceCallback mServiceCallback = new ServiceCallback();
private HashSet<Result> mListeners = new HashSet<Result>();
private static String[] MESSAGEID_TO_ACCOUNTID_PROJECTION = new String[] {
@ -417,7 +418,7 @@ public class Controller {
* @param callback the Controller callback by which results will be reported
*/
public void loadAttachment(long attachmentId, long messageId, long accountId,
final Result callback, Object tag) {
final Result callback) {
Attachment attachInfo = Attachment.restoreAttachmentWithId(mProviderContext, attachmentId);
@ -455,7 +456,7 @@ public class Controller {
if (isMessagingController(account)) {
return null;
} else {
return new EmailServiceProxy(mContext, SyncManager.class);
return new EmailServiceProxy(mContext, SyncManager.class, mServiceCallback);
}
}
@ -505,10 +506,9 @@ public class Controller {
* @param messageId the message which contains the attachment
* @param attachmentId the attachment being loaded
* @param progress 0 for "starting", 1..99 for updates (if needed in UI), 100 for complete
* @param tag caller-defined tag, if supplied
*/
public void loadAttachmentCallback(MessagingException result, long messageId,
long attachmentId, int progress, Object tag);
long attachmentId, int progress);
}
/**
@ -570,87 +570,54 @@ public class Controller {
/**
* Service callback for load attachment
*/
private class LoadAttachmentCallback extends IEmailServiceCallback.Stub {
private class ServiceCallback extends IEmailServiceCallback.Stub {
private final static boolean DEBUG_FAIL_DOWNLOADS = false; // do not check in "true"
Result mCallback;
boolean mMadeFirstCallback;
Object mTag;
public LoadAttachmentCallback(Result callback, Object tag) {
super();
mCallback = callback;
mMadeFirstCallback = false;
mTag = tag;
}
/**
* Callback from Service for load attachment status.
*
* This performs some translations to what the UI expects, which is (assuming no fail):
* progress = 0 ("started")
* progress = 1..99 ("running")
* progress = 100 ("finished")
*
* @param messageId the id of the message the callback relates to
* @param attachmentId the id of the attachment (if any)
* @param statusCode from the definitions in EmailServiceStatus
* @param progress the progress (from 0 to 100) of a download
*/
public void status(long messageId, long attachmentId, int statusCode, int progress) {
if (mCallback != null && isActiveResultCallback(mCallback)) {
MessagingException result = null;
switch (statusCode) {
case EmailServiceStatus.SUCCESS:
progress = 100;
break;
case EmailServiceStatus.IN_PROGRESS:
// special case, force a single "progress = 0" for the first time
if (!mMadeFirstCallback) {
progress = 0;
mMadeFirstCallback = true;
} else if (DEBUG_FAIL_DOWNLOADS && progress > 75) {
result = new MessagingException(
String.valueOf(EmailServiceStatus.CONNECTION_ERROR));
} else if (progress <= 0 || progress >= 100) {
return;
}
break;
default:
result = new MessagingException(String.valueOf(statusCode));
break;
}
mCallback.loadAttachmentCallback(result, messageId, attachmentId, progress, mTag);
// prevent any trailing reports if there was an error
if (result != null) {
mCallback = null;
}
}
}
public void loadAttachmentStatus(long messageId, long attachmentId, int statusCode,
int progress) throws RemoteException {
// TODO Auto-generated method stub
MessagingException result = null;
switch (statusCode) {
case EmailServiceStatus.SUCCESS:
progress = 100;
break;
case EmailServiceStatus.IN_PROGRESS:
if (DEBUG_FAIL_DOWNLOADS && progress > 75) {
result = new MessagingException(
String.valueOf(EmailServiceStatus.CONNECTION_ERROR));
}
// discard progress reports that look like sentinels
if (progress < 0 || progress >= 100) {
return;
}
break;
default:
result = new MessagingException(String.valueOf(statusCode));
break;
}
synchronized (mListeners) {
for (Result listener : mListeners) {
listener.loadAttachmentCallback(result, messageId, attachmentId, progress);
}
}
}
public void sendMessageStatus(long messageId, int statusCode, int progress)
throws RemoteException {
// TODO Auto-generated method stub
}
public void syncMailboxListStatus(long accountId, int statusCode, int progress)
throws RemoteException {
// TODO Auto-generated method stub
}
public void syncMailboxStatus(long mailboxId, int statusCode, int progress)
throws RemoteException {
// TODO Auto-generated method stub
}
}
}

View File

@ -706,7 +706,7 @@ public class AccountFolderList extends ExpandableListActivity {
}
public void loadAttachmentCallback(MessagingException result, long messageId,
long attachmentId, int progress, Object tag) {
long attachmentId, int progress) {
}
}

View File

@ -782,7 +782,7 @@ public class FolderMessageList extends ExpandableListActivity {
}
public void loadAttachmentCallback(MessagingException result, long messageId,
long attachmentId, int progress, Object tag) {
long attachmentId, int progress) {
}
}

View File

@ -1243,7 +1243,7 @@ public class MessageCompose extends Activity implements OnClickListener, OnFocus
}
public void loadAttachmentCallback(MessagingException result, long messageId,
long attachmentId, int progress, Object tag) {
long attachmentId, int progress) {
}
}

View File

@ -801,7 +801,7 @@ public class MessageList extends ListActivity implements OnItemClickListener, On
}
public void loadAttachmentCallback(MessagingException result, long messageId,
long attachmentId, int progress, Object tag) {
long attachmentId, int progress) {
}
}

View File

@ -137,6 +137,10 @@ public class MessageView extends Activity
private LoadBodyTask mLoadBodyTask;
private LoadAttachmentsTask mLoadAttachmentsTask;
private long mLoadAttachmentId; // the attachment being saved/viewed
private boolean mLoadAttachmentSave; // if true, saving - if false, viewing
private String mLoadAttachmentName; // the display name
private String mFolder;
private String mMessageUid;
private Cursor mMessageListCursor;
@ -152,7 +156,7 @@ public class MessageView extends Activity
private ControllerResults mControllerCallback = new ControllerResults();
class MessageViewHandler extends Handler {
private static final int MSG_PROGRESS = 2;
private static final int MSG_ATTACHMENT_PROGRESS = 2;
private static final int MSG_SET_ATTACHMENTS_ENABLED = 4;
private static final int MSG_SET_HEADERS = 5;
private static final int MSG_NETWORK_ERROR = 6;
@ -168,16 +172,17 @@ public class MessageView extends Activity
@Override
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case MSG_PROGRESS:
if (msg.arg1 != 0) {
case MSG_ATTACHMENT_PROGRESS:
boolean progress = (msg.arg1 != 0);
if (progress) {
mProgressDialog.setMessage(
getString(R.string.message_view_fetching_attachment_progress,
msg.obj));
mLoadAttachmentName));
mProgressDialog.show();
} else {
mProgressDialog.dismiss();
}
setProgressBarIndeterminateVisibility(msg.arg1 != 0);
setProgressBarIndeterminateVisibility(progress);
break;
case MSG_SET_ATTACHMENTS_ENABLED:
for (int i = 0, count = mAttachments.getChildCount(); i < count; i++) {
@ -233,20 +238,17 @@ public class MessageView extends Activity
.iconView.setImageBitmap((Bitmap) msg.obj);
break;
case MSG_FINISH_LOAD_ATTACHMENT:
boolean save = msg.arg1 != 0;
long attachmentId = (Long)msg.obj;
doFinishLoadAttachment(save, attachmentId);
doFinishLoadAttachment(attachmentId);
break;
default:
super.handleMessage(msg);
}
}
public void progress(boolean progress, String filename) {
android.os.Message msg = new android.os.Message();
msg.what = MSG_PROGRESS;
public void attachmentProgress(boolean progress) {
android.os.Message msg = android.os.Message.obtain(this, MSG_ATTACHMENT_PROGRESS);
msg.arg1 = progress ? 1 : 0;
msg.obj = filename;
sendMessage(msg);
}
@ -315,9 +317,8 @@ public class MessageView extends Activity
sendMessage(msg);
}
public void finishLoadAttachment(long attachmentId, boolean save) {
public void finishLoadAttachment(long attachmentId) {
android.os.Message msg = android.os.Message.obtain(this, MSG_FINISH_LOAD_ATTACHMENT);
msg.arg1 = save ? 1 : 0;
msg.obj = Long.valueOf(attachmentId);
sendMessage(msg);
}
@ -666,17 +667,21 @@ public class MessageView extends Activity
return;
}
LoadAttachTag tag = new LoadAttachTag(true, attachment.name);
mLoadAttachmentId = attachment.attachmentId;
mLoadAttachmentSave = true;
mLoadAttachmentName = attachment.name;
Controller.getInstance(getApplication()).loadAttachment(attachment.attachmentId,
mMessageId, mAccountId, mControllerCallback, tag);
mMessageId, mAccountId, mControllerCallback);
}
private void onViewAttachment(AttachmentInfo attachment) {
LoadAttachTag tag = new LoadAttachTag(false, attachment.name);
mLoadAttachmentId = attachment.attachmentId;
mLoadAttachmentSave = false;
mLoadAttachmentName = attachment.name;
Controller.getInstance(getApplication()).loadAttachment(attachment.attachmentId,
mMessageId, mAccountId, mControllerCallback, tag);
mMessageId, mAccountId, mControllerCallback);
}
private void onShowPictures() {
@ -1188,40 +1193,26 @@ public class MessageView extends Activity
}
}
/**
* Passed-back tag for Controller.loadAttachmentCallback
*/
private static class LoadAttachTag {
boolean save; // false = view, true = save
String name; // the server-side name of the attachment
LoadAttachTag(boolean _save, String _name) {
save = _save;
name = _name;
}
}
/**
* Controller results listener. This completely replaces MessagingListener
*/
class ControllerResults implements Controller.Result {
public void loadAttachmentCallback(MessagingException result, long messageId,
long attachmentId, int progress, Object tag) {
long attachmentId, int progress) {
if (messageId == MessageView.this.mMessageId) {
LoadAttachTag tagInfo = (LoadAttachTag) tag;
if (result == null) {
switch (progress) {
case 0:
mHandler.setAttachmentsEnabled(false);
mHandler.progress(true, tagInfo.name);
mHandler.attachmentProgress(true);
mHandler.fetchingAttachment();
break;
case 100:
mHandler.setAttachmentsEnabled(true);
mHandler.progress(false, null);
mHandler.attachmentProgress(false);
updateAttachmentThumbnail(attachmentId);
mHandler.finishLoadAttachment(attachmentId, tagInfo.save);
mHandler.finishLoadAttachment(attachmentId);
break;
default:
// do nothing - we don't have a progress bar at this time
@ -1229,7 +1220,7 @@ public class MessageView extends Activity
}
} else {
mHandler.setAttachmentsEnabled(true);
mHandler.progress(false, null);
mHandler.attachmentProgress(false);
mHandler.networkError();
}
}
@ -1401,7 +1392,7 @@ public class MessageView extends Activity
Part part, Object tag, boolean requiresDownload) {
mHandler.setAttachmentsEnabled(false);
Object[] params = (Object[]) tag;
mHandler.progress(true, ((AttachmentInfo) params[1]).name);
// mHandler.progress(true, ((AttachmentInfo) params[1]).name);
if (requiresDownload) {
mHandler.fetchingAttachment();
}
@ -1411,7 +1402,7 @@ public class MessageView extends Activity
public void loadAttachmentFinished(Account account, com.android.email.mail.Message message,
Part part, Object tag) {
mHandler.setAttachmentsEnabled(true);
mHandler.progress(false, null);
// mHandler.progress(false, null);
// updateAttachmentThumbnail(part);
Object[] params = (Object[]) tag;
@ -1459,7 +1450,7 @@ public class MessageView extends Activity
public void loadAttachmentFailed(Account account, com.android.email.mail.Message message,
Part part, Object tag, String reason) {
mHandler.setAttachmentsEnabled(true);
mHandler.progress(false, null);
// mHandler.progress(false, null);
mHandler.networkError();
}
@ -1497,14 +1488,18 @@ public class MessageView extends Activity
* @param save If true, save to SD card. If false, send view intent
* @param attachmentId the attachment that was just downloaded
*/
private void doFinishLoadAttachment(boolean save, long attachmentId) {
private void doFinishLoadAttachment(long attachmentId) {
// If the result does't line up, just skip it - we handle one at a time.
if (attachmentId != mLoadAttachmentId) {
return;
}
Attachment attachment =
Attachment.restoreAttachmentWithId(MessageView.this, attachmentId);
Uri attachmentUri = AttachmentProvider.getAttachmentUri(mAccountId, attachment.mId);
Uri contentUri =
AttachmentProvider.resolveAttachmentIdToContentUri(getContentResolver(), attachmentUri);
if (save) {
if (mLoadAttachmentSave) {
try {
File file = createUniqueFile(Environment.getExternalStorageDirectory(),
attachment.mFileName);

View File

@ -220,8 +220,7 @@ public class EmailServiceProxy implements IEmailService {
setTask(new Runnable () {
public void run() {
try {
if (mCallback != null) mService.setCallback(mCallback);
mService.setCallback(cb);
mService.setCallback(cb);
} catch (RemoteException e) {
}
}

View File

@ -20,32 +20,32 @@ package com.android.exchange;
oneway interface IEmailServiceCallback {
/*
* Ordinary results:
* statuscode = 0, progress = 0: "starting"
* statuscode = 0, progress = 100: "finished"
* statuscode = 1, progress = 0: "starting"
* statuscode = 0, progress = n/a: "finished"
*
* If there is an error, it must be reported as follows:
* statuscode != 0, progress = n/a: "stopping due to error"
* statuscode = err, progress = n/a: "stopping due to error"
*
* *Optionally* a callback can also include intermediate values from 1..99 e.g.
* statuscode = 0, progress = 0: "starting"
* statuscode = 0, progress = 30: "working"
* statuscode = 0, progress = 60: "working"
* statuscode = 0, progress = 100: "finished"
* statuscode = 1, progress = 0: "starting"
* statuscode = 1, progress = 30: "working"
* statuscode = 1, progress = 60: "working"
* statuscode = 0, progress = n/a: "finished"
*/
/**
* Callback to indicate that an account is being synced (updating folder list)
* accountId = the account being synced
* statusCode = 0 for OK, != 0 for error
* progress = 0 for "start", 1..99 (if available), 100 for "finished"
* statusCode = 0 for OK, 1 for progress, other codes for error
* progress = 0 for "start", 1..100 for optional progress reports
*/
void syncMailboxListStatus(long accountId, int statusCode, int progress);
/**
* Callback to indicate that a mailbox is being synced
* mailboxId = the mailbox being synced
* statusCode = 0 for OK, != 0 for error
* progress = 0 for "start", 1..99 (if available), 100 for "finished"
* statusCode = 0 for OK, 1 for progress, other codes for error
* progress = 0 for "start", 1..100 for optional progress reports
*/
void syncMailboxStatus(long mailboxId, int statusCode, int progress);
@ -53,21 +53,16 @@ oneway interface IEmailServiceCallback {
* Callback to indicate that a particular attachment is being synced
* messageId = the message that owns the attachment
* attachmentId = the attachment being synced
* statusCode = 0 for OK, != 0 for error
* progress = 0 for "start", 1..99 (if available), 100 for "finished"
* statusCode = 0 for OK, 1 for progress, other codes for error
* progress = 0 for "start", 1..100 for optional progress reports
*/
void loadAttachmentStatus(long messageId, long attachmentId, int statusCode, int progress);
/**
* Callback to indicate that a particular message is being sent
* messageId = the message being sent
* statusCode = 0 for OK, != 0 for error
* progress = 0 for "start", 1..99 (if available), 100 for "finished"
* statusCode = 0 for OK, 1 for progress, other codes for error
* progress = 0 for "start", 1..100 for optional progress reports
*/
void sendMessageStatus(long messageId, int statusCode, int progress);
/**
* Deprecated
*/
void status(long messageId, long attachmentId, int statusCode, int progress);
}
}