diff --git a/core/java/android/hardware/ISensorPrivacyManager.aidl b/core/java/android/hardware/ISensorPrivacyManager.aidl index d69a9e14b4bf2..55711654231e9 100644 --- a/core/java/android/hardware/ISensorPrivacyManager.aidl +++ b/core/java/android/hardware/ISensorPrivacyManager.aidl @@ -52,4 +52,6 @@ interface ISensorPrivacyManager { void addUserGlobalIndividualSensorPrivacyListener(int sensor, in ISensorPrivacyListener listener); void removeUserGlobalIndividualSensorPrivacyListener(int sensor, in ISensorPrivacyListener listener); + + void showSensorUseDialog(int sensor); } \ No newline at end of file diff --git a/core/java/android/hardware/SensorPrivacyManager.java b/core/java/android/hardware/SensorPrivacyManager.java index fa7ce11c5414b..3c524b2052f74 100644 --- a/core/java/android/hardware/SensorPrivacyManager.java +++ b/core/java/android/hardware/SensorPrivacyManager.java @@ -33,6 +33,7 @@ import android.os.UserHandle; import android.service.SensorPrivacyIndividualEnabledSensorProto; import android.service.SensorPrivacyToggleSourceProto; import android.util.ArrayMap; +import android.util.Log; import android.util.Pair; import android.util.SparseArray; @@ -48,6 +49,8 @@ import java.util.concurrent.Executor; @SystemService(Context.SENSOR_PRIVACY_SERVICE) public final class SensorPrivacyManager { + private static final String LOG_TAG = SensorPrivacyManager.class.getSimpleName(); + /** * Unique Id of this manager to identify to the service * @hide @@ -504,6 +507,25 @@ public final class SensorPrivacyManager { } } + /** + * If sensor privacy for the provided sensor is enabled then this call will show the user the + * dialog which is shown when an application attempts to use that sensor. If privacy isn't + * enabled then this does nothing. + * + * This call can only be made by the system uid. + * + * @throws SecurityException when called by someone other than system uid. + * + * @hide + */ + public void showSensorUseDialog(int sensor) { + try { + mService.showSensorUseDialog(sensor); + } catch (RemoteException e) { + Log.e(LOG_TAG, "Received exception while trying to show sensor use dialog", e); + } + } + /** * A class implementing this interface can register with the {@link * android.hardware.SensorPrivacyManager} to receive notification when the all-sensor privacy diff --git a/services/core/java/com/android/server/SensorPrivacyService.java b/services/core/java/com/android/server/SensorPrivacyService.java index 40e63dac72ea6..422e8ae148621 100644 --- a/services/core/java/com/android/server/SensorPrivacyService.java +++ b/services/core/java/com/android/server/SensorPrivacyService.java @@ -413,6 +413,12 @@ public final class SensorPrivacyService extends SystemService { return; } + if (uid == Process.SYSTEM_UID) { + // If the system uid is being blamed for sensor access, the ui must be shown + // explicitly using SensorPrivacyManager#showSensorUseDialog + return; + } + synchronized (mLock) { if (mSuppressReminders.containsKey(new Pair<>(sensor, user))) { Log.d(TAG, @@ -421,11 +427,6 @@ public final class SensorPrivacyService extends SystemService { } } - if (uid == Process.SYSTEM_UID) { - enqueueSensorUseReminderDialogAsync(-1, user, packageName, sensor); - return; - } - // TODO: Handle reminders with multiple sensors // - If we have a likely activity that triggered the sensor use overlay a dialog over @@ -1241,6 +1242,18 @@ public final class SensorPrivacyService extends SystemService { } } + @Override + public void showSensorUseDialog(int sensor) { + if (Binder.getCallingUid() != Process.SYSTEM_UID) { + throw new SecurityException("Can only be called by the system uid"); + } + if (!isIndividualSensorPrivacyEnabled(mCurrentUser, sensor)) { + return; + } + enqueueSensorUseReminderDialogAsync( + -1, UserHandle.of(mCurrentUser), "android", sensor); + } + private void userSwitching(int from, int to) { boolean micState; boolean camState;