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
diff --git a/src/com/android/exchange/EasSyncService.java b/src/com/android/exchange/EasSyncService.java
index 0dd5b56..0ac638f 100644
--- a/src/com/android/exchange/EasSyncService.java
+++ b/src/com/android/exchange/EasSyncService.java
@@ -25,6 +25,7 @@
 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 @@
         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 @@
         // 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 @@
                             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 @@
                     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 @@
                         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 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();
diff --git a/src/com/android/exchange/EmailServiceStatus.java b/src/com/android/exchange/EmailServiceStatus.java
index 2a58ebf..ead9a1d 100644
--- a/src/com/android/exchange/EmailServiceStatus.java
+++ b/src/com/android/exchange/EmailServiceStatus.java
@@ -29,6 +29,7 @@
     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;
diff --git a/src/com/android/exchange/IEmailService.aidl b/src/com/android/exchange/IEmailService.aidl
index 13c86f0..2b1dab6 100644
--- a/src/com/android/exchange/IEmailService.aidl
+++ b/src/com/android/exchange/IEmailService.aidl
@@ -23,14 +23,13 @@
     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);
diff --git a/src/com/android/exchange/IEmailServiceCallback.aidl b/src/com/android/exchange/IEmailServiceCallback.aidl
index c3f3674..2fc3dbc 100644
--- a/src/com/android/exchange/IEmailServiceCallback.aidl
+++ b/src/com/android/exchange/IEmailServiceCallback.aidl
@@ -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);
 }
diff --git a/src/com/android/exchange/PartRequest.java b/src/com/android/exchange/PartRequest.java
index 2fc7036..ef3d0a5 100644
--- a/src/com/android/exchange/PartRequest.java
+++ b/src/com/android/exchange/PartRequest.java
@@ -40,28 +40,30 @@
         /* (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;
     }
 }
diff --git a/src/com/android/exchange/SyncManager.java b/src/com/android/exchange/SyncManager.java
index e0ef010..cf71cf7 100644
--- a/src/com/android/exchange/SyncManager.java
+++ b/src/com/android/exchange/SyncManager.java
@@ -111,24 +111,20 @@
             }
         }
 
-        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 @@
             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 @@
         }
     }
 
-    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 @@
                     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 @@
                         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 @@
                 service.mRequestTime = System.currentTimeMillis() + ms;
                 kick();
             } else {
-                startManualSync(mailboxId);
+                startManualSync(mailboxId, null);
             }
         } catch (Exception e) {
             e.printStackTrace();
@@ -773,12 +764,10 @@
         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 @@
         }
     }
 
-    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 @@
                 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 @@
         if (syncType == Account.CHECK_INTERVAL_PUSH) {
             SyncManager.serviceRequestImmediate(mailboxId);
         } else {
-            SyncManager.startManualSync(mailboxId);
+            SyncManager.startManualSync(mailboxId, null);
         }
     }
 
@@ -913,6 +902,9 @@
         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: