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