summaryrefslogtreecommitdiffstats
path: root/services/devicepolicy
diff options
context:
space:
mode:
Diffstat (limited to 'services/devicepolicy')
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DeviceOwner.java90
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java682
2 files changed, 462 insertions, 310 deletions
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DeviceOwner.java b/services/devicepolicy/java/com/android/server/devicepolicy/DeviceOwner.java
index 9fd0e09..ea59d4b 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DeviceOwner.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DeviceOwner.java
@@ -39,18 +39,21 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.io.PrintWriter;
import java.util.HashMap;
+import java.util.Map;
import java.util.Set;
/**
* Stores and restores state for the Device and Profile owners. By definition there can be
* only one device owner, but there may be a profile owner for each user.
*/
-public class DeviceOwner {
+class DeviceOwner {
private static final String TAG = "DevicePolicyManagerService";
private static final String DEVICE_OWNER_XML = "device_owner.xml";
private static final String TAG_DEVICE_OWNER = "device-owner";
+ private static final String TAG_DEVICE_INITIALIZER = "device-initializer";
private static final String TAG_PROFILE_OWNER = "profile-owner";
private static final String ATTR_NAME = "name";
private static final String ATTR_PACKAGE = "package";
@@ -66,6 +69,9 @@ public class DeviceOwner {
// Internal state for the device owner package.
private OwnerInfo mDeviceOwner;
+ // Internal state for the device initializer package.
+ private OwnerInfo mDeviceInitializer;
+
// Internal state for the profile owner packages.
private final HashMap<Integer, OwnerInfo> mProfileOwners = new HashMap<Integer, OwnerInfo>();
@@ -102,12 +108,11 @@ public class DeviceOwner {
}
/**
- * @deprecated Use a component name instead of package name
- * Creates an instance of the device owner object with the profile owner set.
+ * Creates an instance of the device owner object with the device initializer set.
*/
- static DeviceOwner createWithProfileOwner(String packageName, String ownerName, int userId) {
+ static DeviceOwner createWithDeviceInitializer(String packageName, String ownerName) {
DeviceOwner owner = new DeviceOwner();
- owner.mProfileOwners.put(userId, new OwnerInfo(ownerName, packageName));
+ owner.mDeviceInitializer = new OwnerInfo(ownerName, packageName);
return owner;
}
@@ -136,11 +141,24 @@ public class DeviceOwner {
mDeviceOwner = null;
}
- /**
- * @deprecated
- */
- void setProfileOwner(String packageName, String ownerName, int userId) {
- mProfileOwners.put(userId, new OwnerInfo(ownerName, packageName));
+ String getDeviceInitializerPackageName() {
+ return mDeviceInitializer != null ? mDeviceInitializer.packageName : null;
+ }
+
+ String getDeviceInitializerName() {
+ return mDeviceInitializer != null ? mDeviceInitializer.name : null;
+ }
+
+ void setDeviceInitializer(String packageName, String ownerName) {
+ mDeviceInitializer = new OwnerInfo(ownerName, packageName);
+ }
+
+ void clearDeviceInitializer() {
+ mDeviceInitializer = null;
+ }
+
+ boolean hasDeviceInitializer() {
+ return mDeviceInitializer != null;
}
void setProfileOwner(ComponentName admin, String ownerName, int userId) {
@@ -151,16 +169,6 @@ public class DeviceOwner {
mProfileOwners.remove(userId);
}
- /**
- * @deprecated Use getProfileOwnerComponent
- * @param userId
- * @return
- */
- String getProfileOwnerPackageName(int userId) {
- OwnerInfo profileOwner = mProfileOwners.get(userId);
- return profileOwner != null ? profileOwner.packageName : null;
- }
-
ComponentName getProfileOwnerComponent(int userId) {
OwnerInfo profileOwner = mProfileOwners.get(userId);
return profileOwner != null ? profileOwner.admin : null;
@@ -207,6 +215,7 @@ public class DeviceOwner {
return false;
}
+ @VisibleForTesting
void readOwnerFile() {
try {
InputStream input = openRead();
@@ -223,6 +232,10 @@ public class DeviceOwner {
String name = parser.getAttributeValue(null, ATTR_NAME);
String packageName = parser.getAttributeValue(null, ATTR_PACKAGE);
mDeviceOwner = new OwnerInfo(name, packageName);
+ } else if (tag.equals(TAG_DEVICE_INITIALIZER)) {
+ String name = parser.getAttributeValue(null, ATTR_NAME);
+ String packageName = parser.getAttributeValue(null, ATTR_PACKAGE);
+ mDeviceInitializer = new OwnerInfo(name, packageName);
} else if (tag.equals(TAG_PROFILE_OWNER)) {
String profileOwnerPackageName = parser.getAttributeValue(null, ATTR_PACKAGE);
String profileOwnerName = parser.getAttributeValue(null, ATTR_NAME);
@@ -259,6 +272,7 @@ public class DeviceOwner {
}
}
+ @VisibleForTesting
void writeOwnerFile() {
synchronized (this) {
writeOwnerFileLocked();
@@ -282,6 +296,16 @@ public class DeviceOwner {
out.endTag(null, TAG_DEVICE_OWNER);
}
+ // Write device initializer tag
+ if (mDeviceInitializer != null) {
+ out.startTag(null, TAG_DEVICE_INITIALIZER);
+ out.attribute(null, ATTR_PACKAGE, mDeviceInitializer.packageName);
+ if (mDeviceInitializer.name != null) {
+ out.attribute(null, ATTR_NAME, mDeviceInitializer.name);
+ }
+ out.endTag(null, TAG_DEVICE_INITIALIZER);
+ }
+
// Write profile owner tags
if (mProfileOwners.size() > 0) {
for (HashMap.Entry<Integer, OwnerInfo> owner : mProfileOwners.entrySet()) {
@@ -329,10 +353,10 @@ public class DeviceOwner {
}
}
- static class OwnerInfo {
- public String name;
- public String packageName;
- public ComponentName admin;
+ private static class OwnerInfo {
+ public final String name;
+ public final String packageName;
+ public final ComponentName admin;
public OwnerInfo(String name, String packageName) {
this.name = name;
@@ -345,5 +369,23 @@ public class DeviceOwner {
this.admin = admin;
this.packageName = admin.getPackageName();
}
+ public void dump(String prefix, PrintWriter pw) {
+ pw.println(prefix + "admin=" + admin);
+ pw.println(prefix + "name=" + name);
+ pw.println();
+ }
+ }
+
+ public void dump(String prefix, PrintWriter pw) {
+ if (mDeviceOwner != null) {
+ pw.println(prefix + "Device Owner: ");
+ mDeviceOwner.dump(prefix + " ", pw);
+ }
+ if (mProfileOwners != null) {
+ for (Map.Entry<Integer, OwnerInfo> entry : mProfileOwners.entrySet()) {
+ pw.println(prefix + "Profile Owner (User " + entry.getKey() + "): ");
+ entry.getValue().dump(prefix + " ", pw);
+ }
+ }
}
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 40e2056..00d7971 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -48,8 +48,10 @@ import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
import android.content.pm.UserInfo;
import android.database.ContentObserver;
+import android.graphics.Bitmap;
import android.hardware.usb.UsbManager;
import android.media.AudioManager;
import android.media.IAudioService;
@@ -77,6 +79,7 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.security.Credentials;
+import android.security.IKeyChainAliasCallback;
import android.security.IKeyChainService;
import android.security.KeyChain;
import android.security.KeyChain.KeyChainConnection;
@@ -98,6 +101,7 @@ import com.android.internal.R;
import com.android.internal.os.storage.ExternalStorageFormatter;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.JournaledFile;
+import com.android.internal.util.Preconditions;
import com.android.internal.util.XmlUtils;
import com.android.internal.widget.LockPatternUtils;
import com.android.server.LocalServices;
@@ -176,6 +180,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_SMS);
}
+ // The following user restrictions cannot be changed by any active admin, including device
+ // owner and profile owner.
+ private static final Set<String> IMMUTABLE_USER_RESTRICTIONS;
+ static {
+ IMMUTABLE_USER_RESTRICTIONS = new HashSet();
+ IMMUTABLE_USER_RESTRICTIONS.add(UserManager.DISALLOW_WALLPAPER);
+ }
+
private static final Set<String> SECURE_SETTINGS_WHITELIST;
private static final Set<String> SECURE_SETTINGS_DEVICEOWNER_WHITELIST;
private static final Set<String> GLOBAL_SETTINGS_WHITELIST;
@@ -193,13 +205,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.ADB_ENABLED);
GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.AUTO_TIME);
GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.AUTO_TIME_ZONE);
- GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.BLUETOOTH_ON);
GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.DATA_ROAMING);
GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.DEVELOPMENT_SETTINGS_ENABLED);
GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.MODE_RINGER);
GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.NETWORK_PREFERENCE);
GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.USB_MASS_STORAGE_ENABLED);
- GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.WIFI_ON);
GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.WIFI_SLEEP_POLICY);
}
@@ -1138,13 +1148,15 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
boolean ownsProfile = (getProfileOwner(userHandle) != null
&& getProfileOwner(userHandle).getPackageName()
.equals(admin.info.getPackageName()));
+ boolean ownsInitialization = isDeviceInitializer(admin.info.getPackageName())
+ && !hasUserSetupCompleted(userHandle);
if (reqPolicy == DeviceAdminInfo.USES_POLICY_DEVICE_OWNER) {
- if (ownsDevice) {
+ if (ownsDevice || (userHandle == UserHandle.USER_OWNER && ownsInitialization)) {
return admin;
}
} else if (reqPolicy == DeviceAdminInfo.USES_POLICY_PROFILE_OWNER) {
- if (ownsDevice || ownsProfile) {
+ if (ownsDevice || ownsProfile || ownsInitialization) {
return admin;
}
} else {
@@ -1518,11 +1530,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
// a sanity check in case the two get out of sync; this should
// never normally happen.
LockPatternUtils utils = new LockPatternUtils(mContext);
- if (utils.getActivePasswordQuality() < policy.mActivePasswordQuality) {
+ if (utils.getActivePasswordQuality(userHandle) < policy.mActivePasswordQuality) {
Slog.w(LOG_TAG, "Active password quality 0x"
+ Integer.toHexString(policy.mActivePasswordQuality)
+ " does not match actual quality 0x"
- + Integer.toHexString(utils.getActivePasswordQuality()));
+ + Integer.toHexString(utils.getActivePasswordQuality(userHandle)));
policy.mActivePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
policy.mActivePasswordLength = 0;
policy.mActivePasswordUpperCase = 0;
@@ -1578,15 +1590,16 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
void syncDeviceCapabilitiesLocked(DevicePolicyData policy) {
// Ensure the status of the camera is synced down to the system. Interested native services
// should monitor this value and act accordingly.
- boolean systemState = SystemProperties.getBoolean(SYSTEM_PROP_DISABLE_CAMERA, false);
+ String cameraPropertyForUser = SYSTEM_PROP_DISABLE_CAMERA_PREFIX + policy.mUserHandle;
+ boolean systemState = SystemProperties.getBoolean(cameraPropertyForUser, false);
boolean cameraDisabled = getCameraDisabled(null, policy.mUserHandle);
if (cameraDisabled != systemState) {
long token = Binder.clearCallingIdentity();
try {
String value = cameraDisabled ? "1" : "0";
if (DBG) Slog.v(LOG_TAG, "Change in camera state ["
- + SYSTEM_PROP_DISABLE_CAMERA + "] = " + value);
- SystemProperties.set(SYSTEM_PROP_DISABLE_CAMERA, value);
+ + cameraPropertyForUser + "] = " + value);
+ SystemProperties.set(cameraPropertyForUser, value);
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -1897,7 +1910,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
return;
}
if (admin.getUid() != Binder.getCallingUid()) {
- // If trying to remove device owner, refuse when the caller is not the owner.
+ // Active device owners must remain active admins.
if (isDeviceOwner(adminReceiver.getPackageName())) {
return;
}
@@ -1913,17 +1926,15 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
}
- public void setPasswordQuality(ComponentName who, int quality, int userHandle) {
+ public void setPasswordQuality(ComponentName who, int quality) {
if (!mHasFeature) {
return;
}
+ Preconditions.checkNotNull(who, "ComponentName is null");
+ final int userHandle = UserHandle.getCallingUserId();
validateQualityConstant(quality);
- enforceCrossUserPermission(userHandle);
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
ActiveAdmin ap = getActiveAdminForCallerLocked(who,
DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
if (ap.passwordQuality != quality) {
@@ -1962,15 +1973,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
}
- public void setPasswordMinimumLength(ComponentName who, int length, int userHandle) {
+ public void setPasswordMinimumLength(ComponentName who, int length) {
if (!mHasFeature) {
return;
}
- enforceCrossUserPermission(userHandle);
+ Preconditions.checkNotNull(who, "ComponentName is null");
+ final int userHandle = UserHandle.getCallingUserId();
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
ActiveAdmin ap = getActiveAdminForCallerLocked(who,
DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
if (ap.minimumPasswordLength != length) {
@@ -2009,15 +2018,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
}
- public void setPasswordHistoryLength(ComponentName who, int length, int userHandle) {
+ public void setPasswordHistoryLength(ComponentName who, int length) {
if (!mHasFeature) {
return;
}
- enforceCrossUserPermission(userHandle);
+ Preconditions.checkNotNull(who, "ComponentName is null");
+ final int userHandle = UserHandle.getCallingUserId();
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
ActiveAdmin ap = getActiveAdminForCallerLocked(who,
DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
if (ap.passwordHistoryLength != length) {
@@ -2056,18 +2063,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
}
- public void setPasswordExpirationTimeout(ComponentName who, long timeout, int userHandle) {
+ public void setPasswordExpirationTimeout(ComponentName who, long timeout) {
if (!mHasFeature) {
return;
}
- enforceCrossUserPermission(userHandle);
+ Preconditions.checkNotNull(who, "ComponentName is null");
+ Preconditions.checkArgumentNonnegative(timeout, "Timeout must be >= 0 ms");
+ final int userHandle = UserHandle.getCallingUserId();
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
- if (timeout < 0) {
- throw new IllegalArgumentException("Timeout must be >= 0 ms");
- }
ActiveAdmin ap = getActiveAdminForCallerLocked(who,
DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD);
// Calling this API automatically bumps the expiration date
@@ -2225,15 +2228,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
}
- public void setPasswordMinimumUpperCase(ComponentName who, int length, int userHandle) {
+ public void setPasswordMinimumUpperCase(ComponentName who, int length) {
if (!mHasFeature) {
return;
}
- enforceCrossUserPermission(userHandle);
+ Preconditions.checkNotNull(who, "ComponentName is null");
+ final int userHandle = UserHandle.getCallingUserId();
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
ActiveAdmin ap = getActiveAdminForCallerLocked(who,
DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
if (ap.minimumPasswordUpperCase != length) {
@@ -2272,12 +2273,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
}
- public void setPasswordMinimumLowerCase(ComponentName who, int length, int userHandle) {
- enforceCrossUserPermission(userHandle);
+ public void setPasswordMinimumLowerCase(ComponentName who, int length) {
+ Preconditions.checkNotNull(who, "ComponentName is null");
+ final int userHandle = UserHandle.getCallingUserId();
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
ActiveAdmin ap = getActiveAdminForCallerLocked(who,
DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
if (ap.minimumPasswordLowerCase != length) {
@@ -2316,15 +2315,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
}
- public void setPasswordMinimumLetters(ComponentName who, int length, int userHandle) {
+ public void setPasswordMinimumLetters(ComponentName who, int length) {
if (!mHasFeature) {
return;
}
- enforceCrossUserPermission(userHandle);
+ Preconditions.checkNotNull(who, "ComponentName is null");
+ final int userHandle = UserHandle.getCallingUserId();
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
ActiveAdmin ap = getActiveAdminForCallerLocked(who,
DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
if (ap.minimumPasswordLetters != length) {
@@ -2363,15 +2360,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
}
- public void setPasswordMinimumNumeric(ComponentName who, int length, int userHandle) {
+ public void setPasswordMinimumNumeric(ComponentName who, int length) {
if (!mHasFeature) {
return;
}
- enforceCrossUserPermission(userHandle);
+ Preconditions.checkNotNull(who, "ComponentName is null");
+ final int userHandle = UserHandle.getCallingUserId();
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
ActiveAdmin ap = getActiveAdminForCallerLocked(who,
DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
if (ap.minimumPasswordNumeric != length) {
@@ -2410,15 +2405,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
}
- public void setPasswordMinimumSymbols(ComponentName who, int length, int userHandle) {
+ public void setPasswordMinimumSymbols(ComponentName who, int length) {
if (!mHasFeature) {
return;
}
- enforceCrossUserPermission(userHandle);
+ Preconditions.checkNotNull(who, "ComponentName is null");
+ final int userHandle = UserHandle.getCallingUserId();
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
ActiveAdmin ap = getActiveAdminForCallerLocked(who,
DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
if (ap.minimumPasswordSymbols != length) {
@@ -2457,15 +2450,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
}
- public void setPasswordMinimumNonLetter(ComponentName who, int length, int userHandle) {
+ public void setPasswordMinimumNonLetter(ComponentName who, int length) {
if (!mHasFeature) {
return;
}
- enforceCrossUserPermission(userHandle);
+ Preconditions.checkNotNull(who, "ComponentName is null");
+ final int userHandle = UserHandle.getCallingUserId();
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
ActiveAdmin ap = getActiveAdminForCallerLocked(who,
DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
if (ap.minimumPasswordNonLetter != length) {
@@ -2521,8 +2512,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
// This API can only be called by an active device admin,
// so try to retrieve it to check that the caller is one.
- getActiveAdminForCallerLocked(null,
- DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
+ getActiveAdminForCallerLocked(null, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
if (policy.mActivePasswordQuality < getPasswordQuality(null, userHandle)
|| policy.mActivePasswordLength < getPasswordMinimumLength(null, userHandle)) {
return false;
@@ -2555,15 +2545,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
}
- public void setMaximumFailedPasswordsForWipe(ComponentName who, int num, int userHandle) {
+ public void setMaximumFailedPasswordsForWipe(ComponentName who, int num) {
if (!mHasFeature) {
return;
}
- enforceCrossUserPermission(userHandle);
+ Preconditions.checkNotNull(who, "ComponentName is null");
+ final int userHandle = UserHandle.getCallingUserId();
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
// This API can only be called by an active device admin,
// so try to retrieve it to check that the caller is one.
getActiveAdminForCallerLocked(who,
@@ -2631,11 +2619,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
return strictestAdmin;
}
- public boolean resetPassword(String passwordOrNull, int flags, int userHandle) {
+ public boolean resetPassword(String passwordOrNull, int flags) {
if (!mHasFeature) {
return false;
}
- enforceCrossUserPermission(userHandle);
+ final int userHandle = UserHandle.getCallingUserId();
enforceNotManagedProfile(userHandle, "reset the password");
String password = passwordOrNull != null ? passwordOrNull : "";
@@ -2744,9 +2732,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
try {
LockPatternUtils utils = new LockPatternUtils(mContext);
if (!TextUtils.isEmpty(password)) {
- utils.saveLockPassword(password, quality, false, userHandle);
+ utils.saveLockPassword(password, quality, userHandle);
} else {
- utils.clearLock(false, userHandle);
+ utils.clearLock(userHandle);
}
boolean requireEntry = (flags & DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY) != 0;
if (requireEntry) {
@@ -2766,15 +2754,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
return true;
}
- public void setMaximumTimeToLock(ComponentName who, long timeMs, int userHandle) {
+ public void setMaximumTimeToLock(ComponentName who, long timeMs) {
if (!mHasFeature) {
return;
}
- enforceCrossUserPermission(userHandle);
+ Preconditions.checkNotNull(who, "ComponentName is null");
+ final int userHandle = UserHandle.getCallingUserId();
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
ActiveAdmin ap = getActiveAdminForCallerLocked(who,
DeviceAdminInfo.USES_POLICY_FORCE_LOCK);
if (ap.maximumTimeToUnlock != timeMs) {
@@ -2953,9 +2939,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
@Override
public boolean installKeyPair(ComponentName who, byte[] privKey, byte[] cert, String alias) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
+ Preconditions.checkNotNull(who, "ComponentName is null");
synchronized (this) {
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
}
@@ -2980,6 +2964,63 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
return false;
}
+ @Override
+ public void choosePrivateKeyAlias(final int uid, final String host, int port, final String url,
+ final String alias, final IBinder response) {
+ // Caller UID needs to be trusted, so we restrict this method to SYSTEM_UID callers.
+ if (UserHandle.getAppId(Binder.getCallingUid()) != Process.SYSTEM_UID) {
+ return;
+ }
+
+ final UserHandle caller = Binder.getCallingUserHandle();
+ final ComponentName profileOwner = getProfileOwner(caller.getIdentifier());
+
+ if (profileOwner == null) {
+ sendPrivateKeyAliasResponse(null, response);
+ return;
+ }
+
+ Intent intent = new Intent(DeviceAdminReceiver.ACTION_CHOOSE_PRIVATE_KEY_ALIAS);
+ intent.setComponent(profileOwner);
+ intent.putExtra(DeviceAdminReceiver.EXTRA_CHOOSE_PRIVATE_KEY_SENDER_UID, uid);
+ intent.putExtra(DeviceAdminReceiver.EXTRA_CHOOSE_PRIVATE_KEY_HOST, host);
+ intent.putExtra(DeviceAdminReceiver.EXTRA_CHOOSE_PRIVATE_KEY_PORT, port);
+ intent.putExtra(DeviceAdminReceiver.EXTRA_CHOOSE_PRIVATE_KEY_URL, url);
+ intent.putExtra(DeviceAdminReceiver.EXTRA_CHOOSE_PRIVATE_KEY_ALIAS, alias);
+ intent.putExtra(DeviceAdminReceiver.EXTRA_CHOOSE_PRIVATE_KEY_RESPONSE, response);
+
+ final long id = Binder.clearCallingIdentity();
+ try {
+ mContext.sendOrderedBroadcastAsUser(intent, caller, null, new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final String chosenAlias = getResultData();
+ sendPrivateKeyAliasResponse(chosenAlias, response);
+ }
+ }, null, Activity.RESULT_OK, null, null);
+ } finally {
+ Binder.restoreCallingIdentity(id);
+ }
+ }
+
+ private void sendPrivateKeyAliasResponse(final String alias, final IBinder responseBinder) {
+ final IKeyChainAliasCallback keyChainAliasResponse =
+ IKeyChainAliasCallback.Stub.asInterface(responseBinder);
+ new AsyncTask<Void, Void, Void>() {
+ @Override
+ protected Void doInBackground(Void... unused) {
+ try {
+ keyChainAliasResponse.alias(alias);
+ } catch (Exception e) {
+ // Catch everything (not just RemoteException): caller could throw a
+ // RuntimeException back across processes.
+ Log.e(LOG_TAG, "error while responding to callback", e);
+ }
+ return null;
+ }
+ }.execute();
+ }
+
private void wipeDataLocked(boolean wipeExtRequested, String reason) {
// If the SD card is encrypted and non-removable, we have to force a wipe.
boolean forceExtWipe = !Environment.isExternalStorageRemovable() && isExtStorageEncrypted();
@@ -3233,15 +3274,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
public ComponentName setGlobalProxy(ComponentName who, String proxySpec,
- String exclusionList, int userHandle) {
+ String exclusionList) {
if (!mHasFeature) {
return null;
}
- enforceCrossUserPermission(userHandle);
synchronized(this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
+ Preconditions.checkNotNull(who, "ComponentName is null");
// Only check if owner has set global proxy. We don't allow other users to set it.
DevicePolicyData policy = getUserData(UserHandle.USER_OWNER);
@@ -3263,7 +3301,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
// If the user is not the owner, don't set the global proxy. Fail silently.
if (UserHandle.getCallingUserId() != UserHandle.USER_OWNER) {
Slog.w(LOG_TAG, "Only the owner is allowed to set the global proxy. User "
- + userHandle + " is not permitted.");
+ + UserHandle.getCallingUserId() + " is not permitted.");
return null;
}
if (proxySpec == null) {
@@ -3373,16 +3411,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
* Set the storage encryption request for a single admin. Returns the new total request
* status (for all admins).
*/
- public int setStorageEncryption(ComponentName who, boolean encrypt, int userHandle) {
+ public int setStorageEncryption(ComponentName who, boolean encrypt) {
if (!mHasFeature) {
return DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED;
}
- enforceCrossUserPermission(userHandle);
+ Preconditions.checkNotNull(who, "ComponentName is null");
+ final int userHandle = UserHandle.getCallingUserId();
synchronized (this) {
// Check for permissions
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
// Only owner can set storage encryption
if (userHandle != UserHandle.USER_OWNER
|| UserHandle.getCallingUserId() != UserHandle.USER_OWNER) {
@@ -3509,15 +3545,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
/**
* Set whether the screen capture is disabled for the user managed by the specified admin.
*/
- public void setScreenCaptureDisabled(ComponentName who, int userHandle, boolean disabled) {
+ public void setScreenCaptureDisabled(ComponentName who, boolean disabled) {
if (!mHasFeature) {
return;
}
- enforceCrossUserPermission(userHandle);
+ Preconditions.checkNotNull(who, "ComponentName is null");
+ final int userHandle = UserHandle.getCallingUserId();
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
ActiveAdmin ap = getActiveAdminForCallerLocked(who,
DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
if (ap.disableScreenCapture != disabled) {
@@ -3568,15 +3602,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
/**
* Set whether auto time is required by the specified admin (must be device owner).
*/
- public void setAutoTimeRequired(ComponentName who, int userHandle, boolean required) {
+ public void setAutoTimeRequired(ComponentName who, boolean required) {
if (!mHasFeature) {
return;
}
- enforceCrossUserPermission(userHandle);
+ Preconditions.checkNotNull(who, "ComponentName is null");
+ final int userHandle = UserHandle.getCallingUserId();
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
ActiveAdmin admin = getActiveAdminForCallerLocked(who,
DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
if (admin.requireAutoTime != required) {
@@ -3612,22 +3644,21 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
/**
* The system property used to share the state of the camera. The native camera service
- * is expected to read this property and act accordingly.
+ * is expected to read this property and act accordingly. The userId should be appended
+ * to this key.
*/
- public static final String SYSTEM_PROP_DISABLE_CAMERA = "sys.secpolicy.camera.disabled";
+ public static final String SYSTEM_PROP_DISABLE_CAMERA_PREFIX = "sys.secpolicy.camera.off_";
/**
* Disables all device cameras according to the specified admin.
*/
- public void setCameraDisabled(ComponentName who, boolean disabled, int userHandle) {
+ public void setCameraDisabled(ComponentName who, boolean disabled) {
if (!mHasFeature) {
return;
}
- enforceCrossUserPermission(userHandle);
+ Preconditions.checkNotNull(who, "ComponentName is null");
+ final int userHandle = UserHandle.getCallingUserId();
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
ActiveAdmin ap = getActiveAdminForCallerLocked(who,
DeviceAdminInfo.USES_POLICY_DISABLE_CAMERA);
if (ap.disableCamera != disabled) {
@@ -3668,16 +3699,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
/**
* Selectively disable keyguard features.
*/
- public void setKeyguardDisabledFeatures(ComponentName who, int which, int userHandle) {
+ public void setKeyguardDisabledFeatures(ComponentName who, int which) {
if (!mHasFeature) {
return;
}
- enforceCrossUserPermission(userHandle);
+ Preconditions.checkNotNull(who, "ComponentName is null");
+ final int userHandle = UserHandle.getCallingUserId();
enforceNotManagedProfile(userHandle, "disable keyguard features");
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
ActiveAdmin ap = getActiveAdminForCallerLocked(who,
DeviceAdminInfo.USES_POLICY_DISABLE_KEYGUARD_FEATURES);
if (ap.disabledKeyguardFeatures != which) {
@@ -3821,9 +3850,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
@Override
public void clearDeviceOwner(String packageName) {
- if (packageName == null) {
- throw new NullPointerException("packageName is null");
- }
+ Preconditions.checkNotNull(packageName, "packageName is null");
try {
int uid = mContext.getPackageManager().getPackageUid(packageName, 0);
if (uid != Binder.getCallingUid()) {
@@ -3850,6 +3877,110 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
@Override
+ public boolean setDeviceInitializer(ComponentName who, ComponentName initializer,
+ String ownerName) {
+ if (!mHasFeature) {
+ return false;
+ }
+ if (initializer == null || !DeviceOwner.isInstalled(
+ initializer.getPackageName(), mContext.getPackageManager())) {
+ throw new IllegalArgumentException("Invalid component name " + initializer
+ + " for device initializer");
+ }
+ synchronized (this) {
+ enforceCanSetDeviceInitializer(who);
+
+ if (mDeviceOwner != null && mDeviceOwner.hasDeviceInitializer()) {
+ throw new IllegalStateException(
+ "Trying to set device initializer but device initializer is already set.");
+ }
+
+ if (mDeviceOwner == null) {
+ // Device owner state does not exist, create it.
+ mDeviceOwner = DeviceOwner.createWithDeviceInitializer(
+ initializer.getPackageName(), ownerName);
+ mDeviceOwner.writeOwnerFile();
+ return true;
+ } else {
+ // Device owner already exists, update it.
+ mDeviceOwner.setDeviceInitializer(initializer.getPackageName(), ownerName);
+ mDeviceOwner.writeOwnerFile();
+ return true;
+ }
+ }
+ }
+
+ private void enforceCanSetDeviceInitializer(ComponentName who) {
+ if (who == null) {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.MANAGE_DEVICE_ADMINS, null);
+ if (hasUserSetupCompleted(UserHandle.USER_OWNER)) {
+ throw new IllegalStateException(
+ "Trying to set device initializer but device is already provisioned.");
+ }
+ } else {
+ getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
+ }
+ }
+
+ @Override
+ public boolean isDeviceInitializer(String packageName) {
+ if (!mHasFeature) {
+ return false;
+ }
+ synchronized (this) {
+ return mDeviceOwner != null
+ && mDeviceOwner.hasDeviceInitializer()
+ && mDeviceOwner.getDeviceInitializerPackageName().equals(packageName);
+ }
+ }
+
+ @Override
+ public String getDeviceInitializer() {
+ if (!mHasFeature) {
+ return null;
+ }
+ synchronized (this) {
+ if (mDeviceOwner != null && mDeviceOwner.hasDeviceInitializer()) {
+ return mDeviceOwner.getDeviceInitializerPackageName();
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public void clearDeviceInitializer(ComponentName who) {
+ if (!mHasFeature) {
+ return;
+ }
+ Preconditions.checkNotNull(who, "ComponentName is null");
+
+ ActiveAdmin admin = getActiveAdminUncheckedLocked(who, UserHandle.getCallingUserId());
+
+ if (admin.getUid() != Binder.getCallingUid()) {
+ throw new SecurityException("Admin " + who + " is not owned by uid "
+ + Binder.getCallingUid());
+ }
+
+ if (!isDeviceInitializer(admin.info.getPackageName())
+ && !isDeviceOwner(admin.info.getPackageName())) {
+ throw new SecurityException(
+ "clearDeviceInitializer can only be called by the device initializer/owner");
+ }
+ synchronized (this) {
+ long ident = Binder.clearCallingIdentity();
+ try {
+ if (mDeviceOwner != null) {
+ mDeviceOwner.clearDeviceInitializer();
+ mDeviceOwner.writeOwnerFile();
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ }
+
+ @Override
public boolean setProfileOwner(ComponentName who, String ownerName, int userHandle) {
if (!mHasFeature) {
return false;
@@ -3922,7 +4053,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
Bundle userRestrictions = mUserManager.getUserRestrictions();
mUserManager.setUserRestrictions(new Bundle(), userHandle);
if (userRestrictions.getBoolean(UserManager.DISALLOW_ADJUST_VOLUME)) {
- audioManager.setMasterMute(false);
+ audioManager.setMasterMute(false, 0);
}
if (userRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_MICROPHONE)) {
audioManager.setMicrophoneMute(false);
@@ -3944,16 +4075,58 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
@Override
- public void setProfileEnabled(ComponentName who) {
+ public boolean setUserEnabled(ComponentName who) {
if (!mHasFeature) {
- return;
+ return false;
}
- final int userHandle = UserHandle.getCallingUserId();
synchronized (this) {
- // Check for permissions
if (who == null) {
throw new NullPointerException("ComponentName is null");
}
+ int userId = UserHandle.getCallingUserId();
+
+ ActiveAdmin activeAdmin =
+ getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
+ if (!isDeviceInitializer(activeAdmin.info.getPackageName())) {
+ throw new SecurityException(
+ "This method can only be called by device initializers");
+ }
+
+ long id = Binder.clearCallingIdentity();
+ try {
+ if (!isDeviceOwner(activeAdmin.info.getPackageName())) {
+ IPackageManager ipm = AppGlobals.getPackageManager();
+ ipm.setComponentEnabledSetting(who,
+ PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
+ PackageManager.DONT_KILL_APP, userId);
+
+ removeActiveAdmin(who, userId);
+ }
+
+ if (userId == UserHandle.USER_OWNER) {
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.DEVICE_PROVISIONED, 1);
+ }
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ Settings.Secure.USER_SETUP_COMPLETE, 1, userId);
+ } catch (RemoteException e) {
+ Log.i(LOG_TAG, "Can't talk to package manager", e);
+ return false;
+ } finally {
+ restoreCallingIdentity(id);
+ }
+ return true;
+ }
+ }
+
+ @Override
+ public void setProfileEnabled(ComponentName who) {
+ if (!mHasFeature) {
+ return;
+ }
+ Preconditions.checkNotNull(who, "ComponentName is null");
+ final int userHandle = UserHandle.getCallingUserId();
+ synchronized (this) {
// Check if this is the profile owner who is calling
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
int userId = UserHandle.getCallingUserId();
@@ -3975,12 +4148,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
@Override
public void setProfileName(ComponentName who, String profileName) {
+ Preconditions.checkNotNull(who, "ComponentName is null");
int userId = UserHandle.getCallingUserId();
-
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
-
// Check if this is the profile owner (includes device owner).
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
@@ -4042,16 +4211,18 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
/**
- * Device owner can only be set on an unprovisioned device, unless it was initiated by "adb", in
- * which case we allow it if no account is associated with the device.
+ * Device owner can only be set on an unprovisioned device. However, if initiated via "adb",
+ * we also allow it if no accounts or additional users are present on the device.
*/
private boolean allowedToSetDeviceOwnerOnDevice() {
- int callingId = Binder.getCallingUid();
- if (callingId == Process.SHELL_UID || callingId == Process.ROOT_UID) {
- return AccountManager.get(mContext).getAccounts().length == 0;
- } else {
- return !hasUserSetupCompleted(UserHandle.USER_OWNER);
+ if (!hasUserSetupCompleted(UserHandle.USER_OWNER)) {
+ return true;
}
+
+ int callingId = Binder.getCallingUid();
+ return (callingId == Process.SHELL_UID || callingId == Process.ROOT_UID)
+ && mUserManager.getUserCount() == 1
+ && AccountManager.get(mContext).getAccounts().length == 0;
}
private void enforceCrossUserPermission(int userHandle) {
@@ -4128,7 +4299,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
synchronized (this) {
p.println("Current Device Policy Manager state:");
-
+ if (mDeviceOwner != null) {
+ mDeviceOwner.dump(" ", pw);
+ }
int userCount = mUserData.size();
for (int u = 0; u < userCount; u++) {
DevicePolicyData policy = getUserData(mUserData.keyAt(u));
@@ -4156,12 +4329,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
@Override
public void addPersistentPreferredActivity(ComponentName who, IntentFilter filter,
ComponentName activity) {
+ Preconditions.checkNotNull(who, "ComponentName is null");
final int userHandle = UserHandle.getCallingUserId();
-
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
IPackageManager pm = AppGlobals.getPackageManager();
@@ -4178,12 +4348,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
@Override
public void clearPackagePersistentPreferredActivities(ComponentName who, String packageName) {
+ Preconditions.checkNotNull(who, "ComponentName is null");
final int userHandle = UserHandle.getCallingUserId();
-
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
IPackageManager pm = AppGlobals.getPackageManager();
@@ -4200,12 +4367,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
@Override
public void setApplicationRestrictions(ComponentName who, String packageName, Bundle settings) {
+ Preconditions.checkNotNull(who, "ComponentName is null");
final UserHandle userHandle = new UserHandle(UserHandle.getCallingUserId());
-
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
long id = Binder.clearCallingIdentity();
@@ -4218,19 +4382,15 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
public void setTrustAgentConfiguration(ComponentName admin, ComponentName agent,
- PersistableBundle args, int userHandle) {
+ PersistableBundle args) {
if (!mHasFeature) {
return;
}
- enforceCrossUserPermission(userHandle);
+ Preconditions.checkNotNull(admin, "admin is null");
+ Preconditions.checkNotNull(agent, "agent is null");
+ final int userHandle = UserHandle.getCallingUserId();
enforceNotManagedProfile(userHandle, "set trust agent configuration");
synchronized (this) {
- if (admin == null) {
- throw new NullPointerException("admin is null");
- }
- if (agent == null) {
- throw new NullPointerException("agent is null");
- }
ActiveAdmin ap = getActiveAdminForCallerLocked(admin,
DeviceAdminInfo.USES_POLICY_DISABLE_KEYGUARD_FEATURES);
ap.trustAgentInfos.put(agent.flattenToString(), new TrustAgentInfo(args));
@@ -4244,10 +4404,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (!mHasFeature) {
return null;
}
+ Preconditions.checkNotNull(agent, "agent null");
enforceCrossUserPermission(userHandle);
- if (agent == null) {
- throw new NullPointerException("agent is null");
- }
synchronized (this) {
final String componentName = agent.flattenToString();
@@ -4300,10 +4458,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
@Override
public void setRestrictionsProvider(ComponentName who, ComponentName permissionProvider) {
+ Preconditions.checkNotNull(who, "ComponentName is null");
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
int userHandle = UserHandle.getCallingUserId();
@@ -4325,11 +4481,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
public void addCrossProfileIntentFilter(ComponentName who, IntentFilter filter, int flags) {
+ Preconditions.checkNotNull(who, "ComponentName is null");
int callingUserId = UserHandle.getCallingUserId();
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
IPackageManager pm = AppGlobals.getPackageManager();
@@ -4352,11 +4506,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
public void clearCrossProfileIntentFilters(ComponentName who) {
+ Preconditions.checkNotNull(who, "ComponentName is null");
int callingUserId = UserHandle.getCallingUserId();
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
IPackageManager pm = AppGlobals.getPackageManager();
long id = Binder.clearCallingIdentity();
@@ -4397,8 +4549,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
try {
ApplicationInfo applicationInfo = pm.getApplicationInfo(enabledPackage,
PackageManager.GET_UNINSTALLED_PACKAGES, userIdToCheck);
- systemService = (applicationInfo.flags
- & ApplicationInfo.FLAG_SYSTEM) != 0;
+ systemService = (applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
} catch (RemoteException e) {
Log.i(LOG_TAG, "Can't talk to package managed", e);
}
@@ -4427,9 +4578,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (!mHasFeature) {
return false;
}
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
+ Preconditions.checkNotNull(who, "ComponentName is null");
if (packageList != null) {
int userId = UserHandle.getCallingUserId();
@@ -4474,10 +4623,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (!mHasFeature) {
return null;
}
-
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
+ Preconditions.checkNotNull(who, "ComponentName is null");
synchronized (this) {
ActiveAdmin admin = getActiveAdminForCallerLocked(who,
@@ -4532,15 +4678,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
IPackageManager pm = AppGlobals.getPackageManager();
if (installedServices != null) {
for (AccessibilityServiceInfo service : installedServices) {
- String packageName = service.getResolveInfo().serviceInfo.packageName;
- try {
- ApplicationInfo applicationInfo = pm.getApplicationInfo(packageName,
- PackageManager.GET_UNINSTALLED_PACKAGES, userId);
- if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
- result.add(packageName);
- }
- } catch (RemoteException e) {
- Log.i(LOG_TAG, "Accessibility service in missing package", e);
+ ServiceInfo serviceInfo = service.getResolveInfo().serviceInfo;
+ ApplicationInfo applicationInfo = serviceInfo.applicationInfo;
+ if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+ result.add(serviceInfo.packageName);
}
}
}
@@ -4587,9 +4728,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (!mHasFeature) {
return false;
}
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
+ Preconditions.checkNotNull(who, "ComponentName is null");
// TODO When InputMethodManager supports per user calls remove
// this restriction.
@@ -4632,10 +4771,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (!mHasFeature) {
return null;
}
-
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
+ Preconditions.checkNotNull(who, "ComponentName is null");
synchronized (this) {
ActiveAdmin admin = getActiveAdminForCallerLocked(who,
@@ -4691,16 +4827,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
IPackageManager pm = AppGlobals.getPackageManager();
if (imes != null) {
for (InputMethodInfo ime : imes) {
- String packageName = ime.getPackageName();
- try {
- ApplicationInfo applicationInfo = pm.getApplicationInfo(
- packageName, PackageManager.GET_UNINSTALLED_PACKAGES,
- userId);
- if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
- result.add(packageName);
- }
- } catch (RemoteException e) {
- Log.i(LOG_TAG, "Input method for missing package", e);
+ ServiceInfo serviceInfo = ime.getServiceInfo();
+ ApplicationInfo applicationInfo = serviceInfo.applicationInfo;
+ if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+ result.add(serviceInfo.packageName);
}
}
}
@@ -4714,10 +4844,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
@Override
public UserHandle createUser(ComponentName who, String name) {
+ Preconditions.checkNotNull(who, "ComponentName is null");
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
long id = Binder.clearCallingIdentity();
@@ -4768,10 +4896,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
@Override
public boolean removeUser(ComponentName who, UserHandle userHandle) {
+ Preconditions.checkNotNull(who, "ComponentName is null");
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
long id = Binder.clearCallingIdentity();
@@ -4785,10 +4911,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
@Override
public boolean switchUser(ComponentName who, UserHandle userHandle) {
+ Preconditions.checkNotNull(who, "ComponentName is null");
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
long id = Binder.clearCallingIdentity();
@@ -4809,12 +4933,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
@Override
public Bundle getApplicationRestrictions(ComponentName who, String packageName) {
+ Preconditions.checkNotNull(who, "ComponentName is null");
final UserHandle userHandle = new UserHandle(UserHandle.getCallingUserId());
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
long id = Binder.clearCallingIdentity();
@@ -4828,12 +4950,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
@Override
public void setUserRestriction(ComponentName who, String key, boolean enabled) {
+ Preconditions.checkNotNull(who, "ComponentName is null");
final UserHandle user = new UserHandle(UserHandle.getCallingUserId());
final int userHandle = user.getIdentifier();
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
ActiveAdmin activeAdmin =
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
boolean isDeviceOwner = isDeviceOwner(activeAdmin.info.getPackageName());
@@ -4841,6 +4961,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
&& DEVICE_OWNER_USER_RESTRICTIONS.contains(key)) {
throw new SecurityException("Profile owners cannot set user restriction " + key);
}
+ if (IMMUTABLE_USER_RESTRICTIONS.contains(key)) {
+ throw new SecurityException("User restriction " + key + " cannot be changed");
+ }
boolean alreadyRestricted = mUserManager.hasUserRestriction(key, user);
IAudioService iAudioService = null;
@@ -4855,7 +4978,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (UserManager.DISALLOW_UNMUTE_MICROPHONE.equals(key)) {
iAudioService.setMicrophoneMute(true, who.getPackageName());
} else if (UserManager.DISALLOW_ADJUST_VOLUME.equals(key)) {
- iAudioService.setMasterMute(true, 0, who.getPackageName(), null);
+ iAudioService.setMasterMute(true, 0, who.getPackageName());
}
} catch (RemoteException re) {
Slog.e(LOG_TAG, "Failed to talk to AudioService.", re);
@@ -4920,7 +5043,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (UserManager.DISALLOW_UNMUTE_MICROPHONE.equals(key)) {
iAudioService.setMicrophoneMute(false, who.getPackageName());
} else if (UserManager.DISALLOW_ADJUST_VOLUME.equals(key)) {
- iAudioService.setMasterMute(false, 0, who.getPackageName(), null);
+ iAudioService.setMasterMute(false, 0, who.getPackageName());
}
} catch (RemoteException re) {
Slog.e(LOG_TAG, "Failed to talk to AudioService.", re);
@@ -4933,11 +5056,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
@Override
public boolean setApplicationHidden(ComponentName who, String packageName,
boolean hidden) {
+ Preconditions.checkNotNull(who, "ComponentName is null");
int callingUserId = UserHandle.getCallingUserId();
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
long id = Binder.clearCallingIdentity();
@@ -4956,11 +5077,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
@Override
public boolean isApplicationHidden(ComponentName who, String packageName) {
+ Preconditions.checkNotNull(who, "ComponentName is null");
int callingUserId = UserHandle.getCallingUserId();
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
long id = Binder.clearCallingIdentity();
@@ -4979,11 +5098,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
@Override
public void enableSystemApp(ComponentName who, String packageName) {
+ Preconditions.checkNotNull(who, "ComponentName is null");
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
-
// This API can only be called by an active device admin,
// so try to retrieve it to check that the caller is one.
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
@@ -5024,11 +5140,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
@Override
public int enableSystemAppWithIntent(ComponentName who, Intent intent) {
+ Preconditions.checkNotNull(who, "ComponentName is null");
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
-
// This API can only be called by an active device admin,
// so try to retrieve it to check that the caller is one.
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
@@ -5056,15 +5169,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (activitiesToEnable != null) {
for (ResolveInfo info : activitiesToEnable) {
if (info.activityInfo != null) {
-
- if (!isSystemApp(pm, info.activityInfo.packageName, primaryUser.id)) {
- throw new IllegalArgumentException(
- "Only system apps can be enabled this way.");
+ String packageName = info.activityInfo.packageName;
+ if (isSystemApp(pm, packageName, primaryUser.id)) {
+ numberOfAppsInstalled++;
+ pm.installExistingPackageAsUser(packageName, userId);
+ } else {
+ Slog.d(LOG_TAG, "Not enabling " + packageName + " since is not a"
+ + " system app");
}
-
-
- numberOfAppsInstalled++;
- pm.installExistingPackageAsUser(info.activityInfo.packageName, userId);
}
}
}
@@ -5083,7 +5195,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
throws RemoteException {
ApplicationInfo appInfo = pm.getApplicationInfo(packageName, GET_UNINSTALLED_PACKAGES,
userId);
- return (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) > 0;
+ if (appInfo == null) {
+ throw new IllegalArgumentException("The application " + packageName +
+ " is not present on this device");
+ }
+ return (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
}
@Override
@@ -5092,10 +5208,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (!mHasFeature) {
return;
}
+ Preconditions.checkNotNull(who, "ComponentName is null");
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
ActiveAdmin ap = getActiveAdminForCallerLocked(who,
DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
if (disabled) {
@@ -5133,12 +5247,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
@Override
public void setUninstallBlocked(ComponentName who, String packageName,
boolean uninstallBlocked) {
+ Preconditions.checkNotNull(who, "ComponentName is null");
final int userId = UserHandle.getCallingUserId();
-
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
long id = Binder.clearCallingIdentity();
@@ -5185,10 +5296,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (!mHasFeature) {
return;
}
+ Preconditions.checkNotNull(who, "ComponentName is null");
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
ActiveAdmin admin = getActiveAdminForCallerLocked(who,
DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
if (admin.disableCallerId != disabled) {
@@ -5203,12 +5312,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (!mHasFeature) {
return false;
}
-
+ Preconditions.checkNotNull(who, "ComponentName is null");
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
-
ActiveAdmin admin = getActiveAdminForCallerLocked(who,
DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
return admin.disableCallerId;
@@ -5229,13 +5334,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
* Sets which packages may enter lock task mode.
*
* This function can only be called by the device owner.
- * @param components The list of components allowed to enter lock task mode.
+ * @param packages The list of packages allowed to enter lock task mode.
*/
public void setLockTaskPackages(ComponentName who, String[] packages) throws SecurityException {
+ Preconditions.checkNotNull(who, "ComponentName is null");
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
int userHandle = Binder.getCallingUserHandle().getIdentifier();
@@ -5257,15 +5360,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
* This function returns the list of components allowed to start the task lock mode.
*/
public String[] getLockTaskPackages(ComponentName who) {
+ Preconditions.checkNotNull(who, "ComponentName is null");
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
int userHandle = Binder.getCallingUserHandle().getIdentifier();
DevicePolicyData policy = getUserData(userHandle);
- return policy.mLockTaskPackages.toArray(new String[0]);
+ return policy.mLockTaskPackages.toArray(new String[policy.mLockTaskPackages.size()]);
}
}
@@ -5321,16 +5422,19 @@ 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) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
if (!GLOBAL_SETTINGS_WHITELIST.contains(setting)) {
- throw new SecurityException(String.format(
- "Permission denial: device owners cannot update %1$s", setting));
+ // BLUETOOTH_ON and WIFI_ON used to be supported but not any more. We do not want to
+ // throw a SecurityException not to break apps.
+ if (!Settings.Global.BLUETOOTH_ON.equals(setting)
+ && !Settings.Global.WIFI_ON.equals(setting)) {
+ throw new SecurityException(String.format(
+ "Permission denial: device owners cannot update %1$s", setting));
+ }
}
long id = Binder.clearCallingIdentity();
@@ -5344,13 +5448,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
@Override
public void setSecureSetting(ComponentName who, String setting, String value) {
+ Preconditions.checkNotNull(who, "ComponentName is null");
int callingUserId = UserHandle.getCallingUserId();
final ContentResolver contentResolver = mContext.getContentResolver();
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
ActiveAdmin activeAdmin =
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
@@ -5375,18 +5477,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
@Override
public void setMasterVolumeMuted(ComponentName who, boolean on) {
- final ContentResolver contentResolver = mContext.getContentResolver();
-
+ Preconditions.checkNotNull(who, "ComponentName is null");
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
IAudioService iAudioService = IAudioService.Stub.asInterface(
ServiceManager.getService(Context.AUDIO_SERVICE));
- try{
- iAudioService.setMasterMute(on, 0, who.getPackageName(), null);
+ try {
+ iAudioService.setMasterMute(on, 0, who.getPackageName());
} catch (RemoteException re) {
Slog.e(LOG_TAG, "Failed to setMasterMute", re);
}
@@ -5395,12 +5493,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
@Override
public boolean isMasterVolumeMuted(ComponentName who) {
- final ContentResolver contentResolver = mContext.getContentResolver();
-
+ Preconditions.checkNotNull(who, "ComponentName is null");
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
AudioManager audioManager =
@@ -5409,6 +5503,22 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
}
+ @Override
+ public void setUserIcon(ComponentName who, Bitmap icon) {
+ synchronized (this) {
+ Preconditions.checkNotNull(who, "ComponentName is null");
+ getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
+
+ int userId = UserHandle.getCallingUserId();
+ long id = Binder.clearCallingIdentity();
+ try {
+ mUserManager.setUserIcon(userId, icon);
+ } finally {
+ restoreCallingIdentity(id);
+ }
+ }
+ }
+
/**
* We need to update the internal state of whether a user has completed setup once. After
* that, we ignore any changes that reset the Settings.Secure.USER_SETUP_COMPLETE changes