Work on EmailService calls, attachment loading, etc.

* Stubbed in attachment loading in MessageView for EAS messages
* Modified MessageView.Listener to implement IEmailServiceCallback
  for testing callback functionality
* Rewrote EmailServiceProxy entirely
* Simplified loadAttachment service call
This commit is contained in:
Marc Blank 2009-07-19 20:10:35 -07:00
parent 53093871c4
commit 5790d1458f
10 changed files with 264 additions and 154 deletions

View File

@ -33,8 +33,12 @@ import com.android.email.provider.EmailContent.Account;
import com.android.email.provider.EmailContent.Attachment;
import com.android.email.provider.EmailContent.Body;
import com.android.email.provider.EmailContent.BodyColumns;
import com.android.email.provider.EmailContent.HostAuth;
import com.android.email.provider.EmailContent.Message;
import com.android.email.provider.EmailContent.MessageColumns;
import com.android.email.service.EmailServiceProxy;
import com.android.exchange.IEmailServiceCallback;
import com.android.exchange.SyncManager;
import android.app.Activity;
import android.app.ProgressDialog;
@ -53,6 +57,7 @@ import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.RemoteException;
import android.provider.Contacts;
import android.provider.Contacts.Intents;
import android.provider.Contacts.People;
@ -135,6 +140,28 @@ public class MessageView extends Activity
private String mFolder;
private String mMessageUid;
private Cursor mMessageListCursor;
private IEmailServiceCallback mServiceListener = new IEmailServiceCallback.Stub() {
/**
* Placeholder for IEmailService callbacks, which are used with Exchange
*
* @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
*
* NOTE The IEmailServiceCallback interface is likely to change
*/
public void status(long messageId, long attachmentId, int statusCode, int progress)
throws RemoteException {
Attachment att = Attachment.restoreAttachmentWithId(MessageView.this, attachmentId);
if (att != null) {
Log.i("Attachment Callback", "File: " + att.mFileName + ", Status: " + statusCode
+ ", Progress: " + progress);
}
}
};
// TODO all uses of this need to be converted to "mMessage". Then mOldMessage goes away.
private com.android.email.mail.Message mOldMessage;
@ -561,8 +588,7 @@ public class MessageView extends Activity
mMessage.mFlagFavorite = newFavorite;
ContentValues cv = new ContentValues();
cv.put(MessageColumns.FLAG_FAVORITE, newFavorite ? 1 : 0);
Uri uri = ContentUris.withAppendedId(
Message.SYNCED_CONTENT_URI, mMessageId);
Uri uri = ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, mMessageId);
getContentResolver().update(uri, cv, null, null);
}
}
@ -665,6 +691,28 @@ public class MessageView extends Activity
Toast.LENGTH_SHORT).show();
return;
}
// It's too complicated to go from an Attachment to the protocol that created it
// TODO Perhaps we should have Account include a protocol column
com.android.exchange.EmailContent.Attachment att =
com.android.exchange.EmailContent.Attachment.restoreAttachmentWithId(this,
attachment.attachmentId);
if (att != null) {
// Need account to get the HostAuth that includes the protocol
Account acct = Account.restoreAccountWithId(this, mMessage.mAccountKey);
// Need the hostauth to get the protocol
HostAuth ha = HostAuth.restoreHostAuthWithId(this, acct.mHostAuthKeyRecv);
if (ha.mProtocol.equals("eas")) {
try {
new EmailServiceProxy(this, SyncManager.class)
.loadAttachment(att.mId, mServiceListener);
} catch (RemoteException e) {
// TODO Change exception handling to be consistent with however this method
// is implemented for other protocols
Log.e("onDownloadAttachment", "RemoteException", e);
}
}
}
// MessagingController.getInstance(getApplication()).loadAttachment(
// mAccount,
// mOldMessage,
@ -1075,7 +1123,7 @@ public class MessageView extends Activity
protected void onPostExecute(Cursor cursor) {
while (cursor.moveToNext()) {
// load and capture one attachment
Attachment attachment = Attachment.getContent(cursor, Attachment.class);
Attachment attachment = new Attachment().restore(cursor);
addAttachment(attachment);
}
}
@ -1092,6 +1140,7 @@ public class MessageView extends Activity
private void reloadUiFromCursor(Cursor cursor) {
Message message = new Message().restore(cursor);
mMessage = message;
mAccountId = message.mAccountKey;
mSubjectView.setText(message.mSubject);
mFromView.setText(Address.toFriendly(Address.unpack(message.mFrom)));
@ -1196,6 +1245,12 @@ public class MessageView extends Activity
}
}
/**
* MessagingListener is the traditional form of callback used by the Email application; remote
* services (like Exchange) will use mServiceListener
*
* TODO: All of this needs to move to Controller
*/
class Listener extends MessagingListener {
@Override
public void loadMessageForViewHeadersAvailable(Account account, String folder,
@ -1265,9 +1320,10 @@ public class MessageView extends Activity
Matcher proto = WEB_URL_PROTOCOL.matcher(url);
String link;
if (proto.find()) {
// This is work around to force URL protocol part be lower case,
// because WebView could follow only lower case protocol link.
link = proto.group().toLowerCase() + url.substring(proto.end());
// Work around to force URL protocol part be lower case,
// since WebView could follow only lower case protocol link.
link = proto.group().toLowerCase()
+ url.substring(proto.end());
} else {
// Regex.WEB_URL_PATTERN matches URL without protocol part,
// so added default protocol to link.

View File

@ -274,21 +274,6 @@ public class ExchangeStore extends Store {
mPassword = uinfo[1];
}
/**
* Blocking call that checks for a useable server connection, credentials, etc.
* @param uri the server/account to try and connect to
* @throws MessagingException thrown if the connection, server, account are not useable
*/
IEmailServiceCallback mCallback = new IEmailServiceCallback () {
public void status(int statusCode, int progress) throws RemoteException {
Log.d("Status: ", "Code = " + statusCode + ", progress = " + progress);
}
public IBinder asBinder() { return null; }
};
/**
* Here's where we check the settings for EAS.
* @param uri the URI of the account to create
@ -298,8 +283,8 @@ public class ExchangeStore extends Store {
setUri(uri);
boolean ssl = uri.getScheme().contains("ssl+");
try {
IEmailService svc = EmailServiceProxy.getService(mContext, SyncManager.class);
int result = svc.validate("eas", mHost, mUsername, mPassword, ssl ? 443 : 80, ssl);
int result = new EmailServiceProxy(mContext, SyncManager.class)
.validate("eas", mHost, mUsername, mPassword, ssl ? 443 : 80, ssl);
if (result != MessagingException.NO_ERROR) {
if (result == MessagingException.AUTHENTICATION_FAILED) {
throw new AuthenticationFailedException("Authentication failed.");

View File

@ -44,7 +44,6 @@ import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.net.Uri;
import android.util.Config;
import android.util.Log;
import java.util.ArrayList;

View File

@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2009 Marc Blank
* Licensed to The Android Open Source Project.
* Copyright (C) 2009 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.
@ -17,110 +16,183 @@
package com.android.email.service;
import java.util.HashMap;
import com.android.email.mail.MessagingException;
import com.android.exchange.IEmailService;
import com.android.exchange.IEmailServiceCallback;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import com.android.exchange.IEmailService;
import android.util.Log;
/**
* Proxy for an IEmailService (remote email service); handles all connections to the service.
* All calls via the proxy are synchronous; the UI must ensure that these calls are running
* on appropriate background threads.
* The EmailServiceProxy class provides a simple interface for the UI to call into the various
* EmailService classes (e.g. SyncManager for EAS). It wraps the service connect/disconnect
* process so that the caller need not be concerned with it.
*
* A call to loadAttachment, for example, would look like this (assuming MyService is the service)
* EmailProxyService.getService(context, MyService.class).loadAttachment(..args..);
* Use the class like this:
* new EmailServiceClass(context, class).loadAttachment(attachmentId, callback)
*
* Methods without a return value return immediately (i.e. are asynchronous); methods with a
* return value wait for a result from the Service (i.e. they should not be called from the UI
* thread) with a default timeout of 30 seconds (settable)
*
* An EmailServiceProxy object cannot be reused (trying to do so generates a RemoteException)
*/
public class EmailServiceProxy {
public class EmailServiceProxy implements IEmailService {
private static final boolean DEBUG_PROXY = false; // DO NOT CHECK THIS IN SET TO TRUE
private static final String TAG = "EmailServiceProxy";
// Map associating a context and a proxy
static HashMap<Context, EmailServiceProxy> sProxyMap =
new HashMap<Context, EmailServiceProxy>();
private Context mContext;
private Class<?> mClass;
private Runnable mRunnable;
private ServiceConnection mSyncManagerConnection = new EmailServiceConnection ();
private IEmailService mService = null;
private Object mReturn = null;
private int mTimeout = 30;
private boolean mDead = false;
// Map associating, for a given proxy, a class name (String) and a connected service
public HashMap<String, IEmailService> serviceMap =
new HashMap<String, IEmailService>();
public EmailServiceProxy () {
public EmailServiceProxy(Context _context, Class<?> _class) {
mContext = _context;
mClass = _class;
}
class EmailServiceConnection implements ServiceConnection {
EmailServiceProxy mProxy;
EmailServiceConnection (EmailServiceProxy proxy) {
mProxy = proxy;
}
void setProxy (EmailServiceProxy proxy) {
mProxy = proxy;
}
public void onServiceConnected(ComponentName name, IBinder binder) {
synchronized (mProxy) {
IEmailService service = IEmailService.Stub.asInterface(binder);
mProxy.serviceMap.put(name.getClassName(), service);
mService = IEmailService.Stub.asInterface(binder);
if (DEBUG_PROXY) {
Log.v(TAG, "Service " + mClass.getSimpleName() + " connected");
}
runTask();
}
public void onServiceDisconnected(ComponentName name) {
synchronized (mProxy) {
mProxy.serviceMap.remove(name.getClassName());
if (DEBUG_PROXY) {
Log.v(TAG, "Service " + mClass.getSimpleName() + " disconnected");
}
}
}
public ServiceConnection mSyncManagerConnection = new EmailServiceConnection (this);
public EmailServiceProxy setTimeout(int secs) {
mTimeout = secs;
return this;
}
static public IEmailService getService(Context context, Class<? extends Service> klass)
throws RemoteException {
String className = klass.getName();
// First, lets get the proxy for this context
// Make sure we're synchronized on the map
EmailServiceProxy proxy;
synchronized (sProxyMap) {
proxy = sProxyMap.get(context);
if (proxy == null) {
proxy = new EmailServiceProxy();
sProxyMap.put(context, proxy);
}
private void runTask() {
Thread thread = new Thread(mRunnable);
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
}
// Once we have the proxy, we need to synchronize working with its map, connect to the
// appropriate service (if not already connected) and return that service
synchronized (proxy) {
if (proxy.serviceMap.get(klass) == null) {
context.bindService(new Intent(context, klass), proxy.mSyncManagerConnection,
Context.BIND_AUTO_CREATE);
mContext.unbindService(mSyncManagerConnection);
mDead = true;
synchronized(mSyncManagerConnection) {
if (DEBUG_PROXY) {
Log.v(TAG, "Service task completed; disconnecting");
}
mSyncManagerConnection.notify();
}
}
// Wait up to 5 seconds for the connection
int count = 0;
IEmailService service = null;
while (count++ < 10) {
synchronized (proxy) {
service = proxy.serviceMap.get(className);
if (service != null) {
break;
}
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
}
if (service == null) {
private void setTask(Runnable runnable) throws RemoteException {
if (mDead) {
throw new RemoteException();
}
return service;
}
mRunnable = runnable;
if (DEBUG_PROXY) {
Log.v(TAG, "Service " + mClass.getSimpleName() + " bind requested");
}
mContext.bindService(new Intent(mContext, mClass), mSyncManagerConnection,
Context.BIND_AUTO_CREATE);
}
public void waitForCompletion() {
synchronized (mSyncManagerConnection) {
long time = System.currentTimeMillis();
try {
if (DEBUG_PROXY) {
Log.v(TAG, "Waiting for task to complete...");
}
mSyncManagerConnection.wait(mTimeout * 1000L);
} catch (InterruptedException e) {
// Can be ignored safely
}
if (DEBUG_PROXY) {
Log.v(TAG, "Wait finished in " + (System.currentTimeMillis() - time) + "ms");
}
}
}
public boolean createFolder(long accountId, String name) throws RemoteException {
// TODO Auto-generated method stub
return false;
}
public boolean deleteFolder(long accountId, String name) throws RemoteException {
// TODO Auto-generated method stub
return false;
}
public boolean renameFolder(long accountId, String oldName, String newName)
throws RemoteException {
// TODO Auto-generated method stub
return false;
}
public void loadAttachment(final long attachmentId, final IEmailServiceCallback cb)
throws RemoteException {
setTask(new Runnable () {
public void run() {
try {
mService.loadAttachment(attachmentId, cb);
} catch (RemoteException e) {
}
}
});
Log.v(TAG, "loadAttachment finished");
}
public void loadMore(long messageId, IEmailServiceCallback cb) throws RemoteException {
// TODO Auto-generated method stub
}
public void startSync(long mailboxId) throws RemoteException {
// TODO Auto-generated method stub
}
public void stopSync(long mailboxId) throws RemoteException {
// TODO Auto-generated method stub
}
public void updateFolderList(long accountId) throws RemoteException {
// TODO Auto-generated method stub
}
public int validate(final String protocol, final String host, final String userName,
final String password, final int port, final boolean ssl) throws RemoteException {
setTask(new Runnable () {
public void run() {
try {
mReturn = mService.validate(protocol, host, userName, password, port, ssl);
} catch (RemoteException e) {
}
}
});
waitForCompletion();
if (mReturn == null) {
return MessagingException.UNSPECIFIED_EXCEPTION;
} else {
Log.v(TAG, "validate returns " + mReturn);
return (Integer)mReturn;
}
}
public IBinder asBinder() {
return null;
}
}

View File

@ -25,6 +25,7 @@ import com.android.exchange.EmailContent.AttachmentColumns;
import com.android.exchange.EmailContent.HostAuth;
import com.android.exchange.EmailContent.Mailbox;
import com.android.exchange.EmailContent.MailboxColumns;
import com.android.exchange.EmailContent.Message;
import com.android.exchange.adapter.EasContactsSyncAdapter;
import com.android.exchange.adapter.EasEmailSyncAdapter;
import com.android.exchange.adapter.EasFolderSyncParser;
@ -213,17 +214,19 @@ public class EasSyncService extends InteractiveSyncService {
return uc;
}
private void doStatusCallback(IEmailServiceCallback callback, int status) {
private void doStatusCallback(IEmailServiceCallback callback, long messageId,
long attachmentId, int status) {
try {
callback.status(status, 0);
callback.status(messageId, attachmentId, status, 0);
} catch (RemoteException e2) {
// No danger if the client is no longer around
}
}
private void doProgressCallback(IEmailServiceCallback callback, int progress) {
private void doProgressCallback(IEmailServiceCallback callback, long messageId,
long attachmentId, int progress) {
try {
callback.status(EmailServiceStatus.IN_PROGRESS, progress);
callback.status(messageId, attachmentId, EmailServiceStatus.IN_PROGRESS, progress);
} catch (RemoteException e2) {
// No danger if the client is no longer around
}
@ -240,7 +243,8 @@ public class EasSyncService extends InteractiveSyncService {
// TODO Implement internal storage as required
IEmailServiceCallback callback = req.callback;
Attachment att = req.att;
doProgressCallback(callback, 0);
Message msg = Message.restoreMessageWithId(mContext, att.mMessageKey);
doProgressCallback(callback, msg.mId, att.mId, 0);
DefaultHttpClient client = new DefaultHttpClient();
String us = makeUriString("GetAttachment", "&AttachmentName=" + att.mLocation);
HttpPost method = new HttpPost(URI.create(us));
@ -271,7 +275,7 @@ public class EasSyncService extends InteractiveSyncService {
os.write(bytes, 0, read);
len -= read;
int pct = ((length - len) * 100 / length);
doProgressCallback(callback, pct);
doProgressCallback(callback, msg.mId, att.mId, pct);
}
} finally {
mPendingPartRequest = null;
@ -287,11 +291,11 @@ public class EasSyncService extends InteractiveSyncService {
cv.put(AttachmentColumns.CONTENT_URI, f.getAbsolutePath());
cv.put(AttachmentColumns.MIME_TYPE, type);
att.update(mContext, cv);
doStatusCallback(callback, EmailServiceStatus.SUCCESS);
doStatusCallback(callback, msg.mId, att.mId, EmailServiceStatus.SUCCESS);
}
}
} else {
doStatusCallback(callback, EmailServiceStatus.MESSAGE_NOT_FOUND);
doStatusCallback(callback, msg.mId, att.mId, EmailServiceStatus.MESSAGE_NOT_FOUND);
}
}
@ -570,7 +574,7 @@ public class EasSyncService extends InteractiveSyncService {
WHERE_ACCOUNT_KEY_AND_SERVER_ID, mBindArguments, null);
try {
if (c.moveToFirst()) {
SyncManager.startManualSync(c.getLong(Mailbox.CONTENT_ID_COLUMN));
SyncManager.startManualSync(c.getLong(Mailbox.CONTENT_ID_COLUMN), null);
}
} finally {
c.close();
@ -785,8 +789,8 @@ public class EasSyncService extends InteractiveSyncService {
public void run() {
mThread = Thread.currentThread();
TAG = mThread.getName();
mDeviceId = android.provider.Settings.System.getString(mContext.getContentResolver(),
android.provider.Settings.System.ANDROID_ID);
mDeviceId = android.provider.Settings.Secure.getString(mContext.getContentResolver(),
android.provider.Settings.Secure.ANDROID_ID);
// Generate a device id if we don't have one
if (mDeviceId == null) {
mDeviceId = getSimulatedDeviceId();

View File

@ -29,6 +29,7 @@ public interface EmailServiceStatus {
public static final int FOLDER_NOT_DELETED = 0x12;
public static final int FOLDER_NOT_RENAMED = 0x13;
public static final int FOLDER_NOT_CREATED = 0x14;
public static final int REMOTE_EXCEPTION = 0x15;
// Maybe we should automatically retry these?
public static final int CONNECTION_ERROR = 0x20;

View File

@ -23,14 +23,13 @@ interface IEmailService {
int validate(in String protocol, in String host, in String userName, in String password,
int port, boolean ssl) ;
boolean startSync(long mailboxId);
boolean stopSync(long mailboxId);
void startSync(long mailboxId);
void stopSync(long mailboxId);
boolean loadMore(long messageId, IEmailServiceCallback cb);
boolean loadAttachment(long messageId, in EmailContent.Attachment att,
IEmailServiceCallback cb);
void loadMore(long messageId, IEmailServiceCallback cb);
void loadAttachment(long attachmentId, IEmailServiceCallback cb);
boolean updateFolderList(long accountId);
void updateFolderList(long accountId);
boolean createFolder(long accountId, String name);
boolean deleteFolder(long accountId, String name);

View File

@ -18,5 +18,5 @@
package com.android.exchange;
oneway interface IEmailServiceCallback {
void status(int statusCode, int progress);
void status(long messageId, long attachmentId, int statusCode, int progress);
}

View File

@ -40,28 +40,30 @@ public class PartRequest {
/* (non-Javadoc)
* @see com.android.exchange.IEmailServiceCallback#status(int, int)
*/
public void status(int statusCode, int progress) throws RemoteException {
public void status(long messageId, long attachmentId, int statusCode, int progress)
throws RemoteException {
// This is a placeholder, so that all PartRequests have a callback (prevents a lot of
// useless checking in the sync service). When debugging, logs the status and progress
// of the download.
if (Eas.TEST_DEBUG) {
Log.d("Status: ", "Code = " + statusCode + ", progress = " + progress);
Log.d("PartRequestStatus", "Message " + messageId + ", Attachment " + attachmentId
+ ", Code " + statusCode + ", progress " + progress);
}
}
public IBinder asBinder() { return null; }
};
public PartRequest(long _emailId, Attachment _att) {
public PartRequest(Attachment _att) {
timeStamp = System.currentTimeMillis();
emailId = _emailId;
emailId = _att.mMessageKey;
att = _att;
loc = att.mLocation;
callback = sCallback;
}
public PartRequest(long _emailId, Attachment _att, IEmailServiceCallback _callback) {
this(_emailId, _att);
public PartRequest(Attachment _att, IEmailServiceCallback _callback) {
this(_att);
callback = _callback;
}
}

View File

@ -111,24 +111,20 @@ public class SyncManager extends Service implements Runnable {
}
}
public boolean startSync(long mailboxId) throws RemoteException {
public void startSync(long mailboxId) throws RemoteException {
// TODO Auto-generated method stub
return false;
}
public boolean stopSync(long mailboxId) throws RemoteException {
public void stopSync(long mailboxId) throws RemoteException {
// TODO Auto-generated method stub
return false;
}
public boolean updateFolderList(long accountId) throws RemoteException {
public void updateFolderList(long accountId) throws RemoteException {
// TODO Auto-generated method stub
return false;
}
public boolean loadMore(long messageId, IEmailServiceCallback cb) throws RemoteException {
public void loadMore(long messageId, IEmailServiceCallback cb) throws RemoteException {
// TODO Auto-generated method stub
return false;
}
public boolean createFolder(long accountId, String name) throws RemoteException {
@ -147,18 +143,10 @@ public class SyncManager extends Service implements Runnable {
return false;
}
public boolean loadAttachment(long messageId, Attachment att, IEmailServiceCallback cb)
public void loadAttachment(long attachmentId, IEmailServiceCallback cb)
throws RemoteException {
for (int i = 0; i < 10; i++) {
cb.status(EmailServiceStatus.IN_PROGRESS, i * 10);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
// TODO Auto-generated method stub
cb.status(EmailServiceStatus.SUCCESS, 0);
return false;
Attachment att = Attachment.restoreAttachmentWithId(SyncManager.this, attachmentId);
partRequest(new PartRequest(att, cb));
}
};
@ -550,12 +538,15 @@ public class SyncManager extends Service implements Runnable {
}
}
private void startService(Mailbox m) {
private void startService(Mailbox m, PartRequest req) {
synchronized (mSyncToken) {
Account acct = Account.restoreAccountWithId(this, m.mAccountKey);
if (acct != null) {
AbstractSyncService service;
service = new EasSyncService(this, m);
if (req != null) {
service.addPartRequest(req);
}
startService(service, m);
}
}
@ -679,7 +670,7 @@ public class SyncManager extends Service implements Runnable {
long freq = c.getInt(Mailbox.CONTENT_SYNC_FREQUENCY_COLUMN);
if (freq == Account.CHECK_INTERVAL_PUSH) {
Mailbox m = EmailContent.getContent(c, Mailbox.class);
startService(m);
startService(m, null);
} else if (c.getInt(Mailbox.CONTENT_TYPE_COLUMN) == Mailbox.TYPE_OUTBOX) {
int cnt = EmailContent.count(this, Message.CONTENT_URI,
"mailboxKey=" + mid + " and syncServerId=0", null);
@ -691,7 +682,7 @@ public class SyncManager extends Service implements Runnable {
long lastSync = c.getLong(Mailbox.CONTENT_SYNC_TIME_COLUMN);
if (now - lastSync > (freq*MINS)) {
Mailbox m = EmailContent.getContent(c, Mailbox.class);
startService(m);
startService(m, null);
}
}
} else {
@ -746,7 +737,7 @@ public class SyncManager extends Service implements Runnable {
service.mRequestTime = System.currentTimeMillis() + ms;
kick();
} else {
startManualSync(mailboxId);
startManualSync(mailboxId, null);
}
} catch (Exception e) {
e.printStackTrace();
@ -773,12 +764,10 @@ public class SyncManager extends Service implements Runnable {
AbstractSyncService service = INSTANCE.mServiceMap.get(mailboxId);
if (service == null) {
service = startManualSync(mailboxId);
}
if (service != null) {
service.addPartRequest(req);
service = startManualSync(mailboxId, req);
kick();
} else {
service.addPartRequest(req);
}
}
@ -844,7 +833,7 @@ public class SyncManager extends Service implements Runnable {
}
}
static public AbstractSyncService startManualSync(long mailboxId) {
static public AbstractSyncService startManualSync(long mailboxId, PartRequest req) {
if (INSTANCE == null || INSTANCE.mServiceMap == null) {
return null;
}
@ -854,7 +843,7 @@ public class SyncManager extends Service implements Runnable {
INSTANCE.mSyncErrorMap.remove(mailboxId);
Mailbox m = Mailbox.restoreMailboxWithId(INSTANCE, mailboxId);
INSTANCE.log("Starting sync for " + m.mDisplayName);
INSTANCE.startService(m);
INSTANCE.startService(m, req);
}
}
return INSTANCE.mServiceMap.get(mailboxId);
@ -891,7 +880,7 @@ public class SyncManager extends Service implements Runnable {
if (syncType == Account.CHECK_INTERVAL_PUSH) {
SyncManager.serviceRequestImmediate(mailboxId);
} else {
SyncManager.startManualSync(mailboxId);
SyncManager.startManualSync(mailboxId, null);
}
}
@ -913,6 +902,9 @@ public class SyncManager extends Service implements Runnable {
int exitStatus = svc.mExitStatus;
switch (exitStatus) {
case AbstractSyncService.EXIT_DONE:
if (!svc.mPartRequests.isEmpty()) {
// TODO Handle this case
}
errorMap.remove(mailboxId);
break;
case AbstractSyncService.EXIT_IO_ERROR: