blob: 56e8b3eaea2c29628fcf2875ed76adba273f0efd [file] [log] [blame]
Makoto Onukia4f11972015-10-01 13:19:58 -07001/*
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
Makoto Onuki4f160732015-10-27 17:15:38 -070021import android.content.ContentResolver;
22import android.content.Context;
Makoto Onuki4f160732015-10-27 17:15:38 -070023import android.net.Uri;
24import android.os.Binder;
Makoto Onukia4f11972015-10-01 13:19:58 -070025import android.os.Bundle;
Makoto Onuki4f160732015-10-27 17:15:38 -070026import android.os.SystemProperties;
27import android.os.UserHandle;
Makoto Onukia4f11972015-10-01 13:19:58 -070028import 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
Makoto Onukid45a4a22015-11-02 17:17:38 -080037/**
38 * Utility methods for uesr restrictions.
39 *
40 * <p>See {@link UserManagerService} for the method suffixes.
41 */
Makoto Onukia4f11972015-10-01 13:19:58 -070042public class UserRestrictionsUtils {
Makoto Onuki4f160732015-10-27 17:15:38 -070043 private static final String TAG = "UserRestrictionsUtils";
44
Makoto Onukia4f11972015-10-01 13:19:58 -070045 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) {
Makoto Onukia4f11972015-10-01 13:19:58 -0700100 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
Makoto Onuki068c54a2015-10-13 14:34:03 -0700118 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
Makoto Onuki4f160732015-10-27 17:15:38 -0700129 /**
130 * Takes a new use restriction set and the previous set, and apply the restrictions that have
131 * changed.
Makoto Onukid45a4a22015-11-02 17:17:38 -0800132 *
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.
Makoto Onuki4f160732015-10-27 17:15:38 -0700136 */
Makoto Onukid45a4a22015-11-02 17:17:38 -0800137 public static void applyUserRestrictionsLR(Context context, int userId,
138 Bundle newRestrictions, Bundle prevRestrictions) {
Makoto Onuki4f160732015-10-27 17:15:38 -0700139 for (String key : USER_RESTRICTIONS) {
140 final boolean newValue = newRestrictions.getBoolean(key);
141 final boolean prevValue = prevRestrictions.getBoolean(key);
142
143 if (newValue != prevValue) {
Makoto Onukid45a4a22015-11-02 17:17:38 -0800144 applyUserRestrictionLR(context, userId, key, newValue);
Makoto Onuki4f160732015-10-27 17:15:38 -0700145 }
146 }
147 }
148
Makoto Onukid45a4a22015-11-02 17:17:38 -0800149 /**
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,
Makoto Onuki4f160732015-10-27 17:15:38 -0700157 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) {
Makoto Onuki4f160732015-10-27 17:15:38 -0700169 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 }
Makoto Onuki4f160732015-10-27 17:15:38 -0700231 } finally {
232 Binder.restoreCallingIdentity(id);
233 }
234 }
235
Makoto Onukia4f11972015-10-01 13:19:58 -0700236 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 }
Makoto Onuki068c54a2015-10-13 14:34:03 -0700245 if (noneSet) {
246 pw.println(prefix + "none");
247 }
248 } else {
249 pw.println(prefix + "null");
Makoto Onukia4f11972015-10-01 13:19:58 -0700250 }
251 }
252}