Add MAIL_SERVICE WAKEUP, SEND, MOVE, READ, DELETE MESSAGE action

Add change in Email App to process following intents
from Bluetooth App, for MAP MSE support.

- org.codeaurora.email.intent.action.MAIL_SERVICE_WAKEUP
- org.codeaurora.email.intent.action.MAIL_SERVICE_DELETE_MESSAGE
- org.codeaurora.email.intent.action.MAIL_SERVICE_MOVE_MESSAGE
- org.codeaurora.email.intent.action.MAIL_SERVICE_MESSAGE_READ
- org.codeaurora.email.intent.action.MAIL_SERVICE_SEND_PENDING

Change-Id: I2b46265ba20c6f333c9e6d1b19ee73f5a066f1ff
This commit is contained in:
Ashwini Munigala 2014-08-05 15:13:02 +05:30 committed by Linux Build Service Account
parent dcb985eafe
commit 11f2252994
6 changed files with 415 additions and 5 deletions

20
AndroidManifest.xml Normal file → Executable file
View File

@ -448,13 +448,23 @@
<receiver
android:name=".service.EmailBroadcastReceiver"
android:enabled="true">
android:enabled="true"
android:permission="com.android.email.permission.ACCESS_PROVIDER">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.DEVICE_STORAGE_LOW" />
<action android:name="android.intent.action.DEVICE_STORAGE_OK" />
<action android:name="android.intent.action.LOCALE_CHANGED"/>
<action android:name="android.accounts.LOGIN_ACCOUNTS_CHANGED" />
<action android:name="org.codeaurora.email.intent.action.MAIL_SERVICE_WAKEUP" />
<action
android:name="org.codeaurora.email.intent.action.MAIL_SERVICE_DELETE_MESSAGE" />
<action
android:name="org.codeaurora.email.intent.action.MAIL_SERVICE_MOVE_MESSAGE" />
<action
android:name="org.codeaurora.email.intent.action.MAIL_SERVICE_MESSAGE_READ" />
<action
android:name="org.codeaurora.email.intent.action.MAIL_SERVICE_SEND_PENDING" />
</intent-filter>
<!-- To handle new message notifications -->
<intent-filter>
@ -581,6 +591,14 @@
<intent-filter>
<action
android:name="com.android.email.IMAP_INTENT" />
<action
android:name="org.codeaurora.email.intent.action.MAIL_SERVICE_DELETE_MESSAGE" />
<action
android:name="org.codeaurora.email.intent.action.MAIL_SERVICE_MOVE_MESSAGE" />
<action
android:name="org.codeaurora.email.intent.action.MAIL_SERVICE_MESSAGE_READ" />
<action
android:name="org.codeaurora.email.intent.action.MAIL_SERVICE_SEND_PENDING" />
</intent-filter>
</service>

View File

@ -260,11 +260,11 @@ public class AccountReconciler {
final String protocol = EmailServiceUtils.getProtocolFromAccountType(
context, accountType);
final EmailServiceInfo info = EmailServiceUtils.getServiceInfo(context, protocol);
if (info == null || !info.syncCalendar) {
if (info != null && !info.syncCalendar) {
ContentResolver.setIsSyncable(accountManagerAccount,
CalendarContract.AUTHORITY, 0);
}
if (info == null || !info.syncContacts) {
if (info != null && !info.syncContacts) {
ContentResolver.setIsSyncable(accountManagerAccount,
ContactsContract.AUTHORITY, 0);
}

View File

@ -19,13 +19,163 @@ package com.android.email.service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import com.android.email.Preferences;
import com.android.email.R;
import com.android.email.SecurityPolicy;
import com.android.email.provider.AccountReconciler;
import com.android.email.provider.EmailProvider;
import com.android.emailcommon.Logging;
import com.android.emailcommon.VendorPolicyLoader;
import com.android.emailcommon.provider.Account;
import com.android.emailcommon.provider.EmailContent;
import com.android.emailcommon.provider.EmailContent.AccountColumns;
import com.android.emailcommon.provider.HostAuth;
import com.android.emailcommon.provider.Mailbox;
import com.android.mail.utils.LogUtils;
import android.util.Log;
/**
* The broadcast receiver. The actual job is done in EmailBroadcastProcessor on a worker thread.
*/
public class EmailBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "EmailBroadcastReceiver";
private static final String ACTION_CHECK_MAIL =
"org.codeaurora.email.intent.action.MAIL_SERVICE_WAKEUP";
private static final String EXTRA_ACCOUNT = "org.codeaurora.email.intent.extra.ACCOUNT";
private static final String ACTION_DELETE_MESSAGE =
"org.codeaurora.email.intent.action.MAIL_SERVICE_DELETE_MESSAGE";
private static final String ACTION_MOVE_MESSAGE =
"org.codeaurora.email.intent.action.MAIL_SERVICE_MOVE_MESSAGE";
private static final String ACTION_MESSAGE_READ =
"org.codeaurora.email.intent.action.MAIL_SERVICE_MESSAGE_READ";
private static final String ACTION_SEND_PENDING_MAIL =
"org.codeaurora.email.intent.action.MAIL_SERVICE_SEND_PENDING";
private static final String EXTRA_MESSAGE_ID = "org.codeaurora.email.intent.extra.MESSAGE_ID";
private static final String EXTRA_MESSAGE_INFO =
"org.codeaurora.email.intent.extra.MESSAGE_INFO";
@Override
public void onReceive(Context context, Intent intent) {
EmailBroadcastProcessorService.processBroadcastIntent(context, intent);
String action = intent.getAction();
Log.d(TAG,"Received " + action);
if (ACTION_CHECK_MAIL.equals(action)) {
Intent i;
final long accountId = intent.getLongExtra(EXTRA_ACCOUNT, -1);
Log.d(TAG, "accountId is " + accountId);
final long inboxId = Mailbox.findMailboxOfType(context, accountId,
Mailbox.TYPE_INBOX);
Log.d(TAG, "inboxId is " + inboxId);
Mailbox mailbox = Mailbox.restoreMailboxWithId(context, inboxId);
if (mailbox == null) {
return;
}
Account account = Account.restoreAccountWithId(context, mailbox.mAccountKey);
String protocol = account.getProtocol(context);
Log.d(TAG, "protocol is " + protocol);
String legacyImapProtocol = context.getString(R.string.protocol_legacy_imap);
if (protocol.equals(legacyImapProtocol)) {
i = new Intent(context, ImapService.class);
} else {
i = new Intent(context, Pop3Service.class);
}
i.setAction(intent.getAction());
i.putExtra(EXTRA_ACCOUNT,
intent.getLongExtra(EXTRA_ACCOUNT, -1));
context.startService(i);
} else if (ACTION_DELETE_MESSAGE.equals(action)) {
Intent i;
final long messageId = intent.getLongExtra(EXTRA_MESSAGE_ID, -1);
Log.d(TAG, "messageId is " + messageId);
Account account = Account.getAccountForMessageId(context, messageId);
if (account == null ) {
return;
}
String protocol = account.getProtocol(context);
Log.d(TAG, "protocol is " + protocol + " ActId: " + account.getId());
String legacyImapProtocol = context.getString(R.string.protocol_legacy_imap);
if (protocol.equals(legacyImapProtocol)) {
i = new Intent(context, ImapService.class);
i.setAction(intent.getAction());
i.putExtra(EXTRA_ACCOUNT,
intent.getLongExtra(EXTRA_ACCOUNT, -1));
i.putExtra(EXTRA_MESSAGE_ID,
intent.getLongExtra(EXTRA_MESSAGE_ID, -1));
context.startService(i);
} else {
Log.i(TAG, "DELETE MESSAGE POP3 NOT Implemented");
}
} else if (ACTION_MESSAGE_READ.equals(action)) {
Intent i;
final long messageId = intent.getLongExtra(EXTRA_MESSAGE_ID, -1);
Log.d(TAG, "messageId is " + messageId);
Account account = Account.getAccountForMessageId(context, messageId);
if (account == null ) {
return;
}
String protocol = account.getProtocol(context);
Log.d(TAG, "protocol is " + protocol + " ActId: " + account.getId());
String legacyImapProtocol = context.getString(R.string.protocol_legacy_imap);
if (protocol.equals(legacyImapProtocol)) {
i = new Intent(context, ImapService.class);
i.setAction(intent.getAction());
i.putExtra(EXTRA_ACCOUNT,
intent.getLongExtra(EXTRA_ACCOUNT, -1));
i.putExtra(EXTRA_MESSAGE_ID,
intent.getLongExtra(EXTRA_MESSAGE_ID, -1));
i.putExtra(EXTRA_MESSAGE_INFO,
intent.getIntExtra(EXTRA_MESSAGE_INFO, 0));
context.startService(i);
} else {
Log.i(TAG, "READ MESSAGE POP3 NOT Implemented");
}
} else if (ACTION_MOVE_MESSAGE.equals(action)) {
Intent i;
final long messageId = intent.getLongExtra(EXTRA_MESSAGE_ID, -1);
Log.d(TAG, "messageId is " + messageId);
Account account = Account.getAccountForMessageId(context, messageId);
if (account == null ) {
return;
}
String protocol = account.getProtocol(context);
Log.d(TAG, "protocol is " + protocol + " ActId: " + account.getId());
String legacyImapProtocol = context.getString(R.string.protocol_legacy_imap);
if (protocol.equals(legacyImapProtocol)) {
i = new Intent(context, ImapService.class);
i.setAction(intent.getAction());
i.putExtra(EXTRA_ACCOUNT,
intent.getLongExtra(EXTRA_ACCOUNT, -1));
i.putExtra(EXTRA_MESSAGE_ID,
intent.getLongExtra(EXTRA_MESSAGE_ID, -1));
i.putExtra(EXTRA_MESSAGE_INFO,
intent.getIntExtra(EXTRA_MESSAGE_INFO, 0));
context.startService(i);
} else {
Log.i(TAG, "READ MESSAGE POP3 NOT Implemented");
}
} else if (ACTION_SEND_PENDING_MAIL.equals(action)) {
Intent i;
final long accountId = intent.getLongExtra(EXTRA_ACCOUNT, -1);
Log.d(TAG, "accountId is " + accountId);
Account account = Account.restoreAccountWithId(context, accountId);
if (account == null ) {
return;
}
String protocol = account.getProtocol(context);
Log.d(TAG, "protocol is " + protocol);
String legacyImapProtocol = context.getString(R.string.protocol_legacy_imap);
if (protocol.equals(legacyImapProtocol)) {
i = new Intent(context, ImapService.class);
i.setAction(intent.getAction());
i.putExtra(EXTRA_ACCOUNT,
intent.getLongExtra(EXTRA_ACCOUNT, -1));
context.startService(i);
} else {
Log.i(TAG, "SEND MESSAGE POP3 NOT Implemented");
}
} else {
EmailBroadcastProcessorService.processBroadcastIntent(context, intent);
}
}
}

View File

@ -24,12 +24,15 @@ import android.net.TrafficStats;
import android.net.Uri;
import android.os.Bundle;
import android.os.RemoteException;
import android.text.TextUtils;
import com.android.email.DebugUtils;
import com.android.email.NotificationController;
import com.android.email.NotificationControllerCreatorHolder;
import com.android.email.mail.Sender;
import com.android.email.mail.Store;
import com.android.email.provider.AccountReconciler;
import com.android.email.provider.Utilities;
import com.android.email.service.EmailServiceUtils.EmailServiceInfo;
import com.android.emailcommon.Logging;
import com.android.emailcommon.TrafficFlags;
@ -115,10 +118,118 @@ public abstract class EmailServiceStub extends IEmailService.Stub implements IEm
extras.putInt(Mailbox.SYNC_EXTRA_DELTA_MESSAGE_COUNT, deltaMessageCount);
}
ContentResolver.requestSync(acct, EmailContent.AUTHORITY, extras);
LogUtils.i(Logging.LOG_TAG, "requestSync EmailServiceStub startSync %s, %s",
LogUtils.i(Logging.LOG_TAG, "requestSync EmailServiceStub requestSync %s, %s",
account.toString(), extras.toString());
}
/**
* Delete a single message by moving it to the trash, or really delete it if it's already in
* trash or a draft message.
*
* This function has no callback, no result reporting, because the desired outcome
* is reflected entirely by changes to one or more cursors.
*
* @param messageId The id of the message to "delete".
*/
public void deleteMessage(long messageId) {
final EmailContent.Message message =
EmailContent.Message.restoreMessageWithId(mContext, messageId);
if (message == null) {
if (Logging.LOGD) LogUtils.v(Logging.LOG_TAG, "dletMsg message NULL");
return;
}
// 1. Get the message's account
final Account account = Account.restoreAccountWithId(mContext, message.mAccountKey);
// 2. Get the message's original mailbox
final Mailbox mailbox = Mailbox.restoreMailboxWithId(mContext, message.mMailboxKey);
if (account == null || mailbox == null) {
if (Logging.LOGD) LogUtils.v(Logging.LOG_TAG, "dletMsg account or mailbox NULL");
return;
}
if(Logging.LOGD)
LogUtils.d(Logging.LOG_TAG, "AccountKey " + account.mId + "oirigMailbix: "
+ mailbox.mId);
// 3. Confirm that there is a trash mailbox available. If not, create one
Mailbox trashFolder = Mailbox.restoreMailboxOfType(mContext, account.mId,
Mailbox.TYPE_TRASH);
if (trashFolder == null) {
if (Logging.LOGD) LogUtils.v(Logging.LOG_TAG, "dletMsg Trash mailbox NULL");
} else {
LogUtils.d(Logging.LOG_TAG, "TrasMailbix: " + trashFolder.mId);
}
// 4. Drop non-essential data for the message (e.g. attachment files)
AttachmentUtilities.deleteAllAttachmentFiles(mContext, account.mId,
messageId);
Uri uri = ContentUris.withAppendedId(EmailContent.Message.SYNCED_CONTENT_URI,
messageId);
// 5. Perform "delete" as appropriate
if ((mailbox.mId == trashFolder.mId) || (mailbox.mType == Mailbox.TYPE_DRAFTS)) {
// 5a. Really delete it
mContext.getContentResolver().delete(uri, null, null);
} else {
// 5b. Move to trash
ContentValues cv = new ContentValues();
cv.put(EmailContent.MessageColumns.MAILBOX_KEY, trashFolder.mId);
mContext.getContentResolver().update(uri, cv, null, null);
}
}
/**
* Moves messages to a new mailbox.
* This function has no callback, no result reporting, because the desired outcome
* is reflected entirely by changes to one or more cursors.
* Note this method assumes all of the given message and mailbox IDs belong to the same
* account.
*
* @param messageIds IDs of the messages that are to be moved
* @param newMailboxId ID of the new mailbox that the messages will be moved to
* @return an asynchronous task that executes the move (for testing only)
*/
public void MoveMessages(long messageId, long newMailboxId) {
Account account = Account.getAccountForMessageId(mContext, messageId);
if (account != null) {
if (Logging.LOGD) {
LogUtils.d(Logging.LOG_TAG, "moveMessage Acct " + account.mId);
LogUtils.d(Logging.LOG_TAG, "moveMessage messageId:" + messageId);
}
ContentValues cv = new ContentValues();
cv.put(EmailContent.MessageColumns.MAILBOX_KEY, newMailboxId);
ContentResolver resolver = mContext.getContentResolver();
Uri uri = ContentUris.withAppendedId(
EmailContent.Message.SYNCED_CONTENT_URI, messageId);
resolver.update(uri, cv, null, null);
} else {
LogUtils.d(Logging.LOG_TAG, "moveMessage Cannot find account");
}
}
/**
* Set/clear boolean columns of a message
* @param messageId the message to update
* @param columnName the column to update
* @param columnValue the new value for the column
*/
private void setMessageBoolean(long messageId, String columnName, boolean columnValue) {
ContentValues cv = new ContentValues();
cv.put(columnName, columnValue);
Uri uri = ContentUris.withAppendedId(EmailContent.Message.SYNCED_CONTENT_URI, messageId);
mContext.getContentResolver().update(uri, cv, null, null);
}
/**
* Set/clear the unread status of a message
*
* @param messageId the message to update
* @param isRead the new value for the isRead flag
*/
public void setMessageRead(long messageId, boolean isRead) {
setMessageBoolean(messageId, EmailContent.MessageColumns.FLAG_READ, isRead);
}
@Override
public void loadAttachment(final IEmailServiceCallback cb, final long accountId,
final long attachmentId, final boolean background) throws RemoteException {

View File

@ -76,6 +76,7 @@ public class ImapService extends Service {
private static final long QUICK_SYNC_WINDOW_MILLIS = DateUtils.DAY_IN_MILLIS;
private static final long FULL_SYNC_WINDOW_MILLIS = 7 * DateUtils.DAY_IN_MILLIS;
private static final long FULL_SYNC_INTERVAL_MILLIS = 4 * DateUtils.HOUR_IN_MILLIS;
private static final String TAG = "ImapService";
// The maximum number of messages to fetch in a single command.
private static final int MAX_MESSAGES_TO_FETCH = 500;
@ -108,6 +109,20 @@ public class ImapService extends Service {
* We write this into the serverId field of messages that will never be upsynced.
*/
private static final String LOCAL_SERVERID_PREFIX = "Local-";
private static final String ACTION_CHECK_MAIL =
"org.codeaurora.email.intent.action.MAIL_SERVICE_WAKEUP";
private static final String EXTRA_ACCOUNT = "org.codeaurora.email.intent.extra.ACCOUNT";
private static final String ACTION_DELETE_MESSAGE =
"org.codeaurora.email.intent.action.MAIL_SERVICE_DELETE_MESSAGE";
private static final String ACTION_MOVE_MESSAGE =
"org.codeaurora.email.intent.action.MAIL_SERVICE_MOVE_MESSAGE";
private static final String ACTION_MESSAGE_READ =
"org.codeaurora.email.intent.action.MAIL_SERVICE_MESSAGE_READ";
private static final String ACTION_SEND_PENDING_MAIL =
"org.codeaurora.email.intent.action.MAIL_SERVICE_SEND_PENDING";
private static final String EXTRA_MESSAGE_ID = "org.codeaurora.email.intent.extra.MESSAGE_ID";
private static final String EXTRA_MESSAGE_INFO =
"org.codeaurora.email.intent.extra.MESSAGE_INFO";
private static String sMessageDecodeErrorString;
@ -129,6 +144,105 @@ public class ImapService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
final String action = intent.getAction();
if (Logging.LOGD) {
LogUtils.d(Logging.LOG_TAG, "Action: ", action);
}
final long accountId = intent.getLongExtra(EXTRA_ACCOUNT, -1);
Context context = getApplicationContext();
if (ACTION_CHECK_MAIL.equals(action)) {
final long inboxId = Mailbox.findMailboxOfType(context, accountId,
Mailbox.TYPE_INBOX);
if (Logging.LOGD) {
LogUtils.d(Logging.LOG_TAG, "accountId is " + accountId);
LogUtils.d(Logging.LOG_TAG, "inboxId is " + inboxId);
}
if (accountId <= -1 || inboxId <= -1 ) {
return START_NOT_STICKY;
}
mBinder.init(context);
mBinder.requestSync(inboxId,true,0);
} else if (ACTION_DELETE_MESSAGE.equals(action)) {
final long messageId = intent.getLongExtra(EXTRA_MESSAGE_ID, -1);
if (Logging.LOGD) {
LogUtils.d(Logging.LOG_TAG, "action: Delete Message mail");
LogUtils.d(Logging.LOG_TAG, "action: delmsg " + messageId);
}
if (accountId <= -1 || messageId <= -1 ) {
return START_NOT_STICKY;
}
Store remoteStore = null;
try {
remoteStore = Store.getInstance(Account.getAccountForMessageId(context, messageId),
context);
mBinder.init(context);
mBinder.deleteMessage(messageId);
processPendingActionsSynchronous(context,
Account.getAccountForMessageId(context, messageId), remoteStore, true);
} catch (Exception e) {
LogUtils.d(Logging.LOG_TAG, "RemoteException " + e);
}
} else if (ACTION_MESSAGE_READ.equals(action)) {
final long messageId = intent.getLongExtra(EXTRA_MESSAGE_ID, -1);
final int flagRead = intent.getIntExtra(EXTRA_MESSAGE_INFO, 0);
if (Logging.LOGD) {
LogUtils.d(Logging.LOG_TAG, "action: Message Mark Read or UnRead ");
LogUtils.d(Logging.LOG_TAG, "action: delmsg " + messageId);
}
if (accountId <= -1 || messageId <= -1 ) {
return START_NOT_STICKY;
}
Store remoteStore = null;
try {
mBinder.init(context);
mBinder.setMessageRead(messageId, (flagRead == 1)? true:false);
remoteStore = Store.getInstance(Account.getAccountForMessageId(context, messageId),
context);
processPendingActionsSynchronous(context,
Account.getAccountForMessageId(context, messageId), remoteStore, true);
} catch (Exception e){
LogUtils.d(Logging.LOG_TAG, "RemoteException " + e);
}
} else if (ACTION_MOVE_MESSAGE.equals(action)) {
final long messageId = intent.getLongExtra(EXTRA_MESSAGE_ID, -1);
final int mailboxType = intent.getIntExtra(EXTRA_MESSAGE_INFO, Mailbox.TYPE_INBOX);
final long mailboxId = Mailbox.findMailboxOfType(context, accountId, mailboxType);
if (Logging.LOGD) {
LogUtils.d(Logging.LOG_TAG, "action: Move Message mail");
LogUtils.d(Logging.LOG_TAG, "action: movemsg " + messageId +
"mailbox: " + mailboxType + "accountId: " + accountId + "mailboxId: "
+ mailboxId);
}
if (accountId <= -1 || messageId <= -1 || mailboxId <= -1){
return START_NOT_STICKY;
}
Store remoteStore = null;
try {
mBinder.init(context);
mBinder.MoveMessages(messageId, mailboxId);
remoteStore = Store.getInstance(Account.getAccountForMessageId(context, messageId),
context);
processPendingActionsSynchronous(context,
Account.getAccountForMessageId(context, messageId),remoteStore, true);
} catch (Exception e){
LogUtils.d(Logging.LOG_TAG, "RemoteException " + e);
}
} else if (ACTION_SEND_PENDING_MAIL.equals(action)) {
if (Logging.LOGD) {
LogUtils.d(Logging.LOG_TAG, "action: Send Pending Mail " + accountId);
}
if (accountId <= -1 ) {
return START_NOT_STICKY;
}
try {
mBinder.init(context);
mBinder.sendMail(accountId);
} catch (Exception e) {
LogUtils.e(Logging.LOG_TAG, "RemoteException " + e);
}
}
return Service.START_STICKY;
}

View File

@ -62,13 +62,30 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import android.util.Log;
public class Pop3Service extends Service {
private static final String TAG = "Pop3Service";
private static final int DEFAULT_SYNC_COUNT = 100;
private static final String ACTION_CHECK_MAIL =
"org.codeaurora.email.intent.action.MAIL_SERVICE_WAKEUP";
private static final String EXTRA_ACCOUNT = "org.codeaurora.email.intent.extra.ACCOUNT";
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG,"Inside onStartCommand");
final String action = intent.getAction();
Log.d(TAG,"action is " + action);
Context context = getApplicationContext();
if (ACTION_CHECK_MAIL.equals(action)) {
final long accountId = intent.getLongExtra(EXTRA_ACCOUNT, -1);
Log.d(TAG,"accountId is " + accountId);
final long inboxId = Mailbox.findMailboxOfType(context, accountId,
Mailbox.TYPE_INBOX);
Log.d(TAG,"inboxId is " + inboxId);
mBinder.init(context);
mBinder.requestSync(inboxId, true, 0);
}
return Service.START_STICKY;
}