1231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn/* 2231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * Copyright (C) 2009 The Android Open Source Project 3231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * 4231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License"); 5231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * you may not use this file except in compliance with the License. 6231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * You may obtain a copy of the License at 7231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * 8231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * http://www.apache.org/licenses/LICENSE-2.0 9231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * 10231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * Unless required by applicable law or agreed to in writing, software 11231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS, 12231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * See the License for the specific language governing permissions and 14231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * limitations under the License. 15231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn */ 16231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.content; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport com.android.internal.util.ArrayUtils; 202269d1572e5fcfb725ea55f5764d8c3280d69f6dDianne Hackbornimport com.android.internal.util.FastXmlSerializer; 21231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 22a3cdaa5337fa573c4c61770195d6232c2e587090Jason parksimport org.xmlpull.v1.XmlPullParser; 23a3cdaa5337fa573c4c61770195d6232c2e587090Jason parksimport org.xmlpull.v1.XmlPullParserException; 24a3cdaa5337fa573c4c61770195d6232c2e587090Jason parksimport org.xmlpull.v1.XmlSerializer; 25a3cdaa5337fa573c4c61770195d6232c2e587090Jason parks 26d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintanaimport android.accounts.Account; 27f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasaniimport android.accounts.AccountAndUser; 282b5d0ea5e90bd5b9a1b3afdd230e8907315e65e2Yameng Huangimport android.content.res.Resources; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.Cursor; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.sqlite.SQLiteDatabase; 31231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport android.database.sqlite.SQLiteException; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.sqlite.SQLiteQueryBuilder; 33231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport android.os.Bundle; 34231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport android.os.Environment; 35231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport android.os.Handler; 36231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport android.os.Message; 37231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport android.os.Parcel; 38231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport android.os.RemoteCallbackList; 39231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport android.os.RemoteException; 4039606a007a5b1309dd000234f2b8cf156c49fd0fDianne Hackbornimport android.util.AtomicFile; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 42231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport android.util.SparseArray; 43231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport android.util.Xml; 44a3cdaa5337fa573c4c61770195d6232c2e587090Jason parksimport android.util.Pair; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 46231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport java.io.File; 47231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport java.io.FileInputStream; 48231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport java.io.FileOutputStream; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 50231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport java.util.Calendar; 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.HashMap; 52231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport java.util.Iterator; 5369d95de53bc82e6c23c64ad566e428fbefae0543Ashish Sharmaimport java.util.Random; 541125d780a8b61703b8eb28c5c77dac5f3f0022ddJason parksimport java.util.TimeZone; 55a3cdaa5337fa573c4c61770195d6232c2e587090Jason parksimport java.util.List; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 58231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * Singleton that tracks the sync data and overall sync 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * history on the device. 60360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache * 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 63231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornpublic class SyncStorageEngine extends Handler { 6404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "SyncManager"; 66231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private static final boolean DEBUG_FILE = false; 67360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 6804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private static final String XML_ATTR_NEXT_AUTHORITY_ID = "nextAuthorityId"; 6904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private static final String XML_ATTR_LISTEN_FOR_TICKLES = "listen-for-tickles"; 7069d95de53bc82e6c23c64ad566e428fbefae0543Ashish Sharma private static final String XML_ATTR_SYNC_RANDOM_OFFSET = "offsetInSeconds"; 7104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private static final String XML_ATTR_ENABLED = "enabled"; 7204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private static final String XML_ATTR_USER = "user"; 7304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private static final String XML_TAG_LISTEN_FOR_TICKLES = "listenForTickles"; 7404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 75c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana private static final long DEFAULT_POLL_FREQUENCY_SECONDS = 60 * 60 * 24; // One day 76c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 77231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn // @VisibleForTesting 78231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn static final long MILLIS_IN_4WEEKS = 1000L * 60 * 60 * 24 * 7 * 4; 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 80231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** Enum value for a sync start event. */ 81231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public static final int EVENT_START = 0; 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 83231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** Enum value for a sync stop event. */ 84231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public static final int EVENT_STOP = 1; 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 86231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn // TODO: i18n -- grab these out of resources. 87231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** String names for the sync event types. */ 88231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public static final String[] EVENTS = { "START", "STOP" }; 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 90231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** Enum value for a server-initiated sync. */ 91231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public static final int SOURCE_SERVER = 0; 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 93231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** Enum value for a local-initiated sync. */ 94231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public static final int SOURCE_LOCAL = 1; 95231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** 96231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * Enum value for a poll-based sync (e.g., upon connection to 97231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * network) 98231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn */ 99231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public static final int SOURCE_POLL = 2; 100231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 101231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** Enum value for a user-initiated sync. */ 102231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public static final int SOURCE_USER = 3; 103231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 104c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana /** Enum value for a periodic sync. */ 105c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana public static final int SOURCE_PERIODIC = 4; 106c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 107307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana public static final long NOT_IN_BACKOFF_MODE = -1; 108307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana 109043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn public static final Intent SYNC_CONNECTION_SETTING_CHANGED_INTENT = 110ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana new Intent("com.android.sync.SYNC_CONN_STATUS_CHANGED"); 111ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 112231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn // TODO: i18n -- grab these out of resources. 113231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** String names for the sync source types. */ 114231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public static final String[] SOURCES = { "SERVER", 115231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn "LOCAL", 116231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn "POLL", 117c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana "USER", 118c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana "PERIODIC" }; 119231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 120231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn // The MESG column will contain one of these or one of the Error types. 121231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public static final String MESG_SUCCESS = "success"; 122231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public static final String MESG_CANCELED = "canceled"; 123231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 124a33e3f79259b56b03c7912af35944f34ad190e3cDianne Hackborn public static final int MAX_HISTORY = 100; 125360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 126231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private static final int MSG_WRITE_STATUS = 1; 127231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private static final long WRITE_STATUS_DELAY = 1000*60*10; // 10 minutes 128360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 129231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private static final int MSG_WRITE_STATISTICS = 2; 130231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private static final long WRITE_STATISTICS_DELAY = 1000*60*30; // 1/2 hour 1318294fadb155a33da8a40d8412afb35e6b424afcbJoe Onorato 1328294fadb155a33da8a40d8412afb35e6b424afcbJoe Onorato private static final boolean SYNC_ENABLED_DEFAULT = false; 133360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 134c2e4691d788088b22eadc9b2d35e9bdf0b6a0ffcFred Quintana // the version of the accounts xml file format 135fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana private static final int ACCOUNTS_VERSION = 2; 136fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana 137fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana private static HashMap<String, String> sAuthorityRenames; 138fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana 139fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana static { 140fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana sAuthorityRenames = new HashMap<String, String>(); 141fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana sAuthorityRenames.put("contacts", "com.android.contacts"); 142fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana sAuthorityRenames.put("calendar", "com.android.calendar"); 143fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana } 144c2e4691d788088b22eadc9b2d35e9bdf0b6a0ffcFred Quintana 145231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public static class PendingOperation { 1467a1355950172b7a549820e9a2cd4a9b2099ec32fDianne Hackborn final Account account; 14704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final int userId; 148231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn final int syncSource; 149231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn final String authority; 150231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn final Bundle extras; // note: read-only. 151307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana final boolean expedited; 152360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 153231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn int authorityId; 154231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn byte[] flatExtras; 155360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 15604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani PendingOperation(Account account, int userId, int source, 157307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana String authority, Bundle extras, boolean expedited) { 158231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn this.account = account; 15904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani this.userId = userId; 160231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn this.syncSource = source; 161231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn this.authority = authority; 162231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn this.extras = extras != null ? new Bundle(extras) : extras; 163307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana this.expedited = expedited; 164231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn this.authorityId = -1; 165231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 167231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn PendingOperation(PendingOperation other) { 168231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn this.account = other.account; 16904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani this.userId = other.userId; 170231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn this.syncSource = other.syncSource; 171231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn this.authority = other.authority; 172231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn this.extras = other.extras; 173231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn this.authorityId = other.authorityId; 174307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana this.expedited = other.expedited; 175231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 176231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 177360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 178231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn static class AccountInfo { 17904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final AccountAndUser accountAndUser; 180231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn final HashMap<String, AuthorityInfo> authorities = 181231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn new HashMap<String, AuthorityInfo>(); 182360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 18304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani AccountInfo(AccountAndUser accountAndUser) { 18404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani this.accountAndUser = accountAndUser; 185231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 186231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 187360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 188231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public static class AuthorityInfo { 1897a1355950172b7a549820e9a2cd4a9b2099ec32fDianne Hackborn final Account account; 19004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final int userId; 191231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn final String authority; 192231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn final int ident; 193231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn boolean enabled; 1945e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana int syncable; 195307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana long backoffTime; 196307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana long backoffDelay; 197307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana long delayUntil; 198c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana final ArrayList<Pair<Bundle, Long>> periodicSyncs; 199ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 2003aca7d7bec4b48bc68480b9d6b0ccdabf6903dfbCarlos Valdivia /** 2013aca7d7bec4b48bc68480b9d6b0ccdabf6903dfbCarlos Valdivia * Copy constructor for making deep-ish copies. Only the bundles stored 2023aca7d7bec4b48bc68480b9d6b0ccdabf6903dfbCarlos Valdivia * in periodic syncs can make unexpected changes. 2033aca7d7bec4b48bc68480b9d6b0ccdabf6903dfbCarlos Valdivia * 2043aca7d7bec4b48bc68480b9d6b0ccdabf6903dfbCarlos Valdivia * @param toCopy AuthorityInfo to be copied. 2053aca7d7bec4b48bc68480b9d6b0ccdabf6903dfbCarlos Valdivia */ 2063aca7d7bec4b48bc68480b9d6b0ccdabf6903dfbCarlos Valdivia AuthorityInfo(AuthorityInfo toCopy) { 2073aca7d7bec4b48bc68480b9d6b0ccdabf6903dfbCarlos Valdivia account = toCopy.account; 2083aca7d7bec4b48bc68480b9d6b0ccdabf6903dfbCarlos Valdivia userId = toCopy.userId; 2093aca7d7bec4b48bc68480b9d6b0ccdabf6903dfbCarlos Valdivia authority = toCopy.authority; 2103aca7d7bec4b48bc68480b9d6b0ccdabf6903dfbCarlos Valdivia ident = toCopy.ident; 2113aca7d7bec4b48bc68480b9d6b0ccdabf6903dfbCarlos Valdivia enabled = toCopy.enabled; 2123aca7d7bec4b48bc68480b9d6b0ccdabf6903dfbCarlos Valdivia syncable = toCopy.syncable; 2133aca7d7bec4b48bc68480b9d6b0ccdabf6903dfbCarlos Valdivia backoffTime = toCopy.backoffTime; 2143aca7d7bec4b48bc68480b9d6b0ccdabf6903dfbCarlos Valdivia backoffDelay = toCopy.backoffDelay; 2153aca7d7bec4b48bc68480b9d6b0ccdabf6903dfbCarlos Valdivia delayUntil = toCopy.delayUntil; 2163aca7d7bec4b48bc68480b9d6b0ccdabf6903dfbCarlos Valdivia periodicSyncs = new ArrayList<Pair<Bundle, Long>>(); 2173aca7d7bec4b48bc68480b9d6b0ccdabf6903dfbCarlos Valdivia for (Pair<Bundle, Long> sync : toCopy.periodicSyncs) { 2183aca7d7bec4b48bc68480b9d6b0ccdabf6903dfbCarlos Valdivia // Still not a perfect copy, because we are just copying the mappings. 2193aca7d7bec4b48bc68480b9d6b0ccdabf6903dfbCarlos Valdivia periodicSyncs.add(Pair.create(new Bundle(sync.first), sync.second)); 2203aca7d7bec4b48bc68480b9d6b0ccdabf6903dfbCarlos Valdivia } 2213aca7d7bec4b48bc68480b9d6b0ccdabf6903dfbCarlos Valdivia } 2223aca7d7bec4b48bc68480b9d6b0ccdabf6903dfbCarlos Valdivia 22304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani AuthorityInfo(Account account, int userId, String authority, int ident) { 224231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn this.account = account; 22504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani this.userId = userId; 226231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn this.authority = authority; 227231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn this.ident = ident; 2288294fadb155a33da8a40d8412afb35e6b424afcbJoe Onorato enabled = SYNC_ENABLED_DEFAULT; 2294a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana syncable = -1; // default to "unknown" 230307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana backoffTime = -1; // if < 0 then we aren't in backoff mode 231307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana backoffDelay = -1; // if < 0 then we aren't in backoff mode 232c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana periodicSyncs = new ArrayList<Pair<Bundle, Long>>(); 233c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana periodicSyncs.add(Pair.create(new Bundle(), DEFAULT_POLL_FREQUENCY_SECONDS)); 234231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 235231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 236360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 237231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public static class SyncHistoryItem { 238231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn int authorityId; 239231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn int historyId; 240231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn long eventTime; 241231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn long elapsedTime; 242231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn int source; 243231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn int event; 244231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn long upstreamActivity; 245231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn long downstreamActivity; 246231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn String mesg; 247dc47556cb37b6f25faceb5eb97cef60d384b55fbFred Quintana boolean initialization; 248231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 249360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 250231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public static class DayStats { 251231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public final int day; 252231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public int successCount; 253231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public long successTime; 254231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public int failureCount; 255231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public long failureTime; 256360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 257231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public DayStats(int day) { 258231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn this.day = day; 259231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 260231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 261360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 26204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani interface OnSyncRequestListener { 26304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani /** 26404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani * Called when a sync is needed on an account(s) due to some change in state. 26504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani * @param account 26604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani * @param userId 26704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani * @param authority 26804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani * @param extras 26904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani */ 27004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public void onSyncRequest(Account account, int userId, String authority, Bundle extras); 27104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 27204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 273231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn // Primary list of all syncable authorities. Also our global lock. 274231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private final SparseArray<AuthorityInfo> mAuthorities = 275231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn new SparseArray<AuthorityInfo>(); 276360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 27704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private final HashMap<AccountAndUser, AccountInfo> mAccounts 27804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani = new HashMap<AccountAndUser, AccountInfo>(); 279231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 280231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private final ArrayList<PendingOperation> mPendingOperations = 281231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn new ArrayList<PendingOperation>(); 282360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 28304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private final SparseArray<ArrayList<SyncInfo>> mCurrentSyncs 28404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani = new SparseArray<ArrayList<SyncInfo>>(); 285360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 286231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private final SparseArray<SyncStatusInfo> mSyncStatus = 287231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn new SparseArray<SyncStatusInfo>(); 288360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 289231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private final ArrayList<SyncHistoryItem> mSyncHistory = 290231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn new ArrayList<SyncHistoryItem>(); 291360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 292231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private final RemoteCallbackList<ISyncStatusObserver> mChangeListeners 293231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn = new RemoteCallbackList<ISyncStatusObserver>(); 294360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 29577c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana private int mNextAuthorityId = 0; 29677c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana 297231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn // We keep 4 weeks of stats. 298231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private final DayStats[] mDayStats = new DayStats[7*4]; 299231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private final Calendar mCal; 300231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private int mYear; 301231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private int mYearInDays; 302360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 303231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private final Context mContext; 304c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 305231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private static volatile SyncStorageEngine sSyncStorageEngine = null; 306360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 30769d95de53bc82e6c23c64ad566e428fbefae0543Ashish Sharma private int mSyncRandomOffset; 30869d95de53bc82e6c23c64ad566e428fbefae0543Ashish Sharma 309231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** 310231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * This file contains the core engine state: all accounts and the 311231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * settings for them. It must never be lost, and should be changed 312231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * infrequently, so it is stored as an XML file. 313231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn */ 314231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private final AtomicFile mAccountInfoFile; 315360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 316231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** 317231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * This file contains the current sync status. We would like to retain 318231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * it across boots, but its loss is not the end of the world, so we store 319231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * this information as binary data. 320231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn */ 321231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private final AtomicFile mStatusFile; 322360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 323231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** 324231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * This file contains sync statistics. This is purely debugging information 325231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * so is written infrequently and can be thrown away at any time. 326231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn */ 327231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private final AtomicFile mStatisticsFile; 328360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 329231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** 330231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * This file contains the pending sync operations. It is a binary file, 331231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * which must be updated every time an operation is added or removed, 332231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * so we have special handling of it. 333231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn */ 334231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private final AtomicFile mPendingFile; 335231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private static final int PENDING_FINISH_TO_WRITE = 4; 336231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private int mNumPendingFinished = 0; 337360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 338231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private int mNextHistoryId = 0; 33904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private SparseArray<Boolean> mMasterSyncAutomatically = new SparseArray<Boolean>(); 3402b5d0ea5e90bd5b9a1b3afdd230e8907315e65e2Yameng Huang private boolean mDefaultMasterSyncAutomatically; 34104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 34204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private OnSyncRequestListener mSyncRequestListener; 343360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 344c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana private SyncStorageEngine(Context context, File dataDir) { 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sSyncStorageEngine = this; 347360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 348231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mCal = Calendar.getInstance(TimeZone.getTimeZone("GMT+0")); 349360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 3502b5d0ea5e90bd5b9a1b3afdd230e8907315e65e2Yameng Huang mDefaultMasterSyncAutomatically = mContext.getResources().getBoolean( 3512b5d0ea5e90bd5b9a1b3afdd230e8907315e65e2Yameng Huang com.android.internal.R.bool.config_syncstorageengine_masterSyncAutomatically); 3522b5d0ea5e90bd5b9a1b3afdd230e8907315e65e2Yameng Huang 353231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn File systemDir = new File(dataDir, "system"); 354231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn File syncDir = new File(systemDir, "sync"); 355c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana syncDir.mkdirs(); 356231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mAccountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml")); 357231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mStatusFile = new AtomicFile(new File(syncDir, "status.bin")); 358231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mPendingFile = new AtomicFile(new File(syncDir, "pending.bin")); 359231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mStatisticsFile = new AtomicFile(new File(syncDir, "stats.bin")); 360360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 361231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn readAccountInfoLocked(); 362231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn readStatusLocked(); 363231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn readPendingOperationsLocked(); 364231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn readStatisticsLocked(); 36577c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana readAndDeleteLegacyAccountInfoLocked(); 36677c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana writeAccountInfoLocked(); 36777c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana writeStatusLocked(); 36877c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana writePendingOperationsLocked(); 36977c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana writeStatisticsLocked(); 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static SyncStorageEngine newTestInstance(Context context) { 373c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana return new SyncStorageEngine(context, context.getFilesDir()); 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void init(Context context) { 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sSyncStorageEngine != null) { 378307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana return; 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 380c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana // This call will return the correct directory whether Encrypted File Systems is 381c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana // enabled or not. 382a3cdaa5337fa573c4c61770195d6232c2e587090Jason parks File dataDir = Environment.getSecureDataDirectory(); 383c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana sSyncStorageEngine = new SyncStorageEngine(context, dataDir); 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static SyncStorageEngine getSingleton() { 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sSyncStorageEngine == null) { 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalStateException("not initialized"); 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return sSyncStorageEngine; 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 39304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani protected void setOnSyncRequestListener(OnSyncRequestListener listener) { 39404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani if (mSyncRequestListener == null) { 39504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani mSyncRequestListener = listener; 39604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 39704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 39804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 399231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn @Override public void handleMessage(Message msg) { 400231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (msg.what == MSG_WRITE_STATUS) { 4014e80820ab54f3985220ff06b2fcd381565e9f19dDianne Hackborn synchronized (mAuthorities) { 402231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn writeStatusLocked(); 403231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 404231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } else if (msg.what == MSG_WRITE_STATISTICS) { 4054e80820ab54f3985220ff06b2fcd381565e9f19dDianne Hackborn synchronized (mAuthorities) { 406231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn writeStatisticsLocked(); 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 409231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 410360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 41169d95de53bc82e6c23c64ad566e428fbefae0543Ashish Sharma public int getSyncRandomOffset() { 41269d95de53bc82e6c23c64ad566e428fbefae0543Ashish Sharma return mSyncRandomOffset; 41369d95de53bc82e6c23c64ad566e428fbefae0543Ashish Sharma } 41469d95de53bc82e6c23c64ad566e428fbefae0543Ashish Sharma 415231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public void addStatusChangeListener(int mask, ISyncStatusObserver callback) { 416231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn synchronized (mAuthorities) { 417231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mChangeListeners.register(callback, mask); 418231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 419231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 420360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 421231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public void removeStatusChangeListener(ISyncStatusObserver callback) { 422231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn synchronized (mAuthorities) { 423231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mChangeListeners.unregister(callback); 424231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 425231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 426360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 427231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private void reportChange(int which) { 428231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn ArrayList<ISyncStatusObserver> reports = null; 429231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn synchronized (mAuthorities) { 430231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn int i = mChangeListeners.beginBroadcast(); 431231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn while (i > 0) { 432231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn i--; 433231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn Integer mask = (Integer)mChangeListeners.getBroadcastCookie(i); 434231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if ((which & mask.intValue()) == 0) { 435231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn continue; 436231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 437231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (reports == null) { 438231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn reports = new ArrayList<ISyncStatusObserver>(i); 439231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 440231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn reports.add(mChangeListeners.getBroadcastItem(i)); 441231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 442b06ea706530e6d19eb2a1a9a7ae6c5dd77d80af0Dianne Hackborn mChangeListeners.finishBroadcast(); 443231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 444360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 44577c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 44677c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana Log.v(TAG, "reportChange " + which + " to: " + reports); 44777c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana } 448360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 449231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (reports != null) { 450231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn int i = reports.size(); 451231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn while (i > 0) { 452231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn i--; 453231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn try { 454231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn reports.get(i).onStatusChanged(which); 455231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } catch (RemoteException e) { 456231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn // The remote callback list will take care of this for us. 457231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 458231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 459231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 460231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 46170c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani 46204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public boolean getSyncAutomatically(Account account, int userId, String providerName) { 463231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn synchronized (mAuthorities) { 464231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (account != null) { 46504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani AuthorityInfo authority = getAuthorityLocked(account, userId, providerName, 466ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana "getSyncAutomatically"); 467ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return authority != null && authority.enabled; 468231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 469ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 470231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn int i = mAuthorities.size(); 471231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn while (i > 0) { 472231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn i--; 473360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache AuthorityInfo authority = mAuthorities.valueAt(i); 474231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (authority.authority.equals(providerName) 47504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani && authority.userId == userId 476231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn && authority.enabled) { 477231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return true; 478231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 480231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return false; 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 48404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public void setSyncAutomatically(Account account, int userId, String providerName, 48504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani boolean sync) { 48604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani Log.d(TAG, "setSyncAutomatically: " + /* account + */" provider " + providerName 48704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani + ", user " + userId + " -> " + sync); 488231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn synchronized (mAuthorities) { 48904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani AuthorityInfo authority = getOrCreateAuthorityLocked(account, userId, providerName, -1, 49004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani false); 49177c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana if (authority.enabled == sync) { 49277c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana Log.d(TAG, "setSyncAutomatically: already set to " + sync + ", doing nothing"); 49377c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana return; 49477c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana } 4958294fadb155a33da8a40d8412afb35e6b424afcbJoe Onorato authority.enabled = sync; 496231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn writeAccountInfoLocked(); 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4988294fadb155a33da8a40d8412afb35e6b424afcbJoe Onorato 49977c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana if (sync) { 50004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani requestSync(account, userId, providerName, new Bundle()); 5018294fadb155a33da8a40d8412afb35e6b424afcbJoe Onorato } 502ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS); 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 50504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public int getIsSyncable(Account account, int userId, String providerName) { 5065e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana synchronized (mAuthorities) { 5075e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana if (account != null) { 50804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani AuthorityInfo authority = getAuthorityLocked(account, userId, providerName, 5095e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana "getIsSyncable"); 5105e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana if (authority == null) { 5115e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana return -1; 5125e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 5135e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana return authority.syncable; 5145e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 5155e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana 5165e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana int i = mAuthorities.size(); 5175e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana while (i > 0) { 5185e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana i--; 519360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache AuthorityInfo authority = mAuthorities.valueAt(i); 5205e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana if (authority.authority.equals(providerName)) { 5215e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana return authority.syncable; 5225e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 5235e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 5245e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana return -1; 5255e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 5265e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 5275e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana 52804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public void setIsSyncable(Account account, int userId, String providerName, int syncable) { 529b763ab265130b5aa59e4de561ba3836ac294fe62Fred Quintana if (syncable > 1) { 530b763ab265130b5aa59e4de561ba3836ac294fe62Fred Quintana syncable = 1; 531b763ab265130b5aa59e4de561ba3836ac294fe62Fred Quintana } else if (syncable < -1) { 532b763ab265130b5aa59e4de561ba3836ac294fe62Fred Quintana syncable = -1; 533b763ab265130b5aa59e4de561ba3836ac294fe62Fred Quintana } 53404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani Log.d(TAG, "setIsSyncable: " + account + ", provider " + providerName 53504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani + ", user " + userId + " -> " + syncable); 5365e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana synchronized (mAuthorities) { 53704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani AuthorityInfo authority = getOrCreateAuthorityLocked(account, userId, providerName, -1, 53804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani false); 53977c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana if (authority.syncable == syncable) { 54077c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana Log.d(TAG, "setIsSyncable: already set to " + syncable + ", doing nothing"); 54177c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana return; 54277c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana } 5435e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana authority.syncable = syncable; 5445e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana writeAccountInfoLocked(); 5455e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 5465e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana 54777c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana if (syncable > 0) { 54804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani requestSync(account, userId, providerName, new Bundle()); 5495e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 5505e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS); 5515e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 5525e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana 55304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public Pair<Long, Long> getBackoff(Account account, int userId, String providerName) { 554307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana synchronized (mAuthorities) { 55504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani AuthorityInfo authority = getAuthorityLocked(account, userId, providerName, 55604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani "getBackoff"); 557307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana if (authority == null || authority.backoffTime < 0) { 558307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana return null; 559307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana } 560307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana return Pair.create(authority.backoffTime, authority.backoffDelay); 561307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana } 562307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana } 563307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana 56404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public void setBackoff(Account account, int userId, String providerName, 565307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana long nextSyncTime, long nextDelay) { 566307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 567307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana Log.v(TAG, "setBackoff: " + account + ", provider " + providerName 56804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani + ", user " + userId 569307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana + " -> nextSyncTime " + nextSyncTime + ", nextDelay " + nextDelay); 570307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana } 571307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana boolean changed = false; 572307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana synchronized (mAuthorities) { 573307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana if (account == null || providerName == null) { 574307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana for (AccountInfo accountInfo : mAccounts.values()) { 57504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani if (account != null && !account.equals(accountInfo.accountAndUser.account) 57604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani && userId != accountInfo.accountAndUser.userId) { 57704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani continue; 57804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 579307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana for (AuthorityInfo authorityInfo : accountInfo.authorities.values()) { 580307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana if (providerName != null && !providerName.equals(authorityInfo.authority)) { 581307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana continue; 582307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana } 583307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana if (authorityInfo.backoffTime != nextSyncTime 584307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana || authorityInfo.backoffDelay != nextDelay) { 585307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana authorityInfo.backoffTime = nextSyncTime; 586307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana authorityInfo.backoffDelay = nextDelay; 587307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana changed = true; 588307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana } 589307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana } 590307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana } 591307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana } else { 592307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana AuthorityInfo authority = 59304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani getOrCreateAuthorityLocked(account, userId, providerName, -1 /* ident */, 59404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani true); 595307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana if (authority.backoffTime == nextSyncTime && authority.backoffDelay == nextDelay) { 596307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana return; 597307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana } 598307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana authority.backoffTime = nextSyncTime; 599307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana authority.backoffDelay = nextDelay; 600307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana changed = true; 601307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana } 602307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana } 603307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana 604307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana if (changed) { 605307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS); 606307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana } 607307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana } 608307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana 609ed1d253573a238fd53d27def24d298314f24d425Alon Albert public void clearAllBackoffs(SyncQueue syncQueue) { 610744e310f6635026396e32ab0a2c009e464c2be3cAlon Albert boolean changed = false; 611744e310f6635026396e32ab0a2c009e464c2be3cAlon Albert synchronized (mAuthorities) { 612a706e2fd0059b1bb86c487722dbc9fc0fda9c980Jeff Sharkey synchronized (syncQueue) { 613a706e2fd0059b1bb86c487722dbc9fc0fda9c980Jeff Sharkey for (AccountInfo accountInfo : mAccounts.values()) { 614a706e2fd0059b1bb86c487722dbc9fc0fda9c980Jeff Sharkey for (AuthorityInfo authorityInfo : accountInfo.authorities.values()) { 615a706e2fd0059b1bb86c487722dbc9fc0fda9c980Jeff Sharkey if (authorityInfo.backoffTime != NOT_IN_BACKOFF_MODE 616a706e2fd0059b1bb86c487722dbc9fc0fda9c980Jeff Sharkey || authorityInfo.backoffDelay != NOT_IN_BACKOFF_MODE) { 617a706e2fd0059b1bb86c487722dbc9fc0fda9c980Jeff Sharkey if (Log.isLoggable(TAG, Log.VERBOSE)) { 618a706e2fd0059b1bb86c487722dbc9fc0fda9c980Jeff Sharkey Log.v(TAG, "clearAllBackoffs:" 619a706e2fd0059b1bb86c487722dbc9fc0fda9c980Jeff Sharkey + " authority:" + authorityInfo.authority 620a706e2fd0059b1bb86c487722dbc9fc0fda9c980Jeff Sharkey + " account:" + accountInfo.accountAndUser.account.name 621a706e2fd0059b1bb86c487722dbc9fc0fda9c980Jeff Sharkey + " user:" + accountInfo.accountAndUser.userId 622a706e2fd0059b1bb86c487722dbc9fc0fda9c980Jeff Sharkey + " backoffTime was: " + authorityInfo.backoffTime 623a706e2fd0059b1bb86c487722dbc9fc0fda9c980Jeff Sharkey + " backoffDelay was: " + authorityInfo.backoffDelay); 624a706e2fd0059b1bb86c487722dbc9fc0fda9c980Jeff Sharkey } 625a706e2fd0059b1bb86c487722dbc9fc0fda9c980Jeff Sharkey authorityInfo.backoffTime = NOT_IN_BACKOFF_MODE; 626a706e2fd0059b1bb86c487722dbc9fc0fda9c980Jeff Sharkey authorityInfo.backoffDelay = NOT_IN_BACKOFF_MODE; 627a706e2fd0059b1bb86c487722dbc9fc0fda9c980Jeff Sharkey syncQueue.onBackoffChanged(accountInfo.accountAndUser.account, 628a706e2fd0059b1bb86c487722dbc9fc0fda9c980Jeff Sharkey accountInfo.accountAndUser.userId, authorityInfo.authority, 0); 629a706e2fd0059b1bb86c487722dbc9fc0fda9c980Jeff Sharkey changed = true; 630744e310f6635026396e32ab0a2c009e464c2be3cAlon Albert } 631744e310f6635026396e32ab0a2c009e464c2be3cAlon Albert } 632744e310f6635026396e32ab0a2c009e464c2be3cAlon Albert } 633744e310f6635026396e32ab0a2c009e464c2be3cAlon Albert } 634744e310f6635026396e32ab0a2c009e464c2be3cAlon Albert } 635744e310f6635026396e32ab0a2c009e464c2be3cAlon Albert 636744e310f6635026396e32ab0a2c009e464c2be3cAlon Albert if (changed) { 637744e310f6635026396e32ab0a2c009e464c2be3cAlon Albert reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS); 638744e310f6635026396e32ab0a2c009e464c2be3cAlon Albert } 639744e310f6635026396e32ab0a2c009e464c2be3cAlon Albert } 640744e310f6635026396e32ab0a2c009e464c2be3cAlon Albert 64104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public void setDelayUntilTime(Account account, int userId, String providerName, 64204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani long delayUntil) { 643307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 644307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana Log.v(TAG, "setDelayUntil: " + account + ", provider " + providerName 64504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani + ", user " + userId + " -> delayUntil " + delayUntil); 646307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana } 647307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana synchronized (mAuthorities) { 648c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana AuthorityInfo authority = getOrCreateAuthorityLocked( 64904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani account, userId, providerName, -1 /* ident */, true); 650307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana if (authority.delayUntil == delayUntil) { 651307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana return; 652307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana } 653307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana authority.delayUntil = delayUntil; 654307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana } 655307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana 656307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS); 657307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana } 658307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana 65904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public long getDelayUntilTime(Account account, int userId, String providerName) { 660307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana synchronized (mAuthorities) { 66104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani AuthorityInfo authority = getAuthorityLocked(account, userId, providerName, 66204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani "getDelayUntil"); 663307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana if (authority == null) { 664307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana return 0; 665307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana } 666307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana return authority.delayUntil; 667307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana } 668307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana } 669307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana 67004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void updateOrRemovePeriodicSync(Account account, int userId, String providerName, 67104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani Bundle extras, 672c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana long period, boolean add) { 673c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana if (period <= 0) { 674c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana period = 0; 675c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 676c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana if (extras == null) { 677c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana extras = new Bundle(); 678c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 679c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 68004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani Log.v(TAG, "addOrRemovePeriodicSync: " + account + ", user " + userId 68104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani + ", provider " + providerName 682c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana + " -> period " + period + ", extras " + extras); 683c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 684c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana synchronized (mAuthorities) { 68577c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana try { 68677c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana AuthorityInfo authority = 68704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani getOrCreateAuthorityLocked(account, userId, providerName, -1, false); 68877c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana if (add) { 68977c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana // add this periodic sync if one with the same extras doesn't already 69077c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana // exist in the periodicSyncs array 69177c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana boolean alreadyPresent = false; 69277c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana for (int i = 0, N = authority.periodicSyncs.size(); i < N; i++) { 69377c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana Pair<Bundle, Long> syncInfo = authority.periodicSyncs.get(i); 69477c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana final Bundle existingExtras = syncInfo.first; 69577c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana if (equals(existingExtras, extras)) { 69677c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana if (syncInfo.second == period) { 69777c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana return; 69877c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana } 69977c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana authority.periodicSyncs.set(i, Pair.create(extras, period)); 70077c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana alreadyPresent = true; 70177c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana break; 702c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 703c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 70477c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana // if we added an entry to the periodicSyncs array also add an entry to 70577c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana // the periodic syncs status to correspond to it 70677c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana if (!alreadyPresent) { 70777c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana authority.periodicSyncs.add(Pair.create(extras, period)); 70877c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana SyncStatusInfo status = getOrCreateSyncStatusLocked(authority.ident); 70977c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana status.setPeriodicSyncTime(authority.periodicSyncs.size() - 1, 0); 71077c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana } 71177c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana } else { 71277c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana // remove any periodic syncs that match the authority and extras 71377c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana SyncStatusInfo status = mSyncStatus.get(authority.ident); 71477c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana boolean changed = false; 71577c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana Iterator<Pair<Bundle, Long>> iterator = authority.periodicSyncs.iterator(); 71677c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana int i = 0; 71777c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana while (iterator.hasNext()) { 71877c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana Pair<Bundle, Long> syncInfo = iterator.next(); 71977c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana if (equals(syncInfo.first, extras)) { 72077c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana iterator.remove(); 72177c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana changed = true; 72277c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana // if we removed an entry from the periodicSyncs array also 72377c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana // remove the corresponding entry from the status 72477c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana if (status != null) { 72577c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana status.removePeriodicSyncTime(i); 72677c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana } 72777c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana } else { 72877c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana i++; 729c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 73077c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana } 73177c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana if (!changed) { 73277c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana return; 733c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 734c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 73577c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana } finally { 73677c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana writeAccountInfoLocked(); 73777c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana writeStatusLocked(); 738c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 739c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 740c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 741c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS); 742c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 743c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 74404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public void addPeriodicSync(Account account, int userId, String providerName, Bundle extras, 745c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana long pollFrequency) { 74604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani updateOrRemovePeriodicSync(account, userId, providerName, extras, pollFrequency, 74704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani true /* add */); 748c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 749c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 75004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public void removePeriodicSync(Account account, int userId, String providerName, 75104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani Bundle extras) { 75204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani updateOrRemovePeriodicSync(account, userId, providerName, extras, 0 /* period, ignored */, 753c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana false /* remove */); 754c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 755c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 75604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public List<PeriodicSync> getPeriodicSyncs(Account account, int userId, String providerName) { 757c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana ArrayList<PeriodicSync> syncs = new ArrayList<PeriodicSync>(); 758c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana synchronized (mAuthorities) { 75904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani AuthorityInfo authority = getAuthorityLocked(account, userId, providerName, 76004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani "getPeriodicSyncs"); 761c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana if (authority != null) { 762c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana for (Pair<Bundle, Long> item : authority.periodicSyncs) { 76304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani syncs.add(new PeriodicSync(account, providerName, item.first, 76404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani item.second)); 765c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 766c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 767c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 768c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana return syncs; 769c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 770c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 77104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public void setMasterSyncAutomatically(boolean flag, int userId) { 772231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn synchronized (mAuthorities) { 77304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani Boolean auto = mMasterSyncAutomatically.get(userId); 77404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani if (auto != null && (boolean) auto == flag) { 77577c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana return; 77677c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana } 77704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani mMasterSyncAutomatically.put(userId, flag); 778231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn writeAccountInfoLocked(); 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 78077c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana if (flag) { 78104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani requestSync(null, userId, null, new Bundle()); 7828294fadb155a33da8a40d8412afb35e6b424afcbJoe Onorato } 783ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS); 784ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana mContext.sendBroadcast(SYNC_CONNECTION_SETTING_CHANGED_INTENT); 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 78704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public boolean getMasterSyncAutomatically(int userId) { 788231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn synchronized (mAuthorities) { 78904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani Boolean auto = mMasterSyncAutomatically.get(userId); 7902b5d0ea5e90bd5b9a1b3afdd230e8907315e65e2Yameng Huang return auto == null ? mDefaultMasterSyncAutomatically : auto; 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 793360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 79404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public AuthorityInfo getOrCreateAuthority(Account account, int userId, String authority) { 795231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn synchronized (mAuthorities) { 79604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return getOrCreateAuthorityLocked(account, userId, authority, 7971bbcd105a164ebbd69ee3fd1fe8fb75cd8a8c0cbFred Quintana -1 /* assign a new identifier if creating a new authority */, 7981bbcd105a164ebbd69ee3fd1fe8fb75cd8a8c0cbFred Quintana true /* write to storage if this results in a change */); 799231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 801360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 80204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public void removeAuthority(Account account, int userId, String authority) { 8037620f1ae498e01bf2df58eaa1b9b20ef1eb47fa1Fred Quintana synchronized (mAuthorities) { 80404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani removeAuthorityLocked(account, userId, authority, true /* doWrite */); 8057620f1ae498e01bf2df58eaa1b9b20ef1eb47fa1Fred Quintana } 8067620f1ae498e01bf2df58eaa1b9b20ef1eb47fa1Fred Quintana } 8077620f1ae498e01bf2df58eaa1b9b20ef1eb47fa1Fred Quintana 808231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public AuthorityInfo getAuthority(int authorityId) { 809231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn synchronized (mAuthorities) { 810231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return mAuthorities.get(authorityId); 811231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 812231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 813360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 815231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * Returns true if there is currently a sync operation for the given 816918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana * account or authority actively being processed. 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 81804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public boolean isSyncActive(Account account, int userId, String authority) { 819231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn synchronized (mAuthorities) { 82004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani for (SyncInfo syncInfo : getCurrentSyncs(userId)) { 821918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana AuthorityInfo ainfo = getAuthority(syncInfo.authorityId); 822231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (ainfo != null && ainfo.account.equals(account) 82304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani && ainfo.authority.equals(authority) 82404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani && ainfo.userId == userId) { 825231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return true; 826231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 827231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 829360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 830231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return false; 831231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 832360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 833231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public PendingOperation insertIntoPending(PendingOperation op) { 834231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn synchronized (mAuthorities) { 83577c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 83677c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana Log.v(TAG, "insertIntoPending: account=" + op.account 83704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani + " user=" + op.userId 83804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani + " auth=" + op.authority 83904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani + " src=" + op.syncSource 84004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani + " extras=" + op.extras); 84177c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana } 842360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 84304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani AuthorityInfo authority = getOrCreateAuthorityLocked(op.account, op.userId, 844231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn op.authority, 845231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn -1 /* desired identifier */, 846231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn true /* write accounts to storage */); 847231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (authority == null) { 848231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return null; 849231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 850360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 851231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn op = new PendingOperation(op); 852231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn op.authorityId = authority.ident; 853231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mPendingOperations.add(op); 854231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn appendPendingOperationLocked(op); 855360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 856231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn SyncStatusInfo status = getOrCreateSyncStatusLocked(authority.ident); 857231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn status.pending = true; 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 859360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 860ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana reportChange(ContentResolver.SYNC_OBSERVER_TYPE_PENDING); 861231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return op; 862231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 864231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public boolean deleteFromPending(PendingOperation op) { 865231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn boolean res = false; 866231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn synchronized (mAuthorities) { 86777c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 86877c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana Log.v(TAG, "deleteFromPending: account=" + op.account 86904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani + " user=" + op.userId 870231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn + " auth=" + op.authority 871231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn + " src=" + op.syncSource 872231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn + " extras=" + op.extras); 87377c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana } 874231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (mPendingOperations.remove(op)) { 875231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (mPendingOperations.size() == 0 876231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn || mNumPendingFinished >= PENDING_FINISH_TO_WRITE) { 877231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn writePendingOperationsLocked(); 878231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mNumPendingFinished = 0; 879231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } else { 880231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mNumPendingFinished++; 881231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 882360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 88304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani AuthorityInfo authority = getAuthorityLocked(op.account, op.userId, op.authority, 884231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn "deleteFromPending"); 885231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (authority != null) { 88677c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "removing - " + authority); 887231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn final int N = mPendingOperations.size(); 888231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn boolean morePending = false; 889231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn for (int i=0; i<N; i++) { 890231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn PendingOperation cur = mPendingOperations.get(i); 891231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (cur.account.equals(op.account) 89204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani && cur.authority.equals(op.authority) 89304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani && cur.userId == op.userId) { 894231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn morePending = true; 895231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn break; 896231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 897231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 898360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 899231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (!morePending) { 90077c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "no more pending!"); 901231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn SyncStatusInfo status = getOrCreateSyncStatusLocked(authority.ident); 902231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn status.pending = false; 903231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 904231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 905360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 906231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn res = true; 907231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 908231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 909360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 910ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana reportChange(ContentResolver.SYNC_OBSERVER_TYPE_PENDING); 911231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return res; 9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 915231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * Return a copy of the current array of pending operations. The 916231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * PendingOperation objects are the real objects stored inside, so that 917231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * they can be used with deleteFromPending(). 9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 919231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public ArrayList<PendingOperation> getPendingOperations() { 920231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn synchronized (mAuthorities) { 921231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return new ArrayList<PendingOperation>(mPendingOperations); 9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 924360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 926231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * Return the number of currently pending operations. 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 928231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public int getPendingOperationCount() { 929231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn synchronized (mAuthorities) { 930231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return mPendingOperations.size(); 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 933360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 935231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * Called when the set of account has changed, given the new array of 936231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * active accounts. 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 93804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public void doDatabaseCleanup(Account[] accounts, int userId) { 939231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn synchronized (mAuthorities) { 94077c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) Log.w(TAG, "Updating for new accounts..."); 941231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn SparseArray<AuthorityInfo> removing = new SparseArray<AuthorityInfo>(); 942231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn Iterator<AccountInfo> accIt = mAccounts.values().iterator(); 943231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn while (accIt.hasNext()) { 944231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn AccountInfo acc = accIt.next(); 94504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani if (!ArrayUtils.contains(accounts, acc.accountAndUser.account) 94604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani && acc.accountAndUser.userId == userId) { 947231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn // This account no longer exists... 94877c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 94904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani Log.w(TAG, "Account removed: " + acc.accountAndUser); 95077c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana } 951231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn for (AuthorityInfo auth : acc.authorities.values()) { 952231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn removing.put(auth.ident, auth); 953231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 954231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn accIt.remove(); 955231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 956231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 957360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 958231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn // Clean out all data structures. 959231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn int i = removing.size(); 960231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (i > 0) { 961231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn while (i > 0) { 962231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn i--; 963231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn int ident = removing.keyAt(i); 964231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mAuthorities.remove(ident); 965231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn int j = mSyncStatus.size(); 966231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn while (j > 0) { 967231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn j--; 968231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (mSyncStatus.keyAt(j) == ident) { 969231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mSyncStatus.remove(mSyncStatus.keyAt(j)); 970231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 971231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 972231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn j = mSyncHistory.size(); 973231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn while (j > 0) { 974231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn j--; 975231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (mSyncHistory.get(j).authorityId == ident) { 976231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mSyncHistory.remove(j); 977231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 978231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 979231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 980231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn writeAccountInfoLocked(); 981231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn writeStatusLocked(); 982231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn writePendingOperationsLocked(); 983231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn writeStatisticsLocked(); 984231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 988231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** 989918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana * Called when a sync is starting. Supply a valid ActiveSyncContext with information 990918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana * about the sync. 991231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn */ 992918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana public SyncInfo addActiveSync(SyncManager.ActiveSyncContext activeSyncContext) { 993918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana final SyncInfo syncInfo; 994231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn synchronized (mAuthorities) { 995918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 996918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana Log.v(TAG, "setActiveSync: account=" 997918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana + activeSyncContext.mSyncOperation.account 998918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana + " auth=" + activeSyncContext.mSyncOperation.authority 999918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana + " src=" + activeSyncContext.mSyncOperation.syncSource 1000918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana + " extras=" + activeSyncContext.mSyncOperation.extras); 1001918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 1002918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana AuthorityInfo authority = getOrCreateAuthorityLocked( 1003918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana activeSyncContext.mSyncOperation.account, 100404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani activeSyncContext.mSyncOperation.userId, 1005918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana activeSyncContext.mSyncOperation.authority, 1006918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana -1 /* assign a new identifier if creating a new authority */, 1007918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana true /* write to storage if this results in a change */); 1008918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana syncInfo = new SyncInfo(authority.ident, 1009918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana authority.account, authority.authority, 1010918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana activeSyncContext.mStartTime); 101104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani getCurrentSyncs(authority.userId).add(syncInfo); 1012918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 1013918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana 1014918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana reportActiveChange(); 1015918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana return syncInfo; 1016918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 1017918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana 1018918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana /** 1019918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana * Called to indicate that a previously active sync is no longer active. 1020918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana */ 102104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public void removeActiveSync(SyncInfo syncInfo, int userId) { 1022918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana synchronized (mAuthorities) { 1023918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 102404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani Log.v(TAG, "removeActiveSync: account=" + syncInfo.account 102504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani + " user=" + userId 102604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani + " auth=" + syncInfo.authority); 10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 102804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani getCurrentSyncs(userId).remove(syncInfo); 10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1030360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 1031918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana reportActiveChange(); 10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1034231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** 1035231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * To allow others to send active change reports, to poke clients. 1036231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn */ 1037231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public void reportActiveChange() { 1038ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana reportChange(ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE); 1039231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1040360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 1041231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** 1042231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * Note that sync has started for the given account and authority. 1043231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn */ 104404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public long insertStartSyncEvent(Account accountName, int userId, String authorityName, 1045dc47556cb37b6f25faceb5eb97cef60d384b55fbFred Quintana long now, int source, boolean initialization) { 1046231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn long id; 1047231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn synchronized (mAuthorities) { 104877c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 104904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani Log.v(TAG, "insertStartSyncEvent: account=" + accountName + "user=" + userId 1050231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn + " auth=" + authorityName + " source=" + source); 105177c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana } 105204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani AuthorityInfo authority = getAuthorityLocked(accountName, userId, authorityName, 1053231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn "insertStartSyncEvent"); 1054231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (authority == null) { 1055231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return -1; 1056231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1057231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn SyncHistoryItem item = new SyncHistoryItem(); 1058dc47556cb37b6f25faceb5eb97cef60d384b55fbFred Quintana item.initialization = initialization; 1059231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn item.authorityId = authority.ident; 1060231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn item.historyId = mNextHistoryId++; 1061231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (mNextHistoryId < 0) mNextHistoryId = 0; 1062231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn item.eventTime = now; 1063231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn item.source = source; 1064231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn item.event = EVENT_START; 1065231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mSyncHistory.add(0, item); 1066231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn while (mSyncHistory.size() > MAX_HISTORY) { 1067231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mSyncHistory.remove(mSyncHistory.size()-1); 1068231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1069231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn id = item.historyId; 107077c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "returning historyId " + id); 10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1072360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 1073ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana reportChange(ContentResolver.SYNC_OBSERVER_TYPE_STATUS); 1074231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return id; 10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1077c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana public static boolean equals(Bundle b1, Bundle b2) { 1078c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana if (b1.size() != b2.size()) { 1079c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana return false; 1080c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1081c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana if (b1.isEmpty()) { 1082c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana return true; 1083c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1084c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana for (String key : b1.keySet()) { 1085c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana if (!b2.containsKey(key)) { 1086c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana return false; 1087c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1088c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana if (!b1.get(key).equals(b2.get(key))) { 1089c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana return false; 1090c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1091c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1092c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana return true; 1093c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1094c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 109577c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana public void stopSyncEvent(long historyId, long elapsedTime, String resultMessage, 1096231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn long downstreamActivity, long upstreamActivity) { 1097231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn synchronized (mAuthorities) { 109877c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 109977c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana Log.v(TAG, "stopSyncEvent: historyId=" + historyId); 110077c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana } 1101231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn SyncHistoryItem item = null; 1102231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn int i = mSyncHistory.size(); 1103231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn while (i > 0) { 1104231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn i--; 1105231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn item = mSyncHistory.get(i); 1106231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (item.historyId == historyId) { 1107231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn break; 1108231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1109231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn item = null; 1110231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1111360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 1112231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (item == null) { 1113231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn Log.w(TAG, "stopSyncEvent: no history for id " + historyId); 1114231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return; 1115231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1116360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 1117231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn item.elapsedTime = elapsedTime; 1118231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn item.event = EVENT_STOP; 1119231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn item.mesg = resultMessage; 1120231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn item.downstreamActivity = downstreamActivity; 1121231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn item.upstreamActivity = upstreamActivity; 1122360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 1123231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn SyncStatusInfo status = getOrCreateSyncStatusLocked(item.authorityId); 1124360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 1125231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn status.numSyncs++; 1126231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn status.totalElapsedTime += elapsedTime; 1127231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn switch (item.source) { 1128231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn case SOURCE_LOCAL: 1129231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn status.numSourceLocal++; 1130231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn break; 1131231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn case SOURCE_POLL: 1132231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn status.numSourcePoll++; 1133231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn break; 1134231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn case SOURCE_USER: 1135231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn status.numSourceUser++; 1136231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn break; 1137231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn case SOURCE_SERVER: 1138231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn status.numSourceServer++; 1139231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn break; 1140c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana case SOURCE_PERIODIC: 1141c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana status.numSourcePeriodic++; 1142c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana break; 1143231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1144360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 1145231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn boolean writeStatisticsNow = false; 114655280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn int day = getCurrentDayLocked(); 1147231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (mDayStats[0] == null) { 1148231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mDayStats[0] = new DayStats(day); 1149231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } else if (day != mDayStats[0].day) { 1150231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn System.arraycopy(mDayStats, 0, mDayStats, 1, mDayStats.length-1); 1151231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mDayStats[0] = new DayStats(day); 1152231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn writeStatisticsNow = true; 1153231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } else if (mDayStats[0] == null) { 1154231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1155231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn final DayStats ds = mDayStats[0]; 1156360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 1157231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn final long lastSyncTime = (item.eventTime + elapsedTime); 1158231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn boolean writeStatusNow = false; 1159231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (MESG_SUCCESS.equals(resultMessage)) { 1160231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn // - if successful, update the successful columns 1161231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (status.lastSuccessTime == 0 || status.lastFailureTime != 0) { 1162231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn writeStatusNow = true; 1163231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1164231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn status.lastSuccessTime = lastSyncTime; 1165231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn status.lastSuccessSource = item.source; 1166231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn status.lastFailureTime = 0; 1167231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn status.lastFailureSource = -1; 1168231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn status.lastFailureMesg = null; 1169231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn status.initialFailureTime = 0; 1170231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn ds.successCount++; 1171231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn ds.successTime += elapsedTime; 1172231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } else if (!MESG_CANCELED.equals(resultMessage)) { 1173231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (status.lastFailureTime == 0) { 1174231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn writeStatusNow = true; 1175231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1176231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn status.lastFailureTime = lastSyncTime; 1177231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn status.lastFailureSource = item.source; 1178231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn status.lastFailureMesg = resultMessage; 1179231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (status.initialFailureTime == 0) { 1180231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn status.initialFailureTime = lastSyncTime; 1181231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1182231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn ds.failureCount++; 1183231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn ds.failureTime += elapsedTime; 1184231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1185360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 1186231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (writeStatusNow) { 1187231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn writeStatusLocked(); 1188231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } else if (!hasMessages(MSG_WRITE_STATUS)) { 1189231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn sendMessageDelayed(obtainMessage(MSG_WRITE_STATUS), 1190231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn WRITE_STATUS_DELAY); 1191231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1192231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (writeStatisticsNow) { 1193231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn writeStatisticsLocked(); 1194231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } else if (!hasMessages(MSG_WRITE_STATISTICS)) { 1195231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn sendMessageDelayed(obtainMessage(MSG_WRITE_STATISTICS), 1196231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn WRITE_STATISTICS_DELAY); 1197360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache } 11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1199360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 1200ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana reportChange(ContentResolver.SYNC_OBSERVER_TYPE_STATUS); 12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1204918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana * Return a list of the currently active syncs. Note that the returned items are the 1205918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana * real, live active sync objects, so be careful what you do with it. 1206918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana */ 120704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public List<SyncInfo> getCurrentSyncs(int userId) { 1208918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana synchronized (mAuthorities) { 120904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani ArrayList<SyncInfo> syncs = mCurrentSyncs.get(userId); 121004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani if (syncs == null) { 121104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani syncs = new ArrayList<SyncInfo>(); 121204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani mCurrentSyncs.put(userId, syncs); 121304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 12141b6ae002a5ccb4f1e06b8a2971edef2140a35a3cAmith Yamasani return syncs; 1215231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1217360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 1218231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** 1219231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * Return an array of the current sync status for all authorities. Note 1220231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * that the objects inside the array are the real, live status objects, 1221231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * so be careful what you do with them. 1222231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn */ 1223231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public ArrayList<SyncStatusInfo> getSyncStatus() { 1224231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn synchronized (mAuthorities) { 1225231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn final int N = mSyncStatus.size(); 1226231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn ArrayList<SyncStatusInfo> ops = new ArrayList<SyncStatusInfo>(N); 1227231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn for (int i=0; i<N; i++) { 1228231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn ops.add(mSyncStatus.valueAt(i)); 12299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1230231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return ops; 12319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1233360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 1234231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** 1235c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * Return an array of the current authorities. Note 1236c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * that the objects inside the array are the real, live objects, 1237c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * so be careful what you do with them. 1238c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana */ 1239c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana public ArrayList<AuthorityInfo> getAuthorities() { 1240c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana synchronized (mAuthorities) { 1241c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana final int N = mAuthorities.size(); 1242c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana ArrayList<AuthorityInfo> infos = new ArrayList<AuthorityInfo>(N); 1243c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana for (int i=0; i<N; i++) { 12443aca7d7bec4b48bc68480b9d6b0ccdabf6903dfbCarlos Valdivia // Make deep copy because AuthorityInfo syncs are liable to change. 12453aca7d7bec4b48bc68480b9d6b0ccdabf6903dfbCarlos Valdivia infos.add(new AuthorityInfo(mAuthorities.valueAt(i))); 1246c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1247c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana return infos; 1248c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1249c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1250c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 1251c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana /** 1252b752098e8d12d6e7925d97458078dbb896ca8a05Costin Manolache * Returns the status that matches the authority and account. 1253b752098e8d12d6e7925d97458078dbb896ca8a05Costin Manolache * 1254b752098e8d12d6e7925d97458078dbb896ca8a05Costin Manolache * @param account the account we want to check 1255231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * @param authority the authority whose row should be selected 1256c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @return the SyncStatusInfo for the authority 1257231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn */ 125804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public SyncStatusInfo getStatusByAccountAndAuthority(Account account, int userId, 125904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String authority) { 1260b752098e8d12d6e7925d97458078dbb896ca8a05Costin Manolache if (account == null || authority == null) { 1261b752098e8d12d6e7925d97458078dbb896ca8a05Costin Manolache throw new IllegalArgumentException(); 1262b752098e8d12d6e7925d97458078dbb896ca8a05Costin Manolache } 1263231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn synchronized (mAuthorities) { 1264231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn final int N = mSyncStatus.size(); 1265231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn for (int i=0; i<N; i++) { 1266360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache SyncStatusInfo cur = mSyncStatus.valueAt(i); 1267231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn AuthorityInfo ainfo = mAuthorities.get(cur.authorityId); 1268b752098e8d12d6e7925d97458078dbb896ca8a05Costin Manolache 126904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani if (ainfo != null && ainfo.authority.equals(authority) 127004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani && ainfo.userId == userId 127104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani && account.equals(ainfo.account)) { 1272b752098e8d12d6e7925d97458078dbb896ca8a05Costin Manolache return cur; 1273231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1274231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1275b752098e8d12d6e7925d97458078dbb896ca8a05Costin Manolache return null; 1276231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1278360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 1279231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** 1280231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * Return true if the pending status is true of any matching authorities. 1281231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn */ 128204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public boolean isSyncPending(Account account, int userId, String authority) { 1283231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn synchronized (mAuthorities) { 1284231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn final int N = mSyncStatus.size(); 1285231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn for (int i=0; i<N; i++) { 1286360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache SyncStatusInfo cur = mSyncStatus.valueAt(i); 1287231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn AuthorityInfo ainfo = mAuthorities.get(cur.authorityId); 1288231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (ainfo == null) { 1289231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn continue; 1290231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 129104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani if (userId != ainfo.userId) { 129204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani continue; 129304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 1294231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (account != null && !ainfo.account.equals(account)) { 1295231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn continue; 1296231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1297231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (ainfo.authority.equals(authority) && cur.pending) { 1298231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return true; 12999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1301231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return false; 13029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1306231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * Return an array of the current sync status for all authorities. Note 1307231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * that the objects inside the array are the real, live status objects, 1308231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * so be careful what you do with them. 1309231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn */ 1310231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public ArrayList<SyncHistoryItem> getSyncHistory() { 1311231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn synchronized (mAuthorities) { 1312231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn final int N = mSyncHistory.size(); 1313231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn ArrayList<SyncHistoryItem> items = new ArrayList<SyncHistoryItem>(N); 1314231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn for (int i=0; i<N; i++) { 1315231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn items.add(mSyncHistory.get(i)); 1316231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1317231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return items; 1318231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1319231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1320360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 1321231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** 1322231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * Return an array of the current per-day statistics. Note 1323231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * that the objects inside the array are the real, live status objects, 1324231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * so be careful what you do with them. 1325231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn */ 1326231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public DayStats[] getDayStatistics() { 1327231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn synchronized (mAuthorities) { 1328231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn DayStats[] ds = new DayStats[mDayStats.length]; 1329231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn System.arraycopy(mDayStats, 0, ds, 0, ds.length); 1330231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return ds; 1331231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1332231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1333360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 133455280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn private int getCurrentDayLocked() { 1335231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mCal.setTimeInMillis(System.currentTimeMillis()); 1336231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn final int dayOfYear = mCal.get(Calendar.DAY_OF_YEAR); 1337231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (mYear != mCal.get(Calendar.YEAR)) { 1338231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mYear = mCal.get(Calendar.YEAR); 1339231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mCal.clear(); 1340231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mCal.set(Calendar.YEAR, mYear); 1341231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mYearInDays = (int)(mCal.getTimeInMillis()/86400000); 1342231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1343231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return dayOfYear + mYearInDays; 1344231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1345360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 1346231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** 1347231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * Retrieve an authority, returning null if one does not exist. 1348360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache * 1349231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * @param accountName The name of the account for the authority. 1350231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * @param authorityName The name of the authority itself. 1351231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * @param tag If non-null, this will be used in a log message if the 1352231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * requested authority does not exist. 1353231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn */ 135404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private AuthorityInfo getAuthorityLocked(Account accountName, int userId, String authorityName, 1355231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn String tag) { 135604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani AccountAndUser au = new AccountAndUser(accountName, userId); 135704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani AccountInfo accountInfo = mAccounts.get(au); 135804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani if (accountInfo == null) { 1359231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (tag != null) { 1360b763ab265130b5aa59e4de561ba3836ac294fe62Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 136104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani Log.v(TAG, tag + ": unknown account " + au); 1362b763ab265130b5aa59e4de561ba3836ac294fe62Fred Quintana } 1363231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1364231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return null; 1365231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 136604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani AuthorityInfo authority = accountInfo.authorities.get(authorityName); 1367231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (authority == null) { 1368231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (tag != null) { 1369b763ab265130b5aa59e4de561ba3836ac294fe62Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1370b763ab265130b5aa59e4de561ba3836ac294fe62Fred Quintana Log.v(TAG, tag + ": unknown authority " + authorityName); 1371b763ab265130b5aa59e4de561ba3836ac294fe62Fred Quintana } 1372231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1373231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return null; 1374231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1375360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 1376231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return authority; 1377231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1378360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 137904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private AuthorityInfo getOrCreateAuthorityLocked(Account accountName, int userId, 1380231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn String authorityName, int ident, boolean doWrite) { 138104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani AccountAndUser au = new AccountAndUser(accountName, userId); 138204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani AccountInfo account = mAccounts.get(au); 1383231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (account == null) { 138404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani account = new AccountInfo(au); 138504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani mAccounts.put(au, account); 1386231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1387231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn AuthorityInfo authority = account.authorities.get(authorityName); 1388231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (authority == null) { 1389231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (ident < 0) { 139077c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana ident = mNextAuthorityId; 139177c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana mNextAuthorityId++; 139277c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana doWrite = true; 1393231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 139477c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 139577c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana Log.v(TAG, "created a new AuthorityInfo for " + accountName 139604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani + ", user " + userId 139704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani + ", provider " + authorityName); 139877c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana } 139904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani authority = new AuthorityInfo(accountName, userId, authorityName, ident); 1400231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn account.authorities.put(authorityName, authority); 1401231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mAuthorities.put(ident, authority); 1402231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (doWrite) { 1403231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn writeAccountInfoLocked(); 1404231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1405231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1406360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 1407231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return authority; 1408231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1409360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 141004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void removeAuthorityLocked(Account account, int userId, String authorityName, 141104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani boolean doWrite) { 141204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani AccountInfo accountInfo = mAccounts.get(new AccountAndUser(account, userId)); 14137620f1ae498e01bf2df58eaa1b9b20ef1eb47fa1Fred Quintana if (accountInfo != null) { 1414fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana final AuthorityInfo authorityInfo = accountInfo.authorities.remove(authorityName); 1415fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana if (authorityInfo != null) { 1416fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana mAuthorities.remove(authorityInfo.ident); 141777c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana if (doWrite) { 141877c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana writeAccountInfoLocked(); 141977c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana } 14207620f1ae498e01bf2df58eaa1b9b20ef1eb47fa1Fred Quintana } 14217620f1ae498e01bf2df58eaa1b9b20ef1eb47fa1Fred Quintana } 14227620f1ae498e01bf2df58eaa1b9b20ef1eb47fa1Fred Quintana } 14237620f1ae498e01bf2df58eaa1b9b20ef1eb47fa1Fred Quintana 1424c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana public SyncStatusInfo getOrCreateSyncStatus(AuthorityInfo authority) { 1425c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana synchronized (mAuthorities) { 1426c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana return getOrCreateSyncStatusLocked(authority.ident); 1427c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1428c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1429c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 1430231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private SyncStatusInfo getOrCreateSyncStatusLocked(int authorityId) { 1431231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn SyncStatusInfo status = mSyncStatus.get(authorityId); 1432231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (status == null) { 1433231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn status = new SyncStatusInfo(authorityId); 1434231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mSyncStatus.put(authorityId, status); 1435231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1436231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return status; 1437231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1438360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 143955280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn public void writeAllState() { 144055280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn synchronized (mAuthorities) { 144155280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn // Account info is always written so no need to do it here. 1442360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 144355280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn if (mNumPendingFinished > 0) { 144455280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn // Only write these if they are out of date. 144555280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn writePendingOperationsLocked(); 144655280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn } 1447360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 144855280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn // Just always write these... they are likely out of date. 144955280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn writeStatusLocked(); 145055280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn writeStatisticsLocked(); 145155280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn } 145255280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn } 1453360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 1454231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** 1455c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * public for testing 1456c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana */ 1457c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana public void clearAndReadState() { 1458c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana synchronized (mAuthorities) { 1459c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana mAuthorities.clear(); 1460c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana mAccounts.clear(); 1461c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana mPendingOperations.clear(); 1462c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana mSyncStatus.clear(); 1463c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana mSyncHistory.clear(); 1464c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 1465c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana readAccountInfoLocked(); 1466c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana readStatusLocked(); 1467c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana readPendingOperationsLocked(); 1468c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana readStatisticsLocked(); 146977c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana readAndDeleteLegacyAccountInfoLocked(); 147077c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana writeAccountInfoLocked(); 147177c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana writeStatusLocked(); 147277c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana writePendingOperationsLocked(); 147377c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana writeStatisticsLocked(); 1474c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1475c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1476c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 1477c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana /** 1478231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * Read all account information back in to the initial engine state. 1479231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn */ 1480231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private void readAccountInfoLocked() { 148177c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana int highestAuthorityId = -1; 1482231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn FileInputStream fis = null; 14839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1484231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn fis = mAccountInfoFile.openRead(); 1485231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (DEBUG_FILE) Log.v(TAG, "Reading " + mAccountInfoFile.getBaseFile()); 1486231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn XmlPullParser parser = Xml.newPullParser(); 1487231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn parser.setInput(fis, null); 1488231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn int eventType = parser.getEventType(); 1489231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn while (eventType != XmlPullParser.START_TAG) { 1490231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn eventType = parser.next(); 1491231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1492231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn String tagName = parser.getName(); 1493231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if ("accounts".equals(tagName)) { 149404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String listen = parser.getAttributeValue(null, XML_ATTR_LISTEN_FOR_TICKLES); 1495c2e4691d788088b22eadc9b2d35e9bdf0b6a0ffcFred Quintana String versionString = parser.getAttributeValue(null, "version"); 1496c2e4691d788088b22eadc9b2d35e9bdf0b6a0ffcFred Quintana int version; 1497c2e4691d788088b22eadc9b2d35e9bdf0b6a0ffcFred Quintana try { 1498c2e4691d788088b22eadc9b2d35e9bdf0b6a0ffcFred Quintana version = (versionString == null) ? 0 : Integer.parseInt(versionString); 1499c2e4691d788088b22eadc9b2d35e9bdf0b6a0ffcFred Quintana } catch (NumberFormatException e) { 1500c2e4691d788088b22eadc9b2d35e9bdf0b6a0ffcFred Quintana version = 0; 1501c2e4691d788088b22eadc9b2d35e9bdf0b6a0ffcFred Quintana } 150204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String nextIdString = parser.getAttributeValue(null, XML_ATTR_NEXT_AUTHORITY_ID); 150377c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana try { 150477c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana int id = (nextIdString == null) ? 0 : Integer.parseInt(nextIdString); 150577c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana mNextAuthorityId = Math.max(mNextAuthorityId, id); 150677c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana } catch (NumberFormatException e) { 150777c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana // don't care 1508c2e4691d788088b22eadc9b2d35e9bdf0b6a0ffcFred Quintana } 150969d95de53bc82e6c23c64ad566e428fbefae0543Ashish Sharma String offsetString = parser.getAttributeValue(null, XML_ATTR_SYNC_RANDOM_OFFSET); 151069d95de53bc82e6c23c64ad566e428fbefae0543Ashish Sharma try { 151169d95de53bc82e6c23c64ad566e428fbefae0543Ashish Sharma mSyncRandomOffset = (offsetString == null) ? 0 : Integer.parseInt(offsetString); 151269d95de53bc82e6c23c64ad566e428fbefae0543Ashish Sharma } catch (NumberFormatException e) { 151369d95de53bc82e6c23c64ad566e428fbefae0543Ashish Sharma mSyncRandomOffset = 0; 151469d95de53bc82e6c23c64ad566e428fbefae0543Ashish Sharma } 151569d95de53bc82e6c23c64ad566e428fbefae0543Ashish Sharma if (mSyncRandomOffset == 0) { 151669d95de53bc82e6c23c64ad566e428fbefae0543Ashish Sharma Random random = new Random(System.currentTimeMillis()); 151769d95de53bc82e6c23c64ad566e428fbefae0543Ashish Sharma mSyncRandomOffset = random.nextInt(86400); 151869d95de53bc82e6c23c64ad566e428fbefae0543Ashish Sharma } 151904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani mMasterSyncAutomatically.put(0, listen == null || Boolean.parseBoolean(listen)); 1520231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn eventType = parser.next(); 1521c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana AuthorityInfo authority = null; 1522c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana Pair<Bundle, Long> periodicSync = null; 1523231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn do { 1524c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana if (eventType == XmlPullParser.START_TAG) { 1525231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn tagName = parser.getName(); 1526c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana if (parser.getDepth() == 2) { 1527c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana if ("authority".equals(tagName)) { 1528c2e4691d788088b22eadc9b2d35e9bdf0b6a0ffcFred Quintana authority = parseAuthority(parser, version); 1529c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana periodicSync = null; 153077c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana if (authority.ident > highestAuthorityId) { 153177c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana highestAuthorityId = authority.ident; 153277c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana } 153304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } else if (XML_TAG_LISTEN_FOR_TICKLES.equals(tagName)) { 153404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani parseListenForTickles(parser); 1535231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1536c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } else if (parser.getDepth() == 3) { 1537c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana if ("periodicSync".equals(tagName) && authority != null) { 1538c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana periodicSync = parsePeriodicSync(parser, authority); 1539c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1540c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } else if (parser.getDepth() == 4 && periodicSync != null) { 1541c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana if ("extra".equals(tagName)) { 1542c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana parseExtra(parser, periodicSync); 1543231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1544231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1545231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1546231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn eventType = parser.next(); 1547231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } while (eventType != XmlPullParser.END_DOCUMENT); 1548231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1549231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } catch (XmlPullParserException e) { 1550231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn Log.w(TAG, "Error reading accounts", e); 1551c2e4691d788088b22eadc9b2d35e9bdf0b6a0ffcFred Quintana return; 1552231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } catch (java.io.IOException e) { 1553231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (fis == null) Log.i(TAG, "No initial accounts"); 1554231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn else Log.w(TAG, "Error reading accounts", e); 1555c2e4691d788088b22eadc9b2d35e9bdf0b6a0ffcFred Quintana return; 1556231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } finally { 155777c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana mNextAuthorityId = Math.max(highestAuthorityId + 1, mNextAuthorityId); 1558231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (fis != null) { 1559231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn try { 1560231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn fis.close(); 1561231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } catch (java.io.IOException e1) { 1562231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1563231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1564231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1565c2e4691d788088b22eadc9b2d35e9bdf0b6a0ffcFred Quintana 156677c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana maybeMigrateSettingsForRenamedAuthorities(); 1567231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1568360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 1569fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana /** 1570fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana * some authority names have changed. copy over their settings and delete the old ones 1571fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana * @return true if a change was made 1572fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana */ 1573fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana private boolean maybeMigrateSettingsForRenamedAuthorities() { 1574fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana boolean writeNeeded = false; 1575fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana 1576fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana ArrayList<AuthorityInfo> authoritiesToRemove = new ArrayList<AuthorityInfo>(); 1577fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana final int N = mAuthorities.size(); 1578fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana for (int i=0; i<N; i++) { 1579fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana AuthorityInfo authority = mAuthorities.valueAt(i); 1580fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana // skip this authority if it isn't one of the renamed ones 1581fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana final String newAuthorityName = sAuthorityRenames.get(authority.authority); 1582fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana if (newAuthorityName == null) { 1583fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana continue; 1584fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana } 1585fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana 1586fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana // remember this authority so we can remove it later. we can't remove it 1587fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana // now without messing up this loop iteration 1588fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana authoritiesToRemove.add(authority); 1589fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana 1590fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana // this authority isn't enabled, no need to copy it to the new authority name since 1591fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana // the default is "disabled" 1592fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana if (!authority.enabled) { 1593fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana continue; 1594fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana } 1595fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana 1596fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana // if we already have a record of this new authority then don't copy over the settings 159704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani if (getAuthorityLocked(authority.account, authority.userId, newAuthorityName, "cleanup") 159804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani != null) { 1599fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana continue; 1600fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana } 1601fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana 1602fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana AuthorityInfo newAuthority = getOrCreateAuthorityLocked(authority.account, 160304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani authority.userId, newAuthorityName, -1 /* ident */, false /* doWrite */); 1604fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana newAuthority.enabled = true; 1605fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana writeNeeded = true; 1606fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana } 1607fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana 1608fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana for (AuthorityInfo authorityInfo : authoritiesToRemove) { 160904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani removeAuthorityLocked(authorityInfo.account, authorityInfo.userId, 161004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani authorityInfo.authority, false /* doWrite */); 1611fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana writeNeeded = true; 1612fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana } 1613fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana 1614fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana return writeNeeded; 1615fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana } 1616fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana 161704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void parseListenForTickles(XmlPullParser parser) { 161804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String user = parser.getAttributeValue(null, XML_ATTR_USER); 161904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani int userId = 0; 162004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani try { 162104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani userId = Integer.parseInt(user); 162204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } catch (NumberFormatException e) { 162304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani Log.e(TAG, "error parsing the user for listen-for-tickles", e); 162404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } catch (NullPointerException e) { 162504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani Log.e(TAG, "the user in listen-for-tickles is null", e); 162604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 162704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String enabled = parser.getAttributeValue(null, XML_ATTR_ENABLED); 162804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani boolean listen = enabled == null || Boolean.parseBoolean(enabled); 162904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani mMasterSyncAutomatically.put(userId, listen); 163004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 163104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 1632c2e4691d788088b22eadc9b2d35e9bdf0b6a0ffcFred Quintana private AuthorityInfo parseAuthority(XmlPullParser parser, int version) { 1633c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana AuthorityInfo authority = null; 1634c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana int id = -1; 1635c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana try { 1636c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana id = Integer.parseInt(parser.getAttributeValue( 1637c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana null, "id")); 1638c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } catch (NumberFormatException e) { 1639c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana Log.e(TAG, "error parsing the id of the authority", e); 1640c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } catch (NullPointerException e) { 1641c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana Log.e(TAG, "the id of the authority is null", e); 1642c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1643c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana if (id >= 0) { 1644fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana String authorityName = parser.getAttributeValue(null, "authority"); 164504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String enabled = parser.getAttributeValue(null, XML_ATTR_ENABLED); 1646fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana String syncable = parser.getAttributeValue(null, "syncable"); 1647c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana String accountName = parser.getAttributeValue(null, "account"); 1648c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana String accountType = parser.getAttributeValue(null, "type"); 164904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String user = parser.getAttributeValue(null, XML_ATTR_USER); 165004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani int userId = user == null ? 0 : Integer.parseInt(user); 1651c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana if (accountType == null) { 1652c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana accountType = "com.google"; 1653fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana syncable = "unknown"; 1654c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1655c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana authority = mAuthorities.get(id); 1656c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana if (DEBUG_FILE) Log.v(TAG, "Adding authority: account=" 1657c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana + accountName + " auth=" + authorityName 165804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani + " user=" + userId 1659c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana + " enabled=" + enabled 1660c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana + " syncable=" + syncable); 1661c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana if (authority == null) { 1662c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana if (DEBUG_FILE) Log.v(TAG, "Creating entry"); 1663c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana authority = getOrCreateAuthorityLocked( 166404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new Account(accountName, accountType), userId, authorityName, id, false); 1665c2e4691d788088b22eadc9b2d35e9bdf0b6a0ffcFred Quintana // If the version is 0 then we are upgrading from a file format that did not 1666c2e4691d788088b22eadc9b2d35e9bdf0b6a0ffcFred Quintana // know about periodic syncs. In that case don't clear the list since we 1667c2e4691d788088b22eadc9b2d35e9bdf0b6a0ffcFred Quintana // want the default, which is a daily periodioc sync. 1668c2e4691d788088b22eadc9b2d35e9bdf0b6a0ffcFred Quintana // Otherwise clear out this default list since we will populate it later with 1669c2e4691d788088b22eadc9b2d35e9bdf0b6a0ffcFred Quintana // the periodic sync descriptions that are read from the configuration file. 1670c2e4691d788088b22eadc9b2d35e9bdf0b6a0ffcFred Quintana if (version > 0) { 1671c2e4691d788088b22eadc9b2d35e9bdf0b6a0ffcFred Quintana authority.periodicSyncs.clear(); 1672c2e4691d788088b22eadc9b2d35e9bdf0b6a0ffcFred Quintana } 1673c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1674c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana if (authority != null) { 1675c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana authority.enabled = enabled == null || Boolean.parseBoolean(enabled); 1676c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana if ("unknown".equals(syncable)) { 1677c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana authority.syncable = -1; 1678c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } else { 1679c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana authority.syncable = 1680fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana (syncable == null || Boolean.parseBoolean(syncable)) ? 1 : 0; 1681c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1682c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } else { 1683c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana Log.w(TAG, "Failure adding authority: account=" 1684c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana + accountName + " auth=" + authorityName 1685c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana + " enabled=" + enabled 1686c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana + " syncable=" + syncable); 1687c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1688c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1689c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 1690c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana return authority; 1691c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1692c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 1693c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana private Pair<Bundle, Long> parsePeriodicSync(XmlPullParser parser, AuthorityInfo authority) { 1694c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana Bundle extras = new Bundle(); 1695c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana String periodValue = parser.getAttributeValue(null, "period"); 1696c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana final long period; 1697c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana try { 1698c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana period = Long.parseLong(periodValue); 1699c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } catch (NumberFormatException e) { 1700c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana Log.e(TAG, "error parsing the period of a periodic sync", e); 1701c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana return null; 1702c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } catch (NullPointerException e) { 1703c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana Log.e(TAG, "the period of a periodic sync is null", e); 1704c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana return null; 1705c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1706c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana final Pair<Bundle, Long> periodicSync = Pair.create(extras, period); 1707c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana authority.periodicSyncs.add(periodicSync); 1708c2e4691d788088b22eadc9b2d35e9bdf0b6a0ffcFred Quintana 1709c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana return periodicSync; 1710c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1711c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 1712c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana private void parseExtra(XmlPullParser parser, Pair<Bundle, Long> periodicSync) { 1713c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana final Bundle extras = periodicSync.first; 1714c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana String name = parser.getAttributeValue(null, "name"); 1715c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana String type = parser.getAttributeValue(null, "type"); 1716c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana String value1 = parser.getAttributeValue(null, "value1"); 1717c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana String value2 = parser.getAttributeValue(null, "value2"); 1718c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 1719c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana try { 1720c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana if ("long".equals(type)) { 1721c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana extras.putLong(name, Long.parseLong(value1)); 1722c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } else if ("integer".equals(type)) { 1723c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana extras.putInt(name, Integer.parseInt(value1)); 1724c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } else if ("double".equals(type)) { 1725c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana extras.putDouble(name, Double.parseDouble(value1)); 1726c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } else if ("float".equals(type)) { 1727c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana extras.putFloat(name, Float.parseFloat(value1)); 1728c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } else if ("boolean".equals(type)) { 1729c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana extras.putBoolean(name, Boolean.parseBoolean(value1)); 1730c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } else if ("string".equals(type)) { 1731c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana extras.putString(name, value1); 1732c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } else if ("account".equals(type)) { 1733c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana extras.putParcelable(name, new Account(value1, value2)); 1734c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1735c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } catch (NumberFormatException e) { 1736c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana Log.e(TAG, "error parsing bundle value", e); 1737c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } catch (NullPointerException e) { 1738c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana Log.e(TAG, "error parsing bundle value", e); 1739c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1740c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1741c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 1742231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** 1743231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * Write all account information to the account file. 1744231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn */ 1745231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private void writeAccountInfoLocked() { 1746231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (DEBUG_FILE) Log.v(TAG, "Writing new " + mAccountInfoFile.getBaseFile()); 1747231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn FileOutputStream fos = null; 1748360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 1749231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn try { 1750231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn fos = mAccountInfoFile.startWrite(); 1751231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn XmlSerializer out = new FastXmlSerializer(); 1752231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn out.setOutput(fos, "utf-8"); 1753231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn out.startDocument(null, true); 1754231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); 1755360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 1756231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn out.startTag(null, "accounts"); 1757c2e4691d788088b22eadc9b2d35e9bdf0b6a0ffcFred Quintana out.attribute(null, "version", Integer.toString(ACCOUNTS_VERSION)); 175804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani out.attribute(null, XML_ATTR_NEXT_AUTHORITY_ID, Integer.toString(mNextAuthorityId)); 175969d95de53bc82e6c23c64ad566e428fbefae0543Ashish Sharma out.attribute(null, XML_ATTR_SYNC_RANDOM_OFFSET, Integer.toString(mSyncRandomOffset)); 176004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 176104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani // Write the Sync Automatically flags for each user 176204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final int M = mMasterSyncAutomatically.size(); 176304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani for (int m = 0; m < M; m++) { 176404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani int userId = mMasterSyncAutomatically.keyAt(m); 176504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani Boolean listen = mMasterSyncAutomatically.valueAt(m); 176604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani out.startTag(null, XML_TAG_LISTEN_FOR_TICKLES); 176704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani out.attribute(null, XML_ATTR_USER, Integer.toString(userId)); 176804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani out.attribute(null, XML_ATTR_ENABLED, Boolean.toString(listen)); 176904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani out.endTag(null, XML_TAG_LISTEN_FOR_TICKLES); 1770231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1771360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 1772231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn final int N = mAuthorities.size(); 1773231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn for (int i=0; i<N; i++) { 1774360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache AuthorityInfo authority = mAuthorities.valueAt(i); 1775231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn out.startTag(null, "authority"); 1776231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn out.attribute(null, "id", Integer.toString(authority.ident)); 1777ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana out.attribute(null, "account", authority.account.name); 177804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani out.attribute(null, XML_ATTR_USER, Integer.toString(authority.userId)); 1779ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana out.attribute(null, "type", authority.account.type); 1780231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn out.attribute(null, "authority", authority.authority); 178104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani out.attribute(null, XML_ATTR_ENABLED, Boolean.toString(authority.enabled)); 17825e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana if (authority.syncable < 0) { 17835e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana out.attribute(null, "syncable", "unknown"); 1784fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana } else { 1785fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana out.attribute(null, "syncable", Boolean.toString(authority.syncable != 0)); 17865e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 1787c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana for (Pair<Bundle, Long> periodicSync : authority.periodicSyncs) { 1788c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana out.startTag(null, "periodicSync"); 1789c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana out.attribute(null, "period", Long.toString(periodicSync.second)); 1790c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana final Bundle extras = periodicSync.first; 1791c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana for (String key : extras.keySet()) { 1792c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana out.startTag(null, "extra"); 1793c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana out.attribute(null, "name", key); 1794c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana final Object value = extras.get(key); 1795c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana if (value instanceof Long) { 1796c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana out.attribute(null, "type", "long"); 1797c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana out.attribute(null, "value1", value.toString()); 1798c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } else if (value instanceof Integer) { 1799c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana out.attribute(null, "type", "integer"); 1800c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana out.attribute(null, "value1", value.toString()); 1801c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } else if (value instanceof Boolean) { 1802c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana out.attribute(null, "type", "boolean"); 1803c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana out.attribute(null, "value1", value.toString()); 1804c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } else if (value instanceof Float) { 1805c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana out.attribute(null, "type", "float"); 1806c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana out.attribute(null, "value1", value.toString()); 1807c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } else if (value instanceof Double) { 1808c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana out.attribute(null, "type", "double"); 1809c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana out.attribute(null, "value1", value.toString()); 1810c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } else if (value instanceof String) { 1811c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana out.attribute(null, "type", "string"); 1812c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana out.attribute(null, "value1", value.toString()); 1813c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } else if (value instanceof Account) { 1814c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana out.attribute(null, "type", "account"); 1815c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana out.attribute(null, "value1", ((Account)value).name); 1816c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana out.attribute(null, "value2", ((Account)value).type); 1817c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1818c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana out.endTag(null, "extra"); 1819c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1820c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana out.endTag(null, "periodicSync"); 1821c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1822231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn out.endTag(null, "authority"); 1823231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1824360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 1825231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn out.endTag(null, "accounts"); 1826360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 1827231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn out.endDocument(); 1828360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 1829231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mAccountInfoFile.finishWrite(fos); 1830231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } catch (java.io.IOException e1) { 1831231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn Log.w(TAG, "Error writing accounts", e1); 1832231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (fos != null) { 1833231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mAccountInfoFile.failWrite(fos); 1834231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1835231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1836231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1837360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 1838231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn static int getIntColumn(Cursor c, String name) { 1839231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return c.getInt(c.getColumnIndex(name)); 1840231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1841360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 1842231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn static long getLongColumn(Cursor c, String name) { 1843231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return c.getLong(c.getColumnIndex(name)); 1844231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1845360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 1846231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** 1847231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * Load sync engine state from the old syncmanager database, and then 1848231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * erase it. Note that we don't deal with pending operations, active 1849231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * sync, or history. 1850231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn */ 185177c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana private void readAndDeleteLegacyAccountInfoLocked() { 1852231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn // Look for old database to initialize from. 1853231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn File file = mContext.getDatabasePath("syncmanager.db"); 1854231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (!file.exists()) { 1855231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return; 1856231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1857231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn String path = file.getPath(); 1858231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn SQLiteDatabase db = null; 1859231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn try { 1860231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn db = SQLiteDatabase.openDatabase(path, null, 1861231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn SQLiteDatabase.OPEN_READONLY); 1862231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } catch (SQLiteException e) { 1863231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1864360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 1865231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (db != null) { 18662d5ed1fa3d29cdf1afb3bdfc3fc6a061f9f3feb3Dianne Hackborn final boolean hasType = db.getVersion() >= 11; 1867360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 1868231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn // Copy in all of the status information, as well as accounts. 1869231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (DEBUG_FILE) Log.v(TAG, "Reading legacy sync accounts db"); 1870231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); 1871231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn qb.setTables("stats, status"); 1872231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn HashMap<String,String> map = new HashMap<String,String>(); 1873231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn map.put("_id", "status._id as _id"); 1874231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn map.put("account", "stats.account as account"); 18752d5ed1fa3d29cdf1afb3bdfc3fc6a061f9f3feb3Dianne Hackborn if (hasType) { 18762d5ed1fa3d29cdf1afb3bdfc3fc6a061f9f3feb3Dianne Hackborn map.put("account_type", "stats.account_type as account_type"); 18772d5ed1fa3d29cdf1afb3bdfc3fc6a061f9f3feb3Dianne Hackborn } 1878231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn map.put("authority", "stats.authority as authority"); 1879231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn map.put("totalElapsedTime", "totalElapsedTime"); 1880231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn map.put("numSyncs", "numSyncs"); 1881231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn map.put("numSourceLocal", "numSourceLocal"); 1882231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn map.put("numSourcePoll", "numSourcePoll"); 1883231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn map.put("numSourceServer", "numSourceServer"); 1884231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn map.put("numSourceUser", "numSourceUser"); 1885231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn map.put("lastSuccessSource", "lastSuccessSource"); 1886231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn map.put("lastSuccessTime", "lastSuccessTime"); 1887231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn map.put("lastFailureSource", "lastFailureSource"); 1888231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn map.put("lastFailureTime", "lastFailureTime"); 1889231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn map.put("lastFailureMesg", "lastFailureMesg"); 1890231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn map.put("pending", "pending"); 1891231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn qb.setProjectionMap(map); 1892231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn qb.appendWhere("stats._id = status.stats_id"); 1893231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn Cursor c = qb.query(db, null, null, null, null, null, null); 18949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (c.moveToNext()) { 1895231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn String accountName = c.getString(c.getColumnIndex("account")); 18962d5ed1fa3d29cdf1afb3bdfc3fc6a061f9f3feb3Dianne Hackborn String accountType = hasType 18972d5ed1fa3d29cdf1afb3bdfc3fc6a061f9f3feb3Dianne Hackborn ? c.getString(c.getColumnIndex("account_type")) : null; 18987a1355950172b7a549820e9a2cd4a9b2099ec32fDianne Hackborn if (accountType == null) { 18993348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache accountType = "com.google"; 19009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1901231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn String authorityName = c.getString(c.getColumnIndex("authority")); 1902231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn AuthorityInfo authority = this.getOrCreateAuthorityLocked( 190304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new Account(accountName, accountType), 0 /* legacy is single-user */, 19047a1355950172b7a549820e9a2cd4a9b2099ec32fDianne Hackborn authorityName, -1, false); 1905231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (authority != null) { 1906231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn int i = mSyncStatus.size(); 1907231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn boolean found = false; 1908231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn SyncStatusInfo st = null; 1909231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn while (i > 0) { 1910231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn i--; 1911360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache st = mSyncStatus.valueAt(i); 1912231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (st.authorityId == authority.ident) { 1913231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn found = true; 1914231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn break; 1915231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1916231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1917231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (!found) { 1918231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn st = new SyncStatusInfo(authority.ident); 1919231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mSyncStatus.put(authority.ident, st); 1920231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1921231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn st.totalElapsedTime = getLongColumn(c, "totalElapsedTime"); 1922231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn st.numSyncs = getIntColumn(c, "numSyncs"); 1923231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn st.numSourceLocal = getIntColumn(c, "numSourceLocal"); 1924231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn st.numSourcePoll = getIntColumn(c, "numSourcePoll"); 1925231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn st.numSourceServer = getIntColumn(c, "numSourceServer"); 1926231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn st.numSourceUser = getIntColumn(c, "numSourceUser"); 1927c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana st.numSourcePeriodic = 0; 1928231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn st.lastSuccessSource = getIntColumn(c, "lastSuccessSource"); 1929231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn st.lastSuccessTime = getLongColumn(c, "lastSuccessTime"); 1930231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn st.lastFailureSource = getIntColumn(c, "lastFailureSource"); 1931231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn st.lastFailureTime = getLongColumn(c, "lastFailureTime"); 1932231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn st.lastFailureMesg = c.getString(c.getColumnIndex("lastFailureMesg")); 1933231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn st.pending = getIntColumn(c, "pending") != 0; 19349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1936360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 1937231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn c.close(); 1938360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 1939231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn // Retrieve the settings. 1940231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn qb = new SQLiteQueryBuilder(); 1941231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn qb.setTables("settings"); 1942231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn c = qb.query(db, null, null, null, null, null, null); 1943231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn while (c.moveToNext()) { 1944231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn String name = c.getString(c.getColumnIndex("name")); 1945231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn String value = c.getString(c.getColumnIndex("value")); 1946231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (name == null) continue; 1947231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (name.equals("listen_for_tickles")) { 194804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani setMasterSyncAutomatically(value == null || Boolean.parseBoolean(value), 0); 1949231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } else if (name.startsWith("sync_provider_")) { 1950231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn String provider = name.substring("sync_provider_".length(), 1951231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn name.length()); 1952ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana int i = mAuthorities.size(); 1953ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana while (i > 0) { 1954ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana i--; 1955360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache AuthorityInfo authority = mAuthorities.valueAt(i); 1956ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana if (authority.authority.equals(provider)) { 1957ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana authority.enabled = value == null || Boolean.parseBoolean(value); 19585e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana authority.syncable = 1; 1959ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1960ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 19619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1963360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 19649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project c.close(); 1965360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 1966231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn db.close(); 1967360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 1968231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn (new File(path)).delete(); 19699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1971360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 1972231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public static final int STATUS_FILE_END = 0; 1973231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public static final int STATUS_FILE_ITEM = 100; 1974360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 1975231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** 1976231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * Read all sync status back in to the initial engine state. 1977231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn */ 1978231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private void readStatusLocked() { 1979231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (DEBUG_FILE) Log.v(TAG, "Reading " + mStatusFile.getBaseFile()); 1980231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn try { 1981231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn byte[] data = mStatusFile.readFully(); 1982231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn Parcel in = Parcel.obtain(); 1983231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn in.unmarshall(data, 0, data.length); 1984231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn in.setDataPosition(0); 1985231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn int token; 1986231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn while ((token=in.readInt()) != STATUS_FILE_END) { 1987231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (token == STATUS_FILE_ITEM) { 1988231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn SyncStatusInfo status = new SyncStatusInfo(in); 1989231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (mAuthorities.indexOfKey(status.authorityId) >= 0) { 1990231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn status.pending = false; 1991231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (DEBUG_FILE) Log.v(TAG, "Adding status for id " 1992231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn + status.authorityId); 1993231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mSyncStatus.put(status.authorityId, status); 1994231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1995231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } else { 1996231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn // Ooops. 1997231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn Log.w(TAG, "Unknown status token: " + token); 1998231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn break; 1999231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 2000231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 2001231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } catch (java.io.IOException e) { 2002231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn Log.i(TAG, "No initial status"); 20039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2005360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 2006231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** 2007231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * Write all sync status to the sync status file. 2008231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn */ 2009231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private void writeStatusLocked() { 2010231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (DEBUG_FILE) Log.v(TAG, "Writing new " + mStatusFile.getBaseFile()); 2011360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 2012231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn // The file is being written, so we don't need to have a scheduled 2013231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn // write until the next change. 2014231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn removeMessages(MSG_WRITE_STATUS); 2015360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 2016231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn FileOutputStream fos = null; 20179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 2018231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn fos = mStatusFile.startWrite(); 2019231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn Parcel out = Parcel.obtain(); 2020231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn final int N = mSyncStatus.size(); 2021231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn for (int i=0; i<N; i++) { 2022231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn SyncStatusInfo status = mSyncStatus.valueAt(i); 2023231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn out.writeInt(STATUS_FILE_ITEM); 2024231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn status.writeToParcel(out, 0); 20259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2026231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn out.writeInt(STATUS_FILE_END); 2027231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn fos.write(out.marshall()); 2028231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn out.recycle(); 2029360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 2030231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mStatusFile.finishWrite(fos); 2031231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } catch (java.io.IOException e1) { 2032231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn Log.w(TAG, "Error writing status", e1); 2033231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (fos != null) { 2034231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mStatusFile.failWrite(fos); 2035231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 2036231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 2037231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 2038360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 2039307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana public static final int PENDING_OPERATION_VERSION = 2; 2040360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 2041231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** 2042231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * Read all pending operations back in to the initial engine state. 2043231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn */ 2044231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private void readPendingOperationsLocked() { 2045231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (DEBUG_FILE) Log.v(TAG, "Reading " + mPendingFile.getBaseFile()); 2046231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn try { 2047231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn byte[] data = mPendingFile.readFully(); 2048231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn Parcel in = Parcel.obtain(); 2049231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn in.unmarshall(data, 0, data.length); 2050231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn in.setDataPosition(0); 2051231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn final int SIZE = in.dataSize(); 2052231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn while (in.dataPosition() < SIZE) { 2053231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn int version = in.readInt(); 2054307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana if (version != PENDING_OPERATION_VERSION && version != 1) { 2055231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn Log.w(TAG, "Unknown pending operation version " 2056231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn + version + "; dropping all ops"); 2057231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn break; 2058231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 2059231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn int authorityId = in.readInt(); 2060231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn int syncSource = in.readInt(); 2061231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn byte[] flatExtras = in.createByteArray(); 2062307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana boolean expedited; 2063307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana if (version == PENDING_OPERATION_VERSION) { 2064307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana expedited = in.readInt() != 0; 2065307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana } else { 2066307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana expedited = false; 2067307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana } 2068231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn AuthorityInfo authority = mAuthorities.get(authorityId); 2069231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (authority != null) { 20705695c7b4e5bedb692c78a92b95b26e22ae33316bFred Quintana Bundle extras; 2071231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (flatExtras != null) { 2072231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn extras = unflattenBundle(flatExtras); 20735695c7b4e5bedb692c78a92b95b26e22ae33316bFred Quintana } else { 20745695c7b4e5bedb692c78a92b95b26e22ae33316bFred Quintana // if we are unable to parse the extras for whatever reason convert this 20755695c7b4e5bedb692c78a92b95b26e22ae33316bFred Quintana // to a regular sync by creating an empty extras 20765695c7b4e5bedb692c78a92b95b26e22ae33316bFred Quintana extras = new Bundle(); 2077231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 2078231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn PendingOperation op = new PendingOperation( 207904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani authority.account, authority.userId, syncSource, 2080307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana authority.authority, extras, expedited); 2081231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn op.authorityId = authorityId; 2082231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn op.flatExtras = flatExtras; 2083231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (DEBUG_FILE) Log.v(TAG, "Adding pending op: account=" + op.account 2084231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn + " auth=" + op.authority 2085231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn + " src=" + op.syncSource 2086307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana + " expedited=" + op.expedited 2087231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn + " extras=" + op.extras); 2088231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mPendingOperations.add(op); 2089231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 2090231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 2091231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } catch (java.io.IOException e) { 2092231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn Log.i(TAG, "No initial pending operations"); 2093231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 2094231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 2095360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 2096231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private void writePendingOperationLocked(PendingOperation op, Parcel out) { 2097231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn out.writeInt(PENDING_OPERATION_VERSION); 2098231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn out.writeInt(op.authorityId); 2099231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn out.writeInt(op.syncSource); 2100231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (op.flatExtras == null && op.extras != null) { 2101231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn op.flatExtras = flattenBundle(op.extras); 2102231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 2103231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn out.writeByteArray(op.flatExtras); 2104307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana out.writeInt(op.expedited ? 1 : 0); 2105231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 2106360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 2107231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** 2108231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * Write all currently pending ops to the pending ops file. 2109231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn */ 2110231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private void writePendingOperationsLocked() { 2111231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn final int N = mPendingOperations.size(); 2112231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn FileOutputStream fos = null; 2113231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn try { 2114231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (N == 0) { 2115231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (DEBUG_FILE) Log.v(TAG, "Truncating " + mPendingFile.getBaseFile()); 2116231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mPendingFile.truncate(); 2117231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return; 2118231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 2119360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 2120231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (DEBUG_FILE) Log.v(TAG, "Writing new " + mPendingFile.getBaseFile()); 2121231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn fos = mPendingFile.startWrite(); 2122360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 2123231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn Parcel out = Parcel.obtain(); 2124231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn for (int i=0; i<N; i++) { 2125231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn PendingOperation op = mPendingOperations.get(i); 2126231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn writePendingOperationLocked(op, out); 2127231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 2128231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn fos.write(out.marshall()); 2129231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn out.recycle(); 2130360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 2131231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mPendingFile.finishWrite(fos); 2132231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } catch (java.io.IOException e1) { 2133231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn Log.w(TAG, "Error writing pending operations", e1); 2134231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (fos != null) { 2135231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mPendingFile.failWrite(fos); 2136231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 2137231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 2138231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 2139360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 2140231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** 2141231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * Append the given operation to the pending ops file; if unable to, 2142231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * write all pending ops. 2143231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn */ 2144231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private void appendPendingOperationLocked(PendingOperation op) { 2145231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (DEBUG_FILE) Log.v(TAG, "Appending to " + mPendingFile.getBaseFile()); 2146231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn FileOutputStream fos = null; 2147231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn try { 2148231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn fos = mPendingFile.openAppend(); 2149231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } catch (java.io.IOException e) { 2150231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (DEBUG_FILE) Log.v(TAG, "Failed append; writing full file"); 2151231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn writePendingOperationsLocked(); 2152231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return; 2153231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 2154360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 2155231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn try { 2156231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn Parcel out = Parcel.obtain(); 2157231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn writePendingOperationLocked(op, out); 2158231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn fos.write(out.marshall()); 2159231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn out.recycle(); 2160231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } catch (java.io.IOException e1) { 2161231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn Log.w(TAG, "Error writing pending operations", e1); 2162231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } finally { 2163231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn try { 2164231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn fos.close(); 2165231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } catch (java.io.IOException e2) { 21669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2167231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 2168231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 2169360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 2170231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn static private byte[] flattenBundle(Bundle bundle) { 2171231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn byte[] flatData = null; 2172231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn Parcel parcel = Parcel.obtain(); 2173231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn try { 2174231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn bundle.writeToParcel(parcel, 0); 2175231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn flatData = parcel.marshall(); 2176231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } finally { 2177231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn parcel.recycle(); 2178231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 2179231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return flatData; 2180231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 2181360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 2182231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn static private Bundle unflattenBundle(byte[] flatData) { 2183231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn Bundle bundle; 2184231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn Parcel parcel = Parcel.obtain(); 2185231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn try { 2186231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn parcel.unmarshall(flatData, 0, flatData.length); 2187231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn parcel.setDataPosition(0); 2188231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn bundle = parcel.readBundle(); 2189231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } catch (RuntimeException e) { 2190231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn // A RuntimeException is thrown if we were unable to parse the parcel. 2191231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn // Create an empty parcel in this case. 2192231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn bundle = new Bundle(); 21939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 2194231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn parcel.recycle(); 2195231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 2196231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return bundle; 2197231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 2198360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 219904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void requestSync(Account account, int userId, String authority, Bundle extras) { 220004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani // If this is happening in the system process, then call the syncrequest listener 220104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani // to make a request back to the SyncManager directly. 220204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani // If this is probably a test instance, then call back through the ContentResolver 220304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani // which will know which userId to apply based on the Binder id. 220404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani if (android.os.Process.myUid() == android.os.Process.SYSTEM_UID 220504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani && mSyncRequestListener != null) { 220604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani mSyncRequestListener.onSyncRequest(account, userId, authority, extras); 220704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } else { 220804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani ContentResolver.requestSync(account, authority, extras); 220904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 221004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 221104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 2212231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public static final int STATISTICS_FILE_END = 0; 2213231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public static final int STATISTICS_FILE_ITEM_OLD = 100; 2214231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public static final int STATISTICS_FILE_ITEM = 101; 2215360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 2216231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** 2217231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * Read all sync statistics back in to the initial engine state. 2218231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn */ 2219231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private void readStatisticsLocked() { 2220231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn try { 2221231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn byte[] data = mStatisticsFile.readFully(); 2222231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn Parcel in = Parcel.obtain(); 2223231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn in.unmarshall(data, 0, data.length); 2224231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn in.setDataPosition(0); 2225231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn int token; 2226231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn int index = 0; 2227231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn while ((token=in.readInt()) != STATISTICS_FILE_END) { 2228231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (token == STATISTICS_FILE_ITEM 2229231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn || token == STATISTICS_FILE_ITEM_OLD) { 2230231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn int day = in.readInt(); 2231231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (token == STATISTICS_FILE_ITEM_OLD) { 2232231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn day = day - 2009 + 14245; // Magic! 2233231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 2234231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn DayStats ds = new DayStats(day); 2235231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn ds.successCount = in.readInt(); 2236231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn ds.successTime = in.readLong(); 2237231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn ds.failureCount = in.readInt(); 2238231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn ds.failureTime = in.readLong(); 2239231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (index < mDayStats.length) { 2240231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mDayStats[index] = ds; 2241231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn index++; 2242231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 2243231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } else { 2244231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn // Ooops. 2245231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn Log.w(TAG, "Unknown stats token: " + token); 2246231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn break; 2247231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 2248231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 2249231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } catch (java.io.IOException e) { 2250231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn Log.i(TAG, "No initial statistics"); 2251231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 2252231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 2253360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 2254231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** 2255231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn * Write all sync statistics to the sync status file. 2256231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn */ 2257231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private void writeStatisticsLocked() { 2258231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (DEBUG_FILE) Log.v(TAG, "Writing new " + mStatisticsFile.getBaseFile()); 2259360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 2260231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn // The file is being written, so we don't need to have a scheduled 2261231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn // write until the next change. 2262231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn removeMessages(MSG_WRITE_STATISTICS); 2263360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 2264231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn FileOutputStream fos = null; 2265231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn try { 2266231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn fos = mStatisticsFile.startWrite(); 2267231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn Parcel out = Parcel.obtain(); 2268231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn final int N = mDayStats.length; 2269231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn for (int i=0; i<N; i++) { 2270231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn DayStats ds = mDayStats[i]; 2271231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (ds == null) { 2272231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn break; 2273231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 2274231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn out.writeInt(STATISTICS_FILE_ITEM); 2275231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn out.writeInt(ds.day); 2276231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn out.writeInt(ds.successCount); 2277231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn out.writeLong(ds.successTime); 2278231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn out.writeInt(ds.failureCount); 2279231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn out.writeLong(ds.failureTime); 2280231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 2281231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn out.writeInt(STATISTICS_FILE_END); 2282231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn fos.write(out.marshall()); 2283231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn out.recycle(); 2284360e454b2b2f911e9e29268519017cc94ae9d4f4Costin Manolache 2285231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mStatisticsFile.finishWrite(fos); 2286231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } catch (java.io.IOException e1) { 2287231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn Log.w(TAG, "Error writing stats", e1); 2288231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (fos != null) { 2289231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mStatisticsFile.failWrite(fos); 2290231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 22919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2294