From f5395a96510a57fc491fe23f945935c53116820f Mon Sep 17 00:00:00 2001 From: Evan Severson Date: Fri, 19 Feb 2021 15:44:58 -0800 Subject: [PATCH] Set user restriction when mic/camera toggles are used The user restriction will result in the app op returning MODE_IGNORED so the providers know that they shouldn't deliver mic/camera data. The camera service needs to check the state of the toggle directly on app op change so it knows that the ignore was a result of the toggle. TODO: don't allow this restriction to be bypassed Bug: 162549680 Test: Use the features Change-Id: Ia944059f7c217b50ae016de62a25a067fe21878a --- .../android/server/SensorPrivacyService.java | 40 ++++++++++++++++--- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/services/core/java/com/android/server/SensorPrivacyService.java b/services/core/java/com/android/server/SensorPrivacyService.java index f2782f64995ab..8f291898c14d6 100644 --- a/services/core/java/com/android/server/SensorPrivacyService.java +++ b/services/core/java/com/android/server/SensorPrivacyService.java @@ -19,9 +19,10 @@ package com.android.server; import static android.Manifest.permission.MANAGE_SENSOR_PRIVACY; import static android.app.ActivityManager.RunningServiceInfo; import static android.app.ActivityManager.RunningTaskInfo; -import static android.app.AppOpsManager.MODE_ALLOWED; +import static android.app.AppOpsManager.MODE_IGNORED; import static android.app.AppOpsManager.OP_CAMERA; import static android.app.AppOpsManager.OP_RECORD_AUDIO; +import static android.app.AppOpsManager.OP_RECORD_AUDIO_HOTWORD; import static android.content.Intent.EXTRA_PACKAGE_NAME; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.hardware.SensorPrivacyManager.EXTRA_SENSOR; @@ -136,9 +137,13 @@ public final class SensorPrivacyService extends SystemService { private final UserManagerInternal mUserManagerInternal; private final ActivityManager mActivityManager; private final ActivityTaskManager mActivityTaskManager; + private final AppOpsManager mAppOpsManager; + + private final IBinder mAppOpsRestrictionToken = new Binder(); public SensorPrivacyService(Context context) { super(context); + mAppOpsManager = context.getSystemService(AppOpsManager.class); mUserManagerInternal = getLocalService(UserManagerInternal.class); mSensorPrivacyServiceImpl = new SensorPrivacyServiceImpl(context); mActivityManager = context.getSystemService(ActivityManager.class); @@ -185,10 +190,20 @@ public final class SensorPrivacyService extends SystemService { } } + for (int i = 0; i < mIndividualEnabled.size(); i++) { + int userId = mIndividualEnabled.keyAt(i); + SparseBooleanArray userIndividualEnabled = + mIndividualEnabled.get(i); + for (int j = 0; j < userIndividualEnabled.size(); j++) { + int sensor = userIndividualEnabled.keyAt(i); + boolean enabled = userIndividualEnabled.valueAt(j); + setUserRestriction(userId, sensor, enabled); + } + } + int[] micAndCameraOps = new int[]{OP_RECORD_AUDIO, OP_CAMERA}; - AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class); - appOpsManager.startWatchingNoted(micAndCameraOps, this); - appOpsManager.startWatchingStarted(micAndCameraOps, this); + mAppOpsManager.startWatchingNoted(micAndCameraOps, this); + mAppOpsManager.startWatchingStarted(micAndCameraOps, this); mContext.registerReceiver(new BroadcastReceiver() { @Override @@ -212,7 +227,7 @@ public final class SensorPrivacyService extends SystemService { public void onOpNoted(int code, int uid, String packageName, String attributionTag, @AppOpsManager.OpFlags int flags, @AppOpsManager.Mode int result) { - if (result != MODE_ALLOWED || (flags & AppOpsManager.OP_FLAGS_ALL_TRUSTED) == 0) { + if (result != MODE_IGNORED || (flags & AppOpsManager.OP_FLAGS_ALL_TRUSTED) == 0) { return; } @@ -1110,6 +1125,9 @@ public final class SensorPrivacyService extends SystemService { public void handleSensorPrivacyChanged(int userId, int sensor, boolean enabled) { SparseArray> listenersForUser = mIndividualSensorListeners.get(userId); + + setUserRestriction(userId, sensor, enabled); + if (listenersForUser == null) { return; } @@ -1137,6 +1155,18 @@ public final class SensorPrivacyService extends SystemService { } } + private void setUserRestriction(int userId, int sensor, boolean enabled) { + if (sensor == CAMERA) { + mAppOpsManager.setUserRestrictionForUser(OP_CAMERA, enabled, + mAppOpsRestrictionToken, new String[]{}, userId); + } else if (sensor == MICROPHONE) { + mAppOpsManager.setUserRestrictionForUser(OP_RECORD_AUDIO, enabled, + mAppOpsRestrictionToken, new String[]{}, userId); + mAppOpsManager.setUserRestrictionForUser(OP_RECORD_AUDIO_HOTWORD, enabled, + mAppOpsRestrictionToken, new String[]{}, userId); + } + } + private final class DeathRecipient implements IBinder.DeathRecipient { private ISensorPrivacyListener mListener;