UserRestrictionsUtils.java revision d45a4a2ecb18701b4cfadcb4a26663f2eab642fe
1/* 2 * Copyright (C) 2015 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 17package com.android.server.pm; 18 19import com.google.android.collect.Sets; 20 21import android.content.ContentResolver; 22import android.content.Context; 23import android.net.Uri; 24import android.os.Binder; 25import android.os.Bundle; 26import android.os.SystemProperties; 27import android.os.UserHandle; 28import android.os.UserManager; 29 30import org.xmlpull.v1.XmlPullParser; 31import org.xmlpull.v1.XmlSerializer; 32 33import java.io.IOException; 34import java.io.PrintWriter; 35import java.util.Set; 36 37/** 38 * Utility methods for uesr restrictions. 39 * 40 * <p>See {@link UserManagerService} for the method suffixes. 41 */ 42public class UserRestrictionsUtils { 43 private static final String TAG = "UserRestrictionsUtils"; 44 45 private UserRestrictionsUtils() { 46 } 47 48 public static final String[] USER_RESTRICTIONS = { 49 UserManager.DISALLOW_CONFIG_WIFI, 50 UserManager.DISALLOW_MODIFY_ACCOUNTS, 51 UserManager.DISALLOW_INSTALL_APPS, 52 UserManager.DISALLOW_UNINSTALL_APPS, 53 UserManager.DISALLOW_SHARE_LOCATION, 54 UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, 55 UserManager.DISALLOW_CONFIG_BLUETOOTH, 56 UserManager.DISALLOW_USB_FILE_TRANSFER, 57 UserManager.DISALLOW_CONFIG_CREDENTIALS, 58 UserManager.DISALLOW_REMOVE_USER, 59 UserManager.DISALLOW_DEBUGGING_FEATURES, 60 UserManager.DISALLOW_CONFIG_VPN, 61 UserManager.DISALLOW_CONFIG_TETHERING, 62 UserManager.DISALLOW_NETWORK_RESET, 63 UserManager.DISALLOW_FACTORY_RESET, 64 UserManager.DISALLOW_ADD_USER, 65 UserManager.ENSURE_VERIFY_APPS, 66 UserManager.DISALLOW_CONFIG_CELL_BROADCASTS, 67 UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS, 68 UserManager.DISALLOW_APPS_CONTROL, 69 UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA, 70 UserManager.DISALLOW_UNMUTE_MICROPHONE, 71 UserManager.DISALLOW_ADJUST_VOLUME, 72 UserManager.DISALLOW_OUTGOING_CALLS, 73 UserManager.DISALLOW_SMS, 74 UserManager.DISALLOW_FUN, 75 UserManager.DISALLOW_CREATE_WINDOWS, 76 UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE, 77 UserManager.DISALLOW_OUTGOING_BEAM, 78 UserManager.DISALLOW_WALLPAPER, 79 UserManager.DISALLOW_SAFE_BOOT, 80 UserManager.ALLOW_PARENT_PROFILE_APP_LINKING, 81 UserManager.DISALLOW_RECORD_AUDIO, 82 }; 83 84 /** 85 * Set of user restrictions, which can only be enforced by the system. 86 */ 87 public static final Set<String> SYSTEM_CONTROLLED_USER_RESTRICTIONS = Sets.newArraySet( 88 UserManager.DISALLOW_RECORD_AUDIO); 89 90 /** 91 * Set of user restriction which we don't want to persist. 92 */ 93 public static final Set<String> NON_PERSIST_USER_RESTRICTIONS = Sets.newArraySet( 94 UserManager.DISALLOW_RECORD_AUDIO); 95 96 public static void writeRestrictions(XmlSerializer serializer, Bundle restrictions, 97 String tag) throws IOException { 98 serializer.startTag(null, tag); 99 for (String key : USER_RESTRICTIONS) { 100 if (restrictions.getBoolean(key) 101 && !NON_PERSIST_USER_RESTRICTIONS.contains(key)) { 102 serializer.attribute(null, key, "true"); 103 } 104 } 105 serializer.endTag(null, tag); 106 } 107 108 public static void readRestrictions(XmlPullParser parser, Bundle restrictions) 109 throws IOException { 110 for (String key : USER_RESTRICTIONS) { 111 final String value = parser.getAttributeValue(null, key); 112 if (value != null) { 113 restrictions.putBoolean(key, Boolean.parseBoolean(value)); 114 } 115 } 116 } 117 118 public static void merge(Bundle dest, Bundle in) { 119 if (in == null) { 120 return; 121 } 122 for (String key : in.keySet()) { 123 if (in.getBoolean(key, false)) { 124 dest.putBoolean(key, true); 125 } 126 } 127 } 128 129 /** 130 * Takes a new use restriction set and the previous set, and apply the restrictions that have 131 * changed. 132 * 133 * <p>Note this method is called by {@link UserManagerService} while holding 134 * {@code mRestrictionLock}. Be aware when calling into other services, which could cause 135 * a deadlock. 136 */ 137 public static void applyUserRestrictionsLR(Context context, int userId, 138 Bundle newRestrictions, Bundle prevRestrictions) { 139 for (String key : USER_RESTRICTIONS) { 140 final boolean newValue = newRestrictions.getBoolean(key); 141 final boolean prevValue = prevRestrictions.getBoolean(key); 142 143 if (newValue != prevValue) { 144 applyUserRestrictionLR(context, userId, key, newValue); 145 } 146 } 147 } 148 149 /** 150 * Apply each user restriction. 151 * 152 * <p>Note this method is called by {@link UserManagerService} while holding 153 * {@code mRestrictionLock}. Be aware when calling into other services, which could cause 154 * a deadlock. 155 */ 156 private static void applyUserRestrictionLR(Context context, int userId, String key, 157 boolean newValue) { 158 // When certain restrictions are cleared, we don't update the system settings, 159 // because these settings are changeable on the Settings UI and we don't know the original 160 // value -- for example LOCATION_MODE might have been off already when the restriction was 161 // set, and in that case even if the restriction is lifted, changing it to ON would be 162 // wrong. So just don't do anything in such a case. If the user hopes to enable location 163 // later, they can do it on the Settings UI. 164 165 final ContentResolver cr = context.getContentResolver(); 166 final long id = Binder.clearCallingIdentity(); 167 try { 168 switch (key) { 169 case UserManager.DISALLOW_CONFIG_WIFI: 170 if (newValue) { 171 android.provider.Settings.Secure.putIntForUser(cr, 172 android.provider.Settings.Secure 173 .WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, 0, userId); 174 } 175 break; 176 case UserManager.DISALLOW_SHARE_LOCATION: 177 if (newValue) { 178 android.provider.Settings.Secure.putIntForUser(cr, 179 android.provider.Settings.Secure.LOCATION_MODE, 180 android.provider.Settings.Secure.LOCATION_MODE_OFF, 181 userId); 182 android.provider.Settings.Secure.putStringForUser(cr, 183 android.provider.Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "", 184 userId); 185 } 186 // Send out notifications as some clients may want to reread the 187 // value which actually changed due to a restriction having been 188 // applied. 189 final String property = 190 android.provider.Settings.Secure.SYS_PROP_SETTING_VERSION; 191 long version = SystemProperties.getLong(property, 0) + 1; 192 SystemProperties.set(property, Long.toString(version)); 193 194 final String name = android.provider.Settings.Secure.LOCATION_PROVIDERS_ALLOWED; 195 final Uri url = Uri.withAppendedPath( 196 android.provider.Settings.Secure.CONTENT_URI, name); 197 context.getContentResolver().notifyChange(url, null, true, userId); 198 199 break; 200 case UserManager.DISALLOW_DEBUGGING_FEATURES: 201 if (newValue) { 202 // Only disable adb if changing for system user, since it is global 203 // TODO: should this be admin user? 204 if (userId == UserHandle.USER_SYSTEM) { 205 android.provider.Settings.Global.putStringForUser(cr, 206 android.provider.Settings.Global.ADB_ENABLED, "0", 207 userId); 208 } 209 } 210 break; 211 case UserManager.ENSURE_VERIFY_APPS: 212 if (newValue) { 213 android.provider.Settings.Global.putStringForUser( 214 context.getContentResolver(), 215 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, "1", 216 userId); 217 android.provider.Settings.Global.putStringForUser( 218 context.getContentResolver(), 219 android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, "1", 220 userId); 221 } 222 break; 223 case UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES: 224 if (newValue) { 225 android.provider.Settings.Secure.putIntForUser(cr, 226 android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS, 0, 227 userId); 228 } 229 break; 230 } 231 } finally { 232 Binder.restoreCallingIdentity(id); 233 } 234 } 235 236 public static void dumpRestrictions(PrintWriter pw, String prefix, Bundle restrictions) { 237 boolean noneSet = true; 238 if (restrictions != null) { 239 for (String key : restrictions.keySet()) { 240 if (restrictions.getBoolean(key, false)) { 241 pw.println(prefix + key); 242 noneSet = false; 243 } 244 } 245 if (noneSet) { 246 pw.println(prefix + "none"); 247 } 248 } else { 249 pw.println(prefix + "null"); 250 } 251 } 252} 253