diff options
3 files changed, 55 insertions, 0 deletions
diff --git a/core/java/android/app/AppOpsManagerInternal.java b/core/java/android/app/AppOpsManagerInternal.java index 363b5a75b214..4d6e4aedba66 100644 --- a/core/java/android/app/AppOpsManagerInternal.java +++ b/core/java/android/app/AppOpsManagerInternal.java @@ -21,6 +21,7 @@ import android.annotation.Nullable; import android.app.AppOpsManager.AttributionFlags; import android.content.AttributionSource; import android.os.IBinder; +import android.os.UserHandle; import android.util.SparseArray; import android.util.SparseIntArray; @@ -215,4 +216,11 @@ public abstract class AppOpsManagerInternal { * Sets a global restriction on an op code. */ public abstract void setGlobalRestriction(int code, boolean restricted, IBinder token); + + /** + * Gets the number of tokens restricting the given appop for a user, package, and + * attributionTag. + */ + public abstract int getOpRestrictionCount(int code, UserHandle user, String pkg, + String attributionTag); } diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index 24edc01c24df..a9905dcf8904 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -7297,6 +7297,30 @@ public class AppOpsService extends IAppOpsService.Stub { } } } + + @Override + public int getOpRestrictionCount(int code, UserHandle user, String pkg, + String attributionTag) { + int number = 0; + synchronized (AppOpsService.this) { + int numRestrictions = mOpUserRestrictions.size(); + for (int i = 0; i < numRestrictions; i++) { + if (mOpUserRestrictions.valueAt(i) + .hasRestriction(code, pkg, attributionTag, user.getIdentifier())) { + number++; + } + } + + numRestrictions = mOpGlobalRestrictions.size(); + for (int i = 0; i < numRestrictions; i++) { + if (mOpGlobalRestrictions.valueAt(i).hasRestriction(code)) { + number++; + } + } + } + + return number; + } } /** diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java index d3d1c1ca6a2b..e3459a1edc0f 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java @@ -17,6 +17,7 @@ package com.android.server.wm; import static android.Manifest.permission.ACTIVITY_EMBEDDING; +import static android.Manifest.permission.CAMERA; import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW; import static android.Manifest.permission.START_ANY_ACTIVITY; import static android.app.ActivityManager.LOCK_TASK_MODE_LOCKED; @@ -88,6 +89,7 @@ import android.app.ActivityManager; import android.app.ActivityManagerInternal; import android.app.ActivityOptions; import android.app.AppOpsManager; +import android.app.AppOpsManagerInternal; import android.app.IActivityClientController; import android.app.ProfilerInfo; import android.app.ResultInfo; @@ -108,6 +110,8 @@ import android.content.pm.ResolveInfo; import android.content.pm.UserInfo; import android.content.res.Configuration; import android.graphics.Rect; +import android.hardware.SensorPrivacyManager; +import android.hardware.SensorPrivacyManagerInternal; import android.os.Binder; import android.os.Build; import android.os.Bundle; @@ -141,6 +145,7 @@ import com.android.internal.protolog.common.ProtoLog; import com.android.internal.util.ArrayUtils; import com.android.internal.util.function.pooled.PooledConsumer; import com.android.internal.util.function.pooled.PooledLambda; +import com.android.server.LocalServices; import com.android.server.am.ActivityManagerService; import com.android.server.am.UserState; import com.android.server.wm.ActivityMetricsLogger.LaunchingState; @@ -1221,6 +1226,24 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { if (getAppOpsManager().noteOpNoThrow(opCode, callingUid, callingPackage, callingFeatureId, "") != AppOpsManager.MODE_ALLOWED) { + if (CAMERA.equals(permission)) { + SensorPrivacyManagerInternal spmi = + LocalServices.getService(SensorPrivacyManagerInternal.class); + + final UserHandle user = UserHandle.getUserHandleForUid(callingUid); + final boolean cameraPrivacyEnabled = spmi.isSensorPrivacyEnabled( + user.getIdentifier(), SensorPrivacyManager.Sensors.CAMERA); + if (cameraPrivacyEnabled) { + AppOpsManagerInternal aomi = LocalServices.getService( + AppOpsManagerInternal.class); + int numCameraRestrictions = aomi.getOpRestrictionCount( + AppOpsManager.OP_CAMERA, user, callingPackage, null); + if (numCameraRestrictions == 1) { + // Only restricted by the toggles, do not restrict + return ACTIVITY_RESTRICTION_NONE; + } + } + } return ACTIVITY_RESTRICTION_APPOP; } |