| /* |
| * Copyright (C) 2014 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.accounts.Account; |
| import android.accounts.AccountManager; |
| import android.app.ActivityManager; |
| import android.app.AlertDialog; |
| import android.app.Dialog; |
| import android.app.DialogFragment; |
| import android.content.BroadcastReceiver; |
| import android.content.ContentResolver; |
| import android.content.Context; |
| import android.content.DialogInterface; |
| import android.content.Intent; |
| import android.content.IntentFilter; |
| import android.content.pm.ApplicationInfo; |
| import android.content.pm.PackageManager; |
| import android.content.pm.UserInfo; |
| import android.content.res.Resources; |
| import android.graphics.drawable.Drawable; |
| import android.os.Bundle; |
| import android.os.Process; |
| import android.os.UserHandle; |
| import android.os.UserManager; |
| import android.provider.SearchIndexableResource; |
| import android.support.v7.preference.Preference; |
| import android.support.v7.preference.Preference.OnPreferenceClickListener; |
| import android.support.v7.preference.PreferenceGroup; |
| import android.support.v7.preference.PreferenceScreen; |
| import android.util.Log; |
| import android.util.SparseArray; |
| import android.view.Menu; |
| import android.view.MenuInflater; |
| import android.view.MenuItem; |
| |
| import com.android.internal.logging.nano.MetricsProto.MetricsEvent; |
| import com.android.settings.AccessiblePreferenceCategory; |
| import com.android.settings.DimmableIconPreference; |
| import com.android.settings.R; |
| import com.android.settings.SettingsActivity; |
| import com.android.settings.SettingsPreferenceFragment; |
| import com.android.settings.Utils; |
| import com.android.settings.search.BaseSearchIndexProvider; |
| import com.android.settings.search.Index; |
| import com.android.settings.search.Indexable; |
| import com.android.settings.search.SearchIndexableRaw; |
| import com.android.settings.users.UserDialogs; |
| import com.android.settingslib.RestrictedLockUtils; |
| import com.android.settingslib.accounts.AuthenticatorHelper; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collections; |
| import java.util.Comparator; |
| import java.util.List; |
| |
| import static android.content.Intent.EXTRA_USER; |
| import static android.os.UserManager.DISALLOW_MODIFY_ACCOUNTS; |
| import static android.provider.Settings.EXTRA_AUTHORITIES; |
| |
| /** |
| * Settings screen for the account types on the device. |
| * This shows all account types available for personal and work profiles. |
| * |
| * 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 AccountSettings extends SettingsPreferenceFragment |
| implements AuthenticatorHelper.OnAccountsUpdateListener, |
| OnPreferenceClickListener, Indexable { |
| public static final String TAG = "AccountSettings"; |
| |
| private static final String KEY_ACCOUNT = "account"; |
| |
| private static final String ADD_ACCOUNT_ACTION = "android.settings.ADD_ACCOUNT_SETTINGS"; |
| private static final String TAG_CONFIRM_AUTO_SYNC_CHANGE = "confirmAutoSyncChange"; |
| |
| private static final int ORDER_LAST = 1002; |
| private static final int ORDER_NEXT_TO_LAST = 1001; |
| private static final int ORDER_NEXT_TO_NEXT_TO_LAST = 1000; |
| |
| private UserManager mUm; |
| private SparseArray<ProfileData> mProfiles = new SparseArray<ProfileData>(); |
| private ManagedProfileBroadcastReceiver mManagedProfileBroadcastReceiver |
| = new ManagedProfileBroadcastReceiver(); |
| private Preference mProfileNotAvailablePreference; |
| private String[] mAuthorities; |
| private int mAuthoritiesCount = 0; |
| |
| /** |
| * Holds data related to the accounts belonging to one profile. |
| */ |
| private static class ProfileData { |
| /** |
| * The preference that displays the accounts. |
| */ |
| public PreferenceGroup preferenceGroup; |
| /** |
| * The preference that displays the add account button. |
| */ |
| public DimmableIconPreference addAccountPreference; |
| /** |
| * The preference that displays the button to remove the managed profile |
| */ |
| public Preference removeWorkProfilePreference; |
| /** |
| * The preference that displays managed profile settings. |
| */ |
| public Preference managedProfilePreference; |
| /** |
| * The {@link AuthenticatorHelper} that holds accounts data for this profile. |
| */ |
| public AuthenticatorHelper authenticatorHelper; |
| /** |
| * The {@link UserInfo} of the profile. |
| */ |
| public UserInfo userInfo; |
| } |
| |
| @Override |
| protected int getMetricsCategory() { |
| return MetricsEvent.ACCOUNT; |
| } |
| |
| @Override |
| public void onCreate(Bundle savedInstanceState) { |
| super.onCreate(savedInstanceState); |
| mUm = (UserManager) getSystemService(Context.USER_SERVICE); |
| mProfileNotAvailablePreference = new Preference(getPrefContext()); |
| mAuthorities = getActivity().getIntent().getStringArrayExtra(EXTRA_AUTHORITIES); |
| if (mAuthorities != null) { |
| mAuthoritiesCount = mAuthorities.length; |
| } |
| setHasOptionsMenu(true); |
| } |
| |
| @Override |
| public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { |
| inflater.inflate(R.menu.account_settings, menu); |
| super.onCreateOptionsMenu(menu, inflater); |
| } |
| |
| @Override |
| public void onPrepareOptionsMenu(Menu menu) { |
| final UserHandle currentProfile = Process.myUserHandle(); |
| if (mProfiles.size() == 1) { |
| menu.findItem(R.id.account_settings_menu_auto_sync) |
| .setVisible(true) |
| .setOnMenuItemClickListener(new MasterSyncStateClickListener(currentProfile)) |
| .setChecked(ContentResolver.getMasterSyncAutomaticallyAsUser( |
| currentProfile.getIdentifier())); |
| menu.findItem(R.id.account_settings_menu_auto_sync_personal).setVisible(false); |
| menu.findItem(R.id.account_settings_menu_auto_sync_work).setVisible(false); |
| } else if (mProfiles.size() > 1) { |
| // We assume there's only one managed profile, otherwise UI needs to change |
| final UserHandle managedProfile = mProfiles.valueAt(1).userInfo.getUserHandle(); |
| |
| menu.findItem(R.id.account_settings_menu_auto_sync_personal) |
| .setVisible(true) |
| .setOnMenuItemClickListener(new MasterSyncStateClickListener(currentProfile)) |
| .setChecked(ContentResolver.getMasterSyncAutomaticallyAsUser( |
| currentProfile.getIdentifier())); |
| menu.findItem(R.id.account_settings_menu_auto_sync_work) |
| .setVisible(true) |
| .setOnMenuItemClickListener(new MasterSyncStateClickListener(managedProfile)) |
| .setChecked(ContentResolver.getMasterSyncAutomaticallyAsUser( |
| managedProfile.getIdentifier())); |
| menu.findItem(R.id.account_settings_menu_auto_sync).setVisible(false); |
| } else { |
| Log.w(TAG, "Method onPrepareOptionsMenu called before mProfiles was initialized"); |
| } |
| } |
| |
| @Override |
| public void onResume() { |
| super.onResume(); |
| cleanUpPreferences(); |
| updateUi(); |
| mManagedProfileBroadcastReceiver.register(getActivity()); |
| listenToAccountUpdates(); |
| } |
| |
| @Override |
| public void onPause() { |
| super.onPause(); |
| stopListeningToAccountUpdates(); |
| mManagedProfileBroadcastReceiver.unregister(getActivity()); |
| } |
| |
| @Override |
| public void onAccountsUpdate(UserHandle userHandle) { |
| final ProfileData profileData = mProfiles.get(userHandle.getIdentifier()); |
| if (profileData != null) { |
| updateAccountTypes(profileData); |
| } else { |
| Log.w(TAG, "Missing Settings screen for: " + userHandle.getIdentifier()); |
| } |
| } |
| |
| @Override |
| public boolean onPreferenceClick(Preference preference) { |
| // Check the preference |
| final int count = mProfiles.size(); |
| for (int i = 0; i < count; i++) { |
| ProfileData profileData = mProfiles.valueAt(i); |
| if (preference == profileData.addAccountPreference) { |
| Intent intent = new Intent(ADD_ACCOUNT_ACTION); |
| intent.putExtra(EXTRA_USER, profileData.userInfo.getUserHandle()); |
| intent.putExtra(EXTRA_AUTHORITIES, mAuthorities); |
| startActivity(intent); |
| return true; |
| } |
| if (preference == profileData.removeWorkProfilePreference) { |
| final int userId = profileData.userInfo.id; |
| UserDialogs.createRemoveDialog(getActivity(), userId, |
| new DialogInterface.OnClickListener() { |
| @Override |
| public void onClick(DialogInterface dialog, int which) { |
| mUm.removeUser(userId); |
| } |
| } |
| ).show(); |
| return true; |
| } |
| if (preference == profileData.managedProfilePreference) { |
| Bundle arguments = new Bundle(); |
| arguments.putParcelable(Intent.EXTRA_USER, profileData.userInfo.getUserHandle()); |
| ((SettingsActivity) getActivity()).startPreferencePanel( |
| ManagedProfileSettings.class.getName(), arguments, |
| R.string.managed_profile_settings_title, null, null, 0); |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| void updateUi() { |
| // Load the preferences from an XML resource |
| addPreferencesFromResource(R.xml.account_settings); |
| |
| if (Utils.isManagedProfile(mUm)) { |
| // This should not happen |
| Log.e(TAG, "We should not be showing settings for a managed profile"); |
| finish(); |
| return; |
| } |
| |
| final PreferenceScreen preferenceScreen = (PreferenceScreen) findPreference(KEY_ACCOUNT); |
| if(mUm.isLinkedUser()) { |
| // Restricted user or similar |
| UserInfo userInfo = mUm.getUserInfo(UserHandle.myUserId()); |
| updateProfileUi(userInfo, false /* no category needed */, preferenceScreen); |
| } else { |
| List<UserInfo> profiles = mUm.getProfiles(UserHandle.myUserId()); |
| final int profilesCount = profiles.size(); |
| final boolean addCategory = profilesCount > 1; |
| for (int i = 0; i < profilesCount; i++) { |
| updateProfileUi(profiles.get(i), addCategory, preferenceScreen); |
| } |
| } |
| |
| // Add all preferences, starting with one for the primary profile. |
| // Note that we're relying on the ordering given by the SparseArray keys, and on the |
| // value of UserHandle.USER_OWNER being smaller than all the rest. |
| final int profilesCount = mProfiles.size(); |
| for (int i = 0; i < profilesCount; i++) { |
| ProfileData profileData = mProfiles.valueAt(i); |
| if (!profileData.preferenceGroup.equals(preferenceScreen)) { |
| preferenceScreen.addPreference(profileData.preferenceGroup); |
| } |
| updateAccountTypes(profileData); |
| } |
| } |
| |
| private void updateProfileUi(final UserInfo userInfo, boolean addCategory, |
| PreferenceScreen parent) { |
| final Context context = getActivity(); |
| final ProfileData profileData = new ProfileData(); |
| profileData.userInfo = userInfo; |
| if (addCategory) { |
| profileData.preferenceGroup = new AccessiblePreferenceCategory(getPrefContext()); |
| if (userInfo.isManagedProfile()) { |
| profileData.preferenceGroup.setLayoutResource(R.layout.work_profile_category); |
| profileData.preferenceGroup.setTitle(R.string.category_work); |
| String workGroupSummary = getWorkGroupSummary(context, userInfo); |
| profileData.preferenceGroup.setSummary(workGroupSummary); |
| ((AccessiblePreferenceCategory) profileData.preferenceGroup).setContentDescription( |
| getString(R.string.accessibility_category_work, workGroupSummary)); |
| profileData.removeWorkProfilePreference = newRemoveWorkProfilePreference(context); |
| profileData.managedProfilePreference = newManagedProfileSettings(); |
| } else { |
| profileData.preferenceGroup.setTitle(R.string.category_personal); |
| ((AccessiblePreferenceCategory) profileData.preferenceGroup).setContentDescription( |
| getString(R.string.accessibility_category_personal)); |
| } |
| parent.addPreference(profileData.preferenceGroup); |
| } else { |
| profileData.preferenceGroup = parent; |
| } |
| if (userInfo.isEnabled()) { |
| profileData.authenticatorHelper = new AuthenticatorHelper(context, |
| userInfo.getUserHandle(), this); |
| profileData.addAccountPreference = newAddAccountPreference(context); |
| if (RestrictedLockUtils.hasBaseUserRestriction(context, |
| UserManager.DISALLOW_MODIFY_ACCOUNTS, userInfo.id)) { |
| profileData.addAccountPreference.setEnabled(false); |
| } else { |
| profileData.addAccountPreference.checkRestrictionAndSetDisabled( |
| DISALLOW_MODIFY_ACCOUNTS, userInfo.id); |
| } |
| } |
| mProfiles.put(userInfo.id, profileData); |
| Index.getInstance(getActivity()).updateFromClassNameResource( |
| AccountSettings.class.getName(), true, true); |
| } |
| |
| private DimmableIconPreference newAddAccountPreference(Context context) { |
| DimmableIconPreference preference = new DimmableIconPreference(getPrefContext()); |
| preference.setTitle(R.string.add_account_label); |
| preference.setIcon(R.drawable.ic_menu_add); |
| preference.setOnPreferenceClickListener(this); |
| preference.setOrder(ORDER_NEXT_TO_NEXT_TO_LAST); |
| return preference; |
| } |
| |
| private Preference newRemoveWorkProfilePreference(Context context) { |
| Preference preference = new Preference(getPrefContext()); |
| preference.setTitle(R.string.remove_managed_profile_label); |
| preference.setIcon(R.drawable.ic_menu_delete); |
| preference.setOnPreferenceClickListener(this); |
| preference.setOrder(ORDER_LAST); |
| return preference; |
| } |
| |
| |
| private Preference newManagedProfileSettings() { |
| Preference preference = new Preference(getPrefContext()); |
| preference.setTitle(R.string.managed_profile_settings_title); |
| preference.setIcon(R.drawable.ic_settings); |
| preference.setOnPreferenceClickListener(this); |
| preference.setOrder(ORDER_NEXT_TO_LAST); |
| return preference; |
| } |
| |
| private String getWorkGroupSummary(Context context, UserInfo userInfo) { |
| PackageManager packageManager = context.getPackageManager(); |
| ApplicationInfo adminApplicationInfo = Utils.getAdminApplicationInfo(context, userInfo.id); |
| if (adminApplicationInfo == null) { |
| return null; |
| } |
| CharSequence appLabel = packageManager.getApplicationLabel(adminApplicationInfo); |
| return getString(R.string.managing_admin, appLabel); |
| } |
| |
| private void cleanUpPreferences() { |
| PreferenceScreen preferenceScreen = getPreferenceScreen(); |
| if (preferenceScreen != null) { |
| preferenceScreen.removeAll(); |
| } |
| mProfiles.clear(); |
| } |
| |
| private void listenToAccountUpdates() { |
| final int count = mProfiles.size(); |
| for (int i = 0; i < count; i++) { |
| AuthenticatorHelper authenticatorHelper = mProfiles.valueAt(i).authenticatorHelper; |
| if (authenticatorHelper != null) { |
| authenticatorHelper.listenToAccountUpdates(); |
| } |
| } |
| } |
| |
| private void stopListeningToAccountUpdates() { |
| final int count = mProfiles.size(); |
| for (int i = 0; i < count; i++) { |
| AuthenticatorHelper authenticatorHelper = mProfiles.valueAt(i).authenticatorHelper; |
| if (authenticatorHelper != null) { |
| authenticatorHelper.stopListeningToAccountUpdates(); |
| } |
| } |
| } |
| |
| private void updateAccountTypes(ProfileData profileData) { |
| profileData.preferenceGroup.removeAll(); |
| if (profileData.userInfo.isEnabled()) { |
| final ArrayList<AccountPreference> preferences = getAccountTypePreferences( |
| profileData.authenticatorHelper, profileData.userInfo.getUserHandle()); |
| final int count = preferences.size(); |
| for (int i = 0; i < count; i++) { |
| profileData.preferenceGroup.addPreference(preferences.get(i)); |
| } |
| if (profileData.addAccountPreference != null) { |
| profileData.preferenceGroup.addPreference(profileData.addAccountPreference); |
| } |
| } else { |
| // Put a label instead of the accounts list |
| mProfileNotAvailablePreference.setEnabled(false); |
| mProfileNotAvailablePreference.setIcon(R.drawable.empty_icon); |
| mProfileNotAvailablePreference.setTitle(null); |
| mProfileNotAvailablePreference.setSummary( |
| R.string.managed_profile_not_available_label); |
| profileData.preferenceGroup.addPreference(mProfileNotAvailablePreference); |
| } |
| if (profileData.removeWorkProfilePreference != null) { |
| profileData.preferenceGroup.addPreference(profileData.removeWorkProfilePreference); |
| } |
| if (profileData.managedProfilePreference != null) { |
| profileData.preferenceGroup.addPreference(profileData.managedProfilePreference); |
| } |
| } |
| |
| private ArrayList<AccountPreference> getAccountTypePreferences(AuthenticatorHelper helper, |
| UserHandle userHandle) { |
| final String[] accountTypes = helper.getEnabledAccountTypes(); |
| final ArrayList<AccountPreference> accountTypePreferences = |
| new ArrayList<AccountPreference>(accountTypes.length); |
| |
| for (int i = 0; i < accountTypes.length; i++) { |
| final String accountType = accountTypes[i]; |
| // Skip showing any account that does not have any of the requested authorities |
| if (!accountTypeHasAnyRequestedAuthorities(helper, accountType)) { |
| continue; |
| } |
| final CharSequence label = helper.getLabelForType(getActivity(), accountType); |
| if (label == null) { |
| continue; |
| } |
| final String titleResPackageName = helper.getPackageForType(accountType); |
| final int titleResId = helper.getLabelIdForType(accountType); |
| |
| final Account[] accounts = AccountManager.get(getActivity()) |
| .getAccountsByTypeAsUser(accountType, userHandle); |
| final boolean skipToAccount = accounts.length == 1 |
| && !helper.hasAccountPreferences(accountType); |
| |
| if (skipToAccount) { |
| final Bundle fragmentArguments = new Bundle(); |
| fragmentArguments.putParcelable(AccountSyncSettings.ACCOUNT_KEY, |
| accounts[0]); |
| fragmentArguments.putParcelable(EXTRA_USER, userHandle); |
| |
| accountTypePreferences.add(new AccountPreference(getPrefContext(), label, |
| titleResPackageName, titleResId, AccountSyncSettings.class.getName(), |
| fragmentArguments, |
| helper.getDrawableForType(getActivity(), accountType))); |
| } else { |
| final Bundle fragmentArguments = new Bundle(); |
| fragmentArguments.putString(ManageAccountsSettings.KEY_ACCOUNT_TYPE, accountType); |
| fragmentArguments.putString(ManageAccountsSettings.KEY_ACCOUNT_LABEL, |
| label.toString()); |
| fragmentArguments.putParcelable(EXTRA_USER, userHandle); |
| |
| accountTypePreferences.add(new AccountPreference(getPrefContext(), label, |
| titleResPackageName, titleResId, ManageAccountsSettings.class.getName(), |
| fragmentArguments, |
| helper.getDrawableForType(getActivity(), accountType))); |
| } |
| helper.preloadDrawableForType(getActivity(), accountType); |
| } |
| // Sort by label |
| Collections.sort(accountTypePreferences, new Comparator<AccountPreference>() { |
| @Override |
| public int compare(AccountPreference t1, AccountPreference t2) { |
| return t1.mTitle.toString().compareTo(t2.mTitle.toString()); |
| } |
| }); |
| return accountTypePreferences; |
| } |
| |
| private boolean accountTypeHasAnyRequestedAuthorities(AuthenticatorHelper helper, |
| String accountType) { |
| if (mAuthoritiesCount == 0) { |
| // No authorities required |
| return true; |
| } |
| final ArrayList<String> authoritiesForType = helper.getAuthoritiesForAccountType( |
| accountType); |
| if (authoritiesForType == null) { |
| Log.d(TAG, "No sync authorities for account type: " + accountType); |
| return false; |
| } |
| for (int j = 0; j < mAuthoritiesCount; j++) { |
| if (authoritiesForType.contains(mAuthorities[j])) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| private class AccountPreference extends Preference implements OnPreferenceClickListener { |
| /** |
| * Title of the tile that is shown to the user. |
| * @attr ref android.R.styleable#PreferenceHeader_title |
| */ |
| private final CharSequence mTitle; |
| |
| /** |
| * Packange name used to resolve the resources of the title shown to the user in the new |
| * fragment. |
| */ |
| private final String mTitleResPackageName; |
| |
| /** |
| * Resource id of the title shown to the user in the new fragment. |
| */ |
| private final int mTitleResId; |
| |
| /** |
| * Full class name of the fragment to display when this tile is |
| * selected. |
| * @attr ref android.R.styleable#PreferenceHeader_fragment |
| */ |
| private final String mFragment; |
| |
| /** |
| * Optional arguments to supply to the fragment when it is |
| * instantiated. |
| */ |
| private final Bundle mFragmentArguments; |
| |
| public AccountPreference(Context context, CharSequence title, String titleResPackageName, |
| int titleResId, String fragment, Bundle fragmentArguments, |
| Drawable icon) { |
| super(context); |
| mTitle = title; |
| mTitleResPackageName = titleResPackageName; |
| mTitleResId = titleResId; |
| mFragment = fragment; |
| mFragmentArguments = fragmentArguments; |
| setWidgetLayoutResource(R.layout.account_type_preference); |
| |
| setTitle(title); |
| setIcon(icon); |
| |
| setOnPreferenceClickListener(this); |
| } |
| |
| @Override |
| public boolean onPreferenceClick(Preference preference) { |
| if (mFragment != null) { |
| UserHandle user = mFragmentArguments.getParcelable(EXTRA_USER); |
| if (user != null && Utils.startQuietModeDialogIfNecessary(getContext(), mUm, |
| user.getIdentifier())) { |
| return true; |
| } else if (user != null && Utils.unlockWorkProfileIfNecessary(getContext(), |
| user.getIdentifier())) { |
| return true; |
| } |
| Utils.startWithFragment(getContext(), mFragment, mFragmentArguments, |
| null /* resultTo */, 0 /* resultRequestCode */, mTitleResPackageName, |
| mTitleResId, null /* title */); |
| return true; |
| } |
| return false; |
| } |
| } |
| |
| private class ManagedProfileBroadcastReceiver extends BroadcastReceiver { |
| private boolean listeningToManagedProfileEvents; |
| |
| @Override |
| public void onReceive(Context context, Intent intent) { |
| final String action = intent.getAction(); |
| Log.v(TAG, "Received broadcast: " + action); |
| if (action.equals(Intent.ACTION_MANAGED_PROFILE_REMOVED) |
| || action.equals(Intent.ACTION_MANAGED_PROFILE_ADDED)) { |
| // Clean old state |
| stopListeningToAccountUpdates(); |
| cleanUpPreferences(); |
| // Build new state |
| updateUi(); |
| listenToAccountUpdates(); |
| // Force the menu to update. Note that #onPrepareOptionsMenu uses data built by |
| // #updateUi so we must call this later |
| getActivity().invalidateOptionsMenu(); |
| return; |
| } |
| Log.w(TAG, "Cannot handle received broadcast: " + intent.getAction()); |
| } |
| |
| public void register(Context context) { |
| if (!listeningToManagedProfileEvents) { |
| IntentFilter intentFilter = new IntentFilter(); |
| intentFilter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED); |
| intentFilter.addAction(Intent.ACTION_MANAGED_PROFILE_ADDED); |
| context.registerReceiver(this, intentFilter); |
| listeningToManagedProfileEvents = true; |
| } |
| } |
| |
| public void unregister(Context context) { |
| if (listeningToManagedProfileEvents) { |
| context.unregisterReceiver(this); |
| listeningToManagedProfileEvents = false; |
| } |
| } |
| } |
| |
| private class MasterSyncStateClickListener implements MenuItem.OnMenuItemClickListener { |
| private final UserHandle mUserHandle; |
| |
| public MasterSyncStateClickListener(UserHandle userHandle) { |
| mUserHandle = userHandle; |
| } |
| |
| @Override |
| public boolean onMenuItemClick(MenuItem item) { |
| if (ActivityManager.isUserAMonkey()) { |
| Log.d(TAG, "ignoring monkey's attempt to flip sync state"); |
| } else { |
| ConfirmAutoSyncChangeFragment.show(AccountSettings.this, !item.isChecked(), |
| mUserHandle); |
| } |
| return true; |
| } |
| } |
| |
| /** |
| * Dialog to inform user about changing auto-sync setting |
| */ |
| public static class ConfirmAutoSyncChangeFragment extends DialogFragment { |
| private static final String SAVE_ENABLING = "enabling"; |
| private static final String SAVE_USER_HANDLE = "userHandle"; |
| private boolean mEnabling; |
| private UserHandle mUserHandle; |
| |
| public static void show(AccountSettings parent, boolean enabling, UserHandle userHandle) { |
| if (!parent.isAdded()) return; |
| |
| final ConfirmAutoSyncChangeFragment dialog = new ConfirmAutoSyncChangeFragment(); |
| dialog.mEnabling = enabling; |
| dialog.mUserHandle = userHandle; |
| dialog.setTargetFragment(parent, 0); |
| dialog.show(parent.getFragmentManager(), TAG_CONFIRM_AUTO_SYNC_CHANGE); |
| } |
| |
| @Override |
| public Dialog onCreateDialog(Bundle savedInstanceState) { |
| final Context context = getActivity(); |
| if (savedInstanceState != null) { |
| mEnabling = savedInstanceState.getBoolean(SAVE_ENABLING); |
| mUserHandle = (UserHandle) savedInstanceState.getParcelable(SAVE_USER_HANDLE); |
| } |
| |
| final AlertDialog.Builder builder = new AlertDialog.Builder(context); |
| if (!mEnabling) { |
| builder.setTitle(R.string.data_usage_auto_sync_off_dialog_title); |
| builder.setMessage(R.string.data_usage_auto_sync_off_dialog); |
| } else { |
| builder.setTitle(R.string.data_usage_auto_sync_on_dialog_title); |
| builder.setMessage(R.string.data_usage_auto_sync_on_dialog); |
| } |
| |
| builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { |
| @Override |
| public void onClick(DialogInterface dialog, int which) { |
| ContentResolver.setMasterSyncAutomaticallyAsUser(mEnabling, |
| mUserHandle.getIdentifier()); |
| } |
| }); |
| builder.setNegativeButton(android.R.string.cancel, null); |
| |
| return builder.create(); |
| } |
| |
| @Override |
| public void onSaveInstanceState(Bundle outState) { |
| super.onSaveInstanceState(outState); |
| outState.putBoolean(SAVE_ENABLING, mEnabling); |
| outState.putParcelable(SAVE_USER_HANDLE, mUserHandle); |
| } |
| } |
| |
| public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = |
| new BaseSearchIndexProvider() { |
| @Override |
| public List<SearchIndexableResource> getXmlResourcesToIndex( |
| Context context, boolean enabled) { |
| final SearchIndexableResource sir = new SearchIndexableResource(context); |
| sir.xmlResId = R.xml.account_settings; |
| return Arrays.asList(sir); |
| } |
| |
| @Override |
| public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) { |
| final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>(); |
| final Resources res = context.getResources(); |
| final String screenTitle = res.getString(R.string.account_settings_title); |
| |
| final UserManager um = UserManager.get(context); |
| List<UserInfo> profiles = um.getProfiles(UserHandle.myUserId()); |
| final int profilesCount = profiles.size(); |
| for (int i = 0; i < profilesCount; i++) { |
| UserInfo userInfo = profiles.get(i); |
| if (userInfo.isEnabled()) { |
| if (!RestrictedLockUtils.hasBaseUserRestriction(context, |
| DISALLOW_MODIFY_ACCOUNTS, userInfo.id)) { |
| SearchIndexableRaw data = new SearchIndexableRaw(context); |
| data.title = res.getString(R.string.add_account_label); |
| data.screenTitle = screenTitle; |
| result.add(data); |
| } |
| if (userInfo.isManagedProfile()) { |
| { |
| SearchIndexableRaw data = new SearchIndexableRaw(context); |
| data.title = res.getString(R.string.remove_managed_profile_label); |
| data.screenTitle = screenTitle; |
| result.add(data); |
| } |
| { |
| SearchIndexableRaw data = new SearchIndexableRaw(context); |
| data.title = res.getString(R.string.managed_profile_settings_title); |
| data.screenTitle = screenTitle; |
| result.add(data); |
| } |
| } |
| } |
| } |
| return result; |
| } |
| }; |
| } |