ProfileSyncService.java revision 9ab5563a3196760eb381d102cbb2bc0f7abc6a50
1282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// Copyright 2013 The Chromium Authors. All rights reserved. 2282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// Use of this source code is governed by a BSD-style license that can be 3282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// found in the LICENSE file. 4282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 5282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipackage org.chromium.chrome.browser.sync; 6282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 7282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.content.Context; 8282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.util.Log; 9282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 10282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.google.common.annotations.VisibleForTesting; 11282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 12282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport org.chromium.base.CalledByNative; 13282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport org.chromium.base.ThreadUtils; 14282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport org.chromium.chrome.browser.identity.UniqueIdentificationGenerator; 15282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport org.chromium.sync.internal_api.pub.SyncDecryptionPassphraseType; 16282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport org.chromium.sync.internal_api.pub.base.ModelType; 17282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 18282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.util.HashSet; 19282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.util.List; 20282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.util.Set; 21282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.util.concurrent.CopyOnWriteArrayList; 22282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 23282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/** 24282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Android wrapper of the ProfileSyncService which provides access from the Java layer. 25282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * <p/> 26282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * This class mostly wraps native classes, but it make a few business logic decisions, both in Java 27282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * and in native. 28282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * <p/> 29282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Only usable from the UI thread as the native ProfileSyncService requires its access to be in the 30282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * UI thread. 31282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * <p/> 32282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * See chrome/browser/sync/profile_sync_service.h for more details. 33282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 34282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipublic class ProfileSyncService { 35282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 36282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public interface SyncStateChangedListener { 37282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Invoked when the underlying sync status has changed. 38282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void syncStateChanged(); 39282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 40282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 41282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private static final String TAG = "ProfileSyncService"; 42282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 43282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @VisibleForTesting 44282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public static final String SESSION_TAG_PREFIX = "session_sync"; 45282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 46282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private static ProfileSyncService sSyncSetupManager; 47282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 48282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @VisibleForTesting 49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski protected final Context mContext; 50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 51282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Sync state changes more often than listeners are added/removed, so using CopyOnWrite. 52282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private final List<SyncStateChangedListener> mListeners = 53282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski new CopyOnWriteArrayList<SyncStateChangedListener>(); 54282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 55282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Native ProfileSyncServiceAndroid object. Can not be final since we set it to 0 in destroy(). 56282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private final int mNativeProfileSyncServiceAndroid; 57282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 58282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 59282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * A helper method for retrieving the application-wide SyncSetupManager. 60282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * <p/> 61282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Can only be accessed on the main thread. 62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 63282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param context the ApplicationContext is retrieved from the context used as an argument. 64282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @return a singleton instance of the SyncSetupManager 65282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 66282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public static ProfileSyncService get(Context context) { 67282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ThreadUtils.assertOnUiThread(); 68282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (sSyncSetupManager == null) { 69282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sSyncSetupManager = new ProfileSyncService(context); 70282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 71282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return sSyncSetupManager; 72282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 73282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 74282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 75282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * This is called pretty early in our application. Avoid any blocking operations here. 76282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 77282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private ProfileSyncService(Context context) { 78282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ThreadUtils.assertOnUiThread(); 79282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // We should store the application context, as we outlive any activity which may create us. 80282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mContext = context.getApplicationContext(); 81282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // This may cause us to create ProfileSyncService even if sync has not 83282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // been set up, but ProfileSyncService::Startup() won't be called until 84282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // credentials are available. 85282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mNativeProfileSyncServiceAndroid = nativeInit(); 86282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 87282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 88282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @CalledByNative 89282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private static int getProfileSyncServiceAndroid(Context context) { 90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return get(context).mNativeProfileSyncServiceAndroid; 91282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 92282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 93282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 94282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * If we are currently in the process of setting up sync, this method clears the 95282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * sync setup in progress flag. 96282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 97282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @VisibleForTesting 98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void finishSyncFirstSetupIfNeeded() { 99282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (isFirstSetupInProgress()) { 100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski setSyncSetupCompleted(); 101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski setSetupInProgress(false); 102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void signOut() { 106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski nativeSignOutSync(mNativeProfileSyncServiceAndroid); 107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Signs in to sync, using the currently signed-in account. 111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void syncSignIn() { 113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski nativeSignInSync(mNativeProfileSyncServiceAndroid); 114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Notify listeners right away that the sync state has changed (native side does not do 115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // this) 116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski syncStateChanged(); 117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Signs in to sync, using the existing auth token. 121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Deprecated 123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void syncSignIn(String account) { 124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski syncSignIn(); 125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Signs in to sync. 129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param account The username of the account that is signing in. 131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param authToken Not used. ProfileSyncService switched to OAuth2 tokens. 132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Deprecated. Use syncSignIn instead. 133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Deprecated 135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void syncSignInWithAuthToken(String account, String authToken) { 136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski syncSignIn(account); 137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void requestSyncFromNativeChrome(String objectId, long version, String payload) { 140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ThreadUtils.assertOnUiThread(); 141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski nativeNudgeSyncer(mNativeProfileSyncServiceAndroid, objectId, version, payload); 142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void requestSyncFromNativeChromeForAllTypes() { 145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ThreadUtils.assertOnUiThread(); 146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski nativeNudgeSyncerForAllTypes(mNativeProfileSyncServiceAndroid); 147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Nudge the syncer to start a new sync cycle. 151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @VisibleForTesting 153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void requestSyncCycleForTest() { 154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ThreadUtils.assertOnUiThread(); 155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski requestSyncFromNativeChromeForAllTypes(); 156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public String querySyncStatus() { 159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ThreadUtils.assertOnUiThread(); 160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return nativeQuerySyncStatusSummary(mNativeProfileSyncServiceAndroid); 161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Sets the the machine tag used by session sync to a unique value. 165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void setSessionsId(UniqueIdentificationGenerator generator) { 167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ThreadUtils.assertOnUiThread(); 168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String uniqueTag = generator.getUniqueId(null); 169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (uniqueTag.isEmpty()) { 170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Log.e(TAG, "Unable to get unique tag for sync. " + 171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "This may lead to unexpected tab sync behavior."); 172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String sessionTag = SESSION_TAG_PREFIX + uniqueTag; 175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!nativeSetSyncSessionsId(mNativeProfileSyncServiceAndroid, sessionTag)) { 176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Log.e(TAG, "Unable to write session sync tag. " + 177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "This may lead to unexpected tab sync behavior."); 178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Checks if a password or a passphrase is required for decryption of sync data. 183 * <p/> 184 * Returns NONE if the state is unavailable, or decryption passphrase/password is not required. 185 * 186 * @return the enum describing the decryption passphrase type required 187 */ 188 public SyncDecryptionPassphraseType getSyncDecryptionPassphraseTypeIfRequired() { 189 // ProfileSyncService::IsUsingSecondaryPassphrase() requires the sync backend to be 190 // initialized, and that happens just after OnPassphraseRequired(). Therefore, we need to 191 // guard that call with a check of the sync backend since we can not be sure which 192 // passphrase type we should tell the user we need. 193 // This is tracked in: 194 // http://code.google.com/p/chromium/issues/detail?id=108127 195 if (isSyncInitialized() && isPassphraseRequiredForDecryption()) { 196 return getSyncDecryptionPassphraseType(); 197 } 198 return SyncDecryptionPassphraseType.NONE; 199 } 200 201 /** 202 * Returns the actual passphrase type being used for encryption. The sync backend must be 203 * running (isSyncInitialized() returns true) before calling this function. 204 * <p/> 205 * This method should only be used if you want to know the raw value. For checking whether we 206 * should ask the user for a passphrase, you should instead use 207 * getSyncDecryptionPassphraseTypeIfRequired(). 208 */ 209 public SyncDecryptionPassphraseType getSyncDecryptionPassphraseType() { 210 assert isSyncInitialized(); 211 int passphraseType = nativeGetPassphraseType(mNativeProfileSyncServiceAndroid); 212 return SyncDecryptionPassphraseType.fromInternalValue(passphraseType); 213 } 214 215 public boolean isSyncKeystoreMigrationDone() { 216 assert isSyncInitialized(); 217 return nativeIsSyncKeystoreMigrationDone(mNativeProfileSyncServiceAndroid); 218 } 219 220 /** 221 * Returns true if the current explicit passphrase time is defined. 222 */ 223 public boolean hasExplicitPassphraseTime() { 224 assert isSyncInitialized(); 225 return nativeHasExplicitPassphraseTime(mNativeProfileSyncServiceAndroid); 226 } 227 228 public String getSyncEnterGooglePassphraseBodyWithDateText() { 229 assert isSyncInitialized(); 230 return nativeGetSyncEnterGooglePassphraseBodyWithDateText(mNativeProfileSyncServiceAndroid); 231 } 232 233 public String getSyncEnterCustomPassphraseBodyWithDateText() { 234 assert isSyncInitialized(); 235 return nativeGetSyncEnterCustomPassphraseBodyWithDateText(mNativeProfileSyncServiceAndroid); 236 } 237 238 public String getCurrentSignedInAccountText() { 239 assert isSyncInitialized(); 240 return nativeGetCurrentSignedInAccountText(mNativeProfileSyncServiceAndroid); 241 } 242 243 public String getSyncEnterCustomPassphraseBodyText() { 244 return nativeGetSyncEnterCustomPassphraseBodyText(mNativeProfileSyncServiceAndroid); 245 } 246 247 /** 248 * Checks if sync is currently set to use a custom passphrase. The sync backend must be running 249 * (isSyncInitialized() returns true) before calling this function. 250 * 251 * @return true if sync is using a custom passphrase. 252 */ 253 public boolean isUsingSecondaryPassphrase() { 254 assert isSyncInitialized(); 255 return nativeIsUsingSecondaryPassphrase(mNativeProfileSyncServiceAndroid); 256 } 257 258 /** 259 * Checks if we need a passphrase to decrypt a currently-enabled data type. This returns false 260 * if a passphrase is needed for a type that is not currently enabled. 261 * 262 * @return true if we need a passphrase. 263 */ 264 public boolean isPassphraseRequiredForDecryption() { 265 assert isSyncInitialized(); 266 return nativeIsPassphraseRequiredForDecryption(mNativeProfileSyncServiceAndroid); 267 } 268 269 /** 270 * Checks if we need a passphrase to decrypt any data type (including types that aren't 271 * currently enabled or supported, such as passwords). This API is used to determine if we 272 * need to provide a decryption passphrase before we can re-encrypt with a custom passphrase. 273 * 274 * @return true if we need a passphrase for some type. 275 */ 276 public boolean isPassphraseRequiredForExternalType() { 277 assert isSyncInitialized(); 278 return nativeIsPassphraseRequiredForExternalType(mNativeProfileSyncServiceAndroid); 279 } 280 281 /** 282 * Checks if the sync backend is running. 283 * 284 * @return true if sync is initialized/running. 285 */ 286 public boolean isSyncInitialized() { 287 return nativeIsSyncInitialized(mNativeProfileSyncServiceAndroid); 288 } 289 290 /** 291 * Checks if the first sync setup is currently in progress. 292 * 293 * @return true if first sync setup is in progress 294 */ 295 public boolean isFirstSetupInProgress() { 296 return nativeIsFirstSetupInProgress(mNativeProfileSyncServiceAndroid); 297 } 298 299 /** 300 * Checks if the all the data types are encrypted. 301 * 302 * @return true if all data types are encrypted, false if only passwords are encrypted. 303 */ 304 public boolean isEncryptEverythingEnabled() { 305 assert isSyncInitialized(); 306 return nativeIsEncryptEverythingEnabled(mNativeProfileSyncServiceAndroid); 307 } 308 309 /** 310 * Turns on encryption of all data types. This only takes effect after sync configuration is 311 * completed and setPreferredDataTypes() is invoked. 312 */ 313 public void enableEncryptEverything() { 314 assert isSyncInitialized(); 315 nativeEnableEncryptEverything(mNativeProfileSyncServiceAndroid); 316 } 317 318 public void setEncryptionPassphrase(String passphrase, boolean isGaia) { 319 assert isSyncInitialized(); 320 nativeSetEncryptionPassphrase(mNativeProfileSyncServiceAndroid, passphrase, isGaia); 321 } 322 323 public boolean isCryptographerReady() { 324 assert isSyncInitialized(); 325 return nativeIsCryptographerReady(mNativeProfileSyncServiceAndroid); 326 } 327 328 public boolean setDecryptionPassphrase(String passphrase) { 329 assert isSyncInitialized(); 330 return nativeSetDecryptionPassphrase(mNativeProfileSyncServiceAndroid, passphrase); 331 } 332 333 public GoogleServiceAuthError.State getAuthError() { 334 int authErrorCode = nativeGetAuthError(mNativeProfileSyncServiceAndroid); 335 return GoogleServiceAuthError.State.fromCode(authErrorCode); 336 } 337 338 /** 339 * Gets the set of data types that are currently enabled to sync. 340 * 341 * @return Set of enabled types. 342 */ 343 public Set<ModelType> getPreferredDataTypes() { 344 long modelTypeSelection = 345 nativeGetEnabledDataTypes(mNativeProfileSyncServiceAndroid); 346 Set<ModelType> syncTypes = new HashSet<ModelType>(); 347 if ((modelTypeSelection & ModelTypeSelection.AUTOFILL) != 0) { 348 syncTypes.add(ModelType.AUTOFILL); 349 } 350 if ((modelTypeSelection & ModelTypeSelection.AUTOFILL_PROFILE) != 0) { 351 syncTypes.add(ModelType.AUTOFILL_PROFILE); 352 } 353 if ((modelTypeSelection & ModelTypeSelection.BOOKMARK) != 0) { 354 syncTypes.add(ModelType.BOOKMARK); 355 } 356 if ((modelTypeSelection & ModelTypeSelection.EXPERIMENTS) != 0) { 357 syncTypes.add(ModelType.EXPERIMENTS); 358 } 359 if ((modelTypeSelection & ModelTypeSelection.NIGORI) != 0) { 360 syncTypes.add(ModelType.NIGORI); 361 } 362 if ((modelTypeSelection & ModelTypeSelection.PASSWORD) != 0) { 363 syncTypes.add(ModelType.PASSWORD); 364 } 365 if ((modelTypeSelection & ModelTypeSelection.SESSION) != 0) { 366 syncTypes.add(ModelType.SESSION); 367 } 368 if ((modelTypeSelection & ModelTypeSelection.TYPED_URL) != 0) { 369 syncTypes.add(ModelType.TYPED_URL); 370 } 371 if ((modelTypeSelection & ModelTypeSelection.HISTORY_DELETE_DIRECTIVE) != 0) { 372 syncTypes.add(ModelType.HISTORY_DELETE_DIRECTIVE); 373 } 374 if ((modelTypeSelection & ModelTypeSelection.DEVICE_INFO) != 0) { 375 syncTypes.add(ModelType.DEVICE_INFO); 376 } 377 if ((modelTypeSelection & ModelTypeSelection.PROXY_TABS) != 0) { 378 syncTypes.add(ModelType.PROXY_TABS); 379 } 380 if ((modelTypeSelection & ModelTypeSelection.FAVICON_IMAGE) != 0) { 381 syncTypes.add(ModelType.FAVICON_IMAGE); 382 } 383 if ((modelTypeSelection & ModelTypeSelection.FAVICON_TRACKING) != 0) { 384 syncTypes.add(ModelType.FAVICON_TRACKING); 385 } 386 return syncTypes; 387 } 388 389 public boolean hasKeepEverythingSynced() { 390 return nativeHasKeepEverythingSynced(mNativeProfileSyncServiceAndroid); 391 } 392 393 /** 394 * Enables syncing for the passed data types. 395 * 396 * @param syncEverything Set to true if the user wants to sync all data types 397 * (including new data types we add in the future). 398 * @param enabledTypes The set of types to enable. Ignored (can be null) if 399 * syncEverything is true. 400 */ 401 public void setPreferredDataTypes(boolean syncEverything, Set<ModelType> enabledTypes) { 402 long modelTypeSelection = 0; 403 if (syncEverything || enabledTypes.contains(ModelType.AUTOFILL)) { 404 modelTypeSelection |= ModelTypeSelection.AUTOFILL; 405 } 406 if (syncEverything || enabledTypes.contains(ModelType.BOOKMARK)) { 407 modelTypeSelection |= ModelTypeSelection.BOOKMARK; 408 } 409 if (syncEverything || enabledTypes.contains(ModelType.PASSWORD)) { 410 modelTypeSelection |= ModelTypeSelection.PASSWORD; 411 } 412 if (syncEverything || enabledTypes.contains(ModelType.PROXY_TABS)) { 413 modelTypeSelection |= ModelTypeSelection.PROXY_TABS; 414 } 415 if (syncEverything || enabledTypes.contains(ModelType.TYPED_URL)) { 416 modelTypeSelection |= ModelTypeSelection.TYPED_URL; 417 } 418 nativeSetPreferredDataTypes( 419 mNativeProfileSyncServiceAndroid, syncEverything, modelTypeSelection); 420 } 421 422 public void setSyncSetupCompleted() { 423 nativeSetSyncSetupCompleted(mNativeProfileSyncServiceAndroid); 424 } 425 426 public boolean hasSyncSetupCompleted() { 427 return nativeHasSyncSetupCompleted(mNativeProfileSyncServiceAndroid); 428 } 429 430 public boolean isStartSuppressed() { 431 return nativeIsStartSuppressed(mNativeProfileSyncServiceAndroid); 432 } 433 434 /** 435 * Notifies sync whether sync setup is in progress - this tells sync whether it should start 436 * syncing data types when it starts up, or if it should just stay in "configuration mode". 437 * 438 * @param inProgress True to put sync in configuration mode, false to turn off configuration 439 * and allow syncing. 440 */ 441 public void setSetupInProgress(boolean inProgress) { 442 nativeSetSetupInProgress(mNativeProfileSyncServiceAndroid, inProgress); 443 } 444 445 public void addSyncStateChangedListener(SyncStateChangedListener listener) { 446 ThreadUtils.assertOnUiThread(); 447 mListeners.add(listener); 448 } 449 450 public void removeSyncStateChangedListener(SyncStateChangedListener listener) { 451 ThreadUtils.assertOnUiThread(); 452 mListeners.remove(listener); 453 } 454 455 public boolean hasUnrecoverableError() { 456 return nativeHasUnrecoverableError(mNativeProfileSyncServiceAndroid); 457 } 458 459 /** 460 * Called when the state of the native sync engine has changed, so various 461 * UI elements can update themselves. 462 */ 463 @CalledByNative 464 public void syncStateChanged() { 465 if (!mListeners.isEmpty()) { 466 for (SyncStateChangedListener listener : mListeners) { 467 listener.syncStateChanged(); 468 } 469 } 470 } 471 472 @VisibleForTesting 473 public String getSyncInternalsInfoForTest() { 474 ThreadUtils.assertOnUiThread(); 475 return nativeGetAboutInfoForTest(mNativeProfileSyncServiceAndroid); 476 } 477 478 /** 479 * Starts the sync engine. 480 */ 481 public void enableSync() { 482 nativeEnableSync(mNativeProfileSyncServiceAndroid); 483 } 484 485 /** 486 * Stops the sync engine. 487 */ 488 public void disableSync() { 489 nativeDisableSync(mNativeProfileSyncServiceAndroid); 490 } 491 492 // Native methods 493 private native void nativeNudgeSyncer( 494 int nativeProfileSyncServiceAndroid, String objectId, long version, String payload); 495 private native void nativeNudgeSyncerForAllTypes(int nativeProfileSyncServiceAndroid); 496 private native int nativeInit(); 497 private native void nativeEnableSync(int nativeProfileSyncServiceAndroid); 498 private native void nativeDisableSync(int nativeProfileSyncServiceAndroid); 499 private native void nativeSignInSync(int nativeProfileSyncServiceAndroid); 500 private native void nativeSignOutSync(int nativeProfileSyncServiceAndroid); 501 private native void nativeTokenAvailable( 502 int nativeProfileSyncServiceAndroid, String username, String authToken); 503 private native boolean nativeSetSyncSessionsId(int nativeProfileSyncServiceAndroid, String tag); 504 private native String nativeQuerySyncStatusSummary(int nativeProfileSyncServiceAndroid); 505 private native int nativeGetAuthError(int nativeProfileSyncServiceAndroid); 506 private native boolean nativeIsSyncInitialized(int nativeProfileSyncServiceAndroid); 507 private native boolean nativeIsFirstSetupInProgress(int nativeProfileSyncServiceAndroid); 508 private native boolean nativeIsEncryptEverythingEnabled(int nativeProfileSyncServiceAndroid); 509 private native void nativeEnableEncryptEverything(int nativeProfileSyncServiceAndroid); 510 private native boolean nativeIsPassphraseRequiredForDecryption( 511 int nativeProfileSyncServiceAndroid); 512 private native boolean nativeIsPassphraseRequiredForExternalType( 513 int nativeProfileSyncServiceAndroid); 514 private native boolean nativeIsUsingSecondaryPassphrase(int nativeProfileSyncServiceAndroid); 515 private native boolean nativeSetDecryptionPassphrase( 516 int nativeProfileSyncServiceAndroid, String passphrase); 517 private native void nativeSetEncryptionPassphrase( 518 int nativeProfileSyncServiceAndroid, String passphrase, boolean isGaia); 519 private native boolean nativeIsCryptographerReady(int nativeProfileSyncServiceAndroid); 520 private native int nativeGetPassphraseType(int nativeProfileSyncServiceAndroid); 521 private native boolean nativeHasExplicitPassphraseTime(int nativeProfileSyncServiceAndroid); 522 private native String nativeGetSyncEnterGooglePassphraseBodyWithDateText( 523 int nativeProfileSyncServiceAndroid); 524 private native String nativeGetSyncEnterCustomPassphraseBodyWithDateText( 525 int nativeProfileSyncServiceAndroid); 526 private native String nativeGetCurrentSignedInAccountText(int nativeProfileSyncServiceAndroid); 527 private native String nativeGetSyncEnterCustomPassphraseBodyText( 528 int nativeProfileSyncServiceAndroid); 529 private native boolean nativeIsSyncKeystoreMigrationDone(int nativeProfileSyncServiceAndroid); 530 private native long nativeGetEnabledDataTypes( 531 int nativeProfileSyncServiceAndroid); 532 private native void nativeSetPreferredDataTypes( 533 int nativeProfileSyncServiceAndroid, boolean syncEverything, long modelTypeSelection); 534 private native void nativeSetSetupInProgress( 535 int nativeProfileSyncServiceAndroid, boolean inProgress); 536 private native void nativeSetSyncSetupCompleted(int nativeProfileSyncServiceAndroid); 537 private native boolean nativeHasSyncSetupCompleted(int nativeProfileSyncServiceAndroid); 538 private native boolean nativeIsStartSuppressed(int nativeProfileSyncServiceAndroid); 539 private native boolean nativeHasKeepEverythingSynced(int nativeProfileSyncServiceAndroid); 540 private native boolean nativeHasUnrecoverableError(int nativeProfileSyncServiceAndroid); 541 private native String nativeGetAboutInfoForTest(int nativeProfileSyncServiceAndroid); 542} 543