From 76be38c05c4c2d44f1687571ff5e6db341687686 Mon Sep 17 00:00:00 2001 From: Pyuli Naithani Date: Fri, 2 Jul 2021 22:22:32 +0000 Subject: [PATCH] Add statsd logs for Sensor Privacy. BUG: 192269258 Test: ran statsd_testdrive 381 Change-Id: I6f1f2bfe13889f7b3a39684769715cbd4f6009e3 --- core/api/test-current.txt | 12 ++- .../hardware/ISensorPrivacyManager.aidl | 4 +- .../hardware/SensorPrivacyManager.java | 77 +++++++++++++++--- .../android/hardware/sensorprivacy.proto | 18 +++++ .../qs/tiles/SensorPrivacyToggleTile.java | 6 +- .../sensorprivacy/SensorUseStartedActivity.kt | 7 +- .../television/TvUnblockSensorActivity.java | 7 +- .../IndividualSensorPrivacyController.java | 3 +- ...IndividualSensorPrivacyControllerImpl.java | 5 +- .../android/server/SensorPrivacyService.java | 80 +++++++++++++++++-- 10 files changed, 185 insertions(+), 34 deletions(-) diff --git a/core/api/test-current.txt b/core/api/test-current.txt index cb60b011d00e..54a13abdc1d5 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -1047,8 +1047,16 @@ package android.graphics.fonts { package android.hardware { public final class SensorPrivacyManager { - method @RequiresPermission(android.Manifest.permission.MANAGE_SENSOR_PRIVACY) public void setSensorPrivacy(int, boolean); - method @RequiresPermission(android.Manifest.permission.MANAGE_SENSOR_PRIVACY) public void setSensorPrivacyForProfileGroup(int, boolean); + method @RequiresPermission(android.Manifest.permission.MANAGE_SENSOR_PRIVACY) public void setSensorPrivacy(int, int, boolean); + method @RequiresPermission(android.Manifest.permission.MANAGE_SENSOR_PRIVACY) public void setSensorPrivacyForProfileGroup(int, int, boolean); + } + + public static class SensorPrivacyManager.Sources { + field public static final int DIALOG = 3; // 0x3 + field public static final int OTHER = 5; // 0x5 + field public static final int QS_TILE = 1; // 0x1 + field public static final int SETTINGS = 2; // 0x2 + field public static final int SHELL = 4; // 0x4 } } diff --git a/core/java/android/hardware/ISensorPrivacyManager.aidl b/core/java/android/hardware/ISensorPrivacyManager.aidl index 1c8e95917484..6105c26dc651 100644 --- a/core/java/android/hardware/ISensorPrivacyManager.aidl +++ b/core/java/android/hardware/ISensorPrivacyManager.aidl @@ -41,9 +41,9 @@ interface ISensorPrivacyManager { void setSensorPrivacy(boolean enable); - void setIndividualSensorPrivacy(int userId, int sensor, boolean enable); + void setIndividualSensorPrivacy(int userId, int source, int sensor, boolean enable); - void setIndividualSensorPrivacyForProfileGroup(int userId, int sensor, boolean enable); + void setIndividualSensorPrivacyForProfileGroup(int userId, int source, int sensor, boolean enable); // =============== End of transactions used on native side as well ============================ void suppressIndividualSensorPrivacyReminders(int userId, String packageName, IBinder token, diff --git a/core/java/android/hardware/SensorPrivacyManager.java b/core/java/android/hardware/SensorPrivacyManager.java index 1a5e5a85d2a1..584ad55532a3 100644 --- a/core/java/android/hardware/SensorPrivacyManager.java +++ b/core/java/android/hardware/SensorPrivacyManager.java @@ -30,6 +30,7 @@ import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; import android.service.SensorPrivacyIndividualEnabledSensorProto; +import android.service.SensorPrivacyToggleSourceProto; import android.util.ArrayMap; import android.util.Pair; import android.util.SparseArray; @@ -102,6 +103,56 @@ public final class SensorPrivacyManager { public @interface Sensor {} } + /** + * Source through which Privacy Sensor was toggled. + * @hide + */ + @TestApi + public static class Sources { + private Sources() {} + + /** + * Constant for the Quick Setting Tile. + */ + public static final int QS_TILE = SensorPrivacyToggleSourceProto.QS_TILE; + + /** + * Constant for the Settings. + */ + public static final int SETTINGS = SensorPrivacyToggleSourceProto.SETTINGS; + + /** + * Constant for Dialog. + */ + public static final int DIALOG = SensorPrivacyToggleSourceProto.DIALOG; + + /** + * Constant for SHELL. + */ + public static final int SHELL = SensorPrivacyToggleSourceProto.SHELL; + + /** + * Constant for OTHER. + */ + public static final int OTHER = SensorPrivacyToggleSourceProto.OTHER; + + /** + * Source for toggling sensors + * + * @hide + */ + @IntDef(value = { + QS_TILE, + SETTINGS, + DIALOG, + SHELL, + OTHER + }) + @Retention(RetentionPolicy.SOURCE) + public @interface Source {} + + } + /** * A class implementing this interface can register with the {@link * android.hardware.SensorPrivacyManager} to receive notification when the sensor privacy @@ -343,8 +394,9 @@ public final class SensorPrivacyManager { */ @TestApi @RequiresPermission(Manifest.permission.MANAGE_SENSOR_PRIVACY) - public void setSensorPrivacy(@Sensors.Sensor int sensor, boolean enable) { - setSensorPrivacy(sensor, enable, mContext.getUserId()); + public void setSensorPrivacy(@Sources.Source int source, @Sensors.Sensor int sensor, + boolean enable) { + setSensorPrivacy(source, sensor, enable, mContext.getUserId()); } /** @@ -357,10 +409,10 @@ public final class SensorPrivacyManager { * @hide */ @RequiresPermission(Manifest.permission.MANAGE_SENSOR_PRIVACY) - public void setSensorPrivacy(@Sensors.Sensor int sensor, boolean enable, - @UserIdInt int userId) { + public void setSensorPrivacy(@Sources.Source int source, @Sensors.Sensor int sensor, + boolean enable, @UserIdInt int userId) { try { - mService.setIndividualSensorPrivacy(userId, sensor, enable); + mService.setIndividualSensorPrivacy(userId, source, sensor, enable); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -370,6 +422,7 @@ public final class SensorPrivacyManager { * Sets sensor privacy to the specified state for an individual sensor for the profile group of * context's user. * + * @param source the source using which the sensor is toggled. * @param sensor the sensor which to change the state for * @param enable the state to which sensor privacy should be set. * @@ -377,15 +430,16 @@ public final class SensorPrivacyManager { */ @TestApi @RequiresPermission(Manifest.permission.MANAGE_SENSOR_PRIVACY) - public void setSensorPrivacyForProfileGroup(@Sensors.Sensor int sensor, - boolean enable) { - setSensorPrivacyForProfileGroup(sensor, enable, mContext.getUserId()); + public void setSensorPrivacyForProfileGroup(@Sources.Source int source, + @Sensors.Sensor int sensor, boolean enable) { + setSensorPrivacyForProfileGroup(source , sensor, enable, mContext.getUserId()); } /** * Sets sensor privacy to the specified state for an individual sensor for the profile group of * context's user. * + * @param source the source using which the sensor is toggled. * @param sensor the sensor which to change the state for * @param enable the state to which sensor privacy should be set. * @param userId the user's id @@ -393,11 +447,10 @@ public final class SensorPrivacyManager { * @hide */ @RequiresPermission(Manifest.permission.MANAGE_SENSOR_PRIVACY) - public void setSensorPrivacyForProfileGroup(@Sensors.Sensor int sensor, - boolean enable, @UserIdInt int userId) { + public void setSensorPrivacyForProfileGroup(@Sources.Source int source, + @Sensors.Sensor int sensor, boolean enable, @UserIdInt int userId) { try { - mService.setIndividualSensorPrivacyForProfileGroup(userId, sensor, - enable); + mService.setIndividualSensorPrivacyForProfileGroup(userId, source, sensor, enable); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/proto/android/hardware/sensorprivacy.proto b/core/proto/android/hardware/sensorprivacy.proto index 401e0038cada..d52af5c6fe67 100644 --- a/core/proto/android/hardware/sensorprivacy.proto +++ b/core/proto/android/hardware/sensorprivacy.proto @@ -65,4 +65,22 @@ message SensorPrivacyIndividualEnabledSensorProto { // If sensor privacy is enabled for this sensor optional bool is_enabled = 2; +} + +message SensorPrivacyToggleSourceProto { + option (android.msg_privacy).dest = DEST_AUTOMATIC; + + enum Source { + UNKNOWN = 0; + + QS_TILE = 1; + SETTINGS = 2; + DIALOG = 3; + SHELL = 4; + OTHER = 5; + } + + // Source for which sensor privacy was toggled. + optional Source source = 1; + } \ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/SensorPrivacyToggleTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/SensorPrivacyToggleTile.java index f13576c2d4cc..bf72b7728232 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/SensorPrivacyToggleTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/SensorPrivacyToggleTile.java @@ -16,6 +16,8 @@ package com.android.systemui.qs.tiles; +import static android.hardware.SensorPrivacyManager.Sources.QS_TILE; + import android.content.Intent; import android.hardware.SensorPrivacyManager.Sensors.Sensor; import android.os.Handler; @@ -87,12 +89,12 @@ public abstract class SensorPrivacyToggleTile extends QSTileImpl { - mSensorPrivacyController.setSensorBlocked(getSensorId(), + mSensorPrivacyController.setSensorBlocked(QS_TILE, getSensorId(), !mSensorPrivacyController.isSensorBlocked(getSensorId())); }); return; } - mSensorPrivacyController.setSensorBlocked(getSensorId(), + mSensorPrivacyController.setSensorBlocked(QS_TILE, getSensorId(), !mSensorPrivacyController.isSensorBlocked(getSensorId())); } diff --git a/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseStartedActivity.kt b/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseStartedActivity.kt index a79316d6f5a9..24775344240a 100644 --- a/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseStartedActivity.kt +++ b/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseStartedActivity.kt @@ -23,6 +23,7 @@ import android.content.res.Resources import android.hardware.SensorPrivacyManager import android.hardware.SensorPrivacyManager.EXTRA_ALL_SENSORS import android.hardware.SensorPrivacyManager.EXTRA_SENSOR +import android.hardware.SensorPrivacyManager.Sources.DIALOG import android.os.Bundle import android.os.Handler import android.text.Html @@ -225,10 +226,10 @@ class SensorUseStartedActivity @Inject constructor( private fun disableSensorPrivacy() { if (sensor == ALL_SENSORS) { - sensorPrivacyController.setSensorBlocked(MICROPHONE, false) - sensorPrivacyController.setSensorBlocked(CAMERA, false) + sensorPrivacyController.setSensorBlocked(DIALOG, MICROPHONE, false) + sensorPrivacyController.setSensorBlocked(DIALOG, CAMERA, false) } else { - sensorPrivacyController.setSensorBlocked(sensor, false) + sensorPrivacyController.setSensorBlocked(DIALOG, sensor, false) } unsuppressImmediately = true setResult(RESULT_OK) diff --git a/packages/SystemUI/src/com/android/systemui/sensorprivacy/television/TvUnblockSensorActivity.java b/packages/SystemUI/src/com/android/systemui/sensorprivacy/television/TvUnblockSensorActivity.java index 9d101effa99f..8cd3632b65ba 100644 --- a/packages/SystemUI/src/com/android/systemui/sensorprivacy/television/TvUnblockSensorActivity.java +++ b/packages/SystemUI/src/com/android/systemui/sensorprivacy/television/TvUnblockSensorActivity.java @@ -18,6 +18,7 @@ package com.android.systemui.sensorprivacy.television; import static android.hardware.SensorPrivacyManager.Sensors.CAMERA; import static android.hardware.SensorPrivacyManager.Sensors.MICROPHONE; +import static android.hardware.SensorPrivacyManager.Sources.OTHER; import android.hardware.SensorPrivacyManager; import android.os.Bundle; @@ -119,10 +120,10 @@ public class TvUnblockSensorActivity extends TvBottomSheetActivity { com.android.internal.R.string.sensor_privacy_start_use_dialog_turn_on_button); unblockButton.setOnClickListener(v -> { if (mSensor == ALL_SENSORS) { - mSensorPrivacyController.setSensorBlocked(CAMERA, false); - mSensorPrivacyController.setSensorBlocked(MICROPHONE, false); + mSensorPrivacyController.setSensorBlocked(OTHER, CAMERA, false); + mSensorPrivacyController.setSensorBlocked(OTHER, MICROPHONE, false); } else { - mSensorPrivacyController.setSensorBlocked(mSensor, false); + mSensorPrivacyController.setSensorBlocked(OTHER, mSensor, false); } }); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/IndividualSensorPrivacyController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/IndividualSensorPrivacyController.java index d7d1e737661e..acfdda4cea49 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/IndividualSensorPrivacyController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/IndividualSensorPrivacyController.java @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.policy; import android.hardware.SensorPrivacyManager.Sensors.Sensor; +import android.hardware.SensorPrivacyManager.Sources.Source; public interface IndividualSensorPrivacyController extends CallbackController { @@ -26,7 +27,7 @@ public interface IndividualSensorPrivacyController extends boolean isSensorBlocked(@Sensor int sensor); - void setSensorBlocked(@Sensor int sensor, boolean blocked); + void setSensorBlocked(@Source int source, @Sensor int sensor, boolean blocked); void suppressSensorPrivacyReminders(String packageName, boolean suppress); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/IndividualSensorPrivacyControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/IndividualSensorPrivacyControllerImpl.java index f58a7c030b80..9807165f69d0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/IndividualSensorPrivacyControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/IndividualSensorPrivacyControllerImpl.java @@ -21,6 +21,7 @@ import static android.hardware.SensorPrivacyManager.Sensors.MICROPHONE; import android.hardware.SensorPrivacyManager; import android.hardware.SensorPrivacyManager.Sensors.Sensor; +import android.hardware.SensorPrivacyManager.Sources.Source; import android.util.ArraySet; import android.util.SparseBooleanArray; @@ -62,8 +63,8 @@ public class IndividualSensorPrivacyControllerImpl implements IndividualSensorPr } @Override - public void setSensorBlocked(@Sensor int sensor, boolean blocked) { - mSensorPrivacyManager.setSensorPrivacyForProfileGroup(sensor, blocked); + public void setSensorBlocked(@Source int source, @Sensor int sensor, boolean blocked) { + mSensorPrivacyManager.setSensorPrivacyForProfileGroup(source, sensor, blocked); } @Override diff --git a/services/core/java/com/android/server/SensorPrivacyService.java b/services/core/java/com/android/server/SensorPrivacyService.java index 2a3358f4c7b6..a6dab4a6757e 100644 --- a/services/core/java/com/android/server/SensorPrivacyService.java +++ b/services/core/java/com/android/server/SensorPrivacyService.java @@ -36,9 +36,26 @@ import static android.hardware.SensorPrivacyManager.EXTRA_ALL_SENSORS; import static android.hardware.SensorPrivacyManager.EXTRA_SENSOR; import static android.hardware.SensorPrivacyManager.Sensors.CAMERA; import static android.hardware.SensorPrivacyManager.Sensors.MICROPHONE; +import static android.hardware.SensorPrivacyManager.Sources.DIALOG; +import static android.hardware.SensorPrivacyManager.Sources.OTHER; +import static android.hardware.SensorPrivacyManager.Sources.QS_TILE; +import static android.hardware.SensorPrivacyManager.Sources.SETTINGS; +import static android.hardware.SensorPrivacyManager.Sources.SHELL; import static android.os.UserHandle.USER_SYSTEM; import static android.service.SensorPrivacyIndividualEnabledSensorProto.UNKNOWN; +import static com.android.internal.util.FrameworkStatsLog.PRIVACY_SENSOR_TOGGLE_INTERACTION; +import static com.android.internal.util.FrameworkStatsLog.PRIVACY_SENSOR_TOGGLE_INTERACTION__ACTION__TOGGLE_OFF; +import static com.android.internal.util.FrameworkStatsLog.PRIVACY_SENSOR_TOGGLE_INTERACTION__ACTION__TOGGLE_ON; +import static com.android.internal.util.FrameworkStatsLog.PRIVACY_SENSOR_TOGGLE_INTERACTION__SENSOR__CAMERA; +import static com.android.internal.util.FrameworkStatsLog.PRIVACY_SENSOR_TOGGLE_INTERACTION__SENSOR__MICROPHONE; +import static com.android.internal.util.FrameworkStatsLog.PRIVACY_SENSOR_TOGGLE_INTERACTION__SENSOR__SENSOR_UNKNOWN; +import static com.android.internal.util.FrameworkStatsLog.PRIVACY_SENSOR_TOGGLE_INTERACTION__SOURCE__DIALOG; +import static com.android.internal.util.FrameworkStatsLog.PRIVACY_SENSOR_TOGGLE_INTERACTION__SOURCE__QS_TILE; +import static com.android.internal.util.FrameworkStatsLog.PRIVACY_SENSOR_TOGGLE_INTERACTION__SOURCE__SETTINGS; +import static com.android.internal.util.FrameworkStatsLog.PRIVACY_SENSOR_TOGGLE_INTERACTION__SOURCE__SOURCE_UNKNOWN; +import static com.android.internal.util.FrameworkStatsLog.write; + import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; @@ -287,12 +304,14 @@ public final class SensorPrivacyService extends SystemService { mAppOpsManager.startWatchingNoted(micAndCameraOps, this); mAppOpsManager.startWatchingStarted(micAndCameraOps, this); + + mContext.registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { setIndividualSensorPrivacy( ((UserHandle) intent.getParcelableExtra( - Intent.EXTRA_USER)).getIdentifier(), + Intent.EXTRA_USER)).getIdentifier(), OTHER, intent.getIntExtra(EXTRA_SENSOR, UNKNOWN), false); } }, new IntentFilter(ACTION_DISABLE_INDIVIDUAL_SENSOR_PRIVACY), @@ -627,12 +646,17 @@ public final class SensorPrivacyService extends SystemService { } @Override - public void setIndividualSensorPrivacy(@UserIdInt int userId, int sensor, boolean enable) { + public void setIndividualSensorPrivacy(@UserIdInt int userId, + @SensorPrivacyManager.Sources.Source int source, int sensor, boolean enable) { enforceManageSensorPrivacyPermission(); if (!canChangeIndividualSensorPrivacy(userId, sensor)) { return; } + if (userId == mUserManagerInternal.getProfileParentId(userId)) { + logSensorPrivacyToggle(source, sensor, enable); + } + setIndividualSensorPrivacyUnchecked(userId, sensor, enable); } @@ -686,14 +710,56 @@ public final class SensorPrivacyService extends SystemService { return true; } + private void logSensorPrivacyToggle(int source, int sensor, boolean enable) { + long logMins = 0L; + //(TODO:pyuli) : Add timestamp after persistent storage for timestamp is done. + + int logAction = -1; + if (enable) { + logAction = PRIVACY_SENSOR_TOGGLE_INTERACTION__ACTION__TOGGLE_OFF; + } else { + logAction = PRIVACY_SENSOR_TOGGLE_INTERACTION__ACTION__TOGGLE_ON; + } + + int logSensor = -1; + switch(sensor) { + case CAMERA: + logSensor = PRIVACY_SENSOR_TOGGLE_INTERACTION__SENSOR__CAMERA; + break; + case MICROPHONE: + logSensor = PRIVACY_SENSOR_TOGGLE_INTERACTION__SENSOR__MICROPHONE; + break; + default: + logSensor = PRIVACY_SENSOR_TOGGLE_INTERACTION__SENSOR__SENSOR_UNKNOWN; + } + + int logSource = -1; + switch(source) { + case QS_TILE : + logSource = PRIVACY_SENSOR_TOGGLE_INTERACTION__SOURCE__QS_TILE; + break; + case DIALOG : + logSource = PRIVACY_SENSOR_TOGGLE_INTERACTION__SOURCE__DIALOG; + break; + case SETTINGS: + logSource = PRIVACY_SENSOR_TOGGLE_INTERACTION__SOURCE__SETTINGS; + break; + default: + logSource = PRIVACY_SENSOR_TOGGLE_INTERACTION__SOURCE__SOURCE_UNKNOWN; + } + + write(PRIVACY_SENSOR_TOGGLE_INTERACTION, logSensor, logAction, logSource, logMins); + + } + @Override - public void setIndividualSensorPrivacyForProfileGroup(@UserIdInt int userId, int sensor, - boolean enable) { + public void setIndividualSensorPrivacyForProfileGroup(@UserIdInt int userId, + @SensorPrivacyManager.Sources.Source int source, int sensor, boolean enable) { enforceManageSensorPrivacyPermission(); int parentId = mUserManagerInternal.getProfileParentId(userId); forAllUsers(userId2 -> { if (parentId == mUserManagerInternal.getProfileParentId(userId2)) { - setIndividualSensorPrivacy(userId2, sensor, enable); + setIndividualSensorPrivacy(userId2, source, sensor, enable); } }); } @@ -1214,7 +1280,7 @@ public final class SensorPrivacyService extends SystemService { return -1; } - setIndividualSensorPrivacy(userId, sensor, true); + setIndividualSensorPrivacy(userId, SHELL, sensor, true); } break; case "disable" : { @@ -1224,7 +1290,7 @@ public final class SensorPrivacyService extends SystemService { return -1; } - setIndividualSensorPrivacy(userId, sensor, false); + setIndividualSensorPrivacy(userId, SHELL, sensor, false); } break; case "reset": {