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

Commit d5065ba8 authored by Ytai Ben-Tsvi's avatar Ytai Ben-Tsvi
Browse files

Pass models to soundtrigger middleware with shared memory

This both avoids the need to make extra copied for the models and
allows exceeding the parcel size limits.

Bug: 150100907
Test: Manual testing of basic sound trigger functionality
Change-Id: Ic4c5c1a9de3e29b1b6fa82442254e1afe7daec19
parent 5688bc3e
Loading
Loading
Loading
Loading
+22 −1
Original line number Diff line number Diff line
@@ -32,7 +32,11 @@ import android.media.soundtrigger_middleware.RecognitionMode;
import android.media.soundtrigger_middleware.SoundModel;
import android.media.soundtrigger_middleware.SoundTriggerModuleDescriptor;
import android.media.soundtrigger_middleware.SoundTriggerModuleProperties;
import android.os.SharedMemory;
import android.system.ErrnoException;

import java.io.FileDescriptor;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.UUID;

@@ -105,7 +109,8 @@ class ConversionUtil {
        aidlModel.type = apiModel.type;
        aidlModel.uuid = api2aidlUuid(apiModel.uuid);
        aidlModel.vendorUuid = api2aidlUuid(apiModel.vendorUuid);
        aidlModel.data = Arrays.copyOf(apiModel.data, apiModel.data.length);
        aidlModel.data = byteArrayToSharedMemory(apiModel.data, "SoundTrigger SoundModel");
        aidlModel.dataSize = apiModel.data.length;
        return aidlModel;
    }

@@ -352,4 +357,20 @@ class ConversionUtil {
        }
        return result;
    }

    private static @Nullable FileDescriptor byteArrayToSharedMemory(byte[] data, String name) {
        if (data.length == 0) {
            return null;
        }

        try {
            SharedMemory shmem = SharedMemory.create(name != null ? name : "", data.length);
            ByteBuffer buffer = shmem.mapReadWrite();
            buffer.put(data);
            shmem.unmap(buffer);
            return shmem.getFileDescriptor();
        } catch (ErrnoException e) {
            throw new RuntimeException(e);
        }
    }
}
+35 −6
Original line number Diff line number Diff line
@@ -21,14 +21,13 @@ import static android.system.OsConstants.PROT_READ;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.system.ErrnoException;
import android.system.Os;
import android.util.Log;

import com.android.internal.util.Preconditions;

import java.io.FileDescriptor;
import java.nio.ByteBuffer;
import java.nio.DirectByteBuffer;
import java.util.ArrayList;
@@ -82,8 +81,7 @@ public final class HidlMemoryUtil {
            ByteBuffer buffer = shmem.mapReadWrite();
            buffer.put(input);
            shmem.unmap(buffer);
            NativeHandle handle = new NativeHandle(shmem.getFileDescriptor(), true);
            return new HidlMemory("ashmem", input.length, handle);
            return sharedMemoryToHidlMemory(shmem);
        } catch (ErrnoException e) {
            throw new RuntimeException(e);
        }
@@ -128,8 +126,7 @@ public final class HidlMemoryUtil {
                buffer.put(b);
            }
            shmem.unmap(buffer);
            NativeHandle handle = new NativeHandle(shmem.getFileDescriptor(), true);
            return new HidlMemory("ashmem", input.size(), handle);
            return sharedMemoryToHidlMemory(shmem);
        } catch (ErrnoException e) {
            throw new RuntimeException(e);
        }
@@ -189,6 +186,38 @@ public final class HidlMemoryUtil {
        return result;
    }

    /**
     * Converts a SharedMemory to a HidlMemory without copying.
     *
     * @param shmem The shared memory object. Null means "empty" and will still result in a non-null
     *              return value.
     * @return The HidlMemory instance.
     */
    @NonNull public static HidlMemory sharedMemoryToHidlMemory(@Nullable SharedMemory shmem) {
        if (shmem == null) {
            return new HidlMemory("ashmem", 0, null);
        }
        return fileDescriptorToHidlMemory(shmem.getFileDescriptor(), shmem.getSize());
    }

    /**
     * Converts a FileDescriptor to a HidlMemory without copying.
     *
     * @param fd   The FileDescriptor object. Null is allowed if size is 0 and will still result in
     *             a non-null return value.
     * @param size The size of the memory buffer.
     * @return The HidlMemory instance.
     */
    @NonNull public static HidlMemory fileDescriptorToHidlMemory(@Nullable FileDescriptor fd,
            int size) {
        Preconditions.checkArgument(fd != null || size == 0);
        if (fd == null) {
            return new HidlMemory("ashmem", 0, null);
        }
        NativeHandle handle = new NativeHandle(fd, true);
        return new HidlMemory("ashmem", size, handle);
    }

    private static ByteBuffer getBuffer(@NonNull HidlMemory mem) {
        try {
            final int size = (int) mem.getSize();
+3 −1
Original line number Diff line number Diff line
@@ -32,5 +32,7 @@ parcelable SoundModel {
     * was build for */
    String vendorUuid;
    /** Opaque data transparent to Android framework */
    byte[] data;
    FileDescriptor data;
    /** Size of the above data, in bytes. */
    int dataSize;
}
+2 −2
Original line number Diff line number Diff line
@@ -196,8 +196,8 @@ class ConversionUtil {
        hidlModel.header.type = aidl2hidlSoundModelType(aidlModel.type);
        hidlModel.header.uuid = aidl2hidlUuid(aidlModel.uuid);
        hidlModel.header.vendorUuid = aidl2hidlUuid(aidlModel.vendorUuid);
        hidlModel.data = HidlMemoryUtil.byteArrayToHidlMemory(aidlModel.data,
                "SoundTrigger SoundModel");
        hidlModel.data = HidlMemoryUtil.fileDescriptorToHidlMemory(aidlModel.data,
                aidlModel.dataSize);
        return hidlModel;
    }

+19 −1
Original line number Diff line number Diff line
@@ -60,6 +60,8 @@ import android.os.HwParcel;
import android.os.IHwBinder;
import android.os.IHwInterface;
import android.os.RemoteException;
import android.os.SharedMemory;
import android.system.ErrnoException;
import android.util.Pair;

import org.junit.Before;
@@ -71,6 +73,9 @@ import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.stubbing.Answer;

import java.io.FileDescriptor;
import java.nio.ByteBuffer;

@RunWith(Parameterized.class)
public class SoundTriggerMiddlewareImplTest {
    private static final String TAG = "SoundTriggerMiddlewareImplTest";
@@ -104,12 +109,25 @@ public class SoundTriggerMiddlewareImplTest {
        return createSoundModel(SoundModelType.GENERIC);
    }

    private static FileDescriptor byteArrayToFileDescriptor(byte[] data) {
        try {
            SharedMemory shmem = SharedMemory.create("", data.length);
            ByteBuffer buffer = shmem.mapReadWrite();
            buffer.put(data);
            return shmem.getFileDescriptor();
        } catch (ErrnoException e) {
            throw new RuntimeException(e);
        }
    }

    private static SoundModel createSoundModel(int type) {
        SoundModel model = new SoundModel();
        model.type = type;
        model.uuid = "12345678-2345-3456-4567-abcdef987654";
        model.vendorUuid = "87654321-5432-6543-7654-456789fedcba";
        model.data = new byte[]{91, 92, 93, 94, 95};
        byte[] data = new byte[]{91, 92, 93, 94, 95};
        model.data = byteArrayToFileDescriptor(data);
        model.dataSize = data.length;
        return model;
    }