Skip to content

Commit 3ac246c

Browse files
committed
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
1 parent 389475e commit 3ac246c

File tree

6 files changed

+68
-0
lines changed

6 files changed

+68
-0
lines changed

core/jni/android_media_AudioSystem.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -2429,6 +2429,12 @@ android_media_AudioSystem_setAssistantUid(JNIEnv *env, jobject thiz, jint uid)
24292429
return (jint)nativeToJavaStatus(status);
24302430
}
24312431

2432+
static jint android_media_AudioSystem_setHotwordDetectionServiceUid(JNIEnv *env, jobject thiz,
2433+
jint uid) {
2434+
status_t status = AudioSystem::setHotwordDetectionServiceUid(uid);
2435+
return (jint)nativeToJavaStatus(status);
2436+
}
2437+
24322438
static jint
24332439
android_media_AudioSystem_setA11yServicesUids(JNIEnv *env, jobject thiz, jintArray uids) {
24342440
std::vector<uid_t> nativeUidsVector;
@@ -2799,6 +2805,8 @@ static const JNINativeMethod gMethods[] =
27992805
{"setSurroundFormatEnabled", "(IZ)I",
28002806
(void *)android_media_AudioSystem_setSurroundFormatEnabled},
28012807
{"setAssistantUid", "(I)I", (void *)android_media_AudioSystem_setAssistantUid},
2808+
{"setHotwordDetectionServiceUid", "(I)I",
2809+
(void *)android_media_AudioSystem_setHotwordDetectionServiceUid},
28022810
{"setA11yServicesUids", "([I)I", (void *)android_media_AudioSystem_setA11yServicesUids},
28032811
{"isHapticPlaybackSupported", "()Z",
28042812
(void *)android_media_AudioSystem_isHapticPlaybackSupported},

media/java/android/media/AudioManagerInternal.java

+11
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,17 @@ public abstract class AudioManagerInternal {
3838

3939
public abstract void updateRingerModeAffectedStreamsInternal();
4040

41+
/**
42+
* Notify the UID of the currently active {@link android.service.voice.HotwordDetectionService}.
43+
*
44+
* <p>The caller is expected to take care of any performance implications, e.g. by using a
45+
* background thread to call this method.</p>
46+
*
47+
* @param uid UID of the currently active service or {@link android.os.Process#INVALID_UID} if
48+
* none.
49+
*/
50+
public abstract void setHotwordDetectionServiceUid(int uid);
51+
4152
public abstract void setAccessibilityServiceUids(IntArray uids);
4253

4354
/**

media/java/android/media/AudioSystem.java

+7
Original file line numberDiff line numberDiff line change
@@ -1768,6 +1768,13 @@ public static native int getHwOffloadEncodingFormatsSupportedForA2DP(
17681768
*/
17691769
public static native int setAssistantUid(int uid);
17701770

1771+
/**
1772+
* Communicate UID of the current {@link android.service.voice.HotwordDetectionService} to audio
1773+
* policy service.
1774+
* @hide
1775+
*/
1776+
public static native int setHotwordDetectionServiceUid(int uid);
1777+
17711778
/**
17721779
* @hide
17731780
* Communicate UIDs of active accessibility services to audio policy service.

services/core/java/com/android/server/audio/AudioService.java

+18
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,11 @@ protected boolean removeEldestEntry(Map.Entry eldest) {
736736
private VolumePolicy mVolumePolicy = VolumePolicy.DEFAULT;
737737
private long mLoweredFromNormalToVibrateTime;
738738

739+
// Uid of the active hotword detection service to check if caller is the one or not.
740+
@GuardedBy("mHotwordDetectionServiceUidLock")
741+
private int mHotwordDetectionServiceUid = android.os.Process.INVALID_UID;
742+
private final Object mHotwordDetectionServiceUidLock = new Object();
743+
739744
// Array of Uids of valid accessibility services to check if caller is one of them
740745
private final Object mAccessibilityServiceUidsLock = new Object();
741746
@GuardedBy("mAccessibilityServiceUidsLock")
@@ -1337,6 +1342,9 @@ public void onAudioServerDied() {
13371342
updateAssistantUId(true);
13381343
AudioSystem.setRttEnabled(mRttEnabled);
13391344
}
1345+
synchronized (mHotwordDetectionServiceUidLock) {
1346+
AudioSystem.setHotwordDetectionServiceUid(mHotwordDetectionServiceUid);
1347+
}
13401348
synchronized (mAccessibilityServiceUidsLock) {
13411349
AudioSystem.setA11yServicesUids(mAccessibilityServiceUids);
13421350
}
@@ -9107,6 +9115,16 @@ public void updateRingerModeAffectedStreamsInternal() {
91079115
}
91089116
}
91099117

9118+
@Override
9119+
public void setHotwordDetectionServiceUid(int uid) {
9120+
synchronized (mHotwordDetectionServiceUidLock) {
9121+
if (mHotwordDetectionServiceUid != uid) {
9122+
mHotwordDetectionServiceUid = uid;
9123+
AudioSystem.setHotwordDetectionServiceUid(mHotwordDetectionServiceUid);
9124+
}
9125+
}
9126+
}
9127+
91109128
@Override
91119129
public void setAccessibilityServiceUids(IntArray uids) {
91129130
synchronized (mAccessibilityServiceUidsLock) {

services/core/java/com/android/server/audio/AudioSystemAdapter.java

+8
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,14 @@ public int muteMicrophone(boolean on) {
366366
return AudioSystem.muteMicrophone(on);
367367
}
368368

369+
/**
370+
* Same as {@link AudioSystem#setHotwordDetectionServiceUid(int)}
371+
* Communicate UID of current HotwordDetectionService to audio policy service.
372+
*/
373+
public int setHotwordDetectionServiceUid(int uid) {
374+
return AudioSystem.setHotwordDetectionServiceUid(uid);
375+
}
376+
369377
/**
370378
* Same as {@link AudioSystem#setCurrentImeUid(int)}
371379
* Communicate UID of current InputMethodService to audio policy service.

services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java

+16
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import android.hardware.soundtrigger.IRecognitionStatusCallback;
3737
import android.hardware.soundtrigger.SoundTrigger;
3838
import android.media.AudioFormat;
39+
import android.media.AudioManagerInternal;
3940
import android.media.permission.Identity;
4041
import android.media.permission.PermissionUtil;
4142
import android.os.Binder;
@@ -44,6 +45,7 @@
4445
import android.os.IRemoteCallback;
4546
import android.os.ParcelFileDescriptor;
4647
import android.os.PersistableBundle;
48+
import android.os.Process;
4749
import android.os.RemoteException;
4850
import android.os.ServiceManager;
4951
import android.os.SharedMemory;
@@ -275,6 +277,7 @@ void cancelLocked() {
275277
LocalServices.getService(PermissionManagerServiceInternal.class)
276278
.setHotwordDetectionServiceProvider(null);
277279
mIdentity = null;
280+
updateServiceUidForAudioPolicy(Process.INVALID_UID);
278281
}
279282
mCancellationTaskFuture.cancel(/* may interrupt */ true);
280283
if (mAudioFlinger != null) {
@@ -893,6 +896,8 @@ private void updateServiceIdentity(ServiceConnection connection) {
893896
connection.run(service -> service.ping(new IRemoteCallback.Stub() {
894897
@Override
895898
public void sendResult(Bundle bundle) throws RemoteException {
899+
// TODO: Exit if the service has been unbound already (though there's a very low
900+
// chance this happens).
896901
if (DEBUG) {
897902
Slog.d(TAG, "updating hotword UID " + Binder.getCallingUid());
898903
}
@@ -902,10 +907,21 @@ public void sendResult(Bundle bundle) throws RemoteException {
902907
LocalServices.getService(PermissionManagerServiceInternal.class)
903908
.setHotwordDetectionServiceProvider(() -> uid);
904909
mIdentity = new HotwordDetectionServiceIdentity(uid, mVoiceInteractionServiceUid);
910+
updateServiceUidForAudioPolicy(uid);
905911
}
906912
}));
907913
}
908914

915+
private void updateServiceUidForAudioPolicy(int uid) {
916+
mScheduledExecutorService.execute(() -> {
917+
final AudioManagerInternal audioManager =
918+
LocalServices.getService(AudioManagerInternal.class);
919+
if (audioManager != null) {
920+
audioManager.setHotwordDetectionServiceUid(uid);
921+
}
922+
});
923+
}
924+
909925
private static void bestEffortClose(Closeable closeable) {
910926
try {
911927
closeable.close();

0 commit comments

Comments
 (0)