1 /* 2 * Copyright (C) 2018 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; 18 19 import android.annotation.NonNull; 20 import android.annotation.UserIdInt; 21 import android.app.Activity; 22 import android.app.AlertDialog; 23 import android.app.admin.DevicePolicyManager; 24 import android.content.ComponentName; 25 import android.content.Context; 26 import android.content.Intent; 27 import android.os.Process; 28 import android.os.UserHandle; 29 import android.os.UserManager; 30 import android.view.LayoutInflater; 31 import android.view.View; 32 import android.view.ViewGroup; 33 import android.widget.TextView; 34 35 import androidx.annotation.VisibleForTesting; 36 37 import com.android.settingslib.RestrictedLockUtils; 38 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; 39 import com.android.settingslib.RestrictedLockUtilsInternal; 40 import com.android.tv.settings.deviceadmin.DeviceAdminAdd; 41 42 import java.util.Objects; 43 44 /** 45 * Helper class for {@link ActionDisabledByAdminDialog} which sets up the dialog. 46 */ 47 public class ActionDisabledByAdminDialogHelper { 48 49 private static final String TAG = ActionDisabledByAdminDialogHelper.class.getName(); 50 @VisibleForTesting EnforcedAdmin mEnforcedAdmin; 51 private ViewGroup mDialogView; 52 private String mRestriction = null; 53 private Activity mActivity; 54 ActionDisabledByAdminDialogHelper(Activity activity)55 public ActionDisabledByAdminDialogHelper(Activity activity) { 56 mActivity = activity; 57 } 58 getEnforcementAdminUserId(@onNull EnforcedAdmin admin)59 private @UserIdInt int getEnforcementAdminUserId(@NonNull EnforcedAdmin admin) { 60 if (admin.user == null) { 61 return UserHandle.USER_NULL; 62 } else { 63 return admin.user.getIdentifier(); 64 } 65 } 66 getEnforcementAdminUserId()67 private @UserIdInt int getEnforcementAdminUserId() { 68 return getEnforcementAdminUserId(mEnforcedAdmin); 69 } 70 prepareDialogBuilder(String restriction, EnforcedAdmin enforcedAdmin)71 public AlertDialog.Builder prepareDialogBuilder(String restriction, 72 EnforcedAdmin enforcedAdmin) { 73 mEnforcedAdmin = enforcedAdmin; 74 mRestriction = restriction; 75 final AlertDialog.Builder builder = new AlertDialog.Builder(mActivity); 76 mDialogView = (ViewGroup) LayoutInflater.from(builder.getContext()).inflate( 77 R.layout.admin_support_details_dialog, null); 78 initializeDialogViews(mDialogView, mEnforcedAdmin.component, getEnforcementAdminUserId(), 79 mRestriction); 80 builder.setPositiveButton(R.string.okay, null).setView(mDialogView); 81 maybeSetLearnMoreButton(builder); 82 return builder; 83 } 84 maybeSetLearnMoreButton(AlertDialog.Builder builder)85 void maybeSetLearnMoreButton(AlertDialog.Builder builder) { 86 // The "Learn more" button appears only if the restriction is enforced by an admin in the 87 // same profile group. Otherwise the admin package and its policies are not accessible to 88 // the current user. 89 final UserManager um = UserManager.get(mActivity.getApplicationContext()); 90 if (um.isSameProfileGroup( 91 getEnforcementAdminUserId(mEnforcedAdmin), 92 um.getProcessUserId())) { 93 builder.setNeutralButton(R.string.learn_more, (dialog, which) -> { 94 showAdminPolicies(mEnforcedAdmin, mActivity); 95 mActivity.finish(); 96 }); 97 } 98 } 99 updateDialog(String restriction, EnforcedAdmin admin)100 public void updateDialog(String restriction, EnforcedAdmin admin) { 101 if (mEnforcedAdmin.equals(admin) && Objects.equals(mRestriction, restriction)) { 102 return; 103 } 104 mEnforcedAdmin = admin; 105 mRestriction = restriction; 106 initializeDialogViews(mDialogView, mEnforcedAdmin.component, getEnforcementAdminUserId(), 107 mRestriction); 108 } 109 initializeDialogViews(View root, ComponentName admin, int userId, String restriction)110 private void initializeDialogViews(View root, ComponentName admin, int userId, 111 String restriction) { 112 if (admin == null) { 113 return; 114 } 115 116 setAdminSupportTitle(root, restriction); 117 118 final UserHandle user; 119 if (userId == UserHandle.USER_NULL) { 120 user = null; 121 } else { 122 user = UserHandle.of(userId); 123 } 124 125 setAdminSupportDetails(mActivity, root, new EnforcedAdmin(admin, user)); 126 } 127 128 @VisibleForTesting setAdminSupportTitle(View root, String restriction)129 void setAdminSupportTitle(View root, String restriction) { 130 final TextView titleView = root.findViewById(R.id.admin_support_dialog_title); 131 if (titleView == null) { 132 return; 133 } 134 if (restriction == null) { 135 titleView.setText(R.string.disabled_by_policy_title); 136 return; 137 } 138 switch (restriction) { 139 case UserManager.DISALLOW_ADJUST_VOLUME: 140 titleView.setText(R.string.disabled_by_policy_title_adjust_volume); 141 break; 142 case UserManager.DISALLOW_OUTGOING_CALLS: 143 titleView.setText(R.string.disabled_by_policy_title_outgoing_calls); 144 break; 145 case UserManager.DISALLOW_SMS: 146 titleView.setText(R.string.disabled_by_policy_title_sms); 147 break; 148 case DevicePolicyManager.POLICY_DISABLE_CAMERA: 149 titleView.setText(R.string.disabled_by_policy_title_camera); 150 break; 151 case DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE: 152 titleView.setText(R.string.disabled_by_policy_title_screen_capture); 153 break; 154 case DevicePolicyManager.POLICY_SUSPEND_PACKAGES: 155 titleView.setText(R.string.disabled_by_policy_title_suspend_packages); 156 break; 157 default: 158 // Use general text if no specialized title applies 159 titleView.setText(R.string.disabled_by_policy_title); 160 } 161 } 162 163 @VisibleForTesting setAdminSupportDetails(final Activity activity, final View root, final EnforcedAdmin enforcedAdmin)164 void setAdminSupportDetails(final Activity activity, final View root, 165 final EnforcedAdmin enforcedAdmin) { 166 if (enforcedAdmin == null || enforcedAdmin.component == null) { 167 return; 168 } 169 170 final DevicePolicyManager dpm = (DevicePolicyManager) activity.getSystemService( 171 Context.DEVICE_POLICY_SERVICE); 172 if (!RestrictedLockUtilsInternal.isAdminInCurrentUserOrProfile(activity, 173 enforcedAdmin.component) || !RestrictedLockUtils.isCurrentUserOrProfile( 174 activity, getEnforcementAdminUserId(enforcedAdmin))) { 175 enforcedAdmin.component = null; 176 } else { 177 if (enforcedAdmin.user == null) { 178 enforcedAdmin.user = UserHandle.of(UserHandle.myUserId()); 179 } 180 CharSequence supportMessage = null; 181 if (UserHandle.isSameApp(Process.myUid(), Process.SYSTEM_UID)) { 182 supportMessage = dpm.getShortSupportMessageForUser(enforcedAdmin.component, 183 getEnforcementAdminUserId(enforcedAdmin)); 184 } 185 if (supportMessage != null) { 186 final TextView textView = root.findViewById(R.id.admin_support_msg); 187 textView.setText(supportMessage); 188 } 189 } 190 } 191 showAdminPolicies(final EnforcedAdmin enforcedAdmin, final Activity activity)192 void showAdminPolicies(final EnforcedAdmin enforcedAdmin, final Activity activity) { 193 final Intent intent = new Intent(); 194 if (enforcedAdmin.component != null) { 195 intent.setClass(activity, DeviceAdminAdd.class); 196 intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, 197 enforcedAdmin.component); 198 intent.putExtra(DeviceAdminAdd.EXTRA_CALLED_FROM_SUPPORT_DIALOG, true); 199 // DeviceAdminAdd class may need to run as managed profile. 200 activity.startActivityAsUser(intent, enforcedAdmin.user); 201 } 202 } 203 } 204