diff options
author | Ahaan Ugale <augale@google.com> | 2021-08-04 16:33:36 -0700 |
---|---|---|
committer | Ahaan Ugale <augale@google.com> | 2021-08-04 21:29:21 -0700 |
commit | 3ac246c43294d7f7012bdcb0ccb7bae1aa695bd4 (patch) | |
tree | 557f23ec9dd9c6556b44c153513fb216a0125dce | |
parent | 389475e436f62dc79c0f34315e2ca851c2e17836 (diff) |
Send the HotwordDetectionService UID to AudioPolicy
This change follows the pattern of how the IME UID is set.
The UID is stored in AudioService and re-sent there if the audio server
dies.
Fix: 194368677
Test: manual - hotword works when another app is using the mic and in
Auto projection mode; also after restarting the process or killing
audio server
Test: atest HotwordDetectionServiceBasicTest
Change-Id: I325cb33d17387e62302967b261b6fe61086d8893
6 files changed, 68 insertions, 0 deletions
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp index 16ee6a745e1d..4b93363b5b90 100644 --- a/core/jni/android_media_AudioSystem.cpp +++ b/core/jni/android_media_AudioSystem.cpp @@ -2429,6 +2429,12 @@ android_media_AudioSystem_setAssistantUid(JNIEnv *env, jobject thiz, jint uid) return (jint)nativeToJavaStatus(status); } +static jint android_media_AudioSystem_setHotwordDetectionServiceUid(JNIEnv *env, jobject thiz, + jint uid) { + status_t status = AudioSystem::setHotwordDetectionServiceUid(uid); + return (jint)nativeToJavaStatus(status); +} + static jint android_media_AudioSystem_setA11yServicesUids(JNIEnv *env, jobject thiz, jintArray uids) { std::vector<uid_t> nativeUidsVector; @@ -2799,6 +2805,8 @@ static const JNINativeMethod gMethods[] = {"setSurroundFormatEnabled", "(IZ)I", (void *)android_media_AudioSystem_setSurroundFormatEnabled}, {"setAssistantUid", "(I)I", (void *)android_media_AudioSystem_setAssistantUid}, + {"setHotwordDetectionServiceUid", "(I)I", + (void *)android_media_AudioSystem_setHotwordDetectionServiceUid}, {"setA11yServicesUids", "([I)I", (void *)android_media_AudioSystem_setA11yServicesUids}, {"isHapticPlaybackSupported", "()Z", (void *)android_media_AudioSystem_isHapticPlaybackSupported}, diff --git a/media/java/android/media/AudioManagerInternal.java b/media/java/android/media/AudioManagerInternal.java index c827932194ae..cb887f2d523d 100644 --- a/media/java/android/media/AudioManagerInternal.java +++ b/media/java/android/media/AudioManagerInternal.java @@ -38,6 +38,17 @@ public abstract class AudioManagerInternal { public abstract void updateRingerModeAffectedStreamsInternal(); + /** + * Notify the UID of the currently active {@link android.service.voice.HotwordDetectionService}. + * + * <p>The caller is expected to take care of any performance implications, e.g. by using a + * background thread to call this method.</p> + * + * @param uid UID of the currently active service or {@link android.os.Process#INVALID_UID} if + * none. + */ + public abstract void setHotwordDetectionServiceUid(int uid); + public abstract void setAccessibilityServiceUids(IntArray uids); /** diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java index 8012f03d84b3..69d1889d5762 100644 --- a/media/java/android/media/AudioSystem.java +++ b/media/java/android/media/AudioSystem.java @@ -1769,6 +1769,13 @@ public class AudioSystem public static native int setAssistantUid(int uid); /** + * Communicate UID of the current {@link android.service.voice.HotwordDetectionService} to audio + * policy service. + * @hide + */ + public static native int setHotwordDetectionServiceUid(int uid); + + /** * @hide * Communicate UIDs of active accessibility services to audio policy service. */ diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index f7d091498456..34e2578f7855 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -736,6 +736,11 @@ public class AudioService extends IAudioService.Stub private VolumePolicy mVolumePolicy = VolumePolicy.DEFAULT; private long mLoweredFromNormalToVibrateTime; + // Uid of the active hotword detection service to check if caller is the one or not. + @GuardedBy("mHotwordDetectionServiceUidLock") + private int mHotwordDetectionServiceUid = android.os.Process.INVALID_UID; + private final Object mHotwordDetectionServiceUidLock = new Object(); + // Array of Uids of valid accessibility services to check if caller is one of them private final Object mAccessibilityServiceUidsLock = new Object(); @GuardedBy("mAccessibilityServiceUidsLock") @@ -1337,6 +1342,9 @@ public class AudioService extends IAudioService.Stub updateAssistantUId(true); AudioSystem.setRttEnabled(mRttEnabled); } + synchronized (mHotwordDetectionServiceUidLock) { + AudioSystem.setHotwordDetectionServiceUid(mHotwordDetectionServiceUid); + } synchronized (mAccessibilityServiceUidsLock) { AudioSystem.setA11yServicesUids(mAccessibilityServiceUids); } @@ -9108,6 +9116,16 @@ public class AudioService extends IAudioService.Stub } @Override + public void setHotwordDetectionServiceUid(int uid) { + synchronized (mHotwordDetectionServiceUidLock) { + if (mHotwordDetectionServiceUid != uid) { + mHotwordDetectionServiceUid = uid; + AudioSystem.setHotwordDetectionServiceUid(mHotwordDetectionServiceUid); + } + } + } + + @Override public void setAccessibilityServiceUids(IntArray uids) { synchronized (mAccessibilityServiceUidsLock) { if (uids.size() == 0) { diff --git a/services/core/java/com/android/server/audio/AudioSystemAdapter.java b/services/core/java/com/android/server/audio/AudioSystemAdapter.java index 973fbd2bba17..6d567807f357 100644 --- a/services/core/java/com/android/server/audio/AudioSystemAdapter.java +++ b/services/core/java/com/android/server/audio/AudioSystemAdapter.java @@ -367,6 +367,14 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback { } /** + * Same as {@link AudioSystem#setHotwordDetectionServiceUid(int)} + * Communicate UID of current HotwordDetectionService to audio policy service. + */ + public int setHotwordDetectionServiceUid(int uid) { + return AudioSystem.setHotwordDetectionServiceUid(uid); + } + + /** * Same as {@link AudioSystem#setCurrentImeUid(int)} * Communicate UID of current InputMethodService to audio policy service. */ diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java index 965f126000fd..734172fc1549 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java @@ -36,6 +36,7 @@ import android.content.PermissionChecker; import android.hardware.soundtrigger.IRecognitionStatusCallback; import android.hardware.soundtrigger.SoundTrigger; import android.media.AudioFormat; +import android.media.AudioManagerInternal; import android.media.permission.Identity; import android.media.permission.PermissionUtil; import android.os.Binder; @@ -44,6 +45,7 @@ import android.os.IBinder; import android.os.IRemoteCallback; import android.os.ParcelFileDescriptor; import android.os.PersistableBundle; +import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SharedMemory; @@ -275,6 +277,7 @@ final class HotwordDetectionConnection { LocalServices.getService(PermissionManagerServiceInternal.class) .setHotwordDetectionServiceProvider(null); mIdentity = null; + updateServiceUidForAudioPolicy(Process.INVALID_UID); } mCancellationTaskFuture.cancel(/* may interrupt */ true); if (mAudioFlinger != null) { @@ -893,6 +896,8 @@ final class HotwordDetectionConnection { connection.run(service -> service.ping(new IRemoteCallback.Stub() { @Override public void sendResult(Bundle bundle) throws RemoteException { + // TODO: Exit if the service has been unbound already (though there's a very low + // chance this happens). if (DEBUG) { Slog.d(TAG, "updating hotword UID " + Binder.getCallingUid()); } @@ -902,10 +907,21 @@ final class HotwordDetectionConnection { LocalServices.getService(PermissionManagerServiceInternal.class) .setHotwordDetectionServiceProvider(() -> uid); mIdentity = new HotwordDetectionServiceIdentity(uid, mVoiceInteractionServiceUid); + updateServiceUidForAudioPolicy(uid); } })); } + private void updateServiceUidForAudioPolicy(int uid) { + mScheduledExecutorService.execute(() -> { + final AudioManagerInternal audioManager = + LocalServices.getService(AudioManagerInternal.class); + if (audioManager != null) { + audioManager.setHotwordDetectionServiceUid(uid); + } + }); + } + private static void bestEffortClose(Closeable closeable) { try { closeable.close(); |