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