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
diff --git a/src/com/android/settings/accounts/RemoveAccountPreferenceController.java b/src/com/android/settings/accounts/RemoveAccountPreferenceController.java
index 938606b..1bc30d0 100644
--- a/src/com/android/settings/accounts/RemoveAccountPreferenceController.java
+++ b/src/com/android/settings/accounts/RemoveAccountPreferenceController.java
@@ -17,8 +17,6 @@
 
 import android.accounts.Account;
 import android.accounts.AccountManager;
-import android.accounts.AccountManagerCallback;
-import android.accounts.AccountManagerFuture;
 import android.accounts.AuthenticatorException;
 import android.accounts.OperationCanceledException;
 import android.app.Activity;
@@ -30,6 +28,7 @@
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.util.Log;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.widget.Button;
@@ -153,28 +152,27 @@
         public void onClick(DialogInterface dialog, int which) {
             Activity activity = getTargetFragment().getActivity();
             AccountManager.get(activity).removeAccountAsUser(mAccount, activity,
-                    new AccountManagerCallback<Bundle>() {
-                        @Override
-                        public void run(AccountManagerFuture<Bundle> future) {
-                            boolean failed = true;
-                            try {
-                                if (future.getResult()
-                                        .getBoolean(AccountManager.KEY_BOOLEAN_RESULT)) {
-                                    failed = false;
-                                }
-                            } catch (OperationCanceledException e) {
-                                // handled below
-                            } catch (IOException e) {
-                                // handled below
-                            } catch (AuthenticatorException e) {
-                                // handled below
+                    future -> {
+                        final Activity targetActivity = getTargetFragment().getActivity();
+                        if (targetActivity == null || targetActivity.isFinishing()) {
+                            Log.w(TAG, "Activity is no longer alive, skipping results");
+                            return;
+                        }
+                        boolean failed = true;
+                        try {
+                            if (future.getResult()
+                                    .getBoolean(AccountManager.KEY_BOOLEAN_RESULT)) {
+                                failed = false;
                             }
-                            final Activity activity = getTargetFragment().getActivity();
-                            if (failed && activity != null && !activity.isFinishing()) {
-                                RemoveAccountFailureDialog.show(getTargetFragment());
-                            } else {
-                                activity.finish();
-                            }
+                        } catch (OperationCanceledException
+                                | IOException
+                                | AuthenticatorException e) {
+                            // handled below
+                        }
+                        if (failed) {
+                            RemoveAccountFailureDialog.show(getTargetFragment());
+                        } else {
+                            targetActivity.finish();
                         }
                     }, null, mUserHandle);
         }
diff --git a/tests/robotests/src/com/android/settings/accounts/RemoveAccountPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accounts/RemoveAccountPreferenceControllerTest.java
index cf4cb7c..d98d30a 100644
--- a/tests/robotests/src/com/android/settings/accounts/RemoveAccountPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accounts/RemoveAccountPreferenceControllerTest.java
@@ -144,7 +144,7 @@
     }
 
     @Test
-    public void onClick_shouldNotStartConfirmDialogWhenModifyAccountsIsDisallowed() {
+    public void onClick_modifyAccountsIsDisallowed_shouldNotStartConfirmDialog() {
         when(mFragment.isAdded()).thenReturn(true);
 
         final int userId = UserHandle.myUserId();
@@ -195,7 +195,41 @@
         Bundle resultBundle = new Bundle();
         resultBundle.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true);
         when(future.getResult()).thenReturn(resultBundle);
+
         callback.run(future);
         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();
+    }
 }