Delete most of IEmailServiceCallback.

The old callback mechanism is deprecated, in favor of making
calls on the ContentProvider.

Bug: 9842867

Change-Id: I65f559e593cda24456c4ffb96f785e054626dd0b
This commit is contained in:
Yu Ping Hu 2013-07-29 19:11:41 -07:00
parent c362f66ee1
commit 2075c97f60
15 changed files with 90 additions and 460 deletions

View File

@ -1,118 +0,0 @@
/* Copyright (C) 2012 The Android Open Source Project.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.emailcommon.service;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import com.android.emailcommon.service.IEmailServiceCallback.Stub;
import com.android.mail.utils.LogUtils;
public class EmailServiceCallback extends Stub {
private final RemoteCallbackList<IEmailServiceCallback> mCallbackList;
public EmailServiceCallback(RemoteCallbackList<IEmailServiceCallback> callbackList) {
mCallbackList = callbackList;
}
/**
* Broadcast a callback to the everyone that's registered
*
* @param wrapper the ServiceCallbackWrapper used in the broadcast
*/
private synchronized void broadcastCallback(ServiceCallbackWrapper wrapper) {
RemoteCallbackList<IEmailServiceCallback> callbackList = mCallbackList;
if (callbackList != null) {
// Call everyone on our callback list
int count = callbackList.beginBroadcast();
try {
for (int i = 0; i < count; i++) {
try {
wrapper.call(callbackList.getBroadcastItem(i));
} catch (RemoteException e) {
// Safe to ignore
} catch (RuntimeException e) {
// We don't want an exception in one call to prevent other calls, so
// we'll just log this and continue
LogUtils.e("EmailServiceCallback", "Caught RuntimeException in broadcast",
e);
}
}
} finally {
// No matter what, we need to finish the broadcast
callbackList.finishBroadcast();
}
}
}
@Override
public void loadAttachmentStatus(final long messageId, final long attachmentId,
final int status, final int progress) {
broadcastCallback(new ServiceCallbackWrapper() {
@Override
public void call(IEmailServiceCallback cb) throws RemoteException {
cb.loadAttachmentStatus(messageId, attachmentId, status, progress);
}
});
}
@Override
public void loadMessageStatus(final long messageId, final int status, final int progress) {
broadcastCallback(new ServiceCallbackWrapper() {
@Override
public void call(IEmailServiceCallback cb) throws RemoteException {
cb.loadMessageStatus(messageId, status, progress);
}
});
}
@Override
public void sendMessageStatus(final long messageId, final String subject, final int status,
final int progress) {
broadcastCallback(new ServiceCallbackWrapper() {
@Override
public void call(IEmailServiceCallback cb) throws RemoteException {
cb.sendMessageStatus(messageId, subject, status, progress);
}
});
}
@Override
public void syncMailboxListStatus(final long accountId, final int status,
final int progress) {
broadcastCallback(new ServiceCallbackWrapper() {
@Override
public void call(IEmailServiceCallback cb) throws RemoteException {
cb.syncMailboxListStatus(accountId, status, progress);
}
});
}
@Override
public void syncMailboxStatus(final long mailboxId, final int status,
final int progress) {
broadcastCallback(new ServiceCallbackWrapper() {
@Override
public void call(IEmailServiceCallback cb) throws RemoteException {
cb.syncMailboxStatus(mailboxId, status, progress);
}
});
}
private interface ServiceCallbackWrapper {
public void call(IEmailServiceCallback cb) throws RemoteException;
}
}

View File

@ -62,7 +62,6 @@ public class EmailServiceProxy extends ServiceProxy implements IEmailService {
public static final String VALIDATE_BUNDLE_PROTOCOL_VERSION = "validate_protocol_version";
public static final String VALIDATE_BUNDLE_REDIRECT_ADDRESS = "validate_redirect_address";
private final IEmailServiceCallback mCallback;
private Object mReturn = null;
private IEmailService mService;
private final boolean isRemote;
@ -78,31 +77,25 @@ public class EmailServiceProxy extends ServiceProxy implements IEmailService {
// The first two constructors are used with local services that can be referenced by class
public EmailServiceProxy(Context _context, Class<?> _class) {
this(_context, _class, null);
}
public EmailServiceProxy(Context _context, Class<?> _class, IEmailServiceCallback _callback) {
super(_context, new Intent(_context, _class));
TempDirectory.setTempDirectory(_context);
mCallback = _callback;
isRemote = false;
}
// The following two constructors are used with remote services that must be referenced by
// a known action or by a prebuilt intent
public EmailServiceProxy(Context _context, Intent _intent, IEmailServiceCallback _callback) {
public EmailServiceProxy(Context _context, Intent _intent) {
super(_context, _intent);
try {
Device.getDeviceId(_context);
} catch (IOException e) {
}
TempDirectory.setTempDirectory(_context);
mCallback = _callback;
isRemote = true;
}
public EmailServiceProxy(Context _context, String _action, IEmailServiceCallback _callback) {
this(_context, new Intent(_action), _callback);
public EmailServiceProxy(Context _context, String _action) {
this(_context, new Intent(_action));
}
@Override
@ -138,13 +131,12 @@ public class EmailServiceProxy extends ServiceProxy implements IEmailService {
@Override
public void run() throws RemoteException {
try {
if (mCallback != null) mService.setCallback(mCallback);
mService.loadAttachment(mCallback, attachmentId, background);
mService.loadAttachment(cb, attachmentId, background);
} catch (RemoteException e) {
try {
// Try to send a callback (if set)
if (mCallback != null) {
mCallback.loadAttachmentStatus(-1, attachmentId,
if (cb != null) {
cb.loadAttachmentStatus(-1, attachmentId,
EmailServiceStatus.REMOTE_EXCEPTION, 0);
}
} catch (RemoteException e1) {
@ -171,7 +163,6 @@ public class EmailServiceProxy extends ServiceProxy implements IEmailService {
setTask(new ProxyTask() {
@Override
public void run() throws RemoteException {
if (mCallback != null) mService.setCallback(mCallback);
mService.startSync(mailboxId, userRequest, deltaMessageCount);
}
}, "startSync");
@ -189,7 +180,6 @@ public class EmailServiceProxy extends ServiceProxy implements IEmailService {
setTask(new ProxyTask() {
@Override
public void run() throws RemoteException {
if (mCallback != null) mService.setCallback(mCallback);
mService.stopSync(mailboxId);
}
}, "stopSync");
@ -210,7 +200,6 @@ public class EmailServiceProxy extends ServiceProxy implements IEmailService {
setTask(new ProxyTask() {
@Override
public void run() throws RemoteException{
if (mCallback != null) mService.setCallback(mCallback);
mReturn = mService.validate(hostAuth);
}
}, "validate");
@ -243,7 +232,6 @@ public class EmailServiceProxy extends ServiceProxy implements IEmailService {
setTask(new ProxyTask() {
@Override
public void run() throws RemoteException{
if (mCallback != null) mService.setCallback(mCallback);
mReturn = mService.autoDiscover(userName, password);
}
}, "autoDiscover");
@ -270,7 +258,6 @@ public class EmailServiceProxy extends ServiceProxy implements IEmailService {
setTask(new ProxyTask() {
@Override
public void run() throws RemoteException {
if (mCallback != null) mService.setCallback(mCallback);
mService.updateFolderList(accountId);
}
}, "updateFolderList");
@ -287,28 +274,11 @@ public class EmailServiceProxy extends ServiceProxy implements IEmailService {
setTask(new ProxyTask() {
@Override
public void run() throws RemoteException {
if (mCallback != null) mService.setCallback(mCallback);
mService.setLogging(flags);
}
}, "setLogging");
}
/**
* Set the global callback object to be used by the service; the service MUST always use the
* most recently set callback object
*
* @param cb a callback object through which all service callbacks are executed
*/
@Override
public void setCallback(final IEmailServiceCallback cb) throws RemoteException {
setTask(new ProxyTask() {
@Override
public void run() throws RemoteException {
mService.setCallback(cb);
}
}, "setCallback");
}
/**
* Alert the sync adapter that the account's host information has (or may have) changed; the
* service MUST stop all in-process or pending syncs, clear error states related to the
@ -338,7 +308,6 @@ public class EmailServiceProxy extends ServiceProxy implements IEmailService {
setTask(new ProxyTask() {
@Override
public void run() throws RemoteException {
if (mCallback != null) mService.setCallback(mCallback);
mService.sendMeetingResponse(messageId, response);
}
}, "sendMeetingResponse");
@ -354,7 +323,6 @@ public class EmailServiceProxy extends ServiceProxy implements IEmailService {
setTask(new ProxyTask() {
@Override
public void run() throws RemoteException {
if (mCallback != null) mService.setCallback(mCallback);
mService.loadMore(messageId);
}
}, "startSync");
@ -433,7 +401,6 @@ public class EmailServiceProxy extends ServiceProxy implements IEmailService {
setTask(new ProxyTask() {
@Override
public void run() throws RemoteException{
if (mCallback != null) mService.setCallback(mCallback);
mReturn = mService.searchMessages(accountId, searchParams, destMailboxId);
}
}, "searchMessages");
@ -455,7 +422,6 @@ public class EmailServiceProxy extends ServiceProxy implements IEmailService {
setTask(new ProxyTask() {
@Override
public void run() throws RemoteException{
if (mCallback != null) mService.setCallback(mCallback);
mService.sendMail(accountId);
}
}, "sendMail");
@ -466,7 +432,6 @@ public class EmailServiceProxy extends ServiceProxy implements IEmailService {
setTask(new ProxyTask() {
@Override
public void run() throws RemoteException{
if (mCallback != null) mService.setCallback(mCallback);
mReturn = mService.getCapabilities(acct);
}
}, "getCapabilities");
@ -487,7 +452,6 @@ public class EmailServiceProxy extends ServiceProxy implements IEmailService {
setTask(new ProxyTask() {
@Override
public void run() throws RemoteException{
if (mCallback != null) mService.setCallback(mCallback);
mService.serviceUpdated(emailAddress);
}
}, "settingsUpdate");

View File

@ -64,11 +64,6 @@ public abstract class EmailServiceStatus {
// Values for the SYNC_STATUS_TYPE to specify what kind of sync status we're returning.
public static final int SYNC_STATUS_TYPE_MAILBOX = 0;
public static final int SYNC_STATUS_TYPE_SEND_MESSAGE = 1;
public static final int SYNC_STATUS_TYPE_MAILBOX_LIST = 2;
// Additional status Bundle keys, used for specific status types.
public static final String SYNC_STATUS_SUBJECT = "subject";
/**
* Some status updates need to provide values in addition to the core id, code, and progress.
@ -125,30 +120,4 @@ public abstract class EmailServiceStatus {
syncStatus(cr, syncExtras, SYNC_STATUS_TYPE_MAILBOX, mailboxId, statusCode, progress, null);
}
/**
* If the sync extras specify a callback, then notify the sync requester of the outbound
* message status. This function is for use by the
* {@link android.content.AbstractThreadedSyncAdapter}.
* @param cr A ContentResolver.
* @param syncExtras The extras provided to the sync request.
* @param messageId The message that is being sent.
* @param subject The subject line of that message, or null if the subject is unavailable.
* @param statusCode The status code for this sync operation.
* @param progress The progress of this sync operation.
*/
public static void sendMessageStatus(final ContentResolver cr, final Bundle syncExtras,
final long messageId, final String subject, final int statusCode, final int progress) {
syncStatus(cr, syncExtras, SYNC_STATUS_TYPE_SEND_MESSAGE, messageId, statusCode, progress,
new StatusWriter() {
@Override
public void addToStatus(final Bundle statusExtras) {
statusExtras.putString(SYNC_STATUS_SUBJECT, subject);
}});
}
public static void syncMailboxListStatus(final ContentResolver cr, final Bundle syncExtras,
final long accountId, final int statusCode, final int progress) {
syncStatus(cr, syncExtras, SYNC_STATUS_TYPE_MAILBOX_LIST, accountId, statusCode, progress,
null);
}
}

View File

@ -39,10 +39,6 @@ interface IEmailService {
boolean deleteFolder(long accountId, String name);
boolean renameFolder(long accountId, String oldName, String newName);
// Must not be oneway; unless an exception is thrown, the caller is guaranteed that the callback
// has been registered
void setCallback(IEmailServiceCallback cb);
oneway void setLogging(int on);
oneway void hostChanged(long accountId);

View File

@ -33,22 +33,6 @@ oneway interface IEmailServiceCallback {
* 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, 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, 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);
/**
* Callback to indicate that a particular attachment is being synced
* messageId = the message that owns the attachment
@ -57,20 +41,4 @@ oneway interface IEmailServiceCallback {
* 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, 1 for progress, other codes for error
* progress = 0 for "start", 1..100 for optional progress reports
*/
void sendMessageStatus(long messageId, String subject, int statusCode, int progress);
/**
* Callback to indicate that a particular message is being loaded
* messageId = the message being sent
* statusCode = 0 for OK, 1 for progress, other codes for error
* progress = 0 for "start", 1..100 for optional progress reports
*/
void loadMessageStatus(long messageId, int statusCode, int progress);
}

View File

@ -1223,16 +1223,6 @@ public abstract class SyncManager extends Service implements Runnable {
int syncStatus = EmailContent.SYNC_STATUS_BACKGROUND;
// Don't sync if there's no connectivity
if (sConnectivityHold || (m == null) || sStop) {
if (reason >= SYNC_CALLBACK_START) {
try {
Stub proxy = getCallbackProxy();
if (proxy != null) {
proxy.syncMailboxStatus(m.mId, EmailServiceStatus.CONNECTION_ERROR, 0);
}
} catch (RemoteException e) {
// We tried...
}
}
return;
}
synchronized (sSyncLock) {

View File

@ -344,7 +344,7 @@ public class AccountSetupOptions extends AccountSetupActivity implements OnClick
saveAccountAndFinish();
// Update the folder list (to get our starting folders, e.g. Inbox)
EmailServiceProxy proxy = EmailServiceUtils.getServiceForAccount(this, null, account.mId);
EmailServiceProxy proxy = EmailServiceUtils.getServiceForAccount(this, account.mId);
try {
proxy.updateFolderList(account.mId);
} catch (RemoteException e) {

View File

@ -50,7 +50,7 @@ public class ServiceStore extends Store {
}
private IEmailService getService() {
return EmailServiceUtils.getService(mContext, null, mHostAuth.mProtocol);
return EmailServiceUtils.getService(mContext, mHostAuth.mProtocol);
}
@Override

View File

@ -78,7 +78,6 @@ import com.android.emailcommon.provider.QuickResponse;
import com.android.emailcommon.service.EmailServiceProxy;
import com.android.emailcommon.service.EmailServiceStatus;
import com.android.emailcommon.service.IEmailService;
import com.android.emailcommon.service.IEmailServiceCallback;
import com.android.emailcommon.service.SearchParams;
import com.android.emailcommon.utility.AttachmentUtilities;
import com.android.emailcommon.utility.Utility;
@ -1534,41 +1533,19 @@ public class EmailProvider extends ContentProvider {
return result;
}
private void updateSyncStatus(final Bundle extras) {
final long id = extras.getLong(EmailServiceStatus.SYNC_STATUS_ID);
final Uri uri = ContentUris.withAppendedId(FOLDER_STATUS_URI, id);
EmailProvider.this.getContext().getContentResolver().notifyChange(uri, null);
}
@Override
public Bundle call(String method, String arg, Bundle extras) {
LogUtils.d(TAG, "EmailProvider#call(%s, %s)", method, arg);
// First handle sync status callbacks.
// Handle sync status callbacks.
if (TextUtils.equals(method, SYNC_STATUS_CALLBACK_METHOD)) {
final int syncStatusType = extras.getInt(EmailServiceStatus.SYNC_STATUS_TYPE);
try {
switch (syncStatusType) {
case EmailServiceStatus.SYNC_STATUS_TYPE_MAILBOX:
mServiceCallback.syncMailboxStatus(
extras.getLong(EmailServiceStatus.SYNC_STATUS_ID),
extras.getInt(EmailServiceStatus.SYNC_STATUS_CODE),
extras.getInt(EmailServiceStatus.SYNC_STATUS_PROGRESS));
break;
case EmailServiceStatus.SYNC_STATUS_TYPE_SEND_MESSAGE:
mServiceCallback.sendMessageStatus(
extras.getLong(EmailServiceStatus.SYNC_STATUS_ID),
extras.getString(EmailServiceStatus.SYNC_STATUS_SUBJECT),
extras.getInt(EmailServiceStatus.SYNC_STATUS_CODE),
extras.getInt(EmailServiceStatus.SYNC_STATUS_PROGRESS));
break;
case EmailServiceStatus.SYNC_STATUS_TYPE_MAILBOX_LIST:
mServiceCallback.syncMailboxListStatus(
extras.getLong(EmailServiceStatus.SYNC_STATUS_ID),
extras.getInt(EmailServiceStatus.SYNC_STATUS_CODE),
extras.getInt(EmailServiceStatus.SYNC_STATUS_PROGRESS));
break;
default:
LogUtils.e(TAG, "Sync status received of unknown type %d", syncStatusType);
break;
}
} catch (RemoteException re) {
// This can't actually happen but I have to pacify the compiler.
}
updateSyncStatus(extras);
return null;
}
@ -2488,8 +2465,8 @@ public class EmailProvider extends ContentProvider {
}
private int getCapabilities(Context context, long accountId) {
final EmailServiceProxy service = EmailServiceUtils.getServiceForAccount(context,
mServiceCallback, accountId);
final EmailServiceProxy service =
EmailServiceUtils.getServiceForAccount(context, accountId);
int capabilities = 0;
Account acct = null;
try {
@ -4075,8 +4052,8 @@ public class EmailProvider extends ContentProvider {
// Special case - meeting response
if (values.containsKey(UIProvider.MessageOperations.RESPOND_COLUMN)) {
EmailServiceProxy service = EmailServiceUtils.getServiceForAccount(context,
mServiceCallback, mailbox.mAccountKey);
final EmailServiceProxy service =
EmailServiceUtils.getServiceForAccount(context, mailbox.mAccountKey);
try {
service.sendMeetingResponse(msg.mId,
values.getAsInteger(UIProvider.MessageOperations.RESPOND_COLUMN));
@ -4282,42 +4259,6 @@ public class EmailProvider extends ContentProvider {
notifyUI(uri, Long.toString(id));
}
/**
* Support for services and service notifications
*/
private final IEmailServiceCallback.Stub mServiceCallback =
new IEmailServiceCallback.Stub() {
@Override
public void syncMailboxListStatus(long accountId, int statusCode, int progress)
throws RemoteException {
}
@Override
public void syncMailboxStatus(long mailboxId, int statusCode, int progress)
throws RemoteException {
// We'll get callbacks here from the services, which we'll pass back to the UI
Uri uri = ContentUris.withAppendedId(FOLDER_STATUS_URI, mailboxId);
EmailProvider.this.getContext().getContentResolver().notifyChange(uri, null);
}
@Override
public void loadAttachmentStatus(long messageId, long attachmentId, int statusCode,
int progress) throws RemoteException {
}
@Override
public void sendMessageStatus(long messageId, String subject, int statusCode, int progress)
throws RemoteException {
}
@Override
public void loadMessageStatus(long messageId, int statusCode, int progress)
throws RemoteException {
}
};
private Mailbox getMailbox(final Uri uri) {
final long id = Long.parseLong(uri.getLastPathSegment());
return Mailbox.restoreMailboxWithId(getContext(), id);
@ -4447,8 +4388,8 @@ public class EmailProvider extends ContentProvider {
new AsyncTask<Void, Void, Void>() {
@Override
public Void doInBackground(Void... params) {
final EmailServiceProxy service = EmailServiceUtils.getServiceForAccount(
context, mServiceCallback, accountId);
final EmailServiceProxy service =
EmailServiceUtils.getServiceForAccount(context, accountId);
if (service != null) {
try {
// Save away the total count
@ -4588,7 +4529,7 @@ public class EmailProvider extends ContentProvider {
// Delete PIM data (contacts, calendar), stop syncs, etc. if applicable
if (emailAddress != null) {
final IEmailService service =
EmailServiceUtils.getServiceForAccount(context, null, accountId);
EmailServiceUtils.getServiceForAccount(context, accountId);
if (service != null) {
try {
service.deleteAccountPIMData(emailAddress);

View File

@ -452,7 +452,7 @@ public class AttachmentDownloadService extends Service implements Runnable {
*/
/*package*/ synchronized boolean tryStartDownload(DownloadRequest req) {
EmailServiceProxy service = EmailServiceUtils.getServiceForAccount(
AttachmentDownloadService.this, mServiceCallback, req.accountId);
AttachmentDownloadService.this, req.accountId);
// Do not download the same attachment multiple times
boolean alreadyInProgress = mDownloadsInProgress.get(req.attachmentId) != null;
@ -595,7 +595,7 @@ public class AttachmentDownloadService extends Service implements Runnable {
+ req.messageId);
}
EmailServiceProxy service = EmailServiceUtils.getServiceForAccount(
mContext, null, accountId);
mContext, accountId);
try {
service.sendMail(accountId);
} catch (RemoteException e) {
@ -701,26 +701,6 @@ public class AttachmentDownloadService extends Service implements Runnable {
break;
}
}
@Override
public void syncMailboxListStatus(long accountId, int statusCode, int progress)
throws RemoteException {
}
@Override
public void syncMailboxStatus(long mailboxId, int statusCode, int progress)
throws RemoteException {
}
@Override
public void sendMessageStatus(long messageId, String subject, int statusCode, int progress)
throws RemoteException {
}
@Override
public void loadMessageStatus(long messageId, int statusCode, int progress)
throws RemoteException {
}
}
/*package*/ void addServiceIntentForTest(long accountId, Intent intent) {

View File

@ -96,11 +96,9 @@ public abstract class EmailServiceStub extends IEmailService.Stub implements IEm
};
protected Context mContext;
private IEmailServiceCallback.Stub mCallback;
protected void init(Context context, IEmailServiceCallback.Stub callbackProxy) {
protected void init(Context context) {
mContext = context;
mCallback = callbackProxy;
}
@Override
@ -147,13 +145,10 @@ public abstract class EmailServiceStub extends IEmailService.Stub implements IEm
EmailContent.Message message =
EmailContent.Message.restoreMessageWithId(mContext, messageId);
if (message == null) {
mCallback.loadMessageStatus(messageId,
EmailServiceStatus.MESSAGE_NOT_FOUND, 0);
return;
}
if (message.mFlagLoaded == EmailContent.Message.FLAG_LOADED_COMPLETE) {
// We should NEVER get here
mCallback.loadMessageStatus(messageId, 0, 100);
return;
}
@ -186,28 +181,14 @@ public abstract class EmailServiceStub extends IEmailService.Stub implements IEm
// 4. Write to provider
Utilities.copyOneMessageToProvider(mContext, remoteMessage, account, mailbox,
EmailContent.Message.FLAG_LOADED_COMPLETE);
// 5. Notify UI
mCallback.loadMessageStatus(messageId, 0, 100);
} catch (MessagingException me) {
if (Logging.LOGD) LogUtils.v(Logging.LOG_TAG, "", me);
mCallback.loadMessageStatus(messageId, EmailServiceStatus.REMOTE_EXCEPTION, 0);
} catch (RuntimeException rte) {
mCallback.loadMessageStatus(messageId, EmailServiceStatus.REMOTE_EXCEPTION, 0);
}
}
private void doProgressCallback(long messageId, long attachmentId, int progress) {
try {
mCallback.loadAttachmentStatus(messageId, attachmentId,
EmailServiceStatus.IN_PROGRESS, progress);
} catch (RemoteException e) {
// No danger if the client is no longer around
}
}
// TODO: Switch from using setCallback to the explicitly passed callback.
@Override
public void loadAttachment(final IEmailServiceCallback cb, final long attachmentId,
final boolean background) throws RemoteException {
@ -216,7 +197,7 @@ public abstract class EmailServiceStub extends IEmailService.Stub implements IEm
Attachment attachment =
Attachment.restoreAttachmentWithId(mContext, attachmentId);
if (attachment == null) {
mCallback.loadAttachmentStatus(0, attachmentId,
cb.loadAttachmentStatus(0, attachmentId,
EmailServiceStatus.ATTACHMENT_NOT_FOUND, 0);
return;
}
@ -225,19 +206,19 @@ public abstract class EmailServiceStub extends IEmailService.Stub implements IEm
EmailContent.Message message =
EmailContent.Message.restoreMessageWithId(mContext, attachment.mMessageKey);
if (message == null) {
mCallback.loadAttachmentStatus(messageId, attachmentId,
cb.loadAttachmentStatus(messageId, attachmentId,
EmailServiceStatus.MESSAGE_NOT_FOUND, 0);
}
// If the message is loaded, just report that we're finished
if (Utility.attachmentExists(mContext, attachment)) {
mCallback.loadAttachmentStatus(messageId, attachmentId, EmailServiceStatus.SUCCESS,
cb.loadAttachmentStatus(messageId, attachmentId, EmailServiceStatus.SUCCESS,
0);
return;
}
// Say we're starting...
doProgressCallback(messageId, attachmentId, 0);
cb.loadAttachmentStatus(messageId, attachmentId, EmailServiceStatus.IN_PROGRESS, 0);
// 2. Open the remote folder.
Account account = Account.restoreAccountWithId(mContext, message.mAccountKey);
@ -260,7 +241,7 @@ public abstract class EmailServiceStub extends IEmailService.Stub implements IEm
if (account == null || mailbox == null) {
// If the account/mailbox are gone, just report success; the UI handles this
mCallback.loadAttachmentStatus(messageId, attachmentId,
cb.loadAttachmentStatus(messageId, attachmentId,
EmailServiceStatus.SUCCESS, 0);
return;
}
@ -297,7 +278,7 @@ public abstract class EmailServiceStub extends IEmailService.Stub implements IEm
FetchProfile fp = new FetchProfile();
fp.add(storePart);
remoteFolder.fetch(new Message[] { storeMessage }, fp,
new MessageRetrievalListenerBridge(messageId, attachmentId));
new MessageRetrievalListenerBridge(messageId, attachmentId, cb));
// If we failed to load the attachment, throw an Exception here, so that
// AttachmentDownloadService knows that we failed
@ -310,7 +291,7 @@ public abstract class EmailServiceStub extends IEmailService.Stub implements IEm
attachment);
// 6. Report success
mCallback.loadAttachmentStatus(messageId, attachmentId, EmailServiceStatus.SUCCESS, 0);
cb.loadAttachmentStatus(messageId, attachmentId, EmailServiceStatus.SUCCESS, 0);
// Close the connection
remoteFolder.close(false);
@ -324,7 +305,7 @@ public abstract class EmailServiceStub extends IEmailService.Stub implements IEm
Uri uri = ContentUris.withAppendedId(Attachment.CONTENT_URI, attachmentId);
mContext.getContentResolver().update(uri, cv, null, null);
mCallback.loadAttachmentStatus(0, attachmentId, EmailServiceStatus.CONNECTION_ERROR, 0);
cb.loadAttachmentStatus(0, attachmentId, EmailServiceStatus.CONNECTION_ERROR, 0);
}
}
@ -336,15 +317,24 @@ public abstract class EmailServiceStub extends IEmailService.Stub implements IEm
public class MessageRetrievalListenerBridge implements MessageRetrievalListener {
private final long mMessageId;
private final long mAttachmentId;
private final IEmailServiceCallback mCallback;
public MessageRetrievalListenerBridge(long messageId, long attachmentId) {
public MessageRetrievalListenerBridge(final long messageId, final long attachmentId,
final IEmailServiceCallback callback) {
mMessageId = messageId;
mAttachmentId = attachmentId;
mCallback = callback;
}
@Override
public void loadAttachmentProgress(int progress) {
doProgressCallback(mMessageId, mAttachmentId, progress);
try {
mCallback.loadAttachmentStatus(mMessageId, mAttachmentId,
EmailServiceStatus.IN_PROGRESS, progress);
} catch (final RemoteException e) {
// No danger if the client is no longer around
}
}
@Override
@ -450,11 +440,6 @@ public abstract class EmailServiceStub extends IEmailService.Stub implements IEm
return false;
}
@Override
public void setCallback(IEmailServiceCallback cb) throws RemoteException {
// Not required
}
@Override
public void setLogging(int on) throws RemoteException {
// Not required

View File

@ -112,7 +112,7 @@ public class EmailServiceUtils {
for (EmailServiceInfo info: getServiceInfoList(context)) {
if (info.intentAction != null) {
EmailServiceProxy service =
EmailServiceUtils.getService(context, null, info.protocol);
EmailServiceUtils.getService(context, info.protocol);
if (service != null) {
try {
service.setLogging(debugBits);
@ -131,7 +131,7 @@ public class EmailServiceUtils {
EmailServiceInfo info = getServiceInfo(context, protocol);
if (info == null) return false;
if (info.klass != null) return true;
return new EmailServiceProxy(context, info.intentAction, null).test();
return new EmailServiceProxy(context, info.intentAction).test();
}
/**
@ -140,9 +140,8 @@ public class EmailServiceUtils {
* @param accountId the message of interest
* @result service proxy, or null if n/a
*/
public static EmailServiceProxy getServiceForAccount(Context context,
IEmailServiceCallback callback, long accountId) {
return getService(context, callback, Account.getProtocol(context, accountId));
public static EmailServiceProxy getServiceForAccount(Context context, long accountId) {
return getService(context, Account.getProtocol(context, accountId));
}
/**
@ -191,8 +190,7 @@ public class EmailServiceUtils {
}
}
public static EmailServiceProxy getService(Context context, IEmailServiceCallback callback,
String protocol) {
public static EmailServiceProxy getService(Context context, String protocol) {
EmailServiceInfo info = null;
// Handle the degenerate case here (account might have been deleted)
if (protocol != null) {
@ -200,18 +198,17 @@ public class EmailServiceUtils {
}
if (info == null) {
LogUtils.w(Logging.LOG_TAG, "Returning NullService for " + protocol);
return new EmailServiceProxy(context, NullService.class, null);
return new EmailServiceProxy(context, NullService.class);
} else {
return getServiceFromInfo(context, callback, info);
return getServiceFromInfo(context, info);
}
}
public static EmailServiceProxy getServiceFromInfo(Context context,
IEmailServiceCallback callback, EmailServiceInfo info) {
public static EmailServiceProxy getServiceFromInfo(Context context, EmailServiceInfo info) {
if (info.klass != null) {
return new EmailServiceProxy(context, info.klass, callback);
return new EmailServiceProxy(context, info.klass);
} else {
return new EmailServiceProxy(context, info.intentAction, callback);
return new EmailServiceProxy(context, info.intentAction);
}
}
@ -584,10 +581,6 @@ public class EmailServiceUtils {
return false;
}
@Override
public void setCallback(IEmailServiceCallback cb) throws RemoteException {
}
@Override
public void setLogging(int on) throws RemoteException {
}

View File

@ -26,7 +26,6 @@ import android.database.Cursor;
import android.net.TrafficStats;
import android.net.Uri;
import android.os.IBinder;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.text.TextUtils;
@ -55,9 +54,7 @@ import com.android.emailcommon.provider.EmailContent.MailboxColumns;
import com.android.emailcommon.provider.EmailContent.MessageColumns;
import com.android.emailcommon.provider.EmailContent.SyncColumns;
import com.android.emailcommon.provider.Mailbox;
import com.android.emailcommon.service.EmailServiceCallback;
import com.android.emailcommon.service.EmailServiceStatus;
import com.android.emailcommon.service.IEmailServiceCallback;
import com.android.emailcommon.service.SearchParams;
import com.android.emailcommon.utility.AttachmentUtilities;
import com.android.mail.providers.UIProvider.AccountCapabilities;
@ -108,23 +105,10 @@ public class ImapService extends Service {
return Service.START_STICKY;
}
// Callbacks as set up via setCallback
private static final RemoteCallbackList<IEmailServiceCallback> mCallbackList =
new RemoteCallbackList<IEmailServiceCallback>();
private static final EmailServiceCallback sCallbackProxy =
new EmailServiceCallback(mCallbackList);
/**
* Create our EmailService implementation here.
*/
private final EmailServiceStub mBinder = new EmailServiceStub() {
@Override
public void setCallback(IEmailServiceCallback cb) throws RemoteException {
mCallbackList.register(cb);
}
@Override
public void loadMore(long messageId) throws RemoteException {
// We don't do "loadMore" for IMAP messages; the sync should handle this
@ -155,38 +139,28 @@ public class ImapService extends Service {
@Override
public IBinder onBind(Intent intent) {
mBinder.init(this, sCallbackProxy);
mBinder.init(this);
return mBinder;
}
private static void sendMailboxStatus(Mailbox mailbox, int status) {
sCallbackProxy.syncMailboxStatus(mailbox.mId, status, 0);
}
/**
* Start foreground synchronization of the specified folder. This is called by
* synchronizeMailbox or checkMail.
* TODO this should use ID's instead of fully-restored objects
* @param account
* @param folder
* @param deltaMessageCount requested change in number of messages to sync
* @return The status code for whether this operation succeeded.
* @throws MessagingException
*/
public static void synchronizeMailboxSynchronous(Context context, final Account account,
public static int synchronizeMailboxSynchronous(Context context, final Account account,
final Mailbox folder, final boolean loadMore) throws MessagingException {
sendMailboxStatus(folder, EmailServiceStatus.IN_PROGRESS);
TrafficStats.setThreadStatsTag(TrafficFlags.getSyncFlags(context, account));
if ((folder.mFlags & Mailbox.FLAG_HOLDS_MAIL) == 0) {
sendMailboxStatus(folder, EmailServiceStatus.SUCCESS);
}
NotificationController nc = NotificationController.getInstance(context);
try {
processPendingActionsSynchronous(context, account);
synchronizeMailboxGeneric(context, account, folder, loadMore);
// Clear authentication notification for this account
nc.cancelLoginFailedNotification(account.mId);
sendMailboxStatus(folder, EmailServiceStatus.SUCCESS);
} catch (MessagingException e) {
if (Logging.LOGD) {
LogUtils.v(Logging.LOG_TAG, "synchronizeMailboxSynchronous", e);
@ -195,9 +169,11 @@ public class ImapService extends Service {
// Generate authentication notification
nc.showLoginFailedNotification(account.mId);
}
sendMailboxStatus(folder, e.getExceptionType());
throw e;
}
// TODO: Rather than use exceptions as logic above, return the status and handle it
// correctly in caller.
return EmailServiceStatus.SUCCESS;
}
/**
@ -1502,4 +1478,4 @@ public class ImapService extends Service {
});
return numSearchResults;
}
}
}

View File

@ -26,7 +26,6 @@ import android.database.Cursor;
import android.net.TrafficStats;
import android.net.Uri;
import android.os.IBinder;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import com.android.email.NotificationController;
@ -49,7 +48,6 @@ import com.android.emailcommon.provider.EmailContent.Message;
import com.android.emailcommon.provider.EmailContent.MessageColumns;
import com.android.emailcommon.provider.EmailContent.SyncColumns;
import com.android.emailcommon.provider.Mailbox;
import com.android.emailcommon.service.EmailServiceCallback;
import com.android.emailcommon.service.EmailServiceStatus;
import com.android.emailcommon.service.IEmailServiceCallback;
import com.android.emailcommon.utility.AttachmentUtilities;
@ -73,29 +71,15 @@ public class Pop3Service extends Service {
return Service.START_STICKY;
}
// Callbacks as set up via setCallback
private static final RemoteCallbackList<IEmailServiceCallback> mCallbackList =
new RemoteCallbackList<IEmailServiceCallback>();
private static final EmailServiceCallback sCallbackProxy =
new EmailServiceCallback(mCallbackList);
/**
* Create our EmailService implementation here.
*/
private final EmailServiceStub mBinder = new EmailServiceStub() {
@Override
public void setCallback(IEmailServiceCallback cb) throws RemoteException {
mCallbackList.register(cb);
}
@Override
public int getCapabilities(Account acct) throws RemoteException {
return AccountCapabilities.UNDO;
}
// TODO: Switch from using the callback from setCallback to using the one passed here.
@Override
public void loadAttachment(final IEmailServiceCallback callback, final long attachmentId,
final boolean background) throws RemoteException {
@ -115,14 +99,10 @@ public class Pop3Service extends Service {
@Override
public IBinder onBind(Intent intent) {
mBinder.init(this, sCallbackProxy);
mBinder.init(this);
return mBinder;
}
private static void sendMailboxStatus(Mailbox mailbox, int status) {
sCallbackProxy.syncMailboxStatus(mailbox.mId, status, 0);
}
/**
* Start foreground synchronization of the specified folder. This is called
* by synchronizeMailbox or checkMail. TODO this should use ID's instead of
@ -131,22 +111,17 @@ public class Pop3Service extends Service {
* @param account
* @param folder
* @param deltaMessageCount the requested change in number of messages to sync.
* @return The status code for whether this operation succeeded.
* @throws MessagingException
*/
public static void synchronizeMailboxSynchronous(Context context, final Account account,
public static int synchronizeMailboxSynchronous(Context context, final Account account,
final Mailbox folder, final int deltaMessageCount) throws MessagingException {
sendMailboxStatus(folder, EmailServiceStatus.IN_PROGRESS);
TrafficStats.setThreadStatsTag(TrafficFlags.getSyncFlags(context, account));
if ((folder.mFlags & Mailbox.FLAG_HOLDS_MAIL) == 0) {
sendMailboxStatus(folder, EmailServiceStatus.SUCCESS);
}
NotificationController nc = NotificationController.getInstance(context);
try {
synchronizePop3Mailbox(context, account, folder, deltaMessageCount);
// Clear authentication notification for this account
nc.cancelLoginFailedNotification(account.mId);
sendMailboxStatus(folder, EmailServiceStatus.SUCCESS);
} catch (MessagingException e) {
if (Logging.LOGD) {
LogUtils.v(Logging.LOG_TAG, "synchronizeMailbox", e);
@ -155,9 +130,11 @@ public class Pop3Service extends Service {
// Generate authentication notification
nc.showLoginFailedNotification(account.mId);
}
sendMailboxStatus(folder, e.getExceptionType());
throw e;
}
// TODO: Rather than use exceptions as logic aobve, return the status and handle it
// correctly in caller.
return EmailServiceStatus.SUCCESS;
}
/**

View File

@ -39,6 +39,7 @@ import com.android.emailcommon.provider.EmailContent.AccountColumns;
import com.android.emailcommon.provider.EmailContent.Message;
import com.android.emailcommon.provider.Mailbox;
import com.android.emailcommon.service.EmailServiceProxy;
import com.android.emailcommon.service.EmailServiceStatus;
import com.android.mail.utils.LogUtils;
import java.util.ArrayList;
@ -96,8 +97,9 @@ public class PopImapSyncAdapterService extends Service {
return false;
}
private static void sync(Context context, long mailboxId, SyncResult syncResult,
boolean uiRefresh, int deltaMessageCount) {
private static void sync(final Context context, final long mailboxId,
final Bundle extras, final SyncResult syncResult, final boolean uiRefresh,
final int deltaMessageCount) {
TempDirectory.setTempDirectory(context);
Mailbox mailbox = Mailbox.restoreMailboxWithId(context, mailboxId);
if (mailbox == null) return;
@ -126,15 +128,22 @@ public class PopImapSyncAdapterService extends Service {
String legacyImapProtocol = context.getString(R.string.protocol_legacy_imap);
if (mailbox.mType == Mailbox.TYPE_OUTBOX) {
EmailServiceStub.sendMailImpl(context, account.mId);
} else if (protocol.equals(legacyImapProtocol)) {
ImapService.synchronizeMailboxSynchronous(context, account, mailbox,
deltaMessageCount != 0);
} else {
Pop3Service.synchronizeMailboxSynchronous(context, account, mailbox,
deltaMessageCount);
EmailServiceStatus.syncMailboxStatus(resolver, extras, mailboxId,
EmailServiceStatus.IN_PROGRESS, 0);
final int status;
if (protocol.equals(legacyImapProtocol)) {
status = ImapService.synchronizeMailboxSynchronous(context, account,
mailbox, deltaMessageCount != 0);
} else {
status = Pop3Service.synchronizeMailboxSynchronous(context, account,
mailbox, deltaMessageCount);
}
EmailServiceStatus.syncMailboxStatus(resolver, extras, mailboxId, status, 0);
}
} catch (MessagingException e) {
int cause = e.getExceptionType();
EmailServiceStatus.syncMailboxStatus(resolver, extras, mailboxId, cause, 0);
switch(cause) {
case MessagingException.IOERROR:
syncResult.stats.numIoExceptions++;
@ -190,7 +199,7 @@ public class PopImapSyncAdapterService extends Service {
}
}
for (long mailboxId: mailboxesToUpdate) {
sync(context, mailboxId, syncResult, false, 0);
sync(context, mailboxId, extras, syncResult, false, 0);
}
} else {
LogUtils.d(TAG, "Sync request for " + acct.mDisplayName);
@ -200,7 +209,7 @@ public class PopImapSyncAdapterService extends Service {
if (mailboxId == Mailbox.NO_MAILBOX) {
// Update folders.
EmailServiceProxy service =
EmailServiceUtils.getServiceForAccount(context, null, acct.mId);
EmailServiceUtils.getServiceForAccount(context, acct.mId);
service.updateFolderList(acct.mId);
mailboxId = Mailbox.findMailboxOfType(context, acct.mId,
Mailbox.TYPE_INBOX);
@ -210,7 +219,7 @@ public class PopImapSyncAdapterService extends Service {
extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false);
int deltaMessageCount =
extras.getInt(Mailbox.SYNC_EXTRA_DELTA_MESSAGE_COUNT, 0);
sync(context, mailboxId, syncResult, uiRefresh, deltaMessageCount);
sync(context, mailboxId, extras, syncResult, uiRefresh, deltaMessageCount);
}
}
} catch (Exception e) {
@ -221,4 +230,4 @@ public class PopImapSyncAdapterService extends Service {
}
}
}
}
}