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