DPM.isProvisioningAllowed(ACTION_PROVISION_MANAGED_DEVICE) should
return 'false' for Wear devices after pairing/upgrade.
BUG: 32019375
Change-Id: I2563efe58c98c5dd8440891e478c89e093d8d9ac
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 17f9bad..a960b21 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6394,6 +6394,12 @@
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.
*
* NOTE: Settings are backed up and restored in the order they appear
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index fc14444..b205ead 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 @@
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 @@
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 @@
*/
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 @@
int mPasswordOwner = -1;
long mLastMaximumTimeToLock = -1;
boolean mUserSetupComplete = false;
+ boolean mPaired = false;
int mUserProvisioningState;
int mPermissionPolicy;
@@ -1621,6 +1629,8 @@
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 @@
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 @@
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 @@
// 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<String> packageList;
synchronized (this) {
@@ -6134,6 +6152,13 @@
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 @@
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 @@
}
/**
- * 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.
* <p>
* Unfortunately, we don't know which user's setup state was changed, so we write all of
* them.
*/
- void updateUserSetupComplete() {
+ void updateUserSetupCompleteAndPaired() {
List<UserInfo> users = mUserManager.getUsers(true);
final int N = users.size();
for (int i = 0; i < N; i++) {
@@ -8185,6 +8214,16 @@
}
}
}
+ 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 @@
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 @@
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 @@
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)) {