From 6241365ab42e04e6d37d8977fa4361bfbb38e6aa Mon Sep 17 00:00:00 2001 From: Atneya Nair Date: Mon, 6 Mar 2023 14:40:14 -0800 Subject: [PATCH] Add STModule selection TestApis Enable STInstrumentation for STManager clients. - Add method which lists all device modules - Add factory method which consumes a module properties to attach to - Add factory method which connects to default test module Fixes: 269165331 Test: atest SoundTriggerManagerTest Change-Id: I731d240bc685d0782c9d09dd05129068f301eeb0 --- core/api/test-current.txt | 8 ++ .../soundtrigger/SoundTriggerManager.java | 103 +++++++++++++++++- 2 files changed, 109 insertions(+), 2 deletions(-) diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 2d9a99cf0d8c6..4f0dea570fe8b 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -2074,6 +2074,14 @@ package android.media.soundtrigger { public final class SoundTriggerManager { method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) public static android.media.soundtrigger.SoundTriggerInstrumentation attachInstrumentation(@NonNull java.util.concurrent.Executor, @NonNull android.media.soundtrigger.SoundTriggerInstrumentation.GlobalCallback); + method @NonNull public android.media.soundtrigger.SoundTriggerManager createManagerForModule(@NonNull android.hardware.soundtrigger.SoundTrigger.ModuleProperties); + method @NonNull public android.media.soundtrigger.SoundTriggerManager createManagerForTestModule(); + method @NonNull public static java.util.List listModuleProperties(); + method @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) public int loadSoundModel(@NonNull android.hardware.soundtrigger.SoundTrigger.SoundModel); + } + + public static class SoundTriggerManager.Model { + method @NonNull public android.hardware.soundtrigger.SoundTrigger.SoundModel getSoundModel(); } } diff --git a/media/java/android/media/soundtrigger/SoundTriggerManager.java b/media/java/android/media/soundtrigger/SoundTriggerManager.java index c41bd1bc3094e..b6d70afa85b78 100644 --- a/media/java/android/media/soundtrigger/SoundTriggerManager.java +++ b/media/java/android/media/soundtrigger/SoundTriggerManager.java @@ -22,6 +22,7 @@ import android.annotation.CallbackExecutor; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; +import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; @@ -56,6 +57,7 @@ import com.android.internal.app.ISoundTriggerSession; import com.android.internal.util.Preconditions; import java.util.HashMap; +import java.util.List; import java.util.Objects; import java.util.UUID; import java.util.concurrent.Executor; @@ -74,6 +76,7 @@ public final class SoundTriggerManager { private static final String TAG = "SoundTriggerManager"; private final Context mContext; + private final ISoundTriggerService mSoundTriggerService; private final ISoundTriggerSession mSoundTriggerSession; private final IBinder mBinderToken = new Binder(); @@ -114,12 +117,96 @@ public final class SoundTriggerManager { } } } catch (RemoteException e) { - throw e.rethrowAsRuntimeException(); + throw e.rethrowFromSystemServer(); } mContext = context; + mSoundTriggerService = soundTriggerService; mReceiverInstanceMap = new HashMap(); } + /** + * Construct a {@link SoundTriggerManager} which connects to a specified module. + * + * @param moduleProperties - Properties representing the module to attach to + * @return - A new {@link SoundTriggerManager} which interfaces with the test module. + * @hide + */ + @TestApi + @SuppressLint("ManagerLookup") + public @NonNull SoundTriggerManager createManagerForModule( + @NonNull ModuleProperties moduleProperties) { + return new SoundTriggerManager(mContext, mSoundTriggerService, + Objects.requireNonNull(moduleProperties)); + } + + /** + * Construct a {@link SoundTriggerManager} which connects to a ST module + * which is available for instrumentation through {@link attachInstrumentation}. + * + * @return - A new {@link SoundTriggerManager} which interfaces with the test module. + * @hide + */ + @TestApi + @SuppressLint("ManagerLookup") + public @NonNull SoundTriggerManager createManagerForTestModule() { + return new SoundTriggerManager(mContext, mSoundTriggerService, getTestModuleProperties()); + } + + private final @NonNull SoundTrigger.ModuleProperties getTestModuleProperties() { + var moduleProps = listModuleProperties() + .stream() + .filter((SoundTrigger.ModuleProperties prop) + -> prop.getSupportedModelArch().equals(SoundTrigger.FAKE_HAL_ARCH)) + .findFirst() + .orElse(null); + if (moduleProps == null) { + throw new IllegalStateException("Fake ST HAL should always be available"); + } + return moduleProps; + } + + // Helper constructor to create a manager object attached to a specific ST module. + private SoundTriggerManager(@NonNull Context context, + @NonNull ISoundTriggerService soundTriggerService, + @NonNull ModuleProperties properties) { + try { + Identity originatorIdentity = new Identity(); + originatorIdentity.packageName = ActivityThread.currentOpPackageName(); + try (SafeCloseable ignored = ClearCallingIdentityContext.create()) { + mSoundTriggerSession = soundTriggerService.attachAsOriginator( + originatorIdentity, + Objects.requireNonNull(properties), + mBinderToken); + } + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + mContext = Objects.requireNonNull(context); + mSoundTriggerService = Objects.requireNonNull(soundTriggerService); + mReceiverInstanceMap = new HashMap(); + } + + /** + * Enumerate the available ST modules. Use {@link createManagerForModule(ModuleProperties)} to + * receive a {@link SoundTriggerManager} attached to a specified ST module. + * @return - List of available ST modules to attach to. + * @hide + */ + @TestApi + public static @NonNull List listModuleProperties() { + try { + ISoundTriggerService service = ISoundTriggerService.Stub.asInterface( + ServiceManager.getService(Context.SOUND_TRIGGER_SERVICE)); + Identity originatorIdentity = new Identity(); + originatorIdentity.packageName = ActivityThread.currentOpPackageName(); + try (SafeCloseable ignored = ClearCallingIdentityContext.create()) { + return service.listModuleProperties(originatorIdentity); + } + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** * Updates the given sound trigger model. * @deprecated replace with {@link #loadSoundModel} @@ -317,6 +404,17 @@ public final class SoundTriggerManager { SoundTrigger.GenericSoundModel getGenericSoundModel() { return mGenericSoundModel; } + + /** + * Return a {@link SoundTrigger.SoundModel} view of the model for + * test purposes. + * @hide + */ + @TestApi + public @NonNull SoundTrigger.SoundModel getSoundModel() { + return mGenericSoundModel; + } + } @@ -369,7 +467,8 @@ public final class SoundTriggerManager { */ @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) @UnsupportedAppUsage - public int loadSoundModel(SoundModel soundModel) { + @TestApi + public int loadSoundModel(@NonNull SoundModel soundModel) { if (soundModel == null || mSoundTriggerSession == null) { return STATUS_ERROR; }