diff options
| author | 2023-03-01 14:57:55 -0800 | |
|---|---|---|
| committer | 2023-03-10 15:23:46 -0800 | |
| commit | 21c80c8ec7d660ac2f152e560190ece533b76217 (patch) | |
| tree | 49d04ef2313eb50432e89d9ea59198e38ea4dbe7 | |
| parent | 123492f470f601431ac953e38a8feb81334ed7f1 (diff) | |
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
3 files changed, 135 insertions, 1 deletions
diff --git a/core/java/android/hardware/soundtrigger/ConversionUtil.java b/core/java/android/hardware/soundtrigger/ConversionUtil.java index be57bbee2273..58e7f01b2b08 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.RecognitionMode; 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 @@ public class ConversionUtil { 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 @@ public class ConversionUtil { 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 @@ public class ConversionUtil { 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 @@ public class ConversionUtil { 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 b7a694c14e99..e63f57b5224c 100644 --- a/core/java/android/hardware/soundtrigger/SoundTrigger.java +++ b/core/java/android/hardware/soundtrigger/SoundTrigger.java @@ -1493,6 +1493,45 @@ public class SoundTrigger { + 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 07998595751a..5661b1288345 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 @@ public class ConversionUtilTest { ); 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))); + } } |