• 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.tv.settings.system;
18 
19 import android.accounts.AccountManager;
20 import android.annotation.SuppressLint;
21 import android.app.ActivityManager;
22 import android.app.Fragment;
23 import android.content.BroadcastReceiver;
24 import android.content.Context;
25 import android.content.Intent;
26 import android.content.IntentFilter;
27 import android.content.pm.PackageManager;
28 import android.content.pm.ResolveInfo;
29 import android.content.pm.UserInfo;
30 import android.graphics.Bitmap;
31 import android.graphics.Canvas;
32 import android.graphics.drawable.Drawable;
33 import android.os.AsyncTask;
34 import android.os.Bundle;
35 import android.os.Handler;
36 import android.os.RemoteException;
37 import android.os.ServiceManager;
38 import android.os.UserHandle;
39 import android.os.UserManager;
40 import android.provider.Settings;
41 import android.support.annotation.DrawableRes;
42 import android.support.annotation.IntDef;
43 import android.support.v17.preference.LeanbackPreferenceFragment;
44 import android.support.v17.preference.LeanbackSettingsFragment;
45 import android.support.v4.content.LocalBroadcastManager;
46 import android.support.v7.preference.Preference;
47 import android.support.v7.preference.PreferenceGroup;
48 import android.support.v7.preference.TwoStatePreference;
49 import android.text.TextUtils;
50 import android.util.Log;
51 
52 import com.android.internal.widget.ILockSettings;
53 import com.android.internal.widget.LockPatternUtils;
54 import com.android.internal.widget.VerifyCredentialResponse;
55 import com.android.tv.settings.R;
56 import com.android.tv.settings.dialog.PinDialogFragment;
57 import com.android.tv.settings.users.AppRestrictionsFragment;
58 import com.android.tv.settings.users.RestrictedProfilePinDialogFragment;
59 import com.android.tv.settings.users.UserSwitchListenerService;
60 
61 import java.lang.annotation.Retention;
62 import java.lang.annotation.RetentionPolicy;
63 import java.util.List;
64 
65 public class SecurityFragment extends LeanbackPreferenceFragment
66         implements RestrictedProfilePinDialogFragment.Callback {
67 
68     private static final String TAG = "SecurityFragment";
69 
70     private static final String KEY_UNKNOWN_SOURCES = "unknown_sources";
71     private static final String KEY_VERIFY_APPS = "verify_apps";
72     private static final String KEY_RESTRICTED_PROFILE_GROUP = "restricted_profile_group";
73     private static final String KEY_RESTRICTED_PROFILE_ENTER = "restricted_profile_enter";
74     private static final String KEY_RESTRICTED_PROFILE_EXIT = "restricted_profile_exit";
75     private static final String KEY_RESTRICTED_PROFILE_APPS = "restricted_profile_apps";
76     private static final String KEY_RESTRICTED_PROFILE_PIN = "restricted_profile_pin";
77     private static final String KEY_RESTRICTED_PROFILE_CREATE = "restricted_profile_create";
78     private static final String KEY_RESTRICTED_PROFILE_DELETE = "restricted_profile_delete";
79 
80     private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
81 
82     private static final String ACTION_RESTRICTED_PROFILE_CREATED =
83             "SecurityFragment.RESTRICTED_PROFILE_CREATED";
84     private static final String EXTRA_RESTRICTED_PROFILE_INFO =
85             "SecurityFragment.RESTRICTED_PROFILE_INFO";
86     private static final String SAVESTATE_CREATING_RESTRICTED_PROFILE =
87             "SecurityFragment.CREATING_RESTRICTED_PROFILE";
88 
89     @Retention(RetentionPolicy.SOURCE)
90     @IntDef({PIN_MODE_CHOOSE_LOCKSCREEN,
91             PIN_MODE_RESTRICTED_PROFILE_SWITCH_OUT,
92             PIN_MODE_RESTRICTED_PROFILE_CHANGE_PASSWORD,
93             PIN_MODE_RESTRICTED_PROFILE_DELETE})
94     private @interface PinMode {}
95     private static final int PIN_MODE_CHOOSE_LOCKSCREEN = 1;
96     private static final int PIN_MODE_RESTRICTED_PROFILE_SWITCH_OUT = 2;
97     private static final int PIN_MODE_RESTRICTED_PROFILE_CHANGE_PASSWORD = 3;
98     private static final int PIN_MODE_RESTRICTED_PROFILE_DELETE = 4;
99 
100     private Preference mUnknownSourcesPref;
101     private TwoStatePreference mVerifyAppsPref;
102     private PreferenceGroup mRestrictedProfileGroup;
103     private Preference mRestrictedProfileEnterPref;
104     private Preference mRestrictedProfileExitPref;
105     private Preference mRestrictedProfileAppsPref;
106     private Preference mRestrictedProfilePinPref;
107     private Preference mRestrictedProfileCreatePref;
108     private Preference mRestrictedProfileDeletePref;
109 
110     private UserManager mUserManager;
111     private UserInfo mRestrictedUserInfo;
112     private ILockSettings mLockSettingsService;
113 
114     private boolean mCreatingRestrictedProfile;
115     @SuppressLint("StaticFieldLeak")
116     private static CreateRestrictedProfileTask sCreateRestrictedProfileTask;
117     private final BroadcastReceiver mRestrictedProfileReceiver = new BroadcastReceiver() {
118         @Override
119         public void onReceive(Context context, Intent intent) {
120             UserInfo result = intent.getParcelableExtra(EXTRA_RESTRICTED_PROFILE_INFO);
121             if (isResumed()) {
122                 onRestrictedUserCreated(result);
123             }
124         }
125     };
126 
127     private final Handler mHandler = new Handler();
128 
newInstance()129     public static SecurityFragment newInstance() {
130         return new SecurityFragment();
131     }
132 
133     @Override
onCreate(Bundle savedInstanceState)134     public void onCreate(Bundle savedInstanceState) {
135         mUserManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE);
136         super.onCreate(savedInstanceState);
137         mCreatingRestrictedProfile = savedInstanceState != null
138                 && savedInstanceState.getBoolean(SAVESTATE_CREATING_RESTRICTED_PROFILE);
139     }
140 
141     @Override
onResume()142     public void onResume() {
143         super.onResume();
144         refresh();
145         LocalBroadcastManager.getInstance(getActivity())
146                 .registerReceiver(mRestrictedProfileReceiver,
147                         new IntentFilter(ACTION_RESTRICTED_PROFILE_CREATED));
148         if (mCreatingRestrictedProfile) {
149             UserInfo userInfo = findRestrictedUser(mUserManager);
150             if (userInfo != null) {
151                 onRestrictedUserCreated(userInfo);
152             }
153         }
154     }
155 
156     @Override
onPause()157     public void onPause() {
158         super.onPause();
159         LocalBroadcastManager.getInstance(getActivity())
160                 .unregisterReceiver(mRestrictedProfileReceiver);
161     }
162 
163     @Override
onSaveInstanceState(Bundle outState)164     public void onSaveInstanceState(Bundle outState) {
165         super.onSaveInstanceState(outState);
166         outState.putBoolean(SAVESTATE_CREATING_RESTRICTED_PROFILE, mCreatingRestrictedProfile);
167     }
168 
169     @Override
onCreatePreferences(Bundle savedInstanceState, String rootKey)170     public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
171         setPreferencesFromResource(R.xml.security, null);
172 
173         mUnknownSourcesPref = findPreference(KEY_UNKNOWN_SOURCES);
174         mVerifyAppsPref = (TwoStatePreference) findPreference(KEY_VERIFY_APPS);
175         mRestrictedProfileGroup = (PreferenceGroup) findPreference(KEY_RESTRICTED_PROFILE_GROUP);
176         mRestrictedProfileEnterPref = findPreference(KEY_RESTRICTED_PROFILE_ENTER);
177         mRestrictedProfileExitPref = findPreference(KEY_RESTRICTED_PROFILE_EXIT);
178         mRestrictedProfileAppsPref = findPreference(KEY_RESTRICTED_PROFILE_APPS);
179         mRestrictedProfilePinPref = findPreference(KEY_RESTRICTED_PROFILE_PIN);
180         mRestrictedProfileCreatePref = findPreference(KEY_RESTRICTED_PROFILE_CREATE);
181         mRestrictedProfileDeletePref = findPreference(KEY_RESTRICTED_PROFILE_DELETE);
182     }
183 
refresh()184     private void refresh() {
185         if (isRestrictedProfileInEffect(mUserManager)) {
186             // We are in restricted profile
187             mUnknownSourcesPref.setVisible(false);
188             mVerifyAppsPref.setVisible(false);
189 
190             mRestrictedProfileGroup.setVisible(true);
191             mRestrictedProfileEnterPref.setVisible(false);
192             mRestrictedProfileExitPref.setVisible(true);
193             mRestrictedProfileAppsPref.setVisible(false);
194             mRestrictedProfilePinPref.setVisible(false);
195             mRestrictedProfileCreatePref.setVisible(false);
196             mRestrictedProfileDeletePref.setVisible(false);
197         } else if (getRestrictedUser() != null) {
198             // Not in restricted profile, but it exists
199             mUnknownSourcesPref.setVisible(true);
200             mVerifyAppsPref.setVisible(shouldShowVerifierSetting());
201 
202             mRestrictedProfileGroup.setVisible(true);
203             mRestrictedProfileEnterPref.setVisible(true);
204             mRestrictedProfileExitPref.setVisible(false);
205             mRestrictedProfileAppsPref.setVisible(true);
206             mRestrictedProfilePinPref.setVisible(true);
207             mRestrictedProfileCreatePref.setVisible(false);
208             mRestrictedProfileDeletePref.setVisible(true);
209 
210             AppRestrictionsFragment.prepareArgs(mRestrictedProfileAppsPref.getExtras(),
211                     getRestrictedUser().id, false);
212         } else if (UserManager.supportsMultipleUsers()) {
213             // Not in restricted profile, and it doesn't exist
214             mUnknownSourcesPref.setVisible(true);
215             mVerifyAppsPref.setVisible(shouldShowVerifierSetting());
216 
217             mRestrictedProfileGroup.setVisible(true);
218             mRestrictedProfileEnterPref.setVisible(false);
219             mRestrictedProfileExitPref.setVisible(false);
220             mRestrictedProfileAppsPref.setVisible(false);
221             mRestrictedProfilePinPref.setVisible(false);
222             mRestrictedProfileCreatePref.setVisible(true);
223             mRestrictedProfileDeletePref.setVisible(false);
224         } else {
225             // Not in restricted profile, and can't create one either
226             mUnknownSourcesPref.setVisible(true);
227             mVerifyAppsPref.setVisible(shouldShowVerifierSetting());
228 
229             mRestrictedProfileGroup.setVisible(false);
230             mRestrictedProfileEnterPref.setVisible(false);
231             mRestrictedProfileExitPref.setVisible(false);
232             mRestrictedProfileAppsPref.setVisible(false);
233             mRestrictedProfilePinPref.setVisible(false);
234             mRestrictedProfileCreatePref.setVisible(false);
235             mRestrictedProfileDeletePref.setVisible(false);
236         }
237 
238         mRestrictedProfileCreatePref.setEnabled(sCreateRestrictedProfileTask == null);
239 
240         mUnknownSourcesPref.setEnabled(!isUnknownSourcesBlocked());
241         mVerifyAppsPref.setChecked(isVerifyAppsEnabled());
242         mVerifyAppsPref.setEnabled(isVerifierInstalled());
243     }
244 
245     @Override
onPreferenceTreeClick(Preference preference)246     public boolean onPreferenceTreeClick(Preference preference) {
247         final String key = preference.getKey();
248         if (TextUtils.isEmpty(key)) {
249             return super.onPreferenceTreeClick(preference);
250         }
251         switch (key) {
252             case KEY_VERIFY_APPS:
253                 setVerifyAppsEnabled(mVerifyAppsPref.isChecked());
254                 return true;
255             case KEY_RESTRICTED_PROFILE_ENTER:
256                 final UserInfo restrictedUser = getRestrictedUser();
257                 if (restrictedUser == null) {
258                     Log.e(TAG, "Tried to enter non-existent restricted user");
259                     return true;
260                 }
261                 switchUserNow(restrictedUser.id);
262                 getActivity().finish();
263                 return true;
264             case KEY_RESTRICTED_PROFILE_EXIT:
265                 launchPinDialog(PIN_MODE_RESTRICTED_PROFILE_SWITCH_OUT);
266                 return true;
267             case KEY_RESTRICTED_PROFILE_PIN:
268                 launchPinDialog(PIN_MODE_RESTRICTED_PROFILE_CHANGE_PASSWORD);
269                 return true;
270             case KEY_RESTRICTED_PROFILE_CREATE:
271                 if (hasLockscreenSecurity(new LockPatternUtils(getActivity()))) {
272                     addRestrictedUser();
273                 } else {
274                     launchPinDialog(PIN_MODE_CHOOSE_LOCKSCREEN);
275                 }
276                 return true;
277             case KEY_RESTRICTED_PROFILE_DELETE:
278                 launchPinDialog(PIN_MODE_RESTRICTED_PROFILE_DELETE);
279                 return true;
280         }
281         return super.onPreferenceTreeClick(preference);
282     }
283 
isUnknownSourcesBlocked()284     private boolean isUnknownSourcesBlocked() {
285         final UserManager um = (UserManager) getContext().getSystemService(Context.USER_SERVICE);
286         return um.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES);
287     }
288 
isVerifyAppsEnabled()289     private boolean isVerifyAppsEnabled() {
290         return Settings.Global.getInt(getContext().getContentResolver(),
291                 Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) > 0 && isVerifierInstalled();
292     }
293 
setVerifyAppsEnabled(boolean enable)294     private void setVerifyAppsEnabled(boolean enable) {
295         Settings.Global.putInt(getContext().getContentResolver(),
296                 Settings.Global.PACKAGE_VERIFIER_ENABLE, enable ? 1 : 0);
297     }
298 
isVerifierInstalled()299     private boolean isVerifierInstalled() {
300         final PackageManager pm = getContext().getPackageManager();
301         final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
302         verification.setType(PACKAGE_MIME_TYPE);
303         verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
304         final List<ResolveInfo> receivers = pm.queryBroadcastReceivers(verification, 0);
305         return receivers.size() > 0;
306     }
307 
shouldShowVerifierSetting()308     private boolean shouldShowVerifierSetting() {
309         return Settings.Global.getInt(getContext().getContentResolver(),
310                 Settings.Global.PACKAGE_VERIFIER_SETTING_VISIBLE, 1) > 0;
311     }
312 
launchPinDialog(@inMode int pinMode)313     private void launchPinDialog(@PinMode int pinMode) {
314         @PinDialogFragment.PinDialogType
315         int pinDialogMode;
316 
317         switch (pinMode) {
318             case PIN_MODE_CHOOSE_LOCKSCREEN:
319                 pinDialogMode = PinDialogFragment.PIN_DIALOG_TYPE_NEW_PIN;
320                 break;
321             case PIN_MODE_RESTRICTED_PROFILE_SWITCH_OUT:
322                 pinDialogMode = PinDialogFragment.PIN_DIALOG_TYPE_ENTER_PIN;
323                 break;
324             case PIN_MODE_RESTRICTED_PROFILE_CHANGE_PASSWORD:
325                 pinDialogMode = PinDialogFragment.PIN_DIALOG_TYPE_NEW_PIN;
326                 break;
327             case PIN_MODE_RESTRICTED_PROFILE_DELETE:
328                 pinDialogMode = PinDialogFragment.PIN_DIALOG_TYPE_ENTER_PIN;
329                 break;
330             default:
331                 throw new IllegalArgumentException("Unknown pin mode: " + pinMode);
332         }
333 
334         RestrictedProfilePinDialogFragment restrictedProfilePinDialogFragment =
335                 RestrictedProfilePinDialogFragment.newInstance(pinDialogMode);
336         restrictedProfilePinDialogFragment.setTargetFragment(this, pinMode);
337         restrictedProfilePinDialogFragment.show(getFragmentManager(),
338                 PinDialogFragment.DIALOG_TAG);
339     }
340 
341     @Override
saveLockPassword(String pin, int quality)342     public void saveLockPassword(String pin, int quality) {
343         new LockPatternUtils(getActivity()).saveLockPassword(pin, null, quality,
344                 UserHandle.myUserId());
345     }
346 
347     @Override
checkPassword(String password, int userId)348     public boolean checkPassword(String password, int userId) {
349         try {
350             return getLockSettings().checkCredential(password,
351                 LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, userId,  null /* progressCallback */)
352                     .getResponseCode() == VerifyCredentialResponse.RESPONSE_OK;
353         } catch (final RemoteException e) {
354             // ignore
355         }
356         return false;
357     }
358 
359     @Override
hasLockscreenSecurity()360     public boolean hasLockscreenSecurity() {
361         return hasLockscreenSecurity(new LockPatternUtils(getActivity()));
362     }
363 
getLockSettings()364     private ILockSettings getLockSettings() {
365         if (mLockSettingsService == null) {
366             mLockSettingsService = ILockSettings.Stub.asInterface(
367                     ServiceManager.getService("lock_settings"));
368         }
369         return mLockSettingsService;
370     }
371 
hasLockscreenSecurity(LockPatternUtils lpu)372     private static boolean hasLockscreenSecurity(LockPatternUtils lpu) {
373         return lpu.isLockPasswordEnabled(UserHandle.myUserId())
374                 || lpu.isLockPatternEnabled(UserHandle.myUserId());
375     }
376 
377     @Override
pinFragmentDone(int requestCode, boolean success)378     public void pinFragmentDone(int requestCode, boolean success) {
379         switch (requestCode) {
380             case PIN_MODE_CHOOSE_LOCKSCREEN:
381                 if (success) {
382                     addRestrictedUser();
383                 }
384                 break;
385             case PIN_MODE_RESTRICTED_PROFILE_SWITCH_OUT:
386                 if (success) {
387                     UserInfo myUserInfo =
388                             UserManager.get(getActivity()).getUserInfo(UserHandle.myUserId());
389                     if (myUserInfo == null ||
390                             myUserInfo.restrictedProfileParentId == UserInfo.NO_PROFILE_GROUP_ID) {
391                         switchUserNow(UserHandle.USER_SYSTEM);
392                     } else {
393                         switchUserNow(myUserInfo.restrictedProfileParentId);
394                     }
395                     getActivity().finish();
396                 }
397                 break;
398             case PIN_MODE_RESTRICTED_PROFILE_CHANGE_PASSWORD:
399                 // do nothing
400                 break;
401             case PIN_MODE_RESTRICTED_PROFILE_DELETE:
402                 if (success) {
403                     removeRestrictedUser();
404                     new LockPatternUtils(getActivity()).clearLock(null, UserHandle.myUserId());
405                 }
406                 break;
407         }
408     }
409 
findRestrictedUser(UserManager userManager)410     public static UserInfo findRestrictedUser(UserManager userManager) {
411         for (UserInfo userInfo : userManager.getUsers()) {
412             if (userInfo.isRestricted()) {
413                 return userInfo;
414             }
415         }
416         return null;
417     }
418 
getRestrictedUser()419     private UserInfo getRestrictedUser() {
420         if (mRestrictedUserInfo == null) {
421             mRestrictedUserInfo = findRestrictedUser(mUserManager);
422         }
423         return mRestrictedUserInfo;
424     }
425 
switchUserNow(int userId)426     private static void switchUserNow(int userId) {
427         try {
428             ActivityManager.getService().switchUser(userId);
429         } catch (RemoteException re) {
430             Log.e(TAG, "Caught exception while switching user! ", re);
431         }
432     }
433 
addRestrictedUser()434     private void addRestrictedUser() {
435         if (sCreateRestrictedProfileTask == null) {
436             sCreateRestrictedProfileTask = new CreateRestrictedProfileTask(getContext(),
437                     mUserManager);
438             sCreateRestrictedProfileTask.execute();
439             mCreatingRestrictedProfile = true;
440         }
441         refresh();
442     }
443 
removeRestrictedUser()444     private void removeRestrictedUser() {
445         final UserInfo restrictedUser = getRestrictedUser();
446         if (restrictedUser == null) {
447             Log.w(TAG, "No restricted user to remove?");
448             return;
449         }
450         final int restrictedUserHandle = restrictedUser.id;
451         mRestrictedUserInfo = null;
452         mHandler.post(() -> {
453             mUserManager.removeUser(restrictedUserHandle);
454             UserSwitchListenerService.updateLaunchPoint(getActivity(), false);
455             refresh();
456         });
457     }
458 
isRestrictedProfileInEffect(Context context)459     public static boolean isRestrictedProfileInEffect(Context context) {
460         UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
461         UserInfo userInfo = userManager.getUserInfo(UserHandle.myUserId());
462         return userInfo.isRestricted();
463     }
464 
isRestrictedProfileInEffect(UserManager userManager)465     private static boolean isRestrictedProfileInEffect(UserManager userManager) {
466         UserInfo userInfo = userManager.getUserInfo(UserHandle.myUserId());
467         return userInfo.isRestricted();
468     }
469 
onRestrictedUserCreated(UserInfo result)470     private void onRestrictedUserCreated(UserInfo result) {
471         int userId = result.id;
472         if (result.isRestricted()
473                 && result.restrictedProfileParentId == UserHandle.myUserId()) {
474             final AppRestrictionsFragment restrictionsFragment =
475                     AppRestrictionsFragment.newInstance(userId, true);
476             final Fragment settingsFragment = getCallbackFragment();
477             if (settingsFragment instanceof LeanbackSettingsFragment) {
478                 ((LeanbackSettingsFragment) settingsFragment)
479                         .startPreferenceFragment(restrictionsFragment);
480             } else {
481                 throw new IllegalStateException("Didn't find fragment of expected type: "
482                         + settingsFragment);
483             }
484         }
485         mCreatingRestrictedProfile = false;
486         refresh();
487     }
488 
489     private static class CreateRestrictedProfileTask extends AsyncTask<Void, Void, UserInfo> {
490         private final Context mContext;
491         private final UserManager mUserManager;
492 
CreateRestrictedProfileTask(Context context, UserManager userManager)493         CreateRestrictedProfileTask(Context context, UserManager userManager) {
494             mContext = context.getApplicationContext();
495             mUserManager = userManager;
496         }
497 
498         @Override
doInBackground(Void... params)499         protected UserInfo doInBackground(Void... params) {
500             UserInfo restrictedUserInfo = mUserManager.createProfileForUser(
501                     mContext.getString(R.string.user_new_profile_name),
502                     UserInfo.FLAG_RESTRICTED, UserHandle.myUserId());
503             if (restrictedUserInfo == null) {
504                 final UserInfo existingUserInfo = findRestrictedUser(mUserManager);
505                 if (existingUserInfo == null) {
506                     Log.wtf(TAG, "Got back a null user handle!");
507                 }
508                 return existingUserInfo;
509             }
510             int userId = restrictedUserInfo.id;
511             UserHandle user = new UserHandle(userId);
512             mUserManager.setUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS, true, user);
513             Bitmap bitmap = createBitmapFromDrawable(R.drawable.ic_avatar_default);
514             mUserManager.setUserIcon(userId, bitmap);
515             // Add shared accounts
516             AccountManager.get(mContext).addSharedAccountsFromParentUser(
517                     UserHandle.of(UserHandle.myUserId()), user);
518             return restrictedUserInfo;
519         }
520 
521         @Override
onPostExecute(UserInfo result)522         protected void onPostExecute(UserInfo result) {
523             sCreateRestrictedProfileTask = null;
524             if (result == null) {
525                 return;
526             }
527             UserSwitchListenerService.updateLaunchPoint(mContext, true);
528             LocalBroadcastManager.getInstance(mContext).sendBroadcast(
529                     new Intent(ACTION_RESTRICTED_PROFILE_CREATED)
530                             .putExtra(EXTRA_RESTRICTED_PROFILE_INFO, result));
531         }
532 
createBitmapFromDrawable(@rawableRes int resId)533         private Bitmap createBitmapFromDrawable(@DrawableRes int resId) {
534             Drawable icon = mContext.getDrawable(resId);
535             if (icon == null) {
536                 throw new IllegalArgumentException("Drawable is missing!");
537             }
538             icon.setBounds(0, 0, icon.getIntrinsicWidth(), icon.getIntrinsicHeight());
539             Bitmap bitmap = Bitmap.createBitmap(icon.getIntrinsicWidth(), icon.getIntrinsicHeight(),
540                     Bitmap.Config.ARGB_8888);
541             icon.draw(new Canvas(bitmap));
542             return bitmap;
543         }
544     }
545 }
546