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.cts.verifier.managedprovisioning; 18 19 import android.content.Context; 20 import android.content.Intent; 21 import android.content.pm.PackageManager; 22 import android.content.pm.ResolveInfo; 23 import android.os.UserManager; 24 import android.provider.Settings; 25 import android.provider.Telephony; 26 import android.telephony.TelephonyManager; 27 import android.text.TextUtils; 28 import android.util.ArrayMap; 29 30 import com.android.cts.verifier.R; 31 32 import java.util.ArrayList; 33 import java.util.Arrays; 34 import java.util.List; 35 36 public class UserRestrictions { 37 private static final String[] RESTRICTION_IDS_FOR_POLICY_TRANSPARENCY = new String[] { 38 UserManager.DISALLOW_ADD_USER, 39 UserManager.DISALLOW_ADJUST_VOLUME, 40 UserManager.DISALLOW_APPS_CONTROL, 41 UserManager.DISALLOW_CONFIG_CELL_BROADCASTS, 42 UserManager.DISALLOW_CONFIG_CREDENTIALS, 43 UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS, 44 UserManager.DISALLOW_CONFIG_TETHERING, 45 UserManager.DISALLOW_CONFIG_WIFI, 46 UserManager.DISALLOW_DEBUGGING_FEATURES, 47 UserManager.DISALLOW_FACTORY_RESET, 48 UserManager.DISALLOW_FUN, 49 UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, 50 UserManager.DISALLOW_MODIFY_ACCOUNTS, 51 UserManager.DISALLOW_NETWORK_RESET, 52 UserManager.DISALLOW_OUTGOING_BEAM, 53 UserManager.DISALLOW_REMOVE_MANAGED_PROFILE, 54 UserManager.DISALLOW_SHARE_LOCATION, 55 UserManager.DISALLOW_UNINSTALL_APPS, 56 UserManager.DISALLOW_UNIFIED_PASSWORD, 57 UserManager.DISALLOW_CONFIG_DATE_TIME, 58 UserManager.DISALLOW_CONFIG_LOCATION, 59 UserManager.DISALLOW_AIRPLANE_MODE, 60 UserManager.DISALLOW_CONFIG_SCREEN_TIMEOUT, 61 UserManager.DISALLOW_CONFIG_BRIGHTNESS, 62 }; 63 64 private static final ArrayMap<String, UserRestrictionItem> USER_RESTRICTION_ITEMS; 65 static { 66 final int[] restrictionLabels = new int[] { 67 R.string.disallow_add_user, 68 R.string.disallow_adjust_volume, 69 R.string.disallow_apps_control, 70 R.string.disallow_config_cell_broadcasts, 71 R.string.disallow_config_credentials, 72 R.string.disallow_config_mobile_networks, 73 R.string.disallow_config_tethering, 74 R.string.disallow_config_wifi, 75 R.string.disallow_debugging_features, 76 R.string.disallow_factory_reset, 77 R.string.disallow_fun, 78 R.string.disallow_install_unknown_sources, 79 R.string.disallow_modify_accounts, 80 R.string.disallow_network_reset, 81 R.string.disallow_outgoing_beam, 82 R.string.disallow_remove_managed_profile, 83 R.string.disallow_share_location, 84 R.string.disallow_uninstall_apps, 85 R.string.disallow_unified_challenge, 86 R.string.disallow_config_date_time, 87 R.string.disallow_config_location, 88 R.string.disallow_airplane_mode, 89 R.string.disallow_config_screen_timeout, 90 R.string.disallow_config_brightness 91 }; 92 93 final int[] restrictionActions = new int[] { 94 R.string.disallow_add_user_action, 95 R.string.disallow_adjust_volume_action, 96 R.string.disallow_apps_control_action, 97 R.string.disallow_config_cell_broadcasts_action, 98 R.string.disallow_config_credentials_action, 99 R.string.disallow_config_mobile_networks_action, 100 R.string.disallow_config_tethering_action, 101 R.string.disallow_config_wifi_action, 102 R.string.disallow_debugging_features_action, 103 R.string.disallow_factory_reset_action, 104 R.string.disallow_fun_action, 105 R.string.disallow_install_unknown_sources_action, 106 R.string.disallow_modify_accounts_action, 107 R.string.disallow_network_reset_action, 108 R.string.disallow_outgoing_beam_action, 109 R.string.disallow_remove_managed_profile_action, 110 R.string.disallow_share_location_action, 111 R.string.disallow_uninstall_apps_action, 112 R.string.disallow_unified_challenge_action, 113 R.string.disallow_config_date_time_action, 114 R.string.disallow_config_location_action, 115 R.string.disallow_airplane_mode_action, 116 R.string.disallow_config_screen_timeout_action, 117 R.string.disallow_config_brightness_action 118 }; 119 120 final String[] settingsIntentActions = new String[] { 121 Settings.ACTION_SETTINGS, 122 Settings.ACTION_SOUND_SETTINGS, 123 Settings.ACTION_APPLICATION_SETTINGS, 124 Settings.ACTION_SETTINGS, 125 Settings.ACTION_SECURITY_SETTINGS, 126 Settings.ACTION_WIRELESS_SETTINGS, 127 Settings.ACTION_WIRELESS_SETTINGS, 128 Settings.ACTION_WIFI_SETTINGS, 129 Settings.ACTION_DEVICE_INFO_SETTINGS, 130 Settings.ACTION_SETTINGS, 131 Settings.ACTION_DEVICE_INFO_SETTINGS, 132 Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, 133 Settings.ACTION_SYNC_SETTINGS, 134 Settings.ACTION_SETTINGS, 135 Settings.ACTION_NFC_SETTINGS, 136 Settings.ACTION_SETTINGS, 137 Settings.ACTION_LOCATION_SOURCE_SETTINGS, 138 Settings.ACTION_APPLICATION_SETTINGS, 139 Settings.ACTION_SECURITY_SETTINGS, 140 Settings.ACTION_DATE_SETTINGS, 141 Settings.ACTION_LOCATION_SOURCE_SETTINGS, 142 Settings.ACTION_AIRPLANE_MODE_SETTINGS, 143 Settings.ACTION_DISPLAY_SETTINGS, 144 Settings.ACTION_DISPLAY_SETTINGS, 145 }; 146 147 if (RESTRICTION_IDS_FOR_POLICY_TRANSPARENCY.length != restrictionLabels.length 148 || RESTRICTION_IDS_FOR_POLICY_TRANSPARENCY.length != restrictionActions.length 149 || RESTRICTION_IDS_FOR_POLICY_TRANSPARENCY.length != settingsIntentActions.length) { 150 throw new AssertionError("Number of items in restrictionIds, restrictionLabels, " 151 + "restrictionActions, and settingsIntentActions do not match"); 152 } 153 USER_RESTRICTION_ITEMS = new ArrayMap<>(RESTRICTION_IDS_FOR_POLICY_TRANSPARENCY.length); 154 for (int i = 0; i < RESTRICTION_IDS_FOR_POLICY_TRANSPARENCY.length; ++i) { USER_RESTRICTION_ITEMS.put(RESTRICTION_IDS_FOR_POLICY_TRANSPARENCY[i], new UserRestrictionItem( restrictionLabels[i], restrictionActions[i], settingsIntentActions[i]))155 USER_RESTRICTION_ITEMS.put(RESTRICTION_IDS_FOR_POLICY_TRANSPARENCY[i], 156 new UserRestrictionItem( 157 restrictionLabels[i], 158 restrictionActions[i], 159 settingsIntentActions[i])); 160 } 161 } 162 163 private static final List<String> ALSO_VALID_FOR_MANAGED_PROFILE_POLICY_TRANSPARENCY = 164 Arrays.asList( 165 UserManager.DISALLOW_APPS_CONTROL, 166 UserManager.DISALLOW_UNINSTALL_APPS, 167 UserManager.DISALLOW_MODIFY_ACCOUNTS, UserManager.DISALLOW_SHARE_LOCATION, 168 UserManager.DISALLOW_UNIFIED_PASSWORD, 169 UserManager.DISALLOW_CONFIG_LOCATION); 170 private static final List<String> ALSO_VALID_FOR_MANAGED_USER_POLICY_TRANSPARENCY = 171 Arrays.asList( 172 UserManager.DISALLOW_ADJUST_VOLUME, 173 UserManager.DISALLOW_APPS_CONTROL, 174 UserManager.DISALLOW_CONFIG_WIFI, 175 UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, 176 UserManager.DISALLOW_MODIFY_ACCOUNTS, 177 UserManager.DISALLOW_OUTGOING_BEAM, 178 UserManager.DISALLOW_SHARE_LOCATION, 179 UserManager.DISALLOW_UNINSTALL_APPS, 180 UserManager.DISALLOW_CONFIG_DATE_TIME, 181 UserManager.DISALLOW_CONFIG_LOCATION, 182 UserManager.DISALLOW_CONFIG_SCREEN_TIMEOUT, 183 UserManager.DISALLOW_CONFIG_BRIGHTNESS); 184 185 private static final String ACTION_CREDENTIALS_INSTALL = "com.android.credentials.INSTALL"; 186 getRestrictionLabel(Context context, String restriction)187 public static String getRestrictionLabel(Context context, String restriction) { 188 final UserRestrictionItem item = findRestrictionItem(restriction); 189 return context.getString(item.label); 190 } 191 getUserAction(Context context, String restriction)192 public static String getUserAction(Context context, String restriction) { 193 final UserRestrictionItem item = findRestrictionItem(restriction); 194 return context.getString(item.userAction); 195 } 196 findRestrictionItem(String restriction)197 private static UserRestrictionItem findRestrictionItem(String restriction) { 198 final UserRestrictionItem item = USER_RESTRICTION_ITEMS.get(restriction); 199 if (item == null) { 200 throw new IllegalArgumentException("Unknown restriction: " + restriction); 201 } 202 return item; 203 } 204 getUserRestrictionsForPolicyTransparency(int mode)205 public static List<String> getUserRestrictionsForPolicyTransparency(int mode) { 206 if (mode == PolicyTransparencyTestListActivity.MODE_DEVICE_OWNER) { 207 ArrayList<String> result = new ArrayList<String>(); 208 // They are all valid except for DISALLOW_REMOVE_MANAGED_PROFILE 209 for (String st : RESTRICTION_IDS_FOR_POLICY_TRANSPARENCY) { 210 if (!st.equals(UserManager.DISALLOW_REMOVE_MANAGED_PROFILE) 211 && !st.equals(UserManager.DISALLOW_UNIFIED_PASSWORD)) { 212 result.add(st); 213 } 214 } 215 return result; 216 } else if (mode == PolicyTransparencyTestListActivity.MODE_MANAGED_PROFILE) { 217 return ALSO_VALID_FOR_MANAGED_PROFILE_POLICY_TRANSPARENCY; 218 } else if (mode == PolicyTransparencyTestListActivity.MODE_MANAGED_USER) { 219 return ALSO_VALID_FOR_MANAGED_USER_POLICY_TRANSPARENCY; 220 } 221 throw new RuntimeException("Invalid mode " + mode); 222 } 223 getUserRestrictionTestIntent(Context context, String restriction)224 public static Intent getUserRestrictionTestIntent(Context context, String restriction) { 225 final UserRestrictionItem item = USER_RESTRICTION_ITEMS.get(restriction); 226 final Intent intent = 227 new Intent(PolicyTransparencyTestActivity.ACTION_SHOW_POLICY_TRANSPARENCY_TEST) 228 .putExtra(PolicyTransparencyTestActivity.EXTRA_TEST, 229 PolicyTransparencyTestActivity.TEST_CHECK_USER_RESTRICTION) 230 .putExtra(CommandReceiverActivity.EXTRA_USER_RESTRICTION, restriction) 231 .putExtra(PolicyTransparencyTestActivity.EXTRA_TITLE, 232 context.getString(item.label)) 233 .putExtra(PolicyTransparencyTestActivity.EXTRA_SETTINGS_INTENT_ACTION, 234 item.intentAction); 235 // For DISALLOW_FACTORY_RESET, set on the device owner, not on the current user. 236 if (!UserManager.DISALLOW_FACTORY_RESET.equals(restriction)) { 237 intent.putExtra(CommandReceiverActivity.EXTRA_USE_CURRENT_USER_DPM, true); 238 } 239 return intent; 240 } 241 isRestrictionValid(Context context, String restriction)242 public static boolean isRestrictionValid(Context context, String restriction) { 243 final PackageManager pm = context.getPackageManager(); 244 switch (restriction) { 245 case UserManager.DISALLOW_ADD_USER: 246 return UserManager.supportsMultipleUsers(); 247 case UserManager.DISALLOW_ADJUST_VOLUME: 248 return pm.hasSystemFeature(PackageManager.FEATURE_AUDIO_OUTPUT); 249 case UserManager.DISALLOW_AIRPLANE_MODE: 250 return (!pm.hasSystemFeature(PackageManager.FEATURE_WATCH) 251 && hasSettingsActivity(context, Settings.ACTION_AIRPLANE_MODE_SETTINGS)); 252 case UserManager.DISALLOW_CONFIG_BRIGHTNESS: 253 return (hasSettingsActivity(context, Settings.ACTION_DISPLAY_SETTINGS) 254 && !pm.hasSystemFeature(PackageManager.FEATURE_WATCH)); 255 case UserManager.DISALLOW_CONFIG_CELL_BROADCASTS: 256 final TelephonyManager tm = 257 context.getSystemService(TelephonyManager.class); 258 if (!tm.isSmsCapable()) { 259 return false; 260 } 261 // Get com.android.internal.R.bool.config_cellBroadcastAppLinks 262 final int resId = context.getResources().getIdentifier( 263 "config_cellBroadcastAppLinks", "bool", "android"); 264 boolean isCellBroadcastAppLinkEnabled = context.getResources().getBoolean(resId); 265 try { 266 if (isCellBroadcastAppLinkEnabled) { 267 String packageName = getDefaultCellBroadcastReceiverPackageName(context); 268 if (packageName == null || pm.getApplicationEnabledSetting(packageName) 269 == PackageManager.COMPONENT_ENABLED_STATE_DISABLED) { 270 isCellBroadcastAppLinkEnabled = false; // CMAS app disabled 271 } 272 } 273 } catch (IllegalArgumentException ignored) { 274 isCellBroadcastAppLinkEnabled = false; // CMAS app not installed 275 } 276 return isCellBroadcastAppLinkEnabled; 277 case UserManager.DISALLOW_FUN: 278 // Easter egg is not available on watch 279 return !pm.hasSystemFeature(PackageManager.FEATURE_WATCH); 280 case UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS: 281 return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY); 282 case UserManager.DISALLOW_CONFIG_WIFI: 283 return pm.hasSystemFeature(PackageManager.FEATURE_WIFI); 284 case UserManager.DISALLOW_NETWORK_RESET: 285 // This test should not run on watch 286 return !pm.hasSystemFeature(PackageManager.FEATURE_WATCH); 287 case UserManager.DISALLOW_OUTGOING_BEAM: 288 return pm.hasSystemFeature(PackageManager.FEATURE_NFC) 289 && pm.hasSystemFeature(PackageManager.FEATURE_NFC_BEAM); 290 case UserManager.DISALLOW_SHARE_LOCATION: 291 return pm.hasSystemFeature(PackageManager.FEATURE_LOCATION); 292 case UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES: 293 return !pm.hasSystemFeature(PackageManager.FEATURE_WATCH); 294 case UserManager.DISALLOW_CONFIG_CREDENTIALS: 295 return !pm.hasSystemFeature(PackageManager.FEATURE_WATCH) 296 && hasSettingsActivity(context, ACTION_CREDENTIALS_INSTALL); 297 case UserManager.DISALLOW_CONFIG_LOCATION: 298 case UserManager.DISALLOW_CONFIG_SCREEN_TIMEOUT: 299 // TODO(b/189282625): replace FEATURE_WATCH with a more specific feature 300 return !pm.hasSystemFeature(PackageManager.FEATURE_WATCH); 301 default: 302 return true; 303 } 304 } 305 306 /** 307 * Utility method to query the default CBR's package name. 308 * from frameworks/base/telephony/common/com/android/internal/telephony/CellBroadcastUtils.java 309 */ getDefaultCellBroadcastReceiverPackageName(Context context)310 private static String getDefaultCellBroadcastReceiverPackageName(Context context) { 311 PackageManager packageManager = context.getPackageManager(); 312 ResolveInfo resolveInfo = packageManager.resolveActivity( 313 new Intent(Telephony.Sms.Intents.SMS_CB_RECEIVED_ACTION), 314 PackageManager.MATCH_SYSTEM_ONLY); 315 String packageName; 316 317 if (resolveInfo == null) { 318 return null; 319 } 320 321 packageName = resolveInfo.activityInfo.applicationInfo.packageName; 322 323 if (TextUtils.isEmpty(packageName) || packageManager.checkPermission( 324 android.Manifest.permission.READ_CELL_BROADCASTS, packageName) 325 == PackageManager.PERMISSION_DENIED) { 326 return null; 327 } 328 329 return packageName; 330 } 331 332 /** 333 * Utility to check if the Settings app handles an intent action 334 */ hasSettingsActivity(Context context, String intentAction)335 private static boolean hasSettingsActivity(Context context, String intentAction) { 336 PackageManager packageManager = context.getPackageManager(); 337 ResolveInfo resolveInfo = packageManager.resolveActivity( 338 new Intent(intentAction), 339 PackageManager.MATCH_SYSTEM_ONLY); 340 341 if (resolveInfo == null) { 342 return false; 343 } 344 345 return !TextUtils.isEmpty(resolveInfo.activityInfo.applicationInfo.packageName); 346 } 347 348 private static class UserRestrictionItem { 349 final int label; 350 final int userAction; 351 final String intentAction; UserRestrictionItem(int label, int userAction, String intentAction)352 public UserRestrictionItem(int label, int userAction, String intentAction) { 353 this.label = label; 354 this.userAction = userAction; 355 this.intentAction = intentAction; 356 } 357 } 358 } 359