Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6241365a authored by Atneya Nair's avatar Atneya Nair
Browse files

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
parent 628689cd
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -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<android.hardware.soundtrigger.SoundTrigger.ModuleProperties> 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();
  }

}
+101 −2
Original line number Diff line number Diff line
@@ -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<UUID, SoundTriggerDetector>();
    }

    /**
     * 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<UUID, SoundTriggerDetector>();
    }

    /**
     * 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<ModuleProperties> 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;
        }