Home | History | Annotate | Download | only in system
      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 
    129     public static SecurityFragment newInstance() {
    130         return new SecurityFragment();
    131     }
    132 
    133     @Override
    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
    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
    157     public void onPause() {
    158         super.onPause();
    159         LocalBroadcastManager.getInstance(getActivity())
    160                 .unregisterReceiver(mRestrictedProfileReceiver);
    161     }
    162 
    163     @Override
    164     public void onSaveInstanceState(Bundle outState) {
    165         super.onSaveInstanceState(outState);
    166         outState.putBoolean(SAVESTATE_CREATING_RESTRICTED_PROFILE, mCreatingRestrictedProfile);
    167     }
    168 
    169     @Override
    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 
    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
    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 
    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 
    289     private boolean isVerifyAppsEnabled() {
    290         return Settings.Global.getInt(getContext().getContentResolver(),
    291                 Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) > 0 && isVerifierInstalled();
    292     }
    293 
    294     private void setVerifyAppsEnabled(boolean enable) {
    295         Settings.Global.putInt(getContext().getContentResolver(),
    296                 Settings.Global.PACKAGE_VERIFIER_ENABLE, enable ? 1 : 0);
    297     }
    298 
    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 
    308     private boolean shouldShowVerifierSetting() {
    309         return Settings.Global.getInt(getContext().getContentResolver(),
    310                 Settings.Global.PACKAGE_VERIFIER_SETTING_VISIBLE, 1) > 0;
    311     }
    312 
    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
    342     public void saveLockPassword(String pin, int quality) {
    343         new LockPatternUtils(getActivity()).saveLockPassword(pin, null, quality,
    344                 UserHandle.myUserId());
    345     }
    346 
    347     @Override
    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
    360     public boolean hasLockscreenSecurity() {
    361         return hasLockscreenSecurity(new LockPatternUtils(getActivity()));
    362     }
    363 
    364     private ILockSettings getLockSettings() {
    365         if (mLockSettingsService == null) {
    366             mLockSettingsService = ILockSettings.Stub.asInterface(
    367                     ServiceManager.getService("lock_settings"));
    368         }
    369         return mLockSettingsService;
    370     }
    371 
    372     private static boolean hasLockscreenSecurity(LockPatternUtils lpu) {
    373         return lpu.isLockPasswordEnabled(UserHandle.myUserId())
    374                 || lpu.isLockPatternEnabled(UserHandle.myUserId());
    375     }
    376 
    377     @Override
    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 
    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 
    419     private UserInfo getRestrictedUser() {
    420         if (mRestrictedUserInfo == null) {
    421             mRestrictedUserInfo = findRestrictedUser(mUserManager);
    422         }
    423         return mRestrictedUserInfo;
    424     }
    425 
    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 
    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 
    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 
    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 
    465     private static boolean isRestrictedProfileInEffect(UserManager userManager) {
    466         UserInfo userInfo = userManager.getUserInfo(UserHandle.myUserId());
    467         return userInfo.isRestricted();
    468     }
    469 
    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 
    493         CreateRestrictedProfileTask(Context context, UserManager userManager) {
    494             mContext = context.getApplicationContext();
    495             mUserManager = userManager;
    496         }
    497 
    498         @Override
    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
    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 
    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