diff options
author | Amith Yamasani <yamasani@google.com> | 2014-07-16 17:26:17 -0700 |
---|---|---|
committer | Amith Yamasani <yamasani@google.com> | 2014-07-16 20:36:41 -0700 |
commit | ed239cb950d05ae794999ca75cef0c5371016800 (patch) | |
tree | a1b429ac6832e99602421bfa8ed4f9b43b57a178 /services | |
parent | ce50e7af920bf19f3ebf6274657fc51f136c5c87 (diff) | |
download | frameworks_base-ed239cb950d05ae794999ca75cef0c5371016800.zip frameworks_base-ed239cb950d05ae794999ca75cef0c5371016800.tar.gz frameworks_base-ed239cb950d05ae794999ca75cef0c5371016800.tar.bz2 |
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
Diffstat (limited to 'services')
-rw-r--r-- | services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 5445dc0..a62bc85 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<ComponentName, ActiveAdmin> mAdminMap = new HashMap<ComponentName, ActiveAdmin>(); @@ -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<N; i++) { @@ -1074,6 +1083,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (permissionProvider != null) { policy.mRestrictionsProvider = ComponentName.unflattenFromString(permissionProvider); } + String userSetupComplete = parser.getAttributeValue(null, ATTR_SETUP_COMPLETE); + if (userSetupComplete != null && Boolean.toString(true).equals(userSetupComplete)) { + policy.mUserSetupComplete = true; + } type = parser.next(); int outerDepth = parser.getDepth(); @@ -1266,6 +1279,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } } + // Register an observer for watching for user setup complete. + new SetupContentObserver(mHandler).register(mContext.getContentResolver()); + // Initialize the user setup state, to handle the upgrade case. + updateUserSetupComplete(); } private void cleanUpOldUsers() { @@ -3994,4 +4011,50 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return audioManager.isMasterMute(); } } + + /** + * 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. + * <p> + * Unfortunately, we don't know which user's setup state was changed, so we write all of + * them. + */ + 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, + 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(); + } + } + } } |