• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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