Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(972)

Side by Side Diff: chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmSyncDataStateMachine.java

Issue 2772203004: Add progress and timeout dialogs for getting account management policy (Closed)
Patch Set: Addressed comments Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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.signin; 5 package org.chromium.chrome.browser.signin;
6 6
7 import android.app.DialogFragment; 7 import android.app.DialogFragment;
8 import android.app.Fragment; 8 import android.app.Fragment;
9 import android.app.FragmentManager; 9 import android.app.FragmentManager;
10 import android.content.Context; 10 import android.content.Context;
11 import android.support.annotation.IntDef; 11 import android.support.annotation.IntDef;
12 import android.text.TextUtils; 12 import android.text.TextUtils;
13 13
14 import org.chromium.base.Callback; 14 import org.chromium.base.Callback;
15 import org.chromium.base.Promise; 15 import org.chromium.base.ThreadUtils;
16 import org.chromium.chrome.browser.signin.ConfirmImportSyncDataDialog.ImportSync Type; 16 import org.chromium.chrome.browser.signin.ConfirmImportSyncDataDialog.ImportSync Type;
17 17
18 import java.lang.annotation.Retention; 18 import java.lang.annotation.Retention;
19 import java.lang.annotation.RetentionPolicy; 19 import java.lang.annotation.RetentionPolicy;
20 20
21 /** 21 /**
22 * This class takes care of the various dialogs that must be shown when the user changes the 22 * This class takes care of the various dialogs that must be shown when the user changes the
23 * account they are syncing to (either directly, or by signing in to a new accou nt). Most of the 23 * account they are syncing to (either directly, or by signing in to a new accou nt). Most of the
24 * complexity is due to many of the decisions getting answered through callbacks . 24 * complexity is due to many of the decisions getting answered through callbacks .
25 * 25 *
26 * This class progresses along the following state machine: 26 * This class progresses along the following state machine:
27 * 27 *
28 * E----\ G--\ 28 * E-----\ G--\
29 * ^ | ^ | 29 * ^ | ^ |
30 * | | | v 30 * | v | v
31 * A->B->C->D-+->F->H 31 * A->B->C->D->+->F->H
32 * | | 32 * | ^
33 * \-------/ 33 * v |
34 * \--------/
34 * 35 *
35 * Where: 36 * Where:
36 * A - Start 37 * A - Start
37 * B - Decision: progress to C if the user signed in previously to a different a ccount, F otherwise. 38 * B - Decision: progress to C if the user signed in previously to a different a ccount, F otherwise.
38 * C - Decision: progress to E if we are switching from a managed account, D oth erwise. 39 * C - Decision: progress to E if we are switching from a managed account, D oth erwise.
39 * D - Action: show Import Data Dialog. 40 * D - Action: show Import Data Dialog.
40 * E - Action: show Switching from Managed Account Dialog. 41 * E - Action: show Switching from Managed Account Dialog.
41 * F - Decision: progress to G if we are switching to a managed account, H other wise. 42 * F - Decision: progress to G if we are switching to a managed account, H other wise.
42 * G - Action: show Switching to Managed Account Dialog. 43 * G - Action: show Switching to Managed Account Dialog.
43 * H - End: perform {@link ConfirmImportSyncDataDialog.Listener#onConfirm} with the result of the 44 * H - End: perform {@link ConfirmImportSyncDataDialog.Listener#onConfirm} with the result of the
44 * Import Data Dialog, if displayed or true if switching from a managed acco unt. 45 * Import Data Dialog, if displayed or true if switching from a managed acco unt.
45 * 46 *
46 * At any dialog, the user can cancel the dialog and end the whole process (resu lting in 47 * At any dialog, the user can cancel the dialog and end the whole process (resu lting in
47 * {@link ConfirmImportSyncDataDialog.Listener#onCancel}). 48 * {@link ConfirmImportSyncDataDialog.Listener#onCancel}).
48 */ 49 */
49 public class ConfirmSyncDataStateMachine 50 public class ConfirmSyncDataStateMachine
50 implements ConfirmImportSyncDataDialog.Listener, ConfirmManagedSyncDataD ialog.Listener { 51 implements ConfirmImportSyncDataDialog.Listener, ConfirmManagedSyncDataD ialog.Listener {
51
52 @IntDef({
53 BEFORE_OLD_ACCOUNT_DIALOG, BEFORE_NEW_ACCOUNT_DIALOG,
54 AFTER_NEW_ACCOUNT_DIALOG, DONE
55 })
56 @Retention(RetentionPolicy.SOURCE) 52 @Retention(RetentionPolicy.SOURCE)
53 @IntDef({BEFORE_OLD_ACCOUNT_DIALOG, BEFORE_NEW_ACCOUNT_DIALOG, AFTER_NEW_ACC OUNT_DIALOG, DONE})
57 private @interface State {} 54 private @interface State {}
58 private static final int BEFORE_OLD_ACCOUNT_DIALOG = 0; // Start of state B . 55 private static final int BEFORE_OLD_ACCOUNT_DIALOG = 0; // Start of state B .
59 private static final int BEFORE_NEW_ACCOUNT_DIALOG = 1; // Start of state F . 56 private static final int BEFORE_NEW_ACCOUNT_DIALOG = 1; // Start of state F .
60 private static final int AFTER_NEW_ACCOUNT_DIALOG = 2; // Start of state H . 57 private static final int AFTER_NEW_ACCOUNT_DIALOG = 2; // Start of state H .
61 private static final int DONE = 4; 58 private static final int DONE = 4;
62 59
63 private boolean mWipeData;
64 @State private int mState = BEFORE_OLD_ACCOUNT_DIALOG; 60 @State private int mState = BEFORE_OLD_ACCOUNT_DIALOG;
65 61
62 private static final int ACCOUNT_CHECK_TIMEOUT_MS = 30000;
63
66 private final ConfirmImportSyncDataDialog.Listener mCallback; 64 private final ConfirmImportSyncDataDialog.Listener mCallback;
67 private final String mOldAccountName; 65 private final String mOldAccountName;
68 private final String mNewAccountName; 66 private final String mNewAccountName;
69 private final boolean mCurrentlyManaged; 67 private final boolean mCurrentlyManaged;
70 private final Promise<Boolean> mNewAccountManaged = new Promise<>();
71 private final FragmentManager mFragmentManager; 68 private final FragmentManager mFragmentManager;
72 private final Context mContext; 69 private final Context mContext;
73 private final ImportSyncType mImportSyncType; 70 private final ImportSyncType mImportSyncType;
71 private final ConfirmSyncDataStateMachineDelegate mDelegate;
72
73 private boolean mWipeData;
74 private Boolean mNewAccountManaged;
74 75
75 /** 76 /**
76 * Run this state machine, displaying the appropriate dialogs. 77 * Run this state machine, displaying the appropriate dialogs.
77 * @param callback One of the two functions of the {@link ConfirmImportSyncD ataDialog.Listener} 78 * @param callback One of the two functions of the {@link ConfirmImportSyncD ataDialog.Listener}
78 * are guaranteed to be called. 79 * are guaranteed to be called.
79 */ 80 */
80 public static void run(String oldAccountName, String newAccountName, 81 public static void run(String oldAccountName, String newAccountName,
81 ImportSyncType importSyncType, FragmentManager fragmentManager, Cont ext context, 82 ImportSyncType importSyncType, FragmentManager fragmentManager, Cont ext context,
82 ConfirmImportSyncDataDialog.Listener callback) { 83 ConfirmImportSyncDataDialog.Listener callback) {
83 // Includes implicit not-null assertion. 84 // Includes implicit not-null assertion.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 ConfirmImportSyncDataDialog.Listener callback) { 116 ConfirmImportSyncDataDialog.Listener callback) {
116 mOldAccountName = oldAccountName; 117 mOldAccountName = oldAccountName;
117 mNewAccountName = newAccountName; 118 mNewAccountName = newAccountName;
118 mImportSyncType = importSyncType; 119 mImportSyncType = importSyncType;
119 mFragmentManager = fragmentManager; 120 mFragmentManager = fragmentManager;
120 mContext = context; 121 mContext = context;
121 mCallback = callback; 122 mCallback = callback;
122 123
123 mCurrentlyManaged = SigninManager.get(context).getManagementDomain() != null; 124 mCurrentlyManaged = SigninManager.get(context).getManagementDomain() != null;
124 125
126 mDelegate = new ConfirmSyncDataStateMachineDelegate(mContext);
127
125 // This check isn't needed right now, but can take a few seconds, so we kick it off early. 128 // This check isn't needed right now, but can take a few seconds, so we kick it off early.
gogerald1 2017/03/28 20:22:52 nit: might change this comment accordingly for the
bsazonov 2017/03/29 13:05:05 Fixed the comment. Thanks for pointing it out.
126 SigninManager.isUserManaged(mNewAccountName, mNewAccountManaged.fulfillm entCallback()); 129 requestNewAccountManagementStatus();
127 } 130 }
128 131
129 /** 132 /**
130 * This will progress the state machine, by moving the state along and then by either calling 133 * This will progress the state machine, by moving the state along and then by either calling
131 * itself directly or creating a dialog. If the dialog is dismissed or answe red negatively the 134 * itself directly or creating a dialog. If the dialog is dismissed or answe red negatively the
132 * entire flow is over, if it is answered positively one of the onConfirm fu nctions is called 135 * entire flow is over, if it is answered positively one of the onConfirm fu nctions is called
133 * and this function is called again. 136 * and this function is called again.
134 */ 137 */
135 private void progress() { 138 private void progress() {
136 switch (mState) { 139 switch (mState) {
(...skipping 18 matching lines...) Expand all
155 mOldAccountName, mNewAccountName); 158 mOldAccountName, mNewAccountName);
156 } else { 159 } else {
157 // This will call back into onConfirm(boolean wipeData) on s uccess. 160 // This will call back into onConfirm(boolean wipeData) on s uccess.
158 ConfirmImportSyncDataDialog.showNewInstance(mOldAccountName, mNewAccountName, 161 ConfirmImportSyncDataDialog.showNewInstance(mOldAccountName, mNewAccountName,
159 mImportSyncType, mFragmentManager, this); 162 mImportSyncType, mFragmentManager, this);
160 } 163 }
161 164
162 break; 165 break;
163 case BEFORE_NEW_ACCOUNT_DIALOG: 166 case BEFORE_NEW_ACCOUNT_DIALOG:
164 mState = AFTER_NEW_ACCOUNT_DIALOG; 167 mState = AFTER_NEW_ACCOUNT_DIALOG;
165 168 if (mNewAccountManaged != null) {
166 mNewAccountManaged.then(new Callback<Boolean>() { 169 // No need to show dialog if account management status is al ready known
167 @Override 170 handleNewAccountManagementStatus();
168 public void onResult(Boolean newAccountManaged) { 171 } else {
169 if (newAccountManaged) { 172 showProgressDialog();
170 // Show 'logging into managed account' dialog 173 scheduleTimeout();
171 // This will call back into onConfirm on success. 174 }
172 ConfirmManagedSyncDataDialog.showSignInToManagedAcco untDialog(
173 ConfirmSyncDataStateMachine.this,
174 mFragmentManager, mContext.getResources(),
175 SigninManager.extractDomainName(mNewAccountN ame));
176 } else {
177 progress();
178 }
179 }
180 });
181
182 break; 175 break;
183 case AFTER_NEW_ACCOUNT_DIALOG: 176 case AFTER_NEW_ACCOUNT_DIALOG:
184 mState = DONE; 177 mState = DONE;
185 mCallback.onConfirm(mWipeData); 178 mCallback.onConfirm(mWipeData);
186 break; 179 break;
187 case DONE: 180 case DONE:
188 throw new IllegalStateException("Can't progress from DONE state! "); 181 throw new IllegalStateException("Can't progress from DONE state! ");
189 } 182 }
190 } 183 }
191 184
185 private void requestNewAccountManagementStatus() {
186 SigninManager.isUserManaged(mNewAccountName, new Callback<Boolean>() {
187 @Override
188 public void onResult(Boolean result) {
189 setIsNewAccountManaged(result);
190 }
191 });
192 }
193
194 private void setIsNewAccountManaged(Boolean isManaged) {
195 assert isManaged != null;
196 mNewAccountManaged = isManaged;
197 if (mState == AFTER_NEW_ACCOUNT_DIALOG) {
198 handleNewAccountManagementStatus();
199 }
200 }
201
202 private void handleNewAccountManagementStatus() {
203 assert mNewAccountManaged != null;
204 assert mState == AFTER_NEW_ACCOUNT_DIALOG;
205
206 mDelegate.dismissFetchManagementPolicyProgressDialog();
207 mDelegate.dismissFetchManagementPolicyTimeoutDialog();
208
209 if (mNewAccountManaged) {
210 // Show 'logging into managed account' dialog
211 // This will call back into onConfirm on success.
212 ConfirmManagedSyncDataDialog.showSignInToManagedAccountDialog(
213 ConfirmSyncDataStateMachine.this, mFragmentManager, mContext .getResources(),
214 SigninManager.extractDomainName(mNewAccountName));
215 } else {
216 progress();
217 }
218 }
219
220 private void showProgressDialog() {
221 mDelegate.showFetchManagementPolicyProgressDialog(
222 new ConfirmSyncDataStateMachineDelegate.ProgressDialogListener() {
223 @Override
224 public void onCancel() {
225 ConfirmSyncDataStateMachine.this.onCancel();
226 }
227 });
228 }
229
230 private void scheduleTimeout() {
231 ThreadUtils.postOnUiThreadDelayed(new Runnable() {
232 @Override
233 public void run() {
234 checkTimeout();
235 }
236 }, ACCOUNT_CHECK_TIMEOUT_MS);
237 }
238
239 private void checkTimeout() {
240 if (mState != AFTER_NEW_ACCOUNT_DIALOG || mNewAccountManaged != null) {
241 return;
242 }
243
244 mDelegate.showFetchManagementPolicyTimeoutDialog(
245 new ConfirmSyncDataStateMachineDelegate.TimeoutDialogListener() {
246 @Override
247 public void onCancel() {
248 ConfirmSyncDataStateMachine.this.onCancel();
249 }
250
251 @Override
252 public void onRetry() {
253 requestNewAccountManagementStatus();
254 scheduleTimeout();
255 }
256 });
257 }
258
192 // ConfirmImportSyncDataDialog.Listener implementation. 259 // ConfirmImportSyncDataDialog.Listener implementation.
193 @Override 260 @Override
194 public void onConfirm(boolean wipeData) { 261 public void onConfirm(boolean wipeData) {
195 mWipeData = wipeData; 262 mWipeData = wipeData;
196 progress(); 263 progress();
197 } 264 }
198 265
199 // ConfirmManagedSyncDataDialog.Listener implementation. 266 // ConfirmManagedSyncDataDialog.Listener implementation.
200 @Override 267 @Override
201 public void onConfirm() { 268 public void onConfirm() {
202 progress(); 269 progress();
203 } 270 }
204 271
205 // ConfirmImportSyncDataDialog.Listener & ConfirmManagedSyncDataDialog.Liste ner implementation. 272 // ConfirmImportSyncDataDialog.Listener & ConfirmManagedSyncDataDialog.Liste ner implementation.
206 @Override 273 @Override
207 public void onCancel() { 274 public void onCancel() {
208 mState = DONE; 275 mState = DONE;
209 mCallback.onCancel(); 276 mCallback.onCancel();
277 mDelegate.dismissFetchManagementPolicyProgressDialog();
278 mDelegate.dismissFetchManagementPolicyTimeoutDialog();
210 } 279 }
211 } 280 }
212 281
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698