android:label="@string/header_add_an_account"
android:configChanges="orientation|keyboardHidden|screenSize">
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
- android:value="com.android.settings.accounts.ChooseAccountActivity" />
+ android:value="com.android.settings.accounts.ChooseAccountFragment" />
</activity>
<activity android:name=".CryptKeeper"
limitations under the License.
-->
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
-
-</PreferenceScreen>
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:settings="http://schemas.android.com/apk/res-auto"
+ android:key="add_account_screen"
+ android:title="@string/header_add_an_account"
+ settings:controller="com.android.settings.accounts.ChooseAccountPreferenceController" />
--- /dev/null
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.accounts;
+
+import android.content.Context;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.provider.SearchIndexableResource;
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settings.R;
+import com.android.settings.Utils;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.search.Indexable;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.search.SearchIndexable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Activity asking a user to select an account to be set up.
+ */
+@SearchIndexable
+public class ChooseAccountFragment extends DashboardFragment {
+
+ private static final String TAG = "ChooseAccountFragment";
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsEvent.ACCOUNTS_CHOOSE_ACCOUNT_ACTIVITY;
+ }
+
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+
+ final String[] authorities = getIntent().getStringArrayExtra(
+ AccountPreferenceBase.AUTHORITIES_FILTER_KEY);
+ final String[] accountTypesFilter = getIntent().getStringArrayExtra(
+ AccountPreferenceBase.ACCOUNT_TYPES_FILTER_KEY);
+ final UserManager userManager = UserManager.get(getContext());
+ final UserHandle userHandle = Utils.getSecureTargetUser(getActivity().getActivityToken(),
+ userManager, null /* arguments */, getIntent().getExtras());
+
+ use(ChooseAccountPreferenceController.class).initialize(authorities, accountTypesFilter,
+ userHandle, getActivity());
+ use(EnterpriseDisclosurePreferenceController.class).setFooterPreferenceMixin(
+ mFooterPreferenceMixin);
+ }
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.add_account_settings;
+ }
+
+ @Override
+ protected String getLogTag() {
+ return TAG;
+ }
+
+ @Override
+ protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
+ return buildControllers(context);
+ }
+
+ private static List<AbstractPreferenceController> buildControllers(Context context) {
+ final List<AbstractPreferenceController> controllers = new ArrayList<>();
+ controllers.add(new EnterpriseDisclosurePreferenceController(context));
+ return controllers;
+ }
+
+ public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+ new BaseSearchIndexProvider() {
+ @Override
+ public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
+ boolean enabled) {
+ final ArrayList<SearchIndexableResource> result = new ArrayList<>();
+
+ final SearchIndexableResource sir = new SearchIndexableResource(context);
+ sir.xmlResId = R.xml.add_account_settings;
+ result.add(sir);
+ return result;
+ }
+
+ @Override
+ public List<AbstractPreferenceController> createPreferenceControllers(
+ Context context) {
+ return buildControllers(context);
+ }
+ };
+}
/*
- * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
-import android.os.Bundle;
import android.os.UserHandle;
-import android.os.UserManager;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceGroup;
import android.util.Log;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.internal.util.CharSequences;
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.Utils;
-import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider;
-import com.android.settings.overlay.FeatureFactory;
+import com.android.settings.core.BasePreferenceController;
import com.android.settingslib.RestrictedLockUtils;
-import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
-import com.android.settingslib.widget.FooterPreference;
-import com.android.settingslib.widget.FooterPreferenceMixin;
import com.google.android.collect.Maps;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
+import java.util.Set;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
/**
- * Activity asking a user to select an account to be set up.
- *
* An extra {@link UserHandle} can be specified in the intent as {@link EXTRA_USER}, if the user for
* which the action needs to be performed is different to the one the Settings App will run in.
*/
-public class ChooseAccountActivity extends SettingsPreferenceFragment {
+public class ChooseAccountPreferenceController extends BasePreferenceController {
- private static final String TAG = "ChooseAccountActivity";
+ private static final String TAG = "ChooseAccountPrefCtrler";
- private EnterprisePrivacyFeatureProvider mFeatureProvider;
- private FooterPreference mEnterpriseDisclosurePreference = null;
+ private final List<ProviderEntry> mProviderList;
+ private final Map<String, AuthenticatorDescription> mTypeToAuthDescription;
private String[] mAuthorities;
- private PreferenceGroup mAddAccountGroup;
- private final ArrayList<ProviderEntry> mProviderList = new ArrayList<ProviderEntry>();
- public HashSet<String> mAccountTypesFilter;
+ private Set<String> mAccountTypesFilter;
private AuthenticatorDescription[] mAuthDescs;
- private HashMap<String, ArrayList<String>> mAccountTypeToAuthorities = null;
- private Map<String, AuthenticatorDescription> mTypeToAuthDescription
- = new HashMap<String, AuthenticatorDescription>();
+ private Map<String, List<String>> mAccountTypeToAuthorities;
// The UserHandle of the user we are choosing an account for
private UserHandle mUserHandle;
- private UserManager mUm;
+ private Activity mActivity;
+ private PreferenceScreen mScreen;
- private static class ProviderEntry implements Comparable<ProviderEntry> {
- private final CharSequence name;
- private final String type;
- ProviderEntry(CharSequence providerName, String accountType) {
- name = providerName;
- type = accountType;
- }
+ public ChooseAccountPreferenceController(Context context, String preferenceKey) {
+ super(context, preferenceKey);
- public int compareTo(ProviderEntry another) {
- if (name == null) {
- return -1;
- }
- if (another.name == null) {
- return +1;
+ mProviderList = new ArrayList<>();
+ mTypeToAuthDescription = new HashMap<>();
+ }
+
+ public void initialize(String[] authorities, String[] accountTypesFilter, UserHandle userHandle,
+ Activity activity) {
+ mActivity = activity;
+ mAuthorities = authorities;
+ mUserHandle = userHandle;
+
+ if (accountTypesFilter != null) {
+ mAccountTypesFilter = new HashSet<>();
+ for (String accountType : accountTypesFilter) {
+ mAccountTypesFilter.add(accountType);
}
- return CharSequences.compareToIgnoreCase(name, another.name);
}
}
@Override
- public int getMetricsCategory() {
- return MetricsEvent.ACCOUNTS_CHOOSE_ACCOUNT_ACTIVITY;
+ public int getAvailabilityStatus() {
+ return AVAILABLE;
}
@Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mScreen = screen;
+ updateAuthDescriptions();
+ }
- final Activity activity = getActivity();
- mFeatureProvider = FeatureFactory.getFactory(activity)
- .getEnterprisePrivacyFeatureProvider(activity);
+ @Override
+ public boolean handlePreferenceTreeClick(Preference preference) {
+ if (!(preference instanceof ProviderPreference)) {
+ return false;
+ }
- addPreferencesFromResource(R.xml.add_account_settings);
- mAuthorities = getIntent().getStringArrayExtra(
- AccountPreferenceBase.AUTHORITIES_FILTER_KEY);
- String[] accountTypesFilter = getIntent().getStringArrayExtra(
- AccountPreferenceBase.ACCOUNT_TYPES_FILTER_KEY);
- if (accountTypesFilter != null) {
- mAccountTypesFilter = new HashSet<String>();
- for (String accountType : accountTypesFilter) {
- mAccountTypesFilter.add(accountType);
- }
+ ProviderPreference pref = (ProviderPreference) preference;
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "Attempting to add account of type " + pref.getAccountType());
}
- mAddAccountGroup = getPreferenceScreen();
- mUm = UserManager.get(getContext());
- mUserHandle = Utils.getSecureTargetUser(getActivity().getActivityToken(), mUm,
- null /* arguments */, getIntent().getExtras());
- updateAuthDescriptions();
+ finishWithAccountType(pref.getAccountType());
+ return true;
}
/**
* and update any UI that depends on AuthenticatorDescriptions in onAuthDescriptionsUpdated().
*/
private void updateAuthDescriptions() {
- mAuthDescs = AccountManager.get(getContext()).getAuthenticatorTypesAsUser(
+ mAuthDescs = AccountManager.get(mContext).getAuthenticatorTypesAsUser(
mUserHandle.getIdentifier());
for (int i = 0; i < mAuthDescs.length; i++) {
mTypeToAuthDescription.put(mAuthDescs[i].type, mAuthDescs[i]);
private void onAuthDescriptionsUpdated() {
// Create list of providers to show on preference screen
for (int i = 0; i < mAuthDescs.length; i++) {
- String accountType = mAuthDescs[i].type;
- CharSequence providerName = getLabelForType(accountType);
+ final String accountType = mAuthDescs[i].type;
+ final CharSequence providerName = getLabelForType(accountType);
// Skip preferences for authorities not specified. If no authorities specified,
// then include them all.
- ArrayList<String> accountAuths = getAuthoritiesForAccountType(accountType);
+ final List<String> accountAuths = getAuthoritiesForAccountType(accountType);
boolean addAccountPref = true;
if (mAuthorities != null && mAuthorities.length > 0 && accountAuths != null) {
addAccountPref = false;
addAccountPref = false;
}
if (addAccountPref) {
- mProviderList.add(new ProviderEntry(providerName, accountType));
+ mProviderList.add(
+ new ProviderEntry(providerName, accountType));
} else {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "Skipped pref " + providerName + ": has no authority we need");
}
}
}
-
- final Context context = getPreferenceScreen().getContext();
+ final Context context = mScreen.getContext();
if (mProviderList.size() == 1) {
// There's only one provider that matches. If it is disabled by admin show the
// support dialog otherwise run it.
- EnforcedAdmin admin = RestrictedLockUtils.checkIfAccountManagementDisabled(
- context, mProviderList.get(0).type, mUserHandle.getIdentifier());
+ final RestrictedLockUtils.EnforcedAdmin admin =
+ RestrictedLockUtils.checkIfAccountManagementDisabled(
+ context, mProviderList.get(0).getType(), mUserHandle.getIdentifier());
if (admin != null) {
- setResult(RESULT_CANCELED, RestrictedLockUtils.getShowAdminSupportDetailsIntent(
- context, admin));
- finish();
+ mActivity.setResult(RESULT_CANCELED,
+ RestrictedLockUtils.getShowAdminSupportDetailsIntent(
+ context, admin));
+ mActivity.finish();
} else {
- finishWithAccountType(mProviderList.get(0).type);
+ finishWithAccountType(mProviderList.get(0).getType());
}
} else if (mProviderList.size() > 0) {
Collections.sort(mProviderList);
- mAddAccountGroup.removeAll();
for (ProviderEntry pref : mProviderList) {
- Drawable drawable = getDrawableForType(pref.type);
- ProviderPreference p = new ProviderPreference(getPreferenceScreen().getContext(),
- pref.type, drawable, pref.name);
+ final Drawable drawable = getDrawableForType(pref.getType());
+ final ProviderPreference p = new ProviderPreference(context,
+ pref.getType(), drawable, pref.getName());
+ p.setKey(pref.getType().toString());
p.checkAccountManagementAndSetDisabled(mUserHandle.getIdentifier());
- mAddAccountGroup.addPreference(p);
+ mScreen.addPreference(p);
}
- addEnterpriseDisclosure();
} else {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
final StringBuilder auths = new StringBuilder();
}
Log.v(TAG, "No providers found for authorities: " + auths);
}
- setResult(RESULT_CANCELED);
- finish();
+ mActivity.setResult(RESULT_CANCELED);
+ mActivity.finish();
}
}
- private void addEnterpriseDisclosure() {
- final CharSequence disclosure = mFeatureProvider.getDeviceOwnerDisclosure();
- if (disclosure == null) {
- return;
- }
- if (mEnterpriseDisclosurePreference == null) {
- mEnterpriseDisclosurePreference = mFooterPreferenceMixin.createFooterPreference();
- mEnterpriseDisclosurePreference.setSelectable(false);
- }
- mEnterpriseDisclosurePreference.setTitle(disclosure);
- mAddAccountGroup.addPreference(mEnterpriseDisclosurePreference);
- }
-
- public ArrayList<String> getAuthoritiesForAccountType(String type) {
+ private List<String> getAuthoritiesForAccountType(String type) {
if (mAccountTypeToAuthorities == null) {
mAccountTypeToAuthorities = Maps.newHashMap();
- SyncAdapterType[] syncAdapters = ContentResolver.getSyncAdapterTypesAsUser(
+ final SyncAdapterType[] syncAdapters = ContentResolver.getSyncAdapterTypesAsUser(
mUserHandle.getIdentifier());
for (int i = 0, n = syncAdapters.length; i < n; i++) {
final SyncAdapterType sa = syncAdapters[i];
- ArrayList<String> authorities = mAccountTypeToAuthorities.get(sa.accountType);
+ List<String> authorities = mAccountTypeToAuthorities.get(sa.accountType);
if (authorities == null) {
- authorities = new ArrayList<String>();
+ authorities = new ArrayList<>();
mAccountTypeToAuthorities.put(sa.accountType, authorities);
}
if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.d(TAG, "added authority " + sa.authority + " to accountType "
+ Log.v(TAG, "added authority " + sa.authority + " to accountType "
+ sa.accountType);
}
authorities.add(sa.authority);
/**
* Gets an icon associated with a particular account type. If none found, return null.
+ *
* @param accountType the type of account
* @return a drawable for the icon or a default icon returned by
* {@link PackageManager#getDefaultActivityIcon} if one cannot be found.
*/
- protected Drawable getDrawableForType(final String accountType) {
+ @VisibleForTesting
+ Drawable getDrawableForType(final String accountType) {
Drawable icon = null;
if (mTypeToAuthDescription.containsKey(accountType)) {
try {
- AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType);
- Context authContext = getActivity()
+ final AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType);
+ final Context authContext = mActivity
.createPackageContextAsUser(desc.packageName, 0, mUserHandle);
- icon = getPackageManager().getUserBadgedIcon(
+ icon = mContext.getPackageManager().getUserBadgedIcon(
authContext.getDrawable(desc.iconId), mUserHandle);
} catch (PackageManager.NameNotFoundException e) {
Log.w(TAG, "No icon name for account type " + accountType);
if (icon != null) {
return icon;
} else {
- return getPackageManager().getDefaultActivityIcon();
+ return mContext.getPackageManager().getDefaultActivityIcon();
}
}
/**
* Gets the label associated with a particular account type. If none found, return null.
+ *
* @param accountType the type of account
* @return a CharSequence for the label or null if one cannot be found.
*/
- protected CharSequence getLabelForType(final String accountType) {
+ @VisibleForTesting
+ CharSequence getLabelForType(final String accountType) {
CharSequence label = null;
if (mTypeToAuthDescription.containsKey(accountType)) {
try {
- AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType);
- Context authContext = getActivity()
+ final AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType);
+ final Context authContext = mActivity
.createPackageContextAsUser(desc.packageName, 0, mUserHandle);
label = authContext.getResources().getText(desc.labelId);
} catch (PackageManager.NameNotFoundException e) {
return label;
}
- @Override
- public boolean onPreferenceTreeClick(Preference preference) {
- if (preference instanceof ProviderPreference) {
- ProviderPreference pref = (ProviderPreference) preference;
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "Attempting to add account of type " + pref.getAccountType());
- }
- finishWithAccountType(pref.getAccountType());
- }
- return true;
- }
-
private void finishWithAccountType(String accountType) {
Intent intent = new Intent();
intent.putExtra(AddAccountSettings.EXTRA_SELECTED_ACCOUNT, accountType);
intent.putExtra(EXTRA_USER, mUserHandle);
- setResult(RESULT_OK, intent);
- finish();
+ mActivity.setResult(RESULT_OK, intent);
+ mActivity.finish();
}
}
--- /dev/null
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.accounts;
+
+import android.content.Context;
+
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.widget.FooterPreference;
+import com.android.settingslib.widget.FooterPreferenceMixin;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.PreferenceScreen;
+
+public class EnterpriseDisclosurePreferenceController extends BasePreferenceController {
+
+ private final EnterprisePrivacyFeatureProvider mFeatureProvider;
+ private FooterPreferenceMixin mFooterPreferenceMixin;
+ private PreferenceScreen mScreen;
+
+ public EnterpriseDisclosurePreferenceController(Context context) {
+ // Preference key doesn't matter as we are creating the preference in code.
+ super(context, "add_account_enterprise_disclosure_footer");
+
+ mFeatureProvider = FeatureFactory.getFactory(mContext)
+ .getEnterprisePrivacyFeatureProvider(mContext);
+ }
+
+ public void setFooterPreferenceMixin(FooterPreferenceMixin footerPreferenceMixin) {
+ mFooterPreferenceMixin = footerPreferenceMixin;
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ if (getDisclosure() == null) {
+ return DISABLED_UNSUPPORTED;
+ }
+ return AVAILABLE;
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mScreen = screen;
+ addEnterpriseDisclosure();
+ }
+
+ @VisibleForTesting
+ CharSequence getDisclosure() {
+ return mFeatureProvider.getDeviceOwnerDisclosure();
+ }
+
+ private void addEnterpriseDisclosure() {
+ final CharSequence disclosure = getDisclosure();
+ if (disclosure == null) {
+ return;
+ }
+ final FooterPreference enterpriseDisclosurePreference =
+ mFooterPreferenceMixin.createFooterPreference();
+ enterpriseDisclosurePreference.setSelectable(false);
+ enterpriseDisclosurePreference.setTitle(disclosure);
+ mScreen.addPreference(enterpriseDisclosurePreference);
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.accounts;
+
+import com.android.internal.util.CharSequences;
+
+public class ProviderEntry implements Comparable<ProviderEntry> {
+ private final CharSequence name;
+ private final String type;
+
+ ProviderEntry(CharSequence providerName, String accountType) {
+ name = providerName;
+ type = accountType;
+ }
+
+ public int compareTo(ProviderEntry another) {
+ if (name == null) {
+ return -1;
+ }
+ if (another.name == null) {
+ return +1;
+ }
+ return CharSequences.compareToIgnoreCase(name, another.name);
+ }
+
+ public CharSequence getName() {
+ return name;
+ }
+
+ public String getType() {
+ return type;
+ }
+}
\ No newline at end of file
import com.android.settings.accessibility.ToggleDaltonizerPreferenceFragment;
import com.android.settings.accounts.AccountDashboardFragment;
import com.android.settings.accounts.AccountSyncSettings;
-import com.android.settings.accounts.ChooseAccountActivity;
+import com.android.settings.accounts.ChooseAccountFragment;
import com.android.settings.accounts.ManagedProfileSettings;
import com.android.settings.applications.AppAndNotificationDashboardFragment;
import com.android.settings.applications.DefaultAppSettings;
PictureInPictureSettings.class.getName(),
PictureInPictureDetails.class.getName(),
ManagedProfileSettings.class.getName(),
- ChooseAccountActivity.class.getName(),
+ ChooseAccountFragment.class.getName(),
IccLockSettings.class.getName(),
TestingSettings.class.getName(),
WifiAPITest.class.getName(),
com.android.settings.applications.appinfo.WriteSettingsDetails
com.android.settings.applications.ProcessStatsSummary
com.android.settings.users.RestrictedProfileSettings
-com.android.settings.accounts.ChooseAccountActivity
com.android.settings.accessibility.ToggleAutoclickPreferenceFragment
com.android.settings.applications.AppLaunchSettings
com.android.settings.applications.ProcessStatsUi
--- /dev/null
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.accounts;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+
+import android.accounts.AuthenticatorDescription;
+import android.app.Activity;
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.content.SyncAdapterType;
+import android.graphics.drawable.ColorDrawable;
+import android.os.UserHandle;
+
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.ShadowAccountManager;
+import com.android.settings.testutils.shadow.ShadowContentResolver;
+import com.android.settings.testutils.shadow.ShadowRestrictedLockUtils;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceManager;
+import androidx.preference.PreferenceScreen;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(shadows = {ShadowAccountManager.class, ShadowContentResolver.class,
+ ShadowRestrictedLockUtils.class})
+public class ChooseAccountPreferenceControllerTest {
+
+ private Context mContext;
+ private ChooseAccountPreferenceController mController;
+ private Activity mActivity;
+ private PreferenceManager mPreferenceManager;
+ private PreferenceScreen mPreferenceScreen;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = RuntimeEnvironment.application;
+ mController = spy(new ChooseAccountPreferenceController(mContext, "controller_key"));
+ mActivity = Robolectric.setupActivity(Activity.class);
+ mPreferenceManager = new PreferenceManager(mContext);
+ mPreferenceScreen = mPreferenceManager.createPreferenceScreen(mContext);
+ }
+
+ @After
+ public void tearDown() {
+ ShadowContentResolver.reset();
+ ShadowAccountManager.resetAuthenticator();
+ ShadowRestrictedLockUtils.clearDisabledTypes();
+ }
+
+ @Test
+ public void getAvailabilityStatus_byDefault_shouldBeShown() {
+ assertThat(mController.getAvailabilityStatus()).isEqualTo(
+ BasePreferenceController.AVAILABLE);
+ }
+
+ @Test
+ public void handlePreferenceTreeClick_notProviderPreference_shouldReturnFalse() {
+ final Preference preference = new Preference(mContext);
+ assertThat(mController.handlePreferenceTreeClick(preference)).isFalse();
+ }
+
+ @Test
+ public void handlePreferenceTreeClick_isProviderPreference_shouldFinishFragment() {
+ final ProviderPreference providerPreference = new ProviderPreference(mContext,
+ "account_type", null /* icon */, "provider_name");
+
+ mController.initialize(null, null, null, mActivity);
+ mController.handlePreferenceTreeClick(providerPreference);
+
+ assertThat(mActivity.isFinishing()).isTrue();
+ }
+
+ @Test
+ public void updateAuthDescriptions_oneProvider_shouldNotAddPreference() {
+ final AuthenticatorDescription authDesc = new AuthenticatorDescription("com.acct1",
+ "com.android.settings",
+ R.string.header_add_an_account, 0, 0, 0, false);
+ ShadowAccountManager.addAuthenticator(authDesc);
+
+ final SyncAdapterType[] syncAdapters = {new SyncAdapterType("authority" /* authority */,
+ "com.acct1" /* accountType */, false /* userVisible */,
+ true /* supportsUploading */)};
+ ShadowContentResolver.setSyncAdapterTypes(syncAdapters);
+
+ ShadowRestrictedLockUtils.setHasSystemFeature(true);
+ ShadowRestrictedLockUtils.setDevicePolicyManager(mock(DevicePolicyManager.class));
+ ShadowRestrictedLockUtils.setDisabledTypes(new String[] {"test_type"});
+
+ doReturn("label").when(mController).getLabelForType(anyString());
+
+ mController.initialize(null, null, new UserHandle(3), mActivity);
+ mController.displayPreference(mPreferenceScreen);
+
+ assertThat(mActivity.isFinishing()).isTrue();
+ assertThat(mPreferenceScreen.getPreferenceCount()).isEqualTo(0);
+ }
+
+ @Test
+ public void updateAuthDescriptions_oneAdminDisabledProvider_shouldNotAddPreference() {
+ final AuthenticatorDescription authDesc = new AuthenticatorDescription("com.acct1",
+ "com.android.settings",
+ R.string.header_add_an_account, 0, 0, 0, false);
+ ShadowAccountManager.addAuthenticator(authDesc);
+
+ final SyncAdapterType[] syncAdapters = {new SyncAdapterType("authority" /* authority */,
+ "com.acct1" /* accountType */, false /* userVisible */,
+ true /* supportsUploading */)};
+ ShadowContentResolver.setSyncAdapterTypes(syncAdapters);
+
+ ShadowRestrictedLockUtils.setHasSystemFeature(true);
+ ShadowRestrictedLockUtils.setDevicePolicyManager(mock(DevicePolicyManager.class));
+ ShadowRestrictedLockUtils.setDisabledTypes(new String[] {"com.acct1"});
+
+ doReturn("label").when(mController).getLabelForType(anyString());
+
+ mController.initialize(null, null, new UserHandle(3), mActivity);
+ mController.displayPreference(mPreferenceScreen);
+
+ assertThat(mActivity.isFinishing()).isTrue();
+ assertThat(mPreferenceScreen.getPreferenceCount()).isEqualTo(0);
+ }
+
+ @Test
+ public void updateAuthDescriptions_noProvider_shouldNotAddPreference() {
+ final AuthenticatorDescription authDesc = new AuthenticatorDescription("com.acct1",
+ "com.android.settings",
+ R.string.header_add_an_account, 0, 0, 0, false);
+ ShadowAccountManager.addAuthenticator(authDesc);
+
+ final SyncAdapterType[] syncAdapters = {new SyncAdapterType("authority" /* authority */,
+ "com.acct1" /* accountType */, false /* userVisible */,
+ true /* supportsUploading */)};
+ ShadowContentResolver.setSyncAdapterTypes(syncAdapters);
+
+ doReturn("label").when(mController).getLabelForType(anyString());
+
+ mController.initialize(new String[] {"test_authoritiy1"}, null, new UserHandle(3),
+ mActivity);
+ mController.displayPreference(mPreferenceScreen);
+
+ assertThat(mActivity.isFinishing()).isTrue();
+ assertThat(mPreferenceScreen.getPreferenceCount()).isEqualTo(0);
+ }
+
+ @Test
+ public void
+ updateAuthDescriptions_twoProvider_shouldAddTwoPreference() {
+ final AuthenticatorDescription authDesc = new AuthenticatorDescription("com.acct1",
+ "com.android.settings",
+ R.string.header_add_an_account, 0, 0, 0, false);
+ final AuthenticatorDescription authDesc2 = new AuthenticatorDescription("com.acct2",
+ "com.android.settings",
+ R.string.header_add_an_account, 0, 0, 0, false);
+ ShadowAccountManager.addAuthenticator(authDesc);
+ ShadowAccountManager.addAuthenticator(authDesc2);
+
+ final SyncAdapterType[] syncAdapters = {new SyncAdapterType("authority" /* authority */,
+ "com.acct1" /* accountType */, false /* userVisible */,
+ true /* supportsUploading */), new SyncAdapterType("authority2" /* authority */,
+ "com.acct2" /* accountType */, false /* userVisible */,
+ true /* supportsUploading */)};
+ ShadowContentResolver.setSyncAdapterTypes(syncAdapters);
+
+ doReturn("label").when(mController).getLabelForType(anyString());
+ doReturn("label2").when(mController).getLabelForType(anyString());
+ doReturn(new ColorDrawable()).when(mController).getDrawableForType(anyString());
+ doReturn(new ColorDrawable()).when(mController).getDrawableForType(anyString());
+
+ mController.initialize(null, null, new UserHandle(3), mActivity);
+ mController.displayPreference(mPreferenceScreen);
+
+ assertThat(mPreferenceScreen.getPreferenceCount()).isEqualTo(2);
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.accounts;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import android.content.Context;
+
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.widget.FooterPreferenceMixin;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+
+import androidx.preference.PreferenceManager;
+import androidx.preference.PreferenceScreen;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class EnterpriseDisclosurePreferenceControllerTest {
+
+ private static final String TEST_DISCLOSURE = "This is a test disclosure.";
+
+ private ChooseAccountFragment mFragment;
+ private Context mContext;
+ private EnterpriseDisclosurePreferenceController mController;
+ private FooterPreferenceMixin mFooterPreferenceMixin;
+ private PreferenceManager mPreferenceManager;
+ private PreferenceScreen mPreferenceScreen;
+
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = RuntimeEnvironment.application;
+ mController = spy(new EnterpriseDisclosurePreferenceController(mContext));
+ mFragment = spy(new ChooseAccountFragment());
+ mFooterPreferenceMixin = new FooterPreferenceMixin(mFragment, mFragment.getLifecycle());
+ mPreferenceManager = new PreferenceManager(mContext);
+ mPreferenceScreen = mPreferenceManager.createPreferenceScreen(mContext);
+ }
+
+ @Test
+ public void getAvailabilityStatus_hasDisclosure_shouldBeAvailable() {
+ doReturn(TEST_DISCLOSURE).when(mController).getDisclosure();
+
+ assertThat(mController.getAvailabilityStatus()).isEqualTo(
+ BasePreferenceController.AVAILABLE);
+ }
+
+ @Test
+ public void getAvailabilityStatus_noDisclosure_shouldBeDisabled() {
+ doReturn(null).when(mController).getDisclosure();
+
+ assertThat(mController.getAvailabilityStatus()).isEqualTo(
+ BasePreferenceController.DISABLED_UNSUPPORTED);
+ }
+
+ @Test
+ public void displayPreference_hasDisclosure_shouldSetTitle() {
+ doReturn(TEST_DISCLOSURE).when(mController).getDisclosure();
+ doReturn(mPreferenceScreen).when(mFragment).getPreferenceScreen();
+ doReturn(mPreferenceManager).when(mFragment).getPreferenceManager();
+
+ mController.setFooterPreferenceMixin(mFooterPreferenceMixin);
+ mController.displayPreference(mPreferenceScreen);
+
+ assertThat(mPreferenceScreen.getPreferenceCount()).isEqualTo(1);
+ assertThat(mPreferenceScreen.getPreference(0).getTitle()).isEqualTo(TEST_DISCLOSURE);
+ }
+
+ @Test
+ public void displayPreference_noDisclosure_shouldBeInvisible() {
+ doReturn(null).when(mController).getDisclosure();
+
+ mController.displayPreference(mPreferenceScreen);
+
+ assertThat(mPreferenceScreen.getPreferenceCount()).isEqualTo(0);
+ }
+}
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
+import java.util.HashMap;
+import java.util.Map;
+
@Implements(AccountManager.class)
-public class ShadowAccountManager {
+public class ShadowAccountManager{
+
+ private static final Map<String, AuthenticatorDescription> sAuthenticators = new HashMap<>();
+
@Implementation
public AuthenticatorDescription[] getAuthenticatorTypesAsUser(int userId) {
- return null;
+ return sAuthenticators.values().toArray(new AuthenticatorDescription[sAuthenticators.size()]);
+ }
+
+ public static void addAuthenticator(AuthenticatorDescription authenticator) {
+ sAuthenticators.put(authenticator.type, authenticator);
+ }
+
+ public static void resetAuthenticator() {
+ sAuthenticators.clear();
}
}
package com.android.settings.testutils.shadow;
import android.annotation.UserIdInt;
+import android.app.admin.DevicePolicyManager;
import android.content.Context;
import com.android.internal.util.ArrayUtils;
@Implements(RestrictedLockUtils.class)
public class ShadowRestrictedLockUtils {
- private static boolean isRestricted;
- private static String[] restrictedPkgs;
- private static boolean adminSupportDetailsIntentLaunched;
- private static int keyguardDisabledFeatures;
+
+ private static boolean sIsRestricted;
+ private static boolean sAdminSupportDetailsIntentLaunched;
+ private static boolean sHasSystemFeature;
+ private static String[] sRestrictedPkgs;
+ private static DevicePolicyManager sDevicePolicyManager;
+ private static String[] sDisabledTypes;
+ private static int sKeyguardDisabledFeatures;
@Resetter
public static void reset() {
- isRestricted = false;
- restrictedPkgs = null;
- adminSupportDetailsIntentLaunched = false;
- keyguardDisabledFeatures = 0;
+ sIsRestricted = false;
+ sRestrictedPkgs = null;
+ sAdminSupportDetailsIntentLaunched = false;
+ sKeyguardDisabledFeatures = 0;
+ sDisabledTypes = new String[0];
}
@Implementation
public static EnforcedAdmin checkIfMeteredDataRestricted(Context context,
String packageName, int userId) {
- if (isRestricted) {
+ if (sIsRestricted) {
return new EnforcedAdmin();
}
- if (ArrayUtils.contains(restrictedPkgs, packageName)) {
+ if (ArrayUtils.contains(sRestrictedPkgs, packageName)) {
return new EnforcedAdmin();
}
return null;
@Implementation
public static void sendShowAdminSupportDetailsIntent(Context context, EnforcedAdmin admin) {
- adminSupportDetailsIntentLaunched = true;
+ sAdminSupportDetailsIntentLaunched = true;
+ }
+
+ @Implementation
+ public static EnforcedAdmin checkIfAccountManagementDisabled(Context context,
+ String accountType, int userId) {
+ if (accountType == null) {
+ return null;
+ }
+ if (!sHasSystemFeature || sDevicePolicyManager == null) {
+ return null;
+ }
+ boolean isAccountTypeDisabled = false;
+ if (ArrayUtils.contains(sDisabledTypes, accountType)) {
+ isAccountTypeDisabled = true;
+ }
+ if (!isAccountTypeDisabled) {
+ return null;
+ }
+ return new EnforcedAdmin();
}
@Implementation
public static EnforcedAdmin checkIfKeyguardFeaturesDisabled(Context context,
int features, final @UserIdInt int userId) {
- return (keyguardDisabledFeatures & features) == 0 ? null : new EnforcedAdmin();
+ return (sKeyguardDisabledFeatures & features) == 0 ? null : new EnforcedAdmin();
}
public static boolean hasAdminSupportDetailsIntentLaunched() {
- return adminSupportDetailsIntentLaunched;
+ return sAdminSupportDetailsIntentLaunched;
}
public static void clearAdminSupportDetailsIntentLaunch() {
- adminSupportDetailsIntentLaunched = false;
+ sAdminSupportDetailsIntentLaunched = false;
}
public static void setRestricted(boolean restricted) {
- isRestricted = restricted;
+ sIsRestricted = restricted;
}
public static void setRestrictedPkgs(String... pkgs) {
- restrictedPkgs = pkgs;
+ sRestrictedPkgs = pkgs;
+ }
+
+ public static void setHasSystemFeature(boolean hasSystemFeature) {
+ sHasSystemFeature = hasSystemFeature;
+ }
+
+ public static void setDevicePolicyManager(DevicePolicyManager dpm) {
+ sDevicePolicyManager = dpm;
+ }
+
+ public static void setDisabledTypes(String[] disabledTypes) {
+ sDisabledTypes = disabledTypes;
+ }
+
+ public static void clearDisabledTypes() {
+ sDisabledTypes = new String[0];
}
public static void setKeyguardDisabledFeatures(int features) {
- keyguardDisabledFeatures = features;
+ sKeyguardDisabledFeatures = features;
}
}