• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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.car.settings.enterprise;
18 
19 import android.annotation.Nullable;
20 import android.annotation.UserIdInt;
21 import android.app.Dialog;
22 import android.app.admin.DevicePolicyManager;
23 import android.content.ComponentName;
24 import android.content.Context;
25 import android.content.pm.ApplicationInfo;
26 import android.content.pm.PackageManager;
27 import android.graphics.drawable.Drawable;
28 import android.os.Bundle;
29 import android.os.Process;
30 import android.os.UserHandle;
31 import android.util.IconDrawableFactory;
32 
33 import com.android.car.settings.R;
34 import com.android.car.settings.common.Logger;
35 import com.android.car.ui.AlertDialogBuilder;
36 import com.android.car.ui.preference.CarUiDialogFragment;
37 import com.android.settingslib.RestrictedLockUtils;
38 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
39 import com.android.settingslib.RestrictedLockUtilsInternal;
40 import com.android.settingslib.enterprise.ActionDisabledByAdminController;
41 import com.android.settingslib.enterprise.ActionDisabledByAdminControllerFactory;
42 
43 /**
44  * Shows a dialog explaining that an action is not enabled due to restrictions imposed by an active
45  * device administrator.
46  */
47 // TODO(b/186905050): add unit tests
48 // TODO(b/188836559): move most of this class' logic to settingslib
49 public final class ActionDisabledByAdminDialogFragment extends CarUiDialogFragment {
50 
51     public static final String DISABLED_BY_ADMIN_CONFIRM_DIALOG_TAG =
52             "com.android.car.settings.applications.DisabledByAdminConfirmDialog";
53 
54     private static final String TAG = ActionDisabledByAdminDialogFragment.class.getSimpleName();
55     private static final Logger LOG = new Logger(TAG);
56 
57     private static final String EXTRA_RESTRICTION = TAG + "_restriction";
58     private static final String EXTRA_USER_ID = TAG + "_userId";
59 
60     private String mRestriction;
61 
62     @UserIdInt
63     private int mUserId;
64 
65     private ActionDisabledByAdminController mActionDisabledByAdminController;
66 
67     /**
68      * Gets the dialog for the given user and restriction.
69      */
newInstance(String restriction, @UserIdInt int userId)70     public static ActionDisabledByAdminDialogFragment newInstance(String restriction,
71             @UserIdInt int userId) {
72         ActionDisabledByAdminDialogFragment instance = new ActionDisabledByAdminDialogFragment();
73         instance.mRestriction = restriction;
74         instance.mUserId = userId;
75         return instance;
76     }
77 
78     @Override
onCreateDialog(Bundle savedInstanceState)79     public Dialog onCreateDialog(Bundle savedInstanceState) {
80         if (savedInstanceState != null) {
81             mRestriction = savedInstanceState.getString(EXTRA_RESTRICTION);
82             mUserId = savedInstanceState.getInt(EXTRA_USER_ID);
83         }
84         return initialize(getContext()).create();
85     }
86 
87     @Override
onSaveInstanceState(Bundle outState)88     public void onSaveInstanceState(Bundle outState) {
89         super.onSaveInstanceState(outState);
90 
91         outState.putString(EXTRA_RESTRICTION, mRestriction);
92         outState.putInt(EXTRA_USER_ID, mUserId);
93     }
94 
95     @Override
onDialogClosed(boolean positiveResult)96     protected void onDialogClosed(boolean positiveResult) {
97     }
98 
initialize(Context context)99     private AlertDialogBuilder initialize(Context context) {
100         EnforcedAdmin enforcedAdmin = RestrictedLockUtilsInternal
101                 .checkIfRestrictionEnforced(context, mRestriction, mUserId);
102 
103         AlertDialogBuilder builder = new AlertDialogBuilder(context)
104                 .setPositiveButton(R.string.okay, /* listener= */ null);
105         mActionDisabledByAdminController = ActionDisabledByAdminControllerFactory
106                 .createInstance(context, mRestriction, new DeviceAdminStringProviderImpl(context),
107                         context.getUser());
108         mActionDisabledByAdminController.initialize(
109                 new ActionDisabledLearnMoreButtonLauncherImpl(builder));
110         if (enforcedAdmin != null) {
111             mActionDisabledByAdminController.updateEnforcedAdmin(enforcedAdmin, mUserId);
112             mActionDisabledByAdminController.setupLearnMoreButton(context);
113         }
114         initializeDialogViews(context, builder, enforcedAdmin,
115                 getEnforcementAdminUserId(enforcedAdmin));
116         return builder;
117     }
118 
119     // NOTE: methods below were copied from phone Settings
120     // (com.android.settings.enterprise.ActionDisabledByAdminDialogHelper), but adjusted to
121     // use a AlertDialogBuilder directly, instead of an Activity hosting a dialog.
122 
getEnforcementAdminUserId(@ullable EnforcedAdmin admin)123     private static @UserIdInt int getEnforcementAdminUserId(@Nullable EnforcedAdmin admin) {
124         return admin == null || admin.user == null ? UserHandle.USER_NULL
125                 : admin.user.getIdentifier();
126     }
127 
initializeDialogViews(Context context, AlertDialogBuilder builder, @Nullable EnforcedAdmin enforcedAdmin, @UserIdInt int userId)128     private void initializeDialogViews(Context context, AlertDialogBuilder builder,
129             @Nullable EnforcedAdmin enforcedAdmin, @UserIdInt int userId) {
130         ComponentName admin = null;
131 
132         if (enforcedAdmin != null) {
133             admin = enforcedAdmin.component;
134             if (admin == null) {
135                 return;
136             }
137 
138             mActionDisabledByAdminController.updateEnforcedAdmin(enforcedAdmin, userId);
139         }
140 
141         if (isNotCurrentUserOrProfile(context, admin, userId)) {
142             admin = null;
143         }
144         setAdminSupportIcon(context, builder, admin, userId);
145         setAdminSupportTitle(context, builder, mRestriction);
146 
147         if (enforcedAdmin != null) {
148             setAdminSupportDetails(context, builder, enforcedAdmin);
149         }
150     }
151 
isNotCurrentUserOrProfile(Context context, ComponentName admin, @UserIdInt int userId)152     private boolean isNotCurrentUserOrProfile(Context context, ComponentName admin,
153             @UserIdInt int userId) {
154         return !RestrictedLockUtilsInternal.isAdminInCurrentUserOrProfile(context, admin)
155                 || !RestrictedLockUtils.isCurrentUserOrProfile(context, userId);
156     }
157 
setAdminSupportIcon(Context context, AlertDialogBuilder builder, ComponentName admin, @UserIdInt int userId)158     private void setAdminSupportIcon(Context context, AlertDialogBuilder builder,
159             ComponentName admin, @UserIdInt int userId) {
160         if (isNotCurrentUserOrProfile(context, admin, userId)) {
161             builder.setIcon(context.getDrawable(com.android.internal.R.drawable.ic_info));
162         } else {
163             Drawable badgedIcon = getBadgedIcon(
164                     IconDrawableFactory.newInstance(context),
165                     context.getPackageManager(),
166                     admin.getPackageName(),
167                     userId);
168             builder.setIcon(badgedIcon);
169         }
170     }
171 
setAdminSupportTitle(Context context, AlertDialogBuilder builder, String restriction)172     private void setAdminSupportTitle(Context context, AlertDialogBuilder builder,
173             String restriction) {
174         builder.setTitle(mActionDisabledByAdminController.getAdminSupportTitle(restriction));
175     }
176 
setAdminSupportDetails(Context context, AlertDialogBuilder builder, @Nullable EnforcedAdmin enforcedAdmin)177     private void setAdminSupportDetails(Context context, AlertDialogBuilder builder,
178             @Nullable EnforcedAdmin enforcedAdmin) {
179         if (enforcedAdmin == null || enforcedAdmin.component == null) {
180             LOG.i("setAdminSupportDetails(): no admin on " + enforcedAdmin);
181             return;
182         }
183         CharSequence supportMessage = null;
184         if (!RestrictedLockUtilsInternal.isAdminInCurrentUserOrProfile(context,
185                 enforcedAdmin.component) || !RestrictedLockUtils.isCurrentUserOrProfile(
186                         context, getEnforcementAdminUserId(enforcedAdmin))) {
187             enforcedAdmin.component = null;
188         } else {
189             if (enforcedAdmin.user == null) {
190                 enforcedAdmin.user = UserHandle.of(UserHandle.myUserId());
191             }
192             if (UserHandle.isSameApp(Process.myUid(), Process.SYSTEM_UID)) {
193                 supportMessage = context.getSystemService(DevicePolicyManager.class)
194                         .getShortSupportMessageForUser(enforcedAdmin.component,
195                                 getEnforcementAdminUserId(enforcedAdmin));
196             }
197         }
198         CharSequence supportContentString =
199                 mActionDisabledByAdminController.getAdminSupportContentString(
200                         context, supportMessage);
201         if (supportContentString != null) {
202             builder.setMessage(supportContentString);
203         }
204     }
205 
206     // Copied from com.android.settings.Utils
getBadgedIcon(IconDrawableFactory iconDrawableFactory, PackageManager packageManager, String packageName, int userId)207     private static Drawable getBadgedIcon(IconDrawableFactory iconDrawableFactory,
208             PackageManager packageManager, String packageName, int userId) {
209         try {
210             ApplicationInfo appInfo = packageManager.getApplicationInfoAsUser(
211                     packageName, PackageManager.GET_META_DATA, userId);
212             return iconDrawableFactory.getBadgedIcon(appInfo, userId);
213         } catch (PackageManager.NameNotFoundException e) {
214             return packageManager.getDefaultActivityIcon();
215         }
216     }
217 }
218