19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 177a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeypackage com.android.server.content; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintanaimport android.accounts.Account; 20f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasaniimport android.accounts.AccountAndUser; 21d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintanaimport android.accounts.AccountManager; 2233e446941722b0e31a453399e92e0e82697f05aaFred Quintanaimport android.app.ActivityManager; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.AlarmManager; 249422bdca314064fe82075b90cf529865c8053c44Amith Yamasaniimport android.app.AppGlobals; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.Notification; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.NotificationManager; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.PendingIntent; 287a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeyimport android.content.BroadcastReceiver; 297a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeyimport android.content.ComponentName; 307a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeyimport android.content.ContentResolver; 317a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeyimport android.content.Context; 327a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeyimport android.content.ISyncAdapter; 337a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeyimport android.content.ISyncContext; 3456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williamsimport android.content.ISyncServiceAdapter; 357a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeyimport android.content.ISyncStatusObserver; 367a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeyimport android.content.Intent; 377a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeyimport android.content.IntentFilter; 38fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williamsimport android.content.PeriodicSync; 397a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeyimport android.content.ServiceConnection; 407a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeyimport android.content.SyncActivityTooManyDeletes; 417a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeyimport android.content.SyncAdapterType; 427a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeyimport android.content.SyncAdaptersCache; 437a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeyimport android.content.SyncInfo; 447a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeyimport android.content.SyncResult; 457a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeyimport android.content.SyncStatusInfo; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.ApplicationInfo; 479422bdca314064fe82075b90cf529865c8053c44Amith Yamasaniimport android.content.pm.PackageInfo; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager; 4907ad8dc2087aa02da48353acc19ba82e62d99f82Kenny Guyimport android.content.pm.PackageManager.NameNotFoundException; 50c848b7023bcb19d7a392eb9f4669e56906e5382cFred Quintanaimport android.content.pm.ProviderInfo; 51e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albertimport android.content.pm.RegisteredServicesCache; 5244037e6c41f8167bf5ac51fcb684ad28b20073ceFred Quintanaimport android.content.pm.RegisteredServicesCacheListener; 53e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albertimport android.content.pm.ResolveInfo; 5404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasaniimport android.content.pm.UserInfo; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.ConnectivityManager; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.NetworkInfo; 57a1f1a3c573acd91024fda0ceb3b921c73b186963Dianne Hackbornimport android.os.BatteryStats; 58e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albertimport android.os.Bundle; 59e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albertimport android.os.Handler; 60e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albertimport android.os.IBinder; 61e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albertimport android.os.Looper; 62e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albertimport android.os.Message; 63e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albertimport android.os.PowerManager; 64e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albertimport android.os.RemoteException; 65a1f1a3c573acd91024fda0ceb3b921c73b186963Dianne Hackbornimport android.os.ServiceManager; 66e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albertimport android.os.SystemClock; 67e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albertimport android.os.SystemProperties; 68f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackbornimport android.os.UserHandle; 69258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasaniimport android.os.UserManager; 707e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackbornimport android.os.WorkSource; 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.provider.Settings; 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.format.DateUtils; 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.format.Time; 74632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williamsimport android.text.TextUtils; 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.EventLog; 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 77307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintanaimport android.util.Pair; 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 798e28555f6d4ea557ba79e3d411ea46e5a0788b8fAlon Albertimport com.android.internal.R; 808b2c3a14603d163d7564e6f60286995079687690Jeff Sharkeyimport com.android.internal.annotations.GuardedBy; 81a1f1a3c573acd91024fda0ceb3b921c73b186963Dianne Hackbornimport com.android.internal.app.IBatteryStats; 828d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackbornimport com.android.internal.os.BackgroundThread; 836ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkeyimport com.android.internal.util.IndentingPrintWriter; 847a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeyimport com.android.server.accounts.AccountManagerService; 85dbe846b02e6f6f715787cf8621587f7bc25deaacGeorgi Nikolovimport com.android.server.content.SyncStorageEngine.AuthorityInfo; 867a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeyimport com.android.server.content.SyncStorageEngine.OnSyncRequestListener; 878e28555f6d4ea557ba79e3d411ea46e5a0788b8fAlon Albertimport com.google.android.collect.Lists; 888e28555f6d4ea557ba79e3d411ea46e5a0788b8fAlon Albertimport com.google.android.collect.Maps; 898e28555f6d4ea557ba79e3d411ea46e5a0788b8fAlon Albertimport com.google.android.collect.Sets; 908e28555f6d4ea557ba79e3d411ea46e5a0788b8fAlon Albert 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileDescriptor; 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.PrintWriter; 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 94e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albertimport java.util.Arrays; 95918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintanaimport java.util.Collection; 96918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintanaimport java.util.Collections; 97e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albertimport java.util.Comparator; 98b3029c3d563cf99ea07395282b053e87d5dbbb95Fred Quintanaimport java.util.HashMap; 99231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport java.util.HashSet; 100918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintanaimport java.util.Iterator; 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List; 102e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albertimport java.util.Map; 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Random; 1048e28555f6d4ea557ba79e3d411ea46e5a0788b8fAlon Albertimport java.util.Set; 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1096ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkeypublic class SyncManager { 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "SyncManager"; 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Delay a sync due to local changes this long. In milliseconds */ 11344ee0f03f99b3eea8bf3d3e7f63ad0553623f426Debajit Ghosh private static final long LOCAL_SYNC_DELAY; 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If a sync takes longer than this and the sync queue is not empty then we will 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * cancel it and add it back to the end of the sync queue. In milliseconds. 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11944ee0f03f99b3eea8bf3d3e7f63ad0553623f426Debajit Ghosh private static final long MAX_TIME_PER_SYNC; 12044ee0f03f99b3eea8bf3d3e7f63ad0553623f426Debajit Ghosh 12144ee0f03f99b3eea8bf3d3e7f63ad0553623f426Debajit Ghosh static { 122b4e12494935697fa4ede006b37e6be889ef27109Dianne Hackborn final boolean isLargeRAM = !ActivityManager.isLowRamDeviceStatic(); 12333e446941722b0e31a453399e92e0e82697f05aaFred Quintana int defaultMaxInitSyncs = isLargeRAM ? 5 : 2; 12433e446941722b0e31a453399e92e0e82697f05aaFred Quintana int defaultMaxRegularSyncs = isLargeRAM ? 2 : 1; 12533e446941722b0e31a453399e92e0e82697f05aaFred Quintana MAX_SIMULTANEOUS_INITIALIZATION_SYNCS = 12633e446941722b0e31a453399e92e0e82697f05aaFred Quintana SystemProperties.getInt("sync.max_init_syncs", defaultMaxInitSyncs); 12733e446941722b0e31a453399e92e0e82697f05aaFred Quintana MAX_SIMULTANEOUS_REGULAR_SYNCS = 12833e446941722b0e31a453399e92e0e82697f05aaFred Quintana SystemProperties.getInt("sync.max_regular_syncs", defaultMaxRegularSyncs); 129918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana LOCAL_SYNC_DELAY = 130918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana SystemProperties.getLong("sync.local_sync_delay", 30 * 1000 /* 30 seconds */); 131918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana MAX_TIME_PER_SYNC = 132918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana SystemProperties.getLong("sync.max_time_per_sync", 5 * 60 * 1000 /* 5 minutes */); 133918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana SYNC_NOTIFICATION_DELAY = 134918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana SystemProperties.getLong("sync.notification_delay", 30 * 1000 /* 30 seconds */); 13544ee0f03f99b3eea8bf3d3e7f63ad0553623f426Debajit Ghosh } 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 137918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana private static final long SYNC_NOTIFICATION_DELAY; 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * When retrying a sync for the first time use this delay. After that 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the retry time will double until it reached MAX_SYNC_RETRY_TIME. 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * In milliseconds. 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final long INITIAL_SYNC_RETRY_TIME_IN_MS = 30 * 1000; // 30 seconds 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Default the max sync retry time to this value. 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final long DEFAULT_MAX_SYNC_RETRY_TIME_IN_SECONDS = 60 * 60; // one hour 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1528570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana * How long to wait before retrying a sync that failed due to one already being in progress. 1538570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana */ 1548570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana private static final int DELAY_RETRY_SYNC_IN_PROGRESS_IN_SECONDS = 10; 1558570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana 15692a1c09aa467f03dad78472098d40992303937fbMatthew Williams /** 15792a1c09aa467f03dad78472098d40992303937fbMatthew Williams * How long to wait before considering an active sync to have timed-out, and cancelling it. 15892a1c09aa467f03dad78472098d40992303937fbMatthew Williams */ 15992a1c09aa467f03dad78472098d40992303937fbMatthew Williams private static final long ACTIVE_SYNC_TIMEOUT_MILLIS = 30L * 60 * 1000; // 30 mins. 1603ec4730e375689b8ad9a03fcf98ff7773d726ddaFred Quintana 161d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn private static final String SYNC_WAKE_LOCK_PREFIX = "*sync*/"; 1627e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn private static final String HANDLE_SYNC_ALARM_WAKE_LOCK = "SyncManagerHandleSyncAlarm"; 163918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana private static final String SYNC_LOOP_WAKE_LOCK = "SyncLoopWakeLock"; 164918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana 165918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana private static final int MAX_SIMULTANEOUS_REGULAR_SYNCS; 166918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana private static final int MAX_SIMULTANEOUS_INITIALIZATION_SYNCS; 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Context mContext; 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private static final AccountAndUser[] INITIAL_ACCOUNTS_ARRAY = new AccountAndUser[0]; 17104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 1726ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey // TODO: add better locking around mRunningAccounts 1736ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey private volatile AccountAndUser[] mRunningAccounts = INITIAL_ACCOUNTS_ARRAY; 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project volatile private PowerManager.WakeLock mHandleAlarmWakeLock; 176918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana volatile private PowerManager.WakeLock mSyncManagerWakeLock; 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project volatile private boolean mDataConnectionIsConnected = false; 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project volatile private boolean mStorageIsLow = false; 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final NotificationManager mNotificationMgr; 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private AlarmManager mAlarmService = null; 182a1f1a3c573acd91024fda0ceb3b921c73b186963Dianne Hackborn private final IBatteryStats mBatteryStats; 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1840c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana private SyncStorageEngine mSyncStorageEngine; 185a706e2fd0059b1bb86c487722dbc9fc0fda9c980Jeff Sharkey 1868b2c3a14603d163d7564e6f60286995079687690Jeff Sharkey @GuardedBy("mSyncQueue") 187a706e2fd0059b1bb86c487722dbc9fc0fda9c980Jeff Sharkey private final SyncQueue mSyncQueue; 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1890c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana protected final ArrayList<ActiveSyncContext> mActiveSyncContexts = Lists.newArrayList(); 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // set if the sync active indicator should be reported 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mNeedSyncActiveNotification = false; 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final PendingIntent mSyncAlarmIntent; 195f892fb3a431e04151382d1bddc4438fd04487a6aFred Quintana // Synchronized on "this". Instead of using this directly one should instead call 196f892fb3a431e04151382d1bddc4438fd04487a6aFred Quintana // its accessor, getConnManager(). 197f892fb3a431e04151382d1bddc4438fd04487a6aFred Quintana private ConnectivityManager mConnManagerDoNotUseDirectly; 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1990c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana protected SyncAdaptersCache mSyncAdapters; 200718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private BroadcastReceiver mStorageIntentReceiver = 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new BroadcastReceiver() { 203fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams @Override 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onReceive(Context context, Intent intent) { 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String action = intent.getAction(); 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Intent.ACTION_DEVICE_STORAGE_LOW.equals(action)) { 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Log.isLoggable(TAG, Log.VERBOSE)) { 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.v(TAG, "Internal storage is low."); 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStorageIsLow = true; 21156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams cancelActiveSync( 21256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams SyncStorageEngine.EndPoint.USER_ALL_PROVIDER_ALL_ACCOUNTS_ALL, 21356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams null /* any sync */); 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (Intent.ACTION_DEVICE_STORAGE_OK.equals(action)) { 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Log.isLoggable(TAG, Log.VERBOSE)) { 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.v(TAG, "Internal storage is ok."); 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStorageIsLow = false; 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sendCheckAlarmsMessage(); 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 224603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private BroadcastReceiver mBootCompletedReceiver = new BroadcastReceiver() { 225fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams @Override 226603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void onReceive(Context context, Intent intent) { 227e91ebe2be9580625ff31af8583e55aaefc50474fFred Quintana mSyncHandler.onBootCompleted(); 228d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana } 229d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana }; 230603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 231d648a605e8249219ce60ac93e074758ebb6fc4abAmith Yamasani private BroadcastReceiver mAccountsUpdatedReceiver = new BroadcastReceiver() { 232fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams @Override 233d648a605e8249219ce60ac93e074758ebb6fc4abAmith Yamasani public void onReceive(Context context, Intent intent) { 2346ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey updateRunningAccounts(); 2356ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 2366ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey // Kick off sync for everyone, since this was a radical account change 23757286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert scheduleSync(null, UserHandle.USER_ALL, SyncOperation.REASON_ACCOUNTS_UPDATED, null, 238fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams null, 0 /* no delay */, 0/* no delay */, false); 239d648a605e8249219ce60ac93e074758ebb6fc4abAmith Yamasani } 240d648a605e8249219ce60ac93e074758ebb6fc4abAmith Yamasani }; 241d648a605e8249219ce60ac93e074758ebb6fc4abAmith Yamasani 242b3029c3d563cf99ea07395282b053e87d5dbbb95Fred Quintana private final PowerManager mPowerManager; 243b3029c3d563cf99ea07395282b053e87d5dbbb95Fred Quintana 244fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams // Use this as a random offset to seed all periodic syncs. 24569d95de53bc82e6c23c64ad566e428fbefae0543Ashish Sharma private int mSyncRandomOffsetMillis; 24669d95de53bc82e6c23c64ad566e428fbefae0543Ashish Sharma 2479535c915b61c43d7b4bdb2b35d53774cfb16bfbbAmith Yamasani private final UserManager mUserManager; 248258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasani 249918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana private static final long SYNC_ALARM_TIMEOUT_MIN = 30 * 1000; // 30 seconds 250918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana private static final long SYNC_ALARM_TIMEOUT_MAX = 2 * 60 * 60 * 1000; // two hours 251918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana 252258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasani private List<UserInfo> getAllUsers() { 2539535c915b61c43d7b4bdb2b35d53774cfb16bfbbAmith Yamasani return mUserManager.getUsers(); 25404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 25504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 25604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private boolean containsAccountAndUser(AccountAndUser[] accounts, Account account, int userId) { 25704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani boolean found = false; 25804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani for (int i = 0; i < accounts.length; i++) { 25904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani if (accounts[i].userId == userId 26004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani && accounts[i].account.equals(account)) { 26104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani found = true; 26204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani break; 26304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 26404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 26504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return found; 26604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 26704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 2686ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey public void updateRunningAccounts() { 2696ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey mRunningAccounts = AccountManagerService.getSingleton().getRunningAccounts(); 27004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 2718f55d112983aa922687de7e3581f73913c06e37aJeff Sharkey if (mBootCompleted) { 2728f55d112983aa922687de7e3581f73913c06e37aJeff Sharkey doDatabaseCleanup(); 2738f55d112983aa922687de7e3581f73913c06e37aJeff Sharkey } 2748f55d112983aa922687de7e3581f73913c06e37aJeff Sharkey 27556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams AccountAndUser[] accounts = mRunningAccounts; 276918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana for (ActiveSyncContext currentSyncContext : mActiveSyncContexts) { 27756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (!containsAccountAndUser(accounts, 27856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams currentSyncContext.mSyncOperation.target.account, 27956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams currentSyncContext.mSyncOperation.target.userId)) { 2806ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey Log.d(TAG, "canceling sync since the account is no longer running"); 281918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana sendSyncFinishedOrCanceledMessage(currentSyncContext, 282d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana null /* no result since this is a cancel */); 283603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 284603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 285d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana // we must do this since we don't bother scheduling alarms when 286d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana // the accounts are not set yet 287d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana sendCheckAlarmsMessage(); 288d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana } 289603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2908f55d112983aa922687de7e3581f73913c06e37aJeff Sharkey private void doDatabaseCleanup() { 291db6a14cc85cede0769735fdac4da70766989a3ceAmith Yamasani for (UserInfo user : mUserManager.getUsers(true)) { 292db6a14cc85cede0769735fdac4da70766989a3ceAmith Yamasani // Skip any partially created/removed users 293db6a14cc85cede0769735fdac4da70766989a3ceAmith Yamasani if (user.partial) continue; 2948f55d112983aa922687de7e3581f73913c06e37aJeff Sharkey Account[] accountsForUser = AccountManagerService.getSingleton().getAccounts(user.id); 2958f55d112983aa922687de7e3581f73913c06e37aJeff Sharkey mSyncStorageEngine.doDatabaseCleanup(accountsForUser, user.id); 2968f55d112983aa922687de7e3581f73913c06e37aJeff Sharkey } 2978f55d112983aa922687de7e3581f73913c06e37aJeff Sharkey } 2988f55d112983aa922687de7e3581f73913c06e37aJeff Sharkey 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private BroadcastReceiver mConnectivityIntentReceiver = 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new BroadcastReceiver() { 301fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams @Override 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onReceive(Context context, Intent intent) { 303ed1d253573a238fd53d27def24d298314f24d425Alon Albert final boolean wasConnected = mDataConnectionIsConnected; 304ed1d253573a238fd53d27def24d298314f24d425Alon Albert 305ed1d253573a238fd53d27def24d298314f24d425Alon Albert // don't use the intent to figure out if network is connected, just check 306ed1d253573a238fd53d27def24d298314f24d425Alon Albert // ConnectivityManager directly. 3071bad83adf011ff4e6a6474c62b287d119ba43b3eAlon Albert mDataConnectionIsConnected = readDataConnectionState(); 308ed1d253573a238fd53d27def24d298314f24d425Alon Albert if (mDataConnectionIsConnected) { 309ed1d253573a238fd53d27def24d298314f24d425Alon Albert if (!wasConnected) { 310ed1d253573a238fd53d27def24d298314f24d425Alon Albert if (Log.isLoggable(TAG, Log.VERBOSE)) { 311ed1d253573a238fd53d27def24d298314f24d425Alon Albert Log.v(TAG, "Reconnection detected: clearing all backoffs"); 312ed1d253573a238fd53d27def24d298314f24d425Alon Albert } 313119aac93f8d757ff464dd4d1135ffcf37f7cda02Matthew Williams synchronized (mSyncQueue) { 314119aac93f8d757ff464dd4d1135ffcf37f7cda02Matthew Williams mSyncStorageEngine.clearAllBackoffsLocked(mSyncQueue); 315119aac93f8d757ff464dd4d1135ffcf37f7cda02Matthew Williams } 316ed1d253573a238fd53d27def24d298314f24d425Alon Albert } 317ed1d253573a238fd53d27def24d298314f24d425Alon Albert sendCheckAlarmsMessage(); 318ed1d253573a238fd53d27def24d298314f24d425Alon Albert } 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3221bad83adf011ff4e6a6474c62b287d119ba43b3eAlon Albert private boolean readDataConnectionState() { 323ed1d253573a238fd53d27def24d298314f24d425Alon Albert NetworkInfo networkInfo = getConnectivityManager().getActiveNetworkInfo(); 324ed1d253573a238fd53d27def24d298314f24d425Alon Albert return (networkInfo != null) && networkInfo.isConnected(); 325ed1d253573a238fd53d27def24d298314f24d425Alon Albert } 326ed1d253573a238fd53d27def24d298314f24d425Alon Albert 32755280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn private BroadcastReceiver mShutdownIntentReceiver = 32855280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn new BroadcastReceiver() { 329fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams @Override 33055280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn public void onReceive(Context context, Intent intent) { 33155280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn Log.w(TAG, "Writing sync state before shutdown..."); 33255280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn getSyncStorageEngine().writeAllState(); 33355280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn } 33455280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn }; 33555280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn 336135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani private BroadcastReceiver mUserIntentReceiver = new BroadcastReceiver() { 337135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani @Override 338135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani public void onReceive(Context context, Intent intent) { 3398e28555f6d4ea557ba79e3d411ea46e5a0788b8fAlon Albert String action = intent.getAction(); 3406ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); 3416ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey if (userId == UserHandle.USER_NULL) return; 3426ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 3438e28555f6d4ea557ba79e3d411ea46e5a0788b8fAlon Albert if (Intent.ACTION_USER_REMOVED.equals(action)) { 3446ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey onUserRemoved(userId); 3456ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey } else if (Intent.ACTION_USER_STARTING.equals(action)) { 3466ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey onUserStarting(userId); 3476ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey } else if (Intent.ACTION_USER_STOPPING.equals(action)) { 3486ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey onUserStopping(userId); 3498e28555f6d4ea557ba79e3d411ea46e5a0788b8fAlon Albert } 350135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani } 351135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani }; 352135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String ACTION_SYNC_ALARM = "android.content.syncmanager.SYNC_ALARM"; 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final SyncHandler mSyncHandler; 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3564f9cfc5c52c8b40975c1bc2829efa46b4bddb03fFred Quintana private volatile boolean mBootCompleted = false; 3574f9cfc5c52c8b40975c1bc2829efa46b4bddb03fFred Quintana 358f892fb3a431e04151382d1bddc4438fd04487a6aFred Quintana private ConnectivityManager getConnectivityManager() { 359f892fb3a431e04151382d1bddc4438fd04487a6aFred Quintana synchronized (this) { 360f892fb3a431e04151382d1bddc4438fd04487a6aFred Quintana if (mConnManagerDoNotUseDirectly == null) { 361f892fb3a431e04151382d1bddc4438fd04487a6aFred Quintana mConnManagerDoNotUseDirectly = (ConnectivityManager)mContext.getSystemService( 362f892fb3a431e04151382d1bddc4438fd04487a6aFred Quintana Context.CONNECTIVITY_SERVICE); 363f892fb3a431e04151382d1bddc4438fd04487a6aFred Quintana } 364f892fb3a431e04151382d1bddc4438fd04487a6aFred Quintana return mConnManagerDoNotUseDirectly; 365f892fb3a431e04151382d1bddc4438fd04487a6aFred Quintana } 366f892fb3a431e04151382d1bddc4438fd04487a6aFred Quintana } 367f892fb3a431e04151382d1bddc4438fd04487a6aFred Quintana 368e4996bbd519a088927180c2eed2941fe59a4cd40Jeff Sharkey /** 369e4996bbd519a088927180c2eed2941fe59a4cd40Jeff Sharkey * Should only be created after {@link ContentService#systemReady()} so that 370e4996bbd519a088927180c2eed2941fe59a4cd40Jeff Sharkey * {@link PackageManager} is ready to query. 371e4996bbd519a088927180c2eed2941fe59a4cd40Jeff Sharkey */ 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public SyncManager(Context context, boolean factoryTest) { 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Initialize the SyncStorageEngine first, before registering observers 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // and creating threads and so on; it may fail if the disk is full. 3750c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana mContext = context; 3769535c915b61c43d7b4bdb2b35d53774cfb16bfbbAmith Yamasani 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SyncStorageEngine.init(context); 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSyncStorageEngine = SyncStorageEngine.getSingleton(); 37904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani mSyncStorageEngine.setOnSyncRequestListener(new OnSyncRequestListener() { 380fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams @Override 38156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams public void onSyncRequest(SyncStorageEngine.EndPoint info, int reason, Bundle extras) { 38256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (info.target_provider) { 38356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams scheduleSync(info.account, info.userId, reason, info.provider, extras, 38456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams 0 /* no flex */, 38556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams 0 /* run immediately */, 38656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams false); 38756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } else if (info.target_service) { 38856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams scheduleSync(info.service, info.userId, reason, extras, 38956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams 0 /* no flex */, 39056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams 0 /* run immediately */); 39156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 39204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 39304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani }); 39404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 3950c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana mSyncAdapters = new SyncAdaptersCache(mContext); 39657286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert mSyncQueue = new SyncQueue(mContext.getPackageManager(), mSyncStorageEngine, mSyncAdapters); 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3988d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn mSyncHandler = new SyncHandler(BackgroundThread.get().getLooper()); 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 40044037e6c41f8167bf5ac51fcb684ad28b20073ceFred Quintana mSyncAdapters.setListener(new RegisteredServicesCacheListener<SyncAdapterType>() { 4016ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey @Override 4026ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey public void onServiceChanged(SyncAdapterType type, int userId, boolean removed) { 40344037e6c41f8167bf5ac51fcb684ad28b20073ceFred Quintana if (!removed) { 40457286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert scheduleSync(null, UserHandle.USER_ALL, 40557286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert SyncOperation.REASON_SERVICE_CHANGED, 406fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams type.authority, null, 0 /* no delay */, 0 /* no delay */, 40744037e6c41f8167bf5ac51fcb684ad28b20073ceFred Quintana false /* onlyThoseWithUnkownSyncableState */); 40844037e6c41f8167bf5ac51fcb684ad28b20073ceFred Quintana } 40944037e6c41f8167bf5ac51fcb684ad28b20073ceFred Quintana } 41044037e6c41f8167bf5ac51fcb684ad28b20073ceFred Quintana }, mSyncHandler); 411718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSyncAlarmIntent = PendingIntent.getBroadcast( 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext, 0 /* ignored */, new Intent(ACTION_SYNC_ALARM), 0); 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project context.registerReceiver(mConnectivityIntentReceiver, intentFilter); 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 418e91ebe2be9580625ff31af8583e55aaefc50474fFred Quintana if (!factoryTest) { 419e91ebe2be9580625ff31af8583e55aaefc50474fFred Quintana intentFilter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED); 420d83a096f299abd9c7fe5e441ef1bb169c314b575Dianne Hackborn intentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); 421e91ebe2be9580625ff31af8583e55aaefc50474fFred Quintana context.registerReceiver(mBootCompletedReceiver, intentFilter); 422e91ebe2be9580625ff31af8583e55aaefc50474fFred Quintana } 423603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intentFilter = new IntentFilter(Intent.ACTION_DEVICE_STORAGE_LOW); 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intentFilter.addAction(Intent.ACTION_DEVICE_STORAGE_OK); 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project context.registerReceiver(mStorageIntentReceiver, intentFilter); 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 42855280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn intentFilter = new IntentFilter(Intent.ACTION_SHUTDOWN); 42955280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn intentFilter.setPriority(100); 43055280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn context.registerReceiver(mShutdownIntentReceiver, intentFilter); 43155280a91884b9256e8db6af6a09f28b3feeaa9d8Dianne Hackborn 432135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani intentFilter = new IntentFilter(); 433135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani intentFilter.addAction(Intent.ACTION_USER_REMOVED); 4346ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey intentFilter.addAction(Intent.ACTION_USER_STARTING); 4356ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey intentFilter.addAction(Intent.ACTION_USER_STOPPING); 4368e28555f6d4ea557ba79e3d411ea46e5a0788b8fAlon Albert mContext.registerReceiverAsUser( 4378e28555f6d4ea557ba79e3d411ea46e5a0788b8fAlon Albert mUserIntentReceiver, UserHandle.ALL, intentFilter, null, null); 438135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!factoryTest) { 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNotificationMgr = (NotificationManager) 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project context.getSystemService(Context.NOTIFICATION_SERVICE); 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project context.registerReceiver(new SyncAlarmIntentReceiver(), 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new IntentFilter(ACTION_SYNC_ALARM)); 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNotificationMgr = null; 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 447b3029c3d563cf99ea07395282b053e87d5dbbb95Fred Quintana mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); 4489535c915b61c43d7b4bdb2b35d53774cfb16bfbbAmith Yamasani mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 449a1f1a3c573acd91024fda0ceb3b921c73b186963Dianne Hackborn mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService( 450a1f1a3c573acd91024fda0ceb3b921c73b186963Dianne Hackborn BatteryStats.SERVICE_NAME)); 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This WakeLock is used to ensure that we stay awake between the time that we receive 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // a sync alarm notification and when we finish processing it. We need to do this 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // because we don't do the work in the alarm handler, rather we do it in a message 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // handler. 456b3029c3d563cf99ea07395282b053e87d5dbbb95Fred Quintana mHandleAlarmWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project HANDLE_SYNC_ALARM_WAKE_LOCK); 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandleAlarmWakeLock.setReferenceCounted(false); 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 460918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana // This WakeLock is used to ensure that we stay awake while running the sync loop 461918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana // message handler. Normally we will hold a sync adapter wake lock while it is being 462918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana // synced but during the execution of the sync loop it might finish a sync for 463918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana // one sync adapter before starting the sync for the other sync adapter and we 464918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana // don't want the device to go to sleep during that window. 465918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana mSyncManagerWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, 466918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana SYNC_LOOP_WAKE_LOCK); 467918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana mSyncManagerWakeLock.setReferenceCounted(false); 468918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana 469231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mSyncStorageEngine.addStatusChangeListener( 470ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS, new ISyncStatusObserver.Stub() { 471fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams @Override 472231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public void onStatusChanged(int which) { 473231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn // force the sync loop to run if the settings change 474231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn sendCheckAlarmsMessage(); 475231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 476231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn }); 477e91ebe2be9580625ff31af8583e55aaefc50474fFred Quintana 478e91ebe2be9580625ff31af8583e55aaefc50474fFred Quintana if (!factoryTest) { 479d648a605e8249219ce60ac93e074758ebb6fc4abAmith Yamasani // Register for account list updates for all users 480d648a605e8249219ce60ac93e074758ebb6fc4abAmith Yamasani mContext.registerReceiverAsUser(mAccountsUpdatedReceiver, 481d648a605e8249219ce60ac93e074758ebb6fc4abAmith Yamasani UserHandle.ALL, 482d648a605e8249219ce60ac93e074758ebb6fc4abAmith Yamasani new IntentFilter(AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION), 4835c6756fefb6db0fe468b9d747960a6da344880adMatthew Williams null, null); 484e91ebe2be9580625ff31af8583e55aaefc50474fFred Quintana } 48569d95de53bc82e6c23c64ad566e428fbefae0543Ashish Sharma 48669d95de53bc82e6c23c64ad566e428fbefae0543Ashish Sharma // Pick a random second in a day to seed all periodic syncs 48769d95de53bc82e6c23c64ad566e428fbefae0543Ashish Sharma mSyncRandomOffsetMillis = mSyncStorageEngine.getSyncRandomOffset() * 1000; 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return a random value v that satisfies minValue <= v < maxValue. The difference between 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * maxValue and minValue must be less than Integer.MAX_VALUE. 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long jitterize(long minValue, long maxValue) { 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Random random = new Random(SystemClock.elapsedRealtime()); 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long spread = maxValue - minValue; 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (spread > Integer.MAX_VALUE) { 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("the difference between the maxValue and the " 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + "minValue must be less than " + Integer.MAX_VALUE); 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return minValue + random.nextInt((int)spread); 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 504231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public SyncStorageEngine getSyncStorageEngine() { 505231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return mSyncStorageEngine; 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 50744f574781545781c31db3dcf495ed08763073f75Doug Zongker 5089422bdca314064fe82075b90cf529865c8053c44Amith Yamasani public int getIsSyncable(Account account, int userId, String providerName) { 5099422bdca314064fe82075b90cf529865c8053c44Amith Yamasani int isSyncable = mSyncStorageEngine.getIsSyncable(account, userId, providerName); 5109422bdca314064fe82075b90cf529865c8053c44Amith Yamasani UserInfo userInfo = UserManager.get(mContext).getUserInfo(userId); 5119422bdca314064fe82075b90cf529865c8053c44Amith Yamasani 5129422bdca314064fe82075b90cf529865c8053c44Amith Yamasani // If it's not a restricted user, return isSyncable 5139422bdca314064fe82075b90cf529865c8053c44Amith Yamasani if (userInfo == null || !userInfo.isRestricted()) return isSyncable; 5149422bdca314064fe82075b90cf529865c8053c44Amith Yamasani 5159422bdca314064fe82075b90cf529865c8053c44Amith Yamasani // Else check if the sync adapter has opted-in or not 5169422bdca314064fe82075b90cf529865c8053c44Amith Yamasani RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo = 5179422bdca314064fe82075b90cf529865c8053c44Amith Yamasani mSyncAdapters.getServiceInfo( 5189422bdca314064fe82075b90cf529865c8053c44Amith Yamasani SyncAdapterType.newKey(providerName, account.type), userId); 5199422bdca314064fe82075b90cf529865c8053c44Amith Yamasani if (syncAdapterInfo == null) return isSyncable; 5209422bdca314064fe82075b90cf529865c8053c44Amith Yamasani 5219422bdca314064fe82075b90cf529865c8053c44Amith Yamasani PackageInfo pInfo = null; 5229422bdca314064fe82075b90cf529865c8053c44Amith Yamasani try { 5239422bdca314064fe82075b90cf529865c8053c44Amith Yamasani pInfo = AppGlobals.getPackageManager().getPackageInfo( 5249422bdca314064fe82075b90cf529865c8053c44Amith Yamasani syncAdapterInfo.componentName.getPackageName(), 0, userId); 5259422bdca314064fe82075b90cf529865c8053c44Amith Yamasani if (pInfo == null) return isSyncable; 5269422bdca314064fe82075b90cf529865c8053c44Amith Yamasani } catch (RemoteException re) { 5279422bdca314064fe82075b90cf529865c8053c44Amith Yamasani // Shouldn't happen 5289422bdca314064fe82075b90cf529865c8053c44Amith Yamasani return isSyncable; 5299422bdca314064fe82075b90cf529865c8053c44Amith Yamasani } 5309422bdca314064fe82075b90cf529865c8053c44Amith Yamasani if (pInfo.restrictedAccountType != null 5319422bdca314064fe82075b90cf529865c8053c44Amith Yamasani && pInfo.restrictedAccountType.equals(account.type)) { 5329422bdca314064fe82075b90cf529865c8053c44Amith Yamasani return isSyncable; 5339422bdca314064fe82075b90cf529865c8053c44Amith Yamasani } else { 5349422bdca314064fe82075b90cf529865c8053c44Amith Yamasani return 0; 5359422bdca314064fe82075b90cf529865c8053c44Amith Yamasani } 5369422bdca314064fe82075b90cf529865c8053c44Amith Yamasani } 5379422bdca314064fe82075b90cf529865c8053c44Amith Yamasani 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void ensureAlarmService() { 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mAlarmService == null) { 54056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams mAlarmService = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE); 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 545fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams * Initiate a sync using the new anonymous service API. 546fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams * @param cname SyncService component bound to in order to perform the sync. 547fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams * @param userId the id of the user whose accounts are to be synced. If userId is USER_ALL, 548fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams * then all users' accounts are considered. 549fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams * @param uid Linux uid of the application that is performing the sync. 550fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams * @param extras a Map of SyncAdapter-specific information to control 5518ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams * syncs of a specific provider. Cannot be null. 55256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams * @param beforeRunTimeMillis milliseconds before <code>runtimeMillis</code> that this sync may 55356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams * be run. 55456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams * @param runtimeMillis milliseconds from now by which this sync must be run. 555fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams */ 556fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams public void scheduleSync(ComponentName cname, int userId, int uid, Bundle extras, 55756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams long beforeRunTimeMillis, long runtimeMillis) { 558fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE); 559fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams if (isLoggable) { 56056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams Log.d(TAG, "one off sync for: " + cname + " " + extras.toString()); 561fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams } 56206485a7c6e3bbea1f427f345ac3a18b2346750e0Matthew Williams 563fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams Boolean expedited = extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false); 564fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams if (expedited) { 565fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams runtimeMillis = -1; // this means schedule at the front of the queue 566fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams } 567fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams 568fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams final boolean ignoreSettings = 569fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, false); 57056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams int source = SyncStorageEngine.SOURCE_SERVICE; 5717a2ab3a060f89c5de7f44f85bf58a7b6f6884873Matthew Williams boolean isEnabled = mSyncStorageEngine.getIsTargetServiceActive(cname, userId); 57256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams // Only schedule this sync if 57356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams // - we've explicitly been told to ignore settings. 57456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams // - global sync is enabled for this user. 57556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams boolean syncAllowed = 57656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams ignoreSettings 57756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams || mSyncStorageEngine.getMasterSyncAutomatically(userId); 57856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (!syncAllowed) { 57956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (isLoggable) { 58056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams Log.d(TAG, "scheduleSync: sync of " + cname + " not allowed, dropping request."); 58156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 58256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return; 583fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams } 5848ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams if (!isEnabled) { 58556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (isLoggable) { 58656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams Log.d(TAG, "scheduleSync: " + cname + " is not enabled, dropping request"); 58756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 58856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return; 58956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 59056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams SyncStorageEngine.EndPoint info = new SyncStorageEngine.EndPoint(cname, userId); 59156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams Pair<Long, Long> backoff = mSyncStorageEngine.getBackoff(info); 59256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams long delayUntil = mSyncStorageEngine.getDelayUntilTime(info); 59356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams final long backoffTime = backoff != null ? backoff.first : 0; 5948ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams if (isLoggable) { 59556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams Log.v(TAG, "schedule Sync:" 59656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams + ", delay until " + delayUntil 59756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams + ", run by " + runtimeMillis 59856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams + ", flex " + beforeRunTimeMillis 59956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams + ", source " + source 60056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams + ", sync service " + cname 60156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams + ", extras " + extras); 60256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 6038ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams scheduleSyncOperation( 6048ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams new SyncOperation(cname, userId, uid, source, extras, 6058ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams runtimeMillis /* runtime */, 6068ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams beforeRunTimeMillis /* flextime */, 6078ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams backoffTime, 6088ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams delayUntil)); 609fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams } 610fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams 611fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams /** 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Initiate a sync. This can start a sync for all providers 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * (pass null to url, set onlyTicklable to false), only those 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * providers that are marked as ticklable (pass null to url, 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * set onlyTicklable to true), or a specific provider (set url 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to the content url of the provider). 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the ContentResolver.SYNC_EXTRAS_UPLOAD boolean in extras is 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * true then initiate a sync that just checks for local changes to send 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to the server, otherwise initiate a sync that first gets any 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * changes from the server before sending local changes back to 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the server. 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If a specific provider is being synced (the url is non-null) 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * then the extras can contain SyncAdapter-specific information 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to control what gets synced (e.g. which specific feed to sync). 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>You'll start getting callbacks after this. 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 630ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param requestedAccount the account to sync, may be null to signify all accounts 63104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani * @param userId the id of the user whose accounts are to be synced. If userId is USER_ALL, 63204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani * then all users' accounts are considered. 63357286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert * @param reason for sync request. If this is a positive integer, it is the Linux uid 63457286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert * assigned to the process that requested the sync. If it's negative, the sync was requested by 63557286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert * the SyncManager itself and could be one of the following: 63657286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert * {@link SyncOperation#REASON_BACKGROUND_DATA_SETTINGS_CHANGED} 63757286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert * {@link SyncOperation#REASON_ACCOUNTS_UPDATED} 63857286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert * {@link SyncOperation#REASON_SERVICE_CHANGED} 63957286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert * {@link SyncOperation#REASON_PERIODIC} 64057286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert * {@link SyncOperation#REASON_IS_SYNCABLE} 64157286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert * {@link SyncOperation#REASON_SYNC_AUTO} 64257286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert * {@link SyncOperation#REASON_MASTER_SYNC_AUTO} 64357286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert * {@link SyncOperation#REASON_USER_START} 644ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param requestedAuthority the authority to sync, may be null to indicate all authorities 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param extras a Map of SyncAdapter-specific information to control 646918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana * syncs of a specific provider. Can be null. Is ignored 647918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana * if the url is null. 648fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams * @param beforeRuntimeMillis milliseconds before runtimeMillis that this sync can run. 649fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams * @param runtimeMillis maximum milliseconds in the future to wait before performing sync. 650fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams * @param onlyThoseWithUnkownSyncableState Only sync authorities that have unknown state. 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 65257286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert public void scheduleSync(Account requestedAccount, int userId, int reason, 653fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams String requestedAuthority, Bundle extras, long beforeRuntimeMillis, 654fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams long runtimeMillis, boolean onlyThoseWithUnkownSyncableState) { 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE); 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 657fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams if (extras == null) { 658fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams extras = new Bundle(); 659fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams } 660fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams if (isLoggable) { 661fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams Log.d(TAG, "one-time sync for: " + requestedAccount + " " + extras.toString() + " " 662fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams + requestedAuthority); 663fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams } 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Boolean expedited = extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false); 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (expedited) { 666fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams runtimeMillis = -1; // this means schedule at the front of the queue 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 66904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani AccountAndUser[] accounts; 670f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn if (requestedAccount != null && userId != UserHandle.USER_ALL) { 67104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts = new AccountAndUser[] { new AccountAndUser(requestedAccount, userId) }; 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6736ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey accounts = mRunningAccounts; 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (accounts.length == 0) { 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isLoggable) { 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.v(TAG, "scheduleSync: no accounts configured, dropping"); 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean uploadOnly = extras.getBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD, false); 683ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana final boolean manualSync = extras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false); 68453bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (manualSync) { 68553bd2522ca7767f46646606123b6e2689b811850Fred Quintana extras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, true); 68653bd2522ca7767f46646606123b6e2689b811850Fred Quintana extras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, true); 68753bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 68853bd2522ca7767f46646606123b6e2689b811850Fred Quintana final boolean ignoreSettings = 68953bd2522ca7767f46646606123b6e2689b811850Fred Quintana extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, false); 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int source; 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (uploadOnly) { 693231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn source = SyncStorageEngine.SOURCE_LOCAL; 694ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } else if (manualSync) { 695231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn source = SyncStorageEngine.SOURCE_USER; 696ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } else if (requestedAuthority == null) { 697231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn source = SyncStorageEngine.SOURCE_POLL; 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this isn't strictly server, since arbitrary callers can (and do) request 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // a non-forced two-way sync on a specific url 701231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn source = SyncStorageEngine.SOURCE_SERVER; 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7046ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey for (AccountAndUser account : accounts) { 7056ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey // Compile a list of authorities that have sync adapters. 7066ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey // For each authority sync each account that matches a sync adapter. 7076ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final HashSet<String> syncableAuthorities = new HashSet<String>(); 7086ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey for (RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapter : 7096ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey mSyncAdapters.getAllServices(account.userId)) { 7106ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey syncableAuthorities.add(syncAdapter.type.authority); 7116ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey } 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7136ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey // if the url was specified then replace the list of authorities 7146ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey // with just this authority or clear it if this authority isn't 7156ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey // syncable 7166ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey if (requestedAuthority != null) { 7176ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final boolean hasSyncAdapter = syncableAuthorities.contains(requestedAuthority); 7186ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey syncableAuthorities.clear(); 7196ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey if (hasSyncAdapter) syncableAuthorities.add(requestedAuthority); 7206ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey } 721718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 7226ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey for (String authority : syncableAuthorities) { 7239422bdca314064fe82075b90cf529865c8053c44Amith Yamasani int isSyncable = getIsSyncable(account.account, account.userId, 72404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani authority); 7254a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana if (isSyncable == 0) { 7265e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana continue; 7275e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 7286ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo; 7296ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey syncAdapterInfo = mSyncAdapters.getServiceInfo( 7306ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey SyncAdapterType.newKey(authority, account.account.type), account.userId); 7310c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana if (syncAdapterInfo == null) { 7320c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana continue; 7330c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana } 7340c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana final boolean allowParallelSyncs = syncAdapterInfo.type.allowParallelSyncs(); 7350c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana final boolean isAlwaysSyncable = syncAdapterInfo.type.isAlwaysSyncable(); 7360c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana if (isSyncable < 0 && isAlwaysSyncable) { 73704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani mSyncStorageEngine.setIsSyncable(account.account, account.userId, authority, 1); 7380c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana isSyncable = 1; 7390c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana } 7400c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana if (onlyThoseWithUnkownSyncableState && isSyncable >= 0) { 7410c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana continue; 7420c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana } 7430c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana if (!syncAdapterInfo.type.supportsUploading() && uploadOnly) { 7440c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana continue; 7450c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana } 746f892fb3a431e04151382d1bddc4438fd04487a6aFred Quintana 7470c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana boolean syncAllowed = 74856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams (isSyncable < 0) // always allow if the isSyncable state is unknown 7490c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana || ignoreSettings 75056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams || (mSyncStorageEngine.getMasterSyncAutomatically(account.userId) 75104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani && mSyncStorageEngine.getSyncAutomatically(account.account, 75204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani account.userId, authority)); 7530c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana if (!syncAllowed) { 7540c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana if (isLoggable) { 7550c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana Log.d(TAG, "scheduleSync: sync of " + account + ", " + authority 7560c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana + " is not allowed, dropping request"); 7574a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana } 7580c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana continue; 7590c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana } 76056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams SyncStorageEngine.EndPoint info = 76156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams new SyncStorageEngine.EndPoint( 76256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams account.account, authority, account.userId); 76356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams Pair<Long, Long> backoff = mSyncStorageEngine.getBackoff(info); 76456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams long delayUntil = 76556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams mSyncStorageEngine.getDelayUntilTime(info); 7660c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana final long backoffTime = backoff != null ? backoff.first : 0; 7670c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana if (isSyncable < 0) { 768fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams // Initialisation sync. 7690c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana Bundle newExtras = new Bundle(); 7700c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana newExtras.putBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, true); 7710c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana if (isLoggable) { 772fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams Log.v(TAG, "schedule initialisation Sync:" 773fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams + ", delay until " + delayUntil 774fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams + ", run by " + 0 77556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams + ", flex " + 0 7760c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana + ", source " + source 7770c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana + ", account " + account 7780c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana + ", authority " + authority 7790c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana + ", extras " + newExtras); 780918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 7810c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana scheduleSyncOperation( 78257286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert new SyncOperation(account.account, account.userId, reason, source, 783fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams authority, newExtras, 0 /* immediate */, 0 /* No flex time*/, 784fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams backoffTime, delayUntil, allowParallelSyncs)); 7850c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana } 7860c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana if (!onlyThoseWithUnkownSyncableState) { 7870c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana if (isLoggable) { 7880c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana Log.v(TAG, "scheduleSync:" 789fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams + " delay until " + delayUntil 790fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams + " run by " + runtimeMillis 791fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams + " flex " + beforeRuntimeMillis 7920c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana + ", source " + source 7930c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana + ", account " + account 7940c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana + ", authority " + authority 7950c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana + ", extras " + extras); 796e0616ffb741b64e3bc7a1e3ad9def3d50eee53fdFred Quintana } 7970c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana scheduleSyncOperation( 79857286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert new SyncOperation(account.account, account.userId, reason, source, 799fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams authority, extras, runtimeMillis, beforeRuntimeMillis, 800fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams backoffTime, delayUntil, allowParallelSyncs)); 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 806fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams /** 807fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams * Schedule sync based on local changes to a provider. Occurs within interval 808fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams * [LOCAL_SYNC_DELAY, 2*LOCAL_SYNC_DELAY]. 809fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams */ 81057286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert public void scheduleLocalSync(Account account, int userId, int reason, String authority) { 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Bundle extras = new Bundle(); 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project extras.putBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD, true); 813fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams scheduleSync(account, userId, reason, authority, extras, 814fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams LOCAL_SYNC_DELAY /* earliest run time */, 815fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams 2 * LOCAL_SYNC_DELAY /* latest sync time. */, 8164a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana false /* onlyThoseWithUnkownSyncableState */); 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8196ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey public SyncAdapterType[] getSyncAdapterTypes(int userId) { 8206ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final Collection<RegisteredServicesCache.ServiceInfo<SyncAdapterType>> serviceInfos; 8216ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey serviceInfos = mSyncAdapters.getAllServices(userId); 822ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana SyncAdapterType[] types = new SyncAdapterType[serviceInfos.size()]; 823ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana int i = 0; 824ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana for (RegisteredServicesCache.ServiceInfo<SyncAdapterType> serviceInfo : serviceInfos) { 825ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana types[i] = serviceInfo.type; 826ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana ++i; 827ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 828ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return types; 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void sendSyncAlarmMessage() { 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "sending MESSAGE_SYNC_ALARM"); 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSyncHandler.sendEmptyMessage(SyncHandler.MESSAGE_SYNC_ALARM); 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void sendCheckAlarmsMessage() { 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "sending MESSAGE_CHECK_ALARMS"); 83869d95de53bc82e6c23c64ad566e428fbefae0543Ashish Sharma mSyncHandler.removeMessages(SyncHandler.MESSAGE_CHECK_ALARMS); 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSyncHandler.sendEmptyMessage(SyncHandler.MESSAGE_CHECK_ALARMS); 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void sendSyncFinishedOrCanceledMessage(ActiveSyncContext syncContext, 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SyncResult syncResult) { 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "sending MESSAGE_SYNC_FINISHED"); 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message msg = mSyncHandler.obtainMessage(); 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.what = SyncHandler.MESSAGE_SYNC_FINISHED; 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.obj = new SyncHandlerMessagePayload(syncContext, syncResult); 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSyncHandler.sendMessage(msg); 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 85156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams private void sendCancelSyncsMessage(final SyncStorageEngine.EndPoint info, Bundle extras) { 852918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "sending MESSAGE_CANCEL"); 853918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana Message msg = mSyncHandler.obtainMessage(); 854918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana msg.what = SyncHandler.MESSAGE_CANCEL; 85556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams msg.setData(extras); 85656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams msg.obj = info; 857918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana mSyncHandler.sendMessage(msg); 858918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 859918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana 86092a1c09aa467f03dad78472098d40992303937fbMatthew Williams /** 86192a1c09aa467f03dad78472098d40992303937fbMatthew Williams * Post a delayed message to the handler that will result in the cancellation of the provided 86292a1c09aa467f03dad78472098d40992303937fbMatthew Williams * running sync's context. 86392a1c09aa467f03dad78472098d40992303937fbMatthew Williams */ 86492a1c09aa467f03dad78472098d40992303937fbMatthew Williams private void postSyncExpiryMessage(ActiveSyncContext activeSyncContext) { 86592a1c09aa467f03dad78472098d40992303937fbMatthew Williams if (Log.isLoggable(TAG, Log.VERBOSE)) { 86692a1c09aa467f03dad78472098d40992303937fbMatthew Williams Log.v(TAG, "posting MESSAGE_SYNC_EXPIRED in " + 86792a1c09aa467f03dad78472098d40992303937fbMatthew Williams (ACTIVE_SYNC_TIMEOUT_MILLIS/1000) + "s"); 86892a1c09aa467f03dad78472098d40992303937fbMatthew Williams } 86992a1c09aa467f03dad78472098d40992303937fbMatthew Williams Message msg = mSyncHandler.obtainMessage(); 87092a1c09aa467f03dad78472098d40992303937fbMatthew Williams msg.what = SyncHandler.MESSAGE_SYNC_EXPIRED; 87192a1c09aa467f03dad78472098d40992303937fbMatthew Williams msg.obj = activeSyncContext; 87292a1c09aa467f03dad78472098d40992303937fbMatthew Williams mSyncHandler.sendMessageDelayed(msg, ACTIVE_SYNC_TIMEOUT_MILLIS); 87392a1c09aa467f03dad78472098d40992303937fbMatthew Williams } 87492a1c09aa467f03dad78472098d40992303937fbMatthew Williams 87592a1c09aa467f03dad78472098d40992303937fbMatthew Williams /** 87692a1c09aa467f03dad78472098d40992303937fbMatthew Williams * Remove any time-outs previously posted for the provided active sync. 87792a1c09aa467f03dad78472098d40992303937fbMatthew Williams */ 87892a1c09aa467f03dad78472098d40992303937fbMatthew Williams private void removeSyncExpiryMessage(ActiveSyncContext activeSyncContext) { 87992a1c09aa467f03dad78472098d40992303937fbMatthew Williams if (Log.isLoggable(TAG, Log.VERBOSE)) { 88092a1c09aa467f03dad78472098d40992303937fbMatthew Williams Log.v(TAG, "removing all MESSAGE_SYNC_EXPIRED for " + activeSyncContext.toString()); 88192a1c09aa467f03dad78472098d40992303937fbMatthew Williams } 88292a1c09aa467f03dad78472098d40992303937fbMatthew Williams mSyncHandler.removeMessages(SyncHandler.MESSAGE_SYNC_EXPIRED, activeSyncContext); 88392a1c09aa467f03dad78472098d40992303937fbMatthew Williams } 88492a1c09aa467f03dad78472098d40992303937fbMatthew Williams 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class SyncHandlerMessagePayload { 8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final ActiveSyncContext activeSyncContext; 8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final SyncResult syncResult; 8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SyncHandlerMessagePayload(ActiveSyncContext syncContext, SyncResult syncResult) { 8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.activeSyncContext = syncContext; 8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.syncResult = syncResult; 8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class SyncAlarmIntentReceiver extends BroadcastReceiver { 896fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams @Override 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onReceive(Context context, Intent intent) { 8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandleAlarmWakeLock.acquire(); 8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sendSyncAlarmMessage(); 9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9036e079a32bceb85a44da3b396f8d37e718d1421d5Alon Albert private void clearBackoffSetting(SyncOperation op) { 90456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams mSyncStorageEngine.setBackoff(op.target, 90556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams SyncStorageEngine.NOT_IN_BACKOFF_MODE, 90656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams SyncStorageEngine.NOT_IN_BACKOFF_MODE); 9076e079a32bceb85a44da3b396f8d37e718d1421d5Alon Albert synchronized (mSyncQueue) { 90856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams mSyncQueue.onBackoffChanged(op.target, 0); 9096e079a32bceb85a44da3b396f8d37e718d1421d5Alon Albert } 9106e079a32bceb85a44da3b396f8d37e718d1421d5Alon Albert } 9116e079a32bceb85a44da3b396f8d37e718d1421d5Alon Albert 912307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana private void increaseBackoffSetting(SyncOperation op) { 91369d95de53bc82e6c23c64ad566e428fbefae0543Ashish Sharma // TODO: Use this function to align it to an already scheduled sync 91469d95de53bc82e6c23c64ad566e428fbefae0543Ashish Sharma // operation in the specified window 915307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana final long now = SystemClock.elapsedRealtime(); 9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 917307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana final Pair<Long, Long> previousSettings = 91856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams mSyncStorageEngine.getBackoff(op.target); 919aeeb620906d037902d0c111a2272b6efd97f377aAlon Albert long newDelayInMs = -1; 920aeeb620906d037902d0c111a2272b6efd97f377aAlon Albert if (previousSettings != null) { 921aeeb620906d037902d0c111a2272b6efd97f377aAlon Albert // don't increase backoff before current backoff is expired. This will happen for op's 922aeeb620906d037902d0c111a2272b6efd97f377aAlon Albert // with ignoreBackoff set. 923aeeb620906d037902d0c111a2272b6efd97f377aAlon Albert if (now < previousSettings.first) { 924aeeb620906d037902d0c111a2272b6efd97f377aAlon Albert if (Log.isLoggable(TAG, Log.VERBOSE)) { 925aeeb620906d037902d0c111a2272b6efd97f377aAlon Albert Log.v(TAG, "Still in backoff, do not increase it. " 926aeeb620906d037902d0c111a2272b6efd97f377aAlon Albert + "Remaining: " + ((previousSettings.first - now) / 1000) + " seconds."); 927aeeb620906d037902d0c111a2272b6efd97f377aAlon Albert } 928aeeb620906d037902d0c111a2272b6efd97f377aAlon Albert return; 929aeeb620906d037902d0c111a2272b6efd97f377aAlon Albert } 930aeeb620906d037902d0c111a2272b6efd97f377aAlon Albert // Subsequent delays are the double of the previous delay 931aeeb620906d037902d0c111a2272b6efd97f377aAlon Albert newDelayInMs = previousSettings.second * 2; 932aeeb620906d037902d0c111a2272b6efd97f377aAlon Albert } 933aeeb620906d037902d0c111a2272b6efd97f377aAlon Albert if (newDelayInMs <= 0) { 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // The initial delay is the jitterized INITIAL_SYNC_RETRY_TIME_IN_MS 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newDelayInMs = jitterize(INITIAL_SYNC_RETRY_TIME_IN_MS, 9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (long)(INITIAL_SYNC_RETRY_TIME_IN_MS * 1.1)); 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Cap the delay 940625239a05401bbf18b04d9874cea3f82da7c29a1Jeff Sharkey long maxSyncRetryTimeInSeconds = Settings.Global.getLong(mContext.getContentResolver(), 941625239a05401bbf18b04d9874cea3f82da7c29a1Jeff Sharkey Settings.Global.SYNC_MAX_RETRY_DELAY_IN_SECONDS, 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project DEFAULT_MAX_SYNC_RETRY_TIME_IN_SECONDS); 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newDelayInMs > maxSyncRetryTimeInSeconds * 1000) { 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newDelayInMs = maxSyncRetryTimeInSeconds * 1000; 9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 947c1ac7769d884ad54a320ab3ec6d8406801cfb420Alon Albert final long backoff = now + newDelayInMs; 948c1ac7769d884ad54a320ab3ec6d8406801cfb420Alon Albert 94956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams mSyncStorageEngine.setBackoff(op.target, backoff, newDelayInMs); 950c1ac7769d884ad54a320ab3ec6d8406801cfb420Alon Albert op.backoff = backoff; 951c1ac7769d884ad54a320ab3ec6d8406801cfb420Alon Albert op.updateEffectiveRunTime(); 952c1ac7769d884ad54a320ab3ec6d8406801cfb420Alon Albert 953918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana synchronized (mSyncQueue) { 95456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams mSyncQueue.onBackoffChanged(op.target, backoff); 955918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 956307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana } 957307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana 958307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana private void setDelayUntilTime(SyncOperation op, long delayUntilSeconds) { 959307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana final long delayUntil = delayUntilSeconds * 1000; 960307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana final long absoluteNow = System.currentTimeMillis(); 961307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana long newDelayUntilTime; 962307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana if (delayUntil > absoluteNow) { 963307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana newDelayUntilTime = SystemClock.elapsedRealtime() + (delayUntil - absoluteNow); 964307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana } else { 965307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana newDelayUntilTime = 0; 966307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana } 96756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams mSyncStorageEngine.setDelayUntilTime(op.target, newDelayUntilTime); 968918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana synchronized (mSyncQueue) { 96956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams mSyncQueue.onDelayUntilTimeChanged(op.target, newDelayUntilTime); 970918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9748ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams * Cancel the active sync if it matches the target. 9758ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams * @param info object containing info about which syncs to cancel. The target can 97656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams * have null account/provider info to specify all accounts/providers. 97756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams * @param extras if non-null, specifies the exact sync to remove. 9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 97956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams public void cancelActiveSync(SyncStorageEngine.EndPoint info, Bundle extras) { 98056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams sendCancelSyncsMessage(info, extras); 9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Create and schedule a SyncOperation. 9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param syncOperation the SyncOperation to schedule 9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void scheduleSyncOperation(SyncOperation syncOperation) { 989307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana boolean queueChanged; 9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mSyncQueue) { 991307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana queueChanged = mSyncQueue.add(syncOperation); 9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 994307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana if (queueChanged) { 9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Log.isLoggable(TAG, Log.VERBOSE)) { 9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.v(TAG, "scheduleSyncOperation: enqueued " + syncOperation); 9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sendCheckAlarmsMessage(); 9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Log.isLoggable(TAG, Log.VERBOSE)) { 10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.v(TAG, "scheduleSyncOperation: dropping duplicate sync operation " 10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + syncOperation); 10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1008ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Remove scheduled sync operations. 10098ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams * @param info limit the removals to operations that match this target. The target can 101056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams * have null account/provider info to specify all accounts/providers. 10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 101256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams public void clearScheduledSyncOperations(SyncStorageEngine.EndPoint info) { 10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mSyncQueue) { 101456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams mSyncQueue.remove(info, null /* all operations */); 10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 101656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams mSyncStorageEngine.setBackoff(info, 1017918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana SyncStorageEngine.NOT_IN_BACKOFF_MODE, SyncStorageEngine.NOT_IN_BACKOFF_MODE); 10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 102056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams /** 102156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams * Remove a specified sync, if it exists. 102256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams * @param info Authority for which the sync is to be removed. 102356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams * @param extras extras bundle to uniquely identify sync. 102456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams */ 102556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams public void cancelScheduledSyncOperation(SyncStorageEngine.EndPoint info, Bundle extras) { 102656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams synchronized (mSyncQueue) { 102756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams mSyncQueue.remove(info, extras); 102856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 102956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams // Reset the back-off if there are no more syncs pending. 103056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (!mSyncStorageEngine.isSyncPending(info)) { 103156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams mSyncStorageEngine.setBackoff(info, 103256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams SyncStorageEngine.NOT_IN_BACKOFF_MODE, SyncStorageEngine.NOT_IN_BACKOFF_MODE); 103356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 103456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 103556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams 1036307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana void maybeRescheduleSync(SyncResult syncResult, SyncOperation operation) { 10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean isLoggable = Log.isLoggable(TAG, Log.DEBUG); 10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isLoggable) { 1039307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana Log.d(TAG, "encountered error(s) during the sync: " + syncResult + ", " + operation); 10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 104256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams operation = new SyncOperation(operation, 0L /* newRunTimeFromNow */); 104353bd2522ca7767f46646606123b6e2689b811850Fred Quintana 104453bd2522ca7767f46646606123b6e2689b811850Fred Quintana // The SYNC_EXTRAS_IGNORE_BACKOFF only applies to the first attempt to sync a given 104553bd2522ca7767f46646606123b6e2689b811850Fred Quintana // request. Retries of the request will always honor the backoff, so clear the 104653bd2522ca7767f46646606123b6e2689b811850Fred Quintana // flag in case we retry this request. 104753bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (operation.extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, false)) { 104853bd2522ca7767f46646606123b6e2689b811850Fred Quintana operation.extras.remove(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF); 104953bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 105053bd2522ca7767f46646606123b6e2689b811850Fred Quintana 105153bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (operation.extras.getBoolean(ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY, false)) { 105256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (isLoggable) { 105356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams Log.d(TAG, "not retrying sync operation because SYNC_EXTRAS_DO_NOT_RETRY was specified " 105456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams + operation); 105556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 1056918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } else if (operation.extras.getBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD, false) 1057918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana && !syncResult.syncAlreadyInProgress) { 105856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams // If this was an upward sync then schedule a two-way sync immediately. 105953bd2522ca7767f46646606123b6e2689b811850Fred Quintana operation.extras.remove(ContentResolver.SYNC_EXTRAS_UPLOAD); 106056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (isLoggable) { 106156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams Log.d(TAG, "retrying sync operation as a two-way sync because an upload-only sync " 106256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams + "encountered an error: " + operation); 106356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 106453bd2522ca7767f46646606123b6e2689b811850Fred Quintana scheduleSyncOperation(operation); 1065307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana } else if (syncResult.tooManyRetries) { 106656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams // If this sync aborted because the internal sync loop retried too many times then 106756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams // don't reschedule. Otherwise we risk getting into a retry loop. 106856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (isLoggable) { 106956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams Log.d(TAG, "not retrying sync operation because it retried too many times: " 107056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams + operation); 107156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 1072aa7edda4719dc0accbc29ff917b4280f6b600675Fred Quintana } else if (syncResult.madeSomeProgress()) { 107356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams // If the operation succeeded to some extent then retry immediately. 10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isLoggable) { 1075307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana Log.d(TAG, "retrying sync operation because even though it had an error " 1076307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana + "it achieved some success"); 10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 107853bd2522ca7767f46646606123b6e2689b811850Fred Quintana scheduleSyncOperation(operation); 10798570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana } else if (syncResult.syncAlreadyInProgress) { 10808570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana if (isLoggable) { 10818570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana Log.d(TAG, "retrying sync operation that failed because there was already a " 10828570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana + "sync in progress: " + operation); 10838570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana } 1084fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams scheduleSyncOperation( 1085fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams new SyncOperation( 108656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams operation, 108756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams DELAY_RETRY_SYNC_IN_PROGRESS_IN_SECONDS * 1000 /* newRunTimeFromNow */) 108856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams ); 10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (syncResult.hasSoftError()) { 109056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams // If this was a two-way sync then retry soft errors with an exponential backoff. 1091307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana if (isLoggable) { 1092307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana Log.d(TAG, "retrying sync operation because it encountered a soft error: " 1093307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana + operation); 10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 109553bd2522ca7767f46646606123b6e2689b811850Fred Quintana scheduleSyncOperation(operation); 10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 109756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams // Otherwise do not reschedule. 1098307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana Log.d(TAG, "not retrying sync operation because the error is a hard error: " 1099307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana + operation); 11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11036ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey private void onUserStarting(int userId) { 11046eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey // Make sure that accounts we're about to use are valid 11056eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey AccountManagerService.getSingleton().validateAccounts(userId); 11066eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey 11076ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey mSyncAdapters.invalidateCache(userId); 11086ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 11096ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey updateRunningAccounts(); 11106ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 1111a706e2fd0059b1bb86c487722dbc9fc0fda9c980Jeff Sharkey synchronized (mSyncQueue) { 1112a706e2fd0059b1bb86c487722dbc9fc0fda9c980Jeff Sharkey mSyncQueue.addPendingOperations(userId); 1113a706e2fd0059b1bb86c487722dbc9fc0fda9c980Jeff Sharkey } 11146ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 11156ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey // Schedule sync for any accounts under started user 11168f55d112983aa922687de7e3581f73913c06e37aJeff Sharkey final Account[] accounts = AccountManagerService.getSingleton().getAccounts(userId); 11176ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey for (Account account : accounts) { 111857286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert scheduleSync(account, userId, SyncOperation.REASON_USER_START, null, null, 1119fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams 0 /* no delay */, 0 /* No flex */, 1120fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams true /* onlyThoseWithUnknownSyncableState */); 11216ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey } 11226ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 11236ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey sendCheckAlarmsMessage(); 11246ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey } 11256ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 11266ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey private void onUserStopping(int userId) { 11276ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey updateRunningAccounts(); 11286ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 11296ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey cancelActiveSync( 113056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams new SyncStorageEngine.EndPoint( 113156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams null /* any account */, 113256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams null /* any authority */, 113356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams userId), 113456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams null /* any sync. */ 113556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams ); 11368e28555f6d4ea557ba79e3d411ea46e5a0788b8fAlon Albert } 1137135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani 11386ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey private void onUserRemoved(int userId) { 11396ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey updateRunningAccounts(); 11406ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 1141135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani // Clean up the storage engine database 1142135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani mSyncStorageEngine.doDatabaseCleanup(new Account[0], userId); 1143135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani synchronized (mSyncQueue) { 114456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams mSyncQueue.removeUserLocked(userId); 1145135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani } 1146135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani } 1147135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani 11489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 11499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 11509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1151eca7511f61a6bfbb43a6646f87b5771bcc5d3fdcAlon Albert class ActiveSyncContext extends ISyncContext.Stub 1152eca7511f61a6bfbb43a6646f87b5771bcc5d3fdcAlon Albert implements ServiceConnection, IBinder.DeathRecipient { 11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final SyncOperation mSyncOperation; 11549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final long mHistoryRowId; 1155718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana ISyncAdapter mSyncAdapter; 115656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams ISyncServiceAdapter mSyncServiceAdapter; 11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final long mStartTime; 11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long mTimeoutStartTime; 11593ec4730e375689b8ad9a03fcf98ff7773d726ddaFred Quintana boolean mBound; 1160918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana final PowerManager.WakeLock mSyncWakeLock; 1161918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana final int mSyncAdapterUid; 1162918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana SyncInfo mSyncInfo; 1163eca7511f61a6bfbb43a6646f87b5771bcc5d3fdcAlon Albert boolean mIsLinkedToDeath = false; 1164a1f1a3c573acd91024fda0ceb3b921c73b186963Dianne Hackborn String mEventName; 11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1166918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana /** 1167918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana * Create an ActiveSyncContext for an impending sync and grab the wakelock for that 1168918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana * sync adapter. Since this grabs the wakelock you need to be sure to call 1169918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana * close() when you are done with this ActiveSyncContext, whether the sync succeeded 1170918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana * or not. 1171918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana * @param syncOperation the SyncOperation we are about to sync 1172918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana * @param historyRowId the row in which to record the history info for this sync 1173918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana * @param syncAdapterUid the UID of the application that contains the sync adapter 1174918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana * for this sync. This is used to attribute the wakelock hold to that application. 1175918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana */ 1176918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana public ActiveSyncContext(SyncOperation syncOperation, long historyRowId, 1177918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana int syncAdapterUid) { 11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(); 1179918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana mSyncAdapterUid = syncAdapterUid; 11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSyncOperation = syncOperation; 11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHistoryRowId = historyRowId; 1182718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana mSyncAdapter = null; 118356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams mSyncServiceAdapter = null; 11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStartTime = SystemClock.elapsedRealtime(); 11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTimeoutStartTime = mStartTime; 118656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams mSyncWakeLock = mSyncHandler.getSyncWakeLock(mSyncOperation); 1187918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana mSyncWakeLock.setWorkSource(new WorkSource(syncAdapterUid)); 1188918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana mSyncWakeLock.acquire(); 11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void sendHeartbeat() { 1192307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana // heartbeats are no longer used 11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onFinished(SyncResult result) { 1196918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "onFinished: " + this); 11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // include "this" in the message so that the handler can ignore it if this 11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // ActiveSyncContext is no longer the mActiveSyncContext at message handling 11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // time 12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sendSyncFinishedOrCanceledMessage(this, result); 12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void toString(StringBuilder sb) { 12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sb.append("startTime ").append(mStartTime) 12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project .append(", mTimeoutStartTime ").append(mTimeoutStartTime) 12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project .append(", mHistoryRowId ").append(mHistoryRowId) 12079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project .append(", syncOperation ").append(mSyncOperation); 12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1210718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana public void onServiceConnected(ComponentName name, IBinder service) { 1211718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana Message msg = mSyncHandler.obtainMessage(); 1212718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana msg.what = SyncHandler.MESSAGE_SERVICE_CONNECTED; 121356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams msg.obj = new ServiceConnectionData(this, service); 1214718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana mSyncHandler.sendMessage(msg); 1215718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 1216718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 1217718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana public void onServiceDisconnected(ComponentName name) { 1218718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana Message msg = mSyncHandler.obtainMessage(); 1219718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana msg.what = SyncHandler.MESSAGE_SERVICE_DISCONNECTED; 1220718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana msg.obj = new ServiceConnectionData(this, null); 1221718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana mSyncHandler.sendMessage(msg); 1222718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 1223718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 122456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams boolean bindToSyncAdapter(ComponentName serviceComponent, int userId) { 1225718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 122656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams Log.d(TAG, "bindToSyncAdapter: " + serviceComponent + ", connection " + this); 1227718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 1228718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana Intent intent = new Intent(); 1229718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana intent.setAction("android.content.SyncAdapter"); 123056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams intent.setComponent(serviceComponent); 1231dd9b82c283815747b75fe4434c65e4b6c9c9b54fDianne Hackborn intent.putExtra(Intent.EXTRA_CLIENT_LABEL, 1232dd9b82c283815747b75fe4434c65e4b6c9c9b54fDianne Hackborn com.android.internal.R.string.sync_binding_label); 12334120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn intent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivityAsUser( 12344120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn mContext, 0, new Intent(Settings.ACTION_SYNC_SETTINGS), 0, 12354120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn null, new UserHandle(userId))); 12363ec4730e375689b8ad9a03fcf98ff7773d726ddaFred Quintana mBound = true; 123727b89e6658a0d233a53f5d7ca20dc57fec82d955Amith Yamasani final boolean bindResult = mContext.bindServiceAsUser(intent, this, 1238e02c88af7935c72fb90a478375e61e4a94465587Dianne Hackborn Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND 123904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani | Context.BIND_ALLOW_OOM_MANAGEMENT, 124056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams new UserHandle(mSyncOperation.target.userId)); 12413ec4730e375689b8ad9a03fcf98ff7773d726ddaFred Quintana if (!bindResult) { 12423ec4730e375689b8ad9a03fcf98ff7773d726ddaFred Quintana mBound = false; 1243a1f1a3c573acd91024fda0ceb3b921c73b186963Dianne Hackborn } else { 1244a1f1a3c573acd91024fda0ceb3b921c73b186963Dianne Hackborn try { 1245d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn mEventName = mSyncOperation.wakeLockName(); 1246fdb1956ff71ff57fcdaafaaeb7f42c19de3d7c2fDianne Hackborn mBatteryStats.noteSyncStart(mEventName, mSyncAdapterUid); 1247a1f1a3c573acd91024fda0ceb3b921c73b186963Dianne Hackborn } catch (RemoteException e) { 1248a1f1a3c573acd91024fda0ceb3b921c73b186963Dianne Hackborn } 12493ec4730e375689b8ad9a03fcf98ff7773d726ddaFred Quintana } 12503ec4730e375689b8ad9a03fcf98ff7773d726ddaFred Quintana return bindResult; 1251718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 1252718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 1253918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana /** 1254918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana * Performs the required cleanup, which is the releasing of the wakelock and 1255918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana * unbinding from the sync adapter (if actually bound). 1256918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana */ 12573ec4730e375689b8ad9a03fcf98ff7773d726ddaFred Quintana protected void close() { 1258718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1259718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana Log.d(TAG, "unBindFromSyncAdapter: connection " + this); 1260718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 12613ec4730e375689b8ad9a03fcf98ff7773d726ddaFred Quintana if (mBound) { 12623ec4730e375689b8ad9a03fcf98ff7773d726ddaFred Quintana mBound = false; 12633ec4730e375689b8ad9a03fcf98ff7773d726ddaFred Quintana mContext.unbindService(this); 1264a1f1a3c573acd91024fda0ceb3b921c73b186963Dianne Hackborn try { 1265fdb1956ff71ff57fcdaafaaeb7f42c19de3d7c2fDianne Hackborn mBatteryStats.noteSyncFinish(mEventName, mSyncAdapterUid); 1266a1f1a3c573acd91024fda0ceb3b921c73b186963Dianne Hackborn } catch (RemoteException e) { 1267a1f1a3c573acd91024fda0ceb3b921c73b186963Dianne Hackborn } 12683ec4730e375689b8ad9a03fcf98ff7773d726ddaFred Quintana } 1269918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana mSyncWakeLock.release(); 1270c24ab866b0d46685f6ddd340b9c84375cf8d6831Dianne Hackborn mSyncWakeLock.setWorkSource(null); 1271718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 1272718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 12739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String toString() { 12749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project StringBuilder sb = new StringBuilder(); 12759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project toString(sb); 12769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return sb.toString(); 12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1278eca7511f61a6bfbb43a6646f87b5771bcc5d3fdcAlon Albert 1279eca7511f61a6bfbb43a6646f87b5771bcc5d3fdcAlon Albert @Override 1280eca7511f61a6bfbb43a6646f87b5771bcc5d3fdcAlon Albert public void binderDied() { 1281eca7511f61a6bfbb43a6646f87b5771bcc5d3fdcAlon Albert sendSyncFinishedOrCanceledMessage(this, null); 1282eca7511f61a6bfbb43a6646f87b5771bcc5d3fdcAlon Albert } 12839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void dump(FileDescriptor fd, PrintWriter pw) { 12866ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); 12876ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey dumpSyncState(ipw); 12886ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey dumpSyncHistory(ipw); 12896ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey dumpSyncAdapters(ipw); 12909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1292231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn static String formatTime(long time) { 1293231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn Time tobj = new Time(); 1294231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn tobj.set(time); 1295231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return tobj.format("%Y-%m-%d %H:%M:%S"); 1296231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 129744f574781545781c31db3dcf495ed08763073f75Doug Zongker 1298e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert protected void dumpSyncState(PrintWriter pw) { 1299231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn pw.print("data connected: "); pw.println(mDataConnectionIsConnected); 130004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani pw.print("auto sync: "); 130104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani List<UserInfo> users = getAllUsers(); 130204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani if (users != null) { 130304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani for (UserInfo user : users) { 130404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani pw.print("u" + user.id + "=" 13056ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey + mSyncStorageEngine.getMasterSyncAutomatically(user.id) + " "); 130604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 130704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani pw.println(); 130804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 1309231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn pw.print("memory low: "); pw.println(mStorageIsLow); 13109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13116eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey final AccountAndUser[] accounts = AccountManagerService.getSingleton().getAllAccounts(); 131204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 13136eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey pw.print("accounts: "); 131453bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (accounts != INITIAL_ACCOUNTS_ARRAY) { 1315231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn pw.println(accounts.length); 13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 131753bd2522ca7767f46646606123b6e2689b811850Fred Quintana pw.println("not known yet"); 13189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final long now = SystemClock.elapsedRealtime(); 1320c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana pw.print("now: "); pw.print(now); 1321c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana pw.println(" (" + formatTime(System.currentTimeMillis()) + ")"); 132269d95de53bc82e6c23c64ad566e428fbefae0543Ashish Sharma pw.print("offset: "); pw.print(DateUtils.formatElapsedTime(mSyncRandomOffsetMillis/1000)); 132369d95de53bc82e6c23c64ad566e428fbefae0543Ashish Sharma pw.println(" (HH:MM:SS)"); 1324231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn pw.print("uptime: "); pw.print(DateUtils.formatElapsedTime(now/1000)); 1325231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn pw.println(" (HH:MM:SS)"); 1326231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn pw.print("time spent syncing: "); 1327231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn pw.print(DateUtils.formatElapsedTime( 1328231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mSyncHandler.mSyncTimeTracker.timeSpentSyncing() / 1000)); 1329231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn pw.print(" (HH:MM:SS), sync "); 1330231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn pw.print(mSyncHandler.mSyncTimeTracker.mLastWasSyncing ? "" : "not "); 1331231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn pw.println("in progress"); 13329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mSyncHandler.mAlarmScheduleTime != null) { 1333231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn pw.print("next alarm time: "); pw.print(mSyncHandler.mAlarmScheduleTime); 1334231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn pw.print(" ("); 1335231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn pw.print(DateUtils.formatElapsedTime((mSyncHandler.mAlarmScheduleTime-now)/1000)); 1336231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn pw.println(" (HH:MM:SS) from now)"); 13379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1338231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn pw.println("no alarm is scheduled (there had better not be any pending syncs)"); 13399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1341231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn pw.print("notification info: "); 1342e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert final StringBuilder sb = new StringBuilder(); 13439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSyncHandler.mSyncNotificationInfo.toString(sb); 1344231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn pw.println(sb.toString()); 13459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1346918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana pw.println(); 1347918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana pw.println("Active Syncs: " + mActiveSyncContexts.size()); 134857286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert final PackageManager pm = mContext.getPackageManager(); 1349918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana for (SyncManager.ActiveSyncContext activeSyncContext : mActiveSyncContexts) { 1350918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana final long durationInSeconds = (now - activeSyncContext.mStartTime) / 1000; 1351918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana pw.print(" "); 1352918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana pw.print(DateUtils.formatElapsedTime(durationInSeconds)); 1353918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana pw.print(" - "); 135457286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert pw.print(activeSyncContext.mSyncOperation.dump(pm, false)); 1355918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana pw.println(); 1356918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 1357918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana 13589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mSyncQueue) { 1359231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn sb.setLength(0); 13609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSyncQueue.dump(sb); 1361fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams // Dump Pending Operations. 1362fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams getSyncStorageEngine().dumpPendingOperations(sb); 13639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1364fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams 1365918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana pw.println(); 1366918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana pw.print(sb.toString()); 13679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1368c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana // join the installed sync adapter with the accounts list and emit for everything 1369c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana pw.println(); 1370c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana pw.println("Sync Status"); 137104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani for (AccountAndUser account : accounts) { 137257286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert pw.printf("Account %s u%d %s\n", 137357286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert account.account.name, account.userId, account.account.type); 137457286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert 137557286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert pw.println("======================================================================="); 137657286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert final PrintTable table = new PrintTable(13); 137757286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert table.set(0, 0, 137857286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "Authority", // 0 137957286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "Syncable", // 1 138057286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "Enabled", // 2 138157286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "Delay", // 3 138257286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "Loc", // 4 138357286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "Poll", // 5 138457286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "Per", // 6 138557286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "Serv", // 7 138657286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "User", // 8 138757286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "Tot", // 9 138857286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "Time", // 10 138957286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "Last Sync", // 11 139057286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "Periodic" // 12 139157286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert ); 139257286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert 139357286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert final List<RegisteredServicesCache.ServiceInfo<SyncAdapterType>> sorted = 139457286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert Lists.newArrayList(); 139557286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert sorted.addAll(mSyncAdapters.getAllServices(account.userId)); 139657286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert Collections.sort(sorted, 139757286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert new Comparator<RegisteredServicesCache.ServiceInfo<SyncAdapterType>>() { 139857286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert @Override 139957286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert public int compare(RegisteredServicesCache.ServiceInfo<SyncAdapterType> lhs, 140057286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert RegisteredServicesCache.ServiceInfo<SyncAdapterType> rhs) { 140157286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert return lhs.type.authority.compareTo(rhs.type.authority); 140257286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert } 140357286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert }); 140457286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert for (RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterType : sorted) { 140504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani if (!syncAdapterType.type.accountType.equals(account.account.type)) { 1406c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana continue; 1407c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 140857286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert int row = table.getNumRows(); 1409dbe846b02e6f6f715787cf8621587f7bc25deaacGeorgi Nikolov Pair<AuthorityInfo, SyncStatusInfo> syncAuthoritySyncStatus = 1410dbe846b02e6f6f715787cf8621587f7bc25deaacGeorgi Nikolov mSyncStorageEngine.getCopyOfAuthorityWithSyncStatus( 141156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams new SyncStorageEngine.EndPoint( 141256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams account.account, 141356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams syncAdapterType.type.authority, 141456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams account.userId)); 1415dbe846b02e6f6f715787cf8621587f7bc25deaacGeorgi Nikolov SyncStorageEngine.AuthorityInfo settings = syncAuthoritySyncStatus.first; 1416dbe846b02e6f6f715787cf8621587f7bc25deaacGeorgi Nikolov SyncStatusInfo status = syncAuthoritySyncStatus.second; 14178ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams String authority = settings.target.provider; 141857286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert if (authority.length() > 50) { 141957286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert authority = authority.substring(authority.length() - 50); 1420c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 142157286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert table.set(row, 0, authority, settings.syncable, settings.enabled); 142257286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert table.set(row, 4, 142357286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert status.numSourceLocal, 142457286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert status.numSourcePoll, 142557286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert status.numSourcePeriodic, 142657286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert status.numSourceServer, 142757286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert status.numSourceUser, 142857286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert status.numSyncs, 142957286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert DateUtils.formatElapsedTime(status.totalElapsedTime / 1000)); 143057286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert 143157286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert 143257286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert for (int i = 0; i < settings.periodicSyncs.size(); i++) { 1433fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams final PeriodicSync sync = settings.periodicSyncs.get(i); 1434fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams final String period = 1435fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams String.format("[p:%d s, f: %d s]", sync.period, sync.flexTime); 1436fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams final String extras = 1437fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams sync.extras.size() > 0 ? 1438fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams sync.extras.toString() : "Bundle[]"; 1439fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams final String next = "Next sync: " + formatTime(status.getPeriodicSyncTime(i) 1440fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams + sync.period * 1000); 1441fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams table.set(row + i * 2, 12, period + " " + extras); 144257286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert table.set(row + i * 2 + 1, 12, next); 1443c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 144457286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert 144557286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert int row1 = row; 144657286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert if (settings.delayUntil > now) { 144757286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert table.set(row1++, 12, "D: " + (settings.delayUntil - now) / 1000); 144857286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert if (settings.backoffTime > now) { 144957286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert table.set(row1++, 12, "B: " + (settings.backoffTime - now) / 1000); 145057286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert table.set(row1++, 12, settings.backoffDelay / 1000); 145157286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert } 1452c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 145357286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert 1454c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana if (status.lastSuccessTime != 0) { 145557286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert table.set(row1++, 11, SyncStorageEngine.SOURCES[status.lastSuccessSource] 145657286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert + " " + "SUCCESS"); 145757286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert table.set(row1++, 11, formatTime(status.lastSuccessTime)); 1458c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1459c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana if (status.lastFailureTime != 0) { 146057286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert table.set(row1++, 11, SyncStorageEngine.SOURCES[status.lastFailureSource] 146157286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert + " " + "FAILURE"); 146257286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert table.set(row1++, 11, formatTime(status.lastFailureTime)); 146357286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert //noinspection UnusedAssignment 146457286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert table.set(row1++, 11, status.lastFailureMesg); 14659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 146757286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert table.writeTo(pw); 14689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1471dc2dd88249f5e3df672fc3c7e18f3ddfb08e02b5Fabrice Di Meglio private String getLastFailureMessage(int code) { 1472dc2dd88249f5e3df672fc3c7e18f3ddfb08e02b5Fabrice Di Meglio switch (code) { 1473dc2dd88249f5e3df672fc3c7e18f3ddfb08e02b5Fabrice Di Meglio case ContentResolver.SYNC_ERROR_SYNC_ALREADY_IN_PROGRESS: 1474dc2dd88249f5e3df672fc3c7e18f3ddfb08e02b5Fabrice Di Meglio return "sync already in progress"; 1475dc2dd88249f5e3df672fc3c7e18f3ddfb08e02b5Fabrice Di Meglio 1476dc2dd88249f5e3df672fc3c7e18f3ddfb08e02b5Fabrice Di Meglio case ContentResolver.SYNC_ERROR_AUTHENTICATION: 1477dc2dd88249f5e3df672fc3c7e18f3ddfb08e02b5Fabrice Di Meglio return "authentication error"; 1478dc2dd88249f5e3df672fc3c7e18f3ddfb08e02b5Fabrice Di Meglio 1479dc2dd88249f5e3df672fc3c7e18f3ddfb08e02b5Fabrice Di Meglio case ContentResolver.SYNC_ERROR_IO: 1480dc2dd88249f5e3df672fc3c7e18f3ddfb08e02b5Fabrice Di Meglio return "I/O error"; 1481dc2dd88249f5e3df672fc3c7e18f3ddfb08e02b5Fabrice Di Meglio 1482dc2dd88249f5e3df672fc3c7e18f3ddfb08e02b5Fabrice Di Meglio case ContentResolver.SYNC_ERROR_PARSE: 1483dc2dd88249f5e3df672fc3c7e18f3ddfb08e02b5Fabrice Di Meglio return "parse error"; 1484dc2dd88249f5e3df672fc3c7e18f3ddfb08e02b5Fabrice Di Meglio 1485dc2dd88249f5e3df672fc3c7e18f3ddfb08e02b5Fabrice Di Meglio case ContentResolver.SYNC_ERROR_CONFLICT: 1486dc2dd88249f5e3df672fc3c7e18f3ddfb08e02b5Fabrice Di Meglio return "conflict error"; 1487dc2dd88249f5e3df672fc3c7e18f3ddfb08e02b5Fabrice Di Meglio 1488dc2dd88249f5e3df672fc3c7e18f3ddfb08e02b5Fabrice Di Meglio case ContentResolver.SYNC_ERROR_TOO_MANY_DELETIONS: 1489dc2dd88249f5e3df672fc3c7e18f3ddfb08e02b5Fabrice Di Meglio return "too many deletions error"; 1490dc2dd88249f5e3df672fc3c7e18f3ddfb08e02b5Fabrice Di Meglio 1491dc2dd88249f5e3df672fc3c7e18f3ddfb08e02b5Fabrice Di Meglio case ContentResolver.SYNC_ERROR_TOO_MANY_RETRIES: 1492dc2dd88249f5e3df672fc3c7e18f3ddfb08e02b5Fabrice Di Meglio return "too many retries error"; 1493dc2dd88249f5e3df672fc3c7e18f3ddfb08e02b5Fabrice Di Meglio 1494dc2dd88249f5e3df672fc3c7e18f3ddfb08e02b5Fabrice Di Meglio case ContentResolver.SYNC_ERROR_INTERNAL: 1495dc2dd88249f5e3df672fc3c7e18f3ddfb08e02b5Fabrice Di Meglio return "internal error"; 1496dc2dd88249f5e3df672fc3c7e18f3ddfb08e02b5Fabrice Di Meglio 1497dc2dd88249f5e3df672fc3c7e18f3ddfb08e02b5Fabrice Di Meglio default: 1498dc2dd88249f5e3df672fc3c7e18f3ddfb08e02b5Fabrice Di Meglio return "unknown"; 1499dc2dd88249f5e3df672fc3c7e18f3ddfb08e02b5Fabrice Di Meglio } 1500dc2dd88249f5e3df672fc3c7e18f3ddfb08e02b5Fabrice Di Meglio } 1501dc2dd88249f5e3df672fc3c7e18f3ddfb08e02b5Fabrice Di Meglio 1502231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private void dumpTimeSec(PrintWriter pw, long time) { 1503231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn pw.print(time/1000); pw.print('.'); pw.print((time/100)%10); 1504231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn pw.print('s'); 15059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 150644f574781545781c31db3dcf495ed08763073f75Doug Zongker 1507231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private void dumpDayStatistic(PrintWriter pw, SyncStorageEngine.DayStats ds) { 1508231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn pw.print("Success ("); pw.print(ds.successCount); 1509231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (ds.successCount > 0) { 1510231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn pw.print(" for "); dumpTimeSec(pw, ds.successTime); 1511231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn pw.print(" avg="); dumpTimeSec(pw, ds.successTime/ds.successCount); 1512231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1513231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn pw.print(") Failure ("); pw.print(ds.failureCount); 1514231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (ds.failureCount > 0) { 1515231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn pw.print(" for "); dumpTimeSec(pw, ds.failureTime); 1516231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn pw.print(" avg="); dumpTimeSec(pw, ds.failureTime/ds.failureCount); 1517231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1518231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn pw.println(")"); 15199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 152044f574781545781c31db3dcf495ed08763073f75Doug Zongker 1521e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert protected void dumpSyncHistory(PrintWriter pw) { 1522e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert dumpRecentHistory(pw); 1523e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert dumpDayStatistics(pw); 1524e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert } 1525e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert 1526e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert private void dumpRecentHistory(PrintWriter pw) { 1527e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert final ArrayList<SyncStorageEngine.SyncHistoryItem> items 1528e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert = mSyncStorageEngine.getSyncHistory(); 1529e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert if (items != null && items.size() > 0) { 1530e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert final Map<String, AuthoritySyncStats> authorityMap = Maps.newHashMap(); 1531e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert long totalElapsedTime = 0; 1532e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert long totalTimes = 0; 1533e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert final int N = items.size(); 1534e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert 1535e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert int maxAuthority = 0; 1536e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert int maxAccount = 0; 1537e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert for (SyncStorageEngine.SyncHistoryItem item : items) { 153856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams SyncStorageEngine.AuthorityInfo authorityInfo 1539e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert = mSyncStorageEngine.getAuthority(item.authorityId); 1540e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert final String authorityName; 1541e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert final String accountKey; 154256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (authorityInfo != null) { 15438ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams if (authorityInfo.target.target_provider) { 15448ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams authorityName = authorityInfo.target.provider; 15458ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams accountKey = authorityInfo.target.account.name + "/" 15468ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams + authorityInfo.target.account.type 15478ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams + " u" + authorityInfo.target.userId; 15488ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams } else if (authorityInfo.target.target_service) { 15498ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams authorityName = authorityInfo.target.service.getPackageName() + "/" 15508ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams + authorityInfo.target.service.getClassName() 15518ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams + " u" + authorityInfo.target.userId; 155256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams accountKey = "no account"; 155356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } else { 155456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams authorityName = "Unknown"; 155556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams accountKey = "Unknown"; 155656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 1557e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert } else { 1558e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert authorityName = "Unknown"; 1559e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert accountKey = "Unknown"; 1560e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert } 1561e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert 1562e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert int length = authorityName.length(); 1563e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert if (length > maxAuthority) { 1564e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert maxAuthority = length; 1565e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert } 1566e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert length = accountKey.length(); 1567e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert if (length > maxAccount) { 1568e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert maxAccount = length; 1569e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert } 1570e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert 1571e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert final long elapsedTime = item.elapsedTime; 1572e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert totalElapsedTime += elapsedTime; 1573e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert totalTimes++; 1574e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert AuthoritySyncStats authoritySyncStats = authorityMap.get(authorityName); 1575e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert if (authoritySyncStats == null) { 1576e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert authoritySyncStats = new AuthoritySyncStats(authorityName); 1577e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert authorityMap.put(authorityName, authoritySyncStats); 1578e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert } 1579e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert authoritySyncStats.elapsedTime += elapsedTime; 1580e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert authoritySyncStats.times++; 1581e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert final Map<String, AccountSyncStats> accountMap = authoritySyncStats.accountMap; 1582e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert AccountSyncStats accountSyncStats = accountMap.get(accountKey); 1583e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert if (accountSyncStats == null) { 1584e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert accountSyncStats = new AccountSyncStats(accountKey); 1585e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert accountMap.put(accountKey, accountSyncStats); 1586e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert } 1587e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert accountSyncStats.elapsedTime += elapsedTime; 1588e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert accountSyncStats.times++; 1589e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert 1590e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert } 1591e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert 159227096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert if (totalElapsedTime > 0) { 159327096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert pw.println(); 159427096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert pw.printf("Detailed Statistics (Recent history): " 159527096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert + "%d (# of times) %ds (sync time)\n", 159627096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert totalTimes, totalElapsedTime / 1000); 159727096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert 159827096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert final List<AuthoritySyncStats> sortedAuthorities = 159927096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert new ArrayList<AuthoritySyncStats>(authorityMap.values()); 160027096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert Collections.sort(sortedAuthorities, new Comparator<AuthoritySyncStats>() { 1601bf976ba6576a8ebf0e25f10eca83cb8038578510Alon Albert @Override 160227096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert public int compare(AuthoritySyncStats lhs, AuthoritySyncStats rhs) { 1603bf976ba6576a8ebf0e25f10eca83cb8038578510Alon Albert // reverse order 1604bf976ba6576a8ebf0e25f10eca83cb8038578510Alon Albert int compare = Integer.compare(rhs.times, lhs.times); 1605bf976ba6576a8ebf0e25f10eca83cb8038578510Alon Albert if (compare == 0) { 1606bf976ba6576a8ebf0e25f10eca83cb8038578510Alon Albert compare = Long.compare(rhs.elapsedTime, lhs.elapsedTime); 1607e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert } 1608bf976ba6576a8ebf0e25f10eca83cb8038578510Alon Albert return compare; 1609e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert } 1610bf976ba6576a8ebf0e25f10eca83cb8038578510Alon Albert }); 161127096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert 161227096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert final int maxLength = Math.max(maxAuthority, maxAccount + 3); 161327096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert final int padLength = 2 + 2 + maxLength + 2 + 10 + 11; 161427096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert final char chars[] = new char[padLength]; 161527096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert Arrays.fill(chars, '-'); 161627096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert final String separator = new String(chars); 161727096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert 161827096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert final String authorityFormat = 161927096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert String.format(" %%-%ds: %%-9s %%-11s\n", maxLength + 2); 162027096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert final String accountFormat = 162127096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert String.format(" %%-%ds: %%-9s %%-11s\n", maxLength); 162227096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert 162327096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert pw.println(separator); 162427096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert for (AuthoritySyncStats authoritySyncStats : sortedAuthorities) { 162527096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert String name = authoritySyncStats.name; 162627096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert long elapsedTime; 162727096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert int times; 162827096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert String timeStr; 162927096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert String timesStr; 163027096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert 163127096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert elapsedTime = authoritySyncStats.elapsedTime; 163227096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert times = authoritySyncStats.times; 1633bf976ba6576a8ebf0e25f10eca83cb8038578510Alon Albert timeStr = String.format("%ds/%d%%", 1634bf976ba6576a8ebf0e25f10eca83cb8038578510Alon Albert elapsedTime / 1000, 1635bf976ba6576a8ebf0e25f10eca83cb8038578510Alon Albert elapsedTime * 100 / totalElapsedTime); 1636bf976ba6576a8ebf0e25f10eca83cb8038578510Alon Albert timesStr = String.format("%d/%d%%", 1637bf976ba6576a8ebf0e25f10eca83cb8038578510Alon Albert times, 1638bf976ba6576a8ebf0e25f10eca83cb8038578510Alon Albert times * 100 / totalTimes); 163927096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert pw.printf(authorityFormat, name, timesStr, timeStr); 164027096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert 164127096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert final List<AccountSyncStats> sortedAccounts = 164227096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert new ArrayList<AccountSyncStats>( 164327096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert authoritySyncStats.accountMap.values()); 164427096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert Collections.sort(sortedAccounts, new Comparator<AccountSyncStats>() { 164527096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert @Override 164627096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert public int compare(AccountSyncStats lhs, AccountSyncStats rhs) { 164727096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert // reverse order 164827096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert int compare = Integer.compare(rhs.times, lhs.times); 164927096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert if (compare == 0) { 165027096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert compare = Long.compare(rhs.elapsedTime, lhs.elapsedTime); 165127096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert } 165227096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert return compare; 165327096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert } 165427096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert }); 165527096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert for (AccountSyncStats stats: sortedAccounts) { 165627096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert elapsedTime = stats.elapsedTime; 165727096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert times = stats.times; 165827096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert timeStr = String.format("%ds/%d%%", 165927096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert elapsedTime / 1000, 166027096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert elapsedTime * 100 / totalElapsedTime); 166127096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert timesStr = String.format("%d/%d%%", 166227096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert times, 166327096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert times * 100 / totalTimes); 166427096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert pw.printf(accountFormat, stats.name, timesStr, timeStr); 166527096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert } 166627096822e2da828e0f41c0337cf6f0f11e5bace5Alon Albert pw.println(separator); 1667e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert } 1668e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert } 1669e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert 1670e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert pw.println(); 1671e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert pw.println("Recent Sync History"); 167257286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert final String format = " %-" + maxAccount + "s %-" + maxAuthority + "s %s\n"; 1673bf976ba6576a8ebf0e25f10eca83cb8038578510Alon Albert final Map<String, Long> lastTimeMap = Maps.newHashMap(); 167457286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert final PackageManager pm = mContext.getPackageManager(); 1675e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert for (int i = 0; i < N; i++) { 1676e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert SyncStorageEngine.SyncHistoryItem item = items.get(i); 167756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams SyncStorageEngine.AuthorityInfo authorityInfo 1678e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert = mSyncStorageEngine.getAuthority(item.authorityId); 1679e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert final String authorityName; 1680e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert final String accountKey; 168156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (authorityInfo != null) { 16828ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams if (authorityInfo.target.target_provider) { 16838ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams authorityName = authorityInfo.target.provider; 16848ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams accountKey = authorityInfo.target.account.name + "/" 16858ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams + authorityInfo.target.account.type 16868ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams + " u" + authorityInfo.target.userId; 16878ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams } else if (authorityInfo.target.target_service) { 16888ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams authorityName = authorityInfo.target.service.getPackageName() + "/" 16898ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams + authorityInfo.target.service.getClassName() 16908ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams + " u" + authorityInfo.target.userId; 169156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams accountKey = "none"; 169256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } else { 169356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams authorityName = "Unknown"; 169456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams accountKey = "Unknown"; 169556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 1696e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert } else { 1697e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert authorityName = "Unknown"; 1698e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert accountKey = "Unknown"; 1699e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert } 1700e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert final long elapsedTime = item.elapsedTime; 1701e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert final Time time = new Time(); 1702e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert final long eventTime = item.eventTime; 1703e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert time.set(eventTime); 1704e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert 1705bf976ba6576a8ebf0e25f10eca83cb8038578510Alon Albert final String key = authorityName + "/" + accountKey; 1706bf976ba6576a8ebf0e25f10eca83cb8038578510Alon Albert final Long lastEventTime = lastTimeMap.get(key); 1707bf976ba6576a8ebf0e25f10eca83cb8038578510Alon Albert final String diffString; 1708bf976ba6576a8ebf0e25f10eca83cb8038578510Alon Albert if (lastEventTime == null) { 1709bf976ba6576a8ebf0e25f10eca83cb8038578510Alon Albert diffString = ""; 1710e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert } else { 1711bf976ba6576a8ebf0e25f10eca83cb8038578510Alon Albert final long diff = (lastEventTime - eventTime) / 1000; 1712bf976ba6576a8ebf0e25f10eca83cb8038578510Alon Albert if (diff < 60) { 1713bf976ba6576a8ebf0e25f10eca83cb8038578510Alon Albert diffString = String.valueOf(diff); 1714bf976ba6576a8ebf0e25f10eca83cb8038578510Alon Albert } else if (diff < 3600) { 1715bf976ba6576a8ebf0e25f10eca83cb8038578510Alon Albert diffString = String.format("%02d:%02d", diff / 60, diff % 60); 1716bf976ba6576a8ebf0e25f10eca83cb8038578510Alon Albert } else { 1717bf976ba6576a8ebf0e25f10eca83cb8038578510Alon Albert final long sec = diff % 3600; 1718bf976ba6576a8ebf0e25f10eca83cb8038578510Alon Albert diffString = String.format("%02d:%02d:%02d", 1719bf976ba6576a8ebf0e25f10eca83cb8038578510Alon Albert diff / 3600, sec / 60, sec % 60); 1720bf976ba6576a8ebf0e25f10eca83cb8038578510Alon Albert } 1721e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert } 1722bf976ba6576a8ebf0e25f10eca83cb8038578510Alon Albert lastTimeMap.put(key, eventTime); 1723e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert 1724bf976ba6576a8ebf0e25f10eca83cb8038578510Alon Albert pw.printf(" #%-3d: %s %8s %5.1fs %8s", 1725bf976ba6576a8ebf0e25f10eca83cb8038578510Alon Albert i + 1, 1726bf976ba6576a8ebf0e25f10eca83cb8038578510Alon Albert formatTime(eventTime), 1727bf976ba6576a8ebf0e25f10eca83cb8038578510Alon Albert SyncStorageEngine.SOURCES[item.source], 1728bf976ba6576a8ebf0e25f10eca83cb8038578510Alon Albert ((float) elapsedTime) / 1000, 1729bf976ba6576a8ebf0e25f10eca83cb8038578510Alon Albert diffString); 173057286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert pw.printf(format, accountKey, authorityName, 173157286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert SyncOperation.reasonToString(pm, item.reason)); 1732e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert 1733e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert if (item.event != SyncStorageEngine.EVENT_STOP 1734e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert || item.upstreamActivity != 0 1735e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert || item.downstreamActivity != 0) { 1736e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert pw.printf(" event=%d upstreamActivity=%d downstreamActivity=%d\n", 1737e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert item.event, 1738e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert item.upstreamActivity, 1739e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert item.downstreamActivity); 1740e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert } 1741e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert if (item.mesg != null 1742e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert && !SyncStorageEngine.MESG_SUCCESS.equals(item.mesg)) { 1743e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert pw.printf(" mesg=%s\n", item.mesg); 1744e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert } 1745e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert } 174657286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert pw.println(); 174757286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert pw.println("Recent Sync History Extras"); 174857286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert for (int i = 0; i < N; i++) { 174957286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert final SyncStorageEngine.SyncHistoryItem item = items.get(i); 175057286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert final Bundle extras = item.extras; 175157286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert if (extras == null || extras.size() == 0) { 175257286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert continue; 175357286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert } 175456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams final SyncStorageEngine.AuthorityInfo authorityInfo 175557286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert = mSyncStorageEngine.getAuthority(item.authorityId); 175657286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert final String authorityName; 175757286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert final String accountKey; 175856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (authorityInfo != null) { 17598ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams if (authorityInfo.target.target_provider) { 17608ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams authorityName = authorityInfo.target.provider; 17618ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams accountKey = authorityInfo.target.account.name + "/" 17628ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams + authorityInfo.target.account.type 17638ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams + " u" + authorityInfo.target.userId; 17648ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams } else if (authorityInfo.target.target_service) { 17658ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams authorityName = authorityInfo.target.service.getPackageName() + "/" 17668ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams + authorityInfo.target.service.getClassName() 17678ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams + " u" + authorityInfo.target.userId; 176856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams accountKey = "none"; 176956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } else { 177056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams authorityName = "Unknown"; 177156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams accountKey = "Unknown"; 177256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 177357286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert } else { 177457286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert authorityName = "Unknown"; 177557286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert accountKey = "Unknown"; 177657286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert } 177757286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert final Time time = new Time(); 177857286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert final long eventTime = item.eventTime; 177957286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert time.set(eventTime); 178057286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert 178157286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert pw.printf(" #%-3d: %s %8s ", 178257286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert i + 1, 178357286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert formatTime(eventTime), 178457286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert SyncStorageEngine.SOURCES[item.source]); 178557286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert 178657286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert pw.printf(format, accountKey, authorityName, extras); 178757286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert } 1788e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert } 1789e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert } 1790e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert 1791e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert private void dumpDayStatistics(PrintWriter pw) { 1792231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn SyncStorageEngine.DayStats dses[] = mSyncStorageEngine.getDayStatistics(); 1793231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (dses != null && dses[0] != null) { 1794231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn pw.println(); 1795231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn pw.println("Sync Statistics"); 1796231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn pw.print(" Today: "); dumpDayStatistic(pw, dses[0]); 1797231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn int today = dses[0].day; 1798231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn int i; 1799231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn SyncStorageEngine.DayStats ds; 180044f574781545781c31db3dcf495ed08763073f75Doug Zongker 1801231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn // Print each day in the current week. 1802231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn for (i=1; i<=6 && i < dses.length; i++) { 1803231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn ds = dses[i]; 1804231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (ds == null) break; 1805231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn int delta = today-ds.day; 1806231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (delta > 6) break; 180744f574781545781c31db3dcf495ed08763073f75Doug Zongker 1808231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn pw.print(" Day-"); pw.print(delta); pw.print(": "); 1809231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn dumpDayStatistic(pw, ds); 1810231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 181144f574781545781c31db3dcf495ed08763073f75Doug Zongker 1812231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn // Aggregate all following days into weeks and print totals. 1813231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn int weekDay = today; 1814231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn while (i < dses.length) { 1815231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn SyncStorageEngine.DayStats aggr = null; 1816231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn weekDay -= 7; 1817231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn while (i < dses.length) { 1818231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn ds = dses[i]; 1819231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (ds == null) { 1820231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn i = dses.length; 1821231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn break; 1822231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1823231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn int delta = weekDay-ds.day; 1824231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (delta > 6) break; 1825231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn i++; 182644f574781545781c31db3dcf495ed08763073f75Doug Zongker 1827231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (aggr == null) { 1828231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn aggr = new SyncStorageEngine.DayStats(weekDay); 1829231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1830231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn aggr.successCount += ds.successCount; 1831231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn aggr.successTime += ds.successTime; 1832231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn aggr.failureCount += ds.failureCount; 1833231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn aggr.failureTime += ds.failureTime; 18349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1835231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (aggr != null) { 1836231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn pw.print(" Week-"); pw.print((today-weekDay)/7); pw.print(": "); 1837231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn dumpDayStatistic(pw, aggr); 18389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1839231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1840231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1841e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert } 184244f574781545781c31db3dcf495ed08763073f75Doug Zongker 18436ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey private void dumpSyncAdapters(IndentingPrintWriter pw) { 18446ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey pw.println(); 18456ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final List<UserInfo> users = getAllUsers(); 18466ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey if (users != null) { 18476ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey for (UserInfo user : users) { 18486ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey pw.println("Sync adapters for " + user + ":"); 18496ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey pw.increaseIndent(); 18506ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey for (RegisteredServicesCache.ServiceInfo<?> info : 18516ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey mSyncAdapters.getAllServices(user.id)) { 18526ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey pw.println(info); 18536ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey } 18546ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey pw.decreaseIndent(); 18556ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey pw.println(); 18566ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey } 18576ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey } 18586ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey } 18596ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 1860e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert private static class AuthoritySyncStats { 1861e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert String name; 1862e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert long elapsedTime; 1863e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert int times; 1864e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert Map<String, AccountSyncStats> accountMap = Maps.newHashMap(); 1865e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert 1866e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert private AuthoritySyncStats(String name) { 1867e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert this.name = name; 1868e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert } 1869e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert } 1870e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert 1871e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert private static class AccountSyncStats { 1872e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert String name; 1873e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert long elapsedTime; 1874e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert int times; 1875e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert 1876e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert private AccountSyncStats(String name) { 1877e0bde33e0d2b3ffb7918a5818a387773d4aa3e71Alon Albert this.name = name; 18789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 18829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A helper object to keep track of the time we have spent syncing since the last boot 18839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 18849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class SyncTimeTracker { 18859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** True if a sync was in progress on the most recent call to update() */ 18869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mLastWasSyncing = false; 18879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Used to track when lastWasSyncing was last set */ 18889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long mWhenSyncStarted = 0; 18899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** The cumulative time we have spent syncing */ 18909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mTimeSpentSyncing; 18919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Call to let the tracker know that the sync state may have changed */ 18939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public synchronized void update() { 1894918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana final boolean isSyncInProgress = !mActiveSyncContexts.isEmpty(); 18959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isSyncInProgress == mLastWasSyncing) return; 18969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final long now = SystemClock.elapsedRealtime(); 18979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isSyncInProgress) { 18989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWhenSyncStarted = now; 18999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 19009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTimeSpentSyncing += now - mWhenSyncStarted; 19019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastWasSyncing = isSyncInProgress; 19039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Get how long we have been syncing, in ms */ 19069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public synchronized long timeSpentSyncing() { 19079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mLastWasSyncing) return mTimeSpentSyncing; 19089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final long now = SystemClock.elapsedRealtime(); 19109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mTimeSpentSyncing + (now - mWhenSyncStarted); 19119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1914718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana class ServiceConnectionData { 1915718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana public final ActiveSyncContext activeSyncContext; 191656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams public final IBinder adapter; 191756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams 191856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams ServiceConnectionData(ActiveSyncContext activeSyncContext, IBinder adapter) { 1919718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana this.activeSyncContext = activeSyncContext; 192056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams this.adapter = adapter; 1921718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 1922718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 1923718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 19249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 19259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Handles SyncOperation Messages that are posted to the associated 19269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * HandlerThread. 19279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 19289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class SyncHandler extends Handler { 19299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Messages that can be sent on mHandler 19309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int MESSAGE_SYNC_FINISHED = 1; 19319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int MESSAGE_SYNC_ALARM = 2; 19329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int MESSAGE_CHECK_ALARMS = 3; 1933718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana private static final int MESSAGE_SERVICE_CONNECTED = 4; 1934718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana private static final int MESSAGE_SERVICE_DISCONNECTED = 5; 1935918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana private static final int MESSAGE_CANCEL = 6; 193692a1c09aa467f03dad78472098d40992303937fbMatthew Williams /** Posted delayed in order to expire syncs that are long-running. */ 193792a1c09aa467f03dad78472098d40992303937fbMatthew Williams private static final int MESSAGE_SYNC_EXPIRED = 7; 19389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final SyncNotificationInfo mSyncNotificationInfo = new SyncNotificationInfo(); 19409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Long mAlarmScheduleTime = null; 19419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final SyncTimeTracker mSyncTimeTracker = new SyncTimeTracker(); 194256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams private final HashMap<String, PowerManager.WakeLock> mWakeLocks = Maps.newHashMap(); 19439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19448704fc3dae2361d41d026e6e6cade7a63b12c973Matthew Williams private List<Message> mBootQueue = new ArrayList<Message>(); 19456ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 194695906af2645e67034736cb4f58aad5ee7f52d044Matthew Williams public void onBootCompleted() { 19478704fc3dae2361d41d026e6e6cade7a63b12c973Matthew Williams if (Log.isLoggable(TAG, Log.VERBOSE)) { 19488704fc3dae2361d41d026e6e6cade7a63b12c973Matthew Williams Log.v(TAG, "Boot completed, clearing boot queue."); 19498704fc3dae2361d41d026e6e6cade7a63b12c973Matthew Williams } 19508f55d112983aa922687de7e3581f73913c06e37aJeff Sharkey doDatabaseCleanup(); 19518704fc3dae2361d41d026e6e6cade7a63b12c973Matthew Williams synchronized(this) { 19528704fc3dae2361d41d026e6e6cade7a63b12c973Matthew Williams // Dispatch any stashed messages. 19538704fc3dae2361d41d026e6e6cade7a63b12c973Matthew Williams for (Message message : mBootQueue) { 19548704fc3dae2361d41d026e6e6cade7a63b12c973Matthew Williams sendMessage(message); 19558704fc3dae2361d41d026e6e6cade7a63b12c973Matthew Williams } 19568704fc3dae2361d41d026e6e6cade7a63b12c973Matthew Williams mBootQueue = null; 19578704fc3dae2361d41d026e6e6cade7a63b12c973Matthew Williams mBootCompleted = true; 1958e91ebe2be9580625ff31af8583e55aaefc50474fFred Quintana } 1959e91ebe2be9580625ff31af8583e55aaefc50474fFred Quintana } 1960e91ebe2be9580625ff31af8583e55aaefc50474fFred Quintana 196156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams private PowerManager.WakeLock getSyncWakeLock(SyncOperation operation) { 1962d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn final String wakeLockKey = operation.wakeLockName(); 1963b3029c3d563cf99ea07395282b053e87d5dbbb95Fred Quintana PowerManager.WakeLock wakeLock = mWakeLocks.get(wakeLockKey); 1964b3029c3d563cf99ea07395282b053e87d5dbbb95Fred Quintana if (wakeLock == null) { 1965d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn final String name = SYNC_WAKE_LOCK_PREFIX + wakeLockKey; 1966b3029c3d563cf99ea07395282b053e87d5dbbb95Fred Quintana wakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, name); 1967b3029c3d563cf99ea07395282b053e87d5dbbb95Fred Quintana wakeLock.setReferenceCounted(false); 1968b3029c3d563cf99ea07395282b053e87d5dbbb95Fred Quintana mWakeLocks.put(wakeLockKey, wakeLock); 1969b3029c3d563cf99ea07395282b053e87d5dbbb95Fred Quintana } 1970b3029c3d563cf99ea07395282b053e87d5dbbb95Fred Quintana return wakeLock; 1971b3029c3d563cf99ea07395282b053e87d5dbbb95Fred Quintana } 1972b3029c3d563cf99ea07395282b053e87d5dbbb95Fred Quintana 19738704fc3dae2361d41d026e6e6cade7a63b12c973Matthew Williams /** 19748704fc3dae2361d41d026e6e6cade7a63b12c973Matthew Williams * Stash any messages that come to the handler before boot is complete. 19758704fc3dae2361d41d026e6e6cade7a63b12c973Matthew Williams * {@link #onBootCompleted()} will disable this and dispatch all the messages collected. 19768704fc3dae2361d41d026e6e6cade7a63b12c973Matthew Williams * @param msg Message to dispatch at a later point. 19778704fc3dae2361d41d026e6e6cade7a63b12c973Matthew Williams * @return true if a message was enqueued, false otherwise. This is to avoid losing the 19788704fc3dae2361d41d026e6e6cade7a63b12c973Matthew Williams * message if we manage to acquire the lock but by the time we do boot has completed. 19798704fc3dae2361d41d026e6e6cade7a63b12c973Matthew Williams */ 19808704fc3dae2361d41d026e6e6cade7a63b12c973Matthew Williams private boolean tryEnqueueMessageUntilReadyToRun(Message msg) { 19818704fc3dae2361d41d026e6e6cade7a63b12c973Matthew Williams synchronized (this) { 19828704fc3dae2361d41d026e6e6cade7a63b12c973Matthew Williams if (!mBootCompleted) { 19838704fc3dae2361d41d026e6e6cade7a63b12c973Matthew Williams // Need to copy the message bc looper will recycle it. 19848704fc3dae2361d41d026e6e6cade7a63b12c973Matthew Williams mBootQueue.add(Message.obtain(msg)); 19858704fc3dae2361d41d026e6e6cade7a63b12c973Matthew Williams return true; 1986e91ebe2be9580625ff31af8583e55aaefc50474fFred Quintana } 19878704fc3dae2361d41d026e6e6cade7a63b12c973Matthew Williams return false; 1988e91ebe2be9580625ff31af8583e55aaefc50474fFred Quintana } 1989e91ebe2be9580625ff31af8583e55aaefc50474fFred Quintana } 19908704fc3dae2361d41d026e6e6cade7a63b12c973Matthew Williams 19919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 19929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Used to keep track of whether a sync notification is active and who it is for. 19939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 19949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class SyncNotificationInfo { 19959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // true iff the notification manager has been asked to send the notification 19969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isActive = false; 19979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Set when we transition from not running a sync to running a sync, and cleared on 19999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the opposite transition. 20009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Long startTime = null; 20019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void toString(StringBuilder sb) { 2003918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana sb.append("isActive ").append(isActive).append(", startTime ").append(startTime); 20049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 20079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String toString() { 20089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project StringBuilder sb = new StringBuilder(); 20099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project toString(sb); 20109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return sb.toString(); 20119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public SyncHandler(Looper looper) { 20159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(looper); 20169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void handleMessage(Message msg) { 20198704fc3dae2361d41d026e6e6cade7a63b12c973Matthew Williams if (tryEnqueueMessageUntilReadyToRun(msg)) { 20208704fc3dae2361d41d026e6e6cade7a63b12c973Matthew Williams return; 20218704fc3dae2361d41d026e6e6cade7a63b12c973Matthew Williams } 20228704fc3dae2361d41d026e6e6cade7a63b12c973Matthew Williams 2023918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana long earliestFuturePollTime = Long.MAX_VALUE; 2024918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana long nextPendingSyncTime = Long.MAX_VALUE; 2025753c57bf729def69be3f3ed0bcc07b0d858b73bbSubir Jhanb // Setting the value here instead of a method because we want the dumpsys logs 2026753c57bf729def69be3f3ed0bcc07b0d858b73bbSubir Jhanb // to have the most recent value used. 20279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 20281bad83adf011ff4e6a6474c62b287d119ba43b3eAlon Albert mDataConnectionIsConnected = readDataConnectionState(); 2029918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana mSyncManagerWakeLock.acquire(); 203077c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana // Always do this first so that we be sure that any periodic syncs that 203177c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana // are ready to run have been converted into pending syncs. This allows the 203277c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana // logic that considers the next steps to take based on the set of pending syncs 203377c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana // to also take into account the periodic syncs. 203477c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana earliestFuturePollTime = scheduleReadyPeriodicSyncs(); 20359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (msg.what) { 203692a1c09aa467f03dad78472098d40992303937fbMatthew Williams case SyncHandler.MESSAGE_SYNC_EXPIRED: 203792a1c09aa467f03dad78472098d40992303937fbMatthew Williams ActiveSyncContext expiredContext = (ActiveSyncContext) msg.obj; 203892a1c09aa467f03dad78472098d40992303937fbMatthew Williams if (Log.isLoggable(TAG, Log.DEBUG)) { 203992a1c09aa467f03dad78472098d40992303937fbMatthew Williams Log.d(TAG, "handleSyncHandlerMessage: MESSAGE_SYNC_EXPIRED: expiring " 204092a1c09aa467f03dad78472098d40992303937fbMatthew Williams + expiredContext); 204192a1c09aa467f03dad78472098d40992303937fbMatthew Williams } 204292a1c09aa467f03dad78472098d40992303937fbMatthew Williams cancelActiveSync(expiredContext.mSyncOperation.target, 204392a1c09aa467f03dad78472098d40992303937fbMatthew Williams expiredContext.mSyncOperation.extras); 204492a1c09aa467f03dad78472098d40992303937fbMatthew Williams nextPendingSyncTime = maybeStartNextSyncLocked(); 204592a1c09aa467f03dad78472098d40992303937fbMatthew Williams break; 204692a1c09aa467f03dad78472098d40992303937fbMatthew Williams 2047918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana case SyncHandler.MESSAGE_CANCEL: { 204856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams SyncStorageEngine.EndPoint payload = (SyncStorageEngine.EndPoint) msg.obj; 204956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams Bundle extras = msg.peekData(); 205092a1c09aa467f03dad78472098d40992303937fbMatthew Williams if (Log.isLoggable(TAG, Log.DEBUG)) { 2051918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana Log.d(TAG, "handleSyncHandlerMessage: MESSAGE_SERVICE_CANCEL: " 205256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams + payload + " bundle: " + extras); 2053918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 205456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams cancelActiveSyncLocked(payload, extras); 2055918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana nextPendingSyncTime = maybeStartNextSyncLocked(); 2056918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana break; 2057918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 2058918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana 20599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SyncHandler.MESSAGE_SYNC_FINISHED: 20609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Log.isLoggable(TAG, Log.VERBOSE)) { 20619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.v(TAG, "handleSyncHandlerMessage: MESSAGE_SYNC_FINISHED"); 20629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 206356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams SyncHandlerMessagePayload payload = (SyncHandlerMessagePayload) msg.obj; 2064918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana if (!isSyncStillActive(payload.activeSyncContext)) { 2065918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana Log.d(TAG, "handleSyncHandlerMessage: dropping since the " 2066918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana + "sync is no longer active: " 2067918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana + payload.activeSyncContext); 2068918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana break; 20699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 207056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams runSyncFinishedOrCanceledLocked(payload.syncResult, 207156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams payload.activeSyncContext); 20729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2073918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana // since a sync just finished check if it is time to start a new sync 2074918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana nextPendingSyncTime = maybeStartNextSyncLocked(); 20759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 20769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2077718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana case SyncHandler.MESSAGE_SERVICE_CONNECTED: { 207856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams ServiceConnectionData msgData = (ServiceConnectionData) msg.obj; 2079718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2080718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana Log.d(TAG, "handleSyncHandlerMessage: MESSAGE_SERVICE_CONNECTED: " 2081918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana + msgData.activeSyncContext); 2082718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 2083718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana // check that this isn't an old message 2084918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana if (isSyncStillActive(msgData.activeSyncContext)) { 208556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams runBoundToAdapter( 208656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams msgData.activeSyncContext, 20878ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams msgData.adapter); 2088718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 2089718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana break; 2090718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 2091718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 2092718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana case SyncHandler.MESSAGE_SERVICE_DISCONNECTED: { 2093918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana final ActiveSyncContext currentSyncContext = 209456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams ((ServiceConnectionData) msg.obj).activeSyncContext; 2095718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2096718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana Log.d(TAG, "handleSyncHandlerMessage: MESSAGE_SERVICE_DISCONNECTED: " 2097918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana + currentSyncContext); 2098718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 2099718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana // check that this isn't an old message 2100918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana if (isSyncStillActive(currentSyncContext)) { 2101718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana // cancel the sync if we have a syncadapter, which means one is 2102718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana // outstanding 210356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams try { 210456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (currentSyncContext.mSyncAdapter != null) { 2105918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana currentSyncContext.mSyncAdapter.cancelSync(currentSyncContext); 210656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } else if (currentSyncContext.mSyncServiceAdapter != null) { 210756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams currentSyncContext.mSyncServiceAdapter 210856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams .cancelSync(currentSyncContext); 2109718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 211056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } catch (RemoteException e) { 211156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams // We don't need to retry this in this case. 2112718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 2113718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 2114718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana // pretend that the sync failed with an IOException, 2115718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana // which is a soft error 2116718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana SyncResult syncResult = new SyncResult(); 2117718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana syncResult.stats.numIoExceptions++; 2118918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana runSyncFinishedOrCanceledLocked(syncResult, currentSyncContext); 2119718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 2120918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana // since a sync just finished check if it is time to start a new sync 2121918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana nextPendingSyncTime = maybeStartNextSyncLocked(); 2122718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 2123718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 2124718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana break; 2125718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 2126718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 21279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SyncHandler.MESSAGE_SYNC_ALARM: { 21289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE); 21299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isLoggable) { 21309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.v(TAG, "handleSyncHandlerMessage: MESSAGE_SYNC_ALARM"); 21319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAlarmScheduleTime = null; 21339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 2134918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana nextPendingSyncTime = maybeStartNextSyncLocked(); 21359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 21369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandleAlarmWakeLock.release(); 21379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 21399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SyncHandler.MESSAGE_CHECK_ALARMS: 21429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Log.isLoggable(TAG, Log.VERBOSE)) { 21439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.v(TAG, "handleSyncHandlerMessage: MESSAGE_CHECK_ALARMS"); 21449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2145918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana nextPendingSyncTime = maybeStartNextSyncLocked(); 21469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 21479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 2149918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana manageSyncNotificationLocked(); 2150918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana manageSyncAlarmLocked(earliestFuturePollTime, nextPendingSyncTime); 21519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSyncTimeTracker.update(); 2152918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana mSyncManagerWakeLock.release(); 21539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 215656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams private boolean isDispatchable(SyncStorageEngine.EndPoint target) { 215756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams final boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE); 215856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (target.target_provider) { 215956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams // skip the sync if the account of this operation no longer exists 216056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams AccountAndUser[] accounts = mRunningAccounts; 216156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (!containsAccountAndUser( 216256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams accounts, target.account, target.userId)) { 216356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return false; 216456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 216556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (!mSyncStorageEngine.getMasterSyncAutomatically(target.userId) 216656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams || !mSyncStorageEngine.getSyncAutomatically( 216756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams target.account, 216856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams target.userId, 216956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams target.provider)) { 217056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (isLoggable) { 217156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams Log.v(TAG, " Not scheduling periodic operation: sync turned off."); 217256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 217356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return false; 217456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 217556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (getIsSyncable(target.account, target.userId, target.provider) 217656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams == 0) { 217756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (isLoggable) { 217856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams Log.v(TAG, " Not scheduling periodic operation: isSyncable == 0."); 217956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 218056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return false; 218156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 218256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } else if (target.target_service) { 21837a2ab3a060f89c5de7f44f85bf58a7b6f6884873Matthew Williams if (mSyncStorageEngine.getIsTargetServiceActive(target.service, target.userId)) { 218456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (isLoggable) { 218556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams Log.v(TAG, " Not scheduling periodic operation: isEnabled == 0."); 218656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 218756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return false; 218856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 218956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 219056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return true; 219156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 219256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams 219377c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana /** 219477c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana * Turn any periodic sync operations that are ready to run into pending sync operations. 219556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams * @return the desired start time of the earliest future periodic sync operation, 219677c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana * in milliseconds since boot 219777c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana */ 2198918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana private long scheduleReadyPeriodicSyncs() { 2199fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams final boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE); 2200fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams if (isLoggable) { 2201fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams Log.v(TAG, "scheduleReadyPeriodicSyncs"); 2202fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams } 2203918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana long earliestFuturePollTime = Long.MAX_VALUE; 220404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 220577c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana final long nowAbsolute = System.currentTimeMillis(); 220669d95de53bc82e6c23c64ad566e428fbefae0543Ashish Sharma final long shiftedNowAbsolute = (0 < nowAbsolute - mSyncRandomOffsetMillis) 2207dbe846b02e6f6f715787cf8621587f7bc25deaacGeorgi Nikolov ? (nowAbsolute - mSyncRandomOffsetMillis) : 0; 2208dbe846b02e6f6f715787cf8621587f7bc25deaacGeorgi Nikolov 2209dbe846b02e6f6f715787cf8621587f7bc25deaacGeorgi Nikolov ArrayList<Pair<AuthorityInfo, SyncStatusInfo>> infos = mSyncStorageEngine 2210dbe846b02e6f6f715787cf8621587f7bc25deaacGeorgi Nikolov .getCopyOfAllAuthoritiesWithSyncStatus(); 2211dbe846b02e6f6f715787cf8621587f7bc25deaacGeorgi Nikolov for (Pair<AuthorityInfo, SyncStatusInfo> info : infos) { 2212dbe846b02e6f6f715787cf8621587f7bc25deaacGeorgi Nikolov final AuthorityInfo authorityInfo = info.first; 2213dbe846b02e6f6f715787cf8621587f7bc25deaacGeorgi Nikolov final SyncStatusInfo status = info.second; 221477c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana 2215d08d6686c5e16cedc23cd9bc836a28d629b8622cMatthew Williams if (TextUtils.isEmpty(authorityInfo.target.provider)) { 2216d08d6686c5e16cedc23cd9bc836a28d629b8622cMatthew Williams Log.e(TAG, "Got an empty provider string. Skipping: " 2217d08d6686c5e16cedc23cd9bc836a28d629b8622cMatthew Williams + authorityInfo.target.provider); 221877c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana continue; 221977c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana } 2220c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 22218ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams if (!isDispatchable(authorityInfo.target)) { 222277c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana continue; 222377c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana } 222477c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana 2225dbe846b02e6f6f715787cf8621587f7bc25deaacGeorgi Nikolov for (int i = 0, N = authorityInfo.periodicSyncs.size(); i < N; i++) { 2226fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams final PeriodicSync sync = authorityInfo.periodicSyncs.get(i); 2227fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams final Bundle extras = sync.extras; 2228fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams final Long periodInMillis = sync.period * 1000; 2229fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams final Long flexInMillis = sync.flexTime * 1000; 2230fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams // Skip if the period is invalid. 22314970974d74a2986a333e645a5c141ef5f9a753ccAshish Sharma if (periodInMillis <= 0) { 22324970974d74a2986a333e645a5c141ef5f9a753ccAshish Sharma continue; 22334970974d74a2986a333e645a5c141ef5f9a753ccAshish Sharma } 2234fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams // Find when this periodic sync was last scheduled to run. 223577c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana final long lastPollTimeAbsolute = status.getPeriodicSyncTime(i); 2236fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams final long shiftedLastPollTimeAbsolute = 2237fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams (0 < lastPollTimeAbsolute - mSyncRandomOffsetMillis) ? 2238fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams (lastPollTimeAbsolute - mSyncRandomOffsetMillis) : 0; 223969d95de53bc82e6c23c64ad566e428fbefae0543Ashish Sharma long remainingMillis 2240fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams = periodInMillis - (shiftedNowAbsolute % periodInMillis); 2241fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams long timeSinceLastRunMillis 2242fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams = (nowAbsolute - lastPollTimeAbsolute); 2243fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams // Schedule this periodic sync to run early if it's close enough to its next 2244fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams // runtime, and far enough from its last run time. 2245fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams // If we are early, there will still be time remaining in this period. 2246fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams boolean runEarly = remainingMillis <= flexInMillis 2247fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams && timeSinceLastRunMillis > periodInMillis - flexInMillis; 2248fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams if (isLoggable) { 22498ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams Log.v(TAG, "sync: " + i + " for " + authorityInfo.target + "." 2250fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams + " period: " + (periodInMillis) 2251fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams + " flex: " + (flexInMillis) 2252fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams + " remaining: " + (remainingMillis) 2253fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams + " time_since_last: " + timeSinceLastRunMillis 2254fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams + " last poll absol: " + lastPollTimeAbsolute 2255fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams + " last poll shifed: " + shiftedLastPollTimeAbsolute 2256fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams + " shifted now: " + shiftedNowAbsolute 2257fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams + " run_early: " + runEarly); 2258fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams } 225969d95de53bc82e6c23c64ad566e428fbefae0543Ashish Sharma /* 2260dbe846b02e6f6f715787cf8621587f7bc25deaacGeorgi Nikolov * Sync scheduling strategy: Set the next periodic sync 2261dbe846b02e6f6f715787cf8621587f7bc25deaacGeorgi Nikolov * based on a random offset (in seconds). Also sync right 2262dbe846b02e6f6f715787cf8621587f7bc25deaacGeorgi Nikolov * now if any of the following cases hold and mark it as 2263dbe846b02e6f6f715787cf8621587f7bc25deaacGeorgi Nikolov * having been scheduled 2264fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams * Case 1: This sync is ready to run now. 2265dbe846b02e6f6f715787cf8621587f7bc25deaacGeorgi Nikolov * Case 2: If the lastPollTimeAbsolute is in the 2266dbe846b02e6f6f715787cf8621587f7bc25deaacGeorgi Nikolov * future, sync now and reinitialize. This can happen for 2267dbe846b02e6f6f715787cf8621587f7bc25deaacGeorgi Nikolov * example if the user changed the time, synced and changed 2268dbe846b02e6f6f715787cf8621587f7bc25deaacGeorgi Nikolov * back. 226956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams * Case 3: If we failed to sync at the last scheduled time. 2270fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams * Case 4: This sync is close enough to the time that we can schedule it. 227169d95de53bc82e6c23c64ad566e428fbefae0543Ashish Sharma */ 227256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (remainingMillis == periodInMillis // Case 1 227369d95de53bc82e6c23c64ad566e428fbefae0543Ashish Sharma || lastPollTimeAbsolute > nowAbsolute // Case 2 227456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams || timeSinceLastRunMillis >= periodInMillis // Case 3 227556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams || runEarly) { // Case 4 227669d95de53bc82e6c23c64ad566e428fbefae0543Ashish Sharma // Sync now 22778ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams SyncStorageEngine.EndPoint target = authorityInfo.target; 227856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams final Pair<Long, Long> backoff = 227956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams mSyncStorageEngine.getBackoff(target); 2280fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams mSyncStorageEngine.setPeriodicSyncTime(authorityInfo.ident, 2281fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams authorityInfo.periodicSyncs.get(i), nowAbsolute); 228256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams 228356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (target.target_provider) { 228456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams final RegisteredServicesCache.ServiceInfo<SyncAdapterType> 228556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams syncAdapterInfo = mSyncAdapters.getServiceInfo( 228656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams SyncAdapterType.newKey( 228756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams target.provider, target.account.type), 228856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams target.userId); 228956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (syncAdapterInfo == null) { 229056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams continue; 229156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 229256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams scheduleSyncOperation( 229356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams new SyncOperation(target.account, target.userId, 229456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams SyncOperation.REASON_PERIODIC, 229556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams SyncStorageEngine.SOURCE_PERIODIC, 229656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams target.provider, extras, 229756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams 0 /* runtime */, 0 /* flex */, 229856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams backoff != null ? backoff.first : 0, 229956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams mSyncStorageEngine.getDelayUntilTime(target), 230056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams syncAdapterInfo.type.allowParallelSyncs())); 230156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } else if (target.target_service) { 230256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams scheduleSyncOperation( 230356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams new SyncOperation(target.service, target.userId, 230456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams SyncOperation.REASON_PERIODIC, 230556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams SyncStorageEngine.SOURCE_PERIODIC, 230656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams extras, 230756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams 0 /* runtime */, 230856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams 0 /* flex */, 230956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams backoff != null ? backoff.first : 0, 231056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams mSyncStorageEngine.getDelayUntilTime(target))); 231156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 2312fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams } 2313fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams // Compute when this periodic sync should next run. 2314fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams long nextPollTimeAbsolute; 2315fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams if (runEarly) { 2316fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams // Add the time remaining so we don't get out of phase. 2317fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams nextPollTimeAbsolute = nowAbsolute + periodInMillis + remainingMillis; 2318fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams } else { 2319fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams nextPollTimeAbsolute = nowAbsolute + remainingMillis; 232069d95de53bc82e6c23c64ad566e428fbefae0543Ashish Sharma } 232169d95de53bc82e6c23c64ad566e428fbefae0543Ashish Sharma if (nextPollTimeAbsolute < earliestFuturePollTime) { 232269d95de53bc82e6c23c64ad566e428fbefae0543Ashish Sharma earliestFuturePollTime = nextPollTimeAbsolute; 232377c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana } 232477c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana } 2325c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 2326c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 2327918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana if (earliestFuturePollTime == Long.MAX_VALUE) { 2328918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana return Long.MAX_VALUE; 2329c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 2330c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 233177c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana // convert absolute time to elapsed time 2332fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams return SystemClock.elapsedRealtime() + 2333fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams ((earliestFuturePollTime < nowAbsolute) ? 2334fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams 0 : (earliestFuturePollTime - nowAbsolute)); 2335c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 2336c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 2337918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana private long maybeStartNextSyncLocked() { 2338918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana final boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE); 2339918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana if (isLoggable) Log.v(TAG, "maybeStartNextSync"); 23409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If we aren't ready to run (e.g. the data connection is down), get out. 23429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mDataConnectionIsConnected) { 23439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isLoggable) { 2344918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana Log.v(TAG, "maybeStartNextSync: no data connection, skipping"); 23459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2346918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana return Long.MAX_VALUE; 23479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mStorageIsLow) { 23509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isLoggable) { 2351918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana Log.v(TAG, "maybeStartNextSync: memory low, skipping"); 23529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2353918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana return Long.MAX_VALUE; 23549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If the accounts aren't known yet then we aren't ready to run. We will be kicked 23579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // when the account lookup request does complete. 235856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (mRunningAccounts == INITIAL_ACCOUNTS_ARRAY) { 23599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isLoggable) { 2360918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana Log.v(TAG, "maybeStartNextSync: accounts not known, skipping"); 23619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2362918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana return Long.MAX_VALUE; 23639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Otherwise consume SyncOperations from the head of the SyncQueue until one is 23669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // found that is runnable (not disabled, etc). If that one is ready to run then 23679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // start it, otherwise just get out. 2368918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana final long now = SystemClock.elapsedRealtime(); 23699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2370918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana // will be set to the next time that a sync should be considered for running 2371918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana long nextReadyToRunTime = Long.MAX_VALUE; 2372918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana 2373918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana // order the sync queue, dropping syncs that are not allowed 2374918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana ArrayList<SyncOperation> operations = new ArrayList<SyncOperation>(); 2375918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana synchronized (mSyncQueue) { 2376918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana if (isLoggable) { 2377918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana Log.v(TAG, "build the operation array, syncQueue size is " 2378a706e2fd0059b1bb86c487722dbc9fc0fda9c980Jeff Sharkey + mSyncQueue.getOperations().size()); 2379918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 2380fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams final Iterator<SyncOperation> operationIterator = 2381fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams mSyncQueue.getOperations().iterator(); 23828e28555f6d4ea557ba79e3d411ea46e5a0788b8fAlon Albert 23838e28555f6d4ea557ba79e3d411ea46e5a0788b8fAlon Albert final ActivityManager activityManager 23848e28555f6d4ea557ba79e3d411ea46e5a0788b8fAlon Albert = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); 23858e28555f6d4ea557ba79e3d411ea46e5a0788b8fAlon Albert final Set<Integer> removedUsers = Sets.newHashSet(); 2386918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana while (operationIterator.hasNext()) { 2387918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana final SyncOperation op = operationIterator.next(); 2388307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana 238956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams // If the user is not running, skip the request. 239056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (!activityManager.isUserRunning(op.target.userId)) { 239156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams final UserInfo userInfo = mUserManager.getUserInfo(op.target.userId); 239256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (userInfo == null) { 239356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams removedUsers.add(op.target.userId); 239456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 2395fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams if (isLoggable) { 239656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams Log.v(TAG, " Dropping all sync operations for + " 239756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams + op.target.userId + ": user not running."); 2398fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams } 239977c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana continue; 240077c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana } 240156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (!isOperationValidLocked(op)) { 2402918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana operationIterator.remove(); 2403918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana mSyncStorageEngine.deleteFromPending(op.pendingOperation); 2404918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana continue; 2405918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 2406fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams // If the next run time is in the future, even given the flexible scheduling, 2407fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams // return the time. 2408fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams if (op.effectiveRunTime - op.flexTime > now) { 2409918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana if (nextReadyToRunTime > op.effectiveRunTime) { 2410918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana nextReadyToRunTime = op.effectiveRunTime; 2411918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 2412fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams if (isLoggable) { 241356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams Log.v(TAG, " Not running sync operation: Sync too far in future." 241456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams + "effective: " + op.effectiveRunTime + " flex: " + op.flexTime 241556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams + " now: " + now); 2416fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams } 241777c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana continue; 241877c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana } 241956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams // Add this sync to be run. 2420918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana operations.add(op); 2421918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 242256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams 24238e28555f6d4ea557ba79e3d411ea46e5a0788b8fAlon Albert for (Integer user : removedUsers) { 24248e28555f6d4ea557ba79e3d411ea46e5a0788b8fAlon Albert // if it's still removed 24258e28555f6d4ea557ba79e3d411ea46e5a0788b8fAlon Albert if (mUserManager.getUserInfo(user) == null) { 24266ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey onUserRemoved(user); 24278e28555f6d4ea557ba79e3d411ea46e5a0788b8fAlon Albert } 24288e28555f6d4ea557ba79e3d411ea46e5a0788b8fAlon Albert } 2429918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 2430918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana 2431918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana // find the next operation to dispatch, if one is ready 2432fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams // iterate from the top, keep issuing (while potentially canceling existing syncs) 2433918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana // until the quotas are filled. 2434918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana // once the quotas are filled iterate once more to find when the next one would be 2435918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana // (also considering pre-emption reasons). 2436918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana if (isLoggable) Log.v(TAG, "sort the candidate operations, size " + operations.size()); 2437918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana Collections.sort(operations); 2438918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana if (isLoggable) Log.v(TAG, "dispatch all ready sync operations"); 2439918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana for (int i = 0, N = operations.size(); i < N; i++) { 2440918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana final SyncOperation candidate = operations.get(i); 2441918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana final boolean candidateIsInitialization = candidate.isInitialization(); 2442918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana 2443918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana int numInit = 0; 2444918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana int numRegular = 0; 2445918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana ActiveSyncContext conflict = null; 2446918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana ActiveSyncContext longRunning = null; 2447918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana ActiveSyncContext toReschedule = null; 2448dc47556cb37b6f25faceb5eb97cef60d384b55fbFred Quintana ActiveSyncContext oldestNonExpeditedRegular = null; 2449918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana 2450918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana for (ActiveSyncContext activeSyncContext : mActiveSyncContexts) { 2451918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana final SyncOperation activeOp = activeSyncContext.mSyncOperation; 2452918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana if (activeOp.isInitialization()) { 2453918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana numInit++; 2454918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } else { 2455918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana numRegular++; 2456dc47556cb37b6f25faceb5eb97cef60d384b55fbFred Quintana if (!activeOp.isExpedited()) { 2457dc47556cb37b6f25faceb5eb97cef60d384b55fbFred Quintana if (oldestNonExpeditedRegular == null 2458dc47556cb37b6f25faceb5eb97cef60d384b55fbFred Quintana || (oldestNonExpeditedRegular.mStartTime 2459dc47556cb37b6f25faceb5eb97cef60d384b55fbFred Quintana > activeSyncContext.mStartTime)) { 2460dc47556cb37b6f25faceb5eb97cef60d384b55fbFred Quintana oldestNonExpeditedRegular = activeSyncContext; 2461dc47556cb37b6f25faceb5eb97cef60d384b55fbFred Quintana } 2462dc47556cb37b6f25faceb5eb97cef60d384b55fbFred Quintana } 2463918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 246456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (activeOp.isConflict(candidate)) { 2465918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana conflict = activeSyncContext; 246656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams // don't break out since we want to do a full count of the varieties. 2467918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } else { 2468918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana if (candidateIsInitialization == activeOp.isInitialization() 2469918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana && activeSyncContext.mStartTime + MAX_TIME_PER_SYNC < now) { 2470918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana longRunning = activeSyncContext; 2471918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana // don't break out since we want to do a full count of the varieties 2472918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 2473918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 24749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isLoggable) { 2477918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana Log.v(TAG, "candidate " + (i + 1) + " of " + N + ": " + candidate); 2478918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana Log.v(TAG, " numActiveInit=" + numInit + ", numActiveRegular=" + numRegular); 2479918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana Log.v(TAG, " longRunning: " + longRunning); 2480918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana Log.v(TAG, " conflict: " + conflict); 2481dc47556cb37b6f25faceb5eb97cef60d384b55fbFred Quintana Log.v(TAG, " oldestNonExpeditedRegular: " + oldestNonExpeditedRegular); 24829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2483918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana 2484dc47556cb37b6f25faceb5eb97cef60d384b55fbFred Quintana final boolean roomAvailable = candidateIsInitialization 2485dc47556cb37b6f25faceb5eb97cef60d384b55fbFred Quintana ? numInit < MAX_SIMULTANEOUS_INITIALIZATION_SYNCS 2486dc47556cb37b6f25faceb5eb97cef60d384b55fbFred Quintana : numRegular < MAX_SIMULTANEOUS_REGULAR_SYNCS; 2487dc47556cb37b6f25faceb5eb97cef60d384b55fbFred Quintana 2488918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana if (conflict != null) { 2489918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana if (candidateIsInitialization && !conflict.mSyncOperation.isInitialization() 2490918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana && numInit < MAX_SIMULTANEOUS_INITIALIZATION_SYNCS) { 2491918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana toReschedule = conflict; 2492918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2493918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana Log.v(TAG, "canceling and rescheduling sync since an initialization " 2494918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana + "takes higher priority, " + conflict); 2495918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 24966428046767ee4195617fb41b5639eefa2ca7a939Matthew Williams } else if (candidate.isExpedited() && !conflict.mSyncOperation.isExpedited() 2497918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana && (candidateIsInitialization 2498918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana == conflict.mSyncOperation.isInitialization())) { 2499918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana toReschedule = conflict; 2500918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2501918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana Log.v(TAG, "canceling and rescheduling sync since an expedited " 2502918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana + "takes higher priority, " + conflict); 2503918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 2504918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } else { 2505918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana continue; 2506918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 2507dc47556cb37b6f25faceb5eb97cef60d384b55fbFred Quintana } else if (roomAvailable) { 2508dc47556cb37b6f25faceb5eb97cef60d384b55fbFred Quintana // dispatch candidate 2509dc47556cb37b6f25faceb5eb97cef60d384b55fbFred Quintana } else if (candidate.isExpedited() && oldestNonExpeditedRegular != null 2510dc47556cb37b6f25faceb5eb97cef60d384b55fbFred Quintana && !candidateIsInitialization) { 2511dc47556cb37b6f25faceb5eb97cef60d384b55fbFred Quintana // We found an active, non-expedited regular sync. We also know that the 2512dc47556cb37b6f25faceb5eb97cef60d384b55fbFred Quintana // candidate doesn't conflict with this active sync since conflict 2513dc47556cb37b6f25faceb5eb97cef60d384b55fbFred Quintana // is null. Reschedule the active sync and start the candidate. 2514dc47556cb37b6f25faceb5eb97cef60d384b55fbFred Quintana toReschedule = oldestNonExpeditedRegular; 2515dc47556cb37b6f25faceb5eb97cef60d384b55fbFred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 251656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams Log.v(TAG, "canceling and rescheduling sync since an expedited is ready to" 251756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams + " run, " + oldestNonExpeditedRegular); 2518918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 2519dc47556cb37b6f25faceb5eb97cef60d384b55fbFred Quintana } else if (longRunning != null 2520dc47556cb37b6f25faceb5eb97cef60d384b55fbFred Quintana && (candidateIsInitialization 2521dc47556cb37b6f25faceb5eb97cef60d384b55fbFred Quintana == longRunning.mSyncOperation.isInitialization())) { 2522dc47556cb37b6f25faceb5eb97cef60d384b55fbFred Quintana // We found an active, long-running sync. Reschedule the active 2523dc47556cb37b6f25faceb5eb97cef60d384b55fbFred Quintana // sync and start the candidate. 2524dc47556cb37b6f25faceb5eb97cef60d384b55fbFred Quintana toReschedule = longRunning; 2525dc47556cb37b6f25faceb5eb97cef60d384b55fbFred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2526dc47556cb37b6f25faceb5eb97cef60d384b55fbFred Quintana Log.v(TAG, "canceling and rescheduling sync since it ran roo long, " 2527dc47556cb37b6f25faceb5eb97cef60d384b55fbFred Quintana + longRunning); 2528dc47556cb37b6f25faceb5eb97cef60d384b55fbFred Quintana } 2529dc47556cb37b6f25faceb5eb97cef60d384b55fbFred Quintana } else { 2530dc47556cb37b6f25faceb5eb97cef60d384b55fbFred Quintana // we were unable to find or make space to run this candidate, go on to 2531dc47556cb37b6f25faceb5eb97cef60d384b55fbFred Quintana // the next one 2532dc47556cb37b6f25faceb5eb97cef60d384b55fbFred Quintana continue; 2533918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 2534918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana 2535918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana if (toReschedule != null) { 2536918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana runSyncFinishedOrCanceledLocked(null, toReschedule); 2537918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana scheduleSyncOperation(toReschedule.mSyncOperation); 2538918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 2539a706e2fd0059b1bb86c487722dbc9fc0fda9c980Jeff Sharkey synchronized (mSyncQueue) { 2540918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana mSyncQueue.remove(candidate); 2541918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 254287b146625a2daa7eaa606e1975e94a9a579af8b8Fred Quintana dispatchSyncOperation(candidate); 25439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2545918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana return nextReadyToRunTime; 254656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 254756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams 254856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams /** 254956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams * Determine if a sync is no longer valid and should be dropped from the sync queue and its 255056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams * pending op deleted. 255156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams * @param op operation for which the sync is to be scheduled. 255256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams */ 255356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams private boolean isOperationValidLocked(SyncOperation op) { 255456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams final boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE); 255556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams int targetUid; 255656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams int state; 255756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams final SyncStorageEngine.EndPoint target = op.target; 255856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams boolean syncEnabled = mSyncStorageEngine.getMasterSyncAutomatically(target.userId); 255956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (target.target_provider) { 256056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams // Drop the sync if the account of this operation no longer exists. 256156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams AccountAndUser[] accounts = mRunningAccounts; 256256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (!containsAccountAndUser(accounts, target.account, target.userId)) { 256356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (isLoggable) { 256456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams Log.v(TAG, " Dropping sync operation: account doesn't exist."); 256556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 256656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return false; 256756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 256856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams // Drop this sync request if it isn't syncable. 256956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams state = getIsSyncable(target.account, target.userId, target.provider); 257056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (state == 0) { 257156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (isLoggable) { 257256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams Log.v(TAG, " Dropping sync operation: isSyncable == 0."); 257356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 257456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return false; 257556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 257656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams syncEnabled = syncEnabled && mSyncStorageEngine.getSyncAutomatically( 257756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams target.account, target.userId, target.provider); 257856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams 257956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo; 258056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams syncAdapterInfo = mSyncAdapters.getServiceInfo( 258156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams SyncAdapterType.newKey( 258256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams target.provider, target.account.type), target.userId); 258356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (syncAdapterInfo != null) { 258456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams targetUid = syncAdapterInfo.uid; 258556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } else { 258656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (isLoggable) { 258756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams Log.v(TAG, " Dropping sync operation: No sync adapter registered" 258856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams + "for: " + target); 258956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 259056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return false; 259156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 259256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } else if (target.target_service) { 25937a2ab3a060f89c5de7f44f85bf58a7b6f6884873Matthew Williams state = mSyncStorageEngine.getIsTargetServiceActive(target.service, target.userId) 25947a2ab3a060f89c5de7f44f85bf58a7b6f6884873Matthew Williams ? 1 : 0; 259556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (state == 0) { 259656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams // TODO: Change this to not drop disabled syncs - keep them in the pending queue. 259756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (isLoggable) { 259856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams Log.v(TAG, " Dropping sync operation: isActive == 0."); 259956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 260056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return false; 260156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 260256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams try { 260356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams targetUid = mContext.getPackageManager() 260456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams .getServiceInfo(target.service, 0) 260556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams .applicationInfo 260656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams .uid; 260756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } catch (PackageManager.NameNotFoundException e) { 260856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (isLoggable) { 260956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams Log.v(TAG, " Dropping sync operation: No service registered for: " 261056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams + target.service); 261156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 261256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return false; 261356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 261456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } else { 261556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams Log.e(TAG, "Unknown target for Sync Op: " + target); 261656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return false; 261756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 261856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams 261956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams // We ignore system settings that specify the sync is invalid if: 262056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams // 1) It's manual - we try it anyway. When/if it fails it will be rescheduled. 262156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams // or 262256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams // 2) it's an initialisation sync - we just need to connect to it. 262356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams final boolean ignoreSystemConfiguration = 262456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams op.extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, false) 262556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams || (state < 0); 262656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams 262756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams // Sync not enabled. 262856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (!syncEnabled && !ignoreSystemConfiguration) { 262956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (isLoggable) { 263056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams Log.v(TAG, " Dropping sync operation: disallowed by settings/network."); 263156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 263256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return false; 263356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 263456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams // Network down. 263556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams final NetworkInfo networkInfo = getConnectivityManager() 263656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams .getActiveNetworkInfoForUid(targetUid); 263756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams final boolean uidNetworkConnected = networkInfo != null && networkInfo.isConnected(); 263856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (!uidNetworkConnected && !ignoreSystemConfiguration) { 263956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (isLoggable) { 264056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams Log.v(TAG, " Dropping sync operation: disallowed by settings/network."); 264156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 264256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return false; 264356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 264456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams // Metered network. 264556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (op.isNotAllowedOnMetered() && getConnectivityManager().isActiveNetworkMetered() 264656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams && !ignoreSystemConfiguration) { 264756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (isLoggable) { 264856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams Log.v(TAG, " Dropping sync operation: not allowed on metered network."); 264956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 265056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return false; 265156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 265256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return true; 265356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 2654918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana 265587b146625a2daa7eaa606e1975e94a9a579af8b8Fred Quintana private boolean dispatchSyncOperation(SyncOperation op) { 2656918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 26570c4d04ac2e8aa62560d8d767fa1c87e5361b0b08Fred Quintana Log.v(TAG, "dispatchSyncOperation: we are going to sync " + op); 2658918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana Log.v(TAG, "num active syncs: " + mActiveSyncContexts.size()); 2659918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana for (ActiveSyncContext syncContext : mActiveSyncContexts) { 2660918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana Log.v(TAG, syncContext.toString()); 2661918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 2662918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 266356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams // Connect to the sync adapter. 266456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams int targetUid; 266556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams ComponentName targetComponent; 266656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams final SyncStorageEngine.EndPoint info = op.target; 266756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (info.target_provider) { 266856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams SyncAdapterType syncAdapterType = 266956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams SyncAdapterType.newKey(info.provider, info.account.type); 267056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo; 267156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams syncAdapterInfo = mSyncAdapters.getServiceInfo(syncAdapterType, info.userId); 267256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (syncAdapterInfo == null) { 267356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams Log.d(TAG, "can't find a sync adapter for " + syncAdapterType 267456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams + ", removing settings for it"); 267556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams mSyncStorageEngine.removeAuthority(info); 267656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return false; 267756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 267856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams targetUid = syncAdapterInfo.uid; 267956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams targetComponent = syncAdapterInfo.componentName; 268056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } else { 268156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams // TODO: Store the uid of the service as part of the authority info in order to 268256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams // avoid this call? 268356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams try { 268456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams targetUid = mContext.getPackageManager() 268556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams .getServiceInfo(info.service, 0) 268656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams .applicationInfo 268756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams .uid; 268856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams targetComponent = info.service; 268956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } catch(PackageManager.NameNotFoundException e) { 269056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams Log.d(TAG, "Can't find a service for " + info.service 269156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams + ", removing settings for it"); 269256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams mSyncStorageEngine.removeAuthority(info); 269356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return false; 269456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 2695718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 2696718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana ActiveSyncContext activeSyncContext = 269756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams new ActiveSyncContext(op, insertStartSyncEvent(op), targetUid); 2698918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana activeSyncContext.mSyncInfo = mSyncStorageEngine.addActiveSync(activeSyncContext); 2699918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana mActiveSyncContexts.add(activeSyncContext); 270092a1c09aa467f03dad78472098d40992303937fbMatthew Williams if (!activeSyncContext.mSyncOperation.isInitialization() && 270192a1c09aa467f03dad78472098d40992303937fbMatthew Williams !activeSyncContext.mSyncOperation.isExpedited() && 270292a1c09aa467f03dad78472098d40992303937fbMatthew Williams !activeSyncContext.mSyncOperation.isManual() && 270392a1c09aa467f03dad78472098d40992303937fbMatthew Williams !activeSyncContext.mSyncOperation.isIgnoreSettings()) { 270492a1c09aa467f03dad78472098d40992303937fbMatthew Williams // Post message to expire this sync if it runs for too long. 270592a1c09aa467f03dad78472098d40992303937fbMatthew Williams postSyncExpiryMessage(activeSyncContext); 270692a1c09aa467f03dad78472098d40992303937fbMatthew Williams } 2707718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2708918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana Log.v(TAG, "dispatchSyncOperation: starting " + activeSyncContext); 2709718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 271056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (!activeSyncContext.bindToSyncAdapter(targetComponent, info.userId)) { 271156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams Log.e(TAG, "Bind attempt failed - target: " + targetComponent); 2712918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana closeActiveSyncContext(activeSyncContext); 271387b146625a2daa7eaa606e1975e94a9a579af8b8Fred Quintana return false; 27149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 27159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 271687b146625a2daa7eaa606e1975e94a9a579af8b8Fred Quintana return true; 2717718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 27189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 271956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams private void runBoundToAdapter(final ActiveSyncContext activeSyncContext, 27208ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams IBinder syncAdapter) { 2721918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana final SyncOperation syncOperation = activeSyncContext.mSyncOperation; 27229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 2723eca7511f61a6bfbb43a6646f87b5771bcc5d3fdcAlon Albert activeSyncContext.mIsLinkedToDeath = true; 272456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams syncAdapter.linkToDeath(activeSyncContext, 0); 272556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams 272656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (syncOperation.target.target_provider) { 272756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams activeSyncContext.mSyncAdapter = ISyncAdapter.Stub.asInterface(syncAdapter); 272856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams activeSyncContext.mSyncAdapter 272956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams .startSync(activeSyncContext, syncOperation.target.provider, 273056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams syncOperation.target.account, syncOperation.extras); 273156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } else if (syncOperation.target.target_service) { 273256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams activeSyncContext.mSyncServiceAdapter = 273356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams ISyncServiceAdapter.Stub.asInterface(syncAdapter); 273456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams activeSyncContext.mSyncServiceAdapter 273556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams .startSync(activeSyncContext, syncOperation.extras); 273656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 27379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException remoteExc) { 2738918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana Log.d(TAG, "maybeStartNextSync: caught a RemoteException, rescheduling", remoteExc); 2739918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana closeActiveSyncContext(activeSyncContext); 2740307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana increaseBackoffSetting(syncOperation); 274156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams scheduleSyncOperation( 274256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams new SyncOperation(syncOperation, 0L /* newRunTimeFromNow */)); 27439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RuntimeException exc) { 2744918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana closeActiveSyncContext(activeSyncContext); 2745307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana Log.e(TAG, "Caught RuntimeException while starting the sync " + syncOperation, exc); 27469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 27479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 27489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 274956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams /** 27508ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams * Cancel the sync for the provided target that matches the given bundle. 27518ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams * @param info can have null fields to indicate all the active syncs for that field. 275256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams */ 275356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams private void cancelActiveSyncLocked(SyncStorageEngine.EndPoint info, Bundle extras) { 2754918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana ArrayList<ActiveSyncContext> activeSyncs = 2755918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana new ArrayList<ActiveSyncContext>(mActiveSyncContexts); 2756918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana for (ActiveSyncContext activeSyncContext : activeSyncs) { 2757918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana if (activeSyncContext != null) { 275856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams final SyncStorageEngine.EndPoint opInfo = 275956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams activeSyncContext.mSyncOperation.target; 27608ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams if (!opInfo.matchesSpec(info)) { 276156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams continue; 2762918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 276356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (extras != null && 276456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams !syncExtrasEquals(activeSyncContext.mSyncOperation.extras, 276556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams extras, 276656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams false /* no config settings */)) { 276704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani continue; 276804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 2769918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana runSyncFinishedOrCanceledLocked(null /* no result since this is a cancel */, 2770918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana activeSyncContext); 2771918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 2772918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 2773918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 2774918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana 2775918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana private void runSyncFinishedOrCanceledLocked(SyncResult syncResult, 2776918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana ActiveSyncContext activeSyncContext) { 27779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE); 2778eca7511f61a6bfbb43a6646f87b5771bcc5d3fdcAlon Albert 277956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams final SyncOperation syncOperation = activeSyncContext.mSyncOperation; 278056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams final SyncStorageEngine.EndPoint info = syncOperation.target; 278156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams 2782eca7511f61a6bfbb43a6646f87b5771bcc5d3fdcAlon Albert if (activeSyncContext.mIsLinkedToDeath) { 278356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (info.target_provider) { 278456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams activeSyncContext.mSyncAdapter.asBinder().unlinkToDeath(activeSyncContext, 0); 278556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } else { 27868ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams activeSyncContext.mSyncServiceAdapter.asBinder() 27878ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams .unlinkToDeath(activeSyncContext, 0); 278856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 2789eca7511f61a6bfbb43a6646f87b5771bcc5d3fdcAlon Albert activeSyncContext.mIsLinkedToDeath = false; 2790eca7511f61a6bfbb43a6646f87b5771bcc5d3fdcAlon Albert } 2791918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana closeActiveSyncContext(activeSyncContext); 27929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final long elapsedTime = SystemClock.elapsedRealtime() - activeSyncContext.mStartTime; 27939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String historyMessage; 27949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int downstreamActivity; 27959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int upstreamActivity; 27969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (syncResult != null) { 27979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isLoggable) { 2798307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana Log.v(TAG, "runSyncFinishedOrCanceled [finished]: " 27999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + syncOperation + ", result " + syncResult); 28009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!syncResult.hasError()) { 2803231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn historyMessage = SyncStorageEngine.MESG_SUCCESS; 28049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO: set these correctly when the SyncResult is extended to include it 28059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project downstreamActivity = 0; 28069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project upstreamActivity = 0; 28076e079a32bceb85a44da3b396f8d37e718d1421d5Alon Albert clearBackoffSetting(syncOperation); 28089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2809307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana Log.d(TAG, "failed sync operation " + syncOperation + ", " + syncResult); 2810307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana // the operation failed so increase the backoff time 28113c8a42ddd9482ebc8541f7af6f15afdf3b3ec151Matthew Williams increaseBackoffSetting(syncOperation); 2812307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana // reschedule the sync if so indicated by the syncResult 2813307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana maybeRescheduleSync(syncResult, syncOperation); 281457286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert historyMessage = ContentResolver.syncErrorToString( 281557286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert syncResultToErrorNumber(syncResult)); 28169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO: set these correctly when the SyncResult is extended to include it 28179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project downstreamActivity = 0; 28189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project upstreamActivity = 0; 28199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2820307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana setDelayUntilTime(syncOperation, syncResult.delayUntil); 28219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 28229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isLoggable) { 2823307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana Log.v(TAG, "runSyncFinishedOrCanceled [canceled]: " + syncOperation); 28249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2825718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana if (activeSyncContext.mSyncAdapter != null) { 2826718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana try { 282721bb0deb36af32339521038cdbd827f74468df4aFred Quintana activeSyncContext.mSyncAdapter.cancelSync(activeSyncContext); 2828718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } catch (RemoteException e) { 2829718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana // we don't need to retry this in this case 2830718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 283156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } else if (activeSyncContext.mSyncServiceAdapter != null) { 283256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams try { 283356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams activeSyncContext.mSyncServiceAdapter.cancelSync(activeSyncContext); 283456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } catch (RemoteException e) { 283556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams // we don't need to retry this in this case 283656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 28379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2838231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn historyMessage = SyncStorageEngine.MESG_CANCELED; 28399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project downstreamActivity = 0; 28409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project upstreamActivity = 0; 28419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stopSyncEvent(activeSyncContext.mHistoryRowId, syncOperation, historyMessage, 28449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project upstreamActivity, downstreamActivity, elapsedTime); 284556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams // Check for full-resync and schedule it after closing off the last sync. 284656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (info.target_provider) { 284756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (syncResult != null && syncResult.tooManyDeletions) { 284856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams installHandleTooManyDeletesNotification(info.account, 284956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams info.provider, syncResult.stats.numDeletes, 285056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams info.userId); 285156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } else { 285256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams mNotificationMgr.cancelAsUser(null, 285356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams info.account.hashCode() ^ info.provider.hashCode(), 285456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams new UserHandle(info.userId)); 285556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 285656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (syncResult != null && syncResult.fullSyncRequested) { 285756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams scheduleSyncOperation( 285856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams new SyncOperation(info.account, info.userId, 285956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams syncOperation.reason, 286056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams syncOperation.syncSource, info.provider, new Bundle(), 286156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams 0 /* delay */, 0 /* flex */, 286256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams syncOperation.backoff, syncOperation.delayUntil, 286356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams syncOperation.allowParallelSyncs)); 286456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 28659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 286656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (syncResult != null && syncResult.fullSyncRequested) { 286756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams scheduleSyncOperation( 286856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams new SyncOperation(info.service, info.userId, 286956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams syncOperation.reason, 287056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams syncOperation.syncSource, new Bundle(), 287156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams 0 /* delay */, 0 /* flex */, 287256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams syncOperation.backoff, syncOperation.delayUntil)); 287356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 28749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // no need to schedule an alarm, as that will be done by our caller. 28769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 28779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2878918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana private void closeActiveSyncContext(ActiveSyncContext activeSyncContext) { 2879918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana activeSyncContext.close(); 2880918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana mActiveSyncContexts.remove(activeSyncContext); 288104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani mSyncStorageEngine.removeActiveSync(activeSyncContext.mSyncInfo, 288256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams activeSyncContext.mSyncOperation.target.userId); 288392a1c09aa467f03dad78472098d40992303937fbMatthew Williams removeSyncExpiryMessage(activeSyncContext); 2884918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 2885918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana 28869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 28879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Convert the error-containing SyncResult into the Sync.History error number. Since 28889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the SyncResult may indicate multiple errors at once, this method just returns the 28899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * most "serious" error. 28909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param syncResult the SyncResult from which to read 28919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the most "serious" error set in the SyncResult 28929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IllegalStateException if the SyncResult does not indicate any errors. 28939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If SyncResult.error() is true then it is safe to call this. 28949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 28959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int syncResultToErrorNumber(SyncResult syncResult) { 2896231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (syncResult.syncAlreadyInProgress) 2897ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return ContentResolver.SYNC_ERROR_SYNC_ALREADY_IN_PROGRESS; 2898231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (syncResult.stats.numAuthExceptions > 0) 2899ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return ContentResolver.SYNC_ERROR_AUTHENTICATION; 2900231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (syncResult.stats.numIoExceptions > 0) 2901ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return ContentResolver.SYNC_ERROR_IO; 2902231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (syncResult.stats.numParseExceptions > 0) 2903ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return ContentResolver.SYNC_ERROR_PARSE; 2904231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (syncResult.stats.numConflictDetectedExceptions > 0) 2905ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return ContentResolver.SYNC_ERROR_CONFLICT; 2906231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (syncResult.tooManyDeletions) 2907ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return ContentResolver.SYNC_ERROR_TOO_MANY_DELETIONS; 2908231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (syncResult.tooManyRetries) 2909ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return ContentResolver.SYNC_ERROR_TOO_MANY_RETRIES; 2910231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (syncResult.databaseError) 2911ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return ContentResolver.SYNC_ERROR_INTERNAL; 29129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalStateException("we are not in an error state, " + syncResult); 29139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 29149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2915918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana private void manageSyncNotificationLocked() { 29169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean shouldCancel; 29179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean shouldInstall; 29189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2919918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana if (mActiveSyncContexts.isEmpty()) { 29209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSyncNotificationInfo.startTime = null; 29219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 29229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we aren't syncing. if the notification is active then remember that we need 29239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // to cancel it and then clear out the info 29249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project shouldCancel = mSyncNotificationInfo.isActive; 29259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project shouldInstall = false; 29269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 29279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we are syncing 29289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final long now = SystemClock.elapsedRealtime(); 29299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mSyncNotificationInfo.startTime == null) { 29309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSyncNotificationInfo.startTime = now; 29319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 29329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2933918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana // there are three cases: 2934918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana // - the notification is up: do nothing 29359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // - the notification is not up but it isn't time yet: don't install 29369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // - the notification is not up and it is time: need to install 29379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 29389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mSyncNotificationInfo.isActive) { 2939918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana shouldInstall = shouldCancel = false; 29409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2941918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana // it isn't currently up, so there is nothing to cancel 2942918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana shouldCancel = false; 2943918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana 29449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean timeToShowNotification = 29459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project now > mSyncNotificationInfo.startTime + SYNC_NOTIFICATION_DELAY; 2946918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana if (timeToShowNotification) { 2947918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana shouldInstall = true; 2948918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } else { 2949918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana // show the notification immediately if this is a manual sync 2950918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana shouldInstall = false; 2951918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana for (ActiveSyncContext activeSyncContext : mActiveSyncContexts) { 2952918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana final boolean manualSync = activeSyncContext.mSyncOperation.extras 2953918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana .getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false); 2954918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana if (manualSync) { 2955918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana shouldInstall = true; 2956918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana break; 2957918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 2958918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 2959918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 29609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 29619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 29629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 29639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (shouldCancel && !shouldInstall) { 29649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNeedSyncActiveNotification = false; 29659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sendSyncStateIntent(); 29669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSyncNotificationInfo.isActive = false; 29679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 29689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 29699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (shouldInstall) { 29709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNeedSyncActiveNotification = true; 29719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sendSyncStateIntent(); 29729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSyncNotificationInfo.isActive = true; 29739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 29749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 29759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2976918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana private void manageSyncAlarmLocked(long nextPeriodicEventElapsedTime, 2977918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana long nextPendingEventElapsedTime) { 29789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // in each of these cases the sync loop will be kicked, which will cause this 29799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // method to be called again 29809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mDataConnectionIsConnected) return; 29819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mStorageIsLow) return; 29829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2983918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana // When the status bar notification should be raised 2984918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana final long notificationTime = 2985918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana (!mSyncHandler.mSyncNotificationInfo.isActive 2986918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana && mSyncHandler.mSyncNotificationInfo.startTime != null) 2987918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana ? mSyncHandler.mSyncNotificationInfo.startTime + SYNC_NOTIFICATION_DELAY 2988918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana : Long.MAX_VALUE; 2989918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana 2990918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana // When we should consider canceling an active sync 2991918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana long earliestTimeoutTime = Long.MAX_VALUE; 2992918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana for (ActiveSyncContext currentSyncContext : mActiveSyncContexts) { 2993918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana final long currentSyncTimeoutTime = 2994918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana currentSyncContext.mTimeoutStartTime + MAX_TIME_PER_SYNC; 2995918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2996918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana Log.v(TAG, "manageSyncAlarm: active sync, mTimeoutStartTime + MAX is " 2997918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana + currentSyncTimeoutTime); 29989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2999918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana if (earliestTimeoutTime > currentSyncTimeoutTime) { 3000918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana earliestTimeoutTime = currentSyncTimeoutTime; 30019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 30029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 30039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3004918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 3005918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana Log.v(TAG, "manageSyncAlarm: notificationTime is " + notificationTime); 3006918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 3007918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana 3008918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 3009918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana Log.v(TAG, "manageSyncAlarm: earliestTimeoutTime is " + earliestTimeoutTime); 3010918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 3011918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana 3012918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 3013918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana Log.v(TAG, "manageSyncAlarm: nextPeriodicEventElapsedTime is " 3014918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana + nextPeriodicEventElapsedTime); 3015918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 3016918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 3017918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana Log.v(TAG, "manageSyncAlarm: nextPendingEventElapsedTime is " 3018918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana + nextPendingEventElapsedTime); 3019918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 3020918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana 3021918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana long alarmTime = Math.min(notificationTime, earliestTimeoutTime); 3022918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana alarmTime = Math.min(alarmTime, nextPeriodicEventElapsedTime); 3023918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana alarmTime = Math.min(alarmTime, nextPendingEventElapsedTime); 3024918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana 3025918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana // Bound the alarm time. 3026918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana final long now = SystemClock.elapsedRealtime(); 3027918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana if (alarmTime < now + SYNC_ALARM_TIMEOUT_MIN) { 3028918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 3029918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana Log.v(TAG, "manageSyncAlarm: the alarmTime is too small, " 3030918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana + alarmTime + ", setting to " + (now + SYNC_ALARM_TIMEOUT_MIN)); 3031918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 3032918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana alarmTime = now + SYNC_ALARM_TIMEOUT_MIN; 3033918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } else if (alarmTime > now + SYNC_ALARM_TIMEOUT_MAX) { 3034918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 3035918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana Log.v(TAG, "manageSyncAlarm: the alarmTime is too large, " 3036918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana + alarmTime + ", setting to " + (now + SYNC_ALARM_TIMEOUT_MIN)); 30379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3038918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana alarmTime = now + SYNC_ALARM_TIMEOUT_MAX; 30399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 30409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 30419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // determine if we need to set or cancel the alarm 30429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean shouldSet = false; 30439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean shouldCancel = false; 3044ba35271e91648c9cde2bb606aaf2001282231b07Matthew Williams final boolean alarmIsActive = (mAlarmScheduleTime != null) && (now < mAlarmScheduleTime); 3045918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana final boolean needAlarm = alarmTime != Long.MAX_VALUE; 30469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (needAlarm) { 3047ba35271e91648c9cde2bb606aaf2001282231b07Matthew Williams // Need the alarm if 3048ba35271e91648c9cde2bb606aaf2001282231b07Matthew Williams // - it's currently not set 3049ba35271e91648c9cde2bb606aaf2001282231b07Matthew Williams // - if the alarm is set in the past. 30509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!alarmIsActive || alarmTime < mAlarmScheduleTime) { 30519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project shouldSet = true; 30529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 30539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 30549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project shouldCancel = alarmIsActive; 30559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 30569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3057fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams // Set or cancel the alarm as directed. 30589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ensureAlarmService(); 30599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (shouldSet) { 3060918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 3061918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana Log.v(TAG, "requesting that the alarm manager wake us up at elapsed time " 3062918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana + alarmTime + ", now is " + now + ", " + ((alarmTime - now) / 1000) 3063918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana + " secs from now"); 3064918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 30659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAlarmScheduleTime = alarmTime; 3066ba35271e91648c9cde2bb606aaf2001282231b07Matthew Williams mAlarmService.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, alarmTime, 30679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSyncAlarmIntent); 30689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (shouldCancel) { 30699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAlarmScheduleTime = null; 30709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAlarmService.cancel(mSyncAlarmIntent); 30719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 30729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 30739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 30749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void sendSyncStateIntent() { 30759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent syncStateIntent = new Intent(Intent.ACTION_SYNC_STATE_CHANGED); 3076a34f1ad7c3a68d971e6332aa2fb1c16d083920b3Dianne Hackborn syncStateIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 30779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project syncStateIntent.putExtra("active", mNeedSyncActiveNotification); 3078918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana syncStateIntent.putExtra("failing", false); 3079cd75706117432e33d11639e675bcff50479a6bb9Amith Yamasani mContext.sendBroadcastAsUser(syncStateIntent, UserHandle.OWNER); 30809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 30819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3082d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana private void installHandleTooManyDeletesNotification(Account account, String authority, 30834120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn long numDeletes, int userId) { 30849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNotificationMgr == null) return; 3085c848b7023bcb19d7a392eb9f4669e56906e5382cFred Quintana 3086c848b7023bcb19d7a392eb9f4669e56906e5382cFred Quintana final ProviderInfo providerInfo = mContext.getPackageManager().resolveContentProvider( 3087c848b7023bcb19d7a392eb9f4669e56906e5382cFred Quintana authority, 0 /* flags */); 3088c848b7023bcb19d7a392eb9f4669e56906e5382cFred Quintana if (providerInfo == null) { 3089c848b7023bcb19d7a392eb9f4669e56906e5382cFred Quintana return; 3090c848b7023bcb19d7a392eb9f4669e56906e5382cFred Quintana } 3091c848b7023bcb19d7a392eb9f4669e56906e5382cFred Quintana CharSequence authorityName = providerInfo.loadLabel(mContext.getPackageManager()); 3092c848b7023bcb19d7a392eb9f4669e56906e5382cFred Quintana 3093b19e62add0a747127952862bb7bea0b73379edccFred Quintana Intent clickIntent = new Intent(mContext, SyncActivityTooManyDeletes.class); 30949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project clickIntent.putExtra("account", account); 309586135d3240a50f9224b49fb8407a1c86cae0e1b9Tadashi G. Takaoka clickIntent.putExtra("authority", authority); 3096c848b7023bcb19d7a392eb9f4669e56906e5382cFred Quintana clickIntent.putExtra("provider", authorityName.toString()); 30979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project clickIntent.putExtra("numDeletes", numDeletes); 30989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 30999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!isActivityAvailable(clickIntent)) { 31009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "No activity found to handle too many deletes."); 31019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 31029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 31039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 310407ad8dc2087aa02da48353acc19ba82e62d99f82Kenny Guy UserHandle user = new UserHandle(userId); 31059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final PendingIntent pendingIntent = PendingIntent 31064120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn .getActivityAsUser(mContext, 0, clickIntent, 310707ad8dc2087aa02da48353acc19ba82e62d99f82Kenny Guy PendingIntent.FLAG_CANCEL_CURRENT, null, user); 31089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 31099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CharSequence tooManyDeletesDescFormat = mContext.getResources().getText( 31109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R.string.contentServiceTooManyDeletesNotificationDesc); 31119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 311207ad8dc2087aa02da48353acc19ba82e62d99f82Kenny Guy Context contextForUser = getContextForUser(user); 31139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Notification notification = 31149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new Notification(R.drawable.stat_notify_sync_error, 31159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.getString(R.string.contentServiceSync), 31169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.currentTimeMillis()); 311707ad8dc2087aa02da48353acc19ba82e62d99f82Kenny Guy notification.color = contextForUser.getResources().getColor( 3118255dd04271088590fedc46c8e22b2fd4ab142d39Selim Cinek com.android.internal.R.color.system_notification_accent_color); 311907ad8dc2087aa02da48353acc19ba82e62d99f82Kenny Guy notification.setLatestEventInfo(contextForUser, 312007ad8dc2087aa02da48353acc19ba82e62d99f82Kenny Guy contextForUser.getString(R.string.contentServiceSyncNotificationTitle), 3121c848b7023bcb19d7a392eb9f4669e56906e5382cFred Quintana String.format(tooManyDeletesDescFormat.toString(), authorityName), 31229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pendingIntent); 31239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notification.flags |= Notification.FLAG_ONGOING_EVENT; 31244120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn mNotificationMgr.notifyAsUser(null, account.hashCode() ^ authority.hashCode(), 312507ad8dc2087aa02da48353acc19ba82e62d99f82Kenny Guy notification, user); 31269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 31279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 31289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 31299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Checks whether an activity exists on the system image for the given intent. 31309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 31319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param intent The intent for an activity. 31329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Whether or not an activity exists. 31339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 31349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean isActivityAvailable(Intent intent) { 31359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PackageManager pm = mContext.getPackageManager(); 31369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project List<ResolveInfo> list = pm.queryIntentActivities(intent, 0); 31379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int listSize = list.size(); 31389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < listSize; i++) { 31399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResolveInfo resolveInfo = list.get(i); 31409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((resolveInfo.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) 31419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != 0) { 31429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 31439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 31449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 31459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 31469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 31479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 31489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 31499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long insertStartSyncEvent(SyncOperation syncOperation) { 31509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final long now = System.currentTimeMillis(); 315156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams EventLog.writeEvent(2720, 315256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams syncOperation.toEventLog(SyncStorageEngine.EVENT_START)); 315356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return mSyncStorageEngine.insertStartSyncEvent(syncOperation, now); 31549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 31559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 31569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void stopSyncEvent(long rowId, SyncOperation syncOperation, String resultMessage, 31579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int upstreamActivity, int downstreamActivity, long elapsedTime) { 315856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams EventLog.writeEvent(2720, 315956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams syncOperation.toEventLog(SyncStorageEngine.EVENT_STOP)); 316077c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana mSyncStorageEngine.stopSyncEvent(rowId, elapsedTime, 3161c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana resultMessage, downstreamActivity, upstreamActivity); 31629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 31639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3164918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana 3165918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana private boolean isSyncStillActive(ActiveSyncContext activeSyncContext) { 3166918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana for (ActiveSyncContext sync : mActiveSyncContexts) { 3167918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana if (sync == activeSyncContext) { 3168918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana return true; 3169918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 3170918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 3171918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana return false; 3172918339ab8255f8e1d03d8448ab1d9036c7c15173Fred Quintana } 317357286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert 317456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams /** 317556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams * Sync extra comparison function. 317656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams * @param b1 bundle to compare 317756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams * @param b2 other bundle to compare 317856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams * @param includeSyncSettings if false, ignore system settings in bundle. 317956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams */ 318056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams public static boolean syncExtrasEquals(Bundle b1, Bundle b2, boolean includeSyncSettings) { 318156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (b1 == b2) { 318256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return true; 318356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 31848ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams // Exit early if we can. 318556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (includeSyncSettings && b1.size() != b2.size()) { 318656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return false; 318756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 31888ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams Bundle bigger = b1.size() > b2.size() ? b1 : b2; 31898ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams Bundle smaller = b1.size() > b2.size() ? b2 : b1; 31908ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams for (String key : bigger.keySet()) { 319156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (!includeSyncSettings && isSyncSetting(key)) { 319256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams continue; 319356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 31948ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams if (!smaller.containsKey(key)) { 319556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return false; 319656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 31978ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams if (!bigger.get(key).equals(smaller.get(key))) { 319856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return false; 319956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 320056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 320156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return true; 320256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 320356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams 320456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams /** 32058ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837Matthew Williams * TODO: Get rid of this when we separate sync settings extras from dev specified extras. 320656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams * @return true if the provided key is used by the SyncManager in scheduling the sync. 320756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams */ 320856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams private static boolean isSyncSetting(String key) { 320956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (key.equals(ContentResolver.SYNC_EXTRAS_EXPEDITED)) { 321056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return true; 321156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 321256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (key.equals(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS)) { 321356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return true; 321456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 321556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (key.equals(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF)) { 321656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return true; 321756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 321856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (key.equals(ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY)) { 321956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return true; 322056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 322156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (key.equals(ContentResolver.SYNC_EXTRAS_MANUAL)) { 322256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return true; 322356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 322456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (key.equals(ContentResolver.SYNC_EXTRAS_UPLOAD)) { 322556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return true; 322656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 322756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (key.equals(ContentResolver.SYNC_EXTRAS_OVERRIDE_TOO_MANY_DELETIONS)) { 322856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return true; 322956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 323056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (key.equals(ContentResolver.SYNC_EXTRAS_DISCARD_LOCAL_DELETIONS)) { 323156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return true; 323256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 323356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (key.equals(ContentResolver.SYNC_EXTRAS_EXPECTED_UPLOAD)) { 323456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return true; 323556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 323656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (key.equals(ContentResolver.SYNC_EXTRAS_EXPECTED_DOWNLOAD)) { 323756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return true; 323856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 323956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (key.equals(ContentResolver.SYNC_EXTRAS_PRIORITY)) { 324056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return true; 324156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 324256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (key.equals(ContentResolver.SYNC_EXTRAS_DISALLOW_METERED)) { 324356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return true; 324456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 324556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (key.equals(ContentResolver.SYNC_EXTRAS_INITIALIZE)) { 324656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return true; 324756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 324856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return false; 324956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 325056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams 325157286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert static class PrintTable { 325257286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert private ArrayList<Object[]> mTable = Lists.newArrayList(); 325357286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert private final int mCols; 325457286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert 325557286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert PrintTable(int cols) { 325657286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert mCols = cols; 325757286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert } 325857286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert 325957286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert void set(int row, int col, Object... values) { 326057286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert if (col + values.length > mCols) { 326157286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert throw new IndexOutOfBoundsException("Table only has " + mCols + 326257286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert " columns. can't set " + values.length + " at column " + col); 326357286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert } 326457286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert for (int i = mTable.size(); i <= row; i++) { 326557286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert final Object[] list = new Object[mCols]; 326657286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert mTable.add(list); 326757286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert for (int j = 0; j < mCols; j++) { 326857286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert list[j] = ""; 326957286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert } 327057286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert } 327157286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert System.arraycopy(values, 0, mTable.get(row), col, values.length); 327257286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert } 327357286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert 327457286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert void writeTo(PrintWriter out) { 327557286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert final String[] formats = new String[mCols]; 327657286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert int totalLength = 0; 327757286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert for (int col = 0; col < mCols; ++col) { 327857286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert int maxLength = 0; 327957286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert for (Object[] row : mTable) { 328057286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert final int length = row[col].toString().length(); 328157286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert if (length > maxLength) { 328257286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert maxLength = length; 328357286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert } 328457286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert } 328557286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert totalLength += maxLength; 328657286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert formats[col] = String.format("%%-%ds", maxLength); 328757286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert } 328831068163b660ff041e45f35174f75106dcb47adePatrick Tjin formats[mCols - 1] = "%s"; 328957286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert printRow(out, formats, mTable.get(0)); 329057286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert totalLength += (mCols - 1) * 2; 329157286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert for (int i = 0; i < totalLength; ++i) { 329257286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert out.print("-"); 329357286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert } 329457286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert out.println(); 329557286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert for (int i = 1, mTableSize = mTable.size(); i < mTableSize; i++) { 329657286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert Object[] row = mTable.get(i); 329757286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert printRow(out, formats, row); 329857286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert } 329957286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert } 330057286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert 330157286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert private void printRow(PrintWriter out, String[] formats, Object[] row) { 330257286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert for (int j = 0, rowLength = row.length; j < rowLength; j++) { 330357286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert out.printf(String.format(formats[j], row[j].toString())); 330457286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert out.print(" "); 330557286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert } 330657286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert out.println(); 330757286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert } 330857286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert 330957286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert public int getNumRows() { 331057286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert return mTable.size(); 331157286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert } 331257286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert } 331307ad8dc2087aa02da48353acc19ba82e62d99f82Kenny Guy 331407ad8dc2087aa02da48353acc19ba82e62d99f82Kenny Guy private Context getContextForUser(UserHandle user) { 331507ad8dc2087aa02da48353acc19ba82e62d99f82Kenny Guy try { 331607ad8dc2087aa02da48353acc19ba82e62d99f82Kenny Guy return mContext.createPackageContextAsUser(mContext.getPackageName(), 0, user); 331707ad8dc2087aa02da48353acc19ba82e62d99f82Kenny Guy } catch (NameNotFoundException e) { 331807ad8dc2087aa02da48353acc19ba82e62d99f82Kenny Guy // Default to mContext, not finding the package system is running as is unlikely. 331907ad8dc2087aa02da48353acc19ba82e62d99f82Kenny Guy return mContext; 332007ad8dc2087aa02da48353acc19ba82e62d99f82Kenny Guy } 332107ad8dc2087aa02da48353acc19ba82e62d99f82Kenny Guy } 33229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3323