blob: 5c6e6bb4e72b3020e153d271dad67cbcf9a0b559 [file] [log] [blame]
Doris Lingfd06d2f2016-12-29 14:41:15 -08001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.android.settings.accounts;
17
18import android.accounts.Account;
19import android.accounts.AccountManager;
Doris Lingfd06d2f2016-12-29 14:41:15 -080020import android.accounts.AuthenticatorException;
21import android.accounts.OperationCanceledException;
22import android.app.Activity;
Doris Lingfd06d2f2016-12-29 14:41:15 -080023import android.app.Dialog;
Fan Zhang31b21002019-01-16 13:49:47 -080024import android.app.settings.SettingsEnums;
Doris Lingfd06d2f2016-12-29 14:41:15 -080025import android.content.Context;
26import android.content.DialogInterface;
Tony Makef4c8392017-03-07 13:37:38 +000027import android.content.Intent;
Doris Lingfd06d2f2016-12-29 14:41:15 -080028import android.os.Bundle;
Tony Makef4c8392017-03-07 13:37:38 +000029import android.os.UserHandle;
phweiss7a34e9c2017-06-02 19:38:50 +020030import android.os.UserManager;
Fan Zhange3ecf5b2019-04-23 15:09:39 -070031import android.util.Log;
Doris Lingfd06d2f2016-12-29 14:41:15 -080032import android.view.View;
33import android.view.View.OnClickListener;
34import android.widget.Button;
35
Fan Zhang23f8d592018-08-28 15:11:40 -070036import androidx.appcompat.app.AlertDialog;
37import androidx.fragment.app.Fragment;
38import androidx.preference.PreferenceScreen;
39
Doris Lingfd06d2f2016-12-29 14:41:15 -080040import com.android.settings.R;
Tony Mantler1d583e12017-06-13 13:09:25 -070041import com.android.settings.core.PreferenceControllerMixin;
Doris Lingfd06d2f2016-12-29 14:41:15 -080042import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
yuemingw5f0f6b92018-03-12 16:38:50 +000043import com.android.settingslib.RestrictedLockUtils;
44import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
Philip P. Moltmanne3f72112018-08-28 15:01:43 -070045import com.android.settingslib.RestrictedLockUtilsInternal;
Tony Mantler1d583e12017-06-13 13:09:25 -070046import com.android.settingslib.core.AbstractPreferenceController;
tmfangdce94bb2018-11-26 18:41:01 +080047import com.android.settingslib.widget.LayoutPreference;
Doris Lingfd06d2f2016-12-29 14:41:15 -080048
49import java.io.IOException;
50
Tony Mantler1d583e12017-06-13 13:09:25 -070051public class RemoveAccountPreferenceController extends AbstractPreferenceController
52 implements PreferenceControllerMixin, OnClickListener {
Doris Lingfd06d2f2016-12-29 14:41:15 -080053
54 private static final String KEY_REMOVE_ACCOUNT = "remove_account";
55
56 private Account mAccount;
57 private Fragment mParentFragment;
Tony Makef4c8392017-03-07 13:37:38 +000058 private UserHandle mUserHandle;
Doris Lingfd06d2f2016-12-29 14:41:15 -080059
60 public RemoveAccountPreferenceController(Context context, Fragment parent) {
61 super(context);
62 mParentFragment = parent;
63 }
64
65 @Override
66 public void displayPreference(PreferenceScreen screen) {
67 super.displayPreference(screen);
Fan Zhang7db118e2019-02-14 12:25:29 -080068 final LayoutPreference removeAccountPreference = screen.findPreference(KEY_REMOVE_ACCOUNT);
Doris Lingfd06d2f2016-12-29 14:41:15 -080069 Button removeAccountButton = (Button) removeAccountPreference.findViewById(R.id.button);
70 removeAccountButton.setOnClickListener(this);
71 }
72
73 @Override
74 public boolean isAvailable() {
75 return true;
76 }
77
78 @Override
79 public String getPreferenceKey() {
80 return KEY_REMOVE_ACCOUNT;
81 }
82
83 @Override
84 public void onClick(View v) {
yuemingw5f0f6b92018-03-12 16:38:50 +000085 if (mUserHandle != null) {
Philip P. Moltmanne3f72112018-08-28 15:01:43 -070086 final EnforcedAdmin admin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
87 mContext, UserManager.DISALLOW_MODIFY_ACCOUNTS, mUserHandle.getIdentifier());
yuemingw5f0f6b92018-03-12 16:38:50 +000088 if (admin != null) {
89 RestrictedLockUtils.sendShowAdminSupportDetailsIntent(mContext, admin);
90 return;
91 }
phweiss7a34e9c2017-06-02 19:38:50 +020092 }
yuemingw5f0f6b92018-03-12 16:38:50 +000093
Tony Makef4c8392017-03-07 13:37:38 +000094 ConfirmRemoveAccountDialog.show(mParentFragment, mAccount, mUserHandle);
Doris Lingfd06d2f2016-12-29 14:41:15 -080095 }
96
Tony Makef4c8392017-03-07 13:37:38 +000097 public void init(Account account, UserHandle userHandle) {
Doris Lingfd06d2f2016-12-29 14:41:15 -080098 mAccount = account;
Tony Makef4c8392017-03-07 13:37:38 +000099 mUserHandle = userHandle;
Doris Lingfd06d2f2016-12-29 14:41:15 -0800100 }
101
102 /**
103 * Dialog to confirm with user about account removal
104 */
105 public static class ConfirmRemoveAccountDialog extends InstrumentedDialogFragment implements
106 DialogInterface.OnClickListener {
Tony Makef4c8392017-03-07 13:37:38 +0000107 private static final String KEY_ACCOUNT = "account";
Doris Lingfd06d2f2016-12-29 14:41:15 -0800108 private static final String REMOVE_ACCOUNT_DIALOG = "confirmRemoveAccount";
109 private Account mAccount;
Tony Makef4c8392017-03-07 13:37:38 +0000110 private UserHandle mUserHandle;
Doris Lingfd06d2f2016-12-29 14:41:15 -0800111
Tony Makef4c8392017-03-07 13:37:38 +0000112 public static ConfirmRemoveAccountDialog show(
113 Fragment parent, Account account, UserHandle userHandle) {
Doris Lingfd06d2f2016-12-29 14:41:15 -0800114 if (!parent.isAdded()) {
115 return null;
116 }
117 final ConfirmRemoveAccountDialog dialog = new ConfirmRemoveAccountDialog();
Tony Makef4c8392017-03-07 13:37:38 +0000118 Bundle bundle = new Bundle();
119 bundle.putParcelable(KEY_ACCOUNT, account);
120 bundle.putParcelable(Intent.EXTRA_USER, userHandle);
121 dialog.setArguments(bundle);
Doris Lingfd06d2f2016-12-29 14:41:15 -0800122 dialog.setTargetFragment(parent, 0);
123 dialog.show(parent.getFragmentManager(), REMOVE_ACCOUNT_DIALOG);
124 return dialog;
125 }
126
127 @Override
Tony Makef4c8392017-03-07 13:37:38 +0000128 public void onCreate(Bundle savedInstanceState) {
129 super.onCreate(savedInstanceState);
130 final Bundle arguments = getArguments();
131 mAccount = arguments.getParcelable(KEY_ACCOUNT);
132 mUserHandle = arguments.getParcelable(Intent.EXTRA_USER);
133 }
134
135 @Override
Doris Lingfd06d2f2016-12-29 14:41:15 -0800136 public Dialog onCreateDialog(Bundle savedInstanceState) {
137 final Context context = getActivity();
Doris Lingfd06d2f2016-12-29 14:41:15 -0800138 return new AlertDialog.Builder(context)
Fan Zhangaab36de2018-03-30 16:58:28 -0700139 .setTitle(R.string.really_remove_account_title)
140 .setMessage(R.string.really_remove_account_message)
141 .setNegativeButton(android.R.string.cancel, null)
142 .setPositiveButton(R.string.remove_account_label, this)
143 .create();
Doris Lingfd06d2f2016-12-29 14:41:15 -0800144 }
145
146 @Override
Doris Lingfd06d2f2016-12-29 14:41:15 -0800147 public int getMetricsCategory() {
Fan Zhang31b21002019-01-16 13:49:47 -0800148 return SettingsEnums.DIALOG_ACCOUNT_SYNC_REMOVE;
Doris Lingfd06d2f2016-12-29 14:41:15 -0800149 }
150
151 @Override
152 public void onClick(DialogInterface dialog, int which) {
153 Activity activity = getTargetFragment().getActivity();
154 AccountManager.get(activity).removeAccountAsUser(mAccount, activity,
Fan Zhange3ecf5b2019-04-23 15:09:39 -0700155 future -> {
156 final Activity targetActivity = getTargetFragment().getActivity();
157 if (targetActivity == null || targetActivity.isFinishing()) {
158 Log.w(TAG, "Activity is no longer alive, skipping results");
159 return;
160 }
161 boolean failed = true;
162 try {
163 if (future.getResult()
164 .getBoolean(AccountManager.KEY_BOOLEAN_RESULT)) {
165 failed = false;
Doris Lingfd06d2f2016-12-29 14:41:15 -0800166 }
Fan Zhange3ecf5b2019-04-23 15:09:39 -0700167 } catch (OperationCanceledException
168 | IOException
169 | AuthenticatorException e) {
170 // handled below
171 }
172 if (failed) {
173 RemoveAccountFailureDialog.show(getTargetFragment());
174 } else {
175 targetActivity.finish();
Doris Lingfd06d2f2016-12-29 14:41:15 -0800176 }
Tony Makef4c8392017-03-07 13:37:38 +0000177 }, null, mUserHandle);
Doris Lingfd06d2f2016-12-29 14:41:15 -0800178 }
179 }
180
181 /**
182 * Dialog to tell user about account removal failure
183 */
184 public static class RemoveAccountFailureDialog extends InstrumentedDialogFragment {
185
186 private static final String FAILED_REMOVAL_DIALOG = "removeAccountFailed";
187
188 public static void show(Fragment parent) {
189 if (!parent.isAdded()) {
190 return;
191 }
192 final RemoveAccountFailureDialog dialog = new RemoveAccountFailureDialog();
193 dialog.setTargetFragment(parent, 0);
Sunny Shaod843ee82019-05-30 11:22:39 +0800194 try {
195 dialog.show(parent.getFragmentManager(), FAILED_REMOVAL_DIALOG);
196 } catch (IllegalStateException e) {
197 Log.w(TAG, "Can't show RemoveAccountFailureDialog. " + e.getMessage());
198 }
Doris Lingfd06d2f2016-12-29 14:41:15 -0800199 }
200
201 @Override
202 public Dialog onCreateDialog(Bundle savedInstanceState) {
203 final Context context = getActivity();
204
205 return new AlertDialog.Builder(context)
Fan Zhangaab36de2018-03-30 16:58:28 -0700206 .setTitle(R.string.really_remove_account_title)
207 .setMessage(R.string.remove_account_failed)
208 .setPositiveButton(android.R.string.ok, null)
209 .create();
Doris Lingfd06d2f2016-12-29 14:41:15 -0800210 }
211
212 @Override
213 public int getMetricsCategory() {
Fan Zhang31b21002019-01-16 13:49:47 -0800214 return SettingsEnums.DIALOG_ACCOUNT_SYNC_FAILED_REMOVAL;
Doris Lingfd06d2f2016-12-29 14:41:15 -0800215 }
216
217 }
218}