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

Commit 31b112fe authored by Atneya Nair's avatar Atneya Nair
Browse files

ST HAL Instrumentation client side

- Add model params to TestApi
- Add RecognitionConfig to TestApi
- Add client-side STInstrumentation attach method to STManager
- STInstrumentation implements ISoundTriggerInjection, dispatches appropriate
callbacks and handles session staleness.

Test: atest CtsVoiceInteractionTestCases
Fixes: 271198164
Change-Id: Iaaaf3c0199980bb5f03b70f2b38f4f44d795666c
parent 9407076f
Loading
Loading
Loading
Loading
+69 −0
Original line number Original line Diff line number Diff line
@@ -1651,6 +1651,11 @@ package android.hardware.soundtrigger {
    field @NonNull public static final android.os.Parcelable.Creator<android.hardware.soundtrigger.KeyphraseMetadata> CREATOR;
    field @NonNull public static final android.os.Parcelable.Creator<android.hardware.soundtrigger.KeyphraseMetadata> CREATOR;
  }
  }


  public class SoundTrigger {
    field public static final int MODEL_PARAM_INVALID = -1; // 0xffffffff
    field public static final int MODEL_PARAM_THRESHOLD_FACTOR = 0; // 0x0
  }

  public static final class SoundTrigger.KeyphraseRecognitionExtra implements android.os.Parcelable {
  public static final class SoundTrigger.KeyphraseRecognitionExtra implements android.os.Parcelable {
    ctor public SoundTrigger.KeyphraseRecognitionExtra(int, int, int);
    ctor public SoundTrigger.KeyphraseRecognitionExtra(int, int, int);
  }
  }
@@ -1663,6 +1668,19 @@ package android.hardware.soundtrigger {
    ctor public SoundTrigger.ModuleProperties(int, @NonNull String, @NonNull String, @NonNull String, int, @NonNull String, int, int, int, int, boolean, int, boolean, int, boolean, int);
    ctor public SoundTrigger.ModuleProperties(int, @NonNull String, @NonNull String, @NonNull String, int, @NonNull String, int, int, int, int, boolean, int, boolean, int, boolean, int);
  }
  }


  public static final class SoundTrigger.RecognitionConfig implements android.os.Parcelable {
    ctor public SoundTrigger.RecognitionConfig(boolean, boolean, @Nullable android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionExtra[], @Nullable byte[], int);
    ctor public SoundTrigger.RecognitionConfig(boolean, boolean, @Nullable android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionExtra[], @Nullable byte[]);
    method public int describeContents();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.hardware.soundtrigger.SoundTrigger.RecognitionConfig> CREATOR;
    field public final boolean allowMultipleTriggers;
    field public final int audioCapabilities;
    field public final boolean captureRequested;
    field @NonNull public final byte[] data;
    field @NonNull public final android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionExtra[] keyphrases;
  }

  public static class SoundTrigger.RecognitionEvent {
  public static class SoundTrigger.RecognitionEvent {
    ctor public SoundTrigger.RecognitionEvent(int, int, boolean, int, int, int, boolean, @NonNull android.media.AudioFormat, @Nullable byte[], long);
    ctor public SoundTrigger.RecognitionEvent(int, int, boolean, int, int, int, boolean, @NonNull android.media.AudioFormat, @Nullable byte[], long);
  }
  }
@@ -2000,6 +2018,57 @@ package android.media.metrics {


}
}


package android.media.soundtrigger {

  public final class SoundTriggerInstrumentation {
    method public void setResourceContention(boolean);
    method public void triggerOnResourcesAvailable();
    method public void triggerRestart();
  }

  public static interface SoundTriggerInstrumentation.GlobalCallback {
    method public default void onClientAttached();
    method public default void onClientDetached();
    method public default void onFrameworkDetached();
    method public void onModelLoaded(@NonNull android.media.soundtrigger.SoundTriggerInstrumentation.ModelSession);
    method public default void onPreempted();
    method public default void onRestarted();
  }

  public static interface SoundTriggerInstrumentation.ModelCallback {
    method public default void onModelUnloaded();
    method public default void onParamSet(int, int);
    method public void onRecognitionStarted(@NonNull android.media.soundtrigger.SoundTriggerInstrumentation.RecognitionSession);
  }

  public class SoundTriggerInstrumentation.ModelSession {
    method public void clearModelCallback();
    method @NonNull public java.util.List<android.hardware.soundtrigger.SoundTrigger.Keyphrase> getPhrases();
    method @NonNull public android.media.soundtrigger.SoundTriggerManager.Model getSoundModel();
    method public boolean isKeyphrase();
    method public void setModelCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.soundtrigger.SoundTriggerInstrumentation.ModelCallback);
    method public void triggerUnloadModel();
  }

  public static interface SoundTriggerInstrumentation.RecognitionCallback {
    method public void onRecognitionStopped();
  }

  public class SoundTriggerInstrumentation.RecognitionSession {
    method public void clearRecognitionCallback();
    method public int getAudioSession();
    method @NonNull public android.hardware.soundtrigger.SoundTrigger.RecognitionConfig getRecognitionConfig();
    method public void setRecognitionCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.soundtrigger.SoundTriggerInstrumentation.RecognitionCallback);
    method public void triggerAbortRecognition();
    method public void triggerRecognitionEvent(@NonNull byte[], @Nullable java.util.List<android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionExtra>);
  }

  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);
  }

}

package android.media.tv {
package android.media.tv {


  public final class TvInputManager {
  public final class TvInputManager {
+31 −5
Original line number Original line Diff line number Diff line
@@ -1051,6 +1051,29 @@ public class SoundTrigger {
            return "ModelParamRange [start=" + mStart + ", end=" + mEnd + "]";
            return "ModelParamRange [start=" + mStart + ", end=" + mEnd + "]";
        }
        }
    }
    }
    /**
     * SoundTrigger model parameter types.
     * @hide
     */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(flag = true, prefix = { "MODEL_PARAM" }, value = {
            MODEL_PARAM_INVALID,
            MODEL_PARAM_THRESHOLD_FACTOR
    })
    public @interface ModelParamTypes {}

    /**
     * See {@link ModelParams.INVALID}
     * @hide
     */
    @TestApi
    public static final int MODEL_PARAM_INVALID = ModelParams.INVALID;
    /**
     * See {@link ModelParams.THRESHOLD_FACTOR}
     * @hide
     */
    @TestApi
    public static final int MODEL_PARAM_THRESHOLD_FACTOR = ModelParams.THRESHOLD_FACTOR;


    /**
    /**
     * Modes for key phrase recognition
     * Modes for key phrase recognition
@@ -1450,7 +1473,8 @@ public class SoundTrigger {
     *
     *
     *  @hide
     *  @hide
     */
     */
    public static class RecognitionConfig implements Parcelable {
    @TestApi
    public static final class RecognitionConfig implements Parcelable {
        /** True if the DSP should capture the trigger sound and make it available for further
        /** True if the DSP should capture the trigger sound and make it available for further
         * capture. */
         * capture. */
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
@@ -1464,6 +1488,7 @@ public class SoundTrigger {
         * options for each keyphrase. */
         * options for each keyphrase. */
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
        @NonNull
        @NonNull
        @SuppressLint("ArrayReturn")
        public final KeyphraseRecognitionExtra keyphrases[];
        public final KeyphraseRecognitionExtra keyphrases[];
        /** Opaque data for use by system applications who know about voice engine internals,
        /** Opaque data for use by system applications who know about voice engine internals,
         * typically during enrollment. */
         * typically during enrollment. */
@@ -1479,8 +1504,8 @@ public class SoundTrigger {
        public final int audioCapabilities;
        public final int audioCapabilities;


        public RecognitionConfig(boolean captureRequested, boolean allowMultipleTriggers,
        public RecognitionConfig(boolean captureRequested, boolean allowMultipleTriggers,
                @Nullable KeyphraseRecognitionExtra[] keyphrases, @Nullable byte[] data,
                @SuppressLint("ArrayReturn") @Nullable KeyphraseRecognitionExtra[] keyphrases,
                int audioCapabilities) {
                @Nullable byte[] data, int audioCapabilities) {
            this.captureRequested = captureRequested;
            this.captureRequested = captureRequested;
            this.allowMultipleTriggers = allowMultipleTriggers;
            this.allowMultipleTriggers = allowMultipleTriggers;
            this.keyphrases = keyphrases != null ? keyphrases : new KeyphraseRecognitionExtra[0];
            this.keyphrases = keyphrases != null ? keyphrases : new KeyphraseRecognitionExtra[0];
@@ -1490,7 +1515,8 @@ public class SoundTrigger {


        @UnsupportedAppUsage
        @UnsupportedAppUsage
        public RecognitionConfig(boolean captureRequested, boolean allowMultipleTriggers,
        public RecognitionConfig(boolean captureRequested, boolean allowMultipleTriggers,
                @Nullable KeyphraseRecognitionExtra[] keyphrases, @Nullable byte[] data) {
                @SuppressLint("ArrayReturn") @Nullable KeyphraseRecognitionExtra[] keyphrases,
                @Nullable byte[] data) {
            this(captureRequested, allowMultipleTriggers, keyphrases, data, 0);
            this(captureRequested, allowMultipleTriggers, keyphrases, data, 0);
        }
        }


@@ -1517,7 +1543,7 @@ public class SoundTrigger {
        }
        }


        @Override
        @Override
        public void writeToParcel(Parcel dest, int flags) {
        public void writeToParcel(@NonNull Parcel dest, int flags) {
            dest.writeByte((byte) (captureRequested ? 1 : 0));
            dest.writeByte((byte) (captureRequested ? 1 : 0));
            dest.writeByte((byte) (allowMultipleTriggers ? 1 : 0));
            dest.writeByte((byte) (allowMultipleTriggers ? 1 : 0));
            dest.writeTypedArray(keyphrases, flags);
            dest.writeTypedArray(keyphrases, flags);
+6 −1
Original line number Original line Diff line number Diff line
@@ -16,8 +16,9 @@


package com.android.internal.app;
package com.android.internal.app;


import android.media.permission.Identity;
import android.hardware.soundtrigger.SoundTrigger;
import android.hardware.soundtrigger.SoundTrigger;
import android.media.permission.Identity;
import android.media.soundtrigger_middleware.ISoundTriggerInjection;
import com.android.internal.app.ISoundTriggerSession;
import com.android.internal.app.ISoundTriggerSession;


/**
/**
@@ -74,4 +75,8 @@ interface ISoundTriggerService {
     */
     */
    List<SoundTrigger.ModuleProperties> listModuleProperties(in Identity originatorIdentity);
    List<SoundTrigger.ModuleProperties> listModuleProperties(in Identity originatorIdentity);


    /**
     * Attach an HAL injection interface.
     */
     void attachInjection(ISoundTriggerInjection injection);
}
}
+630 −0

File added.

Preview size limit exceeded, changes collapsed.

+24 −1
Original line number Original line Diff line number Diff line
@@ -18,11 +18,13 @@ package android.media.soundtrigger;


import static android.hardware.soundtrigger.SoundTrigger.STATUS_ERROR;
import static android.hardware.soundtrigger.SoundTrigger.STATUS_ERROR;


import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.SystemService;
import android.annotation.TestApi;
import android.app.ActivityThread;
import android.app.ActivityThread;
import android.compat.annotation.UnsupportedAppUsage;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.ComponentName;
@@ -45,6 +47,7 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.IBinder;
import android.os.ParcelUuid;
import android.os.ParcelUuid;
import android.os.RemoteException;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.provider.Settings;
import android.provider.Settings;
import android.util.Slog;
import android.util.Slog;


@@ -53,9 +56,9 @@ import com.android.internal.app.ISoundTriggerSession;
import com.android.internal.util.Preconditions;
import com.android.internal.util.Preconditions;


import java.util.HashMap;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.Objects;
import java.util.UUID;
import java.util.UUID;
import java.util.concurrent.Executor;


/**
/**
 * This class provides management of non-voice (general sound trigger) based sound recognition
 * This class provides management of non-voice (general sound trigger) based sound recognition
@@ -609,4 +612,24 @@ public final class SoundTriggerManager {
            throw e.rethrowFromSystemServer();
            throw e.rethrowFromSystemServer();
        }
        }
    }
    }

    /**
     * Create a {@link SoundTriggerInstrumentation} for test purposes, which instruments a fake
     * STHAL. Clients must attach to the appropriate underlying ST module.
     * @param executor - Executor to dispatch global callbacks on
     * @param callback - Callback for unsessioned events received by the fake STHAL
     * @return - A {@link SoundTriggerInstrumentation} for observation/injection.
     * @hide
     */
    @TestApi
    @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER)
    @NonNull
    public static SoundTriggerInstrumentation attachInstrumentation(
            @CallbackExecutor @NonNull Executor executor,
            @NonNull SoundTriggerInstrumentation.GlobalCallback callback) {
        ISoundTriggerService service = ISoundTriggerService.Stub.asInterface(
                    ServiceManager.getService(Context.SOUND_TRIGGER_SERVICE));
        return new SoundTriggerInstrumentation(service, executor, callback);
    }

}
}
Loading