diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java index 317e51c27d902..8a265788a94bb 100644 --- a/core/java/android/app/ActivityManagerInternal.java +++ b/core/java/android/app/ActivityManagerInternal.java @@ -19,6 +19,7 @@ package android.app; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; +import android.app.ActivityManager.ProcessCapability; import android.content.ComponentName; import android.content.IIntentReceiver; import android.content.IIntentSender; @@ -634,4 +635,9 @@ public abstract class ActivityManagerInternal { * Return the temp allowlist type when server push messaging is over the quota. */ public abstract @TempAllowListType int getPushMessagingOverQuotaBehavior(); + + /** + * Returns the capability of the given uid + */ + public abstract @ProcessCapability int getUidCapability(int uid); } diff --git a/services/core/java/com/android/server/SensorPrivacyService.java b/services/core/java/com/android/server/SensorPrivacyService.java index 71609d2b557dc..e753226523869 100644 --- a/services/core/java/com/android/server/SensorPrivacyService.java +++ b/services/core/java/com/android/server/SensorPrivacyService.java @@ -17,6 +17,8 @@ package com.android.server; import static android.Manifest.permission.MANAGE_SENSOR_PRIVACY; +import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_CAMERA; +import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_MICROPHONE; import static android.app.ActivityManager.RunningServiceInfo; import static android.app.ActivityManager.RunningTaskInfo; import static android.app.ActivityManager.getCurrentUser; @@ -41,6 +43,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.ActivityManager; +import android.app.ActivityManagerInternal; import android.app.ActivityOptions; import android.app.ActivityTaskManager; import android.app.AppOpsManager; @@ -83,6 +86,7 @@ import android.telephony.TelephonyCallback; import android.telephony.TelephonyManager; import android.telephony.emergency.EmergencyNumber; import android.text.Html; +import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; import android.util.AtomicFile; @@ -156,6 +160,7 @@ public final class SensorPrivacyService extends SystemService { private final SensorPrivacyServiceImpl mSensorPrivacyServiceImpl; private final UserManagerInternal mUserManagerInternal; private final ActivityManager mActivityManager; + private final ActivityManagerInternal mActivityManagerInternal; private final ActivityTaskManager mActivityTaskManager; private final AppOpsManager mAppOpsManager; private final TelephonyManager mTelephonyManager; @@ -173,6 +178,7 @@ public final class SensorPrivacyService extends SystemService { mAppOpsManager = context.getSystemService(AppOpsManager.class); mUserManagerInternal = getLocalService(UserManagerInternal.class); mActivityManager = context.getSystemService(ActivityManager.class); + mActivityManagerInternal = getLocalService(ActivityManagerInternal.class); mActivityTaskManager = context.getSystemService(ActivityTaskManager.class); mTelephonyManager = context.getSystemService(TelephonyManager.class); @@ -421,11 +427,33 @@ public final class SensorPrivacyService extends SystemService { } } - VoiceInteractionManagerInternal voiceInteractionManagerInternal = - LocalServices.getService(VoiceInteractionManagerInternal.class); + String inputMethodComponent = Settings.Secure.getString(mContext.getContentResolver(), + Settings.Secure.DEFAULT_INPUT_METHOD); + String inputMethodPackageName = null; + if (inputMethodComponent != null) { + inputMethodPackageName = ComponentName.unflattenFromString( + inputMethodComponent).getPackageName(); + } + int capability = mActivityManagerInternal.getUidCapability(uid); - if (sensor == MICROPHONE && voiceInteractionManagerInternal != null - && voiceInteractionManagerInternal.hasActiveSession(packageName)) { + if (sensor == MICROPHONE) { + VoiceInteractionManagerInternal voiceInteractionManagerInternal = + LocalServices.getService(VoiceInteractionManagerInternal.class); + if (voiceInteractionManagerInternal != null + && voiceInteractionManagerInternal.hasActiveSession(packageName)) { + enqueueSensorUseReminderDialogAsync(-1, user, packageName, sensor); + return; + } + + if (TextUtils.equals(packageName, inputMethodPackageName) + && (capability & PROCESS_CAPABILITY_FOREGROUND_MICROPHONE) != 0) { + enqueueSensorUseReminderDialogAsync(-1, user, packageName, sensor); + return; + } + } + + if (sensor == CAMERA && TextUtils.equals(packageName, inputMethodPackageName) + && (capability & PROCESS_CAPABILITY_FOREGROUND_CAMERA) != 0) { enqueueSensorUseReminderDialogAsync(-1, user, packageName, sensor); return; } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index ee5ad95913be6..ef4b16ba05e02 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -16341,6 +16341,17 @@ public class ActivityManagerService extends IActivityManager.Stub return mConstants.mPushMessagingOverQuotaBehavior; } } + + @Override + public int getUidCapability(int uid) { + synchronized (ActivityManagerService.this) { + UidRecord uidRecord = mProcessList.getUidRecordLOSP(uid); + if (uidRecord == null) { + throw new IllegalArgumentException("uid record for " + uid + " not found"); + } + return uidRecord.getCurCapability(); + } + } } long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {