Add additional conversion to ST for testing
Testing ST requires converting AIDL types back to API to pass
to the test client.
Add equals to RecognitionConfig.
Bug: 271330425
Test: atest ConversionUtilTest
Change-Id: I98336ac664a1a264835110a34d20b73f430d5de8
diff --git a/core/java/android/hardware/soundtrigger/ConversionUtil.java b/core/java/android/hardware/soundtrigger/ConversionUtil.java
index be57bbe..58e7f01 100644
--- a/core/java/android/hardware/soundtrigger/ConversionUtil.java
+++ b/core/java/android/hardware/soundtrigger/ConversionUtil.java
@@ -34,10 +34,12 @@
import android.media.soundtrigger.SoundModel;
import android.media.soundtrigger_middleware.SoundTriggerModuleDescriptor;
import android.os.ParcelFileDescriptor;
+import android.system.ErrnoException;
import android.os.SharedMemory;
import java.nio.ByteBuffer;
import java.util.Arrays;
+import java.util.Locale;
import java.util.UUID;
/** @hide */
@@ -140,6 +142,14 @@
return aidlPhrase;
}
+ public static SoundTrigger.Keyphrase aidl2apiPhrase(Phrase aidlPhrase) {
+ return new SoundTrigger.Keyphrase(aidlPhrase.id,
+ aidl2apiRecognitionModes(aidlPhrase.recognitionModes),
+ new Locale.Builder().setLanguageTag(aidlPhrase.locale).build(),
+ aidlPhrase.text,
+ Arrays.copyOf(aidlPhrase.users, aidlPhrase.users.length));
+ }
+
public static RecognitionConfig api2aidlRecognitionConfig(
SoundTrigger.RecognitionConfig apiConfig) {
RecognitionConfig aidlConfig = new RecognitionConfig();
@@ -156,6 +166,21 @@
return aidlConfig;
}
+ public static SoundTrigger.RecognitionConfig aidl2apiRecognitionConfig(
+ RecognitionConfig aidlConfig) {
+ var keyphrases =
+ new SoundTrigger.KeyphraseRecognitionExtra[aidlConfig.phraseRecognitionExtras.length];
+ int i = 0;
+ for (var extras : aidlConfig.phraseRecognitionExtras) {
+ keyphrases[i++] = aidl2apiPhraseRecognitionExtra(extras);
+ }
+ return new SoundTrigger.RecognitionConfig(aidlConfig.captureRequested,
+ false /** allowMultipleTriggers **/,
+ keyphrases,
+ Arrays.copyOf(aidlConfig.data, aidlConfig.data.length),
+ aidl2apiAudioCapabilities(aidlConfig.audioCapabilities));
+ }
+
public static PhraseRecognitionExtra api2aidlPhraseRecognitionExtra(
SoundTrigger.KeyphraseRecognitionExtra apiExtra) {
PhraseRecognitionExtra aidlExtra = new PhraseRecognitionExtra();
@@ -281,7 +306,7 @@
return result;
}
- private static @Nullable ParcelFileDescriptor byteArrayToSharedMemory(byte[] data, String name) {
+ public static @Nullable ParcelFileDescriptor byteArrayToSharedMemory(byte[] data, String name) {
if (data.length == 0) {
return null;
}
@@ -298,4 +323,19 @@
throw new RuntimeException(e);
}
}
+
+ public static byte[] sharedMemoryToByteArray(@Nullable ParcelFileDescriptor pfd, int size) {
+ if (pfd == null || size == 0) {
+ return new byte[0];
+ }
+ try (SharedMemory mem = SharedMemory.fromFileDescriptor(pfd)) {
+ ByteBuffer buffer = mem.mapReadOnly();
+ byte[] data = new byte[(size > mem.getSize()) ? mem.getSize() : size];
+ buffer.get(data);
+ mem.unmap(buffer);
+ return data;
+ } catch (ErrnoException e) {
+ throw new RuntimeException(e);
+ }
+ }
}
diff --git a/core/java/android/hardware/soundtrigger/SoundTrigger.java b/core/java/android/hardware/soundtrigger/SoundTrigger.java
index b7a694c..e63f57b 100644
--- a/core/java/android/hardware/soundtrigger/SoundTrigger.java
+++ b/core/java/android/hardware/soundtrigger/SoundTrigger.java
@@ -1493,6 +1493,45 @@
+ Arrays.toString(keyphrases) + ", data=" + Arrays.toString(data)
+ ", audioCapabilities=" + Integer.toHexString(audioCapabilities) + "]";
}
+
+ @Override
+ public final boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (!(obj instanceof RecognitionConfig))
+ return false;
+ RecognitionConfig other = (RecognitionConfig) obj;
+ if (captureRequested != other.captureRequested) {
+ return false;
+ }
+ if (allowMultipleTriggers != other.allowMultipleTriggers) {
+ return false;
+ }
+ if (!Arrays.equals(keyphrases, other.keyphrases)) {
+ return false;
+ }
+ if (!Arrays.equals(data, other.data)) {
+ return false;
+ }
+ if (audioCapabilities != other.audioCapabilities) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public final int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + (captureRequested ? 1 : 0);
+ result = prime * result + (allowMultipleTriggers ? 1 : 0);
+ result = prime * result + Arrays.hashCode(keyphrases);
+ result = prime * result + Arrays.hashCode(data);
+ result = prime * result + audioCapabilities;
+ return result;
+ }
}
/**
diff --git a/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger_middleware/ConversionUtilTest.java b/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger_middleware/ConversionUtilTest.java
index 0799859..5661b12 100644
--- a/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger_middleware/ConversionUtilTest.java
+++ b/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger_middleware/ConversionUtilTest.java
@@ -17,17 +17,32 @@
package com.android.server.soundtrigger_middleware;
import static android.hardware.soundtrigger.ConversionUtil.aidl2apiAudioFormatWithDefault;
+import static android.hardware.soundtrigger.ConversionUtil.aidl2apiPhrase;
+import static android.hardware.soundtrigger.ConversionUtil.aidl2apiRecognitionConfig;
+import static android.hardware.soundtrigger.ConversionUtil.api2aidlPhrase;
+import static android.hardware.soundtrigger.ConversionUtil.api2aidlRecognitionConfig;
+import static android.hardware.soundtrigger.ConversionUtil.byteArrayToSharedMemory;
+import static android.hardware.soundtrigger.ConversionUtil.sharedMemoryToByteArray;
+import static android.hardware.soundtrigger.SoundTrigger.ConfidenceLevel;
+import static android.hardware.soundtrigger.SoundTrigger.RECOGNITION_MODE_GENERIC;
+import static android.hardware.soundtrigger.SoundTrigger.RECOGNITION_MODE_USER_AUTHENTICATION;
+import static android.hardware.soundtrigger.SoundTrigger.RECOGNITION_MODE_USER_IDENTIFICATION;
+import static android.hardware.soundtrigger.SoundTrigger.RECOGNITION_MODE_VOICE_TRIGGER;
+import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import android.hardware.audio.common.V2_0.Uuid;
+import android.hardware.soundtrigger.SoundTrigger;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.Locale;
+
@RunWith(AndroidJUnit4.class)
public class ConversionUtilTest {
private static final String TAG = "ConversionUtilTest";
@@ -57,4 +72,44 @@
);
assertNotNull(format);
}
+
+ @Test
+ public void testRecognitionConfigRoundTrip() {
+ final int flags = SoundTrigger.ModuleProperties.AUDIO_CAPABILITY_ECHO_CANCELLATION
+ | SoundTrigger.ModuleProperties.AUDIO_CAPABILITY_NOISE_SUPPRESSION;
+ final var data = new byte[] {0x11, 0x22};
+ final var keyphrases = new SoundTrigger.KeyphraseRecognitionExtra[2];
+ keyphrases[0] = new SoundTrigger.KeyphraseRecognitionExtra(99,
+ RECOGNITION_MODE_VOICE_TRIGGER | RECOGNITION_MODE_USER_IDENTIFICATION, 13,
+ new ConfidenceLevel[] {new ConfidenceLevel(9999, 50),
+ new ConfidenceLevel(5000, 80)});
+ keyphrases[1] = new SoundTrigger.KeyphraseRecognitionExtra(101,
+ RECOGNITION_MODE_GENERIC, 8, new ConfidenceLevel[] {
+ new ConfidenceLevel(7777, 30),
+ new ConfidenceLevel(2222, 60)});
+
+ var apiconfig = new SoundTrigger.RecognitionConfig(true, false /** must be false **/,
+ keyphrases, data, flags);
+ assertEquals(apiconfig, aidl2apiRecognitionConfig(api2aidlRecognitionConfig(apiconfig)));
+ }
+
+ @Test
+ public void testByteArraySharedMemRoundTrip() {
+ final var data = new byte[] { 0x11, 0x22, 0x33, 0x44,
+ (byte) 0xde, (byte) 0xad, (byte) 0xbe, (byte) 0xef };
+ assertArrayEquals(data, sharedMemoryToByteArray(byteArrayToSharedMemory(data, "name"),
+ 10000000));
+
+ }
+
+ @Test
+ public void testPhraseRoundTrip() {
+ final var users = new int[] {10001, 10002};
+ final var apiphrase = new SoundTrigger.Keyphrase(17 /** id **/,
+ RECOGNITION_MODE_VOICE_TRIGGER | RECOGNITION_MODE_USER_AUTHENTICATION,
+ Locale.forLanguageTag("no_NO"),
+ "Hello Android", /** keyphrase **/
+ users);
+ assertEquals(apiphrase, aidl2apiPhrase(api2aidlPhrase(apiphrase)));
+ }
}