| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.chrome.browser; | 5 package org.chromium.chrome.browser; |
| 6 | 6 |
| 7 import android.accounts.Account; |
| 8 import android.accounts.AccountManager; |
| 7 import android.annotation.TargetApi; | 9 import android.annotation.TargetApi; |
| 8 import android.app.backup.BackupAgent; | 10 import android.app.backup.BackupAgent; |
| 9 import android.app.backup.BackupDataInput; | 11 import android.app.backup.BackupDataInput; |
| 10 import android.app.backup.BackupDataOutput; | 12 import android.app.backup.BackupDataOutput; |
| 11 import android.content.SharedPreferences; | 13 import android.content.SharedPreferences; |
| 12 import android.os.Build; | 14 import android.os.Build; |
| 13 import android.os.ParcelFileDescriptor; | 15 import android.os.ParcelFileDescriptor; |
| 14 | 16 |
| 15 import org.chromium.base.ContextUtils; | 17 import org.chromium.base.ContextUtils; |
| 16 import org.chromium.base.Log; | 18 import org.chromium.base.Log; |
| 19 import org.chromium.base.VisibleForTesting; |
| 17 import org.chromium.chrome.browser.firstrun.FirstRunSignInProcessor; | 20 import org.chromium.chrome.browser.firstrun.FirstRunSignInProcessor; |
| 18 import org.chromium.chrome.browser.firstrun.FirstRunStatus; | 21 import org.chromium.chrome.browser.firstrun.FirstRunStatus; |
| 19 import org.chromium.chrome.browser.preferences.privacy.PrivacyPreferences; | 22 import org.chromium.chrome.browser.preferences.privacy.PrivacyPreferences; |
| 20 import org.chromium.sync.signin.ChromeSigninController; | 23 import org.chromium.sync.signin.ChromeSigninController; |
| 21 | 24 |
| 22 import java.io.IOException; | 25 import java.io.IOException; |
| 23 import java.util.Arrays; | 26 import java.util.Arrays; |
| 24 import java.util.HashSet; | 27 import java.util.HashSet; |
| 25 import java.util.Set; | 28 import java.util.Set; |
| 26 | 29 |
| 27 /** | 30 /** |
| 28 * Backup agent for Chrome, filters the restored backup to remove preferences th
at should not have | 31 * Backup agent for Chrome, filters the restored backup to remove preferences th
at should not have |
| 29 * been restored. | 32 * been restored. |
| 33 * |
| 34 * Note: Nothing in this class can depend on the ChromeApplication instance havi
ng been created. |
| 35 * During restore Android creates a special instance of the Chrome application w
ith its own |
| 36 * Android defined application class, which is not derived from ChromeApplicatio
n. |
| 30 */ | 37 */ |
| 31 @TargetApi(Build.VERSION_CODES.LOLLIPOP) | 38 @TargetApi(Build.VERSION_CODES.LOLLIPOP) |
| 32 public class ChromeBackupAgent extends BackupAgent { | 39 public class ChromeBackupAgent extends BackupAgent { |
| 33 | 40 |
| 34 private static final String TAG = "ChromeBackupAgent"; | 41 private static final String TAG = "ChromeBackupAgent"; |
| 35 | 42 |
| 36 // Lists of preferences that should be restored unchanged. | 43 // Lists of preferences that should be restored unchanged. |
| 37 | 44 |
| 38 // TODO(aberent): At present this only restores the signed in user, and the
FRE settings | 45 // TODO(aberent): At present this only restores the signed in user, and the
FRE settings |
| 39 // (whether is has been completed, and whether the user disabled crash dump
reporting). It | 46 // (whether is has been completed, and whether the user disabled crash dump
reporting). It |
| 40 // should restore all non-device specific aspects of the user's state. This
will involve both | 47 // should also restore all the user's sync choices. This will involve restor
ing a number of |
| 41 // restoring many more Android preferences and many Chrome preferences (in C
hrome's JSON | 48 // Chrome preferences (in Chrome's JSON preference file) in addition to the
Android preferences |
| 42 // preference file). | 49 // currently restored. |
| 43 private static final String[] RESTORED_ANDROID_PREFS = { | 50 private static final String[] RESTORED_ANDROID_PREFS = { |
| 44 PrivacyPreferences.PREF_CRASH_DUMP_UPLOAD, | 51 PrivacyPreferences.PREF_CRASH_DUMP_UPLOAD, |
| 45 FirstRunStatus.FIRST_RUN_FLOW_COMPLETE, | 52 FirstRunStatus.FIRST_RUN_FLOW_COMPLETE, |
| 46 FirstRunSignInProcessor.FIRST_RUN_FLOW_SIGNIN_SETUP, | 53 FirstRunSignInProcessor.FIRST_RUN_FLOW_SIGNIN_SETUP, |
| 47 }; | 54 }; |
| 48 | 55 |
| 56 private static boolean sAllowChromeApplication = false; |
| 57 |
| 49 @Override | 58 @Override |
| 50 public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data, | 59 public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data, |
| 51 ParcelFileDescriptor newState) throws IOException { | 60 ParcelFileDescriptor newState) throws IOException { |
| 52 // No implementation needed for Android 6.0 Auto Backup. Used only on ol
der versions of | 61 // No implementation needed for Android 6.0 Auto Backup. Used only on ol
der versions of |
| 53 // Android Backup | 62 // Android Backup |
| 54 } | 63 } |
| 55 | 64 |
| 56 @Override | 65 @Override |
| 57 public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDe
scriptor newState) | 66 public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDe
scriptor newState) |
| 58 throws IOException { | 67 throws IOException { |
| 59 // No implementation needed for Android 6.0 Auto Backup. Used only on ol
der versions of | 68 // No implementation needed for Android 6.0 Auto Backup. Used only on ol
der versions of |
| 60 // Android Backup | 69 // Android Backup |
| 61 } | 70 } |
| 62 | 71 |
| 72 // May be overriden by downstream products that access account information i
n a different way. |
| 73 protected Account[] getAccounts() { |
| 74 Log.d(TAG, "Getting accounts from AccountManager"); |
| 75 AccountManager manager = (AccountManager) getSystemService(ACCOUNT_SERVI
CE); |
| 76 return manager.getAccounts(); |
| 77 } |
| 78 |
| 79 private boolean accountExistsOnDevice(String userName) { |
| 80 // This cannot use AccountManagerHelper, since that depends on ChromeApp
lication. |
| 81 for (Account account: getAccounts()) { |
| 82 if (account.name.equals(userName)) return true; |
| 83 } |
| 84 return false; |
| 85 } |
| 86 |
| 63 @Override | 87 @Override |
| 64 public void onRestoreFinished() { | 88 public void onRestoreFinished() { |
| 89 if (getApplicationContext() instanceof ChromeApplication && !sAllowChrom
eApplication) { |
| 90 // This should never happen in real use, but will happen during test
ing if Chrome is |
| 91 // already running (even in background, started to provide a service
, for example). |
| 92 Log.w(TAG, "Running with wrong type of Application class"); |
| 93 return; |
| 94 } |
| 95 // This is running without a ChromeApplication instance, so this has to
be done here. |
| 96 ContextUtils.initApplicationContext(getApplicationContext()); |
| 65 SharedPreferences sharedPrefs = ContextUtils.getAppSharedPreferences(); | 97 SharedPreferences sharedPrefs = ContextUtils.getAppSharedPreferences(); |
| 66 Set<String> prefNames = sharedPrefs.getAll().keySet(); | 98 Set<String> prefNames = sharedPrefs.getAll().keySet(); |
| 67 // Save the user name for later restoration. | 99 // Save the user name for later restoration. |
| 68 String userName = sharedPrefs.getString(ChromeSigninController.SIGNED_IN
_ACCOUNT_KEY, null); | 100 String userName = sharedPrefs.getString(ChromeSigninController.SIGNED_IN
_ACCOUNT_KEY, null); |
| 101 Log.d(TAG, "Previous signed in user name = " + userName); |
| 102 // If the user hasn't signed in, or can't sign in, then don't restore an
ything. |
| 103 if (userName == null || !accountExistsOnDevice(userName)) { |
| 104 boolean commitResult = sharedPrefs.edit().clear().commit(); |
| 105 Log.d(TAG, "onRestoreFinished complete, nothing restored; commit res
ult = %s", |
| 106 commitResult); |
| 107 return; |
| 108 } |
| 109 |
| 69 SharedPreferences.Editor editor = sharedPrefs.edit(); | 110 SharedPreferences.Editor editor = sharedPrefs.edit(); |
| 70 // Throw away prefs we don't want to restore. | 111 // Throw away prefs we don't want to restore. |
| 71 Set<String> restoredPrefs = new HashSet<>(Arrays.asList(RESTORED_ANDROID
_PREFS)); | 112 Set<String> restoredPrefs = new HashSet<>(Arrays.asList(RESTORED_ANDROID
_PREFS)); |
| 72 for (String pref : prefNames) { | 113 for (String pref : prefNames) { |
| 73 Log.d(TAG, "Checking pref " + pref); | |
| 74 if (!restoredPrefs.contains(pref)) editor.remove(pref); | 114 if (!restoredPrefs.contains(pref)) editor.remove(pref); |
| 75 } | 115 } |
| 76 // Because FirstRunSignInProcessor.FIRST_RUN_FLOW_SIGNIN_COMPLETE is not
restored Chrome | 116 // Because FirstRunSignInProcessor.FIRST_RUN_FLOW_SIGNIN_COMPLETE is not
restored Chrome |
| 77 // will sign in the user on first run to the account in FIRST_RUN_FLOW_S
IGNIN_ACCOUNT_NAME | 117 // will sign in the user on first run to the account in FIRST_RUN_FLOW_S
IGNIN_ACCOUNT_NAME |
| 78 // if any. If the rest of FRE has been completed this will happen silent
ly. | 118 // if any. If the rest of FRE has been completed this will happen silent
ly. |
| 79 if (userName != null) { | 119 editor.putString(FirstRunSignInProcessor.FIRST_RUN_FLOW_SIGNIN_ACCOUNT_N
AME, userName); |
| 80 editor.putString(FirstRunSignInProcessor.FIRST_RUN_FLOW_SIGNIN_ACCOU
NT_NAME, userName); | |
| 81 } | |
| 82 boolean commitResult = editor.commit(); | 120 boolean commitResult = editor.commit(); |
| 83 | 121 |
| 84 Log.d(TAG, "onRestoreFinished complete; commit result = " + commitResult
); | 122 Log.d(TAG, "onRestoreFinished complete; commit result = %s", commitResul
t); |
| 123 } |
| 124 |
| 125 @VisibleForTesting |
| 126 static void allowChromeApplicationForTesting() { |
| 127 sAllowChromeApplication = true; |
| 85 } | 128 } |
| 86 } | 129 } |
| OLD | NEW |