19fe51f632965f5d085ae45a1089c7c97dcec8881Makoto Onuki/* 29fe51f632965f5d085ae45a1089c7c97dcec8881Makoto Onuki * Copyright (C) 2010 The Android Open Source Project 39fe51f632965f5d085ae45a1089c7c97dcec8881Makoto Onuki * 49fe51f632965f5d085ae45a1089c7c97dcec8881Makoto Onuki * Licensed under the Apache License, Version 2.0 (the "License"); 59fe51f632965f5d085ae45a1089c7c97dcec8881Makoto Onuki * you may not use this file except in compliance with the License. 69fe51f632965f5d085ae45a1089c7c97dcec8881Makoto Onuki * You may obtain a copy of the License at 79fe51f632965f5d085ae45a1089c7c97dcec8881Makoto Onuki * 89fe51f632965f5d085ae45a1089c7c97dcec8881Makoto Onuki * http://www.apache.org/licenses/LICENSE-2.0 99fe51f632965f5d085ae45a1089c7c97dcec8881Makoto Onuki * 109fe51f632965f5d085ae45a1089c7c97dcec8881Makoto Onuki * Unless required by applicable law or agreed to in writing, software 119fe51f632965f5d085ae45a1089c7c97dcec8881Makoto Onuki * distributed under the License is distributed on an "AS IS" BASIS, 129fe51f632965f5d085ae45a1089c7c97dcec8881Makoto Onuki * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139fe51f632965f5d085ae45a1089c7c97dcec8881Makoto Onuki * See the License for the specific language governing permissions and 149fe51f632965f5d085ae45a1089c7c97dcec8881Makoto Onuki * limitations under the License. 159fe51f632965f5d085ae45a1089c7c97dcec8881Makoto Onuki */ 169fe51f632965f5d085ae45a1089c7c97dcec8881Makoto Onuki 1766a47b8dac5e97e37c30b928bc5a227d74baada9Marc Blankpackage com.android.email.service; 189fe51f632965f5d085ae45a1089c7c97dcec8881Makoto Onuki 1970edcf05387df33f4761b766add6b80999e425e9Marc Blankimport android.accounts.AccountManager; 2002f0b1eee8f5de651ad5f0289146f88fea99bce0Yu Ping Huimport android.accounts.AccountManagerCallback; 2170edcf05387df33f4761b766add6b80999e425e9Marc Blankimport android.accounts.AccountManagerFuture; 2270edcf05387df33f4761b766add6b80999e425e9Marc Blankimport android.accounts.AuthenticatorException; 2370edcf05387df33f4761b766add6b80999e425e9Marc Blankimport android.accounts.OperationCanceledException; 2403cd72805dab0379ed255d151f1c17cc60655fc3Marc Blankimport android.app.Service; 25e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blankimport android.content.ContentProviderClient; 2670edcf05387df33f4761b766add6b80999e425e9Marc Blankimport android.content.ContentResolver; 2770edcf05387df33f4761b766add6b80999e425e9Marc Blankimport android.content.ContentUris; 2870edcf05387df33f4761b766add6b80999e425e9Marc Blankimport android.content.ContentValues; 299fe51f632965f5d085ae45a1089c7c97dcec8881Makoto Onukiimport android.content.Context; 309fe51f632965f5d085ae45a1089c7c97dcec8881Makoto Onukiimport android.content.Intent; 313a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantlerimport android.content.pm.ActivityInfo; 323a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantlerimport android.content.res.Configuration; 33f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blankimport android.content.res.Resources; 34f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blankimport android.content.res.TypedArray; 35f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blankimport android.content.res.XmlResourceParser; 3670edcf05387df33f4761b766add6b80999e425e9Marc Blankimport android.database.Cursor; 3770edcf05387df33f4761b766add6b80999e425e9Marc Blankimport android.net.Uri; 3803cd72805dab0379ed255d151f1c17cc60655fc3Marc Blankimport android.os.Bundle; 3903cd72805dab0379ed255d151f1c17cc60655fc3Marc Blankimport android.os.IBinder; 4003cd72805dab0379ed255d151f1c17cc60655fc3Marc Blankimport android.os.RemoteException; 4170edcf05387df33f4761b766add6b80999e425e9Marc Blankimport android.provider.CalendarContract; 42e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blankimport android.provider.CalendarContract.Calendars; 43e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blankimport android.provider.CalendarContract.SyncState; 4470edcf05387df33f4761b766add6b80999e425e9Marc Blankimport android.provider.ContactsContract; 453aad3fcb8bb916c989fe67cfbf527eb0df6fc6d1Martin Hibdonimport android.provider.ContactsContract.RawContacts; 46e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blankimport android.provider.SyncStateContract; 47e1a6088ee4e3f0e4344dd9bc38029b6d01431eabMarc Blank 48f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blankimport com.android.email.R; 4903cd72805dab0379ed255d151f1c17cc60655fc3Marc Blankimport com.android.emailcommon.Api; 50f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blankimport com.android.emailcommon.Logging; 51f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blankimport com.android.emailcommon.provider.Account; 5270edcf05387df33f4761b766add6b80999e425e9Marc Blankimport com.android.emailcommon.provider.EmailContent; 5370edcf05387df33f4761b766add6b80999e425e9Marc Blankimport com.android.emailcommon.provider.EmailContent.AccountColumns; 54e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blankimport com.android.emailcommon.provider.HostAuth; 5566a47b8dac5e97e37c30b928bc5a227d74baada9Marc Blankimport com.android.emailcommon.service.EmailServiceProxy; 5666a47b8dac5e97e37c30b928bc5a227d74baada9Marc Blankimport com.android.emailcommon.service.IEmailService; 5766a47b8dac5e97e37c30b928bc5a227d74baada9Marc Blankimport com.android.emailcommon.service.IEmailServiceCallback; 5803cd72805dab0379ed255d151f1c17cc60655fc3Marc Blankimport com.android.emailcommon.service.SearchParams; 5924bb2dabd9dd7d8bd39fed53f312ae6034e373bbMartin Hibdonimport com.android.emailcommon.service.ServiceProxy; 60f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blankimport com.android.emailcommon.service.SyncWindow; 61560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedyimport com.android.mail.utils.LogUtils; 62b5eed31d1bdfcb8e8b316c9c49331295718001bdYu Ping Huimport com.google.common.collect.ImmutableMap; 63462da178b1be608a74000956c53dc8ecb438c689Yu Ping Hu 64f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blankimport org.xmlpull.v1.XmlPullParserException; 65f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank 66f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blankimport java.io.IOException; 67b5eed31d1bdfcb8e8b316c9c49331295718001bdYu Ping Huimport java.util.Collection; 6832881e8dd375f16e6059452166503f7136f14ae5Paul Westbrookimport java.util.Map; 6966a47b8dac5e97e37c30b928bc5a227d74baada9Marc Blank 709fe51f632965f5d085ae45a1089c7c97dcec8881Makoto Onuki/** 7166a47b8dac5e97e37c30b928bc5a227d74baada9Marc Blank * Utility functions for EmailService support. 729fe51f632965f5d085ae45a1089c7c97dcec8881Makoto Onuki */ 7366a47b8dac5e97e37c30b928bc5a227d74baada9Marc Blankpublic class EmailServiceUtils { 749fe51f632965f5d085ae45a1089c7c97dcec8881Makoto Onuki /** 7524bb2dabd9dd7d8bd39fed53f312ae6034e373bbMartin Hibdon * Ask a service to kill its process. This is used when an account is deleted so that 7624bb2dabd9dd7d8bd39fed53f312ae6034e373bbMartin Hibdon * no background thread that happens to be running will continue, possibly hitting an 7724bb2dabd9dd7d8bd39fed53f312ae6034e373bbMartin Hibdon * NPE or other error when trying to operate on an account that no longer exists. 7824bb2dabd9dd7d8bd39fed53f312ae6034e373bbMartin Hibdon * TODO: This is kind of a hack, it's only needed because we fail so badly if an account 7924bb2dabd9dd7d8bd39fed53f312ae6034e373bbMartin Hibdon * is deleted out from under us while a sync or other operation is in progress. It would 8024bb2dabd9dd7d8bd39fed53f312ae6034e373bbMartin Hibdon * be a lot cleaner if our background services could handle this without crashing. 8124bb2dabd9dd7d8bd39fed53f312ae6034e373bbMartin Hibdon */ 8224bb2dabd9dd7d8bd39fed53f312ae6034e373bbMartin Hibdon public static void killService(Context context, String protocol) { 8324bb2dabd9dd7d8bd39fed53f312ae6034e373bbMartin Hibdon EmailServiceInfo info = getServiceInfo(context, protocol); 8424bb2dabd9dd7d8bd39fed53f312ae6034e373bbMartin Hibdon if (info != null && info.intentAction != null) { 8524bb2dabd9dd7d8bd39fed53f312ae6034e373bbMartin Hibdon final Intent serviceIntent = getServiceIntent(info); 8624bb2dabd9dd7d8bd39fed53f312ae6034e373bbMartin Hibdon serviceIntent.putExtra(ServiceProxy.EXTRA_FORCE_SHUTDOWN, true); 8724bb2dabd9dd7d8bd39fed53f312ae6034e373bbMartin Hibdon context.startService(serviceIntent); 8824bb2dabd9dd7d8bd39fed53f312ae6034e373bbMartin Hibdon } 8924bb2dabd9dd7d8bd39fed53f312ae6034e373bbMartin Hibdon } 9024bb2dabd9dd7d8bd39fed53f312ae6034e373bbMartin Hibdon 9124bb2dabd9dd7d8bd39fed53f312ae6034e373bbMartin Hibdon /** 92f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank * Starts an EmailService by protocol 939fe51f632965f5d085ae45a1089c7c97dcec8881Makoto Onuki */ 94f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public static void startService(Context context, String protocol) { 95f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank EmailServiceInfo info = getServiceInfo(context, protocol); 96f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank if (info != null && info.intentAction != null) { 97e4ac06080ba8b8e57531982ea290354b1a9a4305Paul Westbrook final Intent serviceIntent = getServiceIntent(info); 98e4ac06080ba8b8e57531982ea290354b1a9a4305Paul Westbrook context.startService(serviceIntent); 99f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank } 1009fe51f632965f5d085ae45a1089c7c97dcec8881Makoto Onuki } 1019fe51f632965f5d085ae45a1089c7c97dcec8881Makoto Onuki 1029fe51f632965f5d085ae45a1089c7c97dcec8881Makoto Onuki /** 103f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank * Starts all remote services 1049fe51f632965f5d085ae45a1089c7c97dcec8881Makoto Onuki */ 105f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public static void startRemoteServices(Context context) { 106f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank for (EmailServiceInfo info: getServiceInfoList(context)) { 107f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank if (info.intentAction != null) { 108e4ac06080ba8b8e57531982ea290354b1a9a4305Paul Westbrook final Intent serviceIntent = getServiceIntent(info); 109e4ac06080ba8b8e57531982ea290354b1a9a4305Paul Westbrook context.startService(serviceIntent); 110f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank } 111f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank } 112f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank } 113f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank 114f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank /** 115f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank * Returns whether or not remote services are present on device 116f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank */ 117f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public static boolean areRemoteServicesInstalled(Context context) { 118f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank for (EmailServiceInfo info: getServiceInfoList(context)) { 119f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank if (info.intentAction != null) { 120f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank return true; 121f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank } 122f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank } 123f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank return false; 124f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank } 125f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank 126f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank /** 127f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank * Starts all remote services 128f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank */ 129f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public static void setRemoteServicesLogging(Context context, int debugBits) { 130f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank for (EmailServiceInfo info: getServiceInfoList(context)) { 131f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank if (info.intentAction != null) { 132f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank EmailServiceProxy service = 1332075c97f608a853923980865b72147a5c8ef71f0Yu Ping Hu EmailServiceUtils.getService(context, info.protocol); 134f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank if (service != null) { 135f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank try { 136f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank service.setLogging(debugBits); 137f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank } catch (RemoteException e) { 138f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank // Move along, nothing to see 139f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank } 140f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank } 141f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank } 142f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank } 1433a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank } 1443a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank 1453a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank /** 14666a47b8dac5e97e37c30b928bc5a227d74baada9Marc Blank * Determine if the EmailService is available 1473a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank */ 148f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public static boolean isServiceAvailable(Context context, String protocol) { 149f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank EmailServiceInfo info = getServiceInfo(context, protocol); 150f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank if (info == null) return false; 151f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank if (info.klass != null) return true; 152e4ac06080ba8b8e57531982ea290354b1a9a4305Paul Westbrook final Intent serviceIntent = getServiceIntent(info); 153e4ac06080ba8b8e57531982ea290354b1a9a4305Paul Westbrook return new EmailServiceProxy(context, serviceIntent).test(); 154e4ac06080ba8b8e57531982ea290354b1a9a4305Paul Westbrook } 155e4ac06080ba8b8e57531982ea290354b1a9a4305Paul Westbrook 156e4ac06080ba8b8e57531982ea290354b1a9a4305Paul Westbrook private static Intent getServiceIntent(EmailServiceInfo info) { 157e4ac06080ba8b8e57531982ea290354b1a9a4305Paul Westbrook final Intent serviceIntent = new Intent(info.intentAction); 158e4ac06080ba8b8e57531982ea290354b1a9a4305Paul Westbrook serviceIntent.setPackage(info.intentPackage); 159e4ac06080ba8b8e57531982ea290354b1a9a4305Paul Westbrook return serviceIntent; 160f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank } 161f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank 162f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank /** 163f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank * For a given account id, return a service proxy if applicable, or null. 164f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank * 165f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank * @param accountId the message of interest 1663a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler * @return service proxy, or null if n/a 167f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank */ 1682075c97f608a853923980865b72147a5c8ef71f0Yu Ping Hu public static EmailServiceProxy getServiceForAccount(Context context, long accountId) { 1692075c97f608a853923980865b72147a5c8ef71f0Yu Ping Hu return getService(context, Account.getProtocol(context, accountId)); 170f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank } 171f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank 172f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank /** 173f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank * Holder of service information (currently just name and class/intent); if there is a class 174f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank * member, this is a (local, i.e. same process) service; otherwise, this is a remote service 175f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank */ 176f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public static class EmailServiceInfo { 177f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public String protocol; 178f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public String name; 179f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public String accountType; 180f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank Class<? extends Service> klass; 181f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank String intentAction; 182e4ac06080ba8b8e57531982ea290354b1a9a4305Paul Westbrook String intentPackage; 183f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public int port; 184f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public int portSsl; 185f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public boolean defaultSsl; 186f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public boolean offerTls; 187f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public boolean offerCerts; 188f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public boolean usesSmtp; 189f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public boolean offerLocalDeletes; 190f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public int defaultLocalDeletes; 191f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public boolean offerPrefix; 192f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public boolean usesAutodiscover; 193f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public boolean offerLookback; 194f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public int defaultLookback; 195f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public boolean syncChanges; 196f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public boolean syncContacts; 197f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public boolean syncCalendar; 198f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public boolean offerAttachmentPreload; 199f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public CharSequence[] syncIntervalStrings; 200f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public CharSequence[] syncIntervals; 201f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public int defaultSyncInterval; 202b89744ecfb92a4b8fc66a23b942531d39910de44Marc Blank public String inferPrefix; 203b82ae909d7514bf06090ee3a120aef2154ab0296Marc Blank public boolean offerLoadMore; 204ae46818a1925cc22fe20ee26ffee8779561a903bAlon Albert public boolean offerMoveTo; 20581b0f74efa39d80b0aa18686c96499faf0e2691fMarc Blank public boolean requiresSetup; 2065c523858385176c33a7456bb84035de78552d22dMarc Blank public boolean hide; 207f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank 2085c523858385176c33a7456bb84035de78552d22dMarc Blank @Override 209f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public String toString() { 210f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank StringBuilder sb = new StringBuilder("Protocol: "); 211f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank sb.append(protocol); 212f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank sb.append(", "); 213f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank sb.append(klass != null ? "Local" : "Remote"); 214af092bd5f850653b0d237fb55ccc896f74dc7982Marc Blank sb.append(" , Account Type: "); 215af092bd5f850653b0d237fb55ccc896f74dc7982Marc Blank sb.append(accountType); 216f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank return sb.toString(); 217f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank } 21891237e9dcb0a948f17488b464edabcea0f259d31Makoto Onuki } 21991237e9dcb0a948f17488b464edabcea0f259d31Makoto Onuki 2202075c97f608a853923980865b72147a5c8ef71f0Yu Ping Hu public static EmailServiceProxy getService(Context context, String protocol) { 221cf3b3ae987e73453f2265673a7ba3a72a1a6b4edMarc Blank EmailServiceInfo info = null; 222f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank // Handle the degenerate case here (account might have been deleted) 223cf3b3ae987e73453f2265673a7ba3a72a1a6b4edMarc Blank if (protocol != null) { 224cf3b3ae987e73453f2265673a7ba3a72a1a6b4edMarc Blank info = getServiceInfo(context, protocol); 225cf3b3ae987e73453f2265673a7ba3a72a1a6b4edMarc Blank } 226cf3b3ae987e73453f2265673a7ba3a72a1a6b4edMarc Blank if (info == null) { 227560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy LogUtils.w(Logging.LOG_TAG, "Returning NullService for " + protocol); 2282075c97f608a853923980865b72147a5c8ef71f0Yu Ping Hu return new EmailServiceProxy(context, NullService.class); 229e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank } else { 2302075c97f608a853923980865b72147a5c8ef71f0Yu Ping Hu return getServiceFromInfo(context, info); 231e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank } 232e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank } 233e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank 2342075c97f608a853923980865b72147a5c8ef71f0Yu Ping Hu public static EmailServiceProxy getServiceFromInfo(Context context, EmailServiceInfo info) { 235e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank if (info.klass != null) { 2362075c97f608a853923980865b72147a5c8ef71f0Yu Ping Hu return new EmailServiceProxy(context, info.klass); 237f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank } else { 238e4ac06080ba8b8e57531982ea290354b1a9a4305Paul Westbrook final Intent serviceIntent = getServiceIntent(info); 239e4ac06080ba8b8e57531982ea290354b1a9a4305Paul Westbrook return new EmailServiceProxy(context, serviceIntent); 240f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank } 24166a47b8dac5e97e37c30b928bc5a227d74baada9Marc Blank } 24266a47b8dac5e97e37c30b928bc5a227d74baada9Marc Blank 24381b0f74efa39d80b0aa18686c96499faf0e2691fMarc Blank public static EmailServiceInfo getServiceInfoForAccount(Context context, long accountId) { 24481b0f74efa39d80b0aa18686c96499faf0e2691fMarc Blank String protocol = Account.getProtocol(context, accountId); 24581b0f74efa39d80b0aa18686c96499faf0e2691fMarc Blank return getServiceInfo(context, protocol); 24681b0f74efa39d80b0aa18686c96499faf0e2691fMarc Blank } 24781b0f74efa39d80b0aa18686c96499faf0e2691fMarc Blank 2483a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler public static EmailServiceInfo getServiceInfo(Context context, String protocol) { 2493a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler return getServiceMap(context).get(protocol); 25066a47b8dac5e97e37c30b928bc5a227d74baada9Marc Blank } 25166a47b8dac5e97e37c30b928bc5a227d74baada9Marc Blank 2523a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler public static Collection<EmailServiceInfo> getServiceInfoList(Context context) { 2533a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler return getServiceMap(context).values(); 254c18f8f615f134a2b391d06e2d8d49434a8bb94e5Makoto Onuki } 255c18f8f615f134a2b391d06e2d8d49434a8bb94e5Makoto Onuki 25670edcf05387df33f4761b766add6b80999e425e9Marc Blank private static void finishAccountManagerBlocker(AccountManagerFuture<?> future) { 25770edcf05387df33f4761b766add6b80999e425e9Marc Blank try { 25870edcf05387df33f4761b766add6b80999e425e9Marc Blank // Note: All of the potential errors are simply logged 25970edcf05387df33f4761b766add6b80999e425e9Marc Blank // here, as there is nothing to actually do about them. 26070edcf05387df33f4761b766add6b80999e425e9Marc Blank future.getResult(); 26170edcf05387df33f4761b766add6b80999e425e9Marc Blank } catch (OperationCanceledException e) { 262560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy LogUtils.w(Logging.LOG_TAG, e.toString()); 26370edcf05387df33f4761b766add6b80999e425e9Marc Blank } catch (AuthenticatorException e) { 264560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy LogUtils.w(Logging.LOG_TAG, e.toString()); 26570edcf05387df33f4761b766add6b80999e425e9Marc Blank } catch (IOException e) { 266560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy LogUtils.w(Logging.LOG_TAG, e.toString()); 26770edcf05387df33f4761b766add6b80999e425e9Marc Blank } 26870edcf05387df33f4761b766add6b80999e425e9Marc Blank } 26970edcf05387df33f4761b766add6b80999e425e9Marc Blank 27002f0b1eee8f5de651ad5f0289146f88fea99bce0Yu Ping Hu /** 27102f0b1eee8f5de651ad5f0289146f88fea99bce0Yu Ping Hu * Add an account to the AccountManager. 27202f0b1eee8f5de651ad5f0289146f88fea99bce0Yu Ping Hu * @param context Our {@link Context}. 27302f0b1eee8f5de651ad5f0289146f88fea99bce0Yu Ping Hu * @param account The {@link Account} we're adding. 27402f0b1eee8f5de651ad5f0289146f88fea99bce0Yu Ping Hu * @param email Whether the user wants to sync email on this account. 27502f0b1eee8f5de651ad5f0289146f88fea99bce0Yu Ping Hu * @param calendar Whether the user wants to sync calendar on this account. 27602f0b1eee8f5de651ad5f0289146f88fea99bce0Yu Ping Hu * @param contacts Whether the user wants to sync contacts on this account. 27702f0b1eee8f5de651ad5f0289146f88fea99bce0Yu Ping Hu * @param callback A callback for when the AccountManager is done. 27802f0b1eee8f5de651ad5f0289146f88fea99bce0Yu Ping Hu * @return The result of {@link AccountManager#addAccount}. 27902f0b1eee8f5de651ad5f0289146f88fea99bce0Yu Ping Hu */ 28002f0b1eee8f5de651ad5f0289146f88fea99bce0Yu Ping Hu public static AccountManagerFuture<Bundle> setupAccountManagerAccount(final Context context, 28102f0b1eee8f5de651ad5f0289146f88fea99bce0Yu Ping Hu final Account account, final boolean email, final boolean calendar, 28202f0b1eee8f5de651ad5f0289146f88fea99bce0Yu Ping Hu final boolean contacts, final AccountManagerCallback<Bundle> callback) { 28302f0b1eee8f5de651ad5f0289146f88fea99bce0Yu Ping Hu final Bundle options = new Bundle(5); 28402f0b1eee8f5de651ad5f0289146f88fea99bce0Yu Ping Hu final HostAuth hostAuthRecv = 28502f0b1eee8f5de651ad5f0289146f88fea99bce0Yu Ping Hu HostAuth.restoreHostAuthWithId(context, account.mHostAuthKeyRecv); 28602f0b1eee8f5de651ad5f0289146f88fea99bce0Yu Ping Hu if (hostAuthRecv == null) { 28702f0b1eee8f5de651ad5f0289146f88fea99bce0Yu Ping Hu return null; 28802f0b1eee8f5de651ad5f0289146f88fea99bce0Yu Ping Hu } 28902f0b1eee8f5de651ad5f0289146f88fea99bce0Yu Ping Hu // Set up username/password 29002f0b1eee8f5de651ad5f0289146f88fea99bce0Yu Ping Hu options.putString(EasAuthenticatorService.OPTIONS_USERNAME, account.mEmailAddress); 29102f0b1eee8f5de651ad5f0289146f88fea99bce0Yu Ping Hu options.putString(EasAuthenticatorService.OPTIONS_PASSWORD, hostAuthRecv.mPassword); 29202f0b1eee8f5de651ad5f0289146f88fea99bce0Yu Ping Hu options.putBoolean(EasAuthenticatorService.OPTIONS_CONTACTS_SYNC_ENABLED, contacts); 29302f0b1eee8f5de651ad5f0289146f88fea99bce0Yu Ping Hu options.putBoolean(EasAuthenticatorService.OPTIONS_CALENDAR_SYNC_ENABLED, calendar); 29402f0b1eee8f5de651ad5f0289146f88fea99bce0Yu Ping Hu options.putBoolean(EasAuthenticatorService.OPTIONS_EMAIL_SYNC_ENABLED, email); 29502f0b1eee8f5de651ad5f0289146f88fea99bce0Yu Ping Hu final EmailServiceInfo info = getServiceInfo(context, hostAuthRecv.mProtocol); 29602f0b1eee8f5de651ad5f0289146f88fea99bce0Yu Ping Hu return AccountManager.get(context).addAccount(info.accountType, null, null, options, null, 29702f0b1eee8f5de651ad5f0289146f88fea99bce0Yu Ping Hu callback, null); 29802f0b1eee8f5de651ad5f0289146f88fea99bce0Yu Ping Hu } 29902f0b1eee8f5de651ad5f0289146f88fea99bce0Yu Ping Hu 300462da178b1be608a74000956c53dc8ecb438c689Yu Ping Hu public static void updateAccountManagerType(Context context, 30148b14fde961ef57103f7a31196254e357987f203Yu Ping Hu android.accounts.Account amAccount, final Map<String, String> protocolMap) { 30232881e8dd375f16e6059452166503f7136f14ae5Paul Westbrook final ContentResolver resolver = context.getContentResolver(); 30332881e8dd375f16e6059452166503f7136f14ae5Paul Westbrook final Cursor c = resolver.query(Account.CONTENT_URI, Account.CONTENT_PROJECTION, 30470edcf05387df33f4761b766add6b80999e425e9Marc Blank AccountColumns.EMAIL_ADDRESS + "=?", new String[] { amAccount.name }, null); 30570edcf05387df33f4761b766add6b80999e425e9Marc Blank // That's odd, isn't it? 30670edcf05387df33f4761b766add6b80999e425e9Marc Blank if (c == null) return; 30770edcf05387df33f4761b766add6b80999e425e9Marc Blank try { 30870edcf05387df33f4761b766add6b80999e425e9Marc Blank if (c.moveToNext()) { 30970edcf05387df33f4761b766add6b80999e425e9Marc Blank // Get the EmailProvider Account/HostAuth 31032881e8dd375f16e6059452166503f7136f14ae5Paul Westbrook final Account account = new Account(); 31170edcf05387df33f4761b766add6b80999e425e9Marc Blank account.restore(c); 31232881e8dd375f16e6059452166503f7136f14ae5Paul Westbrook final HostAuth hostAuth = 31370edcf05387df33f4761b766add6b80999e425e9Marc Blank HostAuth.restoreHostAuthWithId(context, account.mHostAuthKeyRecv); 31432881e8dd375f16e6059452166503f7136f14ae5Paul Westbrook if (hostAuth == null) { 31532881e8dd375f16e6059452166503f7136f14ae5Paul Westbrook return; 31632881e8dd375f16e6059452166503f7136f14ae5Paul Westbrook } 31770edcf05387df33f4761b766add6b80999e425e9Marc Blank 318462da178b1be608a74000956c53dc8ecb438c689Yu Ping Hu final String newProtocol = protocolMap.get(hostAuth.mProtocol); 319462da178b1be608a74000956c53dc8ecb438c689Yu Ping Hu if (newProtocol == null) { 320462da178b1be608a74000956c53dc8ecb438c689Yu Ping Hu // This account doesn't need updating. 321e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank return; 322e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank } 323462da178b1be608a74000956c53dc8ecb438c689Yu Ping Hu 324560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy LogUtils.w(Logging.LOG_TAG, "Converting " + amAccount.name + " to " 325462da178b1be608a74000956c53dc8ecb438c689Yu Ping Hu + newProtocol); 326e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank 32732881e8dd375f16e6059452166503f7136f14ae5Paul Westbrook final ContentValues accountValues = new ContentValues(); 32870edcf05387df33f4761b766add6b80999e425e9Marc Blank int oldFlags = account.mFlags; 32970edcf05387df33f4761b766add6b80999e425e9Marc Blank 33070edcf05387df33f4761b766add6b80999e425e9Marc Blank // Mark the provider account incomplete so it can't get reconciled away 33170edcf05387df33f4761b766add6b80999e425e9Marc Blank account.mFlags |= Account.FLAGS_INCOMPLETE; 33270edcf05387df33f4761b766add6b80999e425e9Marc Blank accountValues.put(AccountColumns.FLAGS, account.mFlags); 33332881e8dd375f16e6059452166503f7136f14ae5Paul Westbrook final Uri accountUri = ContentUris.withAppendedId(Account.CONTENT_URI, account.mId); 33470edcf05387df33f4761b766add6b80999e425e9Marc Blank resolver.update(accountUri, accountValues, null, null); 33570edcf05387df33f4761b766add6b80999e425e9Marc Blank 33670edcf05387df33f4761b766add6b80999e425e9Marc Blank // Change the HostAuth to reference the new protocol; this has to be done before 33770edcf05387df33f4761b766add6b80999e425e9Marc Blank // trying to create the AccountManager account (below) 33832881e8dd375f16e6059452166503f7136f14ae5Paul Westbrook final ContentValues hostValues = new ContentValues(); 339462da178b1be608a74000956c53dc8ecb438c689Yu Ping Hu hostValues.put(HostAuth.PROTOCOL, newProtocol); 34070edcf05387df33f4761b766add6b80999e425e9Marc Blank resolver.update(ContentUris.withAppendedId(HostAuth.CONTENT_URI, hostAuth.mId), 34170edcf05387df33f4761b766add6b80999e425e9Marc Blank hostValues, null, null); 342560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy LogUtils.w(Logging.LOG_TAG, "Updated HostAuths"); 34370edcf05387df33f4761b766add6b80999e425e9Marc Blank 34470edcf05387df33f4761b766add6b80999e425e9Marc Blank try { 34570edcf05387df33f4761b766add6b80999e425e9Marc Blank // Get current settings for the existing AccountManager account 34670edcf05387df33f4761b766add6b80999e425e9Marc Blank boolean email = ContentResolver.getSyncAutomatically(amAccount, 34770edcf05387df33f4761b766add6b80999e425e9Marc Blank EmailContent.AUTHORITY); 348e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank if (!email) { 349e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank // Try our old provider name 350e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank email = ContentResolver.getSyncAutomatically(amAccount, 351e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank "com.android.email.provider"); 352e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank } 35332881e8dd375f16e6059452166503f7136f14ae5Paul Westbrook final boolean contacts = ContentResolver.getSyncAutomatically(amAccount, 35470edcf05387df33f4761b766add6b80999e425e9Marc Blank ContactsContract.AUTHORITY); 35532881e8dd375f16e6059452166503f7136f14ae5Paul Westbrook final boolean calendar = ContentResolver.getSyncAutomatically(amAccount, 35670edcf05387df33f4761b766add6b80999e425e9Marc Blank CalendarContract.AUTHORITY); 357560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy LogUtils.w(Logging.LOG_TAG, "Email: " + email + ", Contacts: " + contacts + "," 358560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy + " Calendar: " + calendar); 359e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank 360e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank // Get sync keys for calendar/contacts 36132881e8dd375f16e6059452166503f7136f14ae5Paul Westbrook final String amName = amAccount.name; 36232881e8dd375f16e6059452166503f7136f14ae5Paul Westbrook final String oldType = amAccount.type; 363e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank ContentProviderClient client = context.getContentResolver() 364e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank .acquireContentProviderClient(CalendarContract.CONTENT_URI); 365e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank byte[] calendarSyncKey = null; 366e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank try { 367e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank calendarSyncKey = SyncStateContract.Helpers.get(client, 368e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank asCalendarSyncAdapter(SyncState.CONTENT_URI, amName, oldType), 369e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank new android.accounts.Account(amName, oldType)); 370e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank } catch (RemoteException e) { 371560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy LogUtils.w(Logging.LOG_TAG, "Get calendar key FAILED"); 372e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank } finally { 373e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank client.release(); 374e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank } 375e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank client = context.getContentResolver() 376e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank .acquireContentProviderClient(ContactsContract.AUTHORITY_URI); 377e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank byte[] contactsSyncKey = null; 378e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank try { 379e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank contactsSyncKey = SyncStateContract.Helpers.get(client, 380e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank ContactsContract.SyncState.CONTENT_URI, 381e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank new android.accounts.Account(amName, oldType)); 382e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank } catch (RemoteException e) { 383560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy LogUtils.w(Logging.LOG_TAG, "Get contacts key FAILED"); 384e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank } finally { 385e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank client.release(); 386e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank } 387e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank if (calendarSyncKey != null) { 388560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy LogUtils.w(Logging.LOG_TAG, "Got calendar key: " 389560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy + new String(calendarSyncKey)); 390e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank } 391e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank if (contactsSyncKey != null) { 392560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy LogUtils.w(Logging.LOG_TAG, "Got contacts key: " 393560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy + new String(contactsSyncKey)); 394e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank } 395e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank 396e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank // Set up a new AccountManager account with new type and old settings 39702f0b1eee8f5de651ad5f0289146f88fea99bce0Yu Ping Hu AccountManagerFuture<?> amFuture = setupAccountManagerAccount(context, account, 39802f0b1eee8f5de651ad5f0289146f88fea99bce0Yu Ping Hu email, calendar, contacts, null); 399e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank finishAccountManagerBlocker(amFuture); 400560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy LogUtils.w(Logging.LOG_TAG, "Created new AccountManager account"); 40170edcf05387df33f4761b766add6b80999e425e9Marc Blank 4023aad3fcb8bb916c989fe67cfbf527eb0df6fc6d1Martin Hibdon // TODO: Clean up how we determine the type. 4033aad3fcb8bb916c989fe67cfbf527eb0df6fc6d1Martin Hibdon final String accountType = protocolMap.get(hostAuth.mProtocol + "_type"); 4043aad3fcb8bb916c989fe67cfbf527eb0df6fc6d1Martin Hibdon // Move calendar and contacts data from the old account to the new one. 4053aad3fcb8bb916c989fe67cfbf527eb0df6fc6d1Martin Hibdon // We must do this before deleting the old account or the data is lost. 4063aad3fcb8bb916c989fe67cfbf527eb0df6fc6d1Martin Hibdon moveCalendarData(context.getContentResolver(), amName, oldType, accountType); 4073aad3fcb8bb916c989fe67cfbf527eb0df6fc6d1Martin Hibdon moveContactsData(context.getContentResolver(), amName, oldType, accountType); 4087d6d8c87f86a17cae59af645637458b17e72c716Martin Hibdon 40970edcf05387df33f4761b766add6b80999e425e9Marc Blank // Delete the AccountManager account 410e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank amFuture = AccountManager.get(context) 41170edcf05387df33f4761b766add6b80999e425e9Marc Blank .removeAccount(amAccount, null, null); 41270edcf05387df33f4761b766add6b80999e425e9Marc Blank finishAccountManagerBlocker(amFuture); 413560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy LogUtils.w(Logging.LOG_TAG, "Deleted old AccountManager account"); 41470edcf05387df33f4761b766add6b80999e425e9Marc Blank 415e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank // Restore sync keys for contacts/calendar 4163aad3fcb8bb916c989fe67cfbf527eb0df6fc6d1Martin Hibdon 417462da178b1be608a74000956c53dc8ecb438c689Yu Ping Hu if (accountType != null && 418462da178b1be608a74000956c53dc8ecb438c689Yu Ping Hu calendarSyncKey != null && calendarSyncKey.length != 0) { 419e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank client = context.getContentResolver() 420e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank .acquireContentProviderClient(CalendarContract.CONTENT_URI); 421e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank try { 422e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank SyncStateContract.Helpers.set(client, 423e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank asCalendarSyncAdapter(SyncState.CONTENT_URI, amName, 424462da178b1be608a74000956c53dc8ecb438c689Yu Ping Hu accountType), 425462da178b1be608a74000956c53dc8ecb438c689Yu Ping Hu new android.accounts.Account(amName, accountType), 426e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank calendarSyncKey); 427560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy LogUtils.w(Logging.LOG_TAG, "Set calendar key..."); 428e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank } catch (RemoteException e) { 429560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy LogUtils.w(Logging.LOG_TAG, "Set calendar key FAILED"); 430e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank } finally { 431e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank client.release(); 432e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank } 433e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank } 434462da178b1be608a74000956c53dc8ecb438c689Yu Ping Hu if (accountType != null && 435462da178b1be608a74000956c53dc8ecb438c689Yu Ping Hu contactsSyncKey != null && contactsSyncKey.length != 0) { 436e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank client = context.getContentResolver() 437e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank .acquireContentProviderClient(ContactsContract.AUTHORITY_URI); 438e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank try { 439e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank SyncStateContract.Helpers.set(client, 440e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank ContactsContract.SyncState.CONTENT_URI, 441462da178b1be608a74000956c53dc8ecb438c689Yu Ping Hu new android.accounts.Account(amName, accountType), 442e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank contactsSyncKey); 443560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy LogUtils.w(Logging.LOG_TAG, "Set contacts key..."); 444e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank } catch (RemoteException e) { 445560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy LogUtils.w(Logging.LOG_TAG, "Set contacts key FAILED"); 446e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank } 447e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank } 448e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank 449e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank // That's all folks! 450560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy LogUtils.w(Logging.LOG_TAG, "Account update completed."); 45170edcf05387df33f4761b766add6b80999e425e9Marc Blank } finally { 45270edcf05387df33f4761b766add6b80999e425e9Marc Blank // Clear the incomplete flag on the provider account 45370edcf05387df33f4761b766add6b80999e425e9Marc Blank accountValues.put(AccountColumns.FLAGS, oldFlags); 45470edcf05387df33f4761b766add6b80999e425e9Marc Blank resolver.update(accountUri, accountValues, null, null); 455560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy LogUtils.w(Logging.LOG_TAG, "[Incomplete flag cleared]"); 45670edcf05387df33f4761b766add6b80999e425e9Marc Blank } 45770edcf05387df33f4761b766add6b80999e425e9Marc Blank } 45870edcf05387df33f4761b766add6b80999e425e9Marc Blank } finally { 45970edcf05387df33f4761b766add6b80999e425e9Marc Blank c.close(); 46070edcf05387df33f4761b766add6b80999e425e9Marc Blank } 46170edcf05387df33f4761b766add6b80999e425e9Marc Blank } 46270edcf05387df33f4761b766add6b80999e425e9Marc Blank 4633aad3fcb8bb916c989fe67cfbf527eb0df6fc6d1Martin Hibdon private static void moveCalendarData(final ContentResolver resolver, final String name, 4643aad3fcb8bb916c989fe67cfbf527eb0df6fc6d1Martin Hibdon final String oldType, final String newType) { 4653aad3fcb8bb916c989fe67cfbf527eb0df6fc6d1Martin Hibdon final Uri oldCalendars = Calendars.CONTENT_URI.buildUpon() 4663aad3fcb8bb916c989fe67cfbf527eb0df6fc6d1Martin Hibdon .appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true") 4673aad3fcb8bb916c989fe67cfbf527eb0df6fc6d1Martin Hibdon .appendQueryParameter(Calendars.ACCOUNT_NAME, name) 4683aad3fcb8bb916c989fe67cfbf527eb0df6fc6d1Martin Hibdon .appendQueryParameter(Calendars.ACCOUNT_TYPE, oldType) 4693aad3fcb8bb916c989fe67cfbf527eb0df6fc6d1Martin Hibdon .build(); 4703aad3fcb8bb916c989fe67cfbf527eb0df6fc6d1Martin Hibdon 4713aad3fcb8bb916c989fe67cfbf527eb0df6fc6d1Martin Hibdon // Update this calendar to have the new account type. 4723aad3fcb8bb916c989fe67cfbf527eb0df6fc6d1Martin Hibdon final ContentValues values = new ContentValues(); 4733aad3fcb8bb916c989fe67cfbf527eb0df6fc6d1Martin Hibdon values.put(CalendarContract.Calendars.ACCOUNT_TYPE, newType); 4743aad3fcb8bb916c989fe67cfbf527eb0df6fc6d1Martin Hibdon resolver.update(oldCalendars, values, 4753aad3fcb8bb916c989fe67cfbf527eb0df6fc6d1Martin Hibdon Calendars.ACCOUNT_NAME + "=? AND " + Calendars.ACCOUNT_TYPE + "=?", 4763aad3fcb8bb916c989fe67cfbf527eb0df6fc6d1Martin Hibdon new String[] {name, oldType}); 4773aad3fcb8bb916c989fe67cfbf527eb0df6fc6d1Martin Hibdon } 4783aad3fcb8bb916c989fe67cfbf527eb0df6fc6d1Martin Hibdon 4793aad3fcb8bb916c989fe67cfbf527eb0df6fc6d1Martin Hibdon private static void moveContactsData(final ContentResolver resolver, final String name, 4803aad3fcb8bb916c989fe67cfbf527eb0df6fc6d1Martin Hibdon final String oldType, final String newType) { 4813aad3fcb8bb916c989fe67cfbf527eb0df6fc6d1Martin Hibdon final Uri oldContacts = RawContacts.CONTENT_URI.buildUpon() 4823aad3fcb8bb916c989fe67cfbf527eb0df6fc6d1Martin Hibdon .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true") 4833aad3fcb8bb916c989fe67cfbf527eb0df6fc6d1Martin Hibdon .appendQueryParameter(RawContacts.ACCOUNT_NAME, name) 4843aad3fcb8bb916c989fe67cfbf527eb0df6fc6d1Martin Hibdon .appendQueryParameter(RawContacts.ACCOUNT_TYPE, oldType) 4853aad3fcb8bb916c989fe67cfbf527eb0df6fc6d1Martin Hibdon .build(); 4863aad3fcb8bb916c989fe67cfbf527eb0df6fc6d1Martin Hibdon 4873aad3fcb8bb916c989fe67cfbf527eb0df6fc6d1Martin Hibdon // Update this calendar to have the new account type. 4883aad3fcb8bb916c989fe67cfbf527eb0df6fc6d1Martin Hibdon final ContentValues values = new ContentValues(); 4893aad3fcb8bb916c989fe67cfbf527eb0df6fc6d1Martin Hibdon values.put(CalendarContract.Calendars.ACCOUNT_TYPE, newType); 4903aad3fcb8bb916c989fe67cfbf527eb0df6fc6d1Martin Hibdon resolver.update(oldContacts, values, null, null); 4913aad3fcb8bb916c989fe67cfbf527eb0df6fc6d1Martin Hibdon } 4923aad3fcb8bb916c989fe67cfbf527eb0df6fc6d1Martin Hibdon 4933a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler private static final Configuration sOldConfiguration = new Configuration(); 4943a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler private static Map<String, EmailServiceInfo> sServiceMap = null; 4953a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler private static final Object sServiceMapLock = new Object(); 4963a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler 497c18f8f615f134a2b391d06e2d8d49434a8bb94e5Makoto Onuki /** 498f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank * Parse services.xml file to find our available email services 49991237e9dcb0a948f17488b464edabcea0f259d31Makoto Onuki */ 5003a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler private static Map<String, EmailServiceInfo> getServiceMap(final Context context) { 5013a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler synchronized (sServiceMapLock) { 5023a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler /** 5033a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler * We cache localized strings here, so make sure to regenerate the service map if 5043a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler * the locale changes 5053a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler */ 5063a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler if (sServiceMap == null) { 5073a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler sOldConfiguration.setTo(context.getResources().getConfiguration()); 5083a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler } 509b5eed31d1bdfcb8e8b316c9c49331295718001bdYu Ping Hu 5103a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler final int delta = 5113a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler sOldConfiguration.updateFrom(context.getResources().getConfiguration()); 512b5eed31d1bdfcb8e8b316c9c49331295718001bdYu Ping Hu 5133a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler if (sServiceMap != null 5143a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler && !Configuration.needNewResources(delta, ActivityInfo.CONFIG_LOCALE)) { 5153a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler return sServiceMap; 5163a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler } 5173a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler 5183a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler final ImmutableMap.Builder<String, EmailServiceInfo> builder = ImmutableMap.builder(); 5193a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler 5203a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler try { 5213a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler final Resources res = context.getResources(); 5223a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler final XmlResourceParser xml = res.getXml(R.xml.services); 5233a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler int xmlEventType; 5243a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler // walk through senders.xml file. 5253a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler while ((xmlEventType = xml.next()) != XmlResourceParser.END_DOCUMENT) { 5263a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler if (xmlEventType == XmlResourceParser.START_TAG && 5273a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler "emailservice".equals(xml.getName())) { 5283a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler final EmailServiceInfo info = new EmailServiceInfo(); 5293a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler final TypedArray ta = 5303a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler res.obtainAttributes(xml, R.styleable.EmailServiceInfo); 5313a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler info.protocol = ta.getString(R.styleable.EmailServiceInfo_protocol); 5323a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler info.accountType = ta.getString(R.styleable.EmailServiceInfo_accountType); 5333a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler info.name = ta.getString(R.styleable.EmailServiceInfo_name); 5343a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler info.hide = ta.getBoolean(R.styleable.EmailServiceInfo_hide, false); 5353a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler final String klass = 5363a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler ta.getString(R.styleable.EmailServiceInfo_serviceClass); 5373a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler info.intentAction = ta.getString(R.styleable.EmailServiceInfo_intent); 5383a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler info.intentPackage = 5393a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler ta.getString(R.styleable.EmailServiceInfo_intentPackage); 5403a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler info.defaultSsl = 5413a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler ta.getBoolean(R.styleable.EmailServiceInfo_defaultSsl, false); 5423a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler info.port = ta.getInteger(R.styleable.EmailServiceInfo_port, 0); 5433a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler info.portSsl = ta.getInteger(R.styleable.EmailServiceInfo_portSsl, 0); 5443a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler info.offerTls = ta.getBoolean(R.styleable.EmailServiceInfo_offerTls, false); 5453a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler info.offerCerts = 5463a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler ta.getBoolean(R.styleable.EmailServiceInfo_offerCerts, false); 5473a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler info.offerLocalDeletes = 5483a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler ta.getBoolean(R.styleable.EmailServiceInfo_offerLocalDeletes, false); 5493a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler info.defaultLocalDeletes = 5503a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler ta.getInteger(R.styleable.EmailServiceInfo_defaultLocalDeletes, 5513a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler Account.DELETE_POLICY_ON_DELETE); 5523a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler info.offerPrefix = 5533a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler ta.getBoolean(R.styleable.EmailServiceInfo_offerPrefix, false); 5543a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler info.usesSmtp = ta.getBoolean(R.styleable.EmailServiceInfo_usesSmtp, false); 5553a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler info.usesAutodiscover = 5563a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler ta.getBoolean(R.styleable.EmailServiceInfo_usesAutodiscover, false); 5573a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler info.offerLookback = 5583a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler ta.getBoolean(R.styleable.EmailServiceInfo_offerLookback, false); 5593a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler info.defaultLookback = 5603a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler ta.getInteger(R.styleable.EmailServiceInfo_defaultLookback, 5613a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler SyncWindow.SYNC_WINDOW_3_DAYS); 5623a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler info.syncChanges = 5633a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler ta.getBoolean(R.styleable.EmailServiceInfo_syncChanges, false); 5643a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler info.syncContacts = 5653a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler ta.getBoolean(R.styleable.EmailServiceInfo_syncContacts, false); 5663a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler info.syncCalendar = 5673a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler ta.getBoolean(R.styleable.EmailServiceInfo_syncCalendar, false); 5683a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler info.offerAttachmentPreload = 5693a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler ta.getBoolean(R.styleable.EmailServiceInfo_offerAttachmentPreload, 5703a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler false); 5713a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler info.syncIntervalStrings = 5723a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler ta.getTextArray(R.styleable.EmailServiceInfo_syncIntervalStrings); 5733a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler info.syncIntervals = 5743a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler ta.getTextArray(R.styleable.EmailServiceInfo_syncIntervals); 5753a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler info.defaultSyncInterval = 5763a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler ta.getInteger(R.styleable.EmailServiceInfo_defaultSyncInterval, 15); 5773a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler info.inferPrefix = ta.getString(R.styleable.EmailServiceInfo_inferPrefix); 5783a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler info.offerLoadMore = 5793a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler ta.getBoolean(R.styleable.EmailServiceInfo_offerLoadMore, false); 580ae46818a1925cc22fe20ee26ffee8779561a903bAlon Albert info.offerMoveTo = 581ae46818a1925cc22fe20ee26ffee8779561a903bAlon Albert ta.getBoolean(R.styleable.EmailServiceInfo_offerMoveTo, false); 5823a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler info.requiresSetup = 5833a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler ta.getBoolean(R.styleable.EmailServiceInfo_requiresSetup, false); 5843a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler 5853a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler // Must have either "class" (local) or "intent" (remote) 5863a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler if (klass != null) { 5873a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler try { 5883a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler // noinspection unchecked 5893a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler info.klass = (Class<? extends Service>) Class.forName(klass); 5903a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler } catch (ClassNotFoundException e) { 5913a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler throw new IllegalStateException( 5923a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler "Class not found in service descriptor: " + klass); 5933a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler } 5943a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler } 5953a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler if (info.klass == null && info.intentAction == null) { 596f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank throw new IllegalStateException( 5973a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler "No class or intent action specified in service descriptor"); 598f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank } 5993a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler if (info.klass != null && info.intentAction != null) { 6003a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler throw new IllegalStateException( 6013a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler "Both class and intent action specified in service descriptor"); 6023a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler } 6033a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler builder.put(info.protocol, info); 604f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank } 605f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank } 6063a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler } catch (XmlPullParserException e) { 6073a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler // ignore 6083a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler } catch (IOException e) { 6093a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler // ignore 610f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank } 6113a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler sServiceMap = builder.build(); 6123a8c86b18265eb3786bf32b5c043b5942ddb4e45Tony Mantler return sServiceMap; 61303cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank } 614f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank } 61503cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank 616e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank private static Uri asCalendarSyncAdapter(Uri uri, String account, String accountType) { 617e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank return uri.buildUpon().appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true") 618e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank .appendQueryParameter(Calendars.ACCOUNT_NAME, account) 619e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank .appendQueryParameter(Calendars.ACCOUNT_TYPE, accountType).build(); 620e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank } 621e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank 622f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank /** 623f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank * A no-op service that can be returned for non-existent/null protocols 624f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank */ 625f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank class NullService implements IEmailService { 626f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank @Override 627f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public IBinder asBinder() { 628f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank return null; 62903cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank } 63003cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank 631f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank @Override 632f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public Bundle validate(HostAuth hostauth) throws RemoteException { 633f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank return null; 63403cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank } 63503cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank 636f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank @Override 63717d5bbf768c27ac7782b155e2ab25bcd480f5dcfYu Ping Hu public void startSync(long mailboxId, boolean userRequest, int deltaMessageCount) 63817d5bbf768c27ac7782b155e2ab25bcd480f5dcfYu Ping Hu throws RemoteException { 63903cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank } 64003cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank 641f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank @Override 642f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public void stopSync(long mailboxId) throws RemoteException { 64303cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank } 64403cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank 645f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank @Override 646f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public void loadMore(long messageId) throws RemoteException { 647f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank } 648f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank 649f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank @Override 650d5acf0bbc00cbe9a2c075e1bd4825ccbd9851d8dYu Ping Hu public void loadAttachment(final IEmailServiceCallback cb, final long attachmentId, 651d5acf0bbc00cbe9a2c075e1bd4825ccbd9851d8dYu Ping Hu final boolean background) throws RemoteException { 65203cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank } 65303cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank 654f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank @Override 655f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public void updateFolderList(long accountId) throws RemoteException { 65603cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank } 65703cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank 658f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank @Override 659f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public boolean createFolder(long accountId, String name) throws RemoteException { 66003cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank return false; 66103cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank } 66203cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank 663f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank @Override 664f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public boolean deleteFolder(long accountId, String name) throws RemoteException { 665f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank return false; 66603cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank } 66703cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank 668f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank @Override 669f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public boolean renameFolder(long accountId, String oldName, String newName) 670f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank throws RemoteException { 671f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank return false; 67203cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank } 67303cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank 674f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank @Override 675f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public void setLogging(int on) throws RemoteException { 67603cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank } 67703cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank 678f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank @Override 679f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public void hostChanged(long accountId) throws RemoteException { 68003cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank } 68103cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank 682f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank @Override 683f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public Bundle autoDiscover(String userName, String password) throws RemoteException { 684f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank return null; 68503cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank } 68603cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank 687f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank @Override 688f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public void sendMeetingResponse(long messageId, int response) throws RemoteException { 68903cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank } 69003cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank 691f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank @Override 6929a1f00bee4c50c128df320a3795cfc8295d5e011Yu Ping Hu public void deleteAccountPIMData(final String emailAddress) throws RemoteException { 69303cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank } 69403cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank 695f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank @Override 696f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public int getApiLevel() throws RemoteException { 697f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank return Api.LEVEL; 698f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank } 699f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank 700f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank @Override 701f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public int searchMessages(long accountId, SearchParams params, long destMailboxId) 702f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank throws RemoteException { 70303cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank return 0; 70403cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank } 70503cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank 706f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank @Override 707f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public void sendMail(long accountId) throws RemoteException { 70803cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank } 70903cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank 71003cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank @Override 711e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank public void serviceUpdated(String emailAddress) throws RemoteException { 712e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank } 713e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank 714e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank @Override 7150b5f15d61ebf7c0e8428100637bc479ed93a4cb2Marc Blank public int getCapabilities(Account acct) throws RemoteException { 716f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank return 0; 717f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank } 7189fe51f632965f5d085ae45a1089c7c97dcec8881Makoto Onuki } 7199fe51f632965f5d085ae45a1089c7c97dcec8881Makoto Onuki} 720