Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5263492d authored by Makoto Onuki's avatar Makoto Onuki Committed by Android (Google) Code Review
Browse files

Merge "Allow DO to disable camera device-wise."

parents 3ac162ec 759a763f
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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
+2 −0
Original line number Diff line number Diff line
@@ -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.
+10 −0
Original line number Diff line number Diff line
@@ -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.
     *
+4 −3
Original line number Diff line number Diff line
@@ -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")
+42 −41
Original line number Diff line number Diff line
@@ -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);
@@ -1042,7 +1043,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
            }
            if (removed) {
                validatePasswordOwnerLocked(policy);
                syncDeviceCapabilitiesLocked(policy);
                saveSettingsLocked(policy.mUserHandle);
            }

@@ -1061,6 +1061,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
                }
            }
        }
        if (removed) {
            synchronized (mUserManagerInternal.getUserRestrictionsLock()) {
                synchronized (DevicePolicyManagerService.this) {
                    mUserManagerInternal.updateEffectiveUserRestrictionsRL(
                            userHandle);
                }
            }
        }
    }

    /**
@@ -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) {
@@ -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));
                                }
@@ -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);
                                }
                            }
                        }
                    });
        }
@@ -2022,7 +2035,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
        }

        validatePasswordOwnerLocked(policy);
        syncDeviceCapabilitiesLocked(policy);
        updateMaximumTimeToLockLocked(policy);
        updateLockTaskPackagesLocked(policy.mLockTaskPackages, userHandle);
        if (policy.mStatusBarDisabled) {
@@ -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) {
@@ -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.
     */
@@ -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);
                }
            }
        }
    }

@@ -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();
@@ -4404,7 +4399,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
                ap.disabledKeyguardFeatures = which;
                saveSettingsLocked(userHandle);
            }
            syncDeviceCapabilitiesLocked(getUserData(userHandle));
        }
    }

@@ -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));
        }
    }

@@ -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");
@@ -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(
@@ -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;
                }
@@ -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;
            }
        }