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.support.v7.preference.Preference; 40 import android.support.v7.preference.Preference.OnPreferenceClickListener; 41 import android.support.v7.preference.PreferenceGroup; 42 import android.support.v7.preference.PreferenceScreen; 43 import android.util.ArrayMap; 44 import android.util.Log; 45 import android.util.SparseArray; 46 47 import com.android.internal.annotations.VisibleForTesting; 48 import com.android.settings.AccessiblePreferenceCategory; 49 import com.android.settings.DimmableIconPreference; 50 import com.android.settings.R; 51 import com.android.settings.SettingsActivity; 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.instrumentation.MetricsFeatureProvider; 56 import com.android.settings.overlay.FeatureFactory; 57 import com.android.settings.search.SearchFeatureProviderImpl; 58 import com.android.settings.search.SearchIndexableRaw; 59 import com.android.settingslib.RestrictedPreference; 60 import com.android.settingslib.accounts.AuthenticatorHelper; 61 import com.android.settingslib.core.AbstractPreferenceController; 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 DimmableIconPreference 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 { 196 SearchIndexableRaw data = new SearchIndexableRaw(mContext); 197 data.title = res.getString(R.string.managed_profile_settings_title); 198 data.screenTitle = screenTitle; 199 rawData.add(data); 200 } 201 } 202 } 203 } 204 } 205 206 @Override onResume()207 public void onResume() { 208 updateUi(); 209 mManagedProfileBroadcastReceiver.register(mContext); 210 listenToAccountUpdates(); 211 } 212 213 @Override onPause()214 public void onPause() { 215 stopListeningToAccountUpdates(); 216 mManagedProfileBroadcastReceiver.unregister(mContext); 217 } 218 219 @Override onAccountsUpdate(UserHandle userHandle)220 public void onAccountsUpdate(UserHandle userHandle) { 221 final ProfileData profileData = mProfiles.get(userHandle.getIdentifier()); 222 if (profileData != null) { 223 updateAccountTypes(profileData); 224 } else { 225 Log.w(TAG, "Missing Settings screen for: " + userHandle.getIdentifier()); 226 } 227 } 228 229 @Override onPreferenceClick(Preference preference)230 public boolean onPreferenceClick(Preference preference) { 231 // Check the preference 232 final int count = mProfiles.size(); 233 for (int i = 0; i < count; i++) { 234 ProfileData profileData = mProfiles.valueAt(i); 235 if (preference == profileData.addAccountPreference) { 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 final int userId = profileData.userInfo.id; 244 RemoveUserFragment.newInstance(userId).show(mParent.getFragmentManager(), 245 "removeUser"); 246 return true; 247 } 248 if (preference == profileData.managedProfilePreference) { 249 Bundle arguments = new Bundle(); 250 arguments.putParcelable(Intent.EXTRA_USER, profileData.userInfo.getUserHandle()); 251 ((SettingsActivity) mParent.getActivity()).startPreferencePanel(mParent, 252 ManagedProfileSettings.class.getName(), arguments, 253 R.string.managed_profile_settings_title, null, null, 0); 254 return true; 255 } 256 } 257 return false; 258 } 259 getProfileData()260 SparseArray<ProfileData> getProfileData() { 261 return mProfiles; 262 } 263 updateUi()264 private void updateUi() { 265 if (!isAvailable()) { 266 // This should not happen 267 Log.e(TAG, "We should not be showing settings for a managed profile"); 268 return; 269 } 270 271 for (int i = 0, size = mProfiles.size(); i < size; i++) { 272 mProfiles.valueAt(i).pendingRemoval = true; 273 } 274 if (mUm.isLinkedUser()) { 275 // Restricted user or similar 276 UserInfo userInfo = mUm.getUserInfo(UserHandle.myUserId()); 277 updateProfileUi(userInfo); 278 } else { 279 List<UserInfo> profiles = mUm.getProfiles(UserHandle.myUserId()); 280 final int profilesCount = profiles.size(); 281 for (int i = 0; i < profilesCount; i++) { 282 updateProfileUi(profiles.get(i)); 283 } 284 } 285 cleanUpPreferences(); 286 287 // Add all preferences, starting with one for the primary profile. 288 // Note that we're relying on the ordering given by the SparseArray keys, and on the 289 // value of UserHandle.USER_OWNER being smaller than all the rest. 290 final int profilesCount = mProfiles.size(); 291 for (int i = 0; i < profilesCount; i++) { 292 updateAccountTypes(mProfiles.valueAt(i)); 293 } 294 } 295 updateProfileUi(final UserInfo userInfo)296 private void updateProfileUi(final UserInfo userInfo) { 297 if (mParent.getPreferenceManager() == null) { 298 return; 299 } 300 final ProfileData data = mProfiles.get(userInfo.id); 301 if (data != null) { 302 data.pendingRemoval = false; 303 if (userInfo.isEnabled()) { 304 // recreate the authentication helper to refresh the list of enabled accounts 305 data.authenticatorHelper = 306 new AuthenticatorHelper(mContext, userInfo.getUserHandle(), this); 307 } 308 return; 309 } 310 final Context context = mContext; 311 final ProfileData profileData = new ProfileData(); 312 profileData.userInfo = userInfo; 313 AccessiblePreferenceCategory preferenceGroup = 314 mHelper.createAccessiblePreferenceCategory(mParent.getPreferenceManager().getContext()); 315 preferenceGroup.setOrder(mAccountProfileOrder++); 316 if (isSingleProfile()) { 317 preferenceGroup.setTitle(context.getString(R.string.account_for_section_header, 318 userInfo.name)); 319 preferenceGroup.setContentDescription( 320 mContext.getString(R.string.account_settings)); 321 } else if (userInfo.isManagedProfile()) { 322 preferenceGroup.setTitle(R.string.category_work); 323 String workGroupSummary = getWorkGroupSummary(context, userInfo); 324 preferenceGroup.setSummary(workGroupSummary); 325 preferenceGroup.setContentDescription( 326 mContext.getString(R.string.accessibility_category_work, workGroupSummary)); 327 profileData.removeWorkProfilePreference = newRemoveWorkProfilePreference(context); 328 mHelper.enforceRestrictionOnPreference(profileData.removeWorkProfilePreference, 329 DISALLOW_REMOVE_MANAGED_PROFILE, UserHandle.myUserId()); 330 profileData.managedProfilePreference = newManagedProfileSettings(); 331 } else { 332 preferenceGroup.setTitle(R.string.category_personal); 333 preferenceGroup.setContentDescription( 334 mContext.getString(R.string.accessibility_category_personal)); 335 } 336 final PreferenceScreen screen = mParent.getPreferenceScreen(); 337 if (screen != null) { 338 screen.addPreference(preferenceGroup); 339 } 340 profileData.preferenceGroup = preferenceGroup; 341 if (userInfo.isEnabled()) { 342 profileData.authenticatorHelper = new AuthenticatorHelper(context, 343 userInfo.getUserHandle(), this); 344 profileData.addAccountPreference = newAddAccountPreference(context); 345 mHelper.enforceRestrictionOnPreference(profileData.addAccountPreference, 346 DISALLOW_MODIFY_ACCOUNTS, userInfo.id); 347 } 348 mProfiles.put(userInfo.id, profileData); 349 new SearchFeatureProviderImpl().getIndexingManager(mContext).updateFromClassNameResource( 350 UserAndAccountDashboardFragment.class.getName(), true /* includeInSearchResults */); 351 } 352 newAddAccountPreference(Context context)353 private DimmableIconPreference newAddAccountPreference(Context context) { 354 DimmableIconPreference preference = 355 new DimmableIconPreference(mParent.getPreferenceManager().getContext()); 356 preference.setTitle(R.string.add_account_label); 357 preference.setIcon(R.drawable.ic_menu_add); 358 preference.setOnPreferenceClickListener(this); 359 preference.setOrder(ORDER_NEXT_TO_NEXT_TO_LAST); 360 return preference; 361 } 362 newRemoveWorkProfilePreference(Context context)363 private RestrictedPreference newRemoveWorkProfilePreference(Context context) { 364 RestrictedPreference preference = new RestrictedPreference( 365 mParent.getPreferenceManager().getContext()); 366 preference.setTitle(R.string.remove_managed_profile_label); 367 preference.setIcon(R.drawable.ic_menu_delete); 368 preference.setOnPreferenceClickListener(this); 369 preference.setOrder(ORDER_LAST); 370 return preference; 371 } 372 373 newManagedProfileSettings()374 private Preference newManagedProfileSettings() { 375 Preference preference = new Preference(mParent.getPreferenceManager().getContext()); 376 preference.setTitle(R.string.managed_profile_settings_title); 377 preference.setIcon(R.drawable.ic_settings); 378 preference.setOnPreferenceClickListener(this); 379 preference.setOrder(ORDER_NEXT_TO_LAST); 380 return preference; 381 } 382 getWorkGroupSummary(Context context, UserInfo userInfo)383 private String getWorkGroupSummary(Context context, UserInfo userInfo) { 384 PackageManager packageManager = context.getPackageManager(); 385 ApplicationInfo adminApplicationInfo = Utils.getAdminApplicationInfo(context, userInfo.id); 386 if (adminApplicationInfo == null) { 387 return null; 388 } 389 CharSequence appLabel = packageManager.getApplicationLabel(adminApplicationInfo); 390 return mContext.getString(R.string.managing_admin, appLabel); 391 } 392 cleanUpPreferences()393 void cleanUpPreferences() { 394 PreferenceScreen screen = mParent.getPreferenceScreen(); 395 if (screen == null) { 396 return; 397 } 398 final int count = mProfiles.size(); 399 for (int i = count-1; i >= 0; i--) { 400 final ProfileData data = mProfiles.valueAt(i); 401 if (data.pendingRemoval) { 402 screen.removePreference(data.preferenceGroup); 403 mProfiles.removeAt(i); 404 } 405 } 406 } 407 listenToAccountUpdates()408 private void listenToAccountUpdates() { 409 final int count = mProfiles.size(); 410 for (int i = 0; i < count; i++) { 411 AuthenticatorHelper authenticatorHelper = mProfiles.valueAt(i).authenticatorHelper; 412 if (authenticatorHelper != null) { 413 authenticatorHelper.listenToAccountUpdates(); 414 } 415 } 416 } 417 stopListeningToAccountUpdates()418 private void stopListeningToAccountUpdates() { 419 final int count = mProfiles.size(); 420 for (int i = 0; i < count; i++) { 421 AuthenticatorHelper authenticatorHelper = mProfiles.valueAt(i).authenticatorHelper; 422 if (authenticatorHelper != null) { 423 authenticatorHelper.stopListeningToAccountUpdates(); 424 } 425 } 426 } 427 updateAccountTypes(ProfileData profileData)428 private void updateAccountTypes(ProfileData profileData) { 429 if (mParent.getPreferenceManager() == null 430 || profileData.preferenceGroup.getPreferenceManager() == null) { 431 // This could happen if activity is finishing 432 return; 433 } 434 if (profileData.userInfo.isEnabled()) { 435 final ArrayMap<String, AccountTypePreference> preferenceToRemove = 436 new ArrayMap<>(profileData.accountPreferences); 437 final ArrayList<AccountTypePreference> preferences = getAccountTypePreferences( 438 profileData.authenticatorHelper, profileData.userInfo.getUserHandle(), 439 preferenceToRemove); 440 final int count = preferences.size(); 441 for (int i = 0; i < count; i++) { 442 final AccountTypePreference preference = preferences.get(i); 443 preference.setOrder(i); 444 final String key = preference.getKey(); 445 if (!profileData.accountPreferences.containsKey(key)) { 446 profileData.preferenceGroup.addPreference(preference); 447 profileData.accountPreferences.put(key, preference); 448 } 449 } 450 if (profileData.addAccountPreference != null) { 451 profileData.preferenceGroup.addPreference(profileData.addAccountPreference); 452 } 453 for (String key : preferenceToRemove.keySet()) { 454 profileData.preferenceGroup.removePreference( 455 profileData.accountPreferences.get(key)); 456 profileData.accountPreferences.remove(key); 457 } 458 } else { 459 profileData.preferenceGroup.removeAll(); 460 // Put a label instead of the accounts list 461 if (mProfileNotAvailablePreference == null) { 462 mProfileNotAvailablePreference = 463 new Preference(mParent.getPreferenceManager().getContext()); 464 } 465 mProfileNotAvailablePreference.setEnabled(false); 466 mProfileNotAvailablePreference.setIcon(R.drawable.empty_icon); 467 mProfileNotAvailablePreference.setTitle(null); 468 mProfileNotAvailablePreference.setSummary( 469 R.string.managed_profile_not_available_label); 470 profileData.preferenceGroup.addPreference(mProfileNotAvailablePreference); 471 } 472 if (profileData.removeWorkProfilePreference != null) { 473 profileData.preferenceGroup.addPreference(profileData.removeWorkProfilePreference); 474 } 475 if (profileData.managedProfilePreference != null) { 476 profileData.preferenceGroup.addPreference(profileData.managedProfilePreference); 477 } 478 } 479 getAccountTypePreferences(AuthenticatorHelper helper, UserHandle userHandle, ArrayMap<String, AccountTypePreference> preferenceToRemove)480 private ArrayList<AccountTypePreference> getAccountTypePreferences(AuthenticatorHelper helper, 481 UserHandle userHandle, ArrayMap<String, AccountTypePreference> preferenceToRemove) { 482 final String[] accountTypes = helper.getEnabledAccountTypes(); 483 final ArrayList<AccountTypePreference> accountTypePreferences = 484 new ArrayList<>(accountTypes.length); 485 486 for (int i = 0; i < accountTypes.length; i++) { 487 final String accountType = accountTypes[i]; 488 // Skip showing any account that does not have any of the requested authorities 489 if (!accountTypeHasAnyRequestedAuthorities(helper, accountType)) { 490 continue; 491 } 492 final CharSequence label = helper.getLabelForType(mContext, accountType); 493 if (label == null) { 494 continue; 495 } 496 final String titleResPackageName = helper.getPackageForType(accountType); 497 final int titleResId = helper.getLabelIdForType(accountType); 498 499 final Account[] accounts = AccountManager.get(mContext) 500 .getAccountsByTypeAsUser(accountType, userHandle); 501 final Drawable icon = helper.getDrawableForType(mContext, accountType); 502 final Context prefContext = mParent.getPreferenceManager().getContext(); 503 504 // Add a preference row for each individual account 505 for (Account account : accounts) { 506 final AccountTypePreference preference = 507 preferenceToRemove.remove(AccountTypePreference.buildKey(account)); 508 if (preference != null) { 509 accountTypePreferences.add(preference); 510 continue; 511 } 512 final ArrayList<String> auths = 513 helper.getAuthoritiesForAccountType(account.type); 514 if (!AccountRestrictionHelper.showAccount(mAuthorities, auths)) { 515 continue; 516 } 517 final Bundle fragmentArguments = new Bundle(); 518 fragmentArguments.putParcelable(AccountDetailDashboardFragment.KEY_ACCOUNT, 519 account); 520 fragmentArguments.putParcelable(AccountDetailDashboardFragment.KEY_USER_HANDLE, 521 userHandle); 522 fragmentArguments.putString(AccountDetailDashboardFragment.KEY_ACCOUNT_TYPE, 523 accountType); 524 fragmentArguments.putString(AccountDetailDashboardFragment.KEY_ACCOUNT_LABEL, 525 label.toString()); 526 fragmentArguments.putInt(AccountDetailDashboardFragment.KEY_ACCOUNT_TITLE_RES, 527 titleResId); 528 fragmentArguments.putParcelable(EXTRA_USER, userHandle); 529 accountTypePreferences.add(new AccountTypePreference( 530 prefContext, mMetricsFeatureProvider.getMetricsCategory(mParent), 531 account, titleResPackageName, titleResId, label, 532 AccountDetailDashboardFragment.class.getName(), fragmentArguments, icon)); 533 } 534 helper.preloadDrawableForType(mContext, accountType); 535 } 536 // Sort by label 537 Collections.sort(accountTypePreferences, new Comparator<AccountTypePreference>() { 538 @Override 539 public int compare(AccountTypePreference t1, AccountTypePreference t2) { 540 int result = t1.getSummary().toString().compareTo(t2.getSummary().toString()); 541 return result != 0 542 ? result : t1.getTitle().toString().compareTo(t2.getTitle().toString()); 543 } 544 }); 545 return accountTypePreferences; 546 } 547 accountTypeHasAnyRequestedAuthorities(AuthenticatorHelper helper, String accountType)548 private boolean accountTypeHasAnyRequestedAuthorities(AuthenticatorHelper helper, 549 String accountType) { 550 if (mAuthoritiesCount == 0) { 551 // No authorities required 552 return true; 553 } 554 final ArrayList<String> authoritiesForType = helper.getAuthoritiesForAccountType( 555 accountType); 556 if (authoritiesForType == null) { 557 Log.d(TAG, "No sync authorities for account type: " + accountType); 558 return false; 559 } 560 for (int j = 0; j < mAuthoritiesCount; j++) { 561 if (authoritiesForType.contains(mAuthorities[j])) { 562 return true; 563 } 564 } 565 return false; 566 } 567 isSingleProfile()568 private boolean isSingleProfile() { 569 return mUm.isLinkedUser() || mUm.getProfiles(UserHandle.myUserId()).size() == 1; 570 } 571 572 private class ManagedProfileBroadcastReceiver extends BroadcastReceiver { 573 private boolean mListeningToManagedProfileEvents; 574 575 @Override onReceive(Context context, Intent intent)576 public void onReceive(Context context, Intent intent) { 577 final String action = intent.getAction(); 578 Log.v(TAG, "Received broadcast: " + action); 579 if (action.equals(Intent.ACTION_MANAGED_PROFILE_REMOVED) 580 || action.equals(Intent.ACTION_MANAGED_PROFILE_ADDED)) { 581 // Clean old state 582 stopListeningToAccountUpdates(); 583 // Build new state 584 updateUi(); 585 listenToAccountUpdates(); 586 return; 587 } 588 Log.w(TAG, "Cannot handle received broadcast: " + intent.getAction()); 589 } 590 register(Context context)591 public void register(Context context) { 592 if (!mListeningToManagedProfileEvents) { 593 IntentFilter intentFilter = new IntentFilter(); 594 intentFilter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED); 595 intentFilter.addAction(Intent.ACTION_MANAGED_PROFILE_ADDED); 596 context.registerReceiver(this, intentFilter); 597 mListeningToManagedProfileEvents = true; 598 } 599 } 600 unregister(Context context)601 public void unregister(Context context) { 602 if (mListeningToManagedProfileEvents) { 603 context.unregisterReceiver(this); 604 mListeningToManagedProfileEvents = false; 605 } 606 } 607 } 608 } 609