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