From 35144049846e115b7d1e03fb6c935ed497d83cb2 Mon Sep 17 00:00:00 2001 From: Greg Plesur Date: Mon, 10 Oct 2016 16:23:49 -0400 Subject: [PATCH] DPM.isProvisioningAllowed(ACTION_PROVISION_MANAGED_DEVICE) should return 'false' for Wear devices after pairing/upgrade. BUG: 32019375 Change-Id: I2563efe58c98c5dd8440891e478c89e093d8d9ac --- core/java/android/provider/Settings.java | 6 ++ .../DevicePolicyManagerService.java | 60 ++++++++++++++++--- 2 files changed, 59 insertions(+), 7 deletions(-) diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 17f9bad828de1..a960b2151655f 100755 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -6393,6 +6393,12 @@ public final class Settings { */ public static final String WEB_ACTION_ENABLED = "web_action_enabled"; + /** + * Has this pairable device been paired or upgraded from a previously paired system. + * @hide + */ + public static final String DEVICE_PAIRED = "device_paired"; + /** * This are the settings to be backed up. * diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index fc14444ba6efa..b205ead4c8795 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -222,6 +222,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private static final String ATTR_PERMISSION_POLICY = "permission-policy"; private static final String ATTR_DEVICE_PROVISIONING_CONFIG_APPLIED = "device-provisioning-config-applied"; + private static final String ATTR_DEVICE_PAIRED = "device-paired"; private static final String ATTR_DELEGATED_CERT_INSTALLER = "delegated-cert-installer"; private static final String ATTR_APPLICATION_RESTRICTIONS_MANAGER @@ -301,6 +302,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private static final int CODE_NONSYSTEM_USER_EXISTS = 5; private static final int CODE_ACCOUNTS_NOT_EMPTY = 6; private static final int CODE_NOT_SYSTEM_USER = 7; + private static final int CODE_HAS_PAIRED = 8; @Retention(RetentionPolicy.SOURCE) @IntDef({ CODE_OK, CODE_HAS_DEVICE_OWNER, CODE_USER_HAS_PROFILE_OWNER, CODE_USER_NOT_RUNNING, @@ -344,6 +346,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { */ boolean mHasFeature; + /** + * Whether or not this device is a watch. + */ + boolean mIsWatch; + private final SecurityLogMonitor mSecurityLogMonitor; private final AtomicBoolean mRemoteBugreportServiceIsActive = new AtomicBoolean(); @@ -424,6 +431,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { int mPasswordOwner = -1; long mLastMaximumTimeToLock = -1; boolean mUserSetupComplete = false; + boolean mPaired = false; int mUserProvisioningState; int mPermissionPolicy; @@ -1621,6 +1629,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { mHasFeature = mContext.getPackageManager() .hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN); + mIsWatch = mContext.getPackageManager() + .hasSystemFeature(PackageManager.FEATURE_WATCH); if (!mHasFeature) { // Skip the rest of the initialization return; @@ -2221,6 +2231,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { out.attribute(null, ATTR_SETUP_COMPLETE, Boolean.toString(true)); } + if (policy.mPaired) { + out.attribute(null, ATTR_DEVICE_PAIRED, + Boolean.toString(true)); + } if (policy.mDeviceProvisioningConfigApplied) { out.attribute(null, ATTR_DEVICE_PROVISIONING_CONFIG_APPLIED, Boolean.toString(true)); @@ -2385,6 +2399,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (userSetupComplete != null && Boolean.toString(true).equals(userSetupComplete)) { policy.mUserSetupComplete = true; } + String paired = parser.getAttributeValue(null, ATTR_DEVICE_PAIRED); + if (paired != null && Boolean.toString(true).equals(paired)) { + policy.mPaired = true; + } String deviceProvisioningConfigApplied = parser.getAttributeValue(null, ATTR_DEVICE_PROVISIONING_CONFIG_APPLIED); if (deviceProvisioningConfigApplied != null @@ -2619,7 +2637,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // Register an observer for watching for user setup complete. new SetupContentObserver(mHandler).register(); // Initialize the user setup state, to handle the upgrade case. - updateUserSetupComplete(); + updateUserSetupCompleteAndPaired(); List packageList; synchronized (this) { @@ -6134,6 +6152,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return getUserData(userHandle).mUserSetupComplete; } + private boolean hasPaired(int userHandle) { + if (!mHasFeature) { + return true; + } + return getUserData(userHandle).mPaired; + } + @Override public int getUserProvisioningState() { if (!mHasFeature) { @@ -6412,6 +6437,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { case CODE_ACCOUNTS_NOT_EMPTY: throw new IllegalStateException("Not allowed to set the device owner because there " + "are already some accounts on the device"); + case CODE_HAS_PAIRED: + throw new IllegalStateException("Not allowed to set the device owner because this " + + "device has already paired"); default: throw new IllegalStateException("Unknown @DeviceOwnerPreConditionCode " + code); } @@ -8163,14 +8191,15 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } /** - * 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 - * as we don't trust any apps that might try to reset it. + * We need to update the internal state of whether a user has completed setup or a + * device has paired once. After that, we ignore any changes that reset the + * Settings.Secure.USER_SETUP_COMPLETE or Settings.Secure.DEVICE_PAIRED change + * as we don't trust any apps that might try to reset them. *

* Unfortunately, we don't know which user's setup state was changed, so we write all of * them. */ - void updateUserSetupComplete() { + void updateUserSetupCompleteAndPaired() { List users = mUserManager.getUsers(true); final int N = users.size(); for (int i = 0; i < N; i++) { @@ -8185,6 +8214,16 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } } + if (mIsWatch && mInjector.settingsSecureGetIntForUser(Settings.Secure.DEVICE_PAIRED, 0, + userHandle) != 0) { + DevicePolicyData policy = getUserData(userHandle); + if (!policy.mPaired) { + policy.mPaired = true; + synchronized (this) { + saveSettingsLocked(userHandle); + } + } + } } } @@ -8194,6 +8233,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { Settings.Secure.USER_SETUP_COMPLETE); private final Uri mDeviceProvisioned = Settings.Global.getUriFor( Settings.Global.DEVICE_PROVISIONED); + private final Uri mPaired = Settings.Secure.getUriFor(Settings.Secure.DEVICE_PAIRED); public SetupContentObserver(Handler handler) { super(handler); @@ -8202,12 +8242,15 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { void register() { mInjector.registerContentObserver(mUserSetupComplete, false, this, UserHandle.USER_ALL); mInjector.registerContentObserver(mDeviceProvisioned, false, this, UserHandle.USER_ALL); + if (mIsWatch) { + mInjector.registerContentObserver(mPaired, false, this, UserHandle.USER_ALL); + } } @Override public void onChange(boolean selfChange, Uri uri) { - if (mUserSetupComplete.equals(uri)) { - updateUserSetupComplete(); + if (mUserSetupComplete.equals(uri) || (mIsWatch && mPaired.equals(uri))) { + updateUserSetupCompleteAndPaired(); } else if (mDeviceProvisioned.equals(uri)) { synchronized (DevicePolicyManagerService.this) { // Set PROPERTY_DEVICE_OWNER_PRESENT, for the SUW case where setting the property @@ -8617,6 +8660,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (!mUserManager.isUserRunning(new UserHandle(deviceOwnerUserId))) { return CODE_USER_NOT_RUNNING; } + if (mIsWatch && hasPaired(UserHandle.USER_SYSTEM)) { + return CODE_HAS_PAIRED; + } if (isAdb) { // if shell command runs after user setup completed check device status. Otherwise, OK. if (hasUserSetupCompleted(UserHandle.USER_SYSTEM)) {