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 = 1; 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 if (isSingleProfile()) { 327 preferenceGroup.setTitle(context.getString(R.string.account_for_section_header, 328 BidiFormatter.getInstance().unicodeWrap(userInfo.name))); 329 preferenceGroup.setContentDescription( 330 mContext.getString(R.string.account_settings)); 331 } else if (userInfo.isManagedProfile()) { 332 if (mType == ProfileSelectFragment.ProfileType.ALL) { 333 preferenceGroup.setTitle(R.string.category_work); 334 final String workGroupSummary = getWorkGroupSummary(context, userInfo); 335 preferenceGroup.setSummary(workGroupSummary); 336 preferenceGroup.setContentDescription( 337 mContext.getString(R.string.accessibility_category_work, workGroupSummary)); 338 } 339 profileData.removeWorkProfilePreference = newRemoveWorkProfilePreference(); 340 mHelper.enforceRestrictionOnPreference(profileData.removeWorkProfilePreference, 341 DISALLOW_REMOVE_MANAGED_PROFILE, UserHandle.myUserId()); 342 profileData.managedProfilePreference = newManagedProfileSettings(); 343 } else { 344 if (mType == ProfileSelectFragment.ProfileType.ALL) { 345 preferenceGroup.setTitle(R.string.category_personal); 346 preferenceGroup.setContentDescription( 347 mContext.getString(R.string.accessibility_category_personal)); 348 } 349 } 350 final PreferenceScreen screen = mFragment.getPreferenceScreen(); 351 if (screen != null) { 352 screen.addPreference(preferenceGroup); 353 } 354 profileData.preferenceGroup = preferenceGroup; 355 if (userInfo.isEnabled()) { 356 profileData.authenticatorHelper = new AuthenticatorHelper(context, 357 userInfo.getUserHandle(), this); 358 profileData.addAccountPreference = newAddAccountPreference(); 359 mHelper.enforceRestrictionOnPreference(profileData.addAccountPreference, 360 DISALLOW_MODIFY_ACCOUNTS, userInfo.id); 361 } 362 mProfiles.put(userInfo.id, profileData); 363 } 364 newAddAccountPreference()365 private RestrictedPreference newAddAccountPreference() { 366 RestrictedPreference preference = 367 new RestrictedPreference(mFragment.getPreferenceManager().getContext()); 368 preference.setKey(PREF_KEY_ADD_ACCOUNT); 369 preference.setTitle(R.string.add_account_label); 370 preference.setIcon(R.drawable.ic_add_24dp); 371 preference.setOnPreferenceClickListener(this); 372 preference.setOrder(ORDER_NEXT_TO_NEXT_TO_LAST); 373 return preference; 374 } 375 newRemoveWorkProfilePreference()376 private RestrictedPreference newRemoveWorkProfilePreference() { 377 RestrictedPreference preference = new RestrictedPreference( 378 mFragment.getPreferenceManager().getContext()); 379 preference.setKey(PREF_KEY_REMOVE_PROFILE); 380 preference.setTitle(R.string.remove_managed_profile_label); 381 preference.setIcon(R.drawable.ic_delete); 382 preference.setOnPreferenceClickListener(this); 383 preference.setOrder(ORDER_LAST); 384 return preference; 385 } 386 387 newManagedProfileSettings()388 private Preference newManagedProfileSettings() { 389 Preference preference = new Preference(mFragment.getPreferenceManager().getContext()); 390 preference.setKey(PREF_KEY_WORK_PROFILE_SETTING); 391 preference.setTitle(R.string.managed_profile_settings_title); 392 preference.setIcon(R.drawable.ic_settings_24dp); 393 preference.setOnPreferenceClickListener(this); 394 preference.setOrder(ORDER_NEXT_TO_LAST); 395 return preference; 396 } 397 getWorkGroupSummary(Context context, UserInfo userInfo)398 private String getWorkGroupSummary(Context context, UserInfo userInfo) { 399 PackageManager packageManager = context.getPackageManager(); 400 ApplicationInfo adminApplicationInfo = Utils.getAdminApplicationInfo(context, userInfo.id); 401 if (adminApplicationInfo == null) { 402 return null; 403 } 404 CharSequence appLabel = packageManager.getApplicationLabel(adminApplicationInfo); 405 return mContext.getString(R.string.managing_admin, appLabel); 406 } 407 cleanUpPreferences()408 void cleanUpPreferences() { 409 PreferenceScreen screen = mFragment.getPreferenceScreen(); 410 if (screen == null) { 411 return; 412 } 413 final int count = mProfiles.size(); 414 for (int i = count - 1; i >= 0; i--) { 415 final ProfileData data = mProfiles.valueAt(i); 416 if (data.pendingRemoval) { 417 screen.removePreference(data.preferenceGroup); 418 mProfiles.removeAt(i); 419 } 420 } 421 } 422 listenToAccountUpdates()423 private void listenToAccountUpdates() { 424 final int count = mProfiles.size(); 425 for (int i = 0; i < count; i++) { 426 AuthenticatorHelper authenticatorHelper = mProfiles.valueAt(i).authenticatorHelper; 427 if (authenticatorHelper != null) { 428 authenticatorHelper.listenToAccountUpdates(); 429 } 430 } 431 } 432 stopListeningToAccountUpdates()433 private void stopListeningToAccountUpdates() { 434 final int count = mProfiles.size(); 435 for (int i = 0; i < count; i++) { 436 AuthenticatorHelper authenticatorHelper = mProfiles.valueAt(i).authenticatorHelper; 437 if (authenticatorHelper != null) { 438 authenticatorHelper.stopListeningToAccountUpdates(); 439 } 440 } 441 } 442 updateAccountTypes(ProfileData profileData)443 private void updateAccountTypes(ProfileData profileData) { 444 if (mFragment.getPreferenceManager() == null 445 || profileData.preferenceGroup.getPreferenceManager() == null) { 446 // This could happen if activity is finishing 447 return; 448 } 449 if (profileData.userInfo.isEnabled()) { 450 final ArrayMap<String, AccountTypePreference> preferenceToRemove = 451 new ArrayMap<>(profileData.accountPreferences); 452 final ArrayList<AccountTypePreference> preferences = getAccountTypePreferences( 453 profileData.authenticatorHelper, profileData.userInfo.getUserHandle(), 454 preferenceToRemove); 455 final int count = preferences.size(); 456 for (int i = 0; i < count; i++) { 457 final AccountTypePreference preference = preferences.get(i); 458 preference.setOrder(i); 459 final String key = preference.getKey(); 460 if (!profileData.accountPreferences.containsKey(key)) { 461 profileData.preferenceGroup.addPreference(preference); 462 profileData.accountPreferences.put(key, preference); 463 } 464 } 465 if (profileData.addAccountPreference != null) { 466 profileData.preferenceGroup.addPreference(profileData.addAccountPreference); 467 } 468 for (String key : preferenceToRemove.keySet()) { 469 profileData.preferenceGroup.removePreference( 470 profileData.accountPreferences.get(key)); 471 profileData.accountPreferences.remove(key); 472 } 473 } else { 474 profileData.preferenceGroup.removeAll(); 475 // Put a label instead of the accounts list 476 if (mProfileNotAvailablePreference == null) { 477 mProfileNotAvailablePreference = 478 new Preference(mFragment.getPreferenceManager().getContext()); 479 } 480 mProfileNotAvailablePreference.setEnabled(false); 481 mProfileNotAvailablePreference.setIcon(R.drawable.empty_icon); 482 mProfileNotAvailablePreference.setTitle(null); 483 mProfileNotAvailablePreference.setSummary( 484 R.string.managed_profile_not_available_label); 485 profileData.preferenceGroup.addPreference(mProfileNotAvailablePreference); 486 } 487 if (profileData.removeWorkProfilePreference != null) { 488 profileData.preferenceGroup.addPreference(profileData.removeWorkProfilePreference); 489 } 490 if (profileData.managedProfilePreference != null) { 491 profileData.preferenceGroup.addPreference(profileData.managedProfilePreference); 492 } 493 } 494 getAccountTypePreferences(AuthenticatorHelper helper, UserHandle userHandle, ArrayMap<String, AccountTypePreference> preferenceToRemove)495 private ArrayList<AccountTypePreference> getAccountTypePreferences(AuthenticatorHelper helper, 496 UserHandle userHandle, ArrayMap<String, AccountTypePreference> preferenceToRemove) { 497 final String[] accountTypes = helper.getEnabledAccountTypes(); 498 final ArrayList<AccountTypePreference> accountTypePreferences = 499 new ArrayList<>(accountTypes.length); 500 501 for (int i = 0; i < accountTypes.length; i++) { 502 final String accountType = accountTypes[i]; 503 // Skip showing any account that does not have any of the requested authorities 504 if (!accountTypeHasAnyRequestedAuthorities(helper, accountType)) { 505 continue; 506 } 507 final CharSequence label = helper.getLabelForType(mContext, accountType); 508 if (label == null) { 509 continue; 510 } 511 final String titleResPackageName = helper.getPackageForType(accountType); 512 final int titleResId = helper.getLabelIdForType(accountType); 513 514 final Account[] accounts = AccountManager.get(mContext) 515 .getAccountsByTypeAsUser(accountType, userHandle); 516 final Drawable icon = helper.getDrawableForType(mContext, accountType); 517 final Context prefContext = mFragment.getPreferenceManager().getContext(); 518 519 // Add a preference row for each individual account 520 for (Account account : accounts) { 521 final AccountTypePreference preference = 522 preferenceToRemove.remove(AccountTypePreference.buildKey(account)); 523 if (preference != null) { 524 accountTypePreferences.add(preference); 525 continue; 526 } 527 final ArrayList<String> auths = 528 helper.getAuthoritiesForAccountType(account.type); 529 if (!AccountRestrictionHelper.showAccount(mAuthorities, auths)) { 530 continue; 531 } 532 final Bundle fragmentArguments = new Bundle(); 533 fragmentArguments.putParcelable(AccountDetailDashboardFragment.KEY_ACCOUNT, 534 account); 535 fragmentArguments.putParcelable(AccountDetailDashboardFragment.KEY_USER_HANDLE, 536 userHandle); 537 fragmentArguments.putString(AccountDetailDashboardFragment.KEY_ACCOUNT_TYPE, 538 accountType); 539 fragmentArguments.putString(AccountDetailDashboardFragment.KEY_ACCOUNT_LABEL, 540 label.toString()); 541 fragmentArguments.putInt(AccountDetailDashboardFragment.KEY_ACCOUNT_TITLE_RES, 542 titleResId); 543 fragmentArguments.putParcelable(EXTRA_USER, userHandle); 544 accountTypePreferences.add(new AccountTypePreference( 545 prefContext, mMetricsFeatureProvider.getMetricsCategory(mFragment), 546 account, titleResPackageName, titleResId, label, 547 AccountDetailDashboardFragment.class.getName(), fragmentArguments, icon)); 548 } 549 helper.preloadDrawableForType(mContext, accountType); 550 } 551 // Sort by label 552 Collections.sort(accountTypePreferences, new Comparator<AccountTypePreference>() { 553 @Override 554 public int compare(AccountTypePreference t1, AccountTypePreference t2) { 555 int result = t1.getSummary().toString().compareTo(t2.getSummary().toString()); 556 return result != 0 557 ? result : t1.getTitle().toString().compareTo(t2.getTitle().toString()); 558 } 559 }); 560 return accountTypePreferences; 561 } 562 accountTypeHasAnyRequestedAuthorities(AuthenticatorHelper helper, String accountType)563 private boolean accountTypeHasAnyRequestedAuthorities(AuthenticatorHelper helper, 564 String accountType) { 565 if (mAuthoritiesCount == 0) { 566 // No authorities required 567 return true; 568 } 569 final ArrayList<String> authoritiesForType = helper.getAuthoritiesForAccountType( 570 accountType); 571 if (authoritiesForType == null) { 572 Log.d(TAG, "No sync authorities for account type: " + accountType); 573 return false; 574 } 575 for (int j = 0; j < mAuthoritiesCount; j++) { 576 if (authoritiesForType.contains(mAuthorities[j])) { 577 return true; 578 } 579 } 580 return false; 581 } 582 isSingleProfile()583 private boolean isSingleProfile() { 584 return mUm.isLinkedUser() || mUm.getProfiles(UserHandle.myUserId()).size() == 1; 585 } 586 587 private class ManagedProfileBroadcastReceiver extends BroadcastReceiver { 588 private boolean mListeningToManagedProfileEvents; 589 590 @Override onReceive(Context context, Intent intent)591 public void onReceive(Context context, Intent intent) { 592 final String action = intent.getAction(); 593 Log.v(TAG, "Received broadcast: " + action); 594 if (action.equals(Intent.ACTION_MANAGED_PROFILE_REMOVED) 595 || action.equals(Intent.ACTION_MANAGED_PROFILE_ADDED)) { 596 if (mFragment instanceof AccountWorkProfileDashboardFragment) { 597 mFragment.getActivity().finish(); 598 } else { 599 // Clean old state 600 stopListeningToAccountUpdates(); 601 // Build new state 602 updateUi(); 603 listenToAccountUpdates(); 604 } 605 return; 606 } 607 Log.w(TAG, "Cannot handle received broadcast: " + intent.getAction()); 608 } 609 register(Context context)610 public void register(Context context) { 611 if (!mListeningToManagedProfileEvents) { 612 IntentFilter intentFilter = new IntentFilter(); 613 intentFilter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED); 614 intentFilter.addAction(Intent.ACTION_MANAGED_PROFILE_ADDED); 615 context.registerReceiver(this, intentFilter); 616 mListeningToManagedProfileEvents = true; 617 } 618 } 619 unregister(Context context)620 public void unregister(Context context) { 621 if (mListeningToManagedProfileEvents) { 622 context.unregisterReceiver(this); 623 mListeningToManagedProfileEvents = false; 624 } 625 } 626 } 627 } 628