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(getEnforcementAdminUserId(mEnforcedAdmin), um.getUserHandle())) { 91 builder.setNeutralButton(R.string.learn_more, (dialog, which) -> { 92 showAdminPolicies(mEnforcedAdmin, mActivity); 93 mActivity.finish(); 94 }); 95 } 96 } 97 updateDialog(String restriction, EnforcedAdmin admin)98 public void updateDialog(String restriction, EnforcedAdmin admin) { 99 if (mEnforcedAdmin.equals(admin) && Objects.equals(mRestriction, restriction)) { 100 return; 101 } 102 mEnforcedAdmin = admin; 103 mRestriction = restriction; 104 initializeDialogViews(mDialogView, mEnforcedAdmin.component, getEnforcementAdminUserId(), 105 mRestriction); 106 } 107 initializeDialogViews(View root, ComponentName admin, int userId, String restriction)108 private void initializeDialogViews(View root, ComponentName admin, int userId, 109 String restriction) { 110 if (admin == null) { 111 return; 112 } 113 114 setAdminSupportTitle(root, restriction); 115 116 final UserHandle user; 117 if (userId == UserHandle.USER_NULL) { 118 user = null; 119 } else { 120 user = UserHandle.of(userId); 121 } 122 123 setAdminSupportDetails(mActivity, root, new EnforcedAdmin(admin, user)); 124 } 125 126 @VisibleForTesting setAdminSupportTitle(View root, String restriction)127 void setAdminSupportTitle(View root, String restriction) { 128 final TextView titleView = root.findViewById(R.id.admin_support_dialog_title); 129 if (titleView == null) { 130 return; 131 } 132 if (restriction == null) { 133 titleView.setText(R.string.disabled_by_policy_title); 134 return; 135 } 136 switch (restriction) { 137 case UserManager.DISALLOW_ADJUST_VOLUME: 138 titleView.setText(R.string.disabled_by_policy_title_adjust_volume); 139 break; 140 case UserManager.DISALLOW_OUTGOING_CALLS: 141 titleView.setText(R.string.disabled_by_policy_title_outgoing_calls); 142 break; 143 case UserManager.DISALLOW_SMS: 144 titleView.setText(R.string.disabled_by_policy_title_sms); 145 break; 146 case DevicePolicyManager.POLICY_DISABLE_CAMERA: 147 titleView.setText(R.string.disabled_by_policy_title_camera); 148 break; 149 case DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE: 150 titleView.setText(R.string.disabled_by_policy_title_screen_capture); 151 break; 152 case DevicePolicyManager.POLICY_SUSPEND_PACKAGES: 153 titleView.setText(R.string.disabled_by_policy_title_suspend_packages); 154 break; 155 default: 156 // Use general text if no specialized title applies 157 titleView.setText(R.string.disabled_by_policy_title); 158 } 159 } 160 161 @VisibleForTesting setAdminSupportDetails(final Activity activity, final View root, final EnforcedAdmin enforcedAdmin)162 void setAdminSupportDetails(final Activity activity, final View root, 163 final EnforcedAdmin enforcedAdmin) { 164 if (enforcedAdmin == null || enforcedAdmin.component == null) { 165 return; 166 } 167 168 final DevicePolicyManager dpm = (DevicePolicyManager) activity.getSystemService( 169 Context.DEVICE_POLICY_SERVICE); 170 if (!RestrictedLockUtilsInternal.isAdminInCurrentUserOrProfile(activity, 171 enforcedAdmin.component) || !RestrictedLockUtils.isCurrentUserOrProfile( 172 activity, getEnforcementAdminUserId(enforcedAdmin))) { 173 enforcedAdmin.component = null; 174 } else { 175 if (enforcedAdmin.user == null) { 176 enforcedAdmin.user = UserHandle.of(UserHandle.myUserId()); 177 } 178 CharSequence supportMessage = null; 179 if (UserHandle.isSameApp(Process.myUid(), Process.SYSTEM_UID)) { 180 supportMessage = dpm.getShortSupportMessageForUser(enforcedAdmin.component, 181 getEnforcementAdminUserId(enforcedAdmin)); 182 } 183 if (supportMessage != null) { 184 final TextView textView = root.findViewById(R.id.admin_support_msg); 185 textView.setText(supportMessage); 186 } 187 } 188 } 189 showAdminPolicies(final EnforcedAdmin enforcedAdmin, final Activity activity)190 void showAdminPolicies(final EnforcedAdmin enforcedAdmin, final Activity activity) { 191 final Intent intent = new Intent(); 192 if (enforcedAdmin.component != null) { 193 intent.setClass(activity, DeviceAdminAdd.class); 194 intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, 195 enforcedAdmin.component); 196 intent.putExtra(DeviceAdminAdd.EXTRA_CALLED_FROM_SUPPORT_DIALOG, true); 197 // DeviceAdminAdd class may need to run as managed profile. 198 activity.startActivityAsUser(intent, enforcedAdmin.user); 199 } 200 } 201 } 202