1 /*
2  * Copyright (C) 2010 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.deviceadmin;
18 
19 import android.app.Activity;
20 import android.app.ActivityManager;
21 import android.app.AppOpsManager;
22 import android.app.Dialog;
23 import android.app.admin.DeviceAdminInfo;
24 import android.app.admin.DeviceAdminReceiver;
25 import android.app.admin.DevicePolicyManager;
26 import android.app.settings.SettingsEnums;
27 import android.content.ComponentName;
28 import android.content.DialogInterface;
29 import android.content.Intent;
30 import android.content.pm.ActivityInfo;
31 import android.content.pm.ApplicationInfo;
32 import android.content.pm.PackageInfo;
33 import android.content.pm.PackageManager;
34 import android.content.pm.PackageManager.NameNotFoundException;
35 import android.content.pm.ResolveInfo;
36 import android.content.pm.UserInfo;
37 import android.content.res.Resources;
38 import android.os.Binder;
39 import android.os.Bundle;
40 import android.os.Handler;
41 import android.os.IBinder;
42 import android.os.RemoteCallback;
43 import android.os.RemoteException;
44 import android.os.UserHandle;
45 import android.os.UserManager;
46 import android.text.TextUtils;
47 import android.util.EventLog;
48 import android.util.Log;
49 import android.view.View;
50 import android.view.ViewGroup;
51 import android.widget.AppSecurityPermissions;
52 import android.widget.Button;
53 import android.widget.ImageView;
54 import android.widget.TextView;
55 
56 import androidx.appcompat.app.AlertDialog;
57 import androidx.fragment.app.FragmentActivity;
58 
59 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
60 import com.android.settingslib.RestrictedLockUtilsInternal;
61 import com.android.tv.settings.EventLogTags;
62 import com.android.tv.settings.R;
63 
64 import org.xmlpull.v1.XmlPullParserException;
65 
66 import java.io.IOException;
67 import java.util.ArrayList;
68 import java.util.List;
69 import java.util.Optional;
70 
71 
72 public class DeviceAdminAdd extends FragmentActivity {
73     static final String TAG = "DeviceAdminAdd";
74 
75     static final int DIALOG_WARNING = 1;
76 
77     public static final String EXTRA_DEVICE_ADMIN_PACKAGE_NAME =
78             "android.app.extra.DEVICE_ADMIN_PACKAGE_NAME";
79 
80     public static final String EXTRA_CALLED_FROM_SUPPORT_DIALOG =
81             "android.app.extra.CALLED_FROM_SUPPORT_DIALOG";
82 
83     private final IBinder mToken = new Binder();
84 
85     DevicePolicyManager mDPM;
86     AppOpsManager mAppOps;
87     DeviceAdminInfo mDeviceAdmin;
88     String mProfileOwnerName;
89 
90     boolean mRefreshing;
91     boolean mAddingProfileOwner;
92     boolean mWaitingForRemoveMsg;
93     boolean mUninstalling = false;
94     boolean mAdding;
95     boolean mAdminPoliciesInitialized;
96 
97     ImageView mAdminIcon;
98     TextView mAdminName;
99     TextView mAdminDescription;
100     TextView mAddMsg;
101     TextView mProfileOwnerWarning;
102     ImageView mAddMsgExpander;
103     TextView mAdminWarning;
104     TextView mSupportMessage;
105     ViewGroup mAdminPolicies;
106     Button mActionButton;
107     Button mUninstallButton;
108     Button mCancelButton;
109 
110     Handler mHandler;
111 
112 
113     @Override
onCreate(Bundle icicle)114     protected void onCreate(Bundle icicle) {
115         super.onCreate(icicle);
116 
117         mDPM = getSystemService(DevicePolicyManager.class);
118         mAppOps = getSystemService(AppOpsManager.class);
119         PackageManager packageManager = getPackageManager();
120 
121         if ((getIntent().getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
122             Log.w(TAG, "Cannot start ADD_DEVICE_ADMIN as a new task");
123             finish();
124             return;
125         }
126 
127         String action = getIntent().getAction();
128         ComponentName who = (ComponentName)getIntent().getParcelableExtra(
129                 DevicePolicyManager.EXTRA_DEVICE_ADMIN);
130         if (who == null) {
131             String packageName = getIntent().getStringExtra(EXTRA_DEVICE_ADMIN_PACKAGE_NAME);
132             Optional<ComponentName> installedAdmin = findAdminWithPackageName(packageName);
133             if (!installedAdmin.isPresent()) {
134                 Log.w(TAG, "No component specified in " + action);
135                 finish();
136                 return;
137             }
138             who = installedAdmin.get();
139             mUninstalling = true;
140 
141             Log.d(TAG, "Uninstalling admin " + who);
142         }
143 
144         if (action != null && action.equals(DevicePolicyManager.ACTION_SET_PROFILE_OWNER)) {
145             setResult(RESULT_CANCELED);
146             setFinishOnTouchOutside(true);
147             mAddingProfileOwner = true;
148             mProfileOwnerName =
149                     getIntent().getStringExtra(DevicePolicyManager.EXTRA_PROFILE_OWNER_NAME);
150             String callingPackage = getCallingPackage();
151             if (callingPackage == null || !callingPackage.equals(who.getPackageName())) {
152                 Log.e(TAG, "Unknown or incorrect caller");
153                 finish();
154                 return;
155             }
156             try {
157                 PackageInfo packageInfo = packageManager.getPackageInfo(callingPackage, 0);
158                 if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
159                     Log.e(TAG, "Cannot set a non-system app as a profile owner");
160                     finish();
161                     return;
162                 }
163             } catch (NameNotFoundException nnfe) {
164                 Log.e(TAG, "Cannot find the package " + callingPackage);
165                 finish();
166                 return;
167             }
168         }
169 
170         ActivityInfo ai;
171         try {
172             ai = packageManager.getReceiverInfo(who, PackageManager.GET_META_DATA);
173         } catch (PackageManager.NameNotFoundException e) {
174             Log.w(TAG, "Unable to retrieve device policy " + who, e);
175             finish();
176             return;
177         }
178 
179         // When activating, make sure the given component name is actually a valid device admin.
180         // No need to check this when deactivating, because it is safe to deactivate an active
181         // invalid device admin.
182         if (!mDPM.isAdminActive(who)) {
183             List<ResolveInfo> avail = packageManager.queryBroadcastReceivers(
184                     new Intent(DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED),
185                     PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS);
186             int count = avail == null ? 0 : avail.size();
187             boolean found = false;
188             for (int i=0; i<count; i++) {
189                 ResolveInfo ri = avail.get(i);
190                 if (ai.packageName.equals(ri.activityInfo.packageName)
191                         && ai.name.equals(ri.activityInfo.name)) {
192                     try {
193                         // We didn't retrieve the meta data for all possible matches, so
194                         // need to use the activity info of this specific one that was retrieved.
195                         ri.activityInfo = ai;
196                         DeviceAdminInfo dpi = new DeviceAdminInfo(this, ri);
197                         found = true;
198                     } catch (XmlPullParserException e) {
199                         Log.w(TAG, "Bad " + ri.activityInfo, e);
200                     } catch (IOException e) {
201                         Log.w(TAG, "Bad " + ri.activityInfo, e);
202                     }
203                     break;
204                 }
205             }
206             if (!found) {
207                 Log.w(TAG, "Request to add invalid device admin: " + who);
208                 finish();
209                 return;
210             }
211         }
212 
213         ResolveInfo ri = new ResolveInfo();
214         ri.activityInfo = ai;
215         try {
216             mDeviceAdmin = new DeviceAdminInfo(this, ri);
217         } catch (XmlPullParserException e) {
218             Log.w(TAG, "Unable to retrieve device policy " + who, e);
219             finish();
220             return;
221         } catch (IOException e) {
222             Log.w(TAG, "Unable to retrieve device policy " + who, e);
223             finish();
224             return;
225         }
226 
227         // This admin already exists, an we have two options at this point.  If new policy
228         // bits are set, show the user the new list.  If nothing has changed, simply return
229         // "OK" immediately.
230         if (DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN.equals(getIntent().getAction())) {
231             mRefreshing = false;
232             if (mDPM.isAdminActive(who)) {
233                 if (mDPM.isRemovingAdmin(who, android.os.Process.myUserHandle().getIdentifier())) {
234                     Log.w(TAG, "Requested admin is already being removed: " + who);
235                     finish();
236                     return;
237                 }
238 
239                 ArrayList<DeviceAdminInfo.PolicyInfo> newPolicies = mDeviceAdmin.getUsedPolicies();
240                 for (int i = 0; i < newPolicies.size(); i++) {
241                     DeviceAdminInfo.PolicyInfo pi = newPolicies.get(i);
242                     if (!mDPM.hasGrantedPolicy(who, pi.ident)) {
243                         mRefreshing = true;
244                         break;
245                     }
246                 }
247                 if (!mRefreshing) {
248                     // Nothing changed (or policies were removed) - return immediately
249                     setResult(Activity.RESULT_OK);
250                     finish();
251                     return;
252                 }
253             }
254         }
255 
256         if (mAddingProfileOwner) {
257             // If we're trying to add a profile owner and user setup hasn't completed yet, no
258             // need to prompt for permission. Just add and finish
259             if (!mDPM.hasUserSetupCompleted()) {
260                 addAndFinish();
261                 return;
262             }
263 
264             // othewise, only the defined default supervision profile owner can be set after user
265             // setup.
266             final String supervisor = getString(
267                     com.android.internal.R.string.config_defaultSupervisionProfileOwnerComponent);
268             if (supervisor == null) {
269                 Log.w(TAG, "Unable to set profile owner post-setup, no default supervisor"
270                         + "profile owner defined");
271                 finish();
272                 return;
273             }
274 
275             final ComponentName supervisorComponent = ComponentName.unflattenFromString(
276                     supervisor);
277             if (who.compareTo(supervisorComponent) != 0) {
278                 Log.w(TAG, "Unable to set non-default profile owner post-setup " + who);
279                 finish();
280                 return;
281             } else {
282                 addAndFinish();
283             }
284         }
285 
286         // Create UI for device admin config (CtsVerifier mostly)
287         createAddDeviceAdminUi();
288     }
289 
addAndFinish()290     void addAndFinish() {
291         try {
292             logSpecialPermissionChange(true, mDeviceAdmin.getComponent().getPackageName());
293             mDPM.setActiveAdmin(mDeviceAdmin.getComponent(), mRefreshing);
294             EventLog.writeEvent(EventLogTags.EXP_DET_DEVICE_ADMIN_ACTIVATED_BY_USER,
295                 mDeviceAdmin.getActivityInfo().applicationInfo.uid);
296 
297             setResult(Activity.RESULT_OK);
298         } catch (RuntimeException e) {
299             // Something bad happened...  could be that it was
300             // already set, though.
301             Log.w(TAG, "Exception trying to activate admin "
302                     + mDeviceAdmin.getComponent(), e);
303             if (mDPM.isAdminActive(mDeviceAdmin.getComponent())) {
304                 setResult(Activity.RESULT_OK);
305             }
306         }
307         if (mAddingProfileOwner) {
308             try {
309                 mDPM.setProfileOwner(mDeviceAdmin.getComponent(),
310                         mProfileOwnerName, UserHandle.myUserId());
311             } catch (RuntimeException re) {
312                 setResult(Activity.RESULT_CANCELED);
313             }
314         }
315         finish();
316     }
317 
logSpecialPermissionChange(boolean allow, String packageName)318     void logSpecialPermissionChange(boolean allow, String packageName) {
319         int logCategory = allow ? SettingsEnums.APP_SPECIAL_PERMISSION_ADMIN_ALLOW :
320                 SettingsEnums.APP_SPECIAL_PERMISSION_ADMIN_DENY;
321     }
322 
323     @Override
onResume()324     protected void onResume() {
325         super.onResume();
326         mActionButton.setEnabled(true);
327         if (!mAddingProfileOwner) {
328             updateInterface();
329         }
330         // As long as we are running, don't let anyone overlay stuff on top of the screen.
331         mAppOps.setUserRestriction(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, true, mToken);
332         mAppOps.setUserRestriction(AppOpsManager.OP_TOAST_WINDOW, true, mToken);
333     }
334 
335     @Override
onPause()336     protected void onPause() {
337         super.onPause();
338         // This just greys out the button. The actual listener is attached to R.id.restricted_action
339         mActionButton.setEnabled(false);
340         mAppOps.setUserRestriction(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, false, mToken);
341         mAppOps.setUserRestriction(AppOpsManager.OP_TOAST_WINDOW, false, mToken);
342         try {
343             ActivityManager.getService().resumeAppSwitches();
344         } catch (RemoteException e) {
345         }
346     }
347 
348 
349      /**
350      * @return an {@link Optional} containing the admin with a given package name, if it exists,
351      *         or {@link Optional#empty()} otherwise.
352      */
findAdminWithPackageName(String packageName)353     private Optional<ComponentName> findAdminWithPackageName(String packageName) {
354         List<ComponentName> admins = mDPM.getActiveAdmins();
355         if (admins == null) {
356             return Optional.empty();
357         }
358         return admins.stream().filter(i -> i.getPackageName().equals(packageName)).findAny();
359     }
360 
isAdminUninstallable()361     private boolean isAdminUninstallable() {
362         // System apps can't be uninstalled.
363         return !mDeviceAdmin.getActivityInfo().applicationInfo.isSystemApp();
364     }
365 
createAddDeviceAdminUi()366     private void createAddDeviceAdminUi() {
367         setContentView(R.layout.device_admin_add);
368 
369         mAdminIcon = (ImageView) findViewById(R.id.admin_icon);
370         mAdminName = (TextView) findViewById(R.id.admin_name);
371         mAdminDescription = (TextView) findViewById(R.id.admin_description);
372         mProfileOwnerWarning = (TextView) findViewById(R.id.profile_owner_warning);
373 
374         mAddMsg = (TextView) findViewById(R.id.add_msg);
375         mAddMsgExpander = (ImageView) findViewById(R.id.add_msg_expander);
376 
377 
378         mAdminWarning = (TextView) findViewById(R.id.admin_warning);
379         mAdminPolicies = (ViewGroup) findViewById(R.id.admin_policies);
380         mSupportMessage = (TextView) findViewById(R.id.admin_support_message);
381 
382         mCancelButton = (Button) findViewById(R.id.cancel_button);
383         mCancelButton.setFilterTouchesWhenObscured(true);
384         mCancelButton.setOnClickListener(new View.OnClickListener() {
385             public void onClick(View v) {
386                 EventLog.writeEvent(EventLogTags.EXP_DET_DEVICE_ADMIN_DECLINED_BY_USER,
387                         mDeviceAdmin.getActivityInfo().applicationInfo.uid);
388                 finish();
389             }
390         });
391 
392         mUninstallButton = (Button) findViewById(R.id.uninstall_button);
393         mUninstallButton.setFilterTouchesWhenObscured(true);
394         mUninstallButton.setOnClickListener(new View.OnClickListener() {
395             public void onClick(View v) {
396                 EventLog.writeEvent(EventLogTags.EXP_DET_DEVICE_ADMIN_UNINSTALLED_BY_USER,
397                         mDeviceAdmin.getActivityInfo().applicationInfo.uid);
398                 mDPM.uninstallPackageWithActiveAdmins(mDeviceAdmin.getPackageName());
399                 finish();
400             }
401         });
402 
403         mActionButton = (Button) findViewById(R.id.action_button);
404 
405         final View restrictedAction = findViewById(R.id.restricted_action);
406         restrictedAction.setFilterTouchesWhenObscured(true);
407         restrictedAction.setOnClickListener(new View.OnClickListener() {
408             public void onClick(View v) {
409                 if (!mActionButton.isEnabled()) {
410                     return;
411                 }
412                 if (mAdding) {
413                     addAndFinish();
414                 } else if (mUninstalling) {
415                     mDPM.uninstallPackageWithActiveAdmins(mDeviceAdmin.getPackageName());
416                     finish();
417                 } else if (!mWaitingForRemoveMsg) {
418                     try {
419                         // Don't allow the admin to put a dialog up in front
420                         // of us while we interact with the user.
421                         ActivityManager.getService().stopAppSwitches();
422                     } catch (RemoteException e) {
423                     }
424                     mWaitingForRemoveMsg = true;
425                     mDPM.getRemoveWarning(mDeviceAdmin.getComponent(),
426                             new RemoteCallback(new RemoteCallback.OnResultListener() {
427                                 @Override
428                                 public void onResult(Bundle result) {
429                                     CharSequence msg = result != null
430                                             ? result.getCharSequence(
431                                             DeviceAdminReceiver.EXTRA_DISABLE_WARNING)
432                                             : null;
433                                     continueRemoveAction(msg);
434                                 }
435                             }, mHandler));
436                     // Don't want to wait too long.
437                     getWindow().getDecorView().getHandler().postDelayed(new Runnable() {
438                         @Override public void run() {
439                             continueRemoveAction(null);
440                         }
441                     }, 2 * 1000);
442                 }
443             }
444         });
445     }
446 
updateInterface()447     void updateInterface() {
448         findViewById(R.id.restricted_icon).setVisibility(View.GONE);
449         mAdminIcon.setImageDrawable(mDeviceAdmin.loadIcon(getPackageManager()));
450         mAdminName.setText(mDeviceAdmin.loadLabel(getPackageManager()));
451         try {
452             mAdminDescription.setText(
453                     mDeviceAdmin.loadDescription(getPackageManager()));
454             mAdminDescription.setVisibility(View.VISIBLE);
455         } catch (Resources.NotFoundException e) {
456             mAdminDescription.setVisibility(View.GONE);
457         }
458         String mAddMsgText = null;
459         if (mAddMsgText != null) {
460             mAddMsg.setText(mAddMsgText);
461             mAddMsg.setVisibility(View.VISIBLE);
462         } else {
463             mAddMsg.setVisibility(View.GONE);
464             mAddMsgExpander.setVisibility(View.GONE);
465         }
466         if (!mRefreshing && !mAddingProfileOwner
467                 && mDPM.isAdminActive(mDeviceAdmin.getComponent())) {
468             mAdding = false;
469             final boolean isProfileOwner =
470                     mDeviceAdmin.getComponent().equals(mDPM.getProfileOwner());
471             final boolean isManagedProfile = isManagedProfile(mDeviceAdmin);
472             if (isProfileOwner && isManagedProfile) {
473                 // Profile owner in a managed profile, user can remove profile to disable admin.
474                 mAdminWarning.setText(R.string.admin_profile_owner_message);
475                 mActionButton.setText(R.string.remove_managed_profile_label);
476 
477                 final EnforcedAdmin admin = getAdminEnforcingCantRemoveProfile();
478                 final boolean hasBaseRestriction = hasBaseCantRemoveProfileRestriction();
479                 if ((hasBaseRestriction && mDPM.isOrganizationOwnedDeviceWithManagedProfile())
480                         || (admin != null && !hasBaseRestriction)) {
481                     findViewById(R.id.restricted_icon).setVisibility(View.VISIBLE);
482                 }
483                 mActionButton.setEnabled(admin == null && !hasBaseRestriction);
484             } else if (isProfileOwner || mDeviceAdmin.getComponent().equals(
485                             mDPM.getDeviceOwnerComponentOnCallingUser())) {
486                 // Profile owner in a user or device owner, user can't disable admin.
487                 if (isProfileOwner) {
488                     // Show profile owner in a user description.
489                     mAdminWarning.setText(R.string.admin_profile_owner_user_message);
490                 } else {
491                     // Show device owner description.
492                     mAdminWarning.setText(R.string.admin_device_owner_message);
493                 }
494                 mActionButton.setText(R.string.remove_device_admin);
495                 mActionButton.setEnabled(false);
496             } else {
497                 addDeviceAdminPolicies(false /* showDescription */);
498                 mAdminWarning.setText(getString(R.string.device_admin_status,
499                         mDeviceAdmin.getActivityInfo().applicationInfo.loadLabel(
500                         getPackageManager())));
501                 setTitle(R.string.active_device_admin_msg);
502                 if (mUninstalling) {
503                     mActionButton.setText(R.string.remove_and_uninstall_device_admin);
504                 } else {
505                     mActionButton.setText(R.string.remove_device_admin);
506                 }
507             }
508             CharSequence supportMessage = mDPM.getLongSupportMessageForUser(
509                     mDeviceAdmin.getComponent(), UserHandle.myUserId());
510             if (!TextUtils.isEmpty(supportMessage)) {
511                 mSupportMessage.setText(supportMessage);
512                 mSupportMessage.setVisibility(View.VISIBLE);
513             } else {
514                 mSupportMessage.setVisibility(View.GONE);
515             }
516         } else {
517             addDeviceAdminPolicies(true /* showDescription */);
518             mAdminWarning.setText(getString(R.string.device_admin_warning,
519                     mDeviceAdmin.getActivityInfo().applicationInfo.loadLabel(getPackageManager())));
520             setTitle(R.string.add_device_admin_msg);
521             mActionButton.setText(R.string.add_device_admin);
522             if (isAdminUninstallable()) {
523                 mUninstallButton.setVisibility(View.VISIBLE);
524             }
525             mSupportMessage.setVisibility(View.GONE);
526             mAdding = true;
527         }
528     }
529 
continueRemoveAction(CharSequence msg)530     void continueRemoveAction(CharSequence msg) {
531         if (!mWaitingForRemoveMsg) {
532             return;
533         }
534         mWaitingForRemoveMsg = false;
535         if (msg == null) {
536             try {
537                 ActivityManager.getService().resumeAppSwitches();
538             } catch (RemoteException e) {
539             }
540             logSpecialPermissionChange(false, mDeviceAdmin.getComponent().getPackageName());
541             mDPM.removeActiveAdmin(mDeviceAdmin.getComponent());
542             finish();
543         } else {
544             try {
545                 // Continue preventing anything from coming in front.
546                 ActivityManager.getService().stopAppSwitches();
547             } catch (RemoteException e) {
548             }
549             Bundle args = new Bundle();
550             args.putCharSequence(
551                     DeviceAdminReceiver.EXTRA_DISABLE_WARNING, msg);
552             showDialog(DIALOG_WARNING, args);
553         }
554     }
555 
addDeviceAdminPolicies(boolean showDescription)556     private void addDeviceAdminPolicies(boolean showDescription) {
557         if (!mAdminPoliciesInitialized) {
558             boolean isAdminUser = UserManager.get(this).isAdminUser();
559             for (DeviceAdminInfo.PolicyInfo pi : mDeviceAdmin.getUsedPolicies()) {
560                 int descriptionId = isAdminUser ? pi.description : pi.descriptionForSecondaryUsers;
561                 int labelId = isAdminUser ? pi.label : pi.labelForSecondaryUsers;
562                 View view = AppSecurityPermissions.getPermissionItemView(this, getText(labelId),
563                         showDescription ? getText(descriptionId) : "", true);
564                 mAdminPolicies.addView(view);
565             }
566             mAdminPoliciesInitialized = true;
567         }
568     }
569 
570     @Override
onCreateDialog(int id, Bundle args)571     protected Dialog onCreateDialog(int id, Bundle args) {
572         switch (id) {
573             case DIALOG_WARNING: {
574                 CharSequence msg = args.getCharSequence(DeviceAdminReceiver.EXTRA_DISABLE_WARNING);
575                 AlertDialog.Builder builder = new AlertDialog.Builder(this);
576                 builder.setMessage(msg);
577                 builder.setPositiveButton(R.string.settings_ok,
578                         new DialogInterface.OnClickListener() {
579                             public void onClick(DialogInterface dialog, int which) {
580                             try {
581                                 ActivityManager.getService().resumeAppSwitches();
582                             } catch (RemoteException e) {
583                             }
584                             mDPM.removeActiveAdmin(mDeviceAdmin.getComponent());
585                             finish();
586                         }
587                     });
588                 builder.setNegativeButton(R.string.settings_cancel, null);
589                 return builder.create();
590             }
591             default:
592                 return super.onCreateDialog(id, args);
593 
594         }
595     }
596 
597     /**
598      * @return true if adminInfo is running in a managed profile.
599      */
isManagedProfile(DeviceAdminInfo adminInfo)600     private boolean isManagedProfile(DeviceAdminInfo adminInfo) {
601         UserManager um = UserManager.get(this);
602         UserInfo info = um.getUserInfo(
603                 UserHandle.getUserId(adminInfo.getActivityInfo().applicationInfo.uid));
604         return info != null ? info.isManagedProfile() : false;
605     }
606 
getAdminEnforcingCantRemoveProfile()607     private EnforcedAdmin getAdminEnforcingCantRemoveProfile() {
608         // Removing a managed profile is disallowed if DISALLOW_REMOVE_MANAGED_PROFILE
609         // is set in the parent rather than the user itself.
610         return RestrictedLockUtilsInternal.checkIfRestrictionEnforced(this,
611                 UserManager.DISALLOW_REMOVE_MANAGED_PROFILE, getParentUserId());
612     }
613 
hasBaseCantRemoveProfileRestriction()614     private boolean hasBaseCantRemoveProfileRestriction() {
615         return RestrictedLockUtilsInternal.hasBaseUserRestriction(this,
616                 UserManager.DISALLOW_REMOVE_MANAGED_PROFILE, getParentUserId());
617     }
618 
getParentUserId()619     private int getParentUserId() {
620         return UserManager.get(this).getProfileParent(UserHandle.myUserId()).id;
621     }
622 }
623