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

Commit 21c80c8e authored by Atneya Nair's avatar Atneya Nair
Browse files

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
parent 123492f4
Loading
Loading
Loading
Loading
+41 −1
Original line number Diff line number Diff line
@@ -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);
        }
    }
}
+39 −0
Original line number Diff line number Diff line
@@ -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;
        }
    }

    /**
+55 −0
Original line number Diff line number Diff line
@@ -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)));
    }
}