ProfileSyncService.java revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Copyright 2013 The Chromium Authors. All rights reserved. 2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Use of this source code is governed by a BSD-style license that can be 3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// found in the LICENSE file. 4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgpackage org.chromium.chrome.browser.sync; 6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgimport android.content.Context; 8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgimport android.util.Log; 9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgimport com.google.common.annotations.VisibleForTesting; 11b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgimport org.chromium.base.CalledByNative; 13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgimport org.chromium.base.ThreadUtils; 14b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgimport org.chromium.chrome.browser.identity.UniqueIdentificationGenerator; 15281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.orgimport org.chromium.sync.internal_api.pub.SyncDecryptionPassphraseType; 16281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.orgimport org.chromium.sync.internal_api.pub.base.ModelType; 17281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org 18b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgimport java.util.HashSet; 19281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.orgimport java.util.List; 20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgimport java.util.Set; 21281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.orgimport java.util.concurrent.CopyOnWriteArrayList; 22281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org 23281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org/** 24281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org * Android wrapper of the ProfileSyncService which provides access from the Java layer. 25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * <p/> 26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This class mostly wraps native classes, but it make a few business logic decisions, both in Java 27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * and in native. 28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * <p/> 29281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org * Only usable from the UI thread as the native ProfileSyncService requires its access to be in the 30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * UI thread. 31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * <p/> 32b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * See chrome/browser/sync/profile_sync_service.h for more details. 33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgpublic class ProfileSyncService { 35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public interface SyncStateChangedListener { 37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Invoked when the underlying sync status has changed. 38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public void syncStateChanged(); 39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org private static final String TAG = ProfileSyncService.class.getSimpleName(); 42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org @VisibleForTesting 44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public static final String SESSION_TAG_PREFIX = "session_sync"; 45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org private static ProfileSyncService sSyncSetupManager; 47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org @VisibleForTesting 49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org protected final Context mContext; 50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Sync state changes more often than listeners are added/removed, so using CopyOnWrite. 52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org private final List<SyncStateChangedListener> mListeners = 53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org new CopyOnWriteArrayList<SyncStateChangedListener>(); 54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Native ProfileSyncServiceAndroid object. Can not be final since we set it to 0 in destroy(). 56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org private final int mNativeProfileSyncServiceAndroid; 57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /** 599d10769e109601915022fea44ec392645c3b0704wu@webrtc.org * A helper method for retrieving the application-wide SyncSetupManager. 609d10769e109601915022fea44ec392645c3b0704wu@webrtc.org * <p/> 61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Can only be accessed on the main thread. 629d10769e109601915022fea44ec392645c3b0704wu@webrtc.org * 63ea7b33ee032bd2d1528384e26ba079dee0d280fbwu@webrtc.org * @param context the ApplicationContext is retrieved from the context used as an argument. 64ea7b33ee032bd2d1528384e26ba079dee0d280fbwu@webrtc.org * @return a singleton instance of the SyncSetupManager 65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public static ProfileSyncService get(Context context) { 67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ThreadUtils.assertOnUiThread(); 68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (sSyncSetupManager == null) { 69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sSyncSetupManager = new ProfileSyncService(context); 70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return sSyncSetupManager; 72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 73ea7b33ee032bd2d1528384e26ba079dee0d280fbwu@webrtc.org 74ea7b33ee032bd2d1528384e26ba079dee0d280fbwu@webrtc.org /** 75b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This is called pretty early in our application. Avoid any blocking operations here. 76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org private ProfileSyncService(Context context) { 78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ThreadUtils.assertOnUiThread(); 79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // We should store the application context, as we outlive any activity which may create us. 80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mContext = context.getApplicationContext(); 81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // This may cause us to create ProfileSyncService even if sync has not 83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // been set up, but ProfileSyncService::Startup() won't be called until 84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // credentials are available. 85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mNativeProfileSyncServiceAndroid = nativeInit(); 86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org @CalledByNative 89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org private static int getProfileSyncServiceAndroid(Context context) { 90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return get(context).mNativeProfileSyncServiceAndroid; 91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /** 94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * If we are currently in the process of setting up sync, this method clears the 95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * sync setup in progress flag. 96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org @VisibleForTesting 98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public void finishSyncFirstSetupIfNeeded() { 99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (isFirstSetupInProgress()) { 100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org setSyncSetupCompleted(); 101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org setSetupInProgress(false); 102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public void signOut() { 106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org nativeSignOutSync(mNativeProfileSyncServiceAndroid); 107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /** 1105dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org * Signs in to sync, using the currently signed-in account. 111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public void syncSignIn() { 113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org nativeSignInSync(mNativeProfileSyncServiceAndroid); 114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Notify listeners right away that the sync state has changed (native side does not do 115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // this) 116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org syncStateChanged(); 117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /** 120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Signs in to sync, using the existing auth token. 121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org @Deprecated 123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public void syncSignIn(String account) { 1245dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org syncSignIn(); 1255dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org } 126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /** 128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Signs in to sync. 129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * @param account The username of the account that is signing in. 131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * @param authToken Not used. ProfileSyncService switched to OAuth2 tokens. 132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Deprecated. Use syncSignIn instead. 133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org @Deprecated 135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public void syncSignInWithAuthToken(String account, String authToken) { 136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org syncSignIn(account); 137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public void requestSyncFromNativeChrome(String objectId, long version, String payload) { 140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ThreadUtils.assertOnUiThread(); 141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org nativeNudgeSyncer(mNativeProfileSyncServiceAndroid, objectId, version, payload); 142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public void requestSyncFromNativeChromeForAllTypes() { 145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ThreadUtils.assertOnUiThread(); 1465dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org nativeNudgeSyncerForAllTypes(mNativeProfileSyncServiceAndroid); 147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /** 150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Nudge the syncer to start a new sync cycle. 151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org @VisibleForTesting 153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public void requestSyncCycleForTest() { 154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ThreadUtils.assertOnUiThread(); 155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org requestSyncFromNativeChromeForAllTypes(); 156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public String querySyncStatus() { 159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ThreadUtils.assertOnUiThread(); 160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return nativeQuerySyncStatusSummary(mNativeProfileSyncServiceAndroid); 161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /** 164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Sets the the machine tag used by session sync to a unique value. 165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public void setSessionsId(UniqueIdentificationGenerator generator) { 167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ThreadUtils.assertOnUiThread(); 168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org String uniqueTag = generator.getUniqueId(null); 169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (uniqueTag.isEmpty()) { 170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Log.e(TAG, "Unable to get unique tag for sync. " + 171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "This may lead to unexpected tab sync behavior."); 172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return; 173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org String sessionTag = SESSION_TAG_PREFIX + uniqueTag; 175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!nativeSetSyncSessionsId(mNativeProfileSyncServiceAndroid, sessionTag)) { 176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Log.e(TAG, "Unable to write session sync tag. " + 177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "This may lead to unexpected tab sync behavior."); 178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /** 182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Checks if a password or a passphrase is required for decryption of sync data. 183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * <p/> 184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Returns NONE if the state is unavailable, or decryption passphrase/password is not required. 185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * @return the enum describing the decryption passphrase type required 187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public SyncDecryptionPassphraseType getSyncDecryptionPassphraseTypeIfRequired() { 189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // ProfileSyncService::IsUsingSecondaryPassphrase() requires the sync backend to be 190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // initialized, and that happens just after OnPassphraseRequired(). Therefore, we need to 191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // guard that call with a check of the sync backend since we can not be sure which 192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // passphrase type we should tell the user we need. 193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // This is tracked in: 194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // http://code.google.com/p/chromium/issues/detail?id=108127 195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (isSyncInitialized() && isPassphraseRequiredForDecryption()) { 1965dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org return getSyncDecryptionPassphraseType(); 197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return SyncDecryptionPassphraseType.NONE; 199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /** 202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Returns the actual passphrase type being used for encryption. The sync backend must be 2035dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org * running (isSyncInitialized() returns true) before calling this function. 204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * <p/> 205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This method should only be used if you want to know the raw value. For checking whether we 206b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * should ask the user for a passphrase, you should instead use 207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * getSyncDecryptionPassphraseTypeIfRequired(). 2085dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org */ 209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public SyncDecryptionPassphraseType getSyncDecryptionPassphraseType() { 210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert isSyncInitialized(); 211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int passphraseType = nativeGetPassphraseType(mNativeProfileSyncServiceAndroid); 212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return SyncDecryptionPassphraseType.fromInternalValue(passphraseType); 2135dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org } 214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public boolean isSyncKeystoreMigrationDone() { 216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert isSyncInitialized(); 217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return nativeIsSyncKeystoreMigrationDone(mNativeProfileSyncServiceAndroid); 218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2195dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org 220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /** 221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Returns true if the current explicit passphrase time is defined. 222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public boolean hasExplicitPassphraseTime() { 2245dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org assert isSyncInitialized(); 225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return nativeHasExplicitPassphraseTime(mNativeProfileSyncServiceAndroid); 226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public String getSyncEnterGooglePassphraseBodyWithDateText() { 2295dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org assert isSyncInitialized(); 230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return nativeGetSyncEnterGooglePassphraseBodyWithDateText(mNativeProfileSyncServiceAndroid); 231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public String getSyncEnterCustomPassphraseBodyWithDateText() { 2345dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org assert isSyncInitialized(); 235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return nativeGetSyncEnterCustomPassphraseBodyWithDateText(mNativeProfileSyncServiceAndroid); 236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2375dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org 238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public String getCurrentSignedInAccountText() { 239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert isSyncInitialized(); 240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return nativeGetCurrentSignedInAccountText(mNativeProfileSyncServiceAndroid); 241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public String getSyncEnterCustomPassphraseBodyText() { 244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return nativeGetSyncEnterCustomPassphraseBodyText(mNativeProfileSyncServiceAndroid); 245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /** 248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Checks if sync is currently set to use a custom passphrase. The sync backend must be running 249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * (isSyncInitialized() returns true) before calling this function. 250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * @return true if sync is using a custom passphrase. 252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public boolean isUsingSecondaryPassphrase() { 254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert isSyncInitialized(); 255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return nativeIsUsingSecondaryPassphrase(mNativeProfileSyncServiceAndroid); 256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2575dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org 258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /** 259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Checks if we need a passphrase to decrypt a currently-enabled data type. This returns false 260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * if a passphrase is needed for a type that is not currently enabled. 261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * @return true if we need a passphrase. 263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public boolean isPassphraseRequiredForDecryption() { 265b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert isSyncInitialized(); 266b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return nativeIsPassphraseRequiredForDecryption(mNativeProfileSyncServiceAndroid); 267b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 268b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 269b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /** 270b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Checks if we need a passphrase to decrypt any data type (including types that aren't 271b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * currently enabled or supported, such as passwords). This API is used to determine if we 272b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * need to provide a decryption passphrase before we can re-encrypt with a custom passphrase. 273b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 274b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * @return true if we need a passphrase for some type. 275b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 276b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public boolean isPassphraseRequiredForExternalType() { 277b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert isSyncInitialized(); 278b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return nativeIsPassphraseRequiredForExternalType(mNativeProfileSyncServiceAndroid); 279b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2805dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org 281b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /** 282b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Checks if the sync backend is running. 283b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 284b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * @return true if sync is initialized/running. 285b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 286b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public boolean isSyncInitialized() { 287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return nativeIsSyncInitialized(mNativeProfileSyncServiceAndroid); 288b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 289b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /** 291b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Checks if the first sync setup is currently in progress. 292b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 293b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * @return true if first sync setup is in progress 294b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public boolean isFirstSetupInProgress() { 296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return nativeIsFirstSetupInProgress(mNativeProfileSyncServiceAndroid); 297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 298b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 299b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /** 300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Checks if the all the data types are encrypted. 301b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 302b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * @return true if all data types are encrypted, false if only passwords are encrypted. 303b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 304b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public boolean isEncryptEverythingEnabled() { 305b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert isSyncInitialized(); 306b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return nativeIsEncryptEverythingEnabled(mNativeProfileSyncServiceAndroid); 307b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 308b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 309b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /** 310b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Turns on encryption of all data types. This only takes effect after sync configuration is 311b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * completed and setPreferredDataTypes() is invoked. 312b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 313b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public void enableEncryptEverything() { 314b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert isSyncInitialized(); 315b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org nativeEnableEncryptEverything(mNativeProfileSyncServiceAndroid); 316b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 317b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 318b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public void setEncryptionPassphrase(String passphrase, boolean isGaia) { 319b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert isSyncInitialized(); 320b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org nativeSetEncryptionPassphrase(mNativeProfileSyncServiceAndroid, passphrase, isGaia); 321b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 322b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 323b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 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