Loading core/java/android/app/AppOpsManager.java +1 −1 Original line number Diff line number Diff line Loading @@ -653,7 +653,7 @@ public class AppOpsManager { null, //WRITE_SETTINGS UserManager.DISALLOW_CREATE_WINDOWS, //SYSTEM_ALERT_WINDOW null, //ACCESS_NOTIFICATIONS null, //CAMERA UserManager.DISALLOW_CAMERA, //CAMERA UserManager.DISALLOW_RECORD_AUDIO, //RECORD_AUDIO null, //PLAY_AUDIO null, //READ_CLIPBOARD Loading core/java/android/app/admin/DevicePolicyManager.java +2 −0 Original line number Diff line number Diff line Loading @@ -2271,6 +2271,8 @@ public class DevicePolicyManager { * on the device, for this user. After setting this, no applications running as this user * will be able to access any cameras on the device. * * <p>If the caller is device owner, then the restriction will be applied to all users. * * <p>The calling device admin must have requested * {@link DeviceAdminInfo#USES_POLICY_DISABLE_CAMERA} to be able to call * this method; if it has not, a security exception will be thrown. Loading core/java/android/os/UserManager.java +10 −0 Original line number Diff line number Diff line Loading @@ -486,6 +486,16 @@ public class UserManager { */ public static final String DISALLOW_RECORD_AUDIO = "no_record_audio"; /** * Specifies if a user is not allowed to use the camera. * * @see DevicePolicyManager#addUserRestriction(ComponentName, String) * @see DevicePolicyManager#clearUserRestriction(ComponentName, String) * @see #getUserRestrictions() * @hide */ public static final String DISALLOW_CAMERA = "no_camera"; /** * Allows apps in the parent profile to handle web links from the managed profile. * Loading services/core/java/com/android/server/pm/UserManagerService.java +4 −3 Original line number Diff line number Diff line Loading @@ -738,10 +738,11 @@ public class UserManagerService extends IUserManager.Stub { mBaseUserRestrictions.put(userId, newRestrictions); } mCachedEffectiveUserRestrictions.put( userId, computeEffectiveUserRestrictionsRL(userId)); final Bundle effective = computeEffectiveUserRestrictionsRL(userId); applyUserRestrictionsRL(userId, mBaseUserRestrictions.get(userId), prevRestrictions); mCachedEffectiveUserRestrictions.put(userId, effective); applyUserRestrictionsRL(userId, effective, prevRestrictions); } @GuardedBy("mRestrictionsLock") Loading services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +42 −41 Original line number Diff line number Diff line Loading @@ -1016,6 +1016,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } // DO NOT call it while taking the "this" lock, which could cause a dead lock. private void handlePackagesChanged(String packageName, int userHandle) { boolean removed = false; if (VERBOSE_LOG) Slog.d(LOG_TAG, "Handling package changes for user " + userHandle); Loading @@ -1042,7 +1043,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } if (removed) { validatePasswordOwnerLocked(policy); syncDeviceCapabilitiesLocked(policy); saveSettingsLocked(policy.mUserHandle); } Loading @@ -1061,6 +1061,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } } if (removed) { synchronized (mUserManagerInternal.getUserRestrictionsLock()) { synchronized (DevicePolicyManagerService.this) { mUserManagerInternal.updateEffectiveUserRestrictionsRL( userHandle); } } } } /** Loading Loading @@ -1682,7 +1690,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } void removeActiveAdminLocked(final ComponentName adminReceiver, int userHandle) { void removeActiveAdminLocked(final ComponentName adminReceiver, final int userHandle) { final ActiveAdmin admin = getActiveAdminUncheckedLocked(adminReceiver, userHandle); if (admin != null) { synchronized (this) { Loading @@ -1701,7 +1709,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { policy.mAdminList.remove(admin); policy.mAdminMap.remove(adminReceiver); validatePasswordOwnerLocked(policy); syncDeviceCapabilitiesLocked(policy); if (doProxyCleanup) { resetGlobalProxyLocked(getUserData(userHandle)); } Loading @@ -1709,6 +1716,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { updateMaximumTimeToLockLocked(policy); policy.mRemovingAdmins.remove(adminReceiver); } synchronized (mUserManagerInternal.getUserRestrictionsLock()) { synchronized (DevicePolicyManagerService.this) { mUserManagerInternal.updateEffectiveUserRestrictionsRL( userHandle); } } } }); } Loading Loading @@ -2022,7 +2035,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } validatePasswordOwnerLocked(policy); syncDeviceCapabilitiesLocked(policy); updateMaximumTimeToLockLocked(policy); updateLockTaskPackagesLocked(policy.mLockTaskPackages, userHandle); if (policy.mStatusBarDisabled) { Loading Loading @@ -2089,31 +2101,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } /** * Pushes down policy information to the system for any policies related to general device * capabilities that need to be enforced by lower level services (e.g. Camera services). */ 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. String cameraPropertyForUser = SYSTEM_PROP_DISABLE_CAMERA_PREFIX + policy.mUserHandle; boolean systemState = mInjector.systemPropertiesGetBoolean(cameraPropertyForUser, false); boolean cameraDisabled = getCameraDisabled(null, policy.mUserHandle); if (cameraDisabled != systemState) { long token = mInjector.binderClearCallingIdentity(); try { String value = cameraDisabled ? "1" : "0"; if (VERBOSE_LOG) { Slog.v(LOG_TAG, "Change in camera state [" + cameraPropertyForUser + "] = " + value); } mInjector.systemPropertiesSet(cameraPropertyForUser, value); } finally { mInjector.binderRestoreCallingIdentity(token); } } } @VisibleForTesting void systemReady(int phase) { if (!mHasFeature) { Loading Loading @@ -4328,13 +4315,6 @@ 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. The userId should be appended * to this key. */ public static final String SYSTEM_PROP_DISABLE_CAMERA_PREFIX = "sys.secpolicy.camera.off_"; /** * Disables all device cameras according to the specified admin. */ Loading @@ -4352,7 +4332,16 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { ap.disableCamera = disabled; saveSettingsLocked(userHandle); } syncDeviceCapabilitiesLocked(getUserData(userHandle)); } // Tell the user manager that the restrictions have changed. synchronized (mUserManagerInternal.getUserRestrictionsLock()) { synchronized (this) { if (isDeviceOwner(who)) { mUserManagerInternal.updateEffectiveUserRestrictionsForAllUsersRL(); } else { mUserManagerInternal.updateEffectiveUserRestrictionsRL(userHandle); } } } } Loading @@ -4370,7 +4359,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle); return (admin != null) ? admin.disableCamera : false; } // First, see if DO has set it. If so, it's device-wide. final ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked(); if (deviceOwner != null && deviceOwner.disableCamera) { return true; } // Then check each device admin on the user. DevicePolicyData policy = getUserData(userHandle); // Determine whether or not the device camera is disabled for any active admins. final int N = policy.mAdminList.size(); Loading Loading @@ -4404,7 +4399,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { ap.disabledKeyguardFeatures = which; saveSettingsLocked(userHandle); } syncDeviceCapabilitiesLocked(getUserData(userHandle)); } } Loading Loading @@ -5036,7 +5030,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { DeviceAdminInfo.USES_POLICY_DISABLE_KEYGUARD_FEATURES); ap.trustAgentInfos.put(agent.flattenToString(), new TrustAgentInfo(args)); saveSettingsLocked(userHandle); syncDeviceCapabilitiesLocked(getUserData(userHandle)); } } Loading Loading @@ -5602,6 +5595,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } // DO NOT call it while taking the "this" lock, which could cause a dead lock. @Override public void setUserRestriction(ComponentName who, String key, boolean enabledFromThisOwner) { Preconditions.checkNotNull(who, "ComponentName is null"); Loading @@ -5612,7 +5606,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { ActiveAdmin activeAdmin = getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); boolean isDeviceOwner = isDeviceOwner(who); final boolean isDeviceOwner = isDeviceOwner(who); if (!isDeviceOwner && userHandle != UserHandle.USER_SYSTEM && DEVICE_OWNER_USER_RESTRICTIONS.contains(key)) { throw new SecurityException( Loading Loading @@ -6463,8 +6457,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { deviceOwner == null ? null : deviceOwner.userRestrictions; final Bundle profileOwnerRestrictions = profileOwner == null ? null : profileOwner.userRestrictions; final boolean cameraDisabled = getCameraDisabled(null, userId); if (deviceOwnerRestrictions == null && profileOwnerRestrictions == null) { if (deviceOwnerRestrictions == null && profileOwnerRestrictions == null && !cameraDisabled) { // No restrictions to merge. return inBundle; } Loading @@ -6473,6 +6469,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { UserRestrictionsUtils.merge(composed, deviceOwnerRestrictions); UserRestrictionsUtils.merge(composed, profileOwnerRestrictions); // Also merge in the camera restriction. if (cameraDisabled) { composed.putBoolean(UserManager.DISALLOW_CAMERA, true); } return composed; } } Loading Loading
core/java/android/app/AppOpsManager.java +1 −1 Original line number Diff line number Diff line Loading @@ -653,7 +653,7 @@ public class AppOpsManager { null, //WRITE_SETTINGS UserManager.DISALLOW_CREATE_WINDOWS, //SYSTEM_ALERT_WINDOW null, //ACCESS_NOTIFICATIONS null, //CAMERA UserManager.DISALLOW_CAMERA, //CAMERA UserManager.DISALLOW_RECORD_AUDIO, //RECORD_AUDIO null, //PLAY_AUDIO null, //READ_CLIPBOARD Loading
core/java/android/app/admin/DevicePolicyManager.java +2 −0 Original line number Diff line number Diff line Loading @@ -2271,6 +2271,8 @@ public class DevicePolicyManager { * on the device, for this user. After setting this, no applications running as this user * will be able to access any cameras on the device. * * <p>If the caller is device owner, then the restriction will be applied to all users. * * <p>The calling device admin must have requested * {@link DeviceAdminInfo#USES_POLICY_DISABLE_CAMERA} to be able to call * this method; if it has not, a security exception will be thrown. Loading
core/java/android/os/UserManager.java +10 −0 Original line number Diff line number Diff line Loading @@ -486,6 +486,16 @@ public class UserManager { */ public static final String DISALLOW_RECORD_AUDIO = "no_record_audio"; /** * Specifies if a user is not allowed to use the camera. * * @see DevicePolicyManager#addUserRestriction(ComponentName, String) * @see DevicePolicyManager#clearUserRestriction(ComponentName, String) * @see #getUserRestrictions() * @hide */ public static final String DISALLOW_CAMERA = "no_camera"; /** * Allows apps in the parent profile to handle web links from the managed profile. * Loading
services/core/java/com/android/server/pm/UserManagerService.java +4 −3 Original line number Diff line number Diff line Loading @@ -738,10 +738,11 @@ public class UserManagerService extends IUserManager.Stub { mBaseUserRestrictions.put(userId, newRestrictions); } mCachedEffectiveUserRestrictions.put( userId, computeEffectiveUserRestrictionsRL(userId)); final Bundle effective = computeEffectiveUserRestrictionsRL(userId); applyUserRestrictionsRL(userId, mBaseUserRestrictions.get(userId), prevRestrictions); mCachedEffectiveUserRestrictions.put(userId, effective); applyUserRestrictionsRL(userId, effective, prevRestrictions); } @GuardedBy("mRestrictionsLock") Loading
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +42 −41 Original line number Diff line number Diff line Loading @@ -1016,6 +1016,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } // DO NOT call it while taking the "this" lock, which could cause a dead lock. private void handlePackagesChanged(String packageName, int userHandle) { boolean removed = false; if (VERBOSE_LOG) Slog.d(LOG_TAG, "Handling package changes for user " + userHandle); Loading @@ -1042,7 +1043,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } if (removed) { validatePasswordOwnerLocked(policy); syncDeviceCapabilitiesLocked(policy); saveSettingsLocked(policy.mUserHandle); } Loading @@ -1061,6 +1061,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } } if (removed) { synchronized (mUserManagerInternal.getUserRestrictionsLock()) { synchronized (DevicePolicyManagerService.this) { mUserManagerInternal.updateEffectiveUserRestrictionsRL( userHandle); } } } } /** Loading Loading @@ -1682,7 +1690,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } void removeActiveAdminLocked(final ComponentName adminReceiver, int userHandle) { void removeActiveAdminLocked(final ComponentName adminReceiver, final int userHandle) { final ActiveAdmin admin = getActiveAdminUncheckedLocked(adminReceiver, userHandle); if (admin != null) { synchronized (this) { Loading @@ -1701,7 +1709,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { policy.mAdminList.remove(admin); policy.mAdminMap.remove(adminReceiver); validatePasswordOwnerLocked(policy); syncDeviceCapabilitiesLocked(policy); if (doProxyCleanup) { resetGlobalProxyLocked(getUserData(userHandle)); } Loading @@ -1709,6 +1716,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { updateMaximumTimeToLockLocked(policy); policy.mRemovingAdmins.remove(adminReceiver); } synchronized (mUserManagerInternal.getUserRestrictionsLock()) { synchronized (DevicePolicyManagerService.this) { mUserManagerInternal.updateEffectiveUserRestrictionsRL( userHandle); } } } }); } Loading Loading @@ -2022,7 +2035,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } validatePasswordOwnerLocked(policy); syncDeviceCapabilitiesLocked(policy); updateMaximumTimeToLockLocked(policy); updateLockTaskPackagesLocked(policy.mLockTaskPackages, userHandle); if (policy.mStatusBarDisabled) { Loading Loading @@ -2089,31 +2101,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } /** * Pushes down policy information to the system for any policies related to general device * capabilities that need to be enforced by lower level services (e.g. Camera services). */ 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. String cameraPropertyForUser = SYSTEM_PROP_DISABLE_CAMERA_PREFIX + policy.mUserHandle; boolean systemState = mInjector.systemPropertiesGetBoolean(cameraPropertyForUser, false); boolean cameraDisabled = getCameraDisabled(null, policy.mUserHandle); if (cameraDisabled != systemState) { long token = mInjector.binderClearCallingIdentity(); try { String value = cameraDisabled ? "1" : "0"; if (VERBOSE_LOG) { Slog.v(LOG_TAG, "Change in camera state [" + cameraPropertyForUser + "] = " + value); } mInjector.systemPropertiesSet(cameraPropertyForUser, value); } finally { mInjector.binderRestoreCallingIdentity(token); } } } @VisibleForTesting void systemReady(int phase) { if (!mHasFeature) { Loading Loading @@ -4328,13 +4315,6 @@ 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. The userId should be appended * to this key. */ public static final String SYSTEM_PROP_DISABLE_CAMERA_PREFIX = "sys.secpolicy.camera.off_"; /** * Disables all device cameras according to the specified admin. */ Loading @@ -4352,7 +4332,16 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { ap.disableCamera = disabled; saveSettingsLocked(userHandle); } syncDeviceCapabilitiesLocked(getUserData(userHandle)); } // Tell the user manager that the restrictions have changed. synchronized (mUserManagerInternal.getUserRestrictionsLock()) { synchronized (this) { if (isDeviceOwner(who)) { mUserManagerInternal.updateEffectiveUserRestrictionsForAllUsersRL(); } else { mUserManagerInternal.updateEffectiveUserRestrictionsRL(userHandle); } } } } Loading @@ -4370,7 +4359,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle); return (admin != null) ? admin.disableCamera : false; } // First, see if DO has set it. If so, it's device-wide. final ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked(); if (deviceOwner != null && deviceOwner.disableCamera) { return true; } // Then check each device admin on the user. DevicePolicyData policy = getUserData(userHandle); // Determine whether or not the device camera is disabled for any active admins. final int N = policy.mAdminList.size(); Loading Loading @@ -4404,7 +4399,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { ap.disabledKeyguardFeatures = which; saveSettingsLocked(userHandle); } syncDeviceCapabilitiesLocked(getUserData(userHandle)); } } Loading Loading @@ -5036,7 +5030,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { DeviceAdminInfo.USES_POLICY_DISABLE_KEYGUARD_FEATURES); ap.trustAgentInfos.put(agent.flattenToString(), new TrustAgentInfo(args)); saveSettingsLocked(userHandle); syncDeviceCapabilitiesLocked(getUserData(userHandle)); } } Loading Loading @@ -5602,6 +5595,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } // DO NOT call it while taking the "this" lock, which could cause a dead lock. @Override public void setUserRestriction(ComponentName who, String key, boolean enabledFromThisOwner) { Preconditions.checkNotNull(who, "ComponentName is null"); Loading @@ -5612,7 +5606,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { ActiveAdmin activeAdmin = getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); boolean isDeviceOwner = isDeviceOwner(who); final boolean isDeviceOwner = isDeviceOwner(who); if (!isDeviceOwner && userHandle != UserHandle.USER_SYSTEM && DEVICE_OWNER_USER_RESTRICTIONS.contains(key)) { throw new SecurityException( Loading Loading @@ -6463,8 +6457,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { deviceOwner == null ? null : deviceOwner.userRestrictions; final Bundle profileOwnerRestrictions = profileOwner == null ? null : profileOwner.userRestrictions; final boolean cameraDisabled = getCameraDisabled(null, userId); if (deviceOwnerRestrictions == null && profileOwnerRestrictions == null) { if (deviceOwnerRestrictions == null && profileOwnerRestrictions == null && !cameraDisabled) { // No restrictions to merge. return inBundle; } Loading @@ -6473,6 +6469,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { UserRestrictionsUtils.merge(composed, deviceOwnerRestrictions); UserRestrictionsUtils.merge(composed, profileOwnerRestrictions); // Also merge in the camera restriction. if (cameraDisabled) { composed.putBoolean(UserManager.DISALLOW_CAMERA, true); } return composed; } } Loading