From e80fd680078162273a84998dca578372cc59b299 Mon Sep 17 00:00:00 2001 From: Ytai Ben-Tsvi Date: Thu, 25 Feb 2021 13:23:02 -0800 Subject: [PATCH] Support sound models with no data This change allows using SoundModels with null or empty data. Test: Manual testing of soundtrigger use-cases. Testing of null-/empty-data models using SoundTriggerTestService and mocked HAL. Fixes: 181103994 Change-Id: I00b3c4e343a81e9f4f4580becf1128fd3ba60b14 --- .../hardware/soundtrigger/ConversionUtil.java | 21 ++++------ .../soundtrigger_middleware/SoundModel.aidl | 4 +- .../ConversionUtil.java | 41 +++++++++++++------ .../ValidationUtil.java | 4 +- 4 files changed, 42 insertions(+), 28 deletions(-) diff --git a/core/java/android/hardware/soundtrigger/ConversionUtil.java b/core/java/android/hardware/soundtrigger/ConversionUtil.java index 06b5b6745bd17..a5c9a7fafbd86 100644 --- a/core/java/android/hardware/soundtrigger/ConversionUtil.java +++ b/core/java/android/hardware/soundtrigger/ConversionUtil.java @@ -34,10 +34,7 @@ import android.media.soundtrigger_middleware.SoundTriggerModuleDescriptor; import android.media.soundtrigger_middleware.SoundTriggerModuleProperties; import android.os.ParcelFileDescriptor; import android.os.SharedMemory; -import android.system.ErrnoException; -import java.io.FileDescriptor; -import java.io.IOException; import java.nio.ByteBuffer; import java.util.Arrays; import java.util.UUID; @@ -111,13 +108,9 @@ class ConversionUtil { aidlModel.type = apiModel.getType(); aidlModel.uuid = api2aidlUuid(apiModel.getUuid()); aidlModel.vendorUuid = api2aidlUuid(apiModel.getVendorUuid()); - try { - aidlModel.data = ParcelFileDescriptor.dup( - byteArrayToSharedMemory(apiModel.getData(), "SoundTrigger SoundModel")); - } catch (IOException e) { - throw new RuntimeException(e); - } - aidlModel.dataSize = apiModel.getData().length; + byte[] data = apiModel.getData(); + aidlModel.data = byteArrayToSharedMemory(data, "SoundTrigger SoundModel"); + aidlModel.dataSize = data.length; return aidlModel; } @@ -379,7 +372,7 @@ class ConversionUtil { return result; } - private static @Nullable FileDescriptor byteArrayToSharedMemory(byte[] data, String name) { + private static @Nullable ParcelFileDescriptor byteArrayToSharedMemory(byte[] data, String name) { if (data.length == 0) { return null; } @@ -389,8 +382,10 @@ class ConversionUtil { ByteBuffer buffer = shmem.mapReadWrite(); buffer.put(data); shmem.unmap(buffer); - return shmem.getFileDescriptor(); - } catch (ErrnoException e) { + ParcelFileDescriptor fd = shmem.getFdDup(); + shmem.close(); + return fd; + } catch (Exception e) { throw new RuntimeException(e); } } diff --git a/media/aidl/android/media/soundtrigger_middleware/SoundModel.aidl b/media/aidl/android/media/soundtrigger_middleware/SoundModel.aidl index cee3635a1e3bf..8186fb741b595 100644 --- a/media/aidl/android/media/soundtrigger_middleware/SoundModel.aidl +++ b/media/aidl/android/media/soundtrigger_middleware/SoundModel.aidl @@ -32,8 +32,8 @@ parcelable SoundModel { * Unique vendor ID. Identifies the engine the sound model * was build for */ String vendorUuid; - /** Opaque data transparent to Android framework */ - ParcelFileDescriptor data; + /** Opaque data transparent to Android framework. May be null if dataSize is 0. */ + @nullable ParcelFileDescriptor data; /** Size of the above data, in bytes. */ int dataSize; } diff --git a/services/core/java/com/android/server/soundtrigger_middleware/ConversionUtil.java b/services/core/java/com/android/server/soundtrigger_middleware/ConversionUtil.java index de8823c4b7f3e..6366280e17625 100644 --- a/services/core/java/com/android/server/soundtrigger_middleware/ConversionUtil.java +++ b/services/core/java/com/android/server/soundtrigger_middleware/ConversionUtil.java @@ -39,6 +39,7 @@ import android.media.soundtrigger_middleware.RecognitionStatus; import android.media.soundtrigger_middleware.SoundModel; import android.media.soundtrigger_middleware.SoundModelType; import android.media.soundtrigger_middleware.SoundTriggerModuleProperties; +import android.os.HidlMemory; import android.os.HidlMemoryUtil; import android.os.ParcelFileDescriptor; @@ -199,18 +200,7 @@ class ConversionUtil { hidlModel.header.type = aidl2hidlSoundModelType(aidlModel.type); hidlModel.header.uuid = aidl2hidlUuid(aidlModel.uuid); hidlModel.header.vendorUuid = aidl2hidlUuid(aidlModel.vendorUuid); - - // Extract a dup of the underlying FileDescriptor out of aidlModel.data without changing - // the original. - FileDescriptor fd = new FileDescriptor(); - try { - ParcelFileDescriptor dup = aidlModel.data.dup(); - fd.setInt$(dup.detachFd()); - hidlModel.data = HidlMemoryUtil.fileDescriptorToHidlMemory(fd, aidlModel.dataSize); - } catch (IOException e) { - throw new RuntimeException(e); - } - + hidlModel.data = parcelFileDescriptorToHidlMemory(aidlModel.data, aidlModel.dataSize); return hidlModel; } @@ -425,4 +415,31 @@ class ConversionUtil { } return aidlCapabilities; } + + /** + * Convert an AIDL representation of a shared memory block (ParcelFileDescriptor + size) to the + * HIDL representation (HidlMemory). Will not change the incoming data or any ownership + * semantics, but rather duplicate the underlying FD. + * + * @param data The incoming memory block. May be null if dataSize is 0. + * @param dataSize The number of bytes in the block. + * @return A HidlMemory representation of the memory block. Will be non-null even for an empty + * block. + */ + private static @NonNull + HidlMemory parcelFileDescriptorToHidlMemory(@Nullable ParcelFileDescriptor data, int dataSize) { + if (dataSize > 0) { + // Extract a dup of the underlying FileDescriptor out of data. + FileDescriptor fd = new FileDescriptor(); + try { + ParcelFileDescriptor dup = data.dup(); + fd.setInt$(dup.detachFd()); + return HidlMemoryUtil.fileDescriptorToHidlMemory(fd, dataSize); + } catch (IOException e) { + throw new RuntimeException(e); + } + } else { + return HidlMemoryUtil.fileDescriptorToHidlMemory(null, 0); + } + } } diff --git a/services/core/java/com/android/server/soundtrigger_middleware/ValidationUtil.java b/services/core/java/com/android/server/soundtrigger_middleware/ValidationUtil.java index 43047d1ebaaaf..e05c468186ed7 100644 --- a/services/core/java/com/android/server/soundtrigger_middleware/ValidationUtil.java +++ b/services/core/java/com/android/server/soundtrigger_middleware/ValidationUtil.java @@ -62,7 +62,9 @@ public class ValidationUtil { } validateUuid(model.uuid); validateUuid(model.vendorUuid); - Objects.requireNonNull(model.data); + if (model.dataSize > 0) { + Objects.requireNonNull(model.data); + } } static void validatePhraseModel(@Nullable PhraseSoundModel model) {