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

Commit 9d0194cb authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "SoundTrigger test cleanup" into udc-dev

parents 4e471917 49172857
Loading
Loading
Loading
Loading
+99 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.soundtrigger;

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.soundtrigger.ConversionUtil;
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";

    @Test
    public void testDefaultAudioFormatConstruction() {
        // This method should generate a real format when passed null
        final var format = aidl2apiAudioFormatWithDefault(
                null /** exercise default **/,
                true /** isInput **/
                );
        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)));
    }
}
+35 −19
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@
 * limitations under the License.
 */

package android.hardware.soundtrigger;
package com.android.server.soundtrigger;

import android.hardware.soundtrigger.SoundTrigger.ConfidenceLevel;
import android.hardware.soundtrigger.SoundTrigger.Keyphrase;
@@ -22,6 +22,7 @@ import android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionEvent;
import android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionExtra;
import android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel;
import android.hardware.soundtrigger.SoundTrigger.RecognitionEvent;
import android.hardware.soundtrigger.SoundTrigger;
import android.media.AudioFormat;
import android.os.Parcel;
import android.test.InstrumentationTestCase;
@@ -50,10 +51,7 @@ public class SoundTriggerTest extends InstrumentationTestCase {
        Keyphrase unparceled = Keyphrase.CREATOR.createFromParcel(parcel);

        // Verify that they are the same
        assertEquals(keyphrase.getId(), unparceled.getId());
        assertNull(unparceled.getUsers());
        assertEquals(keyphrase.getLocale(), unparceled.getLocale());
        assertEquals(keyphrase.getText(), unparceled.getText());
        assertEquals(keyphrase, unparceled);
    }

    @SmallTest
@@ -115,10 +113,7 @@ public class SoundTriggerTest extends InstrumentationTestCase {
        KeyphraseSoundModel unparceled = KeyphraseSoundModel.CREATOR.createFromParcel(parcel);

        // Verify that they are the same
        assertEquals(ksm.getUuid(), unparceled.getUuid());
        assertNull(unparceled.getData());
        assertEquals(ksm.getType(), unparceled.getType());
        assertTrue(Arrays.equals(keyphrases, unparceled.getKeyphrases()));
        assertEquals(ksm, unparceled);
    }

    @SmallTest
@@ -162,10 +157,7 @@ public class SoundTriggerTest extends InstrumentationTestCase {
        KeyphraseSoundModel unparceled = KeyphraseSoundModel.CREATOR.createFromParcel(parcel);

        // Verify that they are the same
        assertEquals(ksm.getUuid(), unparceled.getUuid());
        assertEquals(ksm.getType(), unparceled.getType());
        assertNull(unparceled.getKeyphrases());
        assertTrue(Arrays.equals(ksm.getData(), unparceled.getData()));
        assertEquals(ksm, unparceled);
    }

    @SmallTest
@@ -226,7 +218,11 @@ public class SoundTriggerTest extends InstrumentationTestCase {
                3 /* captureDelayMs */,
                4 /* capturePreambleMs */,
                false /* triggerInData */,
                null /* captureFormat */,
                new AudioFormat.Builder()
                        .setSampleRate(16000)
                        .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
                        .setChannelMask(AudioFormat.CHANNEL_IN_MONO)
                        .build(),
                null /* data */,
                12345678 /* halEventReceivedMillis */);

@@ -251,7 +247,11 @@ public class SoundTriggerTest extends InstrumentationTestCase {
                3 /* captureDelayMs */,
                4 /* capturePreambleMs */,
                false /* triggerInData */,
                null /* captureFormat */,
                new AudioFormat.Builder()
                        .setSampleRate(16000)
                        .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
                        .setChannelMask(AudioFormat.CHANNEL_IN_MONO)
                        .build(),
                new byte[1] /* data */,
                12345678 /* halEventReceivedMillis */);

@@ -278,7 +278,11 @@ public class SoundTriggerTest extends InstrumentationTestCase {
                3 /* captureDelayMs */,
                4 /* capturePreambleMs */,
                false /* triggerInData */,
                null /* captureFormat */,
                new AudioFormat.Builder()
                        .setSampleRate(16000)
                        .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
                        .setChannelMask(AudioFormat.CHANNEL_IN_MONO)
                        .build(),
                data,
                12345678 /* halEventReceivedMillis */);

@@ -335,7 +339,11 @@ public class SoundTriggerTest extends InstrumentationTestCase {
                3 /* captureDelayMs */,
                4 /* capturePreambleMs */,
                false /* triggerInData */,
                null /* captureFormat */,
                new AudioFormat.Builder()
                        .setSampleRate(16000)
                        .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
                        .setChannelMask(AudioFormat.CHANNEL_IN_MONO)
                        .build(),
                null /* data */,
                null /* keyphraseExtras */,
                12345678 /* halEventReceivedMillis */);
@@ -364,7 +372,11 @@ public class SoundTriggerTest extends InstrumentationTestCase {
                3 /* captureDelayMs */,
                4 /* capturePreambleMs */,
                false /* triggerInData */,
                null /* captureFormat */,
                new AudioFormat.Builder()
                        .setSampleRate(16000)
                        .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
                        .setChannelMask(AudioFormat.CHANNEL_IN_MONO)
                        .build(),
                new byte[1] /* data */,
                kpExtra,
                12345678 /* halEventReceivedMillis */);
@@ -409,7 +421,11 @@ public class SoundTriggerTest extends InstrumentationTestCase {
                3 /* captureDelayMs */,
                4 /* capturePreambleMs */,
                false /* triggerInData */,
                null /* captureFormat */,
                new AudioFormat.Builder()
                        .setSampleRate(16000)
                        .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
                        .setChannelMask(AudioFormat.CHANNEL_IN_MONO)
                        .build(),
                data,
                kpExtra,
                12345678 /* halEventReceivedMillis */);
+1 −69
Original line number Diff line number Diff line
@@ -16,36 +16,18 @@

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";
    private static final String TAG = "SoundTriggerMiddlewareConversionUtilTest";

    @Test
    public void testUuidRoundTrip() {
@@ -62,54 +44,4 @@ public class ConversionUtilTest {
        Uuid reconstructed = ConversionUtil.aidl2hidlUuid(aidl);
        assertEquals(hidl, reconstructed);
    }

    @Test
    public void testDefaultAudioFormatConstruction() {
        // This method should generate a real format when passed null
        final var format = aidl2apiAudioFormatWithDefault(
                null /** exercise default **/,
                true /** isInput **/
                );
        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)));
    }
}
+0 −39
Original line number Diff line number Diff line
#
# Copyright (C) 2014 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := tests

ifeq ($(SOUND_TRIGGER_USE_STUB_MODULE), 1)
  LOCAL_SRC_FILES := $(call all-subdir-java-files)
  LOCAL_PRIVILEGED_MODULE := true
  LOCAL_CERTIFICATE := platform
  TARGET_OUT_DATA_APPS_PRIVILEGED := $(TARGET_OUT_DATA)/priv-app
else
  LOCAL_SRC_FILES := src/android/hardware/soundtrigger/SoundTriggerTest.java
endif

LOCAL_STATIC_JAVA_LIBRARIES := mockito-target
LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base

LOCAL_PACKAGE_NAME := SoundTriggerTests
LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
LOCAL_LICENSE_CONDITIONS := notice
LOCAL_NOTICE_FILE  := $(LOCAL_PATH)/../../NOTICE
LOCAL_PRIVATE_PLATFORM_APIS := true

include $(BUILD_PACKAGE)
+0 −29
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2014 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="android.hardware.soundtrigger">
    <uses-permission android:name="android.permission.MANAGE_SOUND_TRIGGER" />
    <uses-permission android:name="android.permission.INTERNET" />
    
    <application>
        <uses-library android:name="android.test.runner" />
    </application>

    <instrumentation android:name="android.test.InstrumentationTestRunner"
                     android:targetPackage="android.hardware.soundtrigger"
                     android:label="Tests for android.hardware.soundtrigger" />
</manifest>
Loading