Fix a NPE when removing accounts.
Guard against null activity. If activity is already null, there is no need to call finish(). Fixes: 131180213 Test: robotests Change-Id: I19232ed67ddd0c3539b1827de23fdc584850b519
This commit is contained in:
@@ -17,8 +17,6 @@ package com.android.settings.accounts;
|
|||||||
|
|
||||||
import android.accounts.Account;
|
import android.accounts.Account;
|
||||||
import android.accounts.AccountManager;
|
import android.accounts.AccountManager;
|
||||||
import android.accounts.AccountManagerCallback;
|
|
||||||
import android.accounts.AccountManagerFuture;
|
|
||||||
import android.accounts.AuthenticatorException;
|
import android.accounts.AuthenticatorException;
|
||||||
import android.accounts.OperationCanceledException;
|
import android.accounts.OperationCanceledException;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
@@ -30,6 +28,7 @@ import android.content.Intent;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
import android.view.View.OnClickListener;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
@@ -153,28 +152,27 @@ public class RemoveAccountPreferenceController extends AbstractPreferenceControl
|
|||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
Activity activity = getTargetFragment().getActivity();
|
Activity activity = getTargetFragment().getActivity();
|
||||||
AccountManager.get(activity).removeAccountAsUser(mAccount, activity,
|
AccountManager.get(activity).removeAccountAsUser(mAccount, activity,
|
||||||
new AccountManagerCallback<Bundle>() {
|
future -> {
|
||||||
@Override
|
final Activity targetActivity = getTargetFragment().getActivity();
|
||||||
public void run(AccountManagerFuture<Bundle> future) {
|
if (targetActivity == null || targetActivity.isFinishing()) {
|
||||||
|
Log.w(TAG, "Activity is no longer alive, skipping results");
|
||||||
|
return;
|
||||||
|
}
|
||||||
boolean failed = true;
|
boolean failed = true;
|
||||||
try {
|
try {
|
||||||
if (future.getResult()
|
if (future.getResult()
|
||||||
.getBoolean(AccountManager.KEY_BOOLEAN_RESULT)) {
|
.getBoolean(AccountManager.KEY_BOOLEAN_RESULT)) {
|
||||||
failed = false;
|
failed = false;
|
||||||
}
|
}
|
||||||
} catch (OperationCanceledException e) {
|
} catch (OperationCanceledException
|
||||||
// handled below
|
| IOException
|
||||||
} catch (IOException e) {
|
| AuthenticatorException e) {
|
||||||
// handled below
|
|
||||||
} catch (AuthenticatorException e) {
|
|
||||||
// handled below
|
// handled below
|
||||||
}
|
}
|
||||||
final Activity activity = getTargetFragment().getActivity();
|
if (failed) {
|
||||||
if (failed && activity != null && !activity.isFinishing()) {
|
|
||||||
RemoveAccountFailureDialog.show(getTargetFragment());
|
RemoveAccountFailureDialog.show(getTargetFragment());
|
||||||
} else {
|
} else {
|
||||||
activity.finish();
|
targetActivity.finish();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}, null, mUserHandle);
|
}, null, mUserHandle);
|
||||||
}
|
}
|
||||||
|
@@ -144,7 +144,7 @@ public class RemoveAccountPreferenceControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onClick_shouldNotStartConfirmDialogWhenModifyAccountsIsDisallowed() {
|
public void onClick_modifyAccountsIsDisallowed_shouldNotStartConfirmDialog() {
|
||||||
when(mFragment.isAdded()).thenReturn(true);
|
when(mFragment.isAdded()).thenReturn(true);
|
||||||
|
|
||||||
final int userId = UserHandle.myUserId();
|
final int userId = UserHandle.myUserId();
|
||||||
@@ -195,7 +195,41 @@ public class RemoveAccountPreferenceControllerTest {
|
|||||||
Bundle resultBundle = new Bundle();
|
Bundle resultBundle = new Bundle();
|
||||||
resultBundle.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true);
|
resultBundle.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true);
|
||||||
when(future.getResult()).thenReturn(resultBundle);
|
when(future.getResult()).thenReturn(resultBundle);
|
||||||
|
|
||||||
callback.run(future);
|
callback.run(future);
|
||||||
verify(activity).finish();
|
verify(activity).finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Config(shadows = {ShadowAccountManager.class, ShadowContentResolver.class})
|
||||||
|
public void confirmRemove_activityGone_shouldSilentlyRemoveAccount()
|
||||||
|
throws AuthenticatorException, OperationCanceledException, IOException {
|
||||||
|
final Account account = new Account("Account11", "com.acct1");
|
||||||
|
final UserHandle userHandle = new UserHandle(10);
|
||||||
|
final FragmentActivity activity = mock(FragmentActivity.class);
|
||||||
|
when(mFragment.isAdded()).thenReturn(true);
|
||||||
|
when(activity.getSystemService(Context.ACCOUNT_SERVICE)).thenReturn(mAccountManager);
|
||||||
|
when(mFragment.getActivity()).thenReturn(activity).thenReturn(null);
|
||||||
|
|
||||||
|
final RemoveAccountPreferenceController.ConfirmRemoveAccountDialog dialog =
|
||||||
|
RemoveAccountPreferenceController.ConfirmRemoveAccountDialog.show(
|
||||||
|
mFragment, account, userHandle);
|
||||||
|
dialog.onCreate(new Bundle());
|
||||||
|
dialog.onClick(null, 0);
|
||||||
|
|
||||||
|
ArgumentCaptor<AccountManagerCallback<Bundle>> callbackCaptor = ArgumentCaptor.forClass(
|
||||||
|
AccountManagerCallback.class);
|
||||||
|
verify(mAccountManager).removeAccountAsUser(eq(account), nullable(Activity.class),
|
||||||
|
callbackCaptor.capture(), nullable(Handler.class), eq(userHandle));
|
||||||
|
|
||||||
|
AccountManagerCallback<Bundle> callback = callbackCaptor.getValue();
|
||||||
|
assertThat(callback).isNotNull();
|
||||||
|
AccountManagerFuture<Bundle> future = mock(AccountManagerFuture.class);
|
||||||
|
Bundle resultBundle = new Bundle();
|
||||||
|
resultBundle.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true);
|
||||||
|
when(future.getResult()).thenReturn(resultBundle);
|
||||||
|
|
||||||
|
callback.run(future);
|
||||||
|
verify(activity, never()).finish();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user