• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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                         && !pm.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
291                         && hasSettingsActivity(context, Settings.ACTION_AIRPLANE_MODE_SETTINGS));
292             case UserManager.DISALLOW_CONFIG_BRIGHTNESS:
293                 return (hasSettingsActivity(context, Settings.ACTION_DISPLAY_SETTINGS)
294                     && !pm.hasSystemFeature(PackageManager.FEATURE_WATCH));
295             case UserManager.DISALLOW_CONFIG_CELL_BROADCASTS:
296                 if (context.getResources().getBoolean(context.getResources()
297                         .getIdentifier("config_disable_all_cb_messages", "bool", "android"))) {
298                     return false;
299                 }
300                 if (!tm.isSmsCapable()) {
301                     return false;
302                 }
303                 // Get com.android.internal.R.bool.config_cellBroadcastAppLinks
304                 final int resId = context.getResources().getIdentifier(
305                         "config_cellBroadcastAppLinks", "bool", "android");
306                 boolean isCellBroadcastAppLinkEnabled = context.getResources().getBoolean(resId);
307                 try {
308                     if (isCellBroadcastAppLinkEnabled) {
309                         String packageName = getDefaultCellBroadcastReceiverPackageName(context);
310                         if (packageName == null || pm.getApplicationEnabledSetting(packageName)
311                                 == PackageManager.COMPONENT_ENABLED_STATE_DISABLED) {
312                             isCellBroadcastAppLinkEnabled = false;  // CMAS app disabled
313                         }
314                     }
315                 } catch (IllegalArgumentException ignored) {
316                     isCellBroadcastAppLinkEnabled = false;  // CMAS app not installed
317                 }
318                 return isCellBroadcastAppLinkEnabled;
319             case UserManager.DISALLOW_FUN:
320                 // Easter egg is not available on watch or automotive
321                 return FeatureUtil.isFunSupported(context);
322             case UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS:
323                 return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
324             case UserManager.DISALLOW_CONFIG_WIFI:
325                 return pm.hasSystemFeature(PackageManager.FEATURE_WIFI);
326             case UserManager.DISALLOW_NETWORK_RESET:
327                 // This test should not run on watch
328                 return !pm.hasSystemFeature(PackageManager.FEATURE_WATCH);
329             case UserManager.DISALLOW_OUTGOING_BEAM:
330                 return pm.hasSystemFeature(PackageManager.FEATURE_NFC)
331                         && pm.hasSystemFeature(PackageManager.FEATURE_NFC_BEAM);
332             case UserManager.DISALLOW_SHARE_LOCATION:
333                 return pm.hasSystemFeature(PackageManager.FEATURE_LOCATION);
334             case UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES:
335                 return FeatureUtil.isInstallUnknownSourcesSupported(context);
336             case UserManager.DISALLOW_CONFIG_CREDENTIALS:
337                 return !pm.hasSystemFeature(PackageManager.FEATURE_WATCH)
338                         && hasSettingsActivity(context, ACTION_CREDENTIALS_INSTALL);
339             case UserManager.DISALLOW_CONFIG_SCREEN_TIMEOUT:
340                 return FeatureUtil.isScreenTimeoutSupported(context);
341             case UserManager.DISALLOW_CONFIG_LOCATION:
342                 return FeatureUtil.isConfigLocationSupported(context);
343             case UserManager.DISALLOW_APPS_CONTROL:
344                 return !pm.hasSystemFeature(PackageManager.FEATURE_WATCH);
345             case UserManager.DISALLOW_UNINSTALL_APPS:
346                 return !pm.hasSystemFeature(PackageManager.FEATURE_WATCH);
347             default:
348                 return true;
349         }
350     }
351 
352     /**
353      * Utility method to query the default CBR's package name.
354      * from frameworks/base/telephony/common/com/android/internal/telephony/CellBroadcastUtils.java
355      */
getDefaultCellBroadcastReceiverPackageName(Context context)356     private static String getDefaultCellBroadcastReceiverPackageName(Context context) {
357         PackageManager packageManager = context.getPackageManager();
358         ResolveInfo resolveInfo = packageManager.resolveActivity(
359                 new Intent(Telephony.Sms.Intents.SMS_CB_RECEIVED_ACTION),
360                 PackageManager.MATCH_SYSTEM_ONLY);
361         String packageName;
362 
363         if (resolveInfo == null) {
364             return null;
365         }
366 
367         packageName = resolveInfo.activityInfo.applicationInfo.packageName;
368 
369         if (TextUtils.isEmpty(packageName) || packageManager.checkPermission(
370             android.Manifest.permission.READ_CELL_BROADCASTS, packageName)
371                 == PackageManager.PERMISSION_DENIED) {
372             return null;
373         }
374 
375         return packageName;
376     }
377 
378     /**
379      * Utility to check if the Settings app handles an intent action
380      */
hasSettingsActivity(Context context, String intentAction)381     private static boolean hasSettingsActivity(Context context, String intentAction) {
382         PackageManager packageManager = context.getPackageManager();
383         ResolveInfo resolveInfo = packageManager.resolveActivity(
384                 new Intent(intentAction),
385                 PackageManager.MATCH_SYSTEM_ONLY);
386 
387         if (resolveInfo == null) {
388             return false;
389         }
390 
391         return !TextUtils.isEmpty(resolveInfo.activityInfo.applicationInfo.packageName);
392     }
393 
394     /**
395      * Checks whether target mode is device owner test mode
396      */
isDeviceOwnerMode(int mode)397     private static boolean isDeviceOwnerMode(int mode) {
398         return mode == PolicyTransparencyTestListActivity.MODE_DEVICE_OWNER;
399     }
400 
isOnlyValidForDeviceOwnerOrPrimaryUser(String restriction)401     private static boolean isOnlyValidForDeviceOwnerOrPrimaryUser(String restriction) {
402         return DEVICE_OWNER_ONLY_RESTRICTIONS.contains(restriction)
403                 || PRIMARY_USER_ONLY_RESTRICTIONS.contains(restriction);
404     }
405 
406     private static class UserRestrictionItem {
407         final int label;
408         final int userAction;
409         final String intentAction;
UserRestrictionItem(int label, int userAction, String intentAction)410         public UserRestrictionItem(int label, int userAction, String intentAction) {
411             this.label = label;
412             this.userAction = userAction;
413             this.intentAction = intentAction;
414         }
415     }
416 }
417