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
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user