From 03b6c092591aec2a0009ff583bf292e1efe38bca Mon Sep 17 00:00:00 2001 From: Evan Severson Date: Fri, 25 Jun 2021 09:31:11 -0700 Subject: [PATCH] Show mic/cam enable dialog for IME If the IME is bound with capabilities it is considered to be in use by the user so when they attempt to open the mic or camera we show the dialog to renable. Test: Disable microphone and use gboard Bug: 187154145 Change-Id: Icf8d91f2a2b97068852c1b98d36916c07c42d3fa --- .../android/app/ActivityManagerInternal.java | 6 ++++ .../android/server/SensorPrivacyService.java | 36 ++++++++++++++++--- .../server/am/ActivityManagerService.java | 11 ++++++ 3 files changed, 49 insertions(+), 4 deletions(-) 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 2de091bb34bff..2ebf1b5973cbe 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -16323,6 +16323,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) {