();
+
+ private boolean mPushModeRunning = false;
+
+ /**
+ * Factory method.
+ */
+ public static Store newInstance(String uri, Context context, PersistentDataCallbacks callbacks)
+ throws MessagingException {
+ return new ExchangeStore(uri, context, callbacks);
+ }
+
+ /**
+ * eas://user:password@server/domain
+ *
+ * @param _uri
+ * @param application
+ * @throws MessagingException
+ */
+ private ExchangeStore(String _uri, Context context, PersistentDataCallbacks callbacks)
+ throws MessagingException {
+ mContext = context;
+ try {
+ mUri = new URI(_uri);
+ } catch (URISyntaxException e) {
+ throw new MessagingException("Invalid uri for ExchangeStore");
+ }
+ mCallbacks = callbacks;
+
+ String scheme = mUri.getScheme();
+ int connectionSecurity;
+ if (scheme.equals("eas")) {
+ connectionSecurity = ExchangeTransport.CONNECTION_SECURITY_NONE;
+ } else if (scheme.equals("eas+ssl+")) {
+ connectionSecurity = ExchangeTransport.CONNECTION_SECURITY_SSL_REQUIRED;
+ } else {
+ throw new MessagingException("Unsupported protocol");
+ }
+
+ mTransport = ExchangeTransport.getInstance(mUri, context);
+ }
+
+ /**
+ * Retrieve the underlying transport. Used primarily for testing.
+ * @return
+ */
+ /* package */ ExchangeTransport getTransport() {
+ return mTransport;
+ }
+
+ @Override
+ public void checkSettings() throws MessagingException {
+ mTransport.checkSettings(mUri);
+ }
+
+ @Override
+ public Folder getFolder(String name) throws MessagingException {
+ synchronized (mFolders) {
+ Folder folder = mFolders.get(name);
+ if (folder == null) {
+ folder = new ExchangeFolder(this, name);
+ mFolders.put(folder.getName(), folder);
+ }
+ return folder;
+ }
+ }
+
+ @Override
+ public Folder[] getPersonalNamespaces() throws MessagingException {
+ return new Folder[] {
+ getFolder(ExchangeTransport.FOLDER_INBOX),
+ };
+ }
+
+ /**
+ * For a store that supports push mode, this is the API that enables it or disables it.
+ * The store should use this API to start or stop its persistent connection service or thread.
+ *
+ * Note, may be called multiple times, even after push mode has been started or stopped.
+ *
+ * @param enablePushMode start or stop push mode delivery
+ */
+ @Override
+ public void enablePushModeDelivery(boolean enablePushMode) {
+ if (Config.LOGD && Email.DEBUG) {
+ if (enablePushMode && !mPushModeRunning) {
+ Log.d(Email.LOG_TAG, "start push mode");
+ } else if (!enablePushMode && mPushModeRunning) {
+ Log.d(Email.LOG_TAG, "stop push mode");
+ } else {
+ Log.d(Email.LOG_TAG, enablePushMode ?
+ "push mode already started" : "push mode already stopped");
+ }
+ }
+ mPushModeRunning = enablePushMode;
+ }
+
+ /**
+ * Get class of SettingActivity for this Store class.
+ * @return Activity class that has class method actionEditIncomingSettings()
+ */
+ @Override
+ public Class extends android.app.Activity> getSettingActivityClass() {
+ return com.android.email.activity.setup.AccountSetupExchange.class;
+ }
+
+ /**
+ * Get class of sync'er for this Store class. Because exchange Sync rules are so different
+ * than IMAP or POP3, it's likely that an Exchange implementation will need its own sync
+ * controller. If so, this function must return a non-null value.
+ *
+ * @return Message Sync controller, or null to use default
+ */
+ @Override
+ public StoreSynchronizer getMessageSynchronizer() {
+ return null;
+ }
+
+ /**
+ * Inform MessagingController that this store requires message structures to be prefetched
+ * before it can fetch message bodies (this is due to EAS protocol restrictions.)
+ * @return always true for EAS
+ */
+ @Override
+ public boolean requireStructurePrefetch() {
+ return true;
+ }
+
+ /**
+ * Inform MessagingController that messages sent via EAS will be placed in the Sent folder
+ * automatically (server-side) and don't need to be uploaded.
+ * @return always false for EAS (assuming server-side copy is supported)
+ */
+ @Override
+ public boolean requireCopyMessageToSentFolder() {
+ return false;
+ }
+
+ public static class ExchangeTransport {
+ public static final int CONNECTION_SECURITY_NONE = 0;
+ public static final int CONNECTION_SECURITY_SSL_REQUIRED = 1;
+
+ public static final String FOLDER_INBOX = Email.INBOX;
+
+ private static final String TAG = "ExchangeTransport";
+ private final Context mContext;
+
+ private String mHost;
+ private String mDomain;
+ private String mUsername;
+ private String mPassword;
+
+ private static HashMap sUriToInstanceMap =
+ new HashMap();
+ private static final HashMap sFolderMap = new HashMap();
+
+ /**
+ * Public factory. The transport should be a singleton (per Uri)
+ */
+ public synchronized static ExchangeTransport getInstance(URI uri, Context context)
+ throws MessagingException {
+ if (!uri.getScheme().equals("eas") && !uri.getScheme().equals("eas+ssl+")) {
+ throw new MessagingException("Invalid scheme");
+ }
+
+ final String key = uri.toString();
+ ExchangeTransport transport = sUriToInstanceMap.get(key);
+ if (transport == null) {
+ transport = new ExchangeTransport(uri, context);
+ sUriToInstanceMap.put(key, transport);
+ }
+ return transport;
+ }
+
+ /**
+ * Private constructor - use public factory.
+ */
+ private ExchangeTransport(URI uri, Context context) throws MessagingException {
+ mContext = context;
+ setUri(uri);
+ }
+
+ /**
+ * Use the Uri to set up a newly-constructed transport
+ * @param uri
+ * @throws MessagingException
+ */
+ private void setUri(final URI uri) throws MessagingException {
+ mHost = uri.getHost();
+ if (mHost == null) {
+ throw new MessagingException("host not specified");
+ }
+
+ mDomain = uri.getPath();
+ if (!TextUtils.isEmpty(mDomain)) {
+ mDomain = mDomain.substring(1);
+ }
+
+ final String userInfo = uri.getUserInfo();
+ if (userInfo == null) {
+ throw new MessagingException("user information not specifed");
+ }
+ final String[] uinfo = userInfo.split(":", 2);
+ if (uinfo.length != 2) {
+ throw new MessagingException("user name and password not specified");
+ }
+ mUsername = uinfo[0];
+ 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
+ * @throws MessagingException if we can't authenticate the account
+ */
+ public void checkSettings(URI uri) throws MessagingException {
+ 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);
+ if (result != MessagingException.NO_ERROR) {
+ if (result == MessagingException.AUTHENTICATION_FAILED) {
+ throw new AuthenticationFailedException("Authentication failed.");
+ } else {
+ throw new MessagingException(result);
+ }
+ } else {
+ // This code was taken from sample code in AccountsTester
+ Bundle options = new Bundle();
+ options.putString("username", mUsername);
+ options.putString("password", mPassword);
+ Future2Callback callback = new Future2Callback() {
+ public void run(Future2 future) {
+ try {
+ Bundle bundle = future.getResult();
+ bundle.keySet();
+ Log.d(TAG, "account added: " + bundle);
+ } catch (OperationCanceledException e) {
+ Log.d(TAG, "addAccount was canceled");
+ } catch (IOException e) {
+ Log.d(TAG, "addAccount failed: " + e);
+ } catch (AuthenticatorException e) {
+ Log.d(TAG, "addAccount failed: " + e);
+ }
+
+ }
+ };
+ // Here's where we tell AccountManager about the new account. The addAccount
+ // method in AccountManager calls the addAccount method in our authenticator
+ // service (EasAuthenticatorService)
+ AccountManager.get(mContext).addAccount(Eas.ACCOUNT_MANAGER_TYPE, null, null,
+ options, null, callback, null);
+ }
+ svc.loadAttachment(0, new Attachment(), mCallback);
+ } catch (RemoteException e) {
+ throw new MessagingException("Call to validate generated an exception", e);
+ }
+ }
+
+ /**
+ * Typical helper function: Return existence of a given folder
+ */
+ public boolean isFolderAvailable(final String folder) {
+ return sFolderMap.containsKey(folder);
+ }
+ }
+
+ public static class ExchangeFolder extends Folder {
+
+ private final ExchangeTransport mTransport;
+ @SuppressWarnings("unused")
+ private final ExchangeStore mStore;
+ @SuppressWarnings("unused")
+ private final String mName;
+
+ @SuppressWarnings("unused")
+ private PersistentDataCallbacks mPersistenceCallbacks;
+
+ public ExchangeFolder(ExchangeStore store, String name)
+ throws MessagingException {
+ mStore = store;
+ mTransport = store.getTransport();
+ mName = name;
+ if (!mTransport.isFolderAvailable(name)) {
+ throw new MessagingException("folder not supported: " + name);
+ }
+ }
+
+ @Override
+ public void appendMessages(Message[] messages) throws MessagingException {
+ // TODO Implement this function
+ }
+
+ @Override
+ public void close(boolean expunge) throws MessagingException {
+ mPersistenceCallbacks = null;
+ // TODO Implement this function
+ }
+
+ @Override
+ public void copyMessages(Message[] msgs, Folder folder, MessageUpdateCallbacks callbacks)
+ throws MessagingException {
+ // TODO Implement this function
+ }
+
+ @Override
+ public boolean create(FolderType type) throws MessagingException {
+ // TODO Implement this function
+ return false;
+ }
+
+ @Override
+ public void delete(boolean recurse) throws MessagingException {
+ // TODO Implement this function
+ }
+
+ @Override
+ public boolean exists() throws MessagingException {
+ // TODO Implement this function
+ return false;
+ }
+
+ @Override
+ public Message[] expunge() throws MessagingException {
+ // TODO Implement this function
+ return null;
+ }
+
+ @Override
+ public void fetch(Message[] messages, FetchProfile fp, MessageRetrievalListener listener)
+ throws MessagingException {
+ // TODO Implement this function
+ }
+
+ @Override
+ public Message getMessage(String uid) throws MessagingException {
+ // TODO Implement this function
+ return null;
+ }
+
+ @Override
+ public int getMessageCount() throws MessagingException {
+ // TODO Implement this function
+ return 0;
+ }
+
+ @Override
+ public Message[] getMessages(int start, int end, MessageRetrievalListener listener)
+ throws MessagingException {
+ // TODO Implement this function
+ return null;
+ }
+
+ @Override
+ public Message[] getMessages(MessageRetrievalListener listener) throws MessagingException {
+ // TODO Implement this function
+ return null;
+ }
+
+ @Override
+ public Message[] getMessages(String[] uids, MessageRetrievalListener listener)
+ throws MessagingException {
+ // TODO Implement this function
+ return null;
+ }
+
+ @Override
+ public OpenMode getMode() throws MessagingException {
+ // TODO Implement this function
+ return null;
+ }
+
+ @Override
+ public String getName() {
+ // TODO Implement this function
+ return null;
+ }
+
+ @Override
+ public Flag[] getPermanentFlags() throws MessagingException {
+ // TODO Implement this function
+ return null;
+ }
+
+ @Override
+ public int getUnreadMessageCount() throws MessagingException {
+ // TODO Implement this function
+ return 0;
+ }
+
+ @Override
+ public boolean isOpen() {
+ // TODO Implement this function
+ return false;
+ }
+
+ @Override
+ public void open(OpenMode mode, PersistentDataCallbacks callbacks)
+ throws MessagingException {
+ mPersistenceCallbacks = callbacks;
+ // TODO Implement this function
+ }
+
+ @Override
+ public void setFlags(Message[] messages, Flag[] flags, boolean value)
+ throws MessagingException {
+ // TODO Implement this function
+ }
+
+
+ }
+
+
+}
+
diff --git a/src/com/android/email/service/EasAuthenticatorService.java b/src/com/android/email/service/EasAuthenticatorService.java
new file mode 100644
index 000000000..faee0f45e
--- /dev/null
+++ b/src/com/android/email/service/EasAuthenticatorService.java
@@ -0,0 +1,105 @@
+/*
+ * 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.
+ * 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.email.service;
+
+import com.android.exchange.Eas;
+
+import android.accounts.AbstractAccountAuthenticator;
+import android.accounts.Account;
+import android.accounts.AccountAuthenticatorResponse;
+import android.accounts.AccountManager;
+import android.accounts.Constants;
+import android.accounts.NetworkErrorException;
+import android.app.Service;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.IBinder;
+
+/**
+ * A very basic authenticator service for EAS. At the moment, it has no UI hooks. When called
+ * with addAccount, it simply adds the account to AccountManager directly with a username and
+ * password. We will need to implement confirmPassword, confirmCredentials, and updateCredentials.
+ */
+public class EasAuthenticatorService extends Service {
+
+ class EasAuthenticator extends AbstractAccountAuthenticator {
+
+ @Override
+ public Bundle addAccount(AccountAuthenticatorResponse response, String accountType,
+ String authTokenType, String[] requiredFeatures, Bundle options)
+ throws NetworkErrorException {
+ // The Bundle we are passed has username and password set
+ AccountManager.get(EasAuthenticatorService.this).blockingAddAccountExplicitly(
+ new Account(options.getString("username"), Eas.ACCOUNT_MANAGER_TYPE),
+ options.getString("password"), null);
+ Bundle b = new Bundle();
+ b.putString(Constants.ACCOUNT_NAME_KEY, options.getString("username"));
+ b.putString(Constants.ACCOUNT_TYPE_KEY, Eas.ACCOUNT_MANAGER_TYPE);
+ return b;
+ }
+
+ @Override
+ public Bundle confirmCredentials(AccountAuthenticatorResponse response, Account account) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public boolean confirmPassword(AccountAuthenticatorResponse response, Account account,
+ String password) throws NetworkErrorException {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public Bundle editProperties(AccountAuthenticatorResponse response, String accountType) {
+ return null;
+ }
+
+ @Override
+ public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account,
+ String authTokenType, Bundle loginOptions) throws NetworkErrorException {
+ return null;
+ }
+
+ @Override
+ public Bundle hasFeatures(AccountAuthenticatorResponse response, Account account,
+ String[] features) throws NetworkErrorException {
+ return null;
+ }
+
+ @Override
+ public Bundle updateCredentials(AccountAuthenticatorResponse response, Account account,
+ String authTokenType, Bundle loginOptions) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ // TODO Replace this with an appropriate constant in AccountManager, when it's created
+ String authenticatorIntent = "android.accounts.AccountAuthenticator";
+
+ if (authenticatorIntent.equals(intent.getAction())) {
+ return new EasAuthenticator().getIAccountAuthenticator().asBinder();
+ } else {
+ return null;
+ }
+ }
+}
diff --git a/src/com/android/email/service/EmailServiceProxy.java b/src/com/android/email/service/EmailServiceProxy.java
new file mode 100644
index 000000000..4ad0a124d
--- /dev/null
+++ b/src/com/android/email/service/EmailServiceProxy.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2008-2009 Marc Blank
+ * Licensed to 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.email.service;
+
+import java.util.HashMap;
+
+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;
+
+/**
+ * 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.
+ *
+ * A call to loadAttachment, for example, would look like this (assuming MyService is the service)
+ * EmailProxyService.getService(context, MyService.class).loadAttachment(..args..);
+ */
+
+public class EmailServiceProxy {
+
+ // Map associating a context and a proxy
+ static HashMap sProxyMap =
+ new HashMap();
+
+ // Map associating, for a given proxy, a class name (String) and a connected service
+ public HashMap serviceMap =
+ new HashMap();
+
+ public EmailServiceProxy () {
+ }
+
+ 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);
+ }
+ }
+
+ public void onServiceDisconnected(ComponentName name) {
+ synchronized (mProxy) {
+ mProxy.serviceMap.remove(name.getClassName());
+ }
+ }
+ }
+
+ public ServiceConnection mSyncManagerConnection = new EmailServiceConnection (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);
+ }
+ }
+
+ // 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);
+ }
+ }
+
+ // 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) {
+ throw new RemoteException();
+ }
+ return service;
+ }
+}
diff --git a/src/com/android/exchange/Eas.java b/src/com/android/exchange/Eas.java
index 86b5419d5..9e5099a21 100644
--- a/src/com/android/exchange/Eas.java
+++ b/src/com/android/exchange/Eas.java
@@ -27,7 +27,9 @@ public class Eas {
// For temporary use while debugging
public static boolean TEST_DEBUG = false; // DO NOT CHECK IN WITH THIS SET TO TRUE
- public static String VERSION = "0.1";
+ public static final String VERSION = "0.1";
+
+ public static final String ACCOUNT_MANAGER_TYPE = "com.android.exchange";
// From EAS spec
// Mail Cal
diff --git a/src/com/android/exchange/EasSyncService.java b/src/com/android/exchange/EasSyncService.java
index 22a0d375d..a5cf488fc 100644
--- a/src/com/android/exchange/EasSyncService.java
+++ b/src/com/android/exchange/EasSyncService.java
@@ -176,7 +176,7 @@ public class EasSyncService extends InteractiveSyncService {
@Override
- public void loadAttachment(Attachment att, ISyncManagerCallback cb) {
+ public void loadAttachment(Attachment att, IEmailServiceCallback cb) {
// TODO Auto-generated method stub
}
diff --git a/src/com/android/exchange/EmailServiceStatus.java b/src/com/android/exchange/EmailServiceStatus.java
new file mode 100644
index 000000000..2a58ebf53
--- /dev/null
+++ b/src/com/android/exchange/EmailServiceStatus.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2008-2009 Marc Blank
+ * Licensed to 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.exchange;
+
+/**
+ * Definitions of service status codes returned to IEmailServiceCallback's status method
+ */
+public interface EmailServiceStatus {
+ public static final int SUCCESS = 0;
+ public static final int IN_PROGRESS = 1;
+
+ public static final int MESSAGE_NOT_FOUND = 0x10;
+ public static final int ATTACHMENT_NOT_FOUND = 0x11;
+ public static final int FOLDER_NOT_DELETED = 0x12;
+ public static final int FOLDER_NOT_RENAMED = 0x13;
+ public static final int FOLDER_NOT_CREATED = 0x14;
+
+ // Maybe we should automatically retry these?
+ public static final int CONNECTION_ERROR = 0x20;
+}
diff --git a/src/com/android/exchange/ISyncManager.aidl b/src/com/android/exchange/IEmailService.aidl
similarity index 74%
rename from src/com/android/exchange/ISyncManager.aidl
rename to src/com/android/exchange/IEmailService.aidl
index 25665492e..13c86f0a3 100644
--- a/src/com/android/exchange/ISyncManager.aidl
+++ b/src/com/android/exchange/IEmailService.aidl
@@ -14,28 +14,25 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package com.android.exchange;
-import com.android.exchange.ISyncManagerCallback;
+import com.android.exchange.IEmailServiceCallback;
import com.android.exchange.EmailContent;
-interface ISyncManager {
- int validate(in String protocol, in String host, in String userName, in String password, int port, boolean ssl) ;
-
- void registerCallback(ISyncManagerCallback cb);
- void unregisterCallback(ISyncManagerCallback cb);
+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);
- boolean updateFolderList(long accountId);
+ boolean loadMore(long messageId, IEmailServiceCallback cb);
+ boolean loadAttachment(long messageId, in EmailContent.Attachment att,
+ IEmailServiceCallback cb);
- boolean loadMore(long messageId, ISyncManagerCallback cb);
- boolean loadAttachment(long messageId, in EmailContent.Attachment att, ISyncManagerCallback cb);
+ boolean updateFolderList(long accountId);
boolean createFolder(long accountId, String name);
boolean deleteFolder(long accountId, String name);
boolean renameFolder(long accountId, String oldName, String newName);
- //AddressLookup - real-time address lookup (EAS)
}
\ No newline at end of file
diff --git a/src/com/android/exchange/ISyncManagerCallback.aidl b/src/com/android/exchange/IEmailServiceCallback.aidl
similarity index 88%
rename from src/com/android/exchange/ISyncManagerCallback.aidl
rename to src/com/android/exchange/IEmailServiceCallback.aidl
index 0046ad304..c3f367424 100644
--- a/src/com/android/exchange/ISyncManagerCallback.aidl
+++ b/src/com/android/exchange/IEmailServiceCallback.aidl
@@ -17,6 +17,6 @@
package com.android.exchange;
-oneway interface ISyncManagerCallback {
- void progress(int value);
+oneway interface IEmailServiceCallback {
+ void status(int statusCode, int progress);
}
diff --git a/src/com/android/exchange/InteractiveSyncService.java b/src/com/android/exchange/InteractiveSyncService.java
index 23b116fc4..d3109e764 100644
--- a/src/com/android/exchange/InteractiveSyncService.java
+++ b/src/com/android/exchange/InteractiveSyncService.java
@@ -46,5 +46,5 @@ public abstract class InteractiveSyncService extends AbstractSyncService {
public abstract void reloadFolderList();
- public abstract void loadAttachment(Attachment att, ISyncManagerCallback cb);
+ public abstract void loadAttachment(Attachment att, IEmailServiceCallback cb);
}
diff --git a/src/com/android/exchange/SyncManager.java b/src/com/android/exchange/SyncManager.java
index 906564f82..1af6d0cc2 100644
--- a/src/com/android/exchange/SyncManager.java
+++ b/src/com/android/exchange/SyncManager.java
@@ -49,9 +49,9 @@ import android.net.NetworkInfo;
import android.net.Uri;
import android.net.NetworkInfo.State;
import android.os.Bundle;
+import android.os.Debug;
import android.os.Handler;
import android.os.PowerManager;
-import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.PowerManager.WakeLock;
import android.database.ContentObserver;
@@ -94,33 +94,23 @@ public class SyncManager extends Service implements Runnable {
new HashMap();
static private WakeLock mWakeLock = null;
- final RemoteCallbackList mCallbacks =
- new RemoteCallbackList();
-
- private final ISyncManager.Stub mBinder = new ISyncManager.Stub() {
+ /**
+ * Create the binder for EmailService implementation here. These are the calls that are
+ * defined in AbstractSyncService. Only validate is now implemented; loadAttachment currently
+ * spins its wheels counting up to 100%.
+ */
+ private final IEmailService.Stub mBinder = new IEmailService.Stub() {
public int validate(String protocol, String host, String userName, String password,
int port, boolean ssl) throws RemoteException {
try {
- AbstractSyncService.validate(EasSyncService.class, host, userName, password, port, ssl,
- SyncManager.this);
+ AbstractSyncService.validate(EasSyncService.class, host, userName, password, port,
+ ssl, SyncManager.this);
return MessagingException.NO_ERROR;
} catch (MessagingException e) {
return e.getExceptionType();
}
}
- public void registerCallback(ISyncManagerCallback cb) {
- if (cb != null) {
- mCallbacks.register(cb);
- }
- }
-
- public void unregisterCallback(ISyncManagerCallback cb) {
- if (cb != null) {
- mCallbacks.unregister(cb);
- }
- }
-
public boolean startSync(long mailboxId) throws RemoteException {
// TODO Auto-generated method stub
return false;
@@ -136,7 +126,7 @@ public class SyncManager extends Service implements Runnable {
return false;
}
- public boolean loadMore(long messageId, ISyncManagerCallback cb) throws RemoteException {
+ public boolean loadMore(long messageId, IEmailServiceCallback cb) throws RemoteException {
// TODO Auto-generated method stub
return false;
}
@@ -157,9 +147,17 @@ public class SyncManager extends Service implements Runnable {
return false;
}
- public boolean loadAttachment(long messageId, Attachment att, ISyncManagerCallback cb)
+ public boolean loadAttachment(long messageId, Attachment att, 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;
}
};
@@ -237,7 +235,7 @@ public class SyncManager extends Service implements Runnable {
main.mDisplayName = "_main";
main.mServerId = "_main";
main.mAccountKey = acct.mId;
- main.mType = Mailbox.TYPE_MAIL;
+ main.mType = Mailbox.TYPE_NOT_EMAIL;
main.mSyncFrequency = Account.CHECK_INTERVAL_PUSH;
main.mFlagVisible = false;
main.save(getContext());
diff --git a/src/com/android/exchange/adapter/EasFolderSyncParser.java b/src/com/android/exchange/adapter/EasFolderSyncParser.java
index 0e0b07f43..d5b8ab213 100644
--- a/src/com/android/exchange/adapter/EasFolderSyncParser.java
+++ b/src/com/android/exchange/adapter/EasFolderSyncParser.java
@@ -212,6 +212,7 @@ public class EasFolderSyncParser extends EasParser {
m.mDisplayName = name;
m.mServerId = serverId;
m.mAccountKey = mAccountId;
+ m.mType = Mailbox.TYPE_MAIL;
m.mSyncFrequency = Account.CHECK_INTERVAL_NEVER;
switch (type) {
case INBOX_TYPE: