From ed239cb950d05ae794999ca75cef0c5371016800 Mon Sep 17 00:00:00 2001 From: Amith Yamasani Date: Wed, 16 Jul 2014 17:26:17 -0700 Subject: [PATCH] Keep track of user_setup_complete in DPMS This is to ensure that some system app can't modify that state for purposes of changing the profile owner without user consent. Bug: 16207721 Change-Id: Ic5f454d7568cd824b83456eed0e2611779a9adf8 --- .../DevicePolicyManagerService.java | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 5445dc06b2d84..a62bc85b114b1 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -55,7 +55,9 @@ import android.content.pm.UserInfo; import android.media.AudioManager; import android.media.IAudioService; import android.net.ConnectivityManager; +import android.net.Uri; import android.content.pm.PackageManager.NameNotFoundException; +import android.database.ContentObserver; import android.net.ProxyInfo; import android.os.Binder; import android.os.Bundle; @@ -136,6 +138,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private static final boolean DBG = false; private static final String ATTR_PERMISSION_PROVIDER = "permission-provider"; + private static final String ATTR_SETUP_COMPLETE = "setup-complete"; final Context mContext; final UserManager mUserManager; @@ -174,6 +177,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } } + public static class DevicePolicyData { int mActivePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; int mActivePasswordLength = 0; @@ -188,6 +192,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { int mUserHandle; int mPasswordOwner = -1; long mLastMaximumTimeToLock = -1; + boolean mUserSetupComplete = false; final HashMap mAdminMap = new HashMap(); @@ -973,6 +978,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { out.attribute(null, ATTR_PERMISSION_PROVIDER, policy.mRestrictionsProvider.flattenToString()); } + if (policy.mUserSetupComplete) { + out.attribute(null, ATTR_SETUP_COMPLETE, + Boolean.toString(true)); + } final int N = policy.mAdminList.size(); for (int i=0; i + * Unfortunately, we don't know which user's setup state was changed, so we write all of + * them. + */ + void updateUserSetupComplete() { + List 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, + userHandle) != 0) { + DevicePolicyData policy = getUserData(userHandle); + policy.mUserSetupComplete = true; + synchronized (this) { + saveSettingsLocked(userHandle); + } + } + } + } + + private class SetupContentObserver extends ContentObserver { + + private final Uri mUserSetupComplete = Settings.Secure.getUriFor( + Settings.Secure.USER_SETUP_COMPLETE); + + public SetupContentObserver(Handler handler) { + super(handler); + } + + void register(ContentResolver resolver) { + resolver.registerContentObserver(mUserSetupComplete, false, this, UserHandle.USER_ALL); + } + + @Override + public void onChange(boolean selfChange, Uri uri) { + if (mUserSetupComplete.equals(uri)) { + updateUserSetupComplete(); + } + } + } }