Commit 30408fc1 authored by Boris Sazonov's avatar Boris Sazonov Committed by Commit Bot

[Signin][Android] Ignore taps if fragment state has been saved

On Android, input events are delivered asynchronously. Because of that,
onClick listeners may be invoked after the fragment has been removed or
Chrome has been backgrounded. When Chrome is backgrounded, any fragment
transactions will fail to avoid state loss. This CL adds checks to bail
out early from click listeners if the parent fragment isn't resumed or
the state has already been saved. Also, calls to commit and dismiss are
replaced with commitAllowingStateLoss and dismissAllowingStateLoss.

Bug: 987884
Change-Id: I96494eaf0370934f2c502cfd5e768c6e8ec30c08
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1718951
Commit-Queue: Theresa <twellington@chromium.org>
Auto-Submit: Boris Sazonov <bsazonov@chromium.org>
Reviewed-by: default avatarTheresa <twellington@chromium.org>
Cr-Commit-Position: refs/heads/master@{#681299}
parent f5225cb3
......@@ -150,7 +150,7 @@ public class AccountPickerDialogFragment extends DialogFragment {
return;
case ViewType.NEW_ACCOUNT:
// "Add account" row is immutable.
holder.itemView.setOnClickListener(view -> getCallback().addAccount());
holder.itemView.setOnClickListener(view -> addAccount());
return;
default:
assert false : "Unexpected view type!";
......@@ -258,8 +258,14 @@ public class AccountPickerDialogFragment extends DialogFragment {
}
private void onAccountSelected(String accountName, boolean isDefaultAccount) {
if (!isResumed() || isStateSaved()) return;
getCallback().onAccountSelected(accountName, isDefaultAccount);
dismiss();
dismissAllowingStateLoss();
}
private void addAccount() {
if (!isResumed() || isStateSaved()) return;
getCallback().addAccount();
}
private void updateAccounts() {
......@@ -267,7 +273,7 @@ public class AccountPickerDialogFragment extends DialogFragment {
mAccounts = AccountManagerFacade.get().getGoogleAccountNames();
} catch (AccountManagerDelegateException ex) {
Log.e(TAG, "Can't get account list", ex);
dismiss();
dismissAllowingStateLoss();
return;
}
......
......@@ -419,6 +419,8 @@ public abstract class SigninFragmentBase
* visual appearance of these controls. Refuse button is always enabled.
*/
private boolean areControlsEnabled() {
// Ignore clicks if the fragment is being removed or the app is being backgrounded.
if (!isResumed() || isStateSaved()) return false;
return !mAccountSelectionPending && !mIsSigninInProgress && !mHasGmsError;
}
......@@ -510,7 +512,7 @@ public abstract class SigninFragmentBase
AccountPickerDialogFragment.create(mSelectedAccountName);
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.add(dialog, ACCOUNT_PICKER_DIALOG_TAG);
transaction.commit();
transaction.commitAllowingStateLoss();
}
private AccountPickerDialogFragment getAccountPickerDialogFragment() {
......@@ -548,7 +550,7 @@ public abstract class SigninFragmentBase
// Found the account name, dismiss the account picker dialog if it is shown.
AccountPickerDialogFragment accountPickerFragment = getAccountPickerDialogFragment();
if (accountPickerFragment != null) {
accountPickerFragment.dismiss();
accountPickerFragment.dismissAllowingStateLoss();
}
// Wait for the account cache to be updated and select newly-added account.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment