radio: fix 64 bit process compatibility
Fix binder call implementations and shared memory layout to make sure
that structures containig a pointer to metadata buffer are passed
correctly between 32 bit and 64 bit processes.
Change-Id: Ibecf260555225e0764411f62b60831511cb68278
diff --git a/radio/IRadio.cpp b/radio/IRadio.cpp
index 0881a91..ebf3859 100644
--- a/radio/IRadio.cpp
+++ b/radio/IRadio.cpp
@@ -112,7 +112,7 @@
if (status == NO_ERROR) {
status = (status_t)reply.readInt32();
if (status == NO_ERROR) {
- int muteread = reply.readInt32();
+ int32_t muteread = reply.readInt32();
*mute = muteread != 0;
}
}
@@ -145,12 +145,12 @@
return status;
}
- virtual status_t tune(unsigned int channel, unsigned int subChannel)
+ virtual status_t tune(uint32_t channel, uint32_t subChannel)
{
Parcel data, reply;
data.writeInterfaceToken(IRadio::getInterfaceDescriptor());
- data.writeInt32(channel);
- data.writeInt32(subChannel);
+ data.writeUint32(channel);
+ data.writeUint32(subChannel);
status_t status = remote()->transact(TUNE, data, &reply);
if (status == NO_ERROR) {
status = (status_t)reply.readInt32();
@@ -177,27 +177,29 @@
}
radio_metadata_t *metadata = info->metadata;
data.writeInterfaceToken(IRadio::getInterfaceDescriptor());
+ if (metadata != NULL) {
+ data.writeUint32(1);
+ } else {
+ data.writeUint32(0);
+ }
status_t status = remote()->transact(GET_PROGRAM_INFORMATION, data, &reply);
if (status == NO_ERROR) {
status = (status_t)reply.readInt32();
if (status == NO_ERROR) {
reply.read(info, sizeof(struct radio_program_info));
+ // restore local metadata pointer
info->metadata = metadata;
- if (metadata == NULL) {
- return status;
+
+ uint32_t metatataSize = reply.readUint32();
+ if ((metadata != NULL) && (metatataSize != 0)) {
+ radio_metadata_t *newMetadata = (radio_metadata_t *)malloc(metatataSize);
+ if (newMetadata == NULL) {
+ return NO_MEMORY;
+ }
+ reply.read(newMetadata, metatataSize);
+ status = radio_metadata_add_metadata(&info->metadata, newMetadata);
+ free(newMetadata);
}
- size_t size = (size_t)reply.readInt32();
- if (size == 0) {
- return status;
- }
- metadata =
- (radio_metadata_t *)calloc(size / sizeof(unsigned int), sizeof(unsigned int));
- if (metadata == NULL) {
- return NO_MEMORY;
- }
- reply.read(metadata, size);
- status = radio_metadata_add_metadata(&info->metadata, metadata);
- free(metadata);
}
}
return status;
@@ -288,8 +290,8 @@
}
case TUNE: {
CHECK_INTERFACE(IRadio, data, reply);
- unsigned int channel = (unsigned int)data.readInt32();
- unsigned int subChannel = (unsigned int)data.readInt32();
+ uint32_t channel = data.readUint32();
+ uint32_t subChannel = data.readUint32();
status_t status = tune(channel, subChannel);
reply->writeInt32(status);
return NO_ERROR;
@@ -303,22 +305,27 @@
case GET_PROGRAM_INFORMATION: {
CHECK_INTERFACE(IRadio, data, reply);
struct radio_program_info info;
-
- status_t status = radio_metadata_allocate(&info.metadata, 0, 0);
- if (status != NO_ERROR) {
- return status;
+ status_t status;
+ // query metadata only if requested by remote side
+ if (data.readUint32() == 1) {
+ status = radio_metadata_allocate(&info.metadata, 0, 0);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ } else {
+ info.metadata = NULL;
}
status = getProgramInformation(&info);
+
reply->writeInt32(status);
if (status == NO_ERROR) {
reply->write(&info, sizeof(struct radio_program_info));
- int count = radio_metadata_get_count(info.metadata);
- if (count > 0) {
+ if ((info.metadata != NULL) && (radio_metadata_get_count(info.metadata) > 0)) {
size_t size = radio_metadata_get_size(info.metadata);
- reply->writeInt32(size);
+ reply->writeUint32((uint32_t)size);
reply->write(info.metadata, size);
} else {
- reply->writeInt32(0);
+ reply->writeUint32(0);
}
}
radio_metadata_deallocate(info.metadata);