1 /* 2 * Copyright (C) 2016 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 17 package com.android.settings.accounts; 18 19 import static android.content.Intent.EXTRA_USER; 20 import static android.os.UserManager.DISALLOW_MODIFY_ACCOUNTS; 21 import static android.os.UserManager.DISALLOW_REMOVE_MANAGED_PROFILE; 22 import static android.provider.Settings.ACTION_ADD_ACCOUNT; 23 import static android.provider.Settings.EXTRA_AUTHORITIES; 24 25 import android.accounts.Account; 26 import android.accounts.AccountManager; 27 import android.content.BroadcastReceiver; 28 import android.content.Context; 29 import android.content.Intent; 30 import android.content.IntentFilter; 31 import android.content.pm.ApplicationInfo; 32 import android.content.pm.PackageManager; 33 import android.content.pm.UserInfo; 34 import android.content.res.Resources; 35 import android.graphics.drawable.Drawable; 36 import android.os.Bundle; 37 import android.os.UserHandle; 38 import android.os.UserManager; 39 import android.text.BidiFormatter; 40 import android.util.ArrayMap; 41 import android.util.Log; 42 import android.util.SparseArray; 43 44 import androidx.annotation.VisibleForTesting; 45 import androidx.preference.Preference; 46 import androidx.preference.Preference.OnPreferenceClickListener; 47 import androidx.preference.PreferenceGroup; 48 import androidx.preference.PreferenceScreen; 49 50 import com.android.settings.AccessiblePreferenceCategory; 51 import com.android.settings.R; 52 import com.android.settings.SettingsPreferenceFragment; 53 import com.android.settings.Utils; 54 import com.android.settings.core.PreferenceControllerMixin; 55 import com.android.settings.core.SubSettingLauncher; 56 import com.android.settings.dashboard.profileselector.ProfileSelectFragment; 57 import com.android.settings.overlay.FeatureFactory; 58 import com.android.settingslib.RestrictedPreference; 59 import com.android.settingslib.accounts.AuthenticatorHelper; 60 import com.android.settingslib.core.AbstractPreferenceController; 61 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; 62 import com.android.settingslib.core.lifecycle.LifecycleObserver; 63 import com.android.settingslib.core.lifecycle.events.OnPause; 64 import com.android.settingslib.core.lifecycle.events.OnResume; 65 import com.android.settingslib.search.SearchIndexableRaw; 66 67 import java.util.ArrayList; 68 import java.util.Collections; 69 import java.util.Comparator; 70 import java.util.List; 71 72 public class AccountPreferenceController extends AbstractPreferenceController 73 implements PreferenceControllerMixin, AuthenticatorHelper.OnAccountsUpdateListener, 74 OnPreferenceClickListener, LifecycleObserver, OnPause, OnResume { 75 76 private static final String TAG = "AccountPrefController"; 77 78 private static final int ORDER_ACCOUNT_PROFILES = 101; 79 private static final int ORDER_LAST = 1002; 80 private static final int ORDER_NEXT_TO_LAST = 1001; 81 private static final int ORDER_NEXT_TO_NEXT_TO_LAST = 1000; 82 83 private static final String PREF_KEY_ADD_ACCOUNT = "add_account"; 84 private static final String PREF_KEY_REMOVE_PROFILE = "remove_profile"; 85 private static final String PREF_KEY_WORK_PROFILE_SETTING = "work_profile_setting"; 86 87 private UserManager mUm; 88 private SparseArray<ProfileData> mProfiles = new SparseArray<ProfileData>(); 89 private ManagedProfileBroadcastReceiver mManagedProfileBroadcastReceiver = 90 new ManagedProfileBroadcastReceiver(); 91 private Preference mProfileNotAvailablePreference; 92 private String[] mAuthorities; 93 private int mAuthoritiesCount = 0; 94 private SettingsPreferenceFragment mFragment; 95 private int mAccountProfileOrder = ORDER_ACCOUNT_PROFILES; 96 private AccountRestrictionHelper mHelper; 97 private MetricsFeatureProvider mMetricsFeatureProvider; 98 private @ProfileSelectFragment.ProfileType int mType; 99 100 /** 101 * Holds data related to the accounts belonging to one profile. 102 */ 103 public static class ProfileData { 104 /** 105 * The preference that displays the accounts. 106 */ 107 public PreferenceGroup preferenceGroup; 108 /** 109 * The preference that displays the add account button. 110 */ 111 public RestrictedPreference addAccountPreference; 112 /** 113 * The preference that displays the button to remove the managed profile 114 */ 115 public RestrictedPreference removeWorkProfilePreference; 116 /** 117 * The preference that displays managed profile settings. 118 */ 119 public Preference managedProfilePreference; 120 /** 121 * The {@link AuthenticatorHelper} that holds accounts data for this profile. 122 */ 123 public AuthenticatorHelper authenticatorHelper; 124 /** 125 * The {@link UserInfo} of the profile. 126 */ 127 public UserInfo userInfo; 128 /** 129 * The {@link UserInfo} of the profile. 130 */ 131 public boolean pendingRemoval; 132 /** 133 * The map from account key to account preference 134 */ 135 public ArrayMap<String, AccountTypePreference> accountPreferences = new ArrayMap<>(); 136 } 137 AccountPreferenceController(Context context, SettingsPreferenceFragment parent, String[] authorities, @ProfileSelectFragment.ProfileType int type)138 public AccountPreferenceController(Context context, SettingsPreferenceFragment parent, 139 String[] authorities, @ProfileSelectFragment.ProfileType int type) { 140 this(context, parent, authorities, new AccountRestrictionHelper(context), type); 141 } 142 143 @VisibleForTesting AccountPreferenceController(Context context, SettingsPreferenceFragment parent, String[] authorities, AccountRestrictionHelper helper, @ProfileSelectFragment.ProfileType int type)144 AccountPreferenceController(Context context, SettingsPreferenceFragment parent, 145 String[] authorities, AccountRestrictionHelper helper, 146 @ProfileSelectFragment.ProfileType int type) { 147 super(context); 148 mUm = (UserManager) context.getSystemService(Context.USER_SERVICE); 149 mAuthorities = authorities; 150 mFragment = parent; 151 if (mAuthorities != null) { 152 mAuthoritiesCount = mAuthorities.length; 153 } 154 final FeatureFactory featureFactory = FeatureFactory.getFactory(mContext); 155 mMetricsFeatureProvider = featureFactory.getMetricsFeatureProvider(); 156 mHelper = helper; 157 mType = type; 158 } 159 160 @Override isAvailable()161 public boolean isAvailable() { 162 return !mUm.isManagedProfile(); 163 } 164 165 @Override getPreferenceKey()166 public String getPreferenceKey() { 167 return null; 168 } 169 170 @Override displayPreference(PreferenceScreen screen)171 public void displayPreference(PreferenceScreen screen) { 172 super.displayPreference(screen); 173 updateUi(); 174 } 175 176 @Override updateDynamicRawDataToIndex(List<SearchIndexableRaw> rawData)177 public void updateDynamicRawDataToIndex(List<SearchIndexableRaw> rawData) { 178 if (!isAvailable()) { 179 return; 180 } 181 final Resources res = mContext.getResources(); 182 final String screenTitle = res.getString(R.string.account_settings_title); 183 184 List<UserInfo> profiles = mUm.getProfiles(UserHandle.myUserId()); 185 for (final UserInfo userInfo : profiles) { 186 if (userInfo.isEnabled() && userInfo.isManagedProfile()) { 187 if (!mHelper.hasBaseUserRestriction(DISALLOW_REMOVE_MANAGED_PROFILE, 188 UserHandle.myUserId())) { 189 final SearchIndexableRaw data = new SearchIndexableRaw(mContext); 190 data.key = PREF_KEY_REMOVE_PROFILE; 191 data.title = res.getString(R.string.remove_managed_profile_label); 192 data.screenTitle = screenTitle; 193 rawData.add(data); 194 } 195 final SearchIndexableRaw data = new SearchIndexableRaw(mContext); 196 data.key = PREF_KEY_WORK_PROFILE_SETTING; 197 data.title = res.getString(R.string.managed_profile_settings_title); 198 data.screenTitle = screenTitle; 199 rawData.add(data); 200 } 201 } 202 } 203 204 @Override onResume()205 public void onResume() { 206 updateUi(); 207 mManagedProfileBroadcastReceiver.register(mContext); 208 listenToAccountUpdates(); 209 } 210 211 @Override onPause()212 public void onPause() { 213 stopListeningToAccountUpdates(); 214 mManagedProfileBroadcastReceiver.unregister(mContext); 215 } 216 217 @Override onAccountsUpdate(UserHandle userHandle)218 public void onAccountsUpdate(UserHandle userHandle) { 219 final ProfileData profileData = mProfiles.get(userHandle.getIdentifier()); 220 if (profileData != null) { 221 updateAccountTypes(profileData); 222 } else { 223 Log.w(TAG, "Missing Settings screen for: " + userHandle.getIdentifier()); 224 } 225 } 226 227 @Override onPreferenceClick(Preference preference)228 public boolean onPreferenceClick(Preference preference) { 229 final int metricsCategory = mFragment.getMetricsCategory(); 230 // Check the preference 231 final int count = mProfiles.size(); 232 for (int i = 0; i < count; i++) { 233 ProfileData profileData = mProfiles.valueAt(i); 234 if (preference == profileData.addAccountPreference) { 235 mMetricsFeatureProvider.logClickedPreference(preference, metricsCategory); 236 Intent intent = new Intent(ACTION_ADD_ACCOUNT); 237 intent.putExtra(EXTRA_USER, profileData.userInfo.getUserHandle()); 238 intent.putExtra(EXTRA_AUTHORITIES, mAuthorities); 239 mContext.startActivity(intent); 240 return true; 241 } 242 if (preference == profileData.removeWorkProfilePreference) { 243 mMetricsFeatureProvider.logClickedPreference(preference, metricsCategory); 244 final int userId = profileData.userInfo.id; 245 RemoveUserFragment.newInstance(userId).show(mFragment.getFragmentManager(), 246 "removeUser"); 247 return true; 248 } 249 if (preference == profileData.managedProfilePreference) { 250 mMetricsFeatureProvider.logClickedPreference(preference, metricsCategory); 251 Bundle arguments = new Bundle(); 252 arguments.putParcelable(Intent.EXTRA_USER, profileData.userInfo.getUserHandle()); 253 new SubSettingLauncher(mContext) 254 .setSourceMetricsCategory(metricsCategory) 255 .setDestination(ManagedProfileSettings.class.getName()) 256 .setTitleRes(R.string.managed_profile_settings_title) 257 .setArguments(arguments) 258 .launch(); 259 260 return true; 261 } 262 } 263 return false; 264 } 265 updateUi()266 private void updateUi() { 267 if (!isAvailable()) { 268 // This should not happen 269 Log.e(TAG, "We should not be showing settings for a managed profile"); 270 return; 271 } 272 273 for (int i = 0, size = mProfiles.size(); i < size; i++) { 274 mProfiles.valueAt(i).pendingRemoval = true; 275 } 276 if (mUm.isRestrictedProfile()) { 277 // Restricted user or similar 278 UserInfo userInfo = mUm.getUserInfo(UserHandle.myUserId()); 279 updateProfileUi(userInfo); 280 } else { 281 List<UserInfo> profiles = mUm.getProfiles(UserHandle.myUserId()); 282 final int profilesCount = profiles.size(); 283 for (int i = 0; i < profilesCount; i++) { 284 if (profiles.get(i).isManagedProfile() 285 && (mType & ProfileSelectFragment.ProfileType.WORK) != 0) { 286 updateProfileUi(profiles.get(i)); 287 } else if (!profiles.get(i).isManagedProfile() 288 && (mType & ProfileSelectFragment.ProfileType.PERSONAL) != 0) { 289 updateProfileUi(profiles.get(i)); 290 } 291 } 292 } 293 cleanUpPreferences(); 294 295 // Add all preferences, starting with one for the primary profile. 296 // Note that we're relying on the ordering given by the SparseArray keys, and on the 297 // value of UserHandle.USER_OWNER being smaller than all the rest. 298 final int profilesCount = mProfiles.size(); 299 for (int i = 0; i < profilesCount; i++) { 300 updateAccountTypes(mProfiles.valueAt(i)); 301 } 302 } 303 updateProfileUi(final UserInfo userInfo)304 private void updateProfileUi(final UserInfo userInfo) { 305 if (mFragment.getPreferenceManager() == null) { 306 return; 307 } 308 final ProfileData data = mProfiles.get(userInfo.id); 309 if (data != null) { 310 data.pendingRemoval = false; 311 data.userInfo = userInfo; 312 if (userInfo.isEnabled()) { 313 // recreate the authentication helper to refresh the list of enabled accounts 314 data.authenticatorHelper = 315 new AuthenticatorHelper(mContext, userInfo.getUserHandle(), this); 316 } 317 return; 318 } 319 final Context context = mContext; 320 final ProfileData profileData = new ProfileData(); 321 profileData.userInfo = userInfo; 322 AccessiblePreferenceCategory preferenceGroup = 323 mHelper.createAccessiblePreferenceCategory( 324 mFragment.getPreferenceManager().getContext()); 325 preferenceGroup.setOrder(mAccountProfileOrder++); 326 preferenceGroup.setTitle(R.string.account_settings); // default title; may be modified below 327 if (isSingleProfile()) { 328 final String title = context.getString(R.string.account_for_section_header, 329 BidiFormatter.getInstance().unicodeWrap(userInfo.name)); 330 preferenceGroup.setTitle(title); 331 preferenceGroup.setContentDescription(title); 332 } else if (userInfo.isManagedProfile()) { 333 if (mType == ProfileSelectFragment.ProfileType.ALL) { 334 preferenceGroup.setTitle(R.string.category_work); 335 final String workGroupSummary = getWorkGroupSummary(context, userInfo); 336 preferenceGroup.setSummary(workGroupSummary); 337 preferenceGroup.setContentDescription( 338 mContext.getString(R.string.accessibility_category_work, workGroupSummary)); 339 } 340 profileData.removeWorkProfilePreference = newRemoveWorkProfilePreference(); 341 mHelper.enforceRestrictionOnPreference(profileData.removeWorkProfilePreference, 342 DISALLOW_REMOVE_MANAGED_PROFILE, UserHandle.myUserId()); 343 profileData.managedProfilePreference = newManagedProfileSettings(); 344 } else { 345 if (mType == ProfileSelectFragment.ProfileType.ALL) { 346 preferenceGroup.setTitle(R.string.category_personal); 347 preferenceGroup.setContentDescription( 348 mContext.getString(R.string.accessibility_category_personal)); 349 } 350 } 351 final PreferenceScreen screen = mFragment.getPreferenceScreen(); 352 if (screen != null) { 353 screen.addPreference(preferenceGroup); 354 } 355 profileData.preferenceGroup = preferenceGroup; 356 if (userInfo.isEnabled()) { 357 profileData.authenticatorHelper = new AuthenticatorHelper(context, 358 userInfo.getUserHandle(), this); 359 profileData.addAccountPreference = newAddAccountPreference(); 360 mHelper.enforceRestrictionOnPreference(profileData.addAccountPreference, 361 DISALLOW_MODIFY_ACCOUNTS, userInfo.id); 362 } 363 mProfiles.put(userInfo.id, profileData); 364 } 365 newAddAccountPreference()366 private RestrictedPreference newAddAccountPreference() { 367 RestrictedPreference preference = 368 new RestrictedPreference(mFragment.getPreferenceManager().getContext()); 369 preference.setKey(PREF_KEY_ADD_ACCOUNT); 370 preference.setTitle(R.string.add_account_label); 371 preference.setIcon(R.drawable.ic_add_24dp); 372 preference.setOnPreferenceClickListener(this); 373 preference.setOrder(ORDER_NEXT_TO_NEXT_TO_LAST); 374 return preference; 375 } 376 newRemoveWorkProfilePreference()377 private RestrictedPreference newRemoveWorkProfilePreference() { 378 RestrictedPreference preference = new RestrictedPreference( 379 mFragment.getPreferenceManager().getContext()); 380 preference.setKey(PREF_KEY_REMOVE_PROFILE); 381 preference.setTitle(R.string.remove_managed_profile_label); 382 preference.setIcon(R.drawable.ic_delete); 383 preference.setOnPreferenceClickListener(this); 384 preference.setOrder(ORDER_LAST); 385 return preference; 386 } 387 388 newManagedProfileSettings()389 private Preference newManagedProfileSettings() { 390 Preference preference = new Preference(mFragment.getPreferenceManager().getContext()); 391 preference.setKey(PREF_KEY_WORK_PROFILE_SETTING); 392 preference.setTitle(R.string.managed_profile_settings_title); 393 preference.setIcon(R.drawable.ic_settings_24dp); 394 preference.setOnPreferenceClickListener(this); 395 preference.setOrder(ORDER_NEXT_TO_LAST); 396 return preference; 397 } 398 getWorkGroupSummary(Context context, UserInfo userInfo)399 private String getWorkGroupSummary(Context context, UserInfo userInfo) { 400 PackageManager packageManager = context.getPackageManager(); 401 ApplicationInfo adminApplicationInfo = Utils.getAdminApplicationInfo(context, userInfo.id); 402 if (adminApplicationInfo == null) { 403 return null; 404 } 405 CharSequence appLabel = packageManager.getApplicationLabel(adminApplicationInfo); 406 return mContext.getString(R.string.managing_admin, appLabel); 407 } 408 cleanUpPreferences()409 void cleanUpPreferences() { 410 PreferenceScreen screen = mFragment.getPreferenceScreen(); 411 if (screen == null) { 412 return; 413 } 414 final int count = mProfiles.size(); 415 for (int i = count - 1; i >= 0; i--) { 416 final ProfileData data = mProfiles.valueAt(i); 417 if (data.pendingRemoval) { 418 screen.removePreference(data.preferenceGroup); 419 mProfiles.removeAt(i); 420 } 421 } 422 } 423 listenToAccountUpdates()424 private void listenToAccountUpdates() { 425 final int count = mProfiles.size(); 426 for (int i = 0; i < count; i++) { 427 AuthenticatorHelper authenticatorHelper = mProfiles.valueAt(i).authenticatorHelper; 428 if (authenticatorHelper != null) { 429 authenticatorHelper.listenToAccountUpdates(); 430 } 431 } 432 } 433 stopListeningToAccountUpdates()434 private void stopListeningToAccountUpdates() { 435 final int count = mProfiles.size(); 436 for (int i = 0; i < count; i++) { 437 AuthenticatorHelper authenticatorHelper = mProfiles.valueAt(i).authenticatorHelper; 438 if (authenticatorHelper != null) { 439 authenticatorHelper.stopListeningToAccountUpdates(); 440 } 441 } 442 } 443 updateAccountTypes(ProfileData profileData)444 private void updateAccountTypes(ProfileData profileData) { 445 if (mFragment.getPreferenceManager() == null 446 || profileData.preferenceGroup.getPreferenceManager() == null) { 447 // This could happen if activity is finishing 448 return; 449 } 450 if (profileData.userInfo.isEnabled()) { 451 final ArrayMap<String, AccountTypePreference> preferenceToRemove = 452 new ArrayMap<>(profileData.accountPreferences); 453 final ArrayList<AccountTypePreference> preferences = getAccountTypePreferences( 454 profileData.authenticatorHelper, profileData.userInfo.getUserHandle(), 455 preferenceToRemove); 456 final int count = preferences.size(); 457 for (int i = 0; i < count; i++) { 458 final AccountTypePreference preference = preferences.get(i); 459 preference.setOrder(i); 460 final String key = preference.getKey(); 461 if (!profileData.accountPreferences.containsKey(key)) { 462 profileData.preferenceGroup.addPreference(preference); 463 profileData.accountPreferences.put(key, preference); 464 } 465 } 466 if (profileData.addAccountPreference != null) { 467 profileData.preferenceGroup.addPreference(profileData.addAccountPreference); 468 } 469 for (String key : preferenceToRemove.keySet()) { 470 profileData.preferenceGroup.removePreference( 471 profileData.accountPreferences.get(key)); 472 profileData.accountPreferences.remove(key); 473 } 474 } else { 475 profileData.preferenceGroup.removeAll(); 476 // Put a label instead of the accounts list 477 if (mProfileNotAvailablePreference == null) { 478 mProfileNotAvailablePreference = 479 new Preference(mFragment.getPreferenceManager().getContext()); 480 } 481 mProfileNotAvailablePreference.setEnabled(false); 482 mProfileNotAvailablePreference.setIcon(R.drawable.empty_icon); 483 mProfileNotAvailablePreference.setTitle(null); 484 mProfileNotAvailablePreference.setSummary( 485 R.string.managed_profile_not_available_label); 486 profileData.preferenceGroup.addPreference(mProfileNotAvailablePreference); 487 } 488 if (profileData.removeWorkProfilePreference != null) { 489 profileData.preferenceGroup.addPreference(profileData.removeWorkProfilePreference); 490 } 491 if (profileData.managedProfilePreference != null) { 492 profileData.preferenceGroup.addPreference(profileData.managedProfilePreference); 493 } 494 } 495 getAccountTypePreferences(AuthenticatorHelper helper, UserHandle userHandle, ArrayMap<String, AccountTypePreference> preferenceToRemove)496 private ArrayList<AccountTypePreference> getAccountTypePreferences(AuthenticatorHelper helper, 497 UserHandle userHandle, ArrayMap<String, AccountTypePreference> preferenceToRemove) { 498 final String[] accountTypes = helper.getEnabledAccountTypes(); 499 final ArrayList<AccountTypePreference> accountTypePreferences = 500 new ArrayList<>(accountTypes.length); 501 502 for (int i = 0; i < accountTypes.length; i++) { 503 final String accountType = accountTypes[i]; 504 // Skip showing any account that does not have any of the requested authorities 505 if (!accountTypeHasAnyRequestedAuthorities(helper, accountType)) { 506 continue; 507 } 508 final CharSequence label = helper.getLabelForType(mContext, accountType); 509 if (label == null) { 510 continue; 511 } 512 final String titleResPackageName = helper.getPackageForType(accountType); 513 final int titleResId = helper.getLabelIdForType(accountType); 514 515 final Account[] accounts = AccountManager.get(mContext) 516 .getAccountsByTypeAsUser(accountType, userHandle); 517 final Drawable icon = helper.getDrawableForType(mContext, accountType); 518 final Context prefContext = mFragment.getPreferenceManager().getContext(); 519 520 // Add a preference row for each individual account 521 for (Account account : accounts) { 522 final AccountTypePreference preference = 523 preferenceToRemove.remove(AccountTypePreference.buildKey(account)); 524 if (preference != null) { 525 accountTypePreferences.add(preference); 526 continue; 527 } 528 final ArrayList<String> auths = 529 helper.getAuthoritiesForAccountType(account.type); 530 if (!AccountRestrictionHelper.showAccount(mAuthorities, auths)) { 531 continue; 532 } 533 final Bundle fragmentArguments = new Bundle(); 534 fragmentArguments.putParcelable(AccountDetailDashboardFragment.KEY_ACCOUNT, 535 account); 536 fragmentArguments.putParcelable(AccountDetailDashboardFragment.KEY_USER_HANDLE, 537 userHandle); 538 fragmentArguments.putString(AccountDetailDashboardFragment.KEY_ACCOUNT_TYPE, 539 accountType); 540 fragmentArguments.putString(AccountDetailDashboardFragment.KEY_ACCOUNT_LABEL, 541 label.toString()); 542 fragmentArguments.putInt(AccountDetailDashboardFragment.KEY_ACCOUNT_TITLE_RES, 543 titleResId); 544 fragmentArguments.putParcelable(EXTRA_USER, userHandle); 545 accountTypePreferences.add(new AccountTypePreference( 546 prefContext, mMetricsFeatureProvider.getMetricsCategory(mFragment), 547 account, titleResPackageName, titleResId, label, 548 AccountDetailDashboardFragment.class.getName(), fragmentArguments, icon)); 549 } 550 helper.preloadDrawableForType(mContext, accountType); 551 } 552 // Sort by label 553 Collections.sort(accountTypePreferences, new Comparator<AccountTypePreference>() { 554 @Override 555 public int compare(AccountTypePreference t1, AccountTypePreference t2) { 556 int result = t1.getSummary().toString().compareTo(t2.getSummary().toString()); 557 return result != 0 558 ? result : t1.getTitle().toString().compareTo(t2.getTitle().toString()); 559 } 560 }); 561 return accountTypePreferences; 562 } 563 accountTypeHasAnyRequestedAuthorities(AuthenticatorHelper helper, String accountType)564 private boolean accountTypeHasAnyRequestedAuthorities(AuthenticatorHelper helper, 565 String accountType) { 566 if (mAuthoritiesCount == 0) { 567 // No authorities required 568 return true; 569 } 570 final ArrayList<String> authoritiesForType = helper.getAuthoritiesForAccountType( 571 accountType); 572 if (authoritiesForType == null) { 573 Log.d(TAG, "No sync authorities for account type: " + accountType); 574 return false; 575 } 576 for (int j = 0; j < mAuthoritiesCount; j++) { 577 if (authoritiesForType.contains(mAuthorities[j])) { 578 return true; 579 } 580 } 581 return false; 582 } 583 isSingleProfile()584 private boolean isSingleProfile() { 585 return mUm.isLinkedUser() || mUm.getProfiles(UserHandle.myUserId()).size() == 1; 586 } 587 588 private class ManagedProfileBroadcastReceiver extends BroadcastReceiver { 589 private boolean mListeningToManagedProfileEvents; 590 591 @Override onReceive(Context context, Intent intent)592 public void onReceive(Context context, Intent intent) { 593 final String action = intent.getAction(); 594 Log.v(TAG, "Received broadcast: " + action); 595 if (action.equals(Intent.ACTION_MANAGED_PROFILE_REMOVED) 596 || action.equals(Intent.ACTION_MANAGED_PROFILE_ADDED)) { 597 if (mFragment instanceof AccountWorkProfileDashboardFragment) { 598 mFragment.getActivity().finish(); 599 } else { 600 // Clean old state 601 stopListeningToAccountUpdates(); 602 // Build new state 603 updateUi(); 604 listenToAccountUpdates(); 605 } 606 return; 607 } 608 Log.w(TAG, "Cannot handle received broadcast: " + intent.getAction()); 609 } 610 register(Context context)611 public void register(Context context) { 612 if (!mListeningToManagedProfileEvents) { 613 IntentFilter intentFilter = new IntentFilter(); 614 intentFilter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED); 615 intentFilter.addAction(Intent.ACTION_MANAGED_PROFILE_ADDED); 616 context.registerReceiver(this, intentFilter); 617 mListeningToManagedProfileEvents = true; 618 } 619 } 620 unregister(Context context)621 public void unregister(Context context) { 622 if (mListeningToManagedProfileEvents) { 623 context.unregisterReceiver(this); 624 mListeningToManagedProfileEvents = false; 625 } 626 } 627 } 628 } 629