Model ISoundTriggerHal after the AIDL HAL

This changes makes ISoundTriggerHal look similar to the AIDL version
of ISoundTriggerHw (see JavaDoc of the interface for a discussion of
the differences).

This change makes adding support for the AIDL HAL almost trivial and
would allow eventually cleanly dropping support for HIDL by confining
dependencies on it to below the ISoundTriggerHal interface.

AIDL/HIDL conversion now all happen at the Hw2Compat level.

Test: atest atest FrameworksServicesTests:SoundHw2CompatTest FrameworksServicesTests:SoundTriggerMiddlewareImplTest
Test: Manual verification of basic soundtrigger use-cases.
Bug: 178722883
Change-Id: I7cb406b33eac695c1dae0094a3b948fb73cf75f1
diff --git a/Android.bp b/Android.bp
index 4f0559b..97988cc 100644
--- a/Android.bp
+++ b/Android.bp
@@ -679,6 +679,8 @@
     ],
     sdk_version: "core_platform",
     static_libs: [
+        // TODO(b/184162091)
+        "android.hardware.soundtrigger3-V1-java",
         "bouncycastle-repackaged-unbundled",
         "framework-internal-utils",
         // If MimeMap ever becomes its own APEX, then this dependency would need to be removed
diff --git a/services/core/java/com/android/server/soundtrigger_middleware/ConversionUtil.java b/services/core/java/com/android/server/soundtrigger_middleware/ConversionUtil.java
index 75a7749..e006b65 100644
--- a/services/core/java/com/android/server/soundtrigger_middleware/ConversionUtil.java
+++ b/services/core/java/com/android/server/soundtrigger_middleware/ConversionUtil.java
@@ -215,9 +215,11 @@
     }
 
     static @NonNull android.hardware.soundtrigger.V2_3.RecognitionConfig aidl2hidlRecognitionConfig(
-            @NonNull RecognitionConfig aidlConfig) {
+            @NonNull RecognitionConfig aidlConfig, int deviceHandle, int ioHandle) {
         android.hardware.soundtrigger.V2_3.RecognitionConfig hidlConfig =
                 new android.hardware.soundtrigger.V2_3.RecognitionConfig();
+        hidlConfig.base.header.captureDevice = deviceHandle;
+        hidlConfig.base.header.captureHandle = ioHandle;
         hidlConfig.base.header.captureRequested = aidlConfig.captureRequested;
         for (PhraseRecognitionExtra aidlPhraseExtra : aidlConfig.phraseRecognitionExtras) {
             hidlConfig.base.header.phrases.add(aidl2hidlPhraseRecognitionExtra(aidlPhraseExtra));
diff --git a/services/core/java/com/android/server/soundtrigger_middleware/ISoundTriggerHal.java b/services/core/java/com/android/server/soundtrigger_middleware/ISoundTriggerHal.java
index 7f4eb81..aa85dd0 100644
--- a/services/core/java/com/android/server/soundtrigger_middleware/ISoundTriggerHal.java
+++ b/services/core/java/com/android/server/soundtrigger_middleware/ISoundTriggerHal.java
@@ -16,47 +16,131 @@
 
 package com.android.server.soundtrigger_middleware;
 
-import android.hardware.soundtrigger.V2_3.ModelParameterRange;
-import android.hardware.soundtrigger.V2_3.Properties;
-import android.hardware.soundtrigger.V2_3.RecognitionConfig;
-import android.hardware.soundtrigger.V2_4.ISoundTriggerHw;
-import android.hardware.soundtrigger.V2_4.ISoundTriggerHwCallback;
-import android.hardware.soundtrigger.V2_4.ISoundTriggerHwGlobalCallback;
-import android.hidl.base.V1_0.IBase;
-import android.os.IHwBinder;
+import android.hardware.soundtrigger3.ISoundTriggerHw;
+import android.hardware.soundtrigger3.ISoundTriggerHwCallback;
+import android.hardware.soundtrigger3.ISoundTriggerHwGlobalCallback;
+import android.media.soundtrigger.ModelParameterRange;
+import android.media.soundtrigger.PhraseRecognitionEvent;
+import android.media.soundtrigger.PhraseSoundModel;
+import android.media.soundtrigger.Properties;
+import android.media.soundtrigger.RecognitionConfig;
+import android.media.soundtrigger.RecognitionEvent;
+import android.media.soundtrigger.SoundModel;
+import android.os.IBinder;
 
 /**
- * This interface mimics ISoundTriggerHw and ISoundTriggerHwCallback, with a few key differences:
+ * This interface mimics the soundtrigger HAL interface, with a few key differences:
  * <ul>
- * <li>Methods in the original interface generally have a status return value and potentially a
- * second return value which is the actual return value. This is reflected via a synchronous
- * callback, which is not very pleasant to work with. This interface replaces that pattern with
- * the convention that a HalException is thrown for non-OK status, and then we can use the
- * return value for the actual return value.
- * <li>This interface will always include all the methods from the latest 2.x version (and thus
- * from every 2.x version) interface, with the convention that unsupported methods throw a
- * {@link RecoverableException} with a
- * {@link android.media.soundtrigger.Status#OPERATION_NOT_SUPPORTED}
- * code.
- * <li>Cases where the original interface had multiple versions of a method representing the exact
- * thing, or there exists a trivial conversion between the new and old version, this interface
- * represents only the latest version, without any _version suffixes.
- * <li>Removes some of the obscure IBinder methods.
+ * <li>Generally, methods should not throw, except for the following cases:
+ *   <ul>
+ *   <li>Any unexpected HAL behavior is considered an internal HAL malfunction and should be thrown
+ *   as a {@link HalException}, from any method.
+ *   <li>A {@link RuntimeException} with a {@link android.os.DeadObjectException} cause represents
+ *   a dead HAL process and may be thrown by any method.
+ *   <li>Implementations of earlier versions of the interface may throw a
+ *   {@link RecoverableException} with a
+ *   {@link android.media.soundtrigger.Status#OPERATION_NOT_SUPPORTED} for methods that
+ *   have been introduced in later versions of the interface.
+ *   <li>Certain methods are allowed to throw a {@link RecoverableException} with a
+ *   {@link android.media.soundtrigger.Status#RESOURCE_CONTENTION} to indicate transient
+ *   failures.
+ *   </ul>
+ * <li>Some binder-specific details are hidden.
  * <li>No RemoteExceptions are specified. Some implementations of this interface may rethrow
  * RemoteExceptions as RuntimeExceptions, some can guarantee handling them somehow and never throw
  * them.
- * <li>soundModelCallback has been removed, since nobody cares about it. Implementations are free
- * to silently discard it.
  * </ul>
  * For cases where the client wants to explicitly handle specific versions of the underlying driver
  * interface, they may call {@link #interfaceDescriptor()}.
  * <p>
- * <b>Note to maintainers</b>: This class must always be kept in sync with the latest 2.x version,
+ * <b>Note to maintainers</b>: This class must always be kept in sync with the latest version,
  * so that clients have access to the entire functionality without having to burden themselves with
  * compatibility, as much as possible.
  */
 interface ISoundTriggerHal {
     /**
+     * @see ISoundTriggerHw#getProperties()
+     */
+    Properties getProperties();
+
+    /**
+     * @see ISoundTriggerHw#registerGlobalCallback(ISoundTriggerHwGlobalCallback)
+     */
+    void registerCallback(GlobalCallback callback);
+
+    /**
+     * @see ISoundTriggerHw#loadSoundModel(android.media.soundtrigger.SoundModel,
+     * ISoundTriggerHwCallback)
+     */
+    int loadSoundModel(SoundModel soundModel, ModelCallback callback);
+
+    /**
+     * @see ISoundTriggerHw#loadPhraseSoundModel(android.media.soundtrigger.PhraseSoundModel,
+     * ISoundTriggerHwCallback)
+     */
+    int loadPhraseSoundModel(PhraseSoundModel soundModel, ModelCallback callback);
+
+    /**
+     * @see ISoundTriggerHw#unloadSoundModel(int)
+     */
+    void unloadSoundModel(int modelHandle);
+
+    /**
+     * @see ISoundTriggerHw#startRecognition(int, int, int, RecognitionConfig)
+     */
+    void startRecognition(int modelHandle, int deviceHandle, int ioHandle,
+            RecognitionConfig config);
+
+    /**
+     * @see ISoundTriggerHw#stopRecognition(int)
+     */
+    void stopRecognition(int modelHandle);
+
+    /**
+     * @see ISoundTriggerHw#forceRecognitionEvent(int)
+     */
+    void forceRecognitionEvent(int modelHandle);
+
+    /**
+     * @return null if not supported.
+     * @see ISoundTriggerHw#queryParameter(int, int)
+     */
+    ModelParameterRange queryParameter(int modelHandle, int param);
+
+    /**
+     * @see ISoundTriggerHw#getParameter(int, int)
+     */
+    int getModelParameter(int modelHandle, int param);
+
+    /**
+     * @see ISoundTriggerHw#setParameter(int, int, int)
+     */
+    void setModelParameter(int modelHandle, int param, int value);
+
+    /**
+     * @see IBinder#getInterfaceDescriptor()
+     */
+    String interfaceDescriptor();
+
+    /**
+     * @see IBinder#linkToDeath(IBinder.DeathRecipient, int)
+     */
+    void linkToDeath(IBinder.DeathRecipient recipient);
+
+    /**
+     * @see IBinder#unlinkToDeath(IBinder.DeathRecipient, int)
+     */
+    void unlinkToDeath(IBinder.DeathRecipient recipient);
+
+    /*
+     * This is only useful for testing decorators and doesn't actually do anything with the real
+     * HAL. This method would block until all callbacks that were previously generated have been
+     * invoked. For most decorators, this merely flushes the delegate, but for delegates that may
+     * have additional buffers for callbacks this should flush them.
+     */
+    void flushCallbacks();
+
+    /**
      * Kill and restart the HAL instance. This is typically a last resort for error recovery and may
      * result in other related services being killed.
      */
@@ -69,108 +153,18 @@
     void detach();
 
     /**
-     * @see ISoundTriggerHw#getProperties_2_3(ISoundTriggerHw.getProperties_2_3Callback)
-     */
-    Properties getProperties();
-
-    /**
-     * @see ISoundTriggerHw#registerGlobalCallback(ISoundTriggerHwGlobalCallback)
-     */
-    void registerCallback(GlobalCallback callback);
-
-    /**
-     * @see ISoundTriggerHw#loadSoundModel_2_4(
-     *              ISoundTriggerHw.SoundModel,
-     *              ISoundTriggerHwCallback,
-     *              ISoundTriggerHw.loadSoundModel_2_4Callback)
-     */
-    int loadSoundModel(ISoundTriggerHw.SoundModel soundModel, ModelCallback callback);
-
-    /**
-     * @see ISoundTriggerHw#loadPhraseSoundModel_2_4(
-     *              ISoundTriggerHw.PhraseSoundModel,
-     *              ISoundTriggerHwCallback,
-     *              ISoundTriggerHw.loadPhraseSoundModel_2_4Callback)
-     */
-    int loadPhraseSoundModel(ISoundTriggerHw.PhraseSoundModel soundModel, ModelCallback callback);
-
-    /**
-     * @see ISoundTriggerHw#unloadSoundModel(int)
-     */
-    void unloadSoundModel(int modelHandle);
-
-    /**
-     * @see ISoundTriggerHw#stopRecognition(int)
-     */
-    void stopRecognition(int modelHandle);
-
-    /**
-     * @see ISoundTriggerHw#startRecognition_2_4(int, RecognitionConfig)
-     */
-    void startRecognition(int modelHandle, RecognitionConfig config);
-
-    /**
-     * @see ISoundTriggerHw#getModelState(int)
-     */
-    void getModelState(int modelHandle);
-
-    /**
-     * @see ISoundTriggerHw#getParameter(int, int, ISoundTriggerHw.getParameterCallback)
-     */
-    int getModelParameter(int modelHandle, int param);
-
-    /**
-     * @see ISoundTriggerHw#setParameter(int, int, int)
-     */
-    void setModelParameter(int modelHandle, int param, int value);
-
-    /**
-     * @return null if not supported.
-     * @see ISoundTriggerHw#queryParameter(int, int,
-     * ISoundTriggerHw.queryParameterCallback)
-     */
-    ModelParameterRange queryParameter(int modelHandle, int param);
-
-    /**
-     * @see IHwBinder#linkToDeath(IHwBinder.DeathRecipient, long)
-     */
-    boolean linkToDeath(IHwBinder.DeathRecipient recipient, long cookie);
-
-    /**
-     * @see IHwBinder#unlinkToDeath(IHwBinder.DeathRecipient)
-     */
-    boolean unlinkToDeath(IHwBinder.DeathRecipient recipient);
-
-    /**
-     * @see IBase#interfaceDescriptor()
-     */
-    String interfaceDescriptor() throws android.os.RemoteException;
-
-    /*
-     * This is only useful for testing decorators and doesn't actually do anything with the real
-     * HAL. This method would block until all callbacks that were previously generated have been
-     * invoked. For most decorators, this merely flushes the delegate, but for delegates that may
-     * additional buffers for callbacks this should flush them.
-     */
-    void flushCallbacks();
-
-    /**
      * Callback interface for model-related events.
      */
     interface ModelCallback {
         /**
-         * @see ISoundTriggerHwCallback#recognitionCallback_2_1(
-         *              ISoundTriggerHwCallback.RecognitionEvent,
-         *              int)
+         * @see ISoundTriggerHwCallback#recognitionCallback(int, RecognitionEvent)
          */
-        void recognitionCallback(ISoundTriggerHwCallback.RecognitionEvent event);
+        void recognitionCallback(int modelHandle, RecognitionEvent event);
 
         /**
-         * @see ISoundTriggerHwCallback#phraseRecognitionCallback_2_1(
-         *              ISoundTriggerHwCallback.PhraseRecognitionEvent,
-         *              int)
+         * @see ISoundTriggerHwCallback#phraseRecognitionCallback(int, PhraseRecognitionEvent)
          */
-        void phraseRecognitionCallback(ISoundTriggerHwCallback.PhraseRecognitionEvent event);
+        void phraseRecognitionCallback(int modelHandle, PhraseRecognitionEvent event);
 
         /**
          * @see ISoundTriggerHwCallback#modelUnloaded(int)
diff --git a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHalConcurrentCaptureHandler.java b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHalConcurrentCaptureHandler.java
index f751118..e3ce719 100644
--- a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHalConcurrentCaptureHandler.java
+++ b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHalConcurrentCaptureHandler.java
@@ -17,17 +17,18 @@
 package com.android.server.soundtrigger_middleware;
 
 import android.annotation.NonNull;
-import android.hardware.soundtrigger.V2_1.ISoundTriggerHw;
-import android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback;
-import android.hardware.soundtrigger.V2_3.ModelParameterRange;
-import android.hardware.soundtrigger.V2_3.Properties;
-import android.hardware.soundtrigger.V2_3.RecognitionConfig;
 import android.media.permission.SafeCloseable;
+import android.media.soundtrigger.ModelParameterRange;
+import android.media.soundtrigger.PhraseRecognitionEvent;
+import android.media.soundtrigger.PhraseSoundModel;
+import android.media.soundtrigger.Properties;
+import android.media.soundtrigger.RecognitionConfig;
+import android.media.soundtrigger.RecognitionEvent;
 import android.media.soundtrigger.RecognitionStatus;
+import android.media.soundtrigger.SoundModel;
 import android.media.soundtrigger.SoundModelType;
 import android.media.soundtrigger.Status;
-import android.os.IHwBinder;
-import android.os.RemoteException;
+import android.os.IBinder;
 
 import java.util.HashSet;
 import java.util.LinkedList;
@@ -106,7 +107,7 @@
      * Since we're wrapping the death recipient, we need to keep a translation map for unlinking.
      * Key is the client recipient, value is the wrapper.
      */
-    private final @NonNull Map<IHwBinder.DeathRecipient, IHwBinder.DeathRecipient>
+    private final @NonNull Map<IBinder.DeathRecipient, IBinder.DeathRecipient>
             mDeathRecipientMap = new ConcurrentHashMap<>();
 
     private final @NonNull CallbackThread mCallbackThread = new CallbackThread();
@@ -120,12 +121,13 @@
     }
 
     @Override
-    public void startRecognition(int modelHandle, RecognitionConfig config) {
+    public void startRecognition(int modelHandle, int deviceHandle, int ioHandle,
+            RecognitionConfig config) {
         synchronized (mActiveModels) {
             if (mCaptureState) {
                 throw new RecoverableException(Status.RESOURCE_CONTENTION);
             }
-            mDelegate.startRecognition(modelHandle, config);
+            mDelegate.startRecognition(modelHandle, deviceHandle, ioHandle, config);
             mActiveModels.add(modelHandle);
         }
     }
@@ -165,14 +167,14 @@
     }
 
     @Override
-    public int loadSoundModel(ISoundTriggerHw.SoundModel soundModel, ModelCallback callback) {
+    public int loadSoundModel(SoundModel soundModel, ModelCallback callback) {
         int handle = mDelegate.loadSoundModel(soundModel, new CallbackWrapper(callback));
         mLoadedModels.put(handle, new LoadedModel(SoundModelType.GENERIC, callback));
         return handle;
     }
 
     @Override
-    public int loadPhraseSoundModel(ISoundTriggerHw.PhraseSoundModel soundModel,
+    public int loadPhraseSoundModel(PhraseSoundModel soundModel,
             ModelCallback callback) {
         int handle = mDelegate.loadPhraseSoundModel(soundModel, new CallbackWrapper(callback));
         mLoadedModels.put(handle, new LoadedModel(SoundModelType.KEYPHRASE, callback));
@@ -197,23 +199,20 @@
     }
 
     @Override
-    public boolean linkToDeath(IHwBinder.DeathRecipient recipient, long cookie) {
-        IHwBinder.DeathRecipient wrapper = new IHwBinder.DeathRecipient() {
+    public void linkToDeath(IBinder.DeathRecipient recipient) {
+        IBinder.DeathRecipient wrapper = new IBinder.DeathRecipient() {
             @Override
-            public void serviceDied(long cookieBack) {
-                mCallbackThread.push(() -> recipient.serviceDied(cookieBack));
+            public void binderDied() {
+                mCallbackThread.push(() -> recipient.binderDied());
             }
         };
-        if (mDelegate.linkToDeath(wrapper, cookie)) {
-            mDeathRecipientMap.put(recipient, wrapper);
-            return true;
-        }
-        return false;
+        mDelegate.linkToDeath(wrapper);
+        mDeathRecipientMap.put(recipient, wrapper);
     }
 
     @Override
-    public boolean unlinkToDeath(IHwBinder.DeathRecipient recipient) {
-        return mDelegate.unlinkToDeath(mDeathRecipientMap.remove(recipient));
+    public void unlinkToDeath(IBinder.DeathRecipient recipient) {
+        mDelegate.unlinkToDeath(mDeathRecipientMap.remove(recipient));
     }
 
     private class CallbackWrapper implements ISoundTriggerHal.ModelCallback {
@@ -224,22 +223,21 @@
         }
 
         @Override
-        public void recognitionCallback(ISoundTriggerHwCallback.RecognitionEvent event) {
+        public void recognitionCallback(int modelHandle, RecognitionEvent event) {
             // A recognition event must be the last one for its model, unless it is a forced one
             // (those leave the model active).
-            mCallbackThread.pushWithDedupe(event.header.model,
-                    event.header.status != RecognitionStatus.FORCED,
-                    () -> mDelegateCallback.recognitionCallback(event));
+            mCallbackThread.pushWithDedupe(modelHandle,
+                    event.status != RecognitionStatus.FORCED,
+                    () -> mDelegateCallback.recognitionCallback(modelHandle, event));
         }
 
         @Override
-        public void phraseRecognitionCallback(
-                ISoundTriggerHwCallback.PhraseRecognitionEvent event) {
+        public void phraseRecognitionCallback(int modelHandle, PhraseRecognitionEvent event) {
             // A recognition event must be the last one for its model, unless it is a forced one
             // (those leave the model active).
-            mCallbackThread.pushWithDedupe(event.common.header.model,
-                    event.common.header.status != RecognitionStatus.FORCED,
-                    () -> mDelegateCallback.phraseRecognitionCallback(event));
+            mCallbackThread.pushWithDedupe(modelHandle,
+                    event.common.status != RecognitionStatus.FORCED,
+                    () -> mDelegateCallback.phraseRecognitionCallback(modelHandle, event));
         }
 
         @Override
@@ -396,25 +394,18 @@
     private static void notifyAbort(int modelHandle, LoadedModel model) {
         switch (model.type) {
             case SoundModelType.GENERIC: {
-                ISoundTriggerHwCallback.RecognitionEvent event =
-                        new ISoundTriggerHwCallback.RecognitionEvent();
-                event.header.model = modelHandle;
-                event.header.status =
-                        android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.RecognitionStatus.ABORT;
-                event.header.type = android.hardware.soundtrigger.V2_0.SoundModelType.GENERIC;
-                model.callback.recognitionCallback(event);
+                RecognitionEvent event = new RecognitionEvent();
+                event.status = RecognitionStatus.ABORTED;
+                event.type = SoundModelType.GENERIC;
+                model.callback.recognitionCallback(modelHandle, event);
             }
             break;
 
             case SoundModelType.KEYPHRASE: {
-                ISoundTriggerHwCallback.PhraseRecognitionEvent event =
-                        new ISoundTriggerHwCallback.PhraseRecognitionEvent();
-                event.common.header.model = modelHandle;
-                event.common.header.status =
-                        android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.RecognitionStatus.ABORT;
-                event.common.header.type =
-                        android.hardware.soundtrigger.V2_0.SoundModelType.KEYPHRASE;
-                model.callback.phraseRecognitionCallback(event);
+                PhraseRecognitionEvent event = new PhraseRecognitionEvent();
+                event.common.status = RecognitionStatus.ABORTED;
+                event.common.type = SoundModelType.KEYPHRASE;
+                model.callback.phraseRecognitionCallback(modelHandle, event);
             }
             break;
         }
@@ -439,8 +430,8 @@
     }
 
     @Override
-    public void getModelState(int modelHandle) {
-        mDelegate.getModelState(modelHandle);
+    public void forceRecognitionEvent(int modelHandle) {
+        mDelegate.forceRecognitionEvent(modelHandle);
     }
 
     @Override
@@ -459,7 +450,7 @@
     }
 
     @Override
-    public String interfaceDescriptor() throws RemoteException {
+    public String interfaceDescriptor() {
         return mDelegate.interfaceDescriptor();
     }
 }
diff --git a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHalEnforcer.java b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHalEnforcer.java
index c45a325..6870f4f 100644
--- a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHalEnforcer.java
+++ b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHalEnforcer.java
@@ -16,16 +16,17 @@
 
 package com.android.server.soundtrigger_middleware;
 
-import android.hardware.soundtrigger.V2_1.ISoundTriggerHw;
-import android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback;
-import android.hardware.soundtrigger.V2_3.ModelParameterRange;
-import android.hardware.soundtrigger.V2_3.Properties;
-import android.hardware.soundtrigger.V2_3.RecognitionConfig;
+import android.media.soundtrigger.ModelParameterRange;
+import android.media.soundtrigger.PhraseRecognitionEvent;
+import android.media.soundtrigger.PhraseSoundModel;
+import android.media.soundtrigger.Properties;
+import android.media.soundtrigger.RecognitionConfig;
+import android.media.soundtrigger.RecognitionEvent;
 import android.media.soundtrigger.RecognitionStatus;
+import android.media.soundtrigger.SoundModel;
 import android.media.soundtrigger.Status;
 import android.os.DeadObjectException;
-import android.os.IHwBinder;
-import android.os.RemoteException;
+import android.os.IBinder;
 import android.util.Log;
 
 import java.util.HashMap;
@@ -78,7 +79,7 @@
     }
 
     @Override
-    public int loadSoundModel(ISoundTriggerHw.SoundModel soundModel, ModelCallback callback) {
+    public int loadSoundModel(SoundModel soundModel, ModelCallback callback) {
         try {
             synchronized (mModelStates) {
                 int handle = mUnderlying.loadSoundModel(soundModel,
@@ -92,8 +93,7 @@
     }
 
     @Override
-    public int loadPhraseSoundModel(ISoundTriggerHw.PhraseSoundModel soundModel,
-            ModelCallback callback) {
+    public int loadPhraseSoundModel(PhraseSoundModel soundModel, ModelCallback callback) {
         try {
             synchronized (mModelStates) {
                 int handle = mUnderlying.loadPhraseSoundModel(soundModel,
@@ -144,10 +144,11 @@
     }
 
     @Override
-    public void startRecognition(int modelHandle, RecognitionConfig config) {
+    public void startRecognition(int modelHandle, int deviceHandle, int ioHandle,
+            RecognitionConfig config) {
         try {
             synchronized (mModelStates) {
-                mUnderlying.startRecognition(modelHandle, config);
+                mUnderlying.startRecognition(modelHandle, deviceHandle, ioHandle, config);
                 mModelStates.replace(modelHandle, ModelState.ACTIVE);
             }
         } catch (RuntimeException e) {
@@ -156,9 +157,9 @@
     }
 
     @Override
-    public void getModelState(int modelHandle) {
+    public void forceRecognitionEvent(int modelHandle) {
         try {
-            mUnderlying.getModelState(modelHandle);
+            mUnderlying.forceRecognitionEvent(modelHandle);
         } catch (RuntimeException e) {
             throw handleException(e);
         }
@@ -192,17 +193,17 @@
     }
 
     @Override
-    public boolean linkToDeath(IHwBinder.DeathRecipient recipient, long cookie) {
-        return mUnderlying.linkToDeath(recipient, cookie);
+    public void linkToDeath(IBinder.DeathRecipient recipient) {
+        mUnderlying.linkToDeath(recipient);
     }
 
     @Override
-    public boolean unlinkToDeath(IHwBinder.DeathRecipient recipient) {
-        return mUnderlying.unlinkToDeath(recipient);
+    public void unlinkToDeath(IBinder.DeathRecipient recipient) {
+        mUnderlying.unlinkToDeath(recipient);
     }
 
     @Override
-    public String interfaceDescriptor() throws RemoteException {
+    public String interfaceDescriptor() {
         return mUnderlying.interfaceDescriptor();
     }
 
@@ -244,9 +245,8 @@
         }
 
         @Override
-        public void recognitionCallback(ISoundTriggerHwCallback.RecognitionEvent event) {
-            int model = event.header.model;
-            int status = event.header.status;
+        public void recognitionCallback(int model, RecognitionEvent event) {
+            int status = event.status;
 
             synchronized (mModelStates) {
                 ModelState state = mModelStates.get(model);
@@ -260,14 +260,12 @@
                 }
             }
             // Always invoke the delegate from outside the critical section.
-            mUnderlying.recognitionCallback(event);
+            mUnderlying.recognitionCallback(model, event);
         }
 
         @Override
-        public void phraseRecognitionCallback(
-                ISoundTriggerHwCallback.PhraseRecognitionEvent event) {
-            int model = event.common.header.model;
-            int status = event.common.header.status;
+        public void phraseRecognitionCallback(int model, PhraseRecognitionEvent event) {
+            int status = event.common.status;
             synchronized (mModelStates) {
                 ModelState state = mModelStates.get(model);
                 if (state == null || state == ModelState.INACTIVE) {
@@ -280,7 +278,7 @@
                 }
             }
             // Always invoke the delegate from outside the critical section.
-            mUnderlying.phraseRecognitionCallback(event);
+            mUnderlying.phraseRecognitionCallback(model, event);
         }
 
         @Override
diff --git a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHalMaxModelLimiter.java b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHalMaxModelLimiter.java
index 6e5ee70..7dd28e0 100644
--- a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHalMaxModelLimiter.java
+++ b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHalMaxModelLimiter.java
@@ -17,13 +17,13 @@
 package com.android.server.soundtrigger_middleware;
 
 import android.annotation.NonNull;
-import android.hardware.soundtrigger.V2_1.ISoundTriggerHw;
-import android.hardware.soundtrigger.V2_3.ModelParameterRange;
-import android.hardware.soundtrigger.V2_3.Properties;
-import android.hardware.soundtrigger.V2_3.RecognitionConfig;
+import android.media.soundtrigger.ModelParameterRange;
+import android.media.soundtrigger.PhraseSoundModel;
+import android.media.soundtrigger.Properties;
+import android.media.soundtrigger.RecognitionConfig;
+import android.media.soundtrigger.SoundModel;
 import android.media.soundtrigger.Status;
-import android.os.IHwBinder;
-import android.os.RemoteException;
+import android.os.IBinder;
 
 /**
  * This is a decorator around ISoundTriggerHal, which implements enforcement of the maximum number
@@ -70,7 +70,7 @@
     }
 
     @Override
-    public int loadSoundModel(ISoundTriggerHw.SoundModel soundModel, ModelCallback callback) {
+    public int loadSoundModel(SoundModel soundModel, ModelCallback callback) {
         synchronized (this) {
             if (mNumLoadedModels == mMaxModels) {
                 throw new RecoverableException(Status.RESOURCE_CONTENTION);
@@ -82,7 +82,7 @@
     }
 
     @Override
-    public int loadPhraseSoundModel(ISoundTriggerHw.PhraseSoundModel soundModel,
+    public int loadPhraseSoundModel(PhraseSoundModel soundModel,
             ModelCallback callback) {
         synchronized (this) {
             if (mNumLoadedModels == mMaxModels) {
@@ -121,13 +121,14 @@
     }
 
     @Override
-    public void startRecognition(int modelHandle, RecognitionConfig config) {
-        mDelegate.startRecognition(modelHandle, config);
+    public void startRecognition(int modelHandle, int deviceHandle, int ioHandle,
+            RecognitionConfig config) {
+        mDelegate.startRecognition(modelHandle, deviceHandle, ioHandle, config);
     }
 
     @Override
-    public void getModelState(int modelHandle) {
-        mDelegate.getModelState(modelHandle);
+    public void forceRecognitionEvent(int modelHandle) {
+        mDelegate.forceRecognitionEvent(modelHandle);
     }
 
     @Override
@@ -146,17 +147,17 @@
     }
 
     @Override
-    public boolean linkToDeath(IHwBinder.DeathRecipient recipient, long cookie) {
-        return mDelegate.linkToDeath(recipient, cookie);
+    public void linkToDeath(IBinder.DeathRecipient recipient) {
+        mDelegate.linkToDeath(recipient);
     }
 
     @Override
-    public boolean unlinkToDeath(IHwBinder.DeathRecipient recipient) {
-        return mDelegate.unlinkToDeath(recipient);
+    public void unlinkToDeath(IBinder.DeathRecipient recipient) {
+        mDelegate.unlinkToDeath(recipient);
     }
 
     @Override
-    public String interfaceDescriptor() throws RemoteException {
+    public String interfaceDescriptor() {
         return mDelegate.interfaceDescriptor();
     }
 
diff --git a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHalWatchdog.java b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHalWatchdog.java
index 1193d01..5fe06ee 100644
--- a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHalWatchdog.java
+++ b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHalWatchdog.java
@@ -17,12 +17,12 @@
 package com.android.server.soundtrigger_middleware;
 
 import android.annotation.NonNull;
-import android.hardware.soundtrigger.V2_1.ISoundTriggerHw;
-import android.hardware.soundtrigger.V2_3.ModelParameterRange;
-import android.hardware.soundtrigger.V2_3.Properties;
-import android.hardware.soundtrigger.V2_3.RecognitionConfig;
-import android.os.IHwBinder;
-import android.os.RemoteException;
+import android.media.soundtrigger.ModelParameterRange;
+import android.media.soundtrigger.PhraseSoundModel;
+import android.media.soundtrigger.Properties;
+import android.media.soundtrigger.RecognitionConfig;
+import android.media.soundtrigger.SoundModel;
+import android.os.IBinder;
 import android.util.Log;
 
 import java.util.Objects;
@@ -60,14 +60,14 @@
     }
 
     @Override
-    public int loadSoundModel(ISoundTriggerHw.SoundModel soundModel, ModelCallback callback) {
+    public int loadSoundModel(SoundModel soundModel, ModelCallback callback) {
         try (Watchdog ignore = new Watchdog()) {
             return mUnderlying.loadSoundModel(soundModel, callback);
         }
     }
 
     @Override
-    public int loadPhraseSoundModel(ISoundTriggerHw.PhraseSoundModel soundModel,
+    public int loadPhraseSoundModel(PhraseSoundModel soundModel,
             ModelCallback callback) {
         try (Watchdog ignore = new Watchdog()) {
             return mUnderlying.loadPhraseSoundModel(soundModel, callback);
@@ -89,16 +89,17 @@
     }
 
     @Override
-    public void startRecognition(int modelHandle, RecognitionConfig config) {
+    public void startRecognition(int modelHandle, int deviceHandle, int ioHandle,
+            RecognitionConfig config) {
         try (Watchdog ignore = new Watchdog()) {
-            mUnderlying.startRecognition(modelHandle, config);
+            mUnderlying.startRecognition(modelHandle, deviceHandle, ioHandle, config);
         }
     }
 
     @Override
-    public void getModelState(int modelHandle) {
+    public void forceRecognitionEvent(int modelHandle) {
         try (Watchdog ignore = new Watchdog()) {
-            mUnderlying.getModelState(modelHandle);
+            mUnderlying.forceRecognitionEvent(modelHandle);
         }
     }
 
@@ -124,17 +125,17 @@
     }
 
     @Override
-    public boolean linkToDeath(IHwBinder.DeathRecipient recipient, long cookie) {
-        return mUnderlying.linkToDeath(recipient, cookie);
+    public void linkToDeath(IBinder.DeathRecipient recipient) {
+        mUnderlying.linkToDeath(recipient);
     }
 
     @Override
-    public boolean unlinkToDeath(IHwBinder.DeathRecipient recipient) {
-        return mUnderlying.unlinkToDeath(recipient);
+    public void unlinkToDeath(IBinder.DeathRecipient recipient) {
+        mUnderlying.unlinkToDeath(recipient);
     }
 
     @Override
-    public String interfaceDescriptor() throws RemoteException {
+    public String interfaceDescriptor() {
         return mUnderlying.interfaceDescriptor();
     }
 
diff --git a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHw2Compat.java b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHw2Compat.java
index 5dcbad3..7a1f775 100644
--- a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHw2Compat.java
+++ b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHw2Compat.java
@@ -19,11 +19,19 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.hardware.soundtrigger.V2_0.ISoundTriggerHw;
+import android.media.soundtrigger.ModelParameterRange;
+import android.media.soundtrigger.PhraseSoundModel;
+import android.media.soundtrigger.Properties;
+import android.media.soundtrigger.RecognitionConfig;
+import android.media.soundtrigger.SoundModel;
 import android.media.soundtrigger.Status;
+import android.os.IBinder;
 import android.os.IHwBinder;
 import android.os.RemoteException;
 import android.system.OsConstants;
 
+import java.util.HashMap;
+import java.util.Map;
 import java.util.Objects;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
@@ -60,9 +68,14 @@
     private final @NonNull ConcurrentMap<Integer, ModelCallback> mModelCallbacks =
             new ConcurrentHashMap<>();
 
+    // A map from IBinder.DeathRecipient to IHwBinder.DeathRecipient for doing the mapping upon
+    // unlinking.
+    private final @NonNull Map<IBinder.DeathRecipient, IHwBinder.DeathRecipient>
+            mDeathRecipientMap = new HashMap<>();
+
     // The properties are read at construction time and cached, since we need to use some of them
     // to enforce constraints.
-    private final @NonNull android.hardware.soundtrigger.V2_3.Properties mProperties;
+    private final @NonNull Properties mProperties;
 
     static ISoundTriggerHal create(
             @NonNull ISoundTriggerHw underlying,
@@ -79,10 +92,10 @@
         // Add max model limiter for versions <2.4.
         if (compat.mUnderlying_2_4 == null) {
             result = new SoundTriggerHalMaxModelLimiter(result,
-                    compat.mProperties.base.maxSoundModels);
+                    compat.mProperties.maxSoundModels);
         }
         // Add concurrent capture handler for versions <2.4 which do not support concurrent capture.
-        if (compat.mUnderlying_2_4 == null && !compat.mProperties.base.concurrentCapture) {
+        if (compat.mUnderlying_2_4 == null && !compat.mProperties.concurrentCapture) {
             result = new SoundTriggerHalConcurrentCaptureHandler(result, notifier);
         }
         return result;
@@ -172,15 +185,14 @@
     }
 
     @Override
-    public android.hardware.soundtrigger.V2_3.Properties getProperties() {
+    public Properties getProperties() {
         return mProperties;
     }
 
-    private android.hardware.soundtrigger.V2_3.Properties getPropertiesInternal() {
+    private Properties getPropertiesInternal() {
         try {
             AtomicInteger retval = new AtomicInteger(-1);
-            AtomicReference<android.hardware.soundtrigger.V2_3.Properties>
-                    properties =
+            AtomicReference<android.hardware.soundtrigger.V2_3.Properties> properties =
                     new AtomicReference<>();
             try {
                 as2_3().getProperties_2_3(
@@ -193,7 +205,7 @@
                 return getProperties_2_0();
             }
             handleHalStatus(retval.get(), "getProperties_2_3");
-            return properties.get();
+            return ConversionUtil.hidl2aidlProperties(properties.get());
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
         }
@@ -214,15 +226,15 @@
     }
 
     @Override
-    public int loadSoundModel(
-            android.hardware.soundtrigger.V2_1.ISoundTriggerHw.SoundModel soundModel,
-            ModelCallback callback) {
+    public int loadSoundModel(SoundModel soundModel, ModelCallback callback) {
+        android.hardware.soundtrigger.V2_3.ISoundTriggerHw.SoundModel hidlModel =
+                ConversionUtil.aidl2hidlSoundModel(soundModel);
         try {
             AtomicInteger retval = new AtomicInteger(-1);
             AtomicInteger handle = new AtomicInteger(0);
 
             try {
-                as2_4().loadSoundModel_2_4(soundModel, new ModelCallbackWrapper(callback),
+                as2_4().loadSoundModel_2_4(hidlModel, new ModelCallbackWrapper(callback),
                         (r, h) -> {
                             retval.set(r);
                             handle.set(h);
@@ -231,7 +243,7 @@
             } catch (NotSupported e) {
                 // Fall-back to the 2.1 version:
                 try {
-                    as2_1().loadSoundModel_2_1(soundModel, new ModelCallbackWrapper(callback),
+                    as2_1().loadSoundModel_2_1(hidlModel, new ModelCallbackWrapper(callback),
                             0,
                             (r, h) -> {
                                 retval.set(r);
@@ -241,7 +253,7 @@
                     mModelCallbacks.put(handle.get(), callback);
                 } catch (NotSupported ee) {
                     // Fall-back to the 2.0 version:
-                    return loadSoundModel_2_0(soundModel, callback);
+                    return loadSoundModel_2_0(hidlModel, callback);
                 }
             }
             return handle.get();
@@ -251,14 +263,14 @@
     }
 
     @Override
-    public int loadPhraseSoundModel(
-            android.hardware.soundtrigger.V2_1.ISoundTriggerHw.PhraseSoundModel soundModel,
-            ModelCallback callback) {
+    public int loadPhraseSoundModel(PhraseSoundModel soundModel, ModelCallback callback) {
+        android.hardware.soundtrigger.V2_1.ISoundTriggerHw.PhraseSoundModel hidlModel =
+                ConversionUtil.aidl2hidlPhraseSoundModel(soundModel);
         try {
             AtomicInteger retval = new AtomicInteger(-1);
             AtomicInteger handle = new AtomicInteger(0);
             try {
-                as2_4().loadPhraseSoundModel_2_4(soundModel, new ModelCallbackWrapper(callback),
+                as2_4().loadPhraseSoundModel_2_4(hidlModel, new ModelCallbackWrapper(callback),
                         (r, h) -> {
                             retval.set(r);
                             handle.set(h);
@@ -267,7 +279,7 @@
             } catch (NotSupported e) {
                 // Fall-back to the 2.1 version:
                 try {
-                    as2_1().loadPhraseSoundModel_2_1(soundModel, new ModelCallbackWrapper(callback),
+                    as2_1().loadPhraseSoundModel_2_1(hidlModel, new ModelCallbackWrapper(callback),
                             0,
                             (r, h) -> {
                                 retval.set(r);
@@ -277,7 +289,7 @@
                     mModelCallbacks.put(handle.get(), callback);
                 } catch (NotSupported ee) {
                     // Fall-back to the 2.0 version:
-                    return loadPhraseSoundModel_2_0(soundModel, callback);
+                    return loadPhraseSoundModel_2_0(hidlModel, callback);
                 }
             }
             return handle.get();
@@ -310,20 +322,22 @@
     }
 
     @Override
-    public void startRecognition(int modelHandle,
-            android.hardware.soundtrigger.V2_3.RecognitionConfig config) {
+    public void startRecognition(int modelHandle, int deviceHandle, int ioHandle,
+            RecognitionConfig config) {
+        android.hardware.soundtrigger.V2_3.RecognitionConfig hidlConfig =
+                ConversionUtil.aidl2hidlRecognitionConfig(config, deviceHandle, ioHandle);
         try {
             try {
-                int retval = as2_4().startRecognition_2_4(modelHandle, config);
+                int retval = as2_4().startRecognition_2_4(modelHandle, hidlConfig);
                 handleHalStatusAllowBusy(retval, "startRecognition_2_4");
             } catch (NotSupported e) {
                 // Fall-back to the 2.3 version:
                 try {
-                    int retval = as2_3().startRecognition_2_3(modelHandle, config);
+                    int retval = as2_3().startRecognition_2_3(modelHandle, hidlConfig);
                     handleHalStatus(retval, "startRecognition_2_3");
                 } catch (NotSupported ee) {
                     // Fall-back to the 2.0 version:
-                    startRecognition_2_1(modelHandle, config);
+                    startRecognition_2_1(modelHandle, hidlConfig);
                 }
             }
         } catch (RemoteException e) {
@@ -332,7 +346,7 @@
     }
 
     @Override
-    public void getModelState(int modelHandle) {
+    public void forceRecognitionEvent(int modelHandle) {
         try {
             int retval = as2_2().getModelState(modelHandle);
             handleHalStatus(retval, "getModelState");
@@ -375,8 +389,7 @@
     }
 
     @Override
-    public android.hardware.soundtrigger.V2_3.ModelParameterRange queryParameter(int modelHandle,
-            int param) {
+    public ModelParameterRange queryParameter(int modelHandle, int param) {
         AtomicInteger status = new AtomicInteger(-1);
         AtomicReference<android.hardware.soundtrigger.V2_3.OptionalModelParameterRange>
                 optionalRange =
@@ -397,22 +410,28 @@
         return (optionalRange.get().getDiscriminator()
                 == android.hardware.soundtrigger.V2_3.OptionalModelParameterRange.hidl_discriminator.range)
                 ?
-                optionalRange.get().range() : null;
+                ConversionUtil.hidl2aidlModelParameterRange(optionalRange.get().range()) : null;
     }
 
     @Override
-    public boolean linkToDeath(IHwBinder.DeathRecipient recipient, long cookie) {
-        return mBinder.linkToDeath(recipient, cookie);
+    public void linkToDeath(IBinder.DeathRecipient recipient) {
+        IHwBinder.DeathRecipient wrapper = cookie -> recipient.binderDied();
+        mDeathRecipientMap.put(recipient, wrapper);
+        mBinder.linkToDeath(wrapper, 0);
     }
 
     @Override
-    public boolean unlinkToDeath(IHwBinder.DeathRecipient recipient) {
-        return mBinder.unlinkToDeath(recipient);
+    public void unlinkToDeath(IBinder.DeathRecipient recipient) {
+        mBinder.unlinkToDeath(mDeathRecipientMap.remove(recipient));
     }
 
     @Override
-    public String interfaceDescriptor() throws RemoteException {
-        return as2_0().interfaceDescriptor();
+    public String interfaceDescriptor() {
+        try {
+            return as2_0().interfaceDescriptor();
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
     }
 
     @Override
@@ -420,7 +439,7 @@
         // This is a no-op. Only implemented for decorators.
     }
 
-    private android.hardware.soundtrigger.V2_3.Properties getProperties_2_0()
+    private Properties getProperties_2_0()
             throws RemoteException {
         AtomicInteger retval = new AtomicInteger(-1);
         AtomicReference<android.hardware.soundtrigger.V2_0.ISoundTriggerHw.Properties>
@@ -432,7 +451,8 @@
                     properties.set(p);
                 });
         handleHalStatus(retval.get(), "getProperties");
-        return Hw2CompatUtil.convertProperties_2_0_to_2_3(properties.get());
+        return ConversionUtil.hidl2aidlProperties(
+                Hw2CompatUtil.convertProperties_2_0_to_2_3(properties.get()));
     }
 
     private int loadSoundModel_2_0(
@@ -592,14 +612,16 @@
         public void recognitionCallback_2_1(
                 android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.RecognitionEvent event,
                 int cookie) {
-            mDelegate.recognitionCallback(event);
+            mDelegate.recognitionCallback(event.header.model,
+                    ConversionUtil.hidl2aidlRecognitionEvent(event));
         }
 
         @Override
         public void phraseRecognitionCallback_2_1(
                 android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.PhraseRecognitionEvent event,
                 int cookie) {
-            mDelegate.phraseRecognitionCallback(event);
+            mDelegate.phraseRecognitionCallback(event.common.header.model,
+                    ConversionUtil.hidl2aidlPhraseRecognitionEvent(event));
         }
 
         @Override
@@ -615,7 +637,7 @@
                 int cookie) {
             android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.RecognitionEvent event_2_1 =
                     Hw2CompatUtil.convertRecognitionEvent_2_0_to_2_1(event);
-            mDelegate.recognitionCallback(event_2_1);
+            recognitionCallback_2_1(event_2_1, cookie);
         }
 
         @Override
@@ -624,7 +646,7 @@
                 int cookie) {
             android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.PhraseRecognitionEvent
                     event_2_1 = Hw2CompatUtil.convertPhraseRecognitionEvent_2_0_to_2_1(event);
-            mDelegate.phraseRecognitionCallback(event_2_1);
+            phraseRecognitionCallback_2_1(event_2_1, cookie);
         }
 
         @Override
diff --git a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerModule.java b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerModule.java
index bb2b01d..f211158 100644
--- a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerModule.java
+++ b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerModule.java
@@ -18,8 +18,6 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback;
-import android.hardware.soundtrigger.V2_2.ISoundTriggerHw;
 import android.media.soundtrigger.ModelParameterRange;
 import android.media.soundtrigger.PhraseRecognitionEvent;
 import android.media.soundtrigger.PhraseSoundModel;
@@ -32,7 +30,6 @@
 import android.media.soundtrigger_middleware.ISoundTriggerCallback;
 import android.media.soundtrigger_middleware.ISoundTriggerModule;
 import android.os.IBinder;
-import android.os.IHwBinder;
 import android.os.RemoteException;
 import android.util.Log;
 
@@ -84,7 +81,7 @@
  *
  * @hide
  */
-class SoundTriggerModule implements IHwBinder.DeathRecipient, ISoundTriggerHal.GlobalCallback {
+class SoundTriggerModule implements IBinder.DeathRecipient, ISoundTriggerHal.GlobalCallback {
     static private final String TAG = "SoundTriggerModule";
     @NonNull private final HalFactory mHalFactory;
     @NonNull private ISoundTriggerHal mHalService;
@@ -136,7 +133,7 @@
     }
 
     @Override
-    public void serviceDied(long cookie) {
+    public void binderDied() {
         Log.w(TAG, "Underlying HAL driver died.");
         List<ISoundTriggerCallback> callbacks;
         synchronized (this) {
@@ -171,9 +168,9 @@
     private void attachToHal() {
         mHalService = new SoundTriggerHalEnforcer(
                 new SoundTriggerHalWatchdog(mHalFactory.create()));
-        mHalService.linkToDeath(this, 0);
+        mHalService.linkToDeath(this);
         mHalService.registerCallback(this);
-        mProperties = ConversionUtil.hidl2aidlProperties(mHalService.getProperties());
+        mProperties = mHalService.getProperties();
     }
 
     /**
@@ -393,9 +390,7 @@
             private int load(@NonNull SoundModel model,
                     SoundTriggerMiddlewareImpl.AudioSessionProvider.AudioSession audioSession) {
                 mSession = audioSession;
-                ISoundTriggerHw.SoundModel hidlModel = ConversionUtil.aidl2hidlSoundModel(model);
-
-                mHandle = mHalService.loadSoundModel(hidlModel, this);
+                mHandle = mHalService.loadSoundModel(model, this);
                 setState(ModelState.LOADED);
                 mLoadedModels.put(mHandle, this);
                 return mHandle;
@@ -404,10 +399,7 @@
             private int load(@NonNull PhraseSoundModel model,
                     SoundTriggerMiddlewareImpl.AudioSessionProvider.AudioSession audioSession) {
                 mSession = audioSession;
-                ISoundTriggerHw.PhraseSoundModel hidlModel =
-                        ConversionUtil.aidl2hidlPhraseSoundModel(model);
-
-                mHandle = mHalService.loadPhraseSoundModel(hidlModel, this);
+                mHandle = mHalService.loadPhraseSoundModel(model, this);
 
                 setState(ModelState.LOADED);
                 mLoadedModels.put(mHandle, this);
@@ -425,11 +417,8 @@
             }
 
             private void startRecognition(@NonNull RecognitionConfig config) {
-                android.hardware.soundtrigger.V2_3.RecognitionConfig hidlConfig =
-                        ConversionUtil.aidl2hidlRecognitionConfig(config);
-                hidlConfig.base.header.captureDevice = mSession.mDeviceHandle;
-                hidlConfig.base.header.captureHandle = mSession.mIoHandle;
-                mHalService.startRecognition(mHandle, hidlConfig);
+                mHalService.startRecognition(mHandle, mSession.mDeviceHandle,
+                        mSession.mIoHandle, config);
                 setState(ModelState.ACTIVE);
             }
 
@@ -448,7 +437,7 @@
                     // This call is idempotent in order to avoid races.
                     return;
                 }
-                mHalService.getModelState(mHandle);
+                mHalService.forceRecognitionEvent(mHandle);
             }
 
 
@@ -464,19 +453,15 @@
 
             @Nullable
             private ModelParameterRange queryModelParameterSupport(int modelParam) {
-                return ConversionUtil.hidl2aidlModelParameterRange(
-                        mHalService.queryParameter(mHandle,
-                                ConversionUtil.aidl2hidlModelParameter(modelParam)));
+                return mHalService.queryParameter(mHandle, modelParam);
             }
 
             @Override
-            public void recognitionCallback(
-                    @NonNull ISoundTriggerHwCallback.RecognitionEvent recognitionEvent) {
+            public void recognitionCallback(int modelHandle,
+                    @NonNull RecognitionEvent recognitionEvent) {
                 ISoundTriggerCallback callback;
-                RecognitionEvent aidlEvent =
-                        ConversionUtil.hidl2aidlRecognitionEvent(recognitionEvent);
                 synchronized (SoundTriggerModule.this) {
-                    if (aidlEvent.status != RecognitionStatus.FORCED) {
+                    if (recognitionEvent.status != RecognitionStatus.FORCED) {
                         setState(ModelState.LOADED);
                     }
                     callback = mCallback;
@@ -484,7 +469,7 @@
                 // The callback must be invoked outside of the lock.
                 try {
                     if (callback != null) {
-                        callback.onRecognition(mHandle, aidlEvent, mSession.mSessionHandle);
+                        callback.onRecognition(mHandle, recognitionEvent, mSession.mSessionHandle);
                     }
                 } catch (RemoteException e) {
                     // We're not expecting any exceptions here.
@@ -493,13 +478,11 @@
             }
 
             @Override
-            public void phraseRecognitionCallback(
-                    @NonNull ISoundTriggerHwCallback.PhraseRecognitionEvent phraseRecognitionEvent) {
+            public void phraseRecognitionCallback(int modelHandle,
+                    @NonNull PhraseRecognitionEvent phraseRecognitionEvent) {
                 ISoundTriggerCallback callback;
-                PhraseRecognitionEvent aidlEvent =
-                        ConversionUtil.hidl2aidlPhraseRecognitionEvent(phraseRecognitionEvent);
                 synchronized (SoundTriggerModule.this) {
-                    if (aidlEvent.common.status != RecognitionStatus.FORCED) {
+                    if (phraseRecognitionEvent.common.status != RecognitionStatus.FORCED) {
                         setState(ModelState.LOADED);
                     }
                     callback = mCallback;
@@ -508,7 +491,8 @@
                 // The callback must be invoked outside of the lock.
                 try {
                     if (callback != null) {
-                        mCallback.onPhraseRecognition(mHandle, aidlEvent, mSession.mSessionHandle);
+                        mCallback.onPhraseRecognition(mHandle, phraseRecognitionEvent,
+                                mSession.mSessionHandle);
                     }
                 } catch (RemoteException e) {
                     // We're not expecting any exceptions here.
diff --git a/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/SoundHw2CompatTest.java b/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/SoundHw2CompatTest.java
index ea3bc59..1947481 100644
--- a/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/SoundHw2CompatTest.java
+++ b/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/SoundHw2CompatTest.java
@@ -37,8 +37,15 @@
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
+import android.media.soundtrigger.ModelParameterRange;
+import android.media.soundtrigger.PhraseRecognitionEvent;
+import android.media.soundtrigger.Properties;
+import android.media.soundtrigger.RecognitionConfig;
+import android.media.soundtrigger.RecognitionEvent;
+import android.media.soundtrigger.RecognitionStatus;
 import android.media.soundtrigger.Status;
 import android.os.HwParcel;
+import android.os.IBinder;
 import android.os.IHwBinder;
 import android.os.IHwInterface;
 import android.os.RemoteException;
@@ -56,11 +63,8 @@
 
 @RunWith(Parameterized.class)
 public class SoundHw2CompatTest {
-    @Parameterized.Parameter(0)
-    public String mVersion;
-
-    @Parameterized.Parameter(1)
-    public boolean mSupportConcurrentCapture;
+    @Parameterized.Parameter(0) public String mVersion;
+    @Parameterized.Parameter(1) public boolean mSupportConcurrentCapture;
 
     private final Runnable mRebootRunnable = mock(Runnable.class);
     private ISoundTriggerHal mCanonical;
@@ -72,13 +76,7 @@
     public static Iterable<Object[]> data() {
         List<Object[]> result = new LinkedList<>();
 
-        for (String version : new String[]{
-                "V2_0",
-                "V2_1",
-                "V2_2",
-                "V2_3",
-                "V2_4",
-        }) {
+        for (String version : new String[]{"V2_0", "V2_1", "V2_2", "V2_3", "V2_4",}) {
             for (boolean concurrentCapture : new boolean[]{false, true}) {
                 result.add(new Object[]{version, concurrentCapture});
             }
@@ -146,10 +144,8 @@
         android.hardware.soundtrigger.V2_3.Properties halProperties =
                 TestUtil.createDefaultProperties_2_3(mSupportConcurrentCapture);
         doAnswer(invocation -> {
-            ((android.hardware.soundtrigger.V2_0.ISoundTriggerHw.getPropertiesCallback)
-                    invocation.getArgument(
-                            0)).onValues(0,
-                    halProperties.base);
+            ((android.hardware.soundtrigger.V2_0.ISoundTriggerHw.getPropertiesCallback) invocation.getArgument(
+                    0)).onValues(0, halProperties.base);
             return null;
         }).when(mHalDriver).getProperties(any());
 
@@ -157,10 +153,8 @@
             android.hardware.soundtrigger.V2_3.ISoundTriggerHw driver =
                     (android.hardware.soundtrigger.V2_3.ISoundTriggerHw) mHalDriver;
             doAnswer(invocation -> {
-                ((android.hardware.soundtrigger.V2_3.ISoundTriggerHw.getProperties_2_3Callback)
-                        invocation.getArgument(
-                                0)).onValues(0,
-                        halProperties);
+                ((android.hardware.soundtrigger.V2_3.ISoundTriggerHw.getProperties_2_3Callback) invocation.getArgument(
+                        0)).onValues(0, halProperties);
                 return null;
             }).when(driver).getProperties_2_3(any());
         }
@@ -195,9 +189,7 @@
 
     @Test
     public void testGetProperties() throws Exception {
-        android.hardware.soundtrigger.V2_3.Properties halProperties =
-                TestUtil.createDefaultProperties_2_3(mSupportConcurrentCapture);
-        android.hardware.soundtrigger.V2_3.Properties properties = mCanonical.getProperties();
+        Properties properties = mCanonical.getProperties();
 
         if (mHalDriver instanceof android.hardware.soundtrigger.V2_3.ISoundTriggerHw) {
             android.hardware.soundtrigger.V2_3.ISoundTriggerHw driver =
@@ -205,26 +197,22 @@
             // It is OK for the SUT to cache the properties, so the underlying method doesn't
             // need to be called every single time.
             verify(driver, atMost(1)).getProperties_2_3(any());
-            assertEquals(halProperties, properties);
+            TestUtil.validateDefaultProperties(properties, mSupportConcurrentCapture);
         } else {
             // It is OK for the SUT to cache the properties, so the underlying method doesn't
             // need to be called every single time.
             verify(mHalDriver, atMost(1)).getProperties(any());
-            assertEquals(halProperties.base, properties.base);
-            assertEquals(0, properties.audioCapabilities);
-            assertEquals("", properties.supportedModelArch);
+            TestUtil.validateDefaultProperties(properties, mSupportConcurrentCapture, 0, "");
         }
     }
 
     private int loadGenericModel_2_0(ISoundTriggerHal.ModelCallback canonicalCallback)
             throws Exception {
         final int handle = 29;
-        ArgumentCaptor<android.hardware.soundtrigger.V2_0.ISoundTriggerHw.SoundModel>
-                modelCaptor =
+        ArgumentCaptor<android.hardware.soundtrigger.V2_0.ISoundTriggerHw.SoundModel> modelCaptor =
                 ArgumentCaptor.forClass(
                         android.hardware.soundtrigger.V2_0.ISoundTriggerHw.SoundModel.class);
-        ArgumentCaptor<android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback>
-                callbackCaptor =
+        ArgumentCaptor<android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback> callbackCaptor =
                 ArgumentCaptor.forClass(
                         android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.class);
 
@@ -237,8 +225,8 @@
             return null;
         }).when(mHalDriver).loadSoundModel(any(), any(), anyInt(), any());
 
-        assertEquals(handle, mCanonical.loadSoundModel(TestUtil.createGenericSoundModel_2_1(),
-                canonicalCallback));
+        assertEquals(handle,
+                mCanonical.loadSoundModel(TestUtil.createGenericSoundModel(), canonicalCallback));
 
         verify(mHalDriver).loadSoundModel(modelCaptor.capture(), callbackCaptor.capture(), anyInt(),
                 any());
@@ -254,12 +242,10 @@
                 (android.hardware.soundtrigger.V2_1.ISoundTriggerHw) mHalDriver;
 
         final int handle = 29;
-        ArgumentCaptor<android.hardware.soundtrigger.V2_1.ISoundTriggerHw.SoundModel>
-                modelCaptor =
+        ArgumentCaptor<android.hardware.soundtrigger.V2_1.ISoundTriggerHw.SoundModel> modelCaptor =
                 ArgumentCaptor.forClass(
                         android.hardware.soundtrigger.V2_1.ISoundTriggerHw.SoundModel.class);
-        ArgumentCaptor<android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback>
-                callbackCaptor =
+        ArgumentCaptor<android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback> callbackCaptor =
                 ArgumentCaptor.forClass(
                         android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.class);
 
@@ -272,12 +258,11 @@
             return null;
         }).when(driver_2_1).loadSoundModel_2_1(any(), any(), anyInt(), any());
 
-        assertEquals(handle, mCanonical.loadSoundModel(TestUtil.createGenericSoundModel_2_1(),
-                canonicalCallback));
+        assertEquals(handle,
+                mCanonical.loadSoundModel(TestUtil.createGenericSoundModel(), canonicalCallback));
 
         verify(driver_2_1).loadSoundModel_2_1(modelCaptor.capture(), callbackCaptor.capture(),
-                anyInt(),
-                any());
+                anyInt(), any());
 
         TestUtil.validateGenericSoundModel_2_1(modelCaptor.getValue());
         validateCallback_2_1(callbackCaptor.getValue(), canonicalCallback);
@@ -290,12 +275,10 @@
                 (android.hardware.soundtrigger.V2_4.ISoundTriggerHw) mHalDriver;
 
         final int handle = 29;
-        ArgumentCaptor<android.hardware.soundtrigger.V2_1.ISoundTriggerHw.SoundModel>
-                modelCaptor =
+        ArgumentCaptor<android.hardware.soundtrigger.V2_1.ISoundTriggerHw.SoundModel> modelCaptor =
                 ArgumentCaptor.forClass(
                         android.hardware.soundtrigger.V2_1.ISoundTriggerHw.SoundModel.class);
-        ArgumentCaptor<android.hardware.soundtrigger.V2_4.ISoundTriggerHwCallback>
-                callbackCaptor =
+        ArgumentCaptor<android.hardware.soundtrigger.V2_4.ISoundTriggerHwCallback> callbackCaptor =
                 ArgumentCaptor.forClass(
                         android.hardware.soundtrigger.V2_4.ISoundTriggerHwCallback.class);
 
@@ -308,8 +291,8 @@
             return null;
         }).when(driver_2_4).loadSoundModel_2_4(any(), any(), any());
 
-        assertEquals(handle, mCanonical.loadSoundModel(TestUtil.createGenericSoundModel_2_1(),
-                canonicalCallback));
+        assertEquals(handle,
+                mCanonical.loadSoundModel(TestUtil.createGenericSoundModel(), canonicalCallback));
 
         verify(driver_2_4).loadSoundModel_2_4(modelCaptor.capture(), callbackCaptor.capture(),
                 any());
@@ -348,7 +331,7 @@
 
         ISoundTriggerHal.ModelCallback canonicalCallback = mock(
                 ISoundTriggerHal.ModelCallback.class);
-        final int maxModels = TestUtil.createDefaultProperties(false).maxSoundModels;
+        final int maxModels = TestUtil.createDefaultProperties_2_0(false).maxSoundModels;
         int[] modelHandles = new int[maxModels];
 
         // Load as many models as we're allowed.
@@ -361,8 +344,7 @@
         // Now try to load an additional one and expect failure without invoking the underlying
         // driver.
         try {
-            mCanonical.loadPhraseSoundModel(TestUtil.createPhraseSoundModel_2_1(),
-                    canonicalCallback);
+            mCanonical.loadPhraseSoundModel(TestUtil.createPhraseSoundModel(), canonicalCallback);
             fail("Expected an exception");
         } catch (RecoverableException e) {
             assertEquals(Status.RESOURCE_CONTENTION, e.errorCode);
@@ -392,8 +374,7 @@
         ISoundTriggerHal.ModelCallback canonicalCallback = mock(
                 ISoundTriggerHal.ModelCallback.class);
         try {
-            mCanonical.loadSoundModel(TestUtil.createGenericSoundModel_2_1(),
-                    canonicalCallback);
+            mCanonical.loadSoundModel(TestUtil.createGenericSoundModel(), canonicalCallback);
             fail("Expected an exception");
         } catch (RecoverableException e) {
             assertEquals(Status.RESOURCE_CONTENTION, e.errorCode);
@@ -412,11 +393,9 @@
             throws Exception {
         final int handle = 29;
         ArgumentCaptor<android.hardware.soundtrigger.V2_0.ISoundTriggerHw.PhraseSoundModel>
-                modelCaptor =
-                ArgumentCaptor.forClass(
-                        android.hardware.soundtrigger.V2_0.ISoundTriggerHw.PhraseSoundModel.class);
-        ArgumentCaptor<android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback>
-                callbackCaptor =
+                modelCaptor = ArgumentCaptor.forClass(
+                android.hardware.soundtrigger.V2_0.ISoundTriggerHw.PhraseSoundModel.class);
+        ArgumentCaptor<android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback> callbackCaptor =
                 ArgumentCaptor.forClass(
                         android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.class);
 
@@ -429,12 +408,11 @@
             return null;
         }).when(mHalDriver).loadPhraseSoundModel(any(), any(), anyInt(), any());
 
-        assertEquals(handle, mCanonical.loadPhraseSoundModel(TestUtil.createPhraseSoundModel_2_1(),
+        assertEquals(handle, mCanonical.loadPhraseSoundModel(TestUtil.createPhraseSoundModel(),
                 canonicalCallback));
 
         verify(mHalDriver).loadPhraseSoundModel(modelCaptor.capture(), callbackCaptor.capture(),
-                anyInt(),
-                any());
+                anyInt(), any());
 
         TestUtil.validatePhraseSoundModel_2_0(modelCaptor.getValue());
         validateCallback_2_0(callbackCaptor.getValue(), canonicalCallback);
@@ -448,11 +426,9 @@
 
         final int handle = 29;
         ArgumentCaptor<android.hardware.soundtrigger.V2_1.ISoundTriggerHw.PhraseSoundModel>
-                modelCaptor =
-                ArgumentCaptor.forClass(
-                        android.hardware.soundtrigger.V2_1.ISoundTriggerHw.PhraseSoundModel.class);
-        ArgumentCaptor<android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback>
-                callbackCaptor =
+                modelCaptor = ArgumentCaptor.forClass(
+                android.hardware.soundtrigger.V2_1.ISoundTriggerHw.PhraseSoundModel.class);
+        ArgumentCaptor<android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback> callbackCaptor =
                 ArgumentCaptor.forClass(
                         android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.class);
 
@@ -465,12 +441,11 @@
             return null;
         }).when(driver_2_1).loadPhraseSoundModel_2_1(any(), any(), anyInt(), any());
 
-        assertEquals(handle, mCanonical.loadPhraseSoundModel(TestUtil.createPhraseSoundModel_2_1(),
+        assertEquals(handle, mCanonical.loadPhraseSoundModel(TestUtil.createPhraseSoundModel(),
                 canonicalCallback));
 
         verify(driver_2_1).loadPhraseSoundModel_2_1(modelCaptor.capture(), callbackCaptor.capture(),
-                anyInt(),
-                any());
+                anyInt(), any());
 
         TestUtil.validatePhraseSoundModel_2_1(modelCaptor.getValue());
         validateCallback_2_1(callbackCaptor.getValue(), canonicalCallback);
@@ -484,11 +459,9 @@
 
         final int handle = 29;
         ArgumentCaptor<android.hardware.soundtrigger.V2_1.ISoundTriggerHw.PhraseSoundModel>
-                modelCaptor =
-                ArgumentCaptor.forClass(
-                        android.hardware.soundtrigger.V2_1.ISoundTriggerHw.PhraseSoundModel.class);
-        ArgumentCaptor<android.hardware.soundtrigger.V2_4.ISoundTriggerHwCallback>
-                callbackCaptor =
+                modelCaptor = ArgumentCaptor.forClass(
+                android.hardware.soundtrigger.V2_1.ISoundTriggerHw.PhraseSoundModel.class);
+        ArgumentCaptor<android.hardware.soundtrigger.V2_4.ISoundTriggerHwCallback> callbackCaptor =
                 ArgumentCaptor.forClass(
                         android.hardware.soundtrigger.V2_4.ISoundTriggerHwCallback.class);
 
@@ -501,7 +474,7 @@
             return null;
         }).when(driver_2_4).loadPhraseSoundModel_2_4(any(), any(), any());
 
-        assertEquals(handle, mCanonical.loadPhraseSoundModel(TestUtil.createPhraseSoundModel_2_1(),
+        assertEquals(handle, mCanonical.loadPhraseSoundModel(TestUtil.createPhraseSoundModel(),
                 canonicalCallback));
 
         verify(driver_2_4).loadPhraseSoundModel_2_4(modelCaptor.capture(), callbackCaptor.capture(),
@@ -545,8 +518,7 @@
         ISoundTriggerHal.ModelCallback canonicalCallback = mock(
                 ISoundTriggerHal.ModelCallback.class);
         try {
-            mCanonical.loadPhraseSoundModel(TestUtil.createPhraseSoundModel_2_1(),
-                    canonicalCallback);
+            mCanonical.loadPhraseSoundModel(TestUtil.createPhraseSoundModel(), canonicalCallback);
             fail("Expected an exception");
         } catch (RecoverableException e) {
             assertEquals(Status.RESOURCE_CONTENTION, e.errorCode);
@@ -572,16 +544,14 @@
         ArgumentCaptor<android.hardware.soundtrigger.V2_0.ISoundTriggerHw.RecognitionConfig>
                 configCaptor = ArgumentCaptor.forClass(
                 android.hardware.soundtrigger.V2_0.ISoundTriggerHw.RecognitionConfig.class);
-        ArgumentCaptor<android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback>
-                callbackCaptor =
+        ArgumentCaptor<android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback> callbackCaptor =
                 ArgumentCaptor.forClass(
                         android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.class);
 
         when(mHalDriver.startRecognition(eq(handle), any(), any(), anyInt())).thenReturn(0);
 
-        android.hardware.soundtrigger.V2_3.RecognitionConfig config =
-                TestUtil.createRecognitionConfig_2_3(203, 204);
-        mCanonical.startRecognition(handle, config);
+        RecognitionConfig config = TestUtil.createRecognitionConfig();
+        mCanonical.startRecognition(handle, 203, 204, config);
         verify(mHalDriver).startRecognition(eq(handle), configCaptor.capture(),
                 callbackCaptor.capture(), anyInt());
 
@@ -597,54 +567,45 @@
         ArgumentCaptor<android.hardware.soundtrigger.V2_1.ISoundTriggerHw.RecognitionConfig>
                 configCaptor = ArgumentCaptor.forClass(
                 android.hardware.soundtrigger.V2_1.ISoundTriggerHw.RecognitionConfig.class);
-        ArgumentCaptor<android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback>
-                callbackCaptor =
+        ArgumentCaptor<android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback> callbackCaptor =
                 ArgumentCaptor.forClass(
                         android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.class);
 
         when(driver_2_1.startRecognition_2_1(eq(handle), any(), any(), anyInt())).thenReturn(0);
 
-        android.hardware.soundtrigger.V2_3.RecognitionConfig config =
-                TestUtil.createRecognitionConfig_2_3(505, 506);
-        mCanonical.startRecognition(handle, config);
+        RecognitionConfig config = TestUtil.createRecognitionConfig();
+        mCanonical.startRecognition(handle, 505, 506, config);
         verify(driver_2_1).startRecognition_2_1(eq(handle), configCaptor.capture(),
-                callbackCaptor.capture(),
-                anyInt());
+                callbackCaptor.capture(), anyInt());
 
         TestUtil.validateRecognitionConfig_2_1(configCaptor.getValue(), 505, 506);
         validateCallback_2_1(callbackCaptor.getValue(), canonicalCallback);
     }
 
-    private void startRecognition_2_3(int handle)
-            throws Exception {
+    private void startRecognition_2_3(int handle) throws Exception {
         final android.hardware.soundtrigger.V2_3.ISoundTriggerHw driver_2_3 =
                 (android.hardware.soundtrigger.V2_3.ISoundTriggerHw) mHalDriver;
-        ArgumentCaptor<android.hardware.soundtrigger.V2_3.RecognitionConfig>
-                configCaptor = ArgumentCaptor.forClass(
-                android.hardware.soundtrigger.V2_3.RecognitionConfig.class);
+        ArgumentCaptor<android.hardware.soundtrigger.V2_3.RecognitionConfig> configCaptor =
+                ArgumentCaptor.forClass(android.hardware.soundtrigger.V2_3.RecognitionConfig.class);
 
         when(driver_2_3.startRecognition_2_3(eq(handle), any())).thenReturn(0);
 
-        android.hardware.soundtrigger.V2_3.RecognitionConfig config =
-                TestUtil.createRecognitionConfig_2_3(808, 909);
-        mCanonical.startRecognition(handle, config);
+        RecognitionConfig config = TestUtil.createRecognitionConfig();
+        mCanonical.startRecognition(handle, 808, 909, config);
         verify(driver_2_3).startRecognition_2_3(eq(handle), configCaptor.capture());
         TestUtil.validateRecognitionConfig_2_3(configCaptor.getValue(), 808, 909);
     }
 
-    private void startRecognition_2_4(int handle)
-            throws Exception {
+    private void startRecognition_2_4(int handle) throws Exception {
         final android.hardware.soundtrigger.V2_4.ISoundTriggerHw driver_2_4 =
                 (android.hardware.soundtrigger.V2_4.ISoundTriggerHw) mHalDriver;
-        ArgumentCaptor<android.hardware.soundtrigger.V2_3.RecognitionConfig>
-                configCaptor = ArgumentCaptor.forClass(
-                android.hardware.soundtrigger.V2_3.RecognitionConfig.class);
+        ArgumentCaptor<android.hardware.soundtrigger.V2_3.RecognitionConfig> configCaptor =
+                ArgumentCaptor.forClass(android.hardware.soundtrigger.V2_3.RecognitionConfig.class);
 
         when(driver_2_4.startRecognition_2_4(eq(handle), any())).thenReturn(0);
 
-        android.hardware.soundtrigger.V2_3.RecognitionConfig config =
-                TestUtil.createRecognitionConfig_2_3(21, 22);
-        mCanonical.startRecognition(handle, config);
+        RecognitionConfig config = TestUtil.createRecognitionConfig();
+        mCanonical.startRecognition(handle, 21, 22, config);
         verify(driver_2_4).startRecognition_2_4(eq(handle), configCaptor.capture());
         TestUtil.validateRecognitionConfig_2_3(configCaptor.getValue(), 21, 22);
     }
@@ -680,10 +641,9 @@
         final int handle = 68;
         when(driver_2_4.startRecognition_2_4(eq(handle), any())).thenReturn(-OsConstants.EBUSY);
 
-        android.hardware.soundtrigger.V2_3.RecognitionConfig config =
-                TestUtil.createRecognitionConfig_2_3(34, 35);
+        RecognitionConfig config = TestUtil.createRecognitionConfig();
         try {
-            mCanonical.startRecognition(handle, config);
+            mCanonical.startRecognition(handle, 34, 35, config);
             fail("Expected an exception");
         } catch (RecoverableException e) {
             assertEquals(Status.RESOURCE_CONTENTION, e.errorCode);
@@ -731,15 +691,11 @@
         verify(mHalDriver).stopRecognition(handle);
 
         // Expect an abort event (async).
-        ArgumentCaptor<android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.RecognitionEvent>
-                eventCaptor = ArgumentCaptor.forClass(
-                android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.RecognitionEvent.class);
+        ArgumentCaptor<RecognitionEvent> eventCaptor = ArgumentCaptor.forClass(
+                RecognitionEvent.class);
         mCanonical.flushCallbacks();
-        verify(canonicalCallback).recognitionCallback(eventCaptor.capture());
-        assertEquals(
-                android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.RecognitionStatus.ABORT,
-                eventCaptor.getValue().header.status);
-        assertEquals(handle, eventCaptor.getValue().header.model);
+        verify(canonicalCallback).recognitionCallback(eq(handle), eventCaptor.capture());
+        assertEquals(RecognitionStatus.ABORTED, eventCaptor.getValue().status);
 
         // Deactivate external capture.
         mCaptureStateNotifier.setState(false);
@@ -769,10 +725,9 @@
         mCaptureStateNotifier.setState(true);
 
         // Then start.
-        android.hardware.soundtrigger.V2_3.RecognitionConfig config =
-                TestUtil.createRecognitionConfig_2_3(203, 204);
+        RecognitionConfig config = TestUtil.createRecognitionConfig();
         try {
-            mCanonical.startRecognition(handle, config);
+            mCanonical.startRecognition(handle, 203, 204, config);
             fail("Expected an exception");
         } catch (RecoverableException e) {
             assertEquals(Status.RESOURCE_CONTENTION, e.errorCode);
@@ -797,11 +752,11 @@
         if (mHalDriver instanceof android.hardware.soundtrigger.V2_2.ISoundTriggerHw) {
             android.hardware.soundtrigger.V2_2.ISoundTriggerHw driver_2_2 =
                     (android.hardware.soundtrigger.V2_2.ISoundTriggerHw) mHalDriver;
-            mCanonical.getModelState(14);
+            mCanonical.forceRecognitionEvent(14);
             verify(driver_2_2).getModelState(14);
         } else {
             try {
-                mCanonical.getModelState(14);
+                mCanonical.forceRecognitionEvent(14);
                 fail("Expected an exception");
             } catch (RecoverableException e) {
                 assertEquals(Status.OPERATION_NOT_SUPPORTED, e.errorCode);
@@ -817,8 +772,8 @@
                 (android.hardware.soundtrigger.V2_3.ISoundTriggerHw) mHalDriver;
 
         doAnswer(invocation -> {
-            android.hardware.soundtrigger.V2_3.ISoundTriggerHw.getParameterCallback
-                    resultCallback = invocation.getArgument(2);
+            android.hardware.soundtrigger.V2_3.ISoundTriggerHw.getParameterCallback resultCallback =
+                    invocation.getArgument(2);
 
             // This is the return of this method.
             resultCallback.onValues(0, 99);
@@ -863,11 +818,10 @@
             return null;
         }).when(driver_2_3).queryParameter(eq(11), eq(12), any());
 
-        android.hardware.soundtrigger.V2_3.ModelParameterRange range = mCanonical.queryParameter(11,
-                12);
+        ModelParameterRange range = mCanonical.queryParameter(11, 12);
         assertNotNull(range);
-        assertEquals(34, range.start);
-        assertEquals(45, range.end);
+        assertEquals(34, range.minInclusive);
+        assertEquals(45, range.maxInclusive);
         verify(driver_2_3).queryParameter(eq(11), eq(12), any());
     }
 
@@ -888,13 +842,11 @@
                 return null;
             }).when(driver_2_3).queryParameter(eq(11), eq(12), any());
 
-            android.hardware.soundtrigger.V2_3.ModelParameterRange range =
-                    mCanonical.queryParameter(11, 12);
+            ModelParameterRange range = mCanonical.queryParameter(11, 12);
             assertNull(range);
             verify(driver_2_3).queryParameter(eq(11), eq(12), any());
         } else {
-            android.hardware.soundtrigger.V2_3.ModelParameterRange range =
-                    mCanonical.queryParameter(11, 12);
+            ModelParameterRange range = mCanonical.queryParameter(11, 12);
             assertNull(range);
         }
     }
@@ -932,9 +884,9 @@
 
     @Test
     public void testLinkToDeath() throws Exception {
-        IHwBinder.DeathRecipient canonicalRecipient = mock(IHwBinder.DeathRecipient.class);
+        IBinder.DeathRecipient canonicalRecipient = mock(IBinder.DeathRecipient.class);
         when(mHalDriver.linkToDeath(any(), anyLong())).thenReturn(true);
-        mCanonical.linkToDeath(canonicalRecipient, 19);
+        mCanonical.linkToDeath(canonicalRecipient);
 
         ArgumentCaptor<IHwBinder.DeathRecipient> recipientCaptor = ArgumentCaptor.forClass(
                 IHwBinder.DeathRecipient.class);
@@ -943,7 +895,7 @@
 
         recipientCaptor.getValue().serviceDied(cookieCaptor.getValue());
         mCanonical.flushCallbacks();
-        verify(canonicalRecipient).serviceDied(19);
+        verify(canonicalRecipient).binderDied();
 
         mCanonical.unlinkToDeath(canonicalRecipient);
         verify(mHalDriver).unlinkToDeath(recipientCaptor.getValue());
@@ -971,30 +923,28 @@
             final int handle = 85;
             final int status =
                     android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.RecognitionStatus.ABORT;
-            ArgumentCaptor<android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.RecognitionEvent>
-                    eventCaptor = ArgumentCaptor.forClass(
-                    android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.RecognitionEvent.class);
+            ArgumentCaptor<RecognitionEvent> eventCaptor = ArgumentCaptor.forClass(
+                    RecognitionEvent.class);
 
-            hwCallback.recognitionCallback(TestUtil.createRecognitionEvent_2_0(handle, status),
-                    99);
+            hwCallback.recognitionCallback(TestUtil.createRecognitionEvent_2_0(handle, status), 99);
             mCanonical.flushCallbacks();
-            verify(canonicalCallback).recognitionCallback(eventCaptor.capture());
-            TestUtil.validateRecognitionEvent_2_1(eventCaptor.getValue(), handle, status);
+            verify(canonicalCallback).recognitionCallback(eq(handle), eventCaptor.capture());
+            TestUtil.validateRecognitionEvent(eventCaptor.getValue(), RecognitionStatus.ABORTED);
         }
 
         {
             final int handle = 92;
             final int status =
                     android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.RecognitionStatus.SUCCESS;
-            ArgumentCaptor<android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.PhraseRecognitionEvent>
-                    eventCaptor = ArgumentCaptor.forClass(
-                    android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.PhraseRecognitionEvent.class);
+            ArgumentCaptor<PhraseRecognitionEvent> eventCaptor = ArgumentCaptor.forClass(
+                    PhraseRecognitionEvent.class);
 
             hwCallback.phraseRecognitionCallback(
                     TestUtil.createPhraseRecognitionEvent_2_0(handle, status), 99);
             mCanonical.flushCallbacks();
-            verify(canonicalCallback).phraseRecognitionCallback(eventCaptor.capture());
-            TestUtil.validatePhraseRecognitionEvent_2_1(eventCaptor.getValue(), handle, status);
+            verify(canonicalCallback).phraseRecognitionCallback(eq(handle), eventCaptor.capture());
+            TestUtil.validatePhraseRecognitionEvent(eventCaptor.getValue(),
+                    RecognitionStatus.SUCCESS);
         }
         verifyNoMoreInteractions(canonicalCallback);
         clearInvocations(canonicalCallback);
@@ -1007,31 +957,29 @@
             final int handle = 85;
             final int status =
                     android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.RecognitionStatus.ABORT;
-            ArgumentCaptor<android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.RecognitionEvent>
-                    eventCaptor = ArgumentCaptor.forClass(
-                    android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.RecognitionEvent.class);
+            ArgumentCaptor<RecognitionEvent> eventCaptor = ArgumentCaptor.forClass(
+                    RecognitionEvent.class);
 
-            hwCallback.recognitionCallback_2_1(
-                    TestUtil.createRecognitionEvent_2_1(handle, status),
+            hwCallback.recognitionCallback_2_1(TestUtil.createRecognitionEvent_2_1(handle, status),
                     99);
             mCanonical.flushCallbacks();
-            verify(canonicalCallback).recognitionCallback(eventCaptor.capture());
-            TestUtil.validateRecognitionEvent_2_1(eventCaptor.getValue(), handle, status);
+            verify(canonicalCallback).recognitionCallback(eq(handle), eventCaptor.capture());
+            TestUtil.validateRecognitionEvent(eventCaptor.getValue(), RecognitionStatus.ABORTED);
         }
 
         {
             final int handle = 92;
             final int status =
                     android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.RecognitionStatus.SUCCESS;
-            ArgumentCaptor<android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.PhraseRecognitionEvent>
-                    eventCaptor = ArgumentCaptor.forClass(
-                    android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.PhraseRecognitionEvent.class);
+            ArgumentCaptor<PhraseRecognitionEvent> eventCaptor = ArgumentCaptor.forClass(
+                    PhraseRecognitionEvent.class);
 
             hwCallback.phraseRecognitionCallback_2_1(
                     TestUtil.createPhraseRecognitionEvent_2_1(handle, status), 99);
             mCanonical.flushCallbacks();
-            verify(canonicalCallback).phraseRecognitionCallback(eventCaptor.capture());
-            TestUtil.validatePhraseRecognitionEvent_2_1(eventCaptor.getValue(), handle, status);
+            verify(canonicalCallback).phraseRecognitionCallback(eq(handle), eventCaptor.capture());
+            TestUtil.validatePhraseRecognitionEvent(eventCaptor.getValue(),
+                    RecognitionStatus.SUCCESS);
         }
         verifyNoMoreInteractions(canonicalCallback);
         clearInvocations(canonicalCallback);
@@ -1044,31 +992,29 @@
             final int handle = 85;
             final int status =
                     android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.RecognitionStatus.ABORT;
-            ArgumentCaptor<android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.RecognitionEvent>
-                    eventCaptor = ArgumentCaptor.forClass(
-                    android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.RecognitionEvent.class);
+            ArgumentCaptor<RecognitionEvent> eventCaptor = ArgumentCaptor.forClass(
+                    RecognitionEvent.class);
 
-            hwCallback.recognitionCallback_2_1(
-                    TestUtil.createRecognitionEvent_2_1(handle, status),
+            hwCallback.recognitionCallback_2_1(TestUtil.createRecognitionEvent_2_1(handle, status),
                     99);
             mCanonical.flushCallbacks();
-            verify(canonicalCallback).recognitionCallback(eventCaptor.capture());
-            TestUtil.validateRecognitionEvent_2_1(eventCaptor.getValue(), handle, status);
+            verify(canonicalCallback).recognitionCallback(eq(handle), eventCaptor.capture());
+            TestUtil.validateRecognitionEvent(eventCaptor.getValue(), RecognitionStatus.ABORTED);
         }
 
         {
             final int handle = 92;
             final int status =
                     android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.RecognitionStatus.SUCCESS;
-            ArgumentCaptor<android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.PhraseRecognitionEvent>
-                    eventCaptor = ArgumentCaptor.forClass(
-                    android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.PhraseRecognitionEvent.class);
+            ArgumentCaptor<PhraseRecognitionEvent> eventCaptor = ArgumentCaptor.forClass(
+                    PhraseRecognitionEvent.class);
 
             hwCallback.phraseRecognitionCallback_2_1(
                     TestUtil.createPhraseRecognitionEvent_2_1(handle, status), 99);
             mCanonical.flushCallbacks();
-            verify(canonicalCallback).phraseRecognitionCallback(eventCaptor.capture());
-            TestUtil.validatePhraseRecognitionEvent_2_1(eventCaptor.getValue(), handle, status);
+            verify(canonicalCallback).phraseRecognitionCallback(eq(handle), eventCaptor.capture());
+            TestUtil.validatePhraseRecognitionEvent(eventCaptor.getValue(),
+                    RecognitionStatus.SUCCESS);
         }
 
         {
@@ -1081,9 +1027,8 @@
         clearInvocations(canonicalCallback);
     }
 
-    public class CaptureStateNotifier implements ICaptureStateNotifier {
-        private boolean mState = false;
-        private List<Listener> mListeners = new LinkedList<>();
+    public static class CaptureStateNotifier implements ICaptureStateNotifier {
+        private final List<Listener> mListeners = new LinkedList<>();
 
         @Override
         public boolean registerListener(Listener listener) {
@@ -1097,7 +1042,6 @@
         }
 
         public void setState(boolean state) {
-            mState = state;
             for (Listener listener : mListeners) {
                 listener.onCaptureStateChange(state);
             }
diff --git a/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareImplTest.java b/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareImplTest.java
index 4780eb2..1daf831 100644
--- a/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareImplTest.java
@@ -29,7 +29,6 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback;
 import android.media.soundtrigger.ModelParameter;
 import android.media.soundtrigger.ModelParameterRange;
 import android.media.soundtrigger.PhraseRecognitionEvent;
@@ -57,12 +56,10 @@
 
 @RunWith(JUnit4.class)
 public class SoundTriggerMiddlewareImplTest {
-    @Mock
-    public ISoundTriggerHal mHalDriver = mock(ISoundTriggerHal.class);
+    @Mock public ISoundTriggerHal mHalDriver = mock(ISoundTriggerHal.class);
 
-    @Mock
-    private final SoundTriggerMiddlewareImpl.AudioSessionProvider mAudioSessionProvider = mock(
-            SoundTriggerMiddlewareImpl.AudioSessionProvider.class);
+    @Mock private final SoundTriggerMiddlewareImpl.AudioSessionProvider mAudioSessionProvider =
+            mock(SoundTriggerMiddlewareImpl.AudioSessionProvider.class);
 
     private SoundTriggerMiddlewareImpl mService;
 
@@ -73,32 +70,28 @@
     private Pair<Integer, SoundTriggerHwCallback> loadGenericModel(ISoundTriggerModule module,
             int hwHandle) throws RemoteException {
         SoundModel model = TestUtil.createGenericSoundModel();
-        ArgumentCaptor<android.hardware.soundtrigger.V2_1.ISoundTriggerHw.SoundModel> modelCaptor =
-                ArgumentCaptor.forClass(
-                        android.hardware.soundtrigger.V2_1.ISoundTriggerHw.SoundModel.class);
-        ArgumentCaptor<ISoundTriggerHal.ModelCallback> callbackCaptor =
-                ArgumentCaptor.forClass(ISoundTriggerHal.ModelCallback.class);
+        ArgumentCaptor<SoundModel> modelCaptor = ArgumentCaptor.forClass(SoundModel.class);
+        ArgumentCaptor<ISoundTriggerHal.ModelCallback> callbackCaptor = ArgumentCaptor.forClass(
+                ISoundTriggerHal.ModelCallback.class);
 
-        when(mHalDriver.loadSoundModel(any(), any())).thenReturn(
-                hwHandle);
+        when(mHalDriver.loadSoundModel(any(), any())).thenReturn(hwHandle);
         when(mAudioSessionProvider.acquireSession()).thenReturn(
                 new SoundTriggerMiddlewareImpl.AudioSessionProvider.AudioSession(101, 102, 103));
 
         int handle = module.loadModel(model);
         verify(mHalDriver).loadSoundModel(modelCaptor.capture(), callbackCaptor.capture());
         verify(mAudioSessionProvider).acquireSession();
-        TestUtil.validateGenericSoundModel_2_1(modelCaptor.getValue());
+        assertEquals(model, modelCaptor.getValue());
         return new Pair<>(handle, new SoundTriggerHwCallback(callbackCaptor.getValue()));
     }
 
-    private Pair<Integer, SoundTriggerHwCallback> loadPhraseModel(
-            ISoundTriggerModule module, int hwHandle) throws RemoteException {
+    private Pair<Integer, SoundTriggerHwCallback> loadPhraseModel(ISoundTriggerModule module,
+            int hwHandle) throws RemoteException {
         PhraseSoundModel model = TestUtil.createPhraseSoundModel();
-        ArgumentCaptor<android.hardware.soundtrigger.V2_1.ISoundTriggerHw.PhraseSoundModel>
-                modelCaptor = ArgumentCaptor.forClass(
-                android.hardware.soundtrigger.V2_1.ISoundTriggerHw.PhraseSoundModel.class);
-        ArgumentCaptor<ISoundTriggerHal.ModelCallback> callbackCaptor =
-                ArgumentCaptor.forClass(ISoundTriggerHal.ModelCallback.class);
+        ArgumentCaptor<PhraseSoundModel> modelCaptor = ArgumentCaptor.forClass(
+                PhraseSoundModel.class);
+        ArgumentCaptor<ISoundTriggerHal.ModelCallback> callbackCaptor = ArgumentCaptor.forClass(
+                ISoundTriggerHal.ModelCallback.class);
 
         when(mHalDriver.loadPhraseSoundModel(any(), any())).thenReturn(hwHandle);
         when(mAudioSessionProvider.acquireSession()).thenReturn(
@@ -107,7 +100,7 @@
         int handle = module.loadPhraseModel(model);
         verify(mHalDriver).loadPhraseSoundModel(modelCaptor.capture(), callbackCaptor.capture());
         verify(mAudioSessionProvider).acquireSession();
-        TestUtil.validatePhraseSoundModel_2_1(modelCaptor.getValue());
+        assertEquals(model, modelCaptor.getValue());
         return new Pair<>(handle, new SoundTriggerHwCallback(callbackCaptor.getValue()));
     }
 
@@ -118,17 +111,16 @@
         verify(mAudioSessionProvider).releaseSession(101);
     }
 
-    private void startRecognition(ISoundTriggerModule module, int handle,
-            int hwHandle) throws RemoteException {
-        ArgumentCaptor<android.hardware.soundtrigger.V2_3.RecognitionConfig>
-                configCaptor = ArgumentCaptor.forClass(
-                android.hardware.soundtrigger.V2_3.RecognitionConfig.class);
+    private void startRecognition(ISoundTriggerModule module, int handle, int hwHandle)
+            throws RemoteException {
+        ArgumentCaptor<RecognitionConfig> configCaptor = ArgumentCaptor.forClass(
+                RecognitionConfig.class);
 
         RecognitionConfig config = TestUtil.createRecognitionConfig();
 
         module.startRecognition(handle, config);
-        verify(mHalDriver).startRecognition(eq(hwHandle), configCaptor.capture());
-        TestUtil.validateRecognitionConfig_2_3(configCaptor.getValue(), 102, 103);
+        verify(mHalDriver).startRecognition(eq(hwHandle), eq(103), eq(102), configCaptor.capture());
+        assertEquals(config, configCaptor.getValue());
     }
 
     private void stopRecognition(ISoundTriggerModule module, int handle, int hwHandle)
@@ -141,8 +133,7 @@
     public void setUp() throws Exception {
         clearInvocations(mHalDriver);
         clearInvocations(mAudioSessionProvider);
-        when(mHalDriver.getProperties()).thenReturn(
-                TestUtil.createDefaultProperties_2_3(false));
+        when(mHalDriver.getProperties()).thenReturn(TestUtil.createDefaultProperties(false));
         mService = new SoundTriggerMiddlewareImpl(() -> mHalDriver, mAudioSessionProvider);
     }
 
@@ -164,8 +155,7 @@
         assertEquals(1, allDescriptors.length);
 
         Properties properties = allDescriptors[0].properties;
-
-        TestUtil.validateDefaultProperties(properties, false);
+        assertEquals(TestUtil.createDefaultProperties(false), properties);
     }
 
     @Test
@@ -249,7 +239,7 @@
 
         // Start the model.
         doThrow(new RecoverableException(Status.RESOURCE_CONTENTION)).when(
-                mHalDriver).startRecognition(eq(7), any());
+                mHalDriver).startRecognition(eq(7), eq(103), eq(102), any());
 
         try {
             RecognitionConfig config = TestUtil.createRecognitionConfig();
@@ -259,7 +249,7 @@
             assertEquals(Status.RESOURCE_CONTENTION, e.errorCode);
         }
 
-        verify(mHalDriver).startRecognition(eq(7), any());
+        verify(mHalDriver).startRecognition(eq(7), eq(103), eq(102), any());
     }
 
     @Test
@@ -297,15 +287,15 @@
         startRecognition(module, handle, hwHandle);
 
         // Signal a capture from the driver.
-        hwCallback.sendRecognitionEvent(hwHandle,
-                android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.RecognitionStatus.SUCCESS);
+        RecognitionEvent event = hwCallback.sendRecognitionEvent(hwHandle,
+                RecognitionStatus.SUCCESS);
 
         ArgumentCaptor<RecognitionEvent> eventCaptor = ArgumentCaptor.forClass(
                 RecognitionEvent.class);
         verify(callback).onRecognition(eq(handle), eventCaptor.capture(), eq(101));
 
         // Validate the event.
-        TestUtil.validateRecognitionEvent(eventCaptor.getValue(), RecognitionStatus.SUCCESS);
+        assertEquals(event, eventCaptor.getValue());
 
         // Unload the model.
         unloadModel(module, handle, hwHandle);
@@ -327,15 +317,15 @@
         startRecognition(module, handle, hwHandle);
 
         // Signal a capture from the driver.
-        hwCallback.sendPhraseRecognitionEvent(hwHandle,
-                android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.RecognitionStatus.SUCCESS);
+        PhraseRecognitionEvent event = hwCallback.sendPhraseRecognitionEvent(hwHandle,
+                RecognitionStatus.SUCCESS);
 
         ArgumentCaptor<PhraseRecognitionEvent> eventCaptor = ArgumentCaptor.forClass(
                 PhraseRecognitionEvent.class);
         verify(callback).onPhraseRecognition(eq(handle), eventCaptor.capture(), eq(101));
 
         // Validate the event.
-        TestUtil.validatePhraseRecognitionEvent(eventCaptor.getValue(), RecognitionStatus.SUCCESS);
+        assertEquals(event, eventCaptor.getValue());
 
         // Unload the model.
         unloadModel(module, handle, hwHandle);
@@ -358,18 +348,18 @@
 
         // Force a trigger.
         module.forceRecognitionEvent(handle);
-        verify(mHalDriver).getModelState(hwHandle);
+        verify(mHalDriver).forceRecognitionEvent(hwHandle);
 
         // Signal a capture from the driver.
-        // '3' means 'forced', there's no constant for that in the HAL.
-        hwCallback.sendRecognitionEvent(hwHandle, 3);
+        RecognitionEvent event = hwCallback.sendRecognitionEvent(hwHandle,
+                RecognitionStatus.FORCED);
 
         ArgumentCaptor<RecognitionEvent> eventCaptor = ArgumentCaptor.forClass(
                 RecognitionEvent.class);
         verify(callback).onRecognition(eq(handle), eventCaptor.capture(), eq(101));
 
         // Validate the event.
-        TestUtil.validateRecognitionEvent(eventCaptor.getValue(), RecognitionStatus.FORCED);
+        assertEquals(event, eventCaptor.getValue());
 
         // Stop the recognition.
         stopRecognition(module, handle, hwHandle);
@@ -394,7 +384,7 @@
 
         // Force a trigger.
         doThrow(new RecoverableException(Status.OPERATION_NOT_SUPPORTED)).when(
-                mHalDriver).getModelState(hwHandle);
+                mHalDriver).forceRecognitionEvent(hwHandle);
         try {
             module.forceRecognitionEvent(handle);
             fail("Expected an exception");
@@ -426,18 +416,18 @@
 
         // Force a trigger.
         module.forceRecognitionEvent(handle);
-        verify(mHalDriver).getModelState(hwHandle);
+        verify(mHalDriver).forceRecognitionEvent(hwHandle);
 
         // Signal a capture from the driver.
-        // '3' means 'forced', there's no constant for that in the HAL.
-        hwCallback.sendPhraseRecognitionEvent(hwHandle, 3);
+        PhraseRecognitionEvent event = hwCallback.sendPhraseRecognitionEvent(hwHandle,
+                RecognitionStatus.FORCED);
 
         ArgumentCaptor<PhraseRecognitionEvent> eventCaptor = ArgumentCaptor.forClass(
                 PhraseRecognitionEvent.class);
         verify(callback).onPhraseRecognition(eq(handle), eventCaptor.capture(), eq(101));
 
         // Validate the event.
-        TestUtil.validatePhraseRecognitionEvent(eventCaptor.getValue(), RecognitionStatus.FORCED);
+        assertEquals(event, eventCaptor.getValue());
 
         // Stop the recognition.
         stopRecognition(module, handle, hwHandle);
@@ -462,7 +452,7 @@
 
         // Force a trigger.
         doThrow(new RecoverableException(Status.OPERATION_NOT_SUPPORTED)).when(
-                mHalDriver).getModelState(hwHandle);
+                mHalDriver).forceRecognitionEvent(hwHandle);
         try {
             module.forceRecognitionEvent(handle);
             fail("Expected an exception");
@@ -494,7 +484,7 @@
         startRecognition(module, handle, hwHandle);
 
         // Abort.
-        hwCallback.sendRecognitionEvent(hwHandle, ISoundTriggerHwCallback.RecognitionStatus.ABORT);
+        hwCallback.sendRecognitionEvent(hwHandle, RecognitionStatus.ABORTED);
 
         ArgumentCaptor<RecognitionEvent> eventCaptor = ArgumentCaptor.forClass(
                 RecognitionEvent.class);
@@ -524,8 +514,7 @@
         startRecognition(module, handle, hwHandle);
 
         // Abort.
-        hwCallback.sendPhraseRecognitionEvent(hwHandle,
-                ISoundTriggerHwCallback.RecognitionStatus.ABORT);
+        hwCallback.sendPhraseRecognitionEvent(hwHandle, RecognitionStatus.ABORTED);
 
         ArgumentCaptor<PhraseRecognitionEvent> eventCaptor = ArgumentCaptor.forClass(
                 PhraseRecognitionEvent.class);
@@ -546,23 +535,19 @@
         final int hwHandle = 12;
         int modelHandle = loadGenericModel(module, hwHandle).first;
 
-        android.hardware.soundtrigger.V2_3.ModelParameterRange halRange =
-                new android.hardware.soundtrigger.V2_3.ModelParameterRange();
-        halRange.start = 23;
-        halRange.end = 45;
+        ModelParameterRange halRange = new ModelParameterRange();
+        halRange.minInclusive = 23;
+        halRange.maxInclusive = 45;
 
         when(mHalDriver.queryParameter(eq(hwHandle),
-                eq(android.hardware.soundtrigger.V2_3.ModelParameter.THRESHOLD_FACTOR))).thenReturn(
-                halRange);
+                eq(ModelParameter.THRESHOLD_FACTOR))).thenReturn(halRange);
 
         ModelParameterRange range = module.queryModelParameterSupport(modelHandle,
                 ModelParameter.THRESHOLD_FACTOR);
 
-        verify(mHalDriver).queryParameter(eq(hwHandle),
-                eq(android.hardware.soundtrigger.V2_3.ModelParameter.THRESHOLD_FACTOR));
+        verify(mHalDriver).queryParameter(eq(hwHandle), eq(ModelParameter.THRESHOLD_FACTOR));
 
-        assertEquals(23, range.minInclusive);
-        assertEquals(45, range.maxInclusive);
+        assertEquals(halRange, range);
     }
 
     @Test
@@ -573,14 +558,12 @@
         int modelHandle = loadGenericModel(module, hwHandle).first;
 
         when(mHalDriver.queryParameter(eq(hwHandle),
-                eq(android.hardware.soundtrigger.V2_3.ModelParameter.THRESHOLD_FACTOR))).thenReturn(
-                null);
+                eq(ModelParameter.THRESHOLD_FACTOR))).thenReturn(null);
 
         ModelParameterRange range = module.queryModelParameterSupport(modelHandle,
                 ModelParameter.THRESHOLD_FACTOR);
 
-        verify(mHalDriver).queryParameter(eq(hwHandle),
-                eq(android.hardware.soundtrigger.V2_3.ModelParameter.THRESHOLD_FACTOR));
+        verify(mHalDriver).queryParameter(eq(hwHandle), eq(ModelParameter.THRESHOLD_FACTOR));
 
         assertNull(range);
     }
@@ -592,14 +575,12 @@
         final int hwHandle = 14;
         int modelHandle = loadGenericModel(module, hwHandle).first;
 
-        when(mHalDriver.getModelParameter(hwHandle,
-                android.hardware.soundtrigger.V2_3.ModelParameter.THRESHOLD_FACTOR)).thenReturn(
+        when(mHalDriver.getModelParameter(hwHandle, ModelParameter.THRESHOLD_FACTOR)).thenReturn(
                 234);
 
         int value = module.getModelParameter(modelHandle, ModelParameter.THRESHOLD_FACTOR);
 
-        verify(mHalDriver).getModelParameter(hwHandle,
-                android.hardware.soundtrigger.V2_3.ModelParameter.THRESHOLD_FACTOR);
+        verify(mHalDriver).getModelParameter(hwHandle, ModelParameter.THRESHOLD_FACTOR);
 
         assertEquals(234, value);
     }
@@ -613,8 +594,7 @@
 
         module.setModelParameter(modelHandle, ModelParameter.THRESHOLD_FACTOR, 456);
 
-        verify(mHalDriver).setModelParameter(hwHandle,
-                android.hardware.soundtrigger.V2_3.ModelParameter.THRESHOLD_FACTOR, 456);
+        verify(mHalDriver).setModelParameter(hwHandle, ModelParameter.THRESHOLD_FACTOR, 456);
     }
 
     private static class SoundTriggerHwCallback {
@@ -624,14 +604,17 @@
             mCallback = callback;
         }
 
-        private void sendRecognitionEvent(int hwHandle, int status) {
-            mCallback.recognitionCallback(
-                    TestUtil.createRecognitionEvent_2_1(hwHandle, status));
+        private RecognitionEvent sendRecognitionEvent(int hwHandle, @RecognitionStatus int status) {
+            RecognitionEvent event = TestUtil.createRecognitionEvent(status);
+            mCallback.recognitionCallback(hwHandle, event);
+            return event;
         }
 
-        private void sendPhraseRecognitionEvent(int hwHandle, int status) {
-            mCallback.phraseRecognitionCallback(
-                    TestUtil.createPhraseRecognitionEvent_2_1(hwHandle, status));
+        private PhraseRecognitionEvent sendPhraseRecognitionEvent(int hwHandle,
+                @RecognitionStatus int status) {
+            PhraseRecognitionEvent event = TestUtil.createPhraseRecognitionEvent(status);
+            mCallback.phraseRecognitionCallback(hwHandle, event);
+            return event;
         }
 
         private void sendUnloadEvent(int hwHandle) {
diff --git a/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/TestUtil.java b/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/TestUtil.java
index 2cc806e..4eca298 100644
--- a/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/TestUtil.java
+++ b/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/TestUtil.java
@@ -20,11 +20,11 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
-import android.hardware.audio.common.V2_0.AudioConfig;
-import android.hardware.audio.common.V2_0.Uuid;
+import android.annotation.NonNull;
 import android.hardware.soundtrigger.V2_1.ISoundTriggerHw;
 import android.hardware.soundtrigger.V2_4.ISoundTriggerHwCallback;
 import android.media.audio.common.AudioChannelMask;
+import android.media.audio.common.AudioConfig;
 import android.media.audio.common.AudioFormat;
 import android.media.soundtrigger.AudioCapabilities;
 import android.media.soundtrigger.ConfidenceLevel;
@@ -36,6 +36,7 @@
 import android.media.soundtrigger.RecognitionConfig;
 import android.media.soundtrigger.RecognitionEvent;
 import android.media.soundtrigger.RecognitionMode;
+import android.media.soundtrigger.RecognitionStatus;
 import android.media.soundtrigger.SoundModel;
 import android.media.soundtrigger.SoundModelType;
 import android.os.HidlMemoryUtil;
@@ -51,12 +52,12 @@
  * Test utilities, aimed at generating populated objects of the various types and validating
  * corresponding objects generated by the system under test.
  */
-public class TestUtil {
-    public static SoundModel createGenericSoundModel() {
+class TestUtil {
+    static SoundModel createGenericSoundModel() {
         return createSoundModel(SoundModelType.GENERIC);
     }
 
-    private static SoundModel createSoundModel(int type) {
+    private static SoundModel createSoundModel(@SoundModelType int type) {
         SoundModel model = new SoundModel();
         model.type = type;
         model.uuid = "12345678-2345-3456-4567-abcdef987654";
@@ -67,10 +68,6 @@
         return model;
     }
 
-    public static ISoundTriggerHw.SoundModel createGenericSoundModel_2_1() {
-        return ConversionUtil.aidl2hidlSoundModel(createGenericSoundModel());
-    }
-
     private static void validateSoundModel_2_1(ISoundTriggerHw.SoundModel model, int type) {
         assertEquals(type, model.header.type);
         assertEquals("12345678-2345-3456-4567-abcdef987654",
@@ -91,16 +88,16 @@
         assertArrayEquals(new Byte[]{91, 92, 93, 94, 95}, model.data.toArray());
     }
 
-    public static void validateGenericSoundModel_2_1(ISoundTriggerHw.SoundModel model) {
+    static void validateGenericSoundModel_2_1(ISoundTriggerHw.SoundModel model) {
         validateSoundModel_2_1(model, android.hardware.soundtrigger.V2_0.SoundModelType.GENERIC);
     }
 
-    public static void validateGenericSoundModel_2_0(
+    static void validateGenericSoundModel_2_0(
             android.hardware.soundtrigger.V2_0.ISoundTriggerHw.SoundModel model) {
         validateSoundModel_2_0(model, android.hardware.soundtrigger.V2_0.SoundModelType.GENERIC);
     }
 
-    public static PhraseSoundModel createPhraseSoundModel() {
+    static PhraseSoundModel createPhraseSoundModel() {
         PhraseSoundModel model = new PhraseSoundModel();
         model.common = createSoundModel(SoundModelType.KEYPHRASE);
         model.phrases = new Phrase[1];
@@ -114,20 +111,20 @@
         return model;
     }
 
-    public static void validatePhraseSoundModel_2_1(ISoundTriggerHw.PhraseSoundModel model) {
+    static void validatePhraseSoundModel_2_1(ISoundTriggerHw.PhraseSoundModel model) {
         validateSoundModel_2_1(model.common,
                 android.hardware.soundtrigger.V2_0.SoundModelType.KEYPHRASE);
-        validatePhrases(model.phrases);
+        validatePhrases_2_0(model.phrases);
     }
 
-    public static void validatePhraseSoundModel_2_0(
+    static void validatePhraseSoundModel_2_0(
             android.hardware.soundtrigger.V2_0.ISoundTriggerHw.PhraseSoundModel model) {
         validateSoundModel_2_0(model.common,
                 android.hardware.soundtrigger.V2_0.SoundModelType.KEYPHRASE);
-        validatePhrases(model.phrases);
+        validatePhrases_2_0(model.phrases);
     }
 
-    private static void validatePhrases(
+    private static void validatePhrases_2_0(
             List<android.hardware.soundtrigger.V2_0.ISoundTriggerHw.Phrase> phrases) {
         assertEquals(1, phrases.size());
         assertEquals(123, phrases.get(0).id);
@@ -138,18 +135,13 @@
                 phrases.get(0).recognitionModes);
     }
 
-    public static ISoundTriggerHw.PhraseSoundModel createPhraseSoundModel_2_1() {
-        return ConversionUtil.aidl2hidlPhraseSoundModel(createPhraseSoundModel());
-    }
-
-    public static android.hardware.soundtrigger.V2_0.ISoundTriggerHw.Properties createDefaultProperties(
+    static android.hardware.soundtrigger.V2_0.ISoundTriggerHw.Properties createDefaultProperties_2_0(
             boolean supportConcurrentCapture) {
         android.hardware.soundtrigger.V2_0.ISoundTriggerHw.Properties properties =
                 new android.hardware.soundtrigger.V2_0.ISoundTriggerHw.Properties();
         properties.implementor = "implementor";
         properties.description = "description";
         properties.version = 123;
-        properties.uuid = new Uuid();
         properties.uuid.timeLow = 1;
         properties.uuid.timeMid = 2;
         properties.uuid.versionAndTimeHigh = 3;
@@ -172,11 +164,11 @@
         return properties;
     }
 
-    public static android.hardware.soundtrigger.V2_3.Properties createDefaultProperties_2_3(
+    static android.hardware.soundtrigger.V2_3.Properties createDefaultProperties_2_3(
             boolean supportConcurrentCapture) {
         android.hardware.soundtrigger.V2_3.Properties properties =
                 new android.hardware.soundtrigger.V2_3.Properties();
-        properties.base = createDefaultProperties(supportConcurrentCapture);
+        properties.base = createDefaultProperties_2_0(supportConcurrentCapture);
         properties.supportedModelArch = "supportedModelArch";
         properties.audioCapabilities =
                 android.hardware.soundtrigger.V2_3.AudioCapabilities.ECHO_CANCELLATION
@@ -184,8 +176,41 @@
         return properties;
     }
 
-    public static void validateDefaultProperties(Properties properties,
+    static Properties createDefaultProperties(boolean supportConcurrentCapture) {
+        Properties properties = new Properties();
+        properties.implementor = "implementor";
+        properties.description = "description";
+        properties.version = 123;
+        properties.uuid = "00000001-0002-0003-0004-05060708090a";
+        properties.maxSoundModels = 456;
+        properties.maxKeyPhrases = 567;
+        properties.maxUsers = 678;
+        properties.recognitionModes =
+                RecognitionMode.VOICE_TRIGGER
+                        | RecognitionMode.USER_IDENTIFICATION
+                        | RecognitionMode.USER_AUTHENTICATION
+                        | RecognitionMode.GENERIC_TRIGGER;
+        properties.captureTransition = true;
+        properties.maxBufferMs = 321;
+        properties.concurrentCapture = supportConcurrentCapture;
+        properties.triggerInEvent = true;
+        properties.powerConsumptionMw = 432;
+        properties.supportedModelArch = "supportedModelArch";
+        properties.audioCapabilities = AudioCapabilities.ECHO_CANCELLATION
+                | AudioCapabilities.NOISE_SUPPRESSION;
+        return properties;
+    }
+
+    static void validateDefaultProperties(Properties properties,
             boolean supportConcurrentCapture) {
+        validateDefaultProperties(properties, supportConcurrentCapture,
+                AudioCapabilities.ECHO_CANCELLATION | AudioCapabilities.NOISE_SUPPRESSION,
+                "supportedModelArch");
+    }
+
+    static void validateDefaultProperties(Properties properties,
+            boolean supportConcurrentCapture, @AudioCapabilities int audioCapabilities,
+            @NonNull String supportedModelArch) {
         assertEquals("implementor", properties.implementor);
         assertEquals("description", properties.description);
         assertEquals(123, properties.version);
@@ -202,12 +227,11 @@
         assertEquals(supportConcurrentCapture, properties.concurrentCapture);
         assertTrue(properties.triggerInEvent);
         assertEquals(432, properties.powerConsumptionMw);
-        assertEquals("supportedModelArch", properties.supportedModelArch);
-        assertEquals(AudioCapabilities.ECHO_CANCELLATION | AudioCapabilities.NOISE_SUPPRESSION,
-                properties.audioCapabilities);
+        assertEquals(supportedModelArch, properties.supportedModelArch);
+        assertEquals(audioCapabilities, properties.audioCapabilities);
     }
 
-    public static RecognitionConfig createRecognitionConfig() {
+    static RecognitionConfig createRecognitionConfig() {
         RecognitionConfig config = new RecognitionConfig();
         config.captureRequested = true;
         config.phraseRecognitionExtras = new PhraseRecognitionExtra[]{new PhraseRecognitionExtra()};
@@ -223,18 +247,9 @@
         return config;
     }
 
-    public static android.hardware.soundtrigger.V2_3.RecognitionConfig createRecognitionConfig_2_3(
-            int captureHandle, int captureDevice) {
-        android.hardware.soundtrigger.V2_3.RecognitionConfig config =
-                ConversionUtil.aidl2hidlRecognitionConfig(createRecognitionConfig());
-        config.base.header.captureDevice = captureDevice;
-        config.base.header.captureHandle = captureHandle;
-        return config;
-    }
-
-    public static void validateRecognitionConfig_2_0(
+    static void validateRecognitionConfig_2_0(
             android.hardware.soundtrigger.V2_0.ISoundTriggerHw.RecognitionConfig config,
-            int captureHandle, int captureDevice) {
+            int captureDevice, int captureHandle) {
         assertTrue(config.captureRequested);
         assertEquals(captureDevice, config.captureDevice);
         assertEquals(captureHandle, config.captureHandle);
@@ -251,9 +266,9 @@
         assertArrayEquals(new Byte[]{5, 4, 3, 2, 1}, config.data.toArray());
     }
 
-    public static void validateRecognitionConfig_2_1(
+    static void validateRecognitionConfig_2_1(
             android.hardware.soundtrigger.V2_1.ISoundTriggerHw.RecognitionConfig config,
-            int captureHandle, int captureDevice) {
+            int captureDevice, int captureHandle) {
         assertTrue(config.header.captureRequested);
         assertEquals(captureDevice, config.header.captureDevice);
         assertEquals(captureHandle, config.header.captureHandle);
@@ -271,16 +286,16 @@
                 HidlMemoryUtil.hidlMemoryToByteArray(config.data));
     }
 
-    public static void validateRecognitionConfig_2_3(
-            android.hardware.soundtrigger.V2_3.RecognitionConfig config, int captureHandle,
-            int captureDevice) {
-        validateRecognitionConfig_2_1(config.base, captureHandle, captureDevice);
+    static void validateRecognitionConfig_2_3(
+            android.hardware.soundtrigger.V2_3.RecognitionConfig config, int captureDevice,
+            int captureHandle) {
+        validateRecognitionConfig_2_1(config.base, captureDevice, captureHandle);
 
         assertEquals(AudioCapabilities.ECHO_CANCELLATION
                 | AudioCapabilities.NOISE_SUPPRESSION, config.audioCapabilities);
     }
 
-    public static android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.RecognitionEvent createRecognitionEvent_2_0(
+    static android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.RecognitionEvent createRecognitionEvent_2_0(
             int hwHandle,
             int status) {
         android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.RecognitionEvent halEvent =
@@ -294,7 +309,6 @@
         halEvent.captureDelayMs = 234;
         halEvent.capturePreambleMs = 345;
         halEvent.triggerInData = true;
-        halEvent.audioConfig = new AudioConfig();
         halEvent.audioConfig.sampleRateHz = 456;
         halEvent.audioConfig.channelMask = AudioChannelMask.IN_LEFT;
         halEvent.audioConfig.format = AudioFormat.MP3;
@@ -305,7 +319,24 @@
         return halEvent;
     }
 
-    public static ISoundTriggerHwCallback.RecognitionEvent createRecognitionEvent_2_1(
+    static RecognitionEvent createRecognitionEvent(@RecognitionStatus int status) {
+        RecognitionEvent event = new RecognitionEvent();
+        event.status = status;
+        event.type = SoundModelType.GENERIC;
+        event.captureAvailable = true;
+        event.captureDelayMs = 234;
+        event.capturePreambleMs = 345;
+        event.triggerInData = true;
+        event.audioConfig = new AudioConfig();
+        event.audioConfig.sampleRateHz = 456;
+        event.audioConfig.channelMask = AudioChannelMask.IN_LEFT;
+        event.audioConfig.format = AudioFormat.MP3;
+        //event.audioConfig.offloadInfo is irrelevant.
+        event.data = new byte[]{31, 32, 33};
+        return event;
+    }
+
+    static ISoundTriggerHwCallback.RecognitionEvent createRecognitionEvent_2_1(
             int hwHandle,
             int status) {
         ISoundTriggerHwCallback.RecognitionEvent halEvent =
@@ -316,7 +347,7 @@
         return halEvent;
     }
 
-    public static void validateRecognitionEvent(RecognitionEvent event, int status) {
+    static void validateRecognitionEvent(RecognitionEvent event, @RecognitionStatus int status) {
         assertEquals(status, event.status);
         assertEquals(SoundModelType.GENERIC, event.type);
         assertTrue(event.captureAvailable);
@@ -329,24 +360,24 @@
         assertArrayEquals(new byte[]{31, 32, 33}, event.data);
     }
 
-    public static void validateRecognitionEvent_2_1(
-            android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.RecognitionEvent event,
-            int hwHandle,
-            int status) {
-        assertEquals(status, event.header.status);
-        assertEquals(hwHandle, event.header.model);
-        assertEquals(SoundModelType.GENERIC, event.header.type);
-        assertTrue(event.header.captureAvailable);
-        assertEquals(234, event.header.captureDelayMs);
-        assertEquals(345, event.header.capturePreambleMs);
-        assertTrue(event.header.triggerInData);
-        assertEquals(456, event.header.audioConfig.sampleRateHz);
-        assertEquals(AudioChannelMask.IN_LEFT, event.header.audioConfig.channelMask);
-        assertEquals(AudioFormat.MP3, event.header.audioConfig.format);
-        assertArrayEquals(new byte[]{31, 32, 33}, HidlMemoryUtil.hidlMemoryToByteArray(event.data));
+    static PhraseRecognitionEvent createPhraseRecognitionEvent(@RecognitionStatus int status) {
+        PhraseRecognitionEvent event = new PhraseRecognitionEvent();
+        event.common = createRecognitionEvent(status);
+
+        PhraseRecognitionExtra extra = new PhraseRecognitionExtra();
+        extra.id = 123;
+        extra.confidenceLevel = 52;
+        extra.recognitionModes = RecognitionMode.VOICE_TRIGGER
+                | RecognitionMode.GENERIC_TRIGGER;
+        ConfidenceLevel level = new ConfidenceLevel();
+        level.userId = 31;
+        level.levelPercent = 43;
+        extra.levels = new ConfidenceLevel[]{level};
+        event.phraseExtras = new PhraseRecognitionExtra[]{extra};
+        return event;
     }
 
-    public static android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.PhraseRecognitionEvent
+    static android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.PhraseRecognitionEvent
     createPhraseRecognitionEvent_2_0(int hwHandle, int status) {
         android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.PhraseRecognitionEvent halEvent =
                 new android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.PhraseRecognitionEvent();
@@ -367,7 +398,7 @@
         return halEvent;
     }
 
-    public static ISoundTriggerHwCallback.PhraseRecognitionEvent createPhraseRecognitionEvent_2_1(
+    static ISoundTriggerHwCallback.PhraseRecognitionEvent createPhraseRecognitionEvent_2_1(
             int hwHandle, int status) {
         ISoundTriggerHwCallback.PhraseRecognitionEvent halEvent =
                 new ISoundTriggerHwCallback.PhraseRecognitionEvent();
@@ -388,7 +419,8 @@
         return halEvent;
     }
 
-    public static void validatePhraseRecognitionEvent(PhraseRecognitionEvent event, int status) {
+    static void validatePhraseRecognitionEvent(PhraseRecognitionEvent event,
+            @RecognitionStatus int status) {
         validateRecognitionEvent(event.common, status);
 
         assertEquals(1, event.phraseExtras.length);
@@ -401,21 +433,6 @@
         assertEquals(43, event.phraseExtras[0].levels[0].levelPercent);
     }
 
-    public static void validatePhraseRecognitionEvent_2_1(
-            android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.PhraseRecognitionEvent event,
-            int handle, int status) {
-        validateRecognitionEvent_2_1(event.common, handle, status);
-
-        assertEquals(1, event.phraseExtras.size());
-        assertEquals(123, event.phraseExtras.get(0).id);
-        assertEquals(52, event.phraseExtras.get(0).confidenceLevel);
-        assertEquals(RecognitionMode.VOICE_TRIGGER | RecognitionMode.GENERIC_TRIGGER,
-                event.phraseExtras.get(0).recognitionModes);
-        assertEquals(1, event.phraseExtras.get(0).levels.size());
-        assertEquals(31, event.phraseExtras.get(0).levels.get(0).userId);
-        assertEquals(43, event.phraseExtras.get(0).levels.get(0).levelPercent);
-    }
-
     private static FileDescriptor byteArrayToFileDescriptor(byte[] data) {
         try {
             SharedMemory shmem = SharedMemory.create("", data.length);