AccountSettings.java revision 39b467482d1bf256a111c757e9b7621c6f523271
1/* 2 * Copyright (C) 2014 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 */ 16 17package com.android.settings.accounts; 18 19 20import android.accounts.Account; 21import android.accounts.AccountManager; 22import android.app.ActivityManager; 23import android.app.AlertDialog; 24import android.app.Dialog; 25import android.app.DialogFragment; 26import android.content.BroadcastReceiver; 27import android.content.ContentResolver; 28import android.content.Context; 29import android.content.DialogInterface; 30import android.content.Intent; 31import android.content.IntentFilter; 32import android.content.pm.ApplicationInfo; 33import android.content.pm.PackageManager; 34import android.content.pm.UserInfo; 35import android.content.res.Resources; 36import android.graphics.drawable.Drawable; 37import android.os.Bundle; 38import android.os.Process; 39import android.os.UserHandle; 40import android.os.UserManager; 41import android.provider.SearchIndexableResource; 42import android.support.v7.preference.Preference; 43import android.support.v7.preference.Preference.OnPreferenceClickListener; 44import android.support.v7.preference.PreferenceGroup; 45import android.support.v7.preference.PreferenceScreen; 46import android.util.Log; 47import android.util.SparseArray; 48import android.view.Menu; 49import android.view.MenuInflater; 50import android.view.MenuItem; 51 52import com.android.internal.logging.MetricsLogger; 53import com.android.settings.AccessiblePreferenceCategory; 54import com.android.settings.R; 55import com.android.settings.SettingsPreferenceFragment; 56import com.android.settings.Utils; 57import com.android.settings.search.BaseSearchIndexProvider; 58import com.android.settings.search.Index; 59import com.android.settings.search.Indexable; 60import com.android.settings.search.SearchIndexableRaw; 61import com.android.settings.users.UserDialogs; 62 63import java.util.ArrayList; 64import java.util.Arrays; 65import java.util.Collections; 66import java.util.Comparator; 67import java.util.List; 68 69import static android.content.Intent.EXTRA_USER; 70import static android.os.UserManager.DISALLOW_MODIFY_ACCOUNTS; 71import static android.provider.Settings.EXTRA_AUTHORITIES; 72 73/** 74 * Settings screen for the account types on the device. 75 * This shows all account types available for personal and work profiles. 76 * 77 * An extra {@link UserHandle} can be specified in the intent as {@link EXTRA_USER}, if the user for 78 * which the action needs to be performed is different to the one the Settings App will run in. 79 */ 80public class AccountSettings extends SettingsPreferenceFragment 81 implements AuthenticatorHelper.OnAccountsUpdateListener, 82 OnPreferenceClickListener, Indexable { 83 public static final String TAG = "AccountSettings"; 84 85 private static final String KEY_ACCOUNT = "account"; 86 87 private static final String ADD_ACCOUNT_ACTION = "android.settings.ADD_ACCOUNT_SETTINGS"; 88 private static final String TAG_CONFIRM_AUTO_SYNC_CHANGE = "confirmAutoSyncChange"; 89 90 private static final int ORDER_LAST = 1001; 91 private static final int ORDER_NEXT_TO_LAST = 1000; 92 93 private UserManager mUm; 94 private SparseArray<ProfileData> mProfiles = new SparseArray<ProfileData>(); 95 private ManagedProfileBroadcastReceiver mManagedProfileBroadcastReceiver 96 = new ManagedProfileBroadcastReceiver(); 97 private Preference mProfileNotAvailablePreference; 98 private String[] mAuthorities; 99 private int mAuthoritiesCount = 0; 100 101 /** 102 * Holds data related to the accounts belonging to one profile. 103 */ 104 private static class ProfileData { 105 /** 106 * The preference that displays the accounts. 107 */ 108 public PreferenceGroup preferenceGroup; 109 /** 110 * The preference that displays the add account button. 111 */ 112 public Preference addAccountPreference; 113 /** 114 * The preference that displays the button to remove the managed profile 115 */ 116 public Preference removeWorkProfilePreference; 117 /** 118 * The {@link AuthenticatorHelper} that holds accounts data for this profile. 119 */ 120 public AuthenticatorHelper authenticatorHelper; 121 /** 122 * The {@link UserInfo} of the profile. 123 */ 124 public UserInfo userInfo; 125 } 126 127 @Override 128 protected int getMetricsCategory() { 129 return MetricsLogger.ACCOUNT; 130 } 131 132 @Override 133 public void onCreate(Bundle savedInstanceState) { 134 super.onCreate(savedInstanceState); 135 mUm = (UserManager) getSystemService(Context.USER_SERVICE); 136 mProfileNotAvailablePreference = new Preference(getPrefContext()); 137 mAuthorities = getActivity().getIntent().getStringArrayExtra(EXTRA_AUTHORITIES); 138 if (mAuthorities != null) { 139 mAuthoritiesCount = mAuthorities.length; 140 } 141 setHasOptionsMenu(true); 142 } 143 144 @Override 145 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 146 inflater.inflate(R.menu.account_settings, menu); 147 super.onCreateOptionsMenu(menu, inflater); 148 } 149 150 @Override 151 public void onPrepareOptionsMenu(Menu menu) { 152 final UserHandle currentProfile = Process.myUserHandle(); 153 if (mProfiles.size() == 1) { 154 menu.findItem(R.id.account_settings_menu_auto_sync) 155 .setVisible(true) 156 .setOnMenuItemClickListener(new MasterSyncStateClickListener(currentProfile)) 157 .setChecked(ContentResolver.getMasterSyncAutomaticallyAsUser( 158 currentProfile.getIdentifier())); 159 menu.findItem(R.id.account_settings_menu_auto_sync_personal).setVisible(false); 160 menu.findItem(R.id.account_settings_menu_auto_sync_work).setVisible(false); 161 } else if (mProfiles.size() > 1) { 162 // We assume there's only one managed profile, otherwise UI needs to change 163 final UserHandle managedProfile = mProfiles.valueAt(1).userInfo.getUserHandle(); 164 165 menu.findItem(R.id.account_settings_menu_auto_sync_personal) 166 .setVisible(true) 167 .setOnMenuItemClickListener(new MasterSyncStateClickListener(currentProfile)) 168 .setChecked(ContentResolver.getMasterSyncAutomaticallyAsUser( 169 currentProfile.getIdentifier())); 170 menu.findItem(R.id.account_settings_menu_auto_sync_work) 171 .setVisible(true) 172 .setOnMenuItemClickListener(new MasterSyncStateClickListener(managedProfile)) 173 .setChecked(ContentResolver.getMasterSyncAutomaticallyAsUser( 174 managedProfile.getIdentifier())); 175 menu.findItem(R.id.account_settings_menu_auto_sync).setVisible(false); 176 } else { 177 Log.w(TAG, "Method onPrepareOptionsMenu called before mProfiles was initialized"); 178 } 179 } 180 181 @Override 182 public void onResume() { 183 super.onResume(); 184 updateUi(); 185 mManagedProfileBroadcastReceiver.register(getActivity()); 186 listenToAccountUpdates(); 187 } 188 189 @Override 190 public void onPause() { 191 super.onPause(); 192 stopListeningToAccountUpdates(); 193 mManagedProfileBroadcastReceiver.unregister(getActivity()); 194 cleanUpPreferences(); 195 } 196 197 @Override 198 public void onAccountsUpdate(UserHandle userHandle) { 199 final ProfileData profileData = mProfiles.get(userHandle.getIdentifier()); 200 if (profileData != null) { 201 updateAccountTypes(profileData); 202 } else { 203 Log.w(TAG, "Missing Settings screen for: " + userHandle.getIdentifier()); 204 } 205 } 206 207 @Override 208 public boolean onPreferenceClick(Preference preference) { 209 // Check the preference 210 final int count = mProfiles.size(); 211 for (int i = 0; i < count; i++) { 212 ProfileData profileData = mProfiles.valueAt(i); 213 if (preference == profileData.addAccountPreference) { 214 Intent intent = new Intent(ADD_ACCOUNT_ACTION); 215 intent.putExtra(EXTRA_USER, profileData.userInfo.getUserHandle()); 216 intent.putExtra(EXTRA_AUTHORITIES, mAuthorities); 217 startActivity(intent); 218 return true; 219 } 220 if (preference == profileData.removeWorkProfilePreference) { 221 final int userId = profileData.userInfo.id; 222 UserDialogs.createRemoveDialog(getActivity(), userId, 223 new DialogInterface.OnClickListener() { 224 @Override 225 public void onClick(DialogInterface dialog, int which) { 226 mUm.removeUser(userId); 227 } 228 } 229 ).show(); 230 return true; 231 } 232 } 233 return false; 234 } 235 236 void updateUi() { 237 // Load the preferences from an XML resource 238 addPreferencesFromResource(R.xml.account_settings); 239 240 if (Utils.isManagedProfile(mUm)) { 241 // This should not happen 242 Log.e(TAG, "We should not be showing settings for a managed profile"); 243 finish(); 244 return; 245 } 246 247 final PreferenceScreen preferenceScreen = (PreferenceScreen) findPreference(KEY_ACCOUNT); 248 if(mUm.isLinkedUser()) { 249 // Restricted user or similar 250 UserInfo userInfo = mUm.getUserInfo(UserHandle.myUserId()); 251 updateProfileUi(userInfo, false /* no category needed */, preferenceScreen); 252 } else { 253 List<UserInfo> profiles = mUm.getProfiles(UserHandle.myUserId()); 254 final int profilesCount = profiles.size(); 255 final boolean addCategory = profilesCount > 1; 256 for (int i = 0; i < profilesCount; i++) { 257 updateProfileUi(profiles.get(i), addCategory, preferenceScreen); 258 } 259 } 260 261 // Add all preferences, starting with one for the primary profile. 262 // Note that we're relying on the ordering given by the SparseArray keys, and on the 263 // value of UserHandle.USER_OWNER being smaller than all the rest. 264 final int profilesCount = mProfiles.size(); 265 for (int i = 0; i < profilesCount; i++) { 266 ProfileData profileData = mProfiles.valueAt(i); 267 if (!profileData.preferenceGroup.equals(preferenceScreen)) { 268 preferenceScreen.addPreference(profileData.preferenceGroup); 269 } 270 updateAccountTypes(profileData); 271 } 272 } 273 274 private void updateProfileUi(final UserInfo userInfo, boolean addCategory, 275 PreferenceScreen parent) { 276 final Context context = getActivity(); 277 final ProfileData profileData = new ProfileData(); 278 profileData.userInfo = userInfo; 279 if (addCategory) { 280 profileData.preferenceGroup = new AccessiblePreferenceCategory(getPrefContext()); 281 if (userInfo.isManagedProfile()) { 282 profileData.preferenceGroup.setLayoutResource(R.layout.work_profile_category); 283 profileData.preferenceGroup.setTitle(R.string.category_work); 284 String workGroupSummary = getWorkGroupSummary(context, userInfo); 285 profileData.preferenceGroup.setSummary(workGroupSummary); 286 ((AccessiblePreferenceCategory) profileData.preferenceGroup).setContentDescription( 287 getString(R.string.accessibility_category_work, workGroupSummary)); 288 profileData.removeWorkProfilePreference = newRemoveWorkProfilePreference(context); 289 } else { 290 profileData.preferenceGroup.setTitle(R.string.category_personal); 291 ((AccessiblePreferenceCategory) profileData.preferenceGroup).setContentDescription( 292 getString(R.string.accessibility_category_personal)); 293 } 294 parent.addPreference(profileData.preferenceGroup); 295 } else { 296 profileData.preferenceGroup = parent; 297 } 298 if (userInfo.isEnabled()) { 299 profileData.authenticatorHelper = new AuthenticatorHelper(context, 300 userInfo.getUserHandle(), mUm, this); 301 if (!mUm.hasUserRestriction(DISALLOW_MODIFY_ACCOUNTS, userInfo.getUserHandle())) { 302 profileData.addAccountPreference = newAddAccountPreference(context); 303 } 304 } 305 mProfiles.put(userInfo.id, profileData); 306 Index.getInstance(getActivity()).updateFromClassNameResource( 307 AccountSettings.class.getName(), true, true); 308 } 309 310 private Preference newAddAccountPreference(Context context) { 311 Preference preference = new Preference(getPrefContext()); 312 preference.setTitle(R.string.add_account_label); 313 preference.setIcon(R.drawable.ic_menu_add); 314 preference.setOnPreferenceClickListener(this); 315 preference.setOrder(ORDER_NEXT_TO_LAST); 316 return preference; 317 } 318 319 private Preference newRemoveWorkProfilePreference(Context context) { 320 Preference preference = new Preference(getPrefContext()); 321 preference.setTitle(R.string.remove_managed_profile_label); 322 preference.setIcon(R.drawable.ic_menu_delete); 323 preference.setOnPreferenceClickListener(this); 324 preference.setOrder(ORDER_LAST); 325 return preference; 326 } 327 328 private String getWorkGroupSummary(Context context, UserInfo userInfo) { 329 PackageManager packageManager = context.getPackageManager(); 330 ApplicationInfo adminApplicationInfo = Utils.getAdminApplicationInfo(context, userInfo.id); 331 if (adminApplicationInfo == null) { 332 return null; 333 } 334 CharSequence appLabel = packageManager.getApplicationLabel(adminApplicationInfo); 335 return getString(R.string.managing_admin, appLabel); 336 } 337 338 private void cleanUpPreferences() { 339 PreferenceScreen preferenceScreen = getPreferenceScreen(); 340 if (preferenceScreen != null) { 341 preferenceScreen.removeAll(); 342 } 343 mProfiles.clear(); 344 } 345 346 private void listenToAccountUpdates() { 347 final int count = mProfiles.size(); 348 for (int i = 0; i < count; i++) { 349 AuthenticatorHelper authenticatorHelper = mProfiles.valueAt(i).authenticatorHelper; 350 if (authenticatorHelper != null) { 351 authenticatorHelper.listenToAccountUpdates(); 352 } 353 } 354 } 355 356 private void stopListeningToAccountUpdates() { 357 final int count = mProfiles.size(); 358 for (int i = 0; i < count; i++) { 359 AuthenticatorHelper authenticatorHelper = mProfiles.valueAt(i).authenticatorHelper; 360 if (authenticatorHelper != null) { 361 authenticatorHelper.stopListeningToAccountUpdates(); 362 } 363 } 364 } 365 366 private void updateAccountTypes(ProfileData profileData) { 367 profileData.preferenceGroup.removeAll(); 368 if (profileData.userInfo.isEnabled()) { 369 final ArrayList<AccountPreference> preferences = getAccountTypePreferences( 370 profileData.authenticatorHelper, profileData.userInfo.getUserHandle()); 371 final int count = preferences.size(); 372 for (int i = 0; i < count; i++) { 373 profileData.preferenceGroup.addPreference(preferences.get(i)); 374 } 375 if (profileData.addAccountPreference != null) { 376 profileData.preferenceGroup.addPreference(profileData.addAccountPreference); 377 } 378 } else { 379 // Put a label instead of the accounts list 380 mProfileNotAvailablePreference.setEnabled(false); 381 mProfileNotAvailablePreference.setIcon(R.drawable.empty_icon); 382 mProfileNotAvailablePreference.setTitle(null); 383 mProfileNotAvailablePreference.setSummary( 384 R.string.managed_profile_not_available_label); 385 profileData.preferenceGroup.addPreference(mProfileNotAvailablePreference); 386 } 387 if (profileData.removeWorkProfilePreference != null) { 388 profileData.preferenceGroup.addPreference(profileData.removeWorkProfilePreference); 389 } 390 } 391 392 private ArrayList<AccountPreference> getAccountTypePreferences(AuthenticatorHelper helper, 393 UserHandle userHandle) { 394 final String[] accountTypes = helper.getEnabledAccountTypes(); 395 final ArrayList<AccountPreference> accountTypePreferences = 396 new ArrayList<AccountPreference>(accountTypes.length); 397 398 for (int i = 0; i < accountTypes.length; i++) { 399 final String accountType = accountTypes[i]; 400 // Skip showing any account that does not have any of the requested authorities 401 if (!accountTypeHasAnyRequestedAuthorities(helper, accountType)) { 402 continue; 403 } 404 final CharSequence label = helper.getLabelForType(getActivity(), accountType); 405 if (label == null) { 406 continue; 407 } 408 final String titleResPackageName = helper.getPackageForType(accountType); 409 final int titleResId = helper.getLabelIdForType(accountType); 410 411 final Account[] accounts = AccountManager.get(getActivity()) 412 .getAccountsByTypeAsUser(accountType, userHandle); 413 final boolean skipToAccount = accounts.length == 1 414 && !helper.hasAccountPreferences(accountType); 415 416 if (skipToAccount) { 417 final Bundle fragmentArguments = new Bundle(); 418 fragmentArguments.putParcelable(AccountSyncSettings.ACCOUNT_KEY, 419 accounts[0]); 420 fragmentArguments.putParcelable(EXTRA_USER, userHandle); 421 422 accountTypePreferences.add(new AccountPreference(getPrefContext(), label, 423 titleResPackageName, titleResId, AccountSyncSettings.class.getName(), 424 fragmentArguments, 425 helper.getDrawableForType(getActivity(), accountType))); 426 } else { 427 final Bundle fragmentArguments = new Bundle(); 428 fragmentArguments.putString(ManageAccountsSettings.KEY_ACCOUNT_TYPE, accountType); 429 fragmentArguments.putString(ManageAccountsSettings.KEY_ACCOUNT_LABEL, 430 label.toString()); 431 fragmentArguments.putParcelable(EXTRA_USER, userHandle); 432 433 accountTypePreferences.add(new AccountPreference(getPrefContext(), label, 434 titleResPackageName, titleResId, ManageAccountsSettings.class.getName(), 435 fragmentArguments, 436 helper.getDrawableForType(getActivity(), accountType))); 437 } 438 helper.preloadDrawableForType(getActivity(), accountType); 439 } 440 // Sort by label 441 Collections.sort(accountTypePreferences, new Comparator<AccountPreference>() { 442 @Override 443 public int compare(AccountPreference t1, AccountPreference t2) { 444 return t1.mTitle.toString().compareTo(t2.mTitle.toString()); 445 } 446 }); 447 return accountTypePreferences; 448 } 449 450 private boolean accountTypeHasAnyRequestedAuthorities(AuthenticatorHelper helper, 451 String accountType) { 452 if (mAuthoritiesCount == 0) { 453 // No authorities required 454 return true; 455 } 456 final ArrayList<String> authoritiesForType = helper.getAuthoritiesForAccountType( 457 accountType); 458 if (authoritiesForType == null) { 459 Log.d(TAG, "No sync authorities for account type: " + accountType); 460 return false; 461 } 462 for (int j = 0; j < mAuthoritiesCount; j++) { 463 if (authoritiesForType.contains(mAuthorities[j])) { 464 return true; 465 } 466 } 467 return false; 468 } 469 470 private class AccountPreference extends Preference implements OnPreferenceClickListener { 471 /** 472 * Title of the tile that is shown to the user. 473 * @attr ref android.R.styleable#PreferenceHeader_title 474 */ 475 private final CharSequence mTitle; 476 477 /** 478 * Packange name used to resolve the resources of the title shown to the user in the new 479 * fragment. 480 */ 481 private final String mTitleResPackageName; 482 483 /** 484 * Resource id of the title shown to the user in the new fragment. 485 */ 486 private final int mTitleResId; 487 488 /** 489 * Full class name of the fragment to display when this tile is 490 * selected. 491 * @attr ref android.R.styleable#PreferenceHeader_fragment 492 */ 493 private final String mFragment; 494 495 /** 496 * Optional arguments to supply to the fragment when it is 497 * instantiated. 498 */ 499 private final Bundle mFragmentArguments; 500 501 public AccountPreference(Context context, CharSequence title, String titleResPackageName, 502 int titleResId, String fragment, Bundle fragmentArguments, 503 Drawable icon) { 504 super(context); 505 mTitle = title; 506 mTitleResPackageName = titleResPackageName; 507 mTitleResId = titleResId; 508 mFragment = fragment; 509 mFragmentArguments = fragmentArguments; 510 setWidgetLayoutResource(R.layout.account_type_preference); 511 512 setTitle(title); 513 setIcon(icon); 514 515 setOnPreferenceClickListener(this); 516 } 517 518 @Override 519 public boolean onPreferenceClick(Preference preference) { 520 if (mFragment != null) { 521 Utils.startWithFragment(getContext(), mFragment, mFragmentArguments, 522 null /* resultTo */, 0 /* resultRequestCode */, mTitleResPackageName, 523 mTitleResId, null /* title */); 524 return true; 525 } 526 return false; 527 } 528 } 529 530 private class ManagedProfileBroadcastReceiver extends BroadcastReceiver { 531 private boolean listeningToManagedProfileEvents; 532 533 @Override 534 public void onReceive(Context context, Intent intent) { 535 if (intent.getAction().equals(Intent.ACTION_MANAGED_PROFILE_REMOVED) 536 || intent.getAction().equals(Intent.ACTION_MANAGED_PROFILE_ADDED)) { 537 Log.v(TAG, "Received broadcast: " + intent.getAction()); 538 // Clean old state 539 stopListeningToAccountUpdates(); 540 cleanUpPreferences(); 541 // Build new state 542 updateUi(); 543 listenToAccountUpdates(); 544 // Force the menu to update. Note that #onPrepareOptionsMenu uses data built by 545 // #updateUi so we must call this later 546 getActivity().invalidateOptionsMenu(); 547 return; 548 } 549 Log.w(TAG, "Cannot handle received broadcast: " + intent.getAction()); 550 } 551 552 public void register(Context context) { 553 if (!listeningToManagedProfileEvents) { 554 IntentFilter intentFilter = new IntentFilter(); 555 intentFilter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED); 556 intentFilter.addAction(Intent.ACTION_MANAGED_PROFILE_ADDED); 557 context.registerReceiver(this, intentFilter); 558 listeningToManagedProfileEvents = true; 559 } 560 } 561 562 public void unregister(Context context) { 563 if (listeningToManagedProfileEvents) { 564 context.unregisterReceiver(this); 565 listeningToManagedProfileEvents = false; 566 } 567 } 568 } 569 570 private class MasterSyncStateClickListener implements MenuItem.OnMenuItemClickListener { 571 private final UserHandle mUserHandle; 572 573 public MasterSyncStateClickListener(UserHandle userHandle) { 574 mUserHandle = userHandle; 575 } 576 577 @Override 578 public boolean onMenuItemClick(MenuItem item) { 579 if (ActivityManager.isUserAMonkey()) { 580 Log.d(TAG, "ignoring monkey's attempt to flip sync state"); 581 } else { 582 ConfirmAutoSyncChangeFragment.show(AccountSettings.this, !item.isChecked(), 583 mUserHandle); 584 } 585 return true; 586 } 587 } 588 589 /** 590 * Dialog to inform user about changing auto-sync setting 591 */ 592 public static class ConfirmAutoSyncChangeFragment extends DialogFragment { 593 private static final String SAVE_ENABLING = "enabling"; 594 private static final String SAVE_USER_HANDLE = "userHandle"; 595 private boolean mEnabling; 596 private UserHandle mUserHandle; 597 598 public static void show(AccountSettings parent, boolean enabling, UserHandle userHandle) { 599 if (!parent.isAdded()) return; 600 601 final ConfirmAutoSyncChangeFragment dialog = new ConfirmAutoSyncChangeFragment(); 602 dialog.mEnabling = enabling; 603 dialog.mUserHandle = userHandle; 604 dialog.setTargetFragment(parent, 0); 605 dialog.show(parent.getFragmentManager(), TAG_CONFIRM_AUTO_SYNC_CHANGE); 606 } 607 608 @Override 609 public Dialog onCreateDialog(Bundle savedInstanceState) { 610 final Context context = getActivity(); 611 if (savedInstanceState != null) { 612 mEnabling = savedInstanceState.getBoolean(SAVE_ENABLING); 613 mUserHandle = (UserHandle) savedInstanceState.getParcelable(SAVE_USER_HANDLE); 614 } 615 616 final AlertDialog.Builder builder = new AlertDialog.Builder(context); 617 if (!mEnabling) { 618 builder.setTitle(R.string.data_usage_auto_sync_off_dialog_title); 619 builder.setMessage(R.string.data_usage_auto_sync_off_dialog); 620 } else { 621 builder.setTitle(R.string.data_usage_auto_sync_on_dialog_title); 622 builder.setMessage(R.string.data_usage_auto_sync_on_dialog); 623 } 624 625 builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { 626 @Override 627 public void onClick(DialogInterface dialog, int which) { 628 ContentResolver.setMasterSyncAutomaticallyAsUser(mEnabling, 629 mUserHandle.getIdentifier()); 630 } 631 }); 632 builder.setNegativeButton(android.R.string.cancel, null); 633 634 return builder.create(); 635 } 636 637 @Override 638 public void onSaveInstanceState(Bundle outState) { 639 super.onSaveInstanceState(outState); 640 outState.putBoolean(SAVE_ENABLING, mEnabling); 641 outState.putParcelable(SAVE_USER_HANDLE, mUserHandle); 642 } 643 } 644 645 public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = 646 new BaseSearchIndexProvider() { 647 @Override 648 public List<SearchIndexableResource> getXmlResourcesToIndex( 649 Context context, boolean enabled) { 650 final SearchIndexableResource sir = new SearchIndexableResource(context); 651 sir.xmlResId = R.xml.account_settings; 652 return Arrays.asList(sir); 653 } 654 655 @Override 656 public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) { 657 final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>(); 658 final Resources res = context.getResources(); 659 final String screenTitle = res.getString(R.string.account_settings_title); 660 661 final UserManager um = UserManager.get(context); 662 List<UserInfo> profiles = um.getProfiles(UserHandle.myUserId()); 663 final int profilesCount = profiles.size(); 664 for (int i = 0; i < profilesCount; i++) { 665 UserInfo userInfo = profiles.get(i); 666 if (userInfo.isEnabled()) { 667 if (!um.hasUserRestriction( 668 DISALLOW_MODIFY_ACCOUNTS, userInfo.getUserHandle())) { 669 SearchIndexableRaw data = new SearchIndexableRaw(context); 670 data = new SearchIndexableRaw(context); 671 data.title = res.getString(R.string.add_account_label); 672 data.screenTitle = screenTitle; 673 result.add(data); 674 } 675 if (userInfo.isManagedProfile()) { 676 SearchIndexableRaw data = new SearchIndexableRaw(context); 677 data = new SearchIndexableRaw(context); 678 data.title = res.getString(R.string.remove_managed_profile_label); 679 data.screenTitle = screenTitle; 680 result.add(data); 681 } 682 } 683 } 684 return result; 685 } 686 }; 687} 688