10d4fc55861ed4393aa82f124f2865695ef564641Marc Blank/*
20d4fc55861ed4393aa82f124f2865695ef564641Marc Blank * Copyright (C) 2009 The Android Open Source Project
30d4fc55861ed4393aa82f124f2865695ef564641Marc Blank *
40d4fc55861ed4393aa82f124f2865695ef564641Marc Blank * Licensed under the Apache License, Version 2.0 (the "License");
50d4fc55861ed4393aa82f124f2865695ef564641Marc Blank * you may not use this file except in compliance with the License.
60d4fc55861ed4393aa82f124f2865695ef564641Marc Blank * You may obtain a copy of the License at
70d4fc55861ed4393aa82f124f2865695ef564641Marc Blank *
80d4fc55861ed4393aa82f124f2865695ef564641Marc Blank *      http://www.apache.org/licenses/LICENSE-2.0
90d4fc55861ed4393aa82f124f2865695ef564641Marc Blank *
100d4fc55861ed4393aa82f124f2865695ef564641Marc Blank * Unless required by applicable law or agreed to in writing, software
110d4fc55861ed4393aa82f124f2865695ef564641Marc Blank * distributed under the License is distributed on an "AS IS" BASIS,
120d4fc55861ed4393aa82f124f2865695ef564641Marc Blank * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130d4fc55861ed4393aa82f124f2865695ef564641Marc Blank * See the License for the specific language governing permissions and
140d4fc55861ed4393aa82f124f2865695ef564641Marc Blank * limitations under the License.
150d4fc55861ed4393aa82f124f2865695ef564641Marc Blank */
160d4fc55861ed4393aa82f124f2865695ef564641Marc Blank
170d4fc55861ed4393aa82f124f2865695ef564641Marc Blankpackage com.android.emailcommon.service;
180d4fc55861ed4393aa82f124f2865695ef564641Marc Blank
190d4fc55861ed4393aa82f124f2865695ef564641Marc Blankimport android.content.Context;
200d4fc55861ed4393aa82f124f2865695ef564641Marc Blankimport android.content.Intent;
210d4fc55861ed4393aa82f124f2865695ef564641Marc Blankimport android.os.Bundle;
220d4fc55861ed4393aa82f124f2865695ef564641Marc Blankimport android.os.IBinder;
230d4fc55861ed4393aa82f124f2865695ef564641Marc Blankimport android.os.RemoteException;
240d4fc55861ed4393aa82f124f2865695ef564641Marc Blank
25f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blankimport com.android.emailcommon.Device;
26f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blankimport com.android.emailcommon.TempDirectory;
27f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blankimport com.android.emailcommon.mail.MessagingException;
28f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blankimport com.android.emailcommon.provider.HostAuth;
29f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blankimport com.android.emailcommon.provider.Policy;
30560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedyimport com.android.mail.utils.LogUtils;
31f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank
32dc78a769fce18d259eccc602c4623fa74cdf5319Marc Blankimport java.io.IOException;
33dc78a769fce18d259eccc602c4623fa74cdf5319Marc Blank
340d4fc55861ed4393aa82f124f2865695ef564641Marc Blank/**
350d4fc55861ed4393aa82f124f2865695ef564641Marc Blank * The EmailServiceProxy class provides a simple interface for the UI to call into the various
367afbeee47e1a82680c815f2fb8cfdba32d6b0b84Martin Hibdon * EmailService classes (e.g. EasService for EAS).  It wraps the service connect/disconnect
370d4fc55861ed4393aa82f124f2865695ef564641Marc Blank * process so that the caller need not be concerned with it.
380d4fc55861ed4393aa82f124f2865695ef564641Marc Blank *
390d4fc55861ed4393aa82f124f2865695ef564641Marc Blank * Use the class like this:
40c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank *   new EmailServiceProxy(context, class).loadAttachment(attachmentId, callback)
410d4fc55861ed4393aa82f124f2865695ef564641Marc Blank *
420d4fc55861ed4393aa82f124f2865695ef564641Marc Blank * Methods without a return value return immediately (i.e. are asynchronous); methods with a
430d4fc55861ed4393aa82f124f2865695ef564641Marc Blank * return value wait for a result from the Service (i.e. they should not be called from the UI
440d4fc55861ed4393aa82f124f2865695ef564641Marc Blank * thread) with a default timeout of 30 seconds (settable)
450d4fc55861ed4393aa82f124f2865695ef564641Marc Blank *
460d4fc55861ed4393aa82f124f2865695ef564641Marc Blank * An EmailServiceProxy object cannot be reused (trying to do so generates a RemoteException)
470d4fc55861ed4393aa82f124f2865695ef564641Marc Blank */
480d4fc55861ed4393aa82f124f2865695ef564641Marc Blank
490d4fc55861ed4393aa82f124f2865695ef564641Marc Blankpublic class EmailServiceProxy extends ServiceProxy implements IEmailService {
500d4fc55861ed4393aa82f124f2865695ef564641Marc Blank    private static final String TAG = "EmailServiceProxy";
510d4fc55861ed4393aa82f124f2865695ef564641Marc Blank
520d4fc55861ed4393aa82f124f2865695ef564641Marc Blank    public static final String AUTO_DISCOVER_BUNDLE_ERROR_CODE = "autodiscover_error_code";
530d4fc55861ed4393aa82f124f2865695ef564641Marc Blank    public static final String AUTO_DISCOVER_BUNDLE_HOST_AUTH = "autodiscover_host_auth";
540d4fc55861ed4393aa82f124f2865695ef564641Marc Blank
550d4fc55861ed4393aa82f124f2865695ef564641Marc Blank    public static final String VALIDATE_BUNDLE_RESULT_CODE = "validate_result_code";
560d4fc55861ed4393aa82f124f2865695ef564641Marc Blank    public static final String VALIDATE_BUNDLE_POLICY_SET = "validate_policy_set";
570d4fc55861ed4393aa82f124f2865695ef564641Marc Blank    public static final String VALIDATE_BUNDLE_ERROR_MESSAGE = "validate_error_message";
58265530723b8c008f6bc23b1723f4de706a3e9556Marc Blank    public static final String VALIDATE_BUNDLE_UNSUPPORTED_POLICIES =
59265530723b8c008f6bc23b1723f4de706a3e9556Marc Blank        "validate_unsupported_policies";
600d5e21d0fcd337cecce929a3b1bdb0b8b5871b2cYu Ping Hu    public static final String VALIDATE_BUNDLE_PROTOCOL_VERSION = "validate_protocol_version";
61c28347552e543b2fc04c922336ddca75221a1eefYu Ping Hu    public static final String VALIDATE_BUNDLE_REDIRECT_ADDRESS = "validate_redirect_address";
620d4fc55861ed4393aa82f124f2865695ef564641Marc Blank
630d4fc55861ed4393aa82f124f2865695ef564641Marc Blank    private Object mReturn = null;
640d4fc55861ed4393aa82f124f2865695ef564641Marc Blank    private IEmailService mService;
65f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank    private final boolean isRemote;
660d4fc55861ed4393aa82f124f2865695ef564641Marc Blank
670d4fc55861ed4393aa82f124f2865695ef564641Marc Blank    // Standard debugging
6851c653646d14d841fbe527aee9fab7a1886338f8Martin Hibdon    public static final int DEBUG_BIT = 0x01;
690d4fc55861ed4393aa82f124f2865695ef564641Marc Blank    // Verbose (parser) logging
7051c653646d14d841fbe527aee9fab7a1886338f8Martin Hibdon    public static final int DEBUG_EXCHANGE_BIT = 0x02;
710d4fc55861ed4393aa82f124f2865695ef564641Marc Blank    // File (SD card) logging
7251c653646d14d841fbe527aee9fab7a1886338f8Martin Hibdon    public static final int DEBUG_FILE_BIT = 0x04;
7319b2a7ebc9cc770baace1605ff5b44b3fcb46320Makoto Onuki    // Enable strict mode
7451c653646d14d841fbe527aee9fab7a1886338f8Martin Hibdon    public static final int DEBUG_ENABLE_STRICT_MODE = 0x08;
750d4fc55861ed4393aa82f124f2865695ef564641Marc Blank
760d4fc55861ed4393aa82f124f2865695ef564641Marc Blank    // The first two constructors are used with local services that can be referenced by class
770d4fc55861ed4393aa82f124f2865695ef564641Marc Blank    public EmailServiceProxy(Context _context, Class<?> _class) {
780d4fc55861ed4393aa82f124f2865695ef564641Marc Blank        super(_context, new Intent(_context, _class));
7969ef2b22ff6c5dcce78423ef502d14f841b04fedPaul Westbrook        TempDirectory.setTempDirectory(_context);
80f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank        isRemote = false;
810d4fc55861ed4393aa82f124f2865695ef564641Marc Blank    }
820d4fc55861ed4393aa82f124f2865695ef564641Marc Blank
830d4fc55861ed4393aa82f124f2865695ef564641Marc Blank    // The following two constructors are used with remote services that must be referenced by
840d4fc55861ed4393aa82f124f2865695ef564641Marc Blank    // a known action or by a prebuilt intent
852075c97f608a853923980865b72147a5c8ef71f0Yu Ping Hu    public EmailServiceProxy(Context _context, Intent _intent) {
860d4fc55861ed4393aa82f124f2865695ef564641Marc Blank        super(_context, _intent);
87dc78a769fce18d259eccc602c4623fa74cdf5319Marc Blank        try {
88dc78a769fce18d259eccc602c4623fa74cdf5319Marc Blank            Device.getDeviceId(_context);
89dc78a769fce18d259eccc602c4623fa74cdf5319Marc Blank        } catch (IOException e) {
90dc78a769fce18d259eccc602c4623fa74cdf5319Marc Blank        }
9169ef2b22ff6c5dcce78423ef502d14f841b04fedPaul Westbrook        TempDirectory.setTempDirectory(_context);
92f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank        isRemote = true;
930d4fc55861ed4393aa82f124f2865695ef564641Marc Blank    }
940d4fc55861ed4393aa82f124f2865695ef564641Marc Blank
950d4fc55861ed4393aa82f124f2865695ef564641Marc Blank    @Override
960d4fc55861ed4393aa82f124f2865695ef564641Marc Blank    public void onConnected(IBinder binder) {
970d4fc55861ed4393aa82f124f2865695ef564641Marc Blank        mService = IEmailService.Stub.asInterface(binder);
980d4fc55861ed4393aa82f124f2865695ef564641Marc Blank    }
990d4fc55861ed4393aa82f124f2865695ef564641Marc Blank
100f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank    public boolean isRemote() {
101f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank        return isRemote;
102f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank    }
103f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank
104c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank    /**
105c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     * Request an attachment to be loaded; the service MUST give higher priority to
106c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     * non-background loading.  The service MUST use the loadAttachmentStatus callback when
107c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     * loading has started and stopped and SHOULD send callbacks with progress information if
108c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     * possible.
109c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     *
110d5acf0bbc00cbe9a2c075e1bd4825ccbd9851d8dYu Ping Hu     * @param cb The {@link IEmailServiceCallback} to use for this operation.
11170cb2878d72ce1c1775ac0426ff82698a5e59377Anthony Lee     * @param accountId the id of the account in question
112c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     * @param attachmentId the id of the attachment record
113c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     * @param background whether or not this request corresponds to a background action (i.e.
114c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     * prefetch) vs a foreground action (user request)
115c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     */
116f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank    @Override
11770cb2878d72ce1c1775ac0426ff82698a5e59377Anthony Lee    public void loadAttachment(final IEmailServiceCallback cb, final long accountId,
11870cb2878d72ce1c1775ac0426ff82698a5e59377Anthony Lee            final long attachmentId, final boolean background)
119dc78a769fce18d259eccc602c4623fa74cdf5319Marc Blank            throws RemoteException {
1200d4fc55861ed4393aa82f124f2865695ef564641Marc Blank        setTask(new ProxyTask() {
121f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank            @Override
1220d4fc55861ed4393aa82f124f2865695ef564641Marc Blank            public void run() throws RemoteException {
1230d4fc55861ed4393aa82f124f2865695ef564641Marc Blank                try {
12470cb2878d72ce1c1775ac0426ff82698a5e59377Anthony Lee                    mService.loadAttachment(cb, accountId, attachmentId, background);
1250d4fc55861ed4393aa82f124f2865695ef564641Marc Blank                } catch (RemoteException e) {
1260d4fc55861ed4393aa82f124f2865695ef564641Marc Blank                    try {
1270d4fc55861ed4393aa82f124f2865695ef564641Marc Blank                        // Try to send a callback (if set)
1282075c97f608a853923980865b72147a5c8ef71f0Yu Ping Hu                        if (cb != null) {
1292075c97f608a853923980865b72147a5c8ef71f0Yu Ping Hu                            cb.loadAttachmentStatus(-1, attachmentId,
1300d4fc55861ed4393aa82f124f2865695ef564641Marc Blank                                    EmailServiceStatus.REMOTE_EXCEPTION, 0);
1310d4fc55861ed4393aa82f124f2865695ef564641Marc Blank                        }
1320d4fc55861ed4393aa82f124f2865695ef564641Marc Blank                    } catch (RemoteException e1) {
1330d4fc55861ed4393aa82f124f2865695ef564641Marc Blank                    }
1340d4fc55861ed4393aa82f124f2865695ef564641Marc Blank                }
1350d4fc55861ed4393aa82f124f2865695ef564641Marc Blank            }
1360d4fc55861ed4393aa82f124f2865695ef564641Marc Blank        }, "loadAttachment");
1370d4fc55861ed4393aa82f124f2865695ef564641Marc Blank    }
1380d4fc55861ed4393aa82f124f2865695ef564641Marc Blank
139c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank    /**
140c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     * Validate a user account, given a protocol, host address, port, ssl status, and credentials.
141c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     * The result of this call is returned in a Bundle which MUST include a result code and MAY
142c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     * include a PolicySet that is required by the account. A successful validation implies a host
143c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     * address that serves the specified protocol and credentials sufficient to be authorized
144c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     * by the server to do so.
145c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     *
1461d8fd9c05449863ac6a151a6db87c267c4f55ac2Martin Hibdon     * @param hostAuthCom the hostAuthCom object to validate
147c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     * @return a Bundle as described above
148c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     */
149f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank    @Override
1501d8fd9c05449863ac6a151a6db87c267c4f55ac2Martin Hibdon    public Bundle validate(final HostAuthCompat hostAuthCom) throws RemoteException {
1510d4fc55861ed4393aa82f124f2865695ef564641Marc Blank        setTask(new ProxyTask() {
152f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank            @Override
1530d4fc55861ed4393aa82f124f2865695ef564641Marc Blank            public void run() throws RemoteException{
1541d8fd9c05449863ac6a151a6db87c267c4f55ac2Martin Hibdon                mReturn = mService.validate(hostAuthCom);
1550d4fc55861ed4393aa82f124f2865695ef564641Marc Blank            }
1560d4fc55861ed4393aa82f124f2865695ef564641Marc Blank        }, "validate");
1570d4fc55861ed4393aa82f124f2865695ef564641Marc Blank        waitForCompletion();
1580d4fc55861ed4393aa82f124f2865695ef564641Marc Blank        if (mReturn == null) {
1590d4fc55861ed4393aa82f124f2865695ef564641Marc Blank            Bundle bundle = new Bundle();
1600d4fc55861ed4393aa82f124f2865695ef564641Marc Blank            bundle.putInt(VALIDATE_BUNDLE_RESULT_CODE, MessagingException.UNSPECIFIED_EXCEPTION);
1610d4fc55861ed4393aa82f124f2865695ef564641Marc Blank            return bundle;
1620d4fc55861ed4393aa82f124f2865695ef564641Marc Blank        } else {
1630d4fc55861ed4393aa82f124f2865695ef564641Marc Blank            Bundle bundle = (Bundle) mReturn;
164aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank            bundle.setClassLoader(Policy.class.getClassLoader());
165560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy            LogUtils.v(TAG, "validate returns " + bundle.getInt(VALIDATE_BUNDLE_RESULT_CODE));
1660d4fc55861ed4393aa82f124f2865695ef564641Marc Blank            return bundle;
1670d4fc55861ed4393aa82f124f2865695ef564641Marc Blank        }
1680d4fc55861ed4393aa82f124f2865695ef564641Marc Blank    }
1690d4fc55861ed4393aa82f124f2865695ef564641Marc Blank
170c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank    /**
171c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     * Attempt to determine a user's host address and credentials from an email address and
172c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     * password. The result is returned in a Bundle which MUST include an error code and MAY (on
173c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     * success) include a HostAuth record sufficient to enable the service to validate the user's
174c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     * account.
175c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     *
176c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     * @param userName the user's email address
177c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     * @param password the user's password
178c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     * @return a Bundle as described above
179c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     */
180f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank    @Override
1810d4fc55861ed4393aa82f124f2865695ef564641Marc Blank    public Bundle autoDiscover(final String userName, final String password)
1820d4fc55861ed4393aa82f124f2865695ef564641Marc Blank            throws RemoteException {
1830d4fc55861ed4393aa82f124f2865695ef564641Marc Blank        setTask(new ProxyTask() {
184f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank            @Override
1850d4fc55861ed4393aa82f124f2865695ef564641Marc Blank            public void run() throws RemoteException{
1860d4fc55861ed4393aa82f124f2865695ef564641Marc Blank                mReturn = mService.autoDiscover(userName, password);
1870d4fc55861ed4393aa82f124f2865695ef564641Marc Blank            }
1880d4fc55861ed4393aa82f124f2865695ef564641Marc Blank        }, "autoDiscover");
1890d4fc55861ed4393aa82f124f2865695ef564641Marc Blank        waitForCompletion();
1900d4fc55861ed4393aa82f124f2865695ef564641Marc Blank        if (mReturn == null) {
1910d4fc55861ed4393aa82f124f2865695ef564641Marc Blank            return null;
1920d4fc55861ed4393aa82f124f2865695ef564641Marc Blank        } else {
1930d4fc55861ed4393aa82f124f2865695ef564641Marc Blank            Bundle bundle = (Bundle) mReturn;
1940d4fc55861ed4393aa82f124f2865695ef564641Marc Blank            bundle.setClassLoader(HostAuth.class.getClassLoader());
195560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy            LogUtils.v(TAG, "autoDiscover returns "
196560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy                    + bundle.getInt(AUTO_DISCOVER_BUNDLE_ERROR_CODE));
1970d4fc55861ed4393aa82f124f2865695ef564641Marc Blank            return bundle;
1980d4fc55861ed4393aa82f124f2865695ef564641Marc Blank        }
1990d4fc55861ed4393aa82f124f2865695ef564641Marc Blank    }
2000d4fc55861ed4393aa82f124f2865695ef564641Marc Blank
201c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank    /**
202c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     * Request that the service reload the folder list for the specified account. The service
203c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     * MUST use the syncMailboxListStatus callback to indicate "starting" and "finished"
204c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     *
205d5acf0bbc00cbe9a2c075e1bd4825ccbd9851d8dYu Ping Hu     * @param accountId the id of the account whose folder list is to be updated
206c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     */
207f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank    @Override
2080d4fc55861ed4393aa82f124f2865695ef564641Marc Blank    public void updateFolderList(final long accountId) throws RemoteException {
2090d4fc55861ed4393aa82f124f2865695ef564641Marc Blank        setTask(new ProxyTask() {
210f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank            @Override
2110d4fc55861ed4393aa82f124f2865695ef564641Marc Blank            public void run() throws RemoteException {
2120d4fc55861ed4393aa82f124f2865695ef564641Marc Blank                mService.updateFolderList(accountId);
2130d4fc55861ed4393aa82f124f2865695ef564641Marc Blank            }
2140d4fc55861ed4393aa82f124f2865695ef564641Marc Blank        }, "updateFolderList");
2150d4fc55861ed4393aa82f124f2865695ef564641Marc Blank    }
2160d4fc55861ed4393aa82f124f2865695ef564641Marc Blank
217c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank    /**
218c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     * Specify the debug flags selected by the user.  The service SHOULD log debug information as
219c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     * requested.
220c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     *
221c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     * @param flags an integer whose bits represent logging flags as defined in DEBUG_* flags above
222c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     */
223f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank    @Override
224c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank    public void setLogging(final int flags) throws RemoteException {
2250d4fc55861ed4393aa82f124f2865695ef564641Marc Blank        setTask(new ProxyTask() {
226f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank            @Override
2270d4fc55861ed4393aa82f124f2865695ef564641Marc Blank            public void run() throws RemoteException {
228c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank                mService.setLogging(flags);
2290d4fc55861ed4393aa82f124f2865695ef564641Marc Blank            }
2300d4fc55861ed4393aa82f124f2865695ef564641Marc Blank        }, "setLogging");
2310d4fc55861ed4393aa82f124f2865695ef564641Marc Blank    }
2320d4fc55861ed4393aa82f124f2865695ef564641Marc Blank
233c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank    /**
234c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     * Send a meeting response for the specified message
235c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     *
236c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     * @param messageId the id of the message containing the meeting request
237c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     * @param response the response code, as defined in EmailServiceConstants
238c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     */
239f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank    @Override
2400d4fc55861ed4393aa82f124f2865695ef564641Marc Blank    public void sendMeetingResponse(final long messageId, final int response)
2410d4fc55861ed4393aa82f124f2865695ef564641Marc Blank            throws RemoteException {
2420d4fc55861ed4393aa82f124f2865695ef564641Marc Blank        setTask(new ProxyTask() {
243f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank            @Override
2440d4fc55861ed4393aa82f124f2865695ef564641Marc Blank            public void run() throws RemoteException {
2450d4fc55861ed4393aa82f124f2865695ef564641Marc Blank                mService.sendMeetingResponse(messageId, response);
2460d4fc55861ed4393aa82f124f2865695ef564641Marc Blank            }
2470d4fc55861ed4393aa82f124f2865695ef564641Marc Blank        }, "sendMeetingResponse");
2480d4fc55861ed4393aa82f124f2865695ef564641Marc Blank    }
2490d4fc55861ed4393aa82f124f2865695ef564641Marc Blank
250c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank    /**
251c5f5a14ae9095f76d8e8c411cfd8f8e0e8970aa2Martin Hibdon     * Request the service to delete the account's PIM (personal information management) data. This
252c5f5a14ae9095f76d8e8c411cfd8f8e0e8970aa2Martin Hibdon     * data includes any data that is 1) associated with the account and 2) created/stored by the
253c5f5a14ae9095f76d8e8c411cfd8f8e0e8970aa2Martin Hibdon     * service or its sync adapters and 3) not stored in the EmailProvider database (e.g. contact
254c5f5a14ae9095f76d8e8c411cfd8f8e0e8970aa2Martin Hibdon     * and calendar information).
255c5f5a14ae9095f76d8e8c411cfd8f8e0e8970aa2Martin Hibdon     *
256c5f5a14ae9095f76d8e8c411cfd8f8e0e8970aa2Martin Hibdon     * @param emailAddress the email address for the account whose data should be deleted
257c5f5a14ae9095f76d8e8c411cfd8f8e0e8970aa2Martin Hibdon     */
258c5f5a14ae9095f76d8e8c411cfd8f8e0e8970aa2Martin Hibdon    @Override
2597afbeee47e1a82680c815f2fb8cfdba32d6b0b84Martin Hibdon    public void deleteExternalAccountPIMData(final String emailAddress) throws RemoteException {
260c5f5a14ae9095f76d8e8c411cfd8f8e0e8970aa2Martin Hibdon        setTask(new ProxyTask() {
261c5f5a14ae9095f76d8e8c411cfd8f8e0e8970aa2Martin Hibdon            @Override
262c5f5a14ae9095f76d8e8c411cfd8f8e0e8970aa2Martin Hibdon            public void run() throws RemoteException {
2637afbeee47e1a82680c815f2fb8cfdba32d6b0b84Martin Hibdon                mService.deleteExternalAccountPIMData(emailAddress);
264c5f5a14ae9095f76d8e8c411cfd8f8e0e8970aa2Martin Hibdon            }
265c5f5a14ae9095f76d8e8c411cfd8f8e0e8970aa2Martin Hibdon        }, "deleteAccountPIMData");
266c5f5a14ae9095f76d8e8c411cfd8f8e0e8970aa2Martin Hibdon        // This can be called when deleting accounts. After making this call, the caller will
267c5f5a14ae9095f76d8e8c411cfd8f8e0e8970aa2Martin Hibdon        // ask for account reconciliation, which will kill the processes. We wait for completion
268c5f5a14ae9095f76d8e8c411cfd8f8e0e8970aa2Martin Hibdon        // to avoid the race.
269c5f5a14ae9095f76d8e8c411cfd8f8e0e8970aa2Martin Hibdon        waitForCompletion();
270c5f5a14ae9095f76d8e8c411cfd8f8e0e8970aa2Martin Hibdon    }
271c5f5a14ae9095f76d8e8c411cfd8f8e0e8970aa2Martin Hibdon
272c5f5a14ae9095f76d8e8c411cfd8f8e0e8970aa2Martin Hibdon    /**
273c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     * Search for messages given a query string.  The string is interpreted as the logical AND of
274c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     * terms separated by white space.  The search is performed on the specified mailbox in the
275c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     * specified account (including subfolders, as specified by the includeSubfolders parameter).
276c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     * At most numResults messages matching the query term(s) will be added to the mailbox specified
277c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     * as destMailboxId. If mailboxId is -1, the entire account will be searched. If firstResult is
278c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     * specified and non-zero, results will be added starting with the firstResult'th match (i.e.
279c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     * for the continuation of a previous search)
280c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     *
281c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     * @param accountId the id of the account to be searched
28275a754660e33c5e18cacffff193983ba22a7b9b0Marc Blank     * @param searchParams the search specification
283c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     * @param destMailboxId the id of the mailbox into which search results are appended
284c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     * @return the total number of matches for this search (regardless of how many were requested)
285c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank     */
286f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank    @Override
28775a754660e33c5e18cacffff193983ba22a7b9b0Marc Blank    public int searchMessages(final long accountId, final SearchParams searchParams,
28875a754660e33c5e18cacffff193983ba22a7b9b0Marc Blank            final long destMailboxId) throws RemoteException {
289c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank        setTask(new ProxyTask() {
290f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank            @Override
291c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank            public void run() throws RemoteException{
29275a754660e33c5e18cacffff193983ba22a7b9b0Marc Blank                mReturn = mService.searchMessages(accountId, searchParams, destMailboxId);
293c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank            }
294c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank        }, "searchMessages");
295c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank        waitForCompletion();
296c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank        if (mReturn == null) {
297c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank            return 0;
298c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank        } else {
299fb2a3a2f77f954265beaa92b87774006e2d7c185Martin Hibdon            return (Integer) mReturn;
300c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank        }
301c60b8d0529168edecf2376a6f421a0ae1e10fe29Marc Blank    }
302f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank
303f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank    /**
304f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank     * Request the service to send mail in the specified account's Outbox
305f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank     *
306fb2a3a2f77f954265beaa92b87774006e2d7c185Martin Hibdon     * @param accountId the account whose outgoing mail should be sent.
307f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank     */
308f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank    @Override
309f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank    public void sendMail(final long accountId) throws RemoteException {
310f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank        setTask(new ProxyTask() {
311f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank            @Override
312f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank            public void run() throws RemoteException{
313f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank                mService.sendMail(accountId);
314f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank            }
315f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank        }, "sendMail");
316f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank    }
317f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank
318701134953e4591bf2cca020838558a97eab570a1Yu Ping Hu    /**
319701134953e4591bf2cca020838558a97eab570a1Yu Ping Hu     * Request the service to refresh its push notification status (e.g. to start or stop receiving
320701134953e4591bf2cca020838558a97eab570a1Yu Ping Hu     * them, or to change which folders we want notifications for).
321701134953e4591bf2cca020838558a97eab570a1Yu Ping Hu     * @param accountId The account whose push settings to modify.
322701134953e4591bf2cca020838558a97eab570a1Yu Ping Hu     */
323701134953e4591bf2cca020838558a97eab570a1Yu Ping Hu    @Override
324701134953e4591bf2cca020838558a97eab570a1Yu Ping Hu    public void pushModify(final long accountId) throws RemoteException {
325701134953e4591bf2cca020838558a97eab570a1Yu Ping Hu        setTask(new ProxyTask() {
326701134953e4591bf2cca020838558a97eab570a1Yu Ping Hu            @Override
327701134953e4591bf2cca020838558a97eab570a1Yu Ping Hu            public void run() throws RemoteException{
328701134953e4591bf2cca020838558a97eab570a1Yu Ping Hu                mService.pushModify(accountId);
329701134953e4591bf2cca020838558a97eab570a1Yu Ping Hu            }
330fb2a3a2f77f954265beaa92b87774006e2d7c185Martin Hibdon        }, "pushModify");
331701134953e4591bf2cca020838558a97eab570a1Yu Ping Hu    }
332701134953e4591bf2cca020838558a97eab570a1Yu Ping Hu
333163323294e20f620931ae531cc927ae3932cb368Martin Hibdon    @Override
334fb2a3a2f77f954265beaa92b87774006e2d7c185Martin Hibdon    public int sync(final long accountId, final Bundle syncExtras) {
335fb2a3a2f77f954265beaa92b87774006e2d7c185Martin Hibdon        setTask(new ProxyTask() {
336fb2a3a2f77f954265beaa92b87774006e2d7c185Martin Hibdon            @Override
337fb2a3a2f77f954265beaa92b87774006e2d7c185Martin Hibdon            public void run() throws RemoteException{
338fb2a3a2f77f954265beaa92b87774006e2d7c185Martin Hibdon                mReturn = mService.sync(accountId, syncExtras);
339fb2a3a2f77f954265beaa92b87774006e2d7c185Martin Hibdon            }
340fb2a3a2f77f954265beaa92b87774006e2d7c185Martin Hibdon        }, "sync");
341fb2a3a2f77f954265beaa92b87774006e2d7c185Martin Hibdon        waitForCompletion();
342fb2a3a2f77f954265beaa92b87774006e2d7c185Martin Hibdon        if (mReturn == null) {
343fb2a3a2f77f954265beaa92b87774006e2d7c185Martin Hibdon            // This occurs if sync times out.
344fb2a3a2f77f954265beaa92b87774006e2d7c185Martin Hibdon            // TODO: Sync may take a long time, maybe we should extend the timeout here.
345fb2a3a2f77f954265beaa92b87774006e2d7c185Martin Hibdon            return EmailServiceStatus.IO_ERROR;
346fb2a3a2f77f954265beaa92b87774006e2d7c185Martin Hibdon        } else {
347fb2a3a2f77f954265beaa92b87774006e2d7c185Martin Hibdon            return (Integer)mReturn;
348fb2a3a2f77f954265beaa92b87774006e2d7c185Martin Hibdon        }
349fb2a3a2f77f954265beaa92b87774006e2d7c185Martin Hibdon    }
3508103f960d0c0469d67652afd616e9924687aa139Yu Ping Hu
351f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank    @Override
3520d4fc55861ed4393aa82f124f2865695ef564641Marc Blank    public IBinder asBinder() {
3530d4fc55861ed4393aa82f124f2865695ef564641Marc Blank        return null;
3540d4fc55861ed4393aa82f124f2865695ef564641Marc Blank    }
3557afbeee47e1a82680c815f2fb8cfdba32d6b0b84Martin Hibdon
3567afbeee47e1a82680c815f2fb8cfdba32d6b0b84Martin Hibdon    public int getApiVersion() {
3577afbeee47e1a82680c815f2fb8cfdba32d6b0b84Martin Hibdon        setTask(new ProxyTask() {
3587afbeee47e1a82680c815f2fb8cfdba32d6b0b84Martin Hibdon            @Override
3597afbeee47e1a82680c815f2fb8cfdba32d6b0b84Martin Hibdon            public void run() throws RemoteException{
3607afbeee47e1a82680c815f2fb8cfdba32d6b0b84Martin Hibdon                mReturn = mService.getApiVersion();
3617afbeee47e1a82680c815f2fb8cfdba32d6b0b84Martin Hibdon            }
3627afbeee47e1a82680c815f2fb8cfdba32d6b0b84Martin Hibdon        }, "getApiVersion");
3637afbeee47e1a82680c815f2fb8cfdba32d6b0b84Martin Hibdon        waitForCompletion();
3647afbeee47e1a82680c815f2fb8cfdba32d6b0b84Martin Hibdon        if (mReturn == null) {
3657afbeee47e1a82680c815f2fb8cfdba32d6b0b84Martin Hibdon            // This occurs if there is a timeout or remote exception. Is not expected to happen.
3667afbeee47e1a82680c815f2fb8cfdba32d6b0b84Martin Hibdon            LogUtils.wtf(TAG, "failed to get api version");
3677afbeee47e1a82680c815f2fb8cfdba32d6b0b84Martin Hibdon            return -1;
3687afbeee47e1a82680c815f2fb8cfdba32d6b0b84Martin Hibdon        } else {
3697afbeee47e1a82680c815f2fb8cfdba32d6b0b84Martin Hibdon            return (Integer) mReturn;
3707afbeee47e1a82680c815f2fb8cfdba32d6b0b84Martin Hibdon        }
3717afbeee47e1a82680c815f2fb8cfdba32d6b0b84Martin Hibdon    }
3720d4fc55861ed4393aa82f124f2865695ef564641Marc Blank}
373