Add support for the flag (favorite) property in EAS 12; cleanup

* Support flag property in Exchange 2007 (EAS 12)
* Support startSync/stopSync/reloadFolderList in EAS service
* Cleanup files a little bit
This commit is contained in:
Marc Blank 2009-07-20 17:15:45 -07:00
parent 5790d1458f
commit 28fc7799ce
4 changed files with 133 additions and 65 deletions

View File

@ -173,6 +173,8 @@
android:enabled="false" android:enabled="false"
> >
</service> </service>
<!-- Add android:process=":remote" below to enable SyncManager as a separate process -->
<service <service
android:name="com.android.exchange.SyncManager" android:name="com.android.exchange.SyncManager"
android:enabled="true" android:enabled="true"

View File

@ -128,22 +128,6 @@ public class EmailServiceProxy implements IEmailService {
} }
} }
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) public void loadAttachment(final long attachmentId, final IEmailServiceCallback cb)
throws RemoteException { throws RemoteException {
setTask(new Runnable () { setTask(new Runnable () {
@ -154,23 +138,28 @@ public class EmailServiceProxy implements IEmailService {
} }
} }
}); });
Log.v(TAG, "loadAttachment finished");
} }
public void loadMore(long messageId, IEmailServiceCallback cb) throws RemoteException { public void startSync(final long mailboxId) throws RemoteException {
// TODO Auto-generated method stub setTask(new Runnable () {
public void run() {
try {
mService.startSync(mailboxId);
} catch (RemoteException e) {
}
}
});
} }
public void startSync(long mailboxId) throws RemoteException { public void stopSync(final long mailboxId) throws RemoteException {
// TODO Auto-generated method stub setTask(new Runnable () {
} public void run() {
try {
public void stopSync(long mailboxId) throws RemoteException { mService.stopSync(mailboxId);
// TODO Auto-generated method stub } catch (RemoteException e) {
} }
}
public void updateFolderList(long accountId) throws RemoteException { });
// TODO Auto-generated method stub
} }
public int validate(final String protocol, final String host, final String userName, public int validate(final String protocol, final String host, final String userName,
@ -192,7 +181,35 @@ public class EmailServiceProxy implements IEmailService {
} }
} }
public IBinder asBinder() { public void updateFolderList(final long accountId) throws RemoteException {
setTask(new Runnable () {
public void run() {
try {
mService.updateFolderList(accountId);
} catch (RemoteException e) {
}
}
});
}
public void loadMore(long messageId, IEmailServiceCallback cb) throws RemoteException {
// TODO Auto-generated method stub
}
public boolean createFolder(long accountId, String name) throws RemoteException {
return false;
}
public boolean deleteFolder(long accountId, String name) throws RemoteException {
return false;
}
public boolean renameFolder(long accountId, String oldName, String newName)
throws RemoteException {
return false;
}
public IBinder asBinder() {
return null; return null;
} }
} }

View File

@ -22,6 +22,7 @@ import com.android.exchange.EmailContent.Account;
import com.android.exchange.EmailContent.Attachment; import com.android.exchange.EmailContent.Attachment;
import com.android.exchange.EmailContent.HostAuth; import com.android.exchange.EmailContent.HostAuth;
import com.android.exchange.EmailContent.Mailbox; import com.android.exchange.EmailContent.Mailbox;
import com.android.exchange.EmailContent.MailboxColumns;
import com.android.exchange.EmailContent.Message; import com.android.exchange.EmailContent.Message;
import com.android.exchange.EmailContent.MessageColumns; import com.android.exchange.EmailContent.MessageColumns;
import com.android.exchange.EmailContent.SyncColumns; import com.android.exchange.EmailContent.SyncColumns;
@ -100,6 +101,7 @@ public class SyncManager extends Service implements Runnable {
* spins its wheels counting up to 100%. * spins its wheels counting up to 100%.
*/ */
private final IEmailService.Stub mBinder = new IEmailService.Stub() { private final IEmailService.Stub mBinder = new IEmailService.Stub() {
public int validate(String protocol, String host, String userName, String password, public int validate(String protocol, String host, String userName, String password,
int port, boolean ssl) throws RemoteException { int port, boolean ssl) throws RemoteException {
try { try {
@ -112,35 +114,11 @@ public class SyncManager extends Service implements Runnable {
} }
public void startSync(long mailboxId) throws RemoteException { public void startSync(long mailboxId) throws RemoteException {
// TODO Auto-generated method stub startManualSync(mailboxId, null);
} }
public void stopSync(long mailboxId) throws RemoteException { public void stopSync(long mailboxId) throws RemoteException {
// TODO Auto-generated method stub stopManualSync(mailboxId);
}
public void updateFolderList(long accountId) throws RemoteException {
// TODO Auto-generated method stub
}
public void loadMore(long messageId, IEmailServiceCallback cb) throws RemoteException {
// TODO Auto-generated method stub
}
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(long attachmentId, IEmailServiceCallback cb) public void loadAttachment(long attachmentId, IEmailServiceCallback cb)
@ -148,6 +126,45 @@ public class SyncManager extends Service implements Runnable {
Attachment att = Attachment.restoreAttachmentWithId(SyncManager.this, attachmentId); Attachment att = Attachment.restoreAttachmentWithId(SyncManager.this, attachmentId);
partRequest(new PartRequest(att, cb)); partRequest(new PartRequest(att, cb));
} }
public void updateFolderList(long accountId) throws RemoteException {
Cursor c = getContentResolver().query(Mailbox.CONTENT_URI,
Mailbox.CONTENT_PROJECTION, MailboxColumns.ACCOUNT_KEY + "=? AND " +
MailboxColumns.SERVER_ID + "=?",
new String[] {Long.toString(accountId), Eas.ACCOUNT_MAILBOX}, null);
try {
if (c.moveToFirst()) {
synchronized(mSyncToken) {
AbstractSyncService svc =
INSTANCE.mServiceMap.get(c.getLong(Mailbox.CONTENT_ID_COLUMN));
// TODO See if this is sufficient. Low priority since there is no
// user-driven "update folder list" in the UI
svc.mThread.interrupt();
}
}
} finally {
c.close();
}
}
public void loadMore(long messageId, IEmailServiceCallback cb) throws RemoteException {
// TODO Auto-generated method stub
}
// The following three methods are not implemented in this version
public boolean createFolder(long accountId, String name) throws RemoteException {
return false;
}
public boolean deleteFolder(long accountId, String name) throws RemoteException {
return false;
}
public boolean renameFolder(long accountId, String oldName, String newName)
throws RemoteException {
return false;
}
}; };
class AccountObserver extends ContentObserver { class AccountObserver extends ContentObserver {

View File

@ -152,6 +152,9 @@ public class EasEmailSyncAdapter extends EasSyncAdapter {
case EasTags.BASE_BODY: case EasTags.BASE_BODY:
bodyParser(msg); bodyParser(msg);
break; break;
case EasTags.EMAIL_FLAG:
msg.mFlagFavorite = flagParser();
break;
case EasTags.EMAIL_BODY: case EasTags.EMAIL_BODY:
msg.mTextInfo = "X;X;8;" + size; // location;encoding;charset;size msg.mTextInfo = "X;X;8;" + size; // location;encoding;charset;size
msg.mText = getValue(); msg.mText = getValue();
@ -197,6 +200,21 @@ public class EasEmailSyncAdapter extends EasSyncAdapter {
emails.add(msg); emails.add(msg);
} }
// For now, we only care about the "active" state
private Boolean flagParser() throws IOException {
Boolean state = false;
while (nextTag(EasTags.EMAIL_FLAG) != END) {
switch (tag) {
case EasTags.EMAIL_FLAG_STATUS:
state = true;
break;
default:
skipTag();
}
}
return state;
}
private void bodyParser(Message msg) throws IOException { private void bodyParser(Message msg) throws IOException {
String bodyType = Eas.BODY_PREFERENCE_TEXT; String bodyType = Eas.BODY_PREFERENCE_TEXT;
String body = ""; String body = "";
@ -327,18 +345,22 @@ public class EasEmailSyncAdapter extends EasSyncAdapter {
class ServerChange { class ServerChange {
long id; long id;
boolean read; Boolean read;
Boolean flag;
ServerChange(long _id, boolean _read) { ServerChange(long _id, Boolean _read, Boolean _flag) {
id = _id; id = _id;
read = _read; read = _read;
flag = _flag;
} }
} }
private void changeParser(ArrayList<ServerChange> changes) throws IOException { private void changeParser(ArrayList<ServerChange> changes) throws IOException {
String serverId = null; String serverId = null;
boolean oldRead = false; Boolean oldRead = false;
boolean read = true; Boolean read = null;
Boolean oldFlag = false;
Boolean flag = null;
long id = 0; long id = 0;
while (nextTag(EasTags.SYNC_CHANGE) != END) { while (nextTag(EasTags.SYNC_CHANGE) != END) {
switch (tag) { switch (tag) {
@ -349,6 +371,7 @@ public class EasEmailSyncAdapter extends EasSyncAdapter {
if (c.moveToFirst()) { if (c.moveToFirst()) {
mService.userLog("Changing " + serverId); mService.userLog("Changing " + serverId);
oldRead = c.getInt(Message.LIST_READ_COLUMN) == Message.READ; oldRead = c.getInt(Message.LIST_READ_COLUMN) == Message.READ;
oldFlag = c.getInt(Message.LIST_FAVORITE_COLUMN) == 1;
id = c.getLong(Message.LIST_ID_COLUMN); id = c.getLong(Message.LIST_ID_COLUMN);
} }
} finally { } finally {
@ -358,14 +381,18 @@ public class EasEmailSyncAdapter extends EasSyncAdapter {
case EasTags.EMAIL_READ: case EasTags.EMAIL_READ:
read = getValueInt() == 1; read = getValueInt() == 1;
break; break;
case EasTags.EMAIL_FLAG:
flag = flagParser();
break;
case EasTags.SYNC_APPLICATION_DATA: case EasTags.SYNC_APPLICATION_DATA:
break; break;
default: default:
skipTag(); skipTag();
} }
} }
if (oldRead != read) { if ((read != null && !oldRead.equals(read)) ||
changes.add(new ServerChange(id, read)); (flag != null && !oldFlag.equals(flag))) {
changes.add(new ServerChange(id, read, flag));
} }
} }
@ -401,9 +428,13 @@ public class EasEmailSyncAdapter extends EasSyncAdapter {
if (!changedEmails.isEmpty()) { if (!changedEmails.isEmpty()) {
// Server wins in a conflict... // Server wins in a conflict...
for (ServerChange change : changedEmails) { for (ServerChange change : changedEmails) {
// For now, don't handle read->unread ContentValues cv = new ContentValues();
ContentValues cv = new ContentValues(); if (change.read != null) {
cv.put(MessageColumns.FLAG_READ, change.read); cv.put(MessageColumns.FLAG_READ, change.read);
}
if (change.flag != null) {
cv.put(MessageColumns.FLAG_FAVORITE, change.flag);
}
ops.add(ContentProviderOperation.newUpdate( ops.add(ContentProviderOperation.newUpdate(
ContentUris.withAppendedId(Message.CONTENT_URI, change.id)) ContentUris.withAppendedId(Message.CONTENT_URI, change.id))
.withValues(cv) .withValues(cv)
@ -541,6 +572,7 @@ public class EasEmailSyncAdapter extends EasSyncAdapter {
} }
// Send the change to "read". We'll do "flagged" here eventually as well // Send the change to "read". We'll do "flagged" here eventually as well
// TODO Add support for flags here (EAS 12.0 and above) // TODO Add support for flags here (EAS 12.0 and above)
// Or is this not safe??
s.start("Change") s.start("Change")
.data("ServerId", c.getString(Message.LIST_SERVER_ID_COLUMN)) .data("ServerId", c.getString(Message.LIST_SERVER_ID_COLUMN))
.start("ApplicationData") .start("ApplicationData")