diff options
8 files changed, 396 insertions, 145 deletions
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 31fc24bef4f9..341410d3522d 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -59,8 +59,6 @@ import android.util.SparseBooleanArray; import android.util.TimeUtils; import android.util.Xml; -import com.google.android.collect.Sets; - import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.IAppOpsService; import com.android.internal.util.FastXmlSerializer; @@ -82,7 +80,6 @@ import java.io.PrintWriter; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; -import java.util.Set; import libcore.io.IoUtils; @@ -147,10 +144,6 @@ public class UserManagerService extends IUserManager.Stub { */ private static final boolean CONFIG_PROFILES_SHARE_CREDENTIAL = true; - // Set of user restrictions, which can only be enforced by the system - private static final Set<String> SYSTEM_CONTROLLED_RESTRICTIONS = Sets.newArraySet( - UserManager.DISALLOW_RECORD_AUDIO); - static final int WRITE_USER_MSG = 1; static final int WRITE_USER_DELAY = 2*1000; // 2 seconds @@ -596,7 +589,7 @@ public class UserManagerService extends IUserManager.Stub { public void setUserRestriction(String key, boolean value, int userId) { checkManageUsersPermission("setUserRestriction"); synchronized (mPackagesLock) { - if (!SYSTEM_CONTROLLED_RESTRICTIONS.contains(key)) { + if (!UserRestrictionsUtils.SYSTEM_CONTROLLED_USER_RESTRICTIONS.contains(key)) { Bundle restrictions = getUserRestrictions(userId); restrictions.putBoolean(key, value); setUserRestrictionsInternalLocked(restrictions, userId); @@ -622,7 +615,7 @@ public class UserManagerService extends IUserManager.Stub { synchronized (mPackagesLock) { final Bundle oldUserRestrictions = mUserRestrictions.get(userId); // Restore the original state of system controlled restrictions from oldUserRestrictions - for (String key : SYSTEM_CONTROLLED_RESTRICTIONS) { + for (String key : UserRestrictionsUtils.SYSTEM_CONTROLLED_USER_RESTRICTIONS) { restrictions.remove(key); if (oldUserRestrictions.containsKey(key)) { restrictions.putBoolean(key, oldUserRestrictions.getBoolean(key)); @@ -815,7 +808,8 @@ public class UserManagerService extends IUserManager.Stub { && type != XmlPullParser.END_TAG) { if (type == XmlPullParser.START_TAG) { if (parser.getName().equals(TAG_RESTRICTIONS)) { - readRestrictionsLocked(parser, mGuestRestrictions); + UserRestrictionsUtils + .readRestrictions(parser, mGuestRestrictions); } break; } @@ -978,7 +972,7 @@ public class UserManagerService extends IUserManager.Stub { serializer.endTag(null, TAG_NAME); Bundle restrictions = mUserRestrictions.get(userInfo.id); if (restrictions != null) { - writeRestrictionsLocked(serializer, restrictions); + UserRestrictionsUtils.writeRestrictions(serializer, restrictions, TAG_RESTRICTIONS); } serializer.endTag(null, TAG_USER); @@ -1016,7 +1010,8 @@ public class UserManagerService extends IUserManager.Stub { serializer.attribute(null, ATTR_USER_VERSION, Integer.toString(mUserVersion)); serializer.startTag(null, TAG_GUEST_RESTRICTIONS); - writeRestrictionsLocked(serializer, mGuestRestrictions); + UserRestrictionsUtils + .writeRestrictions(serializer, mGuestRestrictions, TAG_RESTRICTIONS); serializer.endTag(null, TAG_GUEST_RESTRICTIONS); final int userSize = mUsers.size(); for (int i = 0; i < userSize; i++) { @@ -1036,45 +1031,6 @@ public class UserManagerService extends IUserManager.Stub { } } - private void writeRestrictionsLocked(XmlSerializer serializer, Bundle restrictions) - throws IOException { - serializer.startTag(null, TAG_RESTRICTIONS); - writeBoolean(serializer, restrictions, UserManager.DISALLOW_CONFIG_WIFI); - writeBoolean(serializer, restrictions, UserManager.DISALLOW_MODIFY_ACCOUNTS); - writeBoolean(serializer, restrictions, UserManager.DISALLOW_INSTALL_APPS); - writeBoolean(serializer, restrictions, UserManager.DISALLOW_UNINSTALL_APPS); - writeBoolean(serializer, restrictions, UserManager.DISALLOW_SHARE_LOCATION); - writeBoolean(serializer, restrictions, - UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES); - writeBoolean(serializer, restrictions, UserManager.DISALLOW_CONFIG_BLUETOOTH); - writeBoolean(serializer, restrictions, UserManager.DISALLOW_USB_FILE_TRANSFER); - writeBoolean(serializer, restrictions, UserManager.DISALLOW_CONFIG_CREDENTIALS); - writeBoolean(serializer, restrictions, UserManager.DISALLOW_REMOVE_USER); - writeBoolean(serializer, restrictions, UserManager.DISALLOW_DEBUGGING_FEATURES); - writeBoolean(serializer, restrictions, UserManager.DISALLOW_CONFIG_VPN); - writeBoolean(serializer, restrictions, UserManager.DISALLOW_CONFIG_TETHERING); - writeBoolean(serializer, restrictions, UserManager.DISALLOW_NETWORK_RESET); - writeBoolean(serializer, restrictions, UserManager.DISALLOW_FACTORY_RESET); - writeBoolean(serializer, restrictions, UserManager.DISALLOW_ADD_USER); - writeBoolean(serializer, restrictions, UserManager.ENSURE_VERIFY_APPS); - writeBoolean(serializer, restrictions, UserManager.DISALLOW_CONFIG_CELL_BROADCASTS); - writeBoolean(serializer, restrictions, UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS); - writeBoolean(serializer, restrictions, UserManager.DISALLOW_APPS_CONTROL); - writeBoolean(serializer, restrictions, UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA); - writeBoolean(serializer, restrictions, UserManager.DISALLOW_UNMUTE_MICROPHONE); - writeBoolean(serializer, restrictions, UserManager.DISALLOW_ADJUST_VOLUME); - writeBoolean(serializer, restrictions, UserManager.DISALLOW_OUTGOING_CALLS); - writeBoolean(serializer, restrictions, UserManager.DISALLOW_SMS); - writeBoolean(serializer, restrictions, UserManager.DISALLOW_FUN); - writeBoolean(serializer, restrictions, UserManager.DISALLOW_CREATE_WINDOWS); - writeBoolean(serializer, restrictions, UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE); - writeBoolean(serializer, restrictions, UserManager.DISALLOW_OUTGOING_BEAM); - writeBoolean(serializer, restrictions, UserManager.DISALLOW_WALLPAPER); - writeBoolean(serializer, restrictions, UserManager.DISALLOW_SAFE_BOOT); - writeBoolean(serializer, restrictions, UserManager.ALLOW_PARENT_PROFILE_APP_LINKING); - serializer.endTag(null, TAG_RESTRICTIONS); - } - private UserInfo readUserLocked(int id) { int flags = 0; int serialNumber = id; @@ -1143,7 +1099,7 @@ public class UserManagerService extends IUserManager.Stub { name = parser.getText(); } } else if (TAG_RESTRICTIONS.equals(tag)) { - readRestrictionsLocked(parser, restrictions); + UserRestrictionsUtils.readRestrictions(parser, restrictions); } } } @@ -1172,60 +1128,6 @@ public class UserManagerService extends IUserManager.Stub { return null; } - private void readRestrictionsLocked(XmlPullParser parser, Bundle restrictions) - throws IOException { - readBoolean(parser, restrictions, UserManager.DISALLOW_CONFIG_WIFI); - readBoolean(parser, restrictions, UserManager.DISALLOW_MODIFY_ACCOUNTS); - readBoolean(parser, restrictions, UserManager.DISALLOW_INSTALL_APPS); - readBoolean(parser, restrictions, UserManager.DISALLOW_UNINSTALL_APPS); - readBoolean(parser, restrictions, UserManager.DISALLOW_SHARE_LOCATION); - readBoolean(parser, restrictions, - UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES); - readBoolean(parser, restrictions, UserManager.DISALLOW_CONFIG_BLUETOOTH); - readBoolean(parser, restrictions, UserManager.DISALLOW_USB_FILE_TRANSFER); - readBoolean(parser, restrictions, UserManager.DISALLOW_CONFIG_CREDENTIALS); - readBoolean(parser, restrictions, UserManager.DISALLOW_REMOVE_USER); - readBoolean(parser, restrictions, UserManager.DISALLOW_DEBUGGING_FEATURES); - readBoolean(parser, restrictions, UserManager.DISALLOW_CONFIG_VPN); - readBoolean(parser, restrictions, UserManager.DISALLOW_CONFIG_TETHERING); - readBoolean(parser, restrictions, UserManager.DISALLOW_NETWORK_RESET); - readBoolean(parser, restrictions, UserManager.DISALLOW_FACTORY_RESET); - readBoolean(parser, restrictions, UserManager.DISALLOW_ADD_USER); - readBoolean(parser, restrictions, UserManager.ENSURE_VERIFY_APPS); - readBoolean(parser, restrictions, UserManager.DISALLOW_CONFIG_CELL_BROADCASTS); - readBoolean(parser, restrictions, UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS); - readBoolean(parser, restrictions, UserManager.DISALLOW_APPS_CONTROL); - readBoolean(parser, restrictions, - UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA); - readBoolean(parser, restrictions, UserManager.DISALLOW_UNMUTE_MICROPHONE); - readBoolean(parser, restrictions, UserManager.DISALLOW_ADJUST_VOLUME); - readBoolean(parser, restrictions, UserManager.DISALLOW_OUTGOING_CALLS); - readBoolean(parser, restrictions, UserManager.DISALLOW_SMS); - readBoolean(parser, restrictions, UserManager.DISALLOW_FUN); - readBoolean(parser, restrictions, UserManager.DISALLOW_CREATE_WINDOWS); - readBoolean(parser, restrictions, UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE); - readBoolean(parser, restrictions, UserManager.DISALLOW_OUTGOING_BEAM); - readBoolean(parser, restrictions, UserManager.DISALLOW_WALLPAPER); - readBoolean(parser, restrictions, UserManager.DISALLOW_SAFE_BOOT); - readBoolean(parser, restrictions, UserManager.ALLOW_PARENT_PROFILE_APP_LINKING); - } - - private void readBoolean(XmlPullParser parser, Bundle restrictions, - String restrictionKey) { - String value = parser.getAttributeValue(null, restrictionKey); - if (value != null) { - restrictions.putBoolean(restrictionKey, Boolean.parseBoolean(value)); - } - } - - private void writeBoolean(XmlSerializer xml, Bundle restrictions, String restrictionKey) - throws IOException { - if (restrictions.containsKey(restrictionKey)) { - xml.attribute(null, restrictionKey, - Boolean.toString(restrictions.getBoolean(restrictionKey))); - } - } - private int readIntAttribute(XmlPullParser parser, String attr, int defaultValue) { String valueString = parser.getAttributeValue(null, attr); if (valueString == null) return defaultValue; @@ -2142,7 +2044,13 @@ public class UserManagerService extends IUserManager.Stub { sb.append(" ago"); pw.println(sb); } + pw.println(" Restrictions:"); + UserRestrictionsUtils.dumpRestrictions( + pw, " ", mUserRestrictions.get(user.id)); } + pw.println(); + pw.println("Guest restrictions:"); + UserRestrictionsUtils.dumpRestrictions(pw, " ", mGuestRestrictions); } } diff --git a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java new file mode 100644 index 000000000000..db1fd2e28dfa --- /dev/null +++ b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.pm; + +import com.google.android.collect.Sets; + +import com.android.internal.util.Preconditions; + +import android.os.Bundle; +import android.os.UserManager; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlSerializer; + +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Set; + +public class UserRestrictionsUtils { + private UserRestrictionsUtils() { + } + + public static final String[] USER_RESTRICTIONS = { + UserManager.DISALLOW_CONFIG_WIFI, + UserManager.DISALLOW_MODIFY_ACCOUNTS, + UserManager.DISALLOW_INSTALL_APPS, + UserManager.DISALLOW_UNINSTALL_APPS, + UserManager.DISALLOW_SHARE_LOCATION, + UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, + UserManager.DISALLOW_CONFIG_BLUETOOTH, + UserManager.DISALLOW_USB_FILE_TRANSFER, + UserManager.DISALLOW_CONFIG_CREDENTIALS, + UserManager.DISALLOW_REMOVE_USER, + UserManager.DISALLOW_DEBUGGING_FEATURES, + UserManager.DISALLOW_CONFIG_VPN, + UserManager.DISALLOW_CONFIG_TETHERING, + UserManager.DISALLOW_NETWORK_RESET, + UserManager.DISALLOW_FACTORY_RESET, + UserManager.DISALLOW_ADD_USER, + UserManager.ENSURE_VERIFY_APPS, + UserManager.DISALLOW_CONFIG_CELL_BROADCASTS, + UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS, + UserManager.DISALLOW_APPS_CONTROL, + UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA, + UserManager.DISALLOW_UNMUTE_MICROPHONE, + UserManager.DISALLOW_ADJUST_VOLUME, + UserManager.DISALLOW_OUTGOING_CALLS, + UserManager.DISALLOW_SMS, + UserManager.DISALLOW_FUN, + UserManager.DISALLOW_CREATE_WINDOWS, + UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE, + UserManager.DISALLOW_OUTGOING_BEAM, + UserManager.DISALLOW_WALLPAPER, + UserManager.DISALLOW_SAFE_BOOT, + UserManager.ALLOW_PARENT_PROFILE_APP_LINKING, + UserManager.DISALLOW_RECORD_AUDIO, + }; + + /** + * Set of user restrictions, which can only be enforced by the system. + */ + public static final Set<String> SYSTEM_CONTROLLED_USER_RESTRICTIONS = Sets.newArraySet( + UserManager.DISALLOW_RECORD_AUDIO); + + /** + * Set of user restriction which we don't want to persist. + */ + public static final Set<String> NON_PERSIST_USER_RESTRICTIONS = Sets.newArraySet( + UserManager.DISALLOW_RECORD_AUDIO); + + public static void writeRestrictions(XmlSerializer serializer, Bundle restrictions, + String tag) throws IOException { + serializer.startTag(null, tag); + for (String key : USER_RESTRICTIONS) { + // + if (restrictions.getBoolean(key) + && !NON_PERSIST_USER_RESTRICTIONS.contains(key)) { + serializer.attribute(null, key, "true"); + } + } + serializer.endTag(null, tag); + } + + public static void readRestrictions(XmlPullParser parser, Bundle restrictions) + throws IOException { + for (String key : USER_RESTRICTIONS) { + final String value = parser.getAttributeValue(null, key); + if (value != null) { + restrictions.putBoolean(key, Boolean.parseBoolean(value)); + } + } + } + + public static void dumpRestrictions(PrintWriter pw, String prefix, Bundle restrictions) { + boolean noneSet = true; + if (restrictions != null) { + for (String key : restrictions.keySet()) { + if (restrictions.getBoolean(key, false)) { + pw.println(prefix + key); + noneSet = false; + } + } + } + if (noneSet) { + pw.println(prefix + "none"); + } + } +} diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index e85f01a9d8da..cb5ab1bc8569 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -124,6 +124,7 @@ import com.android.internal.widget.LockPatternUtils; import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.devicepolicy.DevicePolicyManagerService.ActiveAdmin.TrustAgentInfo; +import com.android.server.pm.UserRestrictionsUtils; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -277,7 +278,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { final LocalService mLocalService; // Stores and loads state on device and profile owners. - private final Owners mOwners; + @VisibleForTesting + final Owners mOwners; private final Binder mToken = new Binder(); @@ -433,6 +435,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private static final String TAG_PROVIDER = "provider"; private static final String TAG_PACKAGE_LIST_ITEM = "item"; + private static final String TAG_USER_RESTRICTIONS = "user-restrictions"; + final DeviceAdminInfo info; int passwordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; @@ -512,6 +516,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { List<String> crossProfileWidgetProviders; + Bundle userRestrictions; + ActiveAdmin(DeviceAdminInfo _info) { info = _info; } @@ -686,6 +692,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { writePackageListToXml(out, TAG_PERMITTED_ACCESSIBILITY_SERVICES, permittedAccessiblityServices); writePackageListToXml(out, TAG_PERMITTED_IMES, permittedInputMethods); + if (hasUserRestrictions()) { + UserRestrictionsUtils.writeRestrictions( + out, userRestrictions, TAG_USER_RESTRICTIONS); + } } void writePackageListToXml(XmlSerializer out, String outerTag, @@ -795,6 +805,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { permittedAccessiblityServices = readPackageList(parser, tag); } else if (TAG_PERMITTED_IMES.equals(tag)) { permittedInputMethods = readPackageList(parser, tag); + } else if (TAG_USER_RESTRICTIONS.equals(tag)) { + UserRestrictionsUtils.readRestrictions(parser, ensureUserRestrictions()); } else { Slog.w(LOG_TAG, "Unknown admin tag: " + tag); XmlUtils.skipCurrentTag(parser); @@ -915,6 +927,17 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return result; } + boolean hasUserRestrictions() { + return userRestrictions != null && userRestrictions.size() > 0; + } + + Bundle ensureUserRestrictions() { + if (userRestrictions == null) { + userRestrictions = new Bundle(); + } + return userRestrictions; + } + void dump(String prefix, PrintWriter pw) { pw.print(prefix); pw.print("uid="); pw.println(getUid()); pw.print(prefix); pw.println("policies:"); @@ -984,6 +1007,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { pw.print(prefix); pw.print("permittedInputMethods="); pw.println(permittedInputMethods.toString()); } + pw.print(prefix); pw.println("userRestrictions:"); + UserRestrictionsUtils.dumpRestrictions(pw, prefix + " ", userRestrictions); } } @@ -1116,6 +1141,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return getCallingUid() == Process.myUid(); } + final int userHandleGetCallingUserId() { + return UserHandle.getUserId(binderGetCallingUid()); + } + File environmentGetUserSystemDirectory(int userId) { return Environment.getUserSystemDirectory(userId); } @@ -1151,6 +1180,42 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { String getDevicePolicyFilePathForSystemUser() { return "/data/system/"; } + + int settingsSecureGetIntForUser(String name, int def, int userHandle) { + return Settings.Secure.getIntForUser(mContext.getContentResolver(), + name, def, userHandle); + } + + void settingsSecurePutIntForUser(String name, int value, int userHandle) { + Settings.Secure.putIntForUser(mContext.getContentResolver(), + name, value, userHandle); + } + + void settingsSecurePutStringForUser(String name, String value, int userHandle) { + Settings.Secure.putStringForUser(mContext.getContentResolver(), + name, value, userHandle); + } + + void settingsGlobalPutStringForUser(String name, String value, int userHandle) { + Settings.Global.putStringForUser(mContext.getContentResolver(), + name, value, userHandle); + } + + void settingsSecurePutInt(String name, int value) { + Settings.Secure.putInt(mContext.getContentResolver(), name, value); + } + + void settingsGlobalPutInt(String name, int value) { + Settings.Global.putInt(mContext.getContentResolver(), name, value); + } + + void settingsSecurePutString(String name, String value) { + Settings.Secure.putString(mContext.getContentResolver(), name, value); + } + + void settingsGlobalPutString(String name, String value) { + Settings.Global.putString(mContext.getContentResolver(), name, value); + } } /** @@ -3158,8 +3223,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } else { // Make sure KEEP_SCREEN_ON is disabled, since that // would allow bypassing of the maximum time to lock. - Settings.Global.putInt(mContext.getContentResolver(), - Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0); + mInjector.settingsGlobalPutInt(Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0); } policy.mLastMaximumTimeToLock = timeMs; @@ -3378,7 +3442,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // If there is a profile owner, redirect to that; otherwise query the device owner. ComponentName aliasChooser = getProfileOwner(caller.getIdentifier()); if (aliasChooser == null && caller.isOwner()) { - ActiveAdmin deviceOwnerAdmin = getDeviceOwnerAdmin(); + ActiveAdmin deviceOwnerAdmin = getDeviceOwnerAdminLocked(); if (deviceOwnerAdmin != null) { aliasChooser = deviceOwnerAdmin.info.getComponent(); } @@ -3838,16 +3902,15 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } catch (NumberFormatException e) {} } exclusionList = exclusionList.trim(); - ContentResolver res = mContext.getContentResolver(); ProxyInfo proxyProperties = new ProxyInfo(data[0], proxyPort, exclusionList); if (!proxyProperties.isValid()) { Slog.e(LOG_TAG, "Invalid proxy properties, ignoring: " + proxyProperties.toString()); return; } - Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_HOST, data[0]); - Settings.Global.putInt(res, Settings.Global.GLOBAL_HTTP_PROXY_PORT, proxyPort); - Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST, + mInjector.settingsGlobalPutString(Settings.Global.GLOBAL_HTTP_PROXY_HOST, data[0]); + mInjector.settingsGlobalPutInt(Settings.Global.GLOBAL_HTTP_PROXY_PORT, proxyPort); + mInjector.settingsGlobalPutString(Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST, exclusionList); } @@ -4071,8 +4134,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (required) { long ident = mInjector.binderClearCallingIdentity(); try { - Settings.Global.putInt(mContext.getContentResolver(), - Settings.Global.AUTO_TIME, 1 /* AUTO_TIME on */); + mInjector.settingsGlobalPutInt(Settings.Global.AUTO_TIME, 1 /* AUTO_TIME on */); } finally { mInjector.binderRestoreCallingIdentity(ident); } @@ -4088,7 +4150,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return false; } synchronized (this) { - ActiveAdmin deviceOwner = getDeviceOwnerAdmin(); + ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked(); return (deviceOwner != null) ? deviceOwner.requireAutoTime : false; } } @@ -4309,7 +4371,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } // Returns the active device owner or null if there is no device owner. - private ActiveAdmin getDeviceOwnerAdmin() { + @VisibleForTesting + ActiveAdmin getDeviceOwnerAdminLocked() { String deviceOwnerPackageName = getDeviceOwner(); if (deviceOwnerPackageName == null) { return null; @@ -4502,7 +4565,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // Returns the active profile owner for this user or null if the current user has no // profile owner. - private ActiveAdmin getProfileOwnerAdmin(int userHandle) { + @VisibleForTesting + ActiveAdmin getProfileOwnerAdminLocked(int userHandle) { ComponentName profileOwner = mOwners.getProfileOwnerComponent(userHandle); if (profileOwner == null) { return null; @@ -5374,7 +5438,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public void setUserRestriction(ComponentName who, String key, boolean enabled) { Preconditions.checkNotNull(who, "ComponentName is null"); - final int userHandle = UserHandle.getCallingUserId(); + final int userHandle = mInjector.userHandleGetCallingUserId(); final UserHandle user = new UserHandle(userHandle); synchronized (this) { ActiveAdmin activeAdmin = @@ -5399,37 +5463,40 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { mInjector.getIAudioService() .setMasterMute(true, 0, mContext.getPackageName(), userHandle); } else if (UserManager.DISALLOW_CONFIG_WIFI.equals(key)) { - Settings.Secure.putIntForUser(mContext.getContentResolver(), + mInjector.settingsSecurePutIntForUser( Settings.Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, 0, userHandle); } else if (UserManager.DISALLOW_SHARE_LOCATION.equals(key)) { - Settings.Secure.putIntForUser(mContext.getContentResolver(), + mInjector.settingsSecurePutIntForUser( Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF, userHandle); - Settings.Secure.putStringForUser(mContext.getContentResolver(), + mInjector.settingsSecurePutStringForUser( Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "", userHandle); } else if (UserManager.DISALLOW_DEBUGGING_FEATURES.equals(key)) { // Only disable adb if changing for system user, since it is global // TODO: should this be admin user? if (userHandle == UserHandle.USER_SYSTEM) { - Settings.Global.putStringForUser(mContext.getContentResolver(), + mInjector.settingsGlobalPutStringForUser( Settings.Global.ADB_ENABLED, "0", userHandle); } } else if (UserManager.ENSURE_VERIFY_APPS.equals(key)) { - Settings.Global.putStringForUser(mContext.getContentResolver(), + mInjector.settingsGlobalPutStringForUser( Settings.Global.PACKAGE_VERIFIER_ENABLE, "1", userHandle); - Settings.Global.putStringForUser(mContext.getContentResolver(), + mInjector.settingsGlobalPutStringForUser( Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, "1", userHandle); } else if (UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES.equals(key)) { - Settings.Secure.putIntForUser(mContext.getContentResolver(), + mInjector.settingsSecurePutIntForUser( Settings.Secure.INSTALL_NON_MARKET_APPS, 0, userHandle); } } mUserManager.setUserRestriction(key, enabled, user); + activeAdmin.ensureUserRestrictions().putBoolean(key, enabled); + saveSettingsLocked(userHandle); + if (enabled != alreadyRestricted) { if (UserManager.DISALLOW_SHARE_LOCATION.equals(key)) { // Send out notifications however as some clients may want to reread the @@ -5730,7 +5797,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // TODO: Should there be a check to make sure this relationship is within a profile group? //enforceSystemProcess("getCrossProfileCallerIdDisabled can only be called by system"); synchronized (this) { - ActiveAdmin admin = getProfileOwnerAdmin(userId); + ActiveAdmin admin = getProfileOwnerAdminLocked(userId); return (admin != null) ? admin.disableCallerId : false; } } @@ -5823,7 +5890,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // within a profile group? // enforceSystemProcess("getCrossProfileCallerIdDisabled can only be called by system"); synchronized (this) { - ActiveAdmin admin = getProfileOwnerAdmin(userId); + ActiveAdmin admin = getProfileOwnerAdminLocked(userId); return (admin != null) ? admin.disableBluetoothContactSharing : false; } } @@ -5926,7 +5993,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public void setGlobalSetting(ComponentName who, String setting, String value) { - final ContentResolver contentResolver = mContext.getContentResolver(); Preconditions.checkNotNull(who, "ComponentName is null"); synchronized (this) { @@ -5954,7 +6020,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { long id = mInjector.binderClearCallingIdentity(); try { - Settings.Global.putString(contentResolver, setting, value); + mInjector.settingsGlobalPutString(setting, value); } finally { mInjector.binderRestoreCallingIdentity(id); } @@ -5983,7 +6049,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { long id = mInjector.binderClearCallingIdentity(); try { - Settings.Secure.putStringForUser(contentResolver, setting, value, callingUserId); + mInjector.settingsSecurePutStringForUser(setting, value, callingUserId); } finally { mInjector.binderRestoreCallingIdentity(id); } @@ -6106,11 +6172,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { */ void updateUserSetupComplete() { List<UserInfo> users = mUserManager.getUsers(true); - ContentResolver resolver = mContext.getContentResolver(); final int N = users.size(); for (int i = 0; i < N; i++) { int userHandle = users.get(i).id; - if (Settings.Secure.getIntForUser(resolver, Settings.Secure.USER_SETUP_COMPLETE, 0, + if (mInjector.settingsSecureGetIntForUser(Settings.Secure.USER_SETUP_COMPLETE, 0, userHandle) != 0) { DevicePolicyData policy = getUserData(userHandle); if (!policy.mUserSetupComplete) { diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java index 76122e1faaa1..f9543c22e086 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java @@ -16,16 +16,11 @@ package com.android.server.devicepolicy; -import android.app.AppGlobals; import android.app.admin.SystemUpdatePolicy; import android.content.ComponentName; import android.content.Context; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.UserInfo; import android.os.Environment; -import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; import android.util.ArrayMap; diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java index f4ffe2ee1d27..b109e7bc9d03 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java @@ -225,5 +225,45 @@ public class DevicePolicyManagerServiceTestable extends DevicePolicyManagerServi boolean userManagerIsSplitSystemUser() { return context.userManagerForMock.isSplitSystemUser(); } + + @Override + int settingsSecureGetIntForUser(String name, int def, int userHandle) { + return context.settings.settingsSecureGetIntForUser(name, def, userHandle); + } + + @Override + void settingsSecurePutIntForUser(String name, int value, int userHandle) { + context.settings.settingsSecurePutIntForUser(name, value, userHandle); + } + + @Override + void settingsSecurePutStringForUser(String name, String value, int userHandle) { + context.settings.settingsSecurePutStringForUser(name, value, userHandle); + } + + @Override + void settingsGlobalPutStringForUser(String name, String value, int userHandle) { + context.settings.settingsGlobalPutStringForUser(name, value, userHandle); + } + + @Override + void settingsSecurePutInt(String name, int value) { + context.settings.settingsSecurePutInt(name, value); + } + + @Override + void settingsGlobalPutInt(String name, int value) { + context.settings.settingsGlobalPutInt(name, value); + } + + @Override + void settingsSecurePutString(String name, String value) { + context.settings.settingsSecurePutString(name, value); + } + + @Override + void settingsGlobalPutString(String name, String value) { + context.settings.settingsGlobalPutString(name, value); + } } } diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java index 5b2379833ad6..03b892e55c41 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java @@ -31,8 +31,8 @@ import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Bundle; import android.content.pm.PackageInfo; -import android.content.pm.UserInfo; import android.os.UserHandle; +import android.os.UserManager; import android.util.Pair; import org.mockito.ArgumentCaptor; @@ -65,8 +65,6 @@ import static org.mockito.Mockito.when; (mmma frameworks/base/services/tests/servicestests/ for non-ninja build) */ public class DevicePolicyManagerTest extends DpmTestBase { - - private DpmMockContext mContext; public DevicePolicyManager dpm; public DevicePolicyManagerServiceTestable dpms; @@ -207,9 +205,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); - final UserInfo uh = new UserInfo(DpmMockContext.CALLER_USER_HANDLE, "user", 0); - - // DO needs to be an DA. + // PO needs to be an DA. dpm.setActiveAdmin(admin, /* replace =*/ false); // Fire! @@ -625,4 +621,97 @@ public class DevicePolicyManagerTest extends DpmTestBase { dpm.setApplicationRestrictions(admin1, "pkg2", new Bundle()); assertEquals(0, dpm.getApplicationRestrictions(admin1, "pkg2").size()); } + + public void testSetUserRestriction_asDo() throws Exception { + mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); + mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); + mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL); + + // First, set DO. + + // Call from a process on the system user. + mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; + + // Make sure admin1 is installed on system user. + setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); + setUpApplicationInfo(PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED, + DpmMockContext.CALLER_SYSTEM_USER_UID); + + // Call. + dpm.setActiveAdmin(admin1, /* replace =*/ false, UserHandle.USER_SYSTEM); + assertTrue(dpm.setDeviceOwner(admin1.getPackageName(), "owner-name", + UserHandle.USER_SYSTEM)); + + assertFalse(dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions() + .getBoolean(UserManager.DISALLOW_SMS)); + assertFalse(dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions() + .getBoolean(UserManager.DISALLOW_OUTGOING_CALLS)); + + dpm.addUserRestriction(admin1, UserManager.DISALLOW_SMS); + dpm.addUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS); + + assertTrue(dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions() + .getBoolean(UserManager.DISALLOW_SMS)); + assertTrue(dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions() + .getBoolean(UserManager.DISALLOW_OUTGOING_CALLS)); + + dpm.clearUserRestriction(admin1, UserManager.DISALLOW_SMS); + + assertFalse(dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions() + .getBoolean(UserManager.DISALLOW_SMS)); + assertTrue(dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions() + .getBoolean(UserManager.DISALLOW_OUTGOING_CALLS)); + + dpm.clearUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS); + + assertFalse(dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions() + .getBoolean(UserManager.DISALLOW_SMS)); + assertFalse(dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions() + .getBoolean(UserManager.DISALLOW_OUTGOING_CALLS)); + + // TODO Check inner calls. + // TODO Make sure restrictions are written to the file. + } + + public void testSetUserRestriction_asPo() { + setAsProfileOwner(admin1); + + assertFalse(dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE) + .ensureUserRestrictions() + .getBoolean(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES)); + assertFalse(dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE) + .ensureUserRestrictions() + .getBoolean(UserManager.DISALLOW_OUTGOING_CALLS)); + + dpm.addUserRestriction(admin1, UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES); + dpm.addUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS); + + assertTrue(dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE) + .ensureUserRestrictions() + .getBoolean(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES)); + assertTrue(dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE) + .ensureUserRestrictions() + .getBoolean(UserManager.DISALLOW_OUTGOING_CALLS)); + + dpm.clearUserRestriction(admin1, UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES); + + assertFalse(dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE) + .ensureUserRestrictions() + .getBoolean(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES)); + assertTrue(dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE) + .ensureUserRestrictions() + .getBoolean(UserManager.DISALLOW_OUTGOING_CALLS)); + + dpm.clearUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS); + + assertFalse(dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE) + .ensureUserRestrictions() + .getBoolean(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES)); + assertFalse(dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE) + .ensureUserRestrictions() + .getBoolean(UserManager.DISALLOW_OUTGOING_CALLS)); + + // TODO Check inner calls. + // TODO Make sure restrictions are written to the file. + } } diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java index 7b36e88c5e29..73d63ea64026 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java @@ -158,6 +158,33 @@ public class DpmMockContext extends MockContext { } } + public static class SettingsForMock { + int settingsSecureGetIntForUser(String name, int def, int userHandle) { + return 0; + } + + void settingsSecurePutIntForUser(String name, int value, int userHandle) { + } + + void settingsSecurePutStringForUser(String name, String value, int userHandle) { + } + + void settingsGlobalPutStringForUser(String name, String value, int userHandle) { + } + + void settingsSecurePutInt(String name, int value) { + } + + void settingsGlobalPutInt(String name, int value) { + } + + void settingsSecurePutString(String name, String value) { + } + + void settingsGlobalPutString(String name, String value) { + } + } + public final Context realTestContext; /** @@ -184,6 +211,7 @@ public class DpmMockContext extends MockContext { public final IBackupManager ibackupManager; public final IAudioService iaudioService; public final LockPatternUtils lockPatternUtils; + public final SettingsForMock settings; /** Note this is a partial mock, not a real mock. */ public final PackageManager packageManager; @@ -212,6 +240,7 @@ public class DpmMockContext extends MockContext { ibackupManager = mock(IBackupManager.class); iaudioService = mock(IAudioService.class); lockPatternUtils = mock(LockPatternUtils.class); + settings = mock(SettingsForMock.class); // Package manager is huge, so we use a partial mock instead. packageManager = spy(context.getPackageManager()); diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/OwnersTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/OwnersTest.java index 525562861dc2..a210d4652fe3 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/OwnersTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/OwnersTest.java @@ -21,6 +21,7 @@ import com.android.server.devicepolicy.DevicePolicyManagerServiceTestable.Owners import android.content.ComponentName; import android.content.pm.UserInfo; import android.os.UserHandle; +import android.os.UserManager; import android.util.Log; import java.io.BufferedReader; @@ -28,6 +29,8 @@ import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.io.StringWriter; import java.util.ArrayList; import static org.mockito.Mockito.when; |