/emailcommon/src/com/android/emailcommon/service/EmailServiceProxy.java
Java | 471 lines | 267 code | 37 blank | 167 comment | 33 complexity | 49b51f37c507b8c4685146c3ab97e4f7 MD5 | raw file
- /*
- * 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.emailcommon.service;
- import android.content.Context;
- import android.content.Intent;
- import android.os.Bundle;
- import android.os.IBinder;
- import android.os.RemoteException;
- import android.util.Log;
- import com.android.emailcommon.Api;
- import com.android.emailcommon.Device;
- import com.android.emailcommon.TempDirectory;
- import com.android.emailcommon.mail.MessagingException;
- import com.android.emailcommon.provider.HostAuth;
- import com.android.emailcommon.provider.Policy;
- import java.io.IOException;
- /**
- * The EmailServiceProxy class provides a simple interface for the UI to call into the various
- * EmailService classes (e.g. ExchangeService for EAS). It wraps the service connect/disconnect
- * process so that the caller need not be concerned with it.
- *
- * Use the class like this:
- * new EmailServiceProxy(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 extends ServiceProxy implements IEmailService {
- private static final String TAG = "EmailServiceProxy";
- // Private intent that will be used to connect to an independent Exchange service
- public static final String EXCHANGE_INTENT = "com.android.email.EXCHANGE_INTENT";
- public static final String IMAP_INTENT = "com.android.email.IMAP_INTENT";
- public static final String AUTO_DISCOVER_BUNDLE_ERROR_CODE = "autodiscover_error_code";
- public static final String AUTO_DISCOVER_BUNDLE_HOST_AUTH = "autodiscover_host_auth";
- public static final String VALIDATE_BUNDLE_RESULT_CODE = "validate_result_code";
- public static final String VALIDATE_BUNDLE_POLICY_SET = "validate_policy_set";
- public static final String VALIDATE_BUNDLE_ERROR_MESSAGE = "validate_error_message";
- public static final String VALIDATE_BUNDLE_UNSUPPORTED_POLICIES =
- "validate_unsupported_policies";
- private final IEmailServiceCallback mCallback;
- private Object mReturn = null;
- private IEmailService mService;
- private final boolean isRemote;
- // Standard debugging
- public static final int DEBUG_BIT = 1;
- // Verbose (parser) logging
- public static final int DEBUG_VERBOSE_BIT = 2;
- // File (SD card) logging
- public static final int DEBUG_FILE_BIT = 4;
- // Enable strict mode
- public static final int DEBUG_ENABLE_STRICT_MODE = 8;
- // The first two constructors are used with local services that can be referenced by class
- public EmailServiceProxy(Context _context, Class<?> _class) {
- this(_context, _class, null);
- }
- public EmailServiceProxy(Context _context, Class<?> _class, IEmailServiceCallback _callback) {
- super(_context, new Intent(_context, _class));
- mCallback = _callback;
- isRemote = false;
- }
- // The following two constructors are used with remote services that must be referenced by
- // a known action or by a prebuilt intent
- public EmailServiceProxy(Context _context, Intent _intent, IEmailServiceCallback _callback) {
- super(_context, _intent);
- try {
- Device.getDeviceId(_context);
- TempDirectory.setTempDirectory(_context);
- } catch (IOException e) {
- }
- mCallback = _callback;
- isRemote = true;
- }
- public EmailServiceProxy(Context _context, String _action, IEmailServiceCallback _callback) {
- super(_context, new Intent(_action));
- try {
- Device.getDeviceId(_context);
- TempDirectory.setTempDirectory(_context);
- } catch (IOException e) {
- }
- mCallback = _callback;
- isRemote = true;
- }
- @Override
- public void onConnected(IBinder binder) {
- mService = IEmailService.Stub.asInterface(binder);
- }
- public boolean isRemote() {
- return isRemote;
- }
- @Override
- public int getApiLevel() {
- return Api.LEVEL;
- }
- /**
- * Request an attachment to be loaded; the service MUST give higher priority to
- * non-background loading. The service MUST use the loadAttachmentStatus callback when
- * loading has started and stopped and SHOULD send callbacks with progress information if
- * possible.
- *
- * @param attachmentId the id of the attachment record
- * @param background whether or not this request corresponds to a background action (i.e.
- * prefetch) vs a foreground action (user request)
- */
- @Override
- public void loadAttachment(final long attachmentId, final boolean background)
- throws RemoteException {
- setTask(new ProxyTask() {
- @Override
- public void run() throws RemoteException {
- try {
- if (mCallback != null) mService.setCallback(mCallback);
- mService.loadAttachment(attachmentId, background);
- } catch (RemoteException e) {
- try {
- // Try to send a callback (if set)
- if (mCallback != null) {
- mCallback.loadAttachmentStatus(-1, attachmentId,
- EmailServiceStatus.REMOTE_EXCEPTION, 0);
- }
- } catch (RemoteException e1) {
- }
- }
- }
- }, "loadAttachment");
- }
- /**
- * Request the sync of a mailbox; the service MUST send the syncMailboxStatus callback
- * indicating "starting" and "finished" (or error), regardless of whether the mailbox is
- * actually syncable.
- *
- * @param mailboxId the id of the mailbox record
- * @param userRequest whether or not the user specifically asked for the sync
- */
- @Override
- public void startSync(final long mailboxId, final boolean userRequest) throws RemoteException {
- setTask(new ProxyTask() {
- @Override
- public void run() throws RemoteException {
- if (mCallback != null) mService.setCallback(mCallback);
- mService.startSync(mailboxId, userRequest);
- }
- }, "startSync");
- }
- /**
- * Request the immediate termination of a mailbox sync. Although the service is not required to
- * acknowledge this request, it MUST send a "finished" (or error) syncMailboxStatus callback if
- * the sync was started via the startSync service call.
- *
- * @param mailboxId the id of the mailbox record
- * @param userRequest whether or not the user specifically asked for the sync
- */
- @Override
- public void stopSync(final long mailboxId) throws RemoteException {
- setTask(new ProxyTask() {
- @Override
- public void run() throws RemoteException {
- if (mCallback != null) mService.setCallback(mCallback);
- mService.stopSync(mailboxId);
- }
- }, "stopSync");
- }
- /**
- * Validate a user account, given a protocol, host address, port, ssl status, and credentials.
- * The result of this call is returned in a Bundle which MUST include a result code and MAY
- * include a PolicySet that is required by the account. A successful validation implies a host
- * address that serves the specified protocol and credentials sufficient to be authorized
- * by the server to do so.
- *
- * @param hostAuth the hostauth object to validate
- * @return a Bundle as described above
- */
- @Override
- public Bundle validate(final HostAuth hostAuth) throws RemoteException {
- setTask(new ProxyTask() {
- @Override
- public void run() throws RemoteException{
- if (mCallback != null) mService.setCallback(mCallback);
- mReturn = mService.validate(hostAuth);
- }
- }, "validate");
- waitForCompletion();
- if (mReturn == null) {
- Bundle bundle = new Bundle();
- bundle.putInt(VALIDATE_BUNDLE_RESULT_CODE, MessagingException.UNSPECIFIED_EXCEPTION);
- return bundle;
- } else {
- Bundle bundle = (Bundle) mReturn;
- bundle.setClassLoader(Policy.class.getClassLoader());
- Log.v(TAG, "validate returns " + bundle.getInt(VALIDATE_BUNDLE_RESULT_CODE));
- return bundle;
- }
- }
- /**
- * Attempt to determine a user's host address and credentials from an email address and
- * password. The result is returned in a Bundle which MUST include an error code and MAY (on
- * success) include a HostAuth record sufficient to enable the service to validate the user's
- * account.
- *
- * @param userName the user's email address
- * @param password the user's password
- * @return a Bundle as described above
- */
- @Override
- public Bundle autoDiscover(final String userName, final String password)
- throws RemoteException {
- setTask(new ProxyTask() {
- @Override
- public void run() throws RemoteException{
- if (mCallback != null) mService.setCallback(mCallback);
- mReturn = mService.autoDiscover(userName, password);
- }
- }, "autoDiscover");
- waitForCompletion();
- if (mReturn == null) {
- return null;
- } else {
- Bundle bundle = (Bundle) mReturn;
- bundle.setClassLoader(HostAuth.class.getClassLoader());
- Log.v(TAG, "autoDiscover returns " + bundle.getInt(AUTO_DISCOVER_BUNDLE_ERROR_CODE));
- return bundle;
- }
- }
- /**
- * Request that the service reload the folder list for the specified account. The service
- * MUST use the syncMailboxListStatus callback to indicate "starting" and "finished"
- *
- * @param accoundId the id of the account whose folder list is to be updated
- */
- @Override
- public void updateFolderList(final long accountId) throws RemoteException {
- setTask(new ProxyTask() {
- @Override
- public void run() throws RemoteException {
- if (mCallback != null) mService.setCallback(mCallback);
- mService.updateFolderList(accountId);
- }
- }, "updateFolderList");
- }
- /**
- * Specify the debug flags selected by the user. The service SHOULD log debug information as
- * requested.
- *
- * @param flags an integer whose bits represent logging flags as defined in DEBUG_* flags above
- */
- @Override
- public void setLogging(final int flags) throws RemoteException {
- setTask(new ProxyTask() {
- @Override
- public void run() throws RemoteException {
- if (mCallback != null) mService.setCallback(mCallback);
- mService.setLogging(flags);
- }
- }, "setLogging");
- }
- /**
- * Set the global callback object to be used by the service; the service MUST always use the
- * most recently set callback object
- *
- * @param cb a callback object through which all service callbacks are executed
- */
- @Override
- public void setCallback(final IEmailServiceCallback cb) throws RemoteException {
- setTask(new ProxyTask() {
- @Override
- public void run() throws RemoteException {
- mService.setCallback(cb);
- }
- }, "setCallback");
- }
- /**
- * Alert the sync adapter that the account's host information has (or may have) changed; the
- * service MUST stop all in-process or pending syncs, clear error states related to the
- * account and its mailboxes, and restart necessary sync adapters (e.g. pushed mailboxes)
- *
- * @param accountId the id of the account whose host information has changed
- */
- @Override
- public void hostChanged(final long accountId) throws RemoteException {
- setTask(new ProxyTask() {
- @Override
- public void run() throws RemoteException {
- mService.hostChanged(accountId);
- }
- }, "hostChanged");
- }
- /**
- * Send a meeting response for the specified message
- *
- * @param messageId the id of the message containing the meeting request
- * @param response the response code, as defined in EmailServiceConstants
- */
- @Override
- public void sendMeetingResponse(final long messageId, final int response)
- throws RemoteException {
- setTask(new ProxyTask() {
- @Override
- public void run() throws RemoteException {
- if (mCallback != null) mService.setCallback(mCallback);
- mService.sendMeetingResponse(messageId, response);
- }
- }, "sendMeetingResponse");
- }
- /**
- * Request the sync adapter to load a complete message
- *
- * @param messageId the id of the message to be loaded
- */
- @Override
- public void loadMore(final long messageId) throws RemoteException {
- setTask(new ProxyTask() {
- @Override
- public void run() throws RemoteException {
- if (mCallback != null) mService.setCallback(mCallback);
- mService.loadMore(messageId);
- }
- }, "startSync");
- }
- /**
- * Not yet used
- *
- * @param accountId the account in which the folder is to be created
- * @param name the name of the folder to be created
- */
- @Override
- public boolean createFolder(long accountId, String name) throws RemoteException {
- return false;
- }
- /**
- * Not yet used
- *
- * @param accountId the account in which the folder resides
- * @param name the name of the folder to be deleted
- */
- @Override
- public boolean deleteFolder(long accountId, String name) throws RemoteException {
- return false;
- }
- /**
- * Not yet used
- *
- * @param accountId the account in which the folder resides
- * @param oldName the name of the existing folder
- * @param newName the new name for the folder
- */
- @Override
- public boolean renameFolder(long accountId, String oldName, String newName)
- throws RemoteException {
- return false;
- }
- /**
- * Request the service to delete the account's PIM (personal information management) data. This
- * data includes any data that is 1) associated with the account and 2) created/stored by the
- * service or its sync adapters and 3) not stored in the EmailProvider database (e.g. contact
- * and calendar information).
- *
- * @param accountId the account whose data is to be deleted
- */
- @Override
- public void deleteAccountPIMData(final long accountId) throws RemoteException {
- setTask(new ProxyTask() {
- @Override
- public void run() throws RemoteException {
- mService.deleteAccountPIMData(accountId);
- }
- }, "deleteAccountPIMData");
- }
- /**
- * PRELIMINARY
- * Search for messages given a query string. The string is interpreted as the logical AND of
- * terms separated by white space. The search is performed on the specified mailbox in the
- * specified account (including subfolders, as specified by the includeSubfolders parameter).
- * At most numResults messages matching the query term(s) will be added to the mailbox specified
- * as destMailboxId. If mailboxId is -1, the entire account will be searched. If firstResult is
- * specified and non-zero, results will be added starting with the firstResult'th match (i.e.
- * for the continuation of a previous search)
- *
- * @param accountId the id of the account to be searched
- * @param searchParams the search specification
- * @param destMailboxId the id of the mailbox into which search results are appended
- * @return the total number of matches for this search (regardless of how many were requested)
- */
- @Override
- public int searchMessages(final long accountId, final SearchParams searchParams,
- final long destMailboxId) throws RemoteException {
- setTask(new ProxyTask() {
- @Override
- public void run() throws RemoteException{
- if (mCallback != null) mService.setCallback(mCallback);
- mReturn = mService.searchMessages(accountId, searchParams, destMailboxId);
- }
- }, "searchMessages");
- waitForCompletion();
- if (mReturn == null) {
- return 0;
- } else {
- return (Integer)mReturn;
- }
- }
- /**
- * Request the service to send mail in the specified account's Outbox
- *
- * @param accountId the account whose outgoing mail should be sent
- */
- @Override
- public void sendMail(final long accountId) throws RemoteException {
- setTask(new ProxyTask() {
- @Override
- public void run() throws RemoteException{
- if (mCallback != null) mService.setCallback(mCallback);
- mService.sendMail(accountId);
- }
- }, "sendMail");
- }
- @Override
- public IBinder asBinder() {
- return null;
- }
- }