When Remove Account is disallowed, show dialog
When DISALLOW_MODIFY_ACCOUNT is set by a device admin, and the user wants to remove an account, show the support dialog instead of showing the confirm dialog. To use the O-API DPM.createAdminSupportIntent(), a wrapper needs to be used, because existing Robolectric tests otherwise don't compile. Bug: 37413849 Test: make RunSettingsRoboTests -j40 ROBOTEST_FILTER=*RemoveAccountPreferenceControllerTest Change-Id: If23ea304ab8b9df1748e6acf3032310843b04780
This commit is contained in:
@@ -21,6 +21,7 @@ import android.accounts.AccountManagerCallback;
|
|||||||
import android.accounts.AccountManagerFuture;
|
import android.accounts.AccountManagerFuture;
|
||||||
import android.accounts.AuthenticatorException;
|
import android.accounts.AuthenticatorException;
|
||||||
import android.accounts.OperationCanceledException;
|
import android.accounts.OperationCanceledException;
|
||||||
|
import android.app.admin.DevicePolicyManager;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
@@ -30,16 +31,20 @@ import android.content.DialogInterface;
|
|||||||
import android.content.Intent;
|
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.support.v7.preference.PreferenceScreen;
|
import android.support.v7.preference.PreferenceScreen;
|
||||||
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;
|
||||||
|
|
||||||
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.internal.logging.nano.MetricsProto;
|
import com.android.internal.logging.nano.MetricsProto;
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.applications.LayoutPreference;
|
import com.android.settings.applications.LayoutPreference;
|
||||||
import com.android.settings.core.PreferenceControllerMixin;
|
import com.android.settings.core.PreferenceControllerMixin;
|
||||||
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||||
|
import com.android.settings.enterprise.DevicePolicyManagerWrapper;
|
||||||
|
import com.android.settings.enterprise.DevicePolicyManagerWrapperImpl;
|
||||||
import com.android.settingslib.core.AbstractPreferenceController;
|
import com.android.settingslib.core.AbstractPreferenceController;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -52,10 +57,19 @@ public class RemoveAccountPreferenceController extends AbstractPreferenceControl
|
|||||||
private Account mAccount;
|
private Account mAccount;
|
||||||
private Fragment mParentFragment;
|
private Fragment mParentFragment;
|
||||||
private UserHandle mUserHandle;
|
private UserHandle mUserHandle;
|
||||||
|
private DevicePolicyManagerWrapper mDpm;
|
||||||
|
|
||||||
public RemoveAccountPreferenceController(Context context, Fragment parent) {
|
public RemoveAccountPreferenceController(Context context, Fragment parent) {
|
||||||
|
this(context, parent, new DevicePolicyManagerWrapperImpl(
|
||||||
|
(DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
RemoveAccountPreferenceController(Context context, Fragment parent,
|
||||||
|
DevicePolicyManagerWrapper dpm) {
|
||||||
super(context);
|
super(context);
|
||||||
mParentFragment = parent;
|
mParentFragment = parent;
|
||||||
|
mDpm = dpm;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -79,6 +93,12 @@ public class RemoveAccountPreferenceController extends AbstractPreferenceControl
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
|
final Intent intent = mDpm.createAdminSupportIntent(UserManager.DISALLOW_MODIFY_ACCOUNTS);
|
||||||
|
if (intent != null) {
|
||||||
|
// DISALLOW_MODIFY_ACCOUNTS is active, show admin support dialog
|
||||||
|
mContext.startActivity(intent);
|
||||||
|
return;
|
||||||
|
}
|
||||||
ConfirmRemoveAccountDialog.show(mParentFragment, mAccount, mUserHandle);
|
ConfirmRemoveAccountDialog.show(mParentFragment, mAccount, mUserHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -18,6 +18,7 @@ package com.android.settings.enterprise;
|
|||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
|
import android.content.Intent;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
@@ -143,4 +144,11 @@ public interface DevicePolicyManagerWrapper {
|
|||||||
* @see android.app.admin.DevicePolicyManager#isUninstallInQueue
|
* @see android.app.admin.DevicePolicyManager#isUninstallInQueue
|
||||||
*/
|
*/
|
||||||
boolean isUninstallInQueue(String packageName);
|
boolean isUninstallInQueue(String packageName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls {@code DevicePolicyManager.createAdminSupportIntent()}.
|
||||||
|
*
|
||||||
|
* @see android.app.admin.DevicePolicyManager#createAdminSupportIntent
|
||||||
|
*/
|
||||||
|
Intent createAdminSupportIntent(String restriction);
|
||||||
}
|
}
|
||||||
|
@@ -19,6 +19,7 @@ package com.android.settings.enterprise;
|
|||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.app.admin.DevicePolicyManager;
|
import android.app.admin.DevicePolicyManager;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
|
import android.content.Intent;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
@@ -111,4 +112,9 @@ public class DevicePolicyManagerWrapperImpl implements DevicePolicyManagerWrappe
|
|||||||
public boolean isUninstallInQueue(String packageName) {
|
public boolean isUninstallInQueue(String packageName) {
|
||||||
return mDpm.isUninstallInQueue(packageName);
|
return mDpm.isUninstallInQueue(packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Intent createAdminSupportIntent(@NonNull String restriction) {
|
||||||
|
return mDpm.createAdminSupportIntent(restriction);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -21,6 +21,7 @@ import static org.mockito.Matchers.any;
|
|||||||
import static org.mockito.Matchers.anyInt;
|
import static org.mockito.Matchers.anyInt;
|
||||||
import static org.mockito.Matchers.eq;
|
import static org.mockito.Matchers.eq;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
@@ -33,17 +34,20 @@ import android.app.Activity;
|
|||||||
import android.app.FragmentManager;
|
import android.app.FragmentManager;
|
||||||
import android.app.FragmentTransaction;
|
import android.app.FragmentTransaction;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
|
import android.os.UserManager;
|
||||||
import android.support.v14.preference.PreferenceFragment;
|
import android.support.v14.preference.PreferenceFragment;
|
||||||
import android.support.v7.preference.PreferenceScreen;
|
import android.support.v7.preference.PreferenceScreen;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
|
||||||
import com.android.settings.TestConfig;
|
import com.android.settings.TestConfig;
|
||||||
import com.android.settings.applications.LayoutPreference;
|
import com.android.settings.applications.LayoutPreference;
|
||||||
|
import com.android.settings.enterprise.DevicePolicyManagerWrapper;
|
||||||
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
import com.android.settings.testutils.shadow.ShadowAccountManager;
|
import com.android.settings.testutils.shadow.ShadowAccountManager;
|
||||||
import com.android.settings.testutils.shadow.ShadowContentResolver;
|
import com.android.settings.testutils.shadow.ShadowContentResolver;
|
||||||
|
|
||||||
@@ -64,6 +68,8 @@ public class RemoveAccountPreferenceControllerTest {
|
|||||||
|
|
||||||
@Mock(answer = RETURNS_DEEP_STUBS)
|
@Mock(answer = RETURNS_DEEP_STUBS)
|
||||||
private AccountManager mAccountManager;
|
private AccountManager mAccountManager;
|
||||||
|
@Mock
|
||||||
|
private DevicePolicyManagerWrapper mDevicePolicyManager;
|
||||||
@Mock(answer = RETURNS_DEEP_STUBS)
|
@Mock(answer = RETURNS_DEEP_STUBS)
|
||||||
private PreferenceFragment mFragment;
|
private PreferenceFragment mFragment;
|
||||||
@Mock
|
@Mock
|
||||||
@@ -92,7 +98,8 @@ public class RemoveAccountPreferenceControllerTest {
|
|||||||
when(mAccountManager.getAuthenticatorTypesAsUser(anyInt())).thenReturn(
|
when(mAccountManager.getAuthenticatorTypesAsUser(anyInt())).thenReturn(
|
||||||
new AuthenticatorDescription[0]);
|
new AuthenticatorDescription[0]);
|
||||||
when(mAccountManager.getAccountsAsUser(anyInt())).thenReturn(new Account[0]);
|
when(mAccountManager.getAccountsAsUser(anyInt())).thenReturn(new Account[0]);
|
||||||
mController = new RemoveAccountPreferenceController(mContext, mFragment);
|
mController = new RemoveAccountPreferenceController(mContext, mFragment,
|
||||||
|
mDevicePolicyManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -116,6 +123,18 @@ public class RemoveAccountPreferenceControllerTest {
|
|||||||
eq(TAG_REMOVE_ACCOUNT_DIALOG));
|
eq(TAG_REMOVE_ACCOUNT_DIALOG));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onClick_shouldNotStartConfirmDialogWhenModifyAccountsIsDisallowed() {
|
||||||
|
when(mFragment.isAdded()).thenReturn(true);
|
||||||
|
when(mDevicePolicyManager.createAdminSupportIntent(UserManager.DISALLOW_MODIFY_ACCOUNTS))
|
||||||
|
.thenReturn(new Intent());
|
||||||
|
mController.onClick(null);
|
||||||
|
|
||||||
|
verify(mFragmentTransaction, never()).add(
|
||||||
|
any(RemoveAccountPreferenceController.ConfirmRemoveAccountDialog.class),
|
||||||
|
eq(TAG_REMOVE_ACCOUNT_DIALOG));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Config(shadows = {ShadowAccountManager.class, ShadowContentResolver.class})
|
@Config(shadows = {ShadowAccountManager.class, ShadowContentResolver.class})
|
||||||
public void confirmRemove_shouldRemoveAccount() {
|
public void confirmRemove_shouldRemoveAccount() {
|
||||||
|
Reference in New Issue
Block a user