diff options
author | Eric Laurent <elaurent@google.com> | 2015-03-05 15:09:23 -0800 |
---|---|---|
committer | Eric Laurent <elaurent@google.com> | 2015-03-10 18:18:12 -0700 |
commit | d73697b9b61be2fa227b93b5c4c8e30badd32e71 (patch) | |
tree | 6defe5ad10e0fabf1c5d72afb661863aac2bec80 | |
parent | a5c5ad3615613ac0f15012e9e07a34582da7fe77 (diff) | |
download | frameworks_av-d73697b9b61be2fa227b93b5c4c8e30badd32e71.zip frameworks_av-d73697b9b61be2fa227b93b5c4c8e30badd32e71.tar.gz frameworks_av-d73697b9b61be2fa227b93b5c4c8e30badd32e71.tar.bz2 |
radio service binder interfaces
Added definiiton and implemention of binder
interfaces fro native broadcastradio service.
Change-Id: Id5a93bc3146229dffc74b56c29ba48e02b9a5518
-rw-r--r-- | include/radio/IRadio.h | 70 | ||||
-rw-r--r-- | include/radio/IRadioClient.h | 50 | ||||
-rw-r--r-- | include/radio/IRadioService.h | 59 | ||||
-rw-r--r-- | radio/Android.mk | 38 | ||||
-rw-r--r-- | radio/IRadio.cpp | 344 | ||||
-rw-r--r-- | radio/IRadioClient.cpp | 75 | ||||
-rw-r--r-- | radio/IRadioService.cpp | 181 |
7 files changed, 817 insertions, 0 deletions
diff --git a/include/radio/IRadio.h b/include/radio/IRadio.h new file mode 100644 index 0000000..1877f8f --- /dev/null +++ b/include/radio/IRadio.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2015 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. + */ + +#ifndef ANDROID_HARDWARE_IRADIO_H +#define ANDROID_HARDWARE_IRADIO_H + +#include <utils/RefBase.h> +#include <binder/IInterface.h> +#include <binder/IMemory.h> +#include <binder/Parcel.h> +#include <system/radio.h> + +namespace android { + +class IRadio : public IInterface +{ +public: + + DECLARE_META_INTERFACE(Radio); + + virtual void detach() = 0; + + virtual status_t setConfiguration(const struct radio_band_config *config) = 0; + + virtual status_t getConfiguration(struct radio_band_config *config) = 0; + + virtual status_t setMute(bool mute) = 0; + + virtual status_t getMute(bool *mute) = 0; + + virtual status_t step(radio_direction_t direction, bool skipSubChannel) = 0; + + virtual status_t scan(radio_direction_t direction, bool skipSubChannel) = 0; + + virtual status_t tune(unsigned int channel, unsigned int subChannel) = 0; + + virtual status_t cancel() = 0; + + virtual status_t getProgramInformation(struct radio_program_info *info) = 0; + + virtual status_t hasControl(bool *hasControl) = 0; +}; + +// ---------------------------------------------------------------------------- + +class BnRadio: public BnInterface<IRadio> +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +}; // namespace android + +#endif //ANDROID_HARDWARE_IRADIO_H diff --git a/include/radio/IRadioClient.h b/include/radio/IRadioClient.h new file mode 100644 index 0000000..9062ad6 --- /dev/null +++ b/include/radio/IRadioClient.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2015 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. + */ + +#ifndef ANDROID_HARDWARE_IRADIO_CLIENT_H +#define ANDROID_HARDWARE_IRADIO_CLIENT_H + +#include <utils/RefBase.h> +#include <binder/IInterface.h> +#include <binder/IMemory.h> +#include <binder/Parcel.h> + +namespace android { + +class IRadioClient : public IInterface +{ +public: + + DECLARE_META_INTERFACE(RadioClient); + + virtual void onEvent(const sp<IMemory>& eventMemory) = 0; + +}; + +// ---------------------------------------------------------------------------- + +class BnRadioClient : public BnInterface<IRadioClient> +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +}; // namespace android + +#endif //ANDROID_HARDWARE_IRADIO_CLIENT_H diff --git a/include/radio/IRadioService.h b/include/radio/IRadioService.h new file mode 100644 index 0000000..a946dd5 --- /dev/null +++ b/include/radio/IRadioService.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2015 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. + */ + +#ifndef ANDROID_HARDWARE_IRADIO_SERVICE_H +#define ANDROID_HARDWARE_IRADIO_SERVICE_H + +#include <utils/RefBase.h> +#include <binder/IInterface.h> +#include <binder/Parcel.h> +#include <system/radio.h> + +namespace android { + +class IRadio; +class IRadioClient; + +class IRadioService : public IInterface +{ +public: + + DECLARE_META_INTERFACE(RadioService); + + virtual status_t listModules(struct radio_properties *properties, + uint32_t *numModules) = 0; + + virtual status_t attach(const radio_handle_t handle, + const sp<IRadioClient>& client, + const struct radio_band_config *config, + bool withAudio, + sp<IRadio>& radio) = 0; +}; + +// ---------------------------------------------------------------------------- + +class BnRadioService: public BnInterface<IRadioService> +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +}; // namespace android + +#endif //ANDROID_HARDWARE_IRADIO_SERVICE_H diff --git a/radio/Android.mk b/radio/Android.mk new file mode 100644 index 0000000..bddc3c2 --- /dev/null +++ b/radio/Android.mk @@ -0,0 +1,38 @@ +# Copyright 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_SRC_FILES:= \ + IRadio.cpp \ + IRadioClient.cpp \ + IRadioService.cpp + +LOCAL_SHARED_LIBRARIES := \ + libcutils \ + libutils \ + liblog \ + libbinder \ + libhardware \ + libradio_metadata + +#LOCAL_C_INCLUDES += \ + system/media/camera/include \ + system/media/private/camera/include + +LOCAL_MODULE:= libradio + +include $(BUILD_SHARED_LIBRARY) diff --git a/radio/IRadio.cpp b/radio/IRadio.cpp new file mode 100644 index 0000000..242df77 --- /dev/null +++ b/radio/IRadio.cpp @@ -0,0 +1,344 @@ +/* +** +** Copyright 2015, 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. +*/ + +#define LOG_TAG "IRadio" +#include <utils/Log.h> +#include <utils/Errors.h> +#include <binder/IMemory.h> +#include <radio/IRadio.h> +#include <radio/IRadioService.h> +#include <radio/IRadioClient.h> +#include <system/radio.h> +#include <system/radio_metadata.h> + +namespace android { + +enum { + DETACH = IBinder::FIRST_CALL_TRANSACTION, + SET_CONFIGURATION, + GET_CONFIGURATION, + SET_MUTE, + GET_MUTE, + SCAN, + STEP, + TUNE, + CANCEL, + GET_PROGRAM_INFORMATION, + HAS_CONTROL +}; + +class BpRadio: public BpInterface<IRadio> +{ +public: + BpRadio(const sp<IBinder>& impl) + : BpInterface<IRadio>(impl) + { + } + + void detach() + { + ALOGV("detach"); + Parcel data, reply; + data.writeInterfaceToken(IRadio::getInterfaceDescriptor()); + remote()->transact(DETACH, data, &reply); + } + + virtual status_t setConfiguration(const struct radio_band_config *config) + { + Parcel data, reply; + if (config == NULL) { + return BAD_VALUE; + } + data.writeInterfaceToken(IRadio::getInterfaceDescriptor()); + data.write(config, sizeof(struct radio_band_config)); + status_t status = remote()->transact(SET_CONFIGURATION, data, &reply); + if (status == NO_ERROR) { + status = (status_t)reply.readInt32(); + } + return status; + } + + virtual status_t getConfiguration(struct radio_band_config *config) + { + Parcel data, reply; + if (config == NULL) { + return BAD_VALUE; + } + data.writeInterfaceToken(IRadio::getInterfaceDescriptor()); + status_t status = remote()->transact(GET_CONFIGURATION, data, &reply); + if (status == NO_ERROR) { + status = (status_t)reply.readInt32(); + if (status == NO_ERROR) { + reply.read(config, sizeof(struct radio_band_config)); + } + } + return status; + } + + virtual status_t setMute(bool mute) + { + Parcel data, reply; + data.writeInterfaceToken(IRadio::getInterfaceDescriptor()); + data.writeInt32(mute ? 1 : 0); + status_t status = remote()->transact(SET_MUTE, data, &reply); + if (status == NO_ERROR) { + status = (status_t)reply.readInt32(); + } + return status; + } + + virtual status_t getMute(bool *mute) + { + Parcel data, reply; + if (mute == NULL) { + return BAD_VALUE; + } + data.writeInterfaceToken(IRadio::getInterfaceDescriptor()); + status_t status = remote()->transact(GET_MUTE, data, &reply); + if (status == NO_ERROR) { + status = (status_t)reply.readInt32(); + if (status == NO_ERROR) { + int muteread = reply.readInt32(); + *mute = muteread != 0; + } + } + return status; + } + + virtual status_t scan(radio_direction_t direction, bool skipSubChannel) + { + Parcel data, reply; + data.writeInterfaceToken(IRadio::getInterfaceDescriptor()); + data.writeInt32(direction); + data.writeInt32(skipSubChannel ? 1 : 0); + status_t status = remote()->transact(SCAN, data, &reply); + if (status == NO_ERROR) { + status = (status_t)reply.readInt32(); + } + return status; + } + + virtual status_t step(radio_direction_t direction, bool skipSubChannel) + { + Parcel data, reply; + data.writeInterfaceToken(IRadio::getInterfaceDescriptor()); + data.writeInt32(direction); + data.writeInt32(skipSubChannel ? 1 : 0); + status_t status = remote()->transact(STEP, data, &reply); + if (status == NO_ERROR) { + status = (status_t)reply.readInt32(); + } + return status; + } + + virtual status_t tune(unsigned int channel, unsigned int subChannel) + { + Parcel data, reply; + data.writeInterfaceToken(IRadio::getInterfaceDescriptor()); + data.writeInt32(channel); + data.writeInt32(subChannel); + status_t status = remote()->transact(TUNE, data, &reply); + if (status == NO_ERROR) { + status = (status_t)reply.readInt32(); + } + return status; + } + + virtual status_t cancel() + { + Parcel data, reply; + data.writeInterfaceToken(IRadio::getInterfaceDescriptor()); + status_t status = remote()->transact(CANCEL, data, &reply); + if (status == NO_ERROR) { + status = (status_t)reply.readInt32(); + } + return status; + } + + virtual status_t getProgramInformation(struct radio_program_info *info) + { + Parcel data, reply; + if (info == NULL) { + return BAD_VALUE; + } + radio_metadata_t *metadata = info->metadata; + data.writeInterfaceToken(IRadio::getInterfaceDescriptor()); + 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)); + info->metadata = metadata; + if (metadata == NULL) { + return status; + } + 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; + } + + virtual status_t hasControl(bool *hasControl) + { + Parcel data, reply; + if (hasControl == NULL) { + return BAD_VALUE; + } + data.writeInterfaceToken(IRadio::getInterfaceDescriptor()); + status_t status = remote()->transact(HAS_CONTROL, data, &reply); + if (status == NO_ERROR) { + status = (status_t)reply.readInt32(); + if (status == NO_ERROR) { + *hasControl = reply.readInt32() != 0; + } + } + return status; + } +}; + +IMPLEMENT_META_INTERFACE(Radio, "android.hardware.IRadio"); + +// ---------------------------------------------------------------------- + +status_t BnRadio::onTransact( + uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) +{ + switch(code) { + case DETACH: { + ALOGV("DETACH"); + CHECK_INTERFACE(IRadio, data, reply); + detach(); + return NO_ERROR; + } break; + case SET_CONFIGURATION: { + CHECK_INTERFACE(IRadio, data, reply); + struct radio_band_config config; + data.read(&config, sizeof(struct radio_band_config)); + status_t status = setConfiguration(&config); + reply->writeInt32(status); + return NO_ERROR; + } + case GET_CONFIGURATION: { + CHECK_INTERFACE(IRadio, data, reply); + struct radio_band_config config; + status_t status = getConfiguration(&config); + reply->writeInt32(status); + if (status == NO_ERROR) { + reply->write(&config, sizeof(struct radio_band_config)); + } + return NO_ERROR; + } + case SET_MUTE: { + CHECK_INTERFACE(IRadio, data, reply); + bool mute = data.readInt32() != 0; + status_t status = setMute(mute); + reply->writeInt32(status); + return NO_ERROR; + } + case GET_MUTE: { + CHECK_INTERFACE(IRadio, data, reply); + bool mute; + status_t status = getMute(&mute); + reply->writeInt32(status); + if (status == NO_ERROR) { + reply->writeInt32(mute ? 1 : 0); + } + return NO_ERROR; + } + case SCAN: { + CHECK_INTERFACE(IRadio, data, reply); + radio_direction_t direction = (radio_direction_t)data.readInt32(); + bool skipSubChannel = data.readInt32() == 1; + status_t status = scan(direction, skipSubChannel); + reply->writeInt32(status); + return NO_ERROR; + } + case STEP: { + CHECK_INTERFACE(IRadio, data, reply); + radio_direction_t direction = (radio_direction_t)data.readInt32(); + bool skipSubChannel = data.readInt32() == 1; + status_t status = step(direction, skipSubChannel); + reply->writeInt32(status); + return NO_ERROR; + } + case TUNE: { + CHECK_INTERFACE(IRadio, data, reply); + unsigned int channel = (unsigned int)data.readInt32(); + unsigned int subChannel = (unsigned int)data.readInt32(); + status_t status = tune(channel, subChannel); + reply->writeInt32(status); + return NO_ERROR; + } + case CANCEL: { + CHECK_INTERFACE(IRadio, data, reply); + status_t status = cancel(); + reply->writeInt32(status); + return NO_ERROR; + } + 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 = 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) { + size_t size = radio_metadata_get_size(info.metadata); + reply->writeInt32(size); + reply->write(info.metadata, size); + } else { + reply->writeInt32(0); + } + } + radio_metadata_deallocate(info.metadata); + return NO_ERROR; + } + case HAS_CONTROL: { + CHECK_INTERFACE(IRadio, data, reply); + bool control; + status_t status = hasControl(&control); + reply->writeInt32(status); + if (status == NO_ERROR) { + reply->writeInt32(control ? 1 : 0); + } + return NO_ERROR; + } + default: + return BBinder::onTransact(code, data, reply, flags); + } +} + +// ---------------------------------------------------------------------------- + +}; // namespace android diff --git a/radio/IRadioClient.cpp b/radio/IRadioClient.cpp new file mode 100644 index 0000000..033ca49 --- /dev/null +++ b/radio/IRadioClient.cpp @@ -0,0 +1,75 @@ +/* +** +** Copyright 2015, 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. +*/ + +#include <stdint.h> +#include <sys/types.h> +#include <binder/IMemory.h> +#include <binder/Parcel.h> +#include <binder/IPCThreadState.h> +#include <binder/IServiceManager.h> +#include <radio/IRadioClient.h> + +namespace android { + +enum { + ON_EVENT = IBinder::FIRST_CALL_TRANSACTION, +}; + +class BpRadioClient: public BpInterface<IRadioClient> +{ + +public: + BpRadioClient(const sp<IBinder>& impl) + : BpInterface<IRadioClient>(impl) + { + } + + virtual void onEvent(const sp<IMemory>& eventMemory) + { + Parcel data, reply; + data.writeInterfaceToken(IRadioClient::getInterfaceDescriptor()); + data.writeStrongBinder(IInterface::asBinder(eventMemory)); + remote()->transact(ON_EVENT, + data, + &reply); + } +}; + +IMPLEMENT_META_INTERFACE(RadioClient, + "android.hardware.IRadioClient"); + +// ---------------------------------------------------------------------- + +status_t BnRadioClient::onTransact( + uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) +{ + switch(code) { + case ON_EVENT: { + CHECK_INTERFACE(IRadioClient, data, reply); + sp<IMemory> eventMemory = interface_cast<IMemory>( + data.readStrongBinder()); + onEvent(eventMemory); + return NO_ERROR; + } break; + default: + return BBinder::onTransact(code, data, reply, flags); + } return NO_ERROR; +} + +// ---------------------------------------------------------------------------- + +}; // namespace android diff --git a/radio/IRadioService.cpp b/radio/IRadioService.cpp new file mode 100644 index 0000000..8c2b3ef --- /dev/null +++ b/radio/IRadioService.cpp @@ -0,0 +1,181 @@ +/* +** +** Copyright 2015, 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. +*/ + +#define LOG_TAG "BpRadioService" +// +#define LOG_NDEBUG 0 + +#include <utils/Log.h> +#include <utils/Errors.h> + +#include <stdint.h> +#include <sys/types.h> +#include <binder/IMemory.h> +#include <binder/Parcel.h> +#include <binder/IPCThreadState.h> +#include <binder/IServiceManager.h> + +#include <radio/IRadioService.h> +#include <radio/IRadio.h> +#include <radio/IRadioClient.h> + +namespace android { + +enum { + LIST_MODULES = IBinder::FIRST_CALL_TRANSACTION, + ATTACH, +}; + +#define MAX_ITEMS_PER_LIST 1024 + +class BpRadioService: public BpInterface<IRadioService> +{ +public: + BpRadioService(const sp<IBinder>& impl) + : BpInterface<IRadioService>(impl) + { + } + + virtual status_t listModules(struct radio_properties *properties, + uint32_t *numModules) + { + if (numModules == NULL || (*numModules != 0 && properties == NULL)) { + return BAD_VALUE; + } + Parcel data, reply; + data.writeInterfaceToken(IRadioService::getInterfaceDescriptor()); + unsigned int numModulesReq = (properties == NULL) ? 0 : *numModules; + data.writeInt32(numModulesReq); + status_t status = remote()->transact(LIST_MODULES, data, &reply); + if (status == NO_ERROR) { + status = (status_t)reply.readInt32(); + *numModules = (unsigned int)reply.readInt32(); + } + ALOGV("listModules() status %d got *numModules %d", status, *numModules); + if (status == NO_ERROR) { + if (numModulesReq > *numModules) { + numModulesReq = *numModules; + } + if (numModulesReq > 0) { + reply.read(properties, numModulesReq * sizeof(struct radio_properties)); + } + } + return status; + } + + virtual status_t attach(radio_handle_t handle, + const sp<IRadioClient>& client, + const struct radio_band_config *config, + bool withAudio, + sp<IRadio>& radio) + { + Parcel data, reply; + data.writeInterfaceToken(IRadioService::getInterfaceDescriptor()); + data.writeInt32(handle); + data.writeStrongBinder(IInterface::asBinder(client)); + ALOGV("attach() config %p withAudio %d region %d type %d", config, withAudio, config->region, config->band.type); + if (config == NULL) { + data.writeInt32(0); + } else { + data.writeInt32(1); + data.write(config, sizeof(struct radio_band_config)); + } + data.writeInt32(withAudio ? 1 : 0); + status_t status = remote()->transact(ATTACH, data, &reply); + if (status != NO_ERROR) { + return status; + } + status = reply.readInt32(); + if (reply.readInt32() != 0) { + radio = interface_cast<IRadio>(reply.readStrongBinder()); + } + return status; + } +}; + +IMPLEMENT_META_INTERFACE(RadioService, "android.hardware.IRadioService"); + +// ---------------------------------------------------------------------- + +status_t BnRadioService::onTransact( + uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) +{ + switch(code) { + case LIST_MODULES: { + CHECK_INTERFACE(IRadioService, data, reply); + unsigned int numModulesReq = data.readInt32(); + if (numModulesReq > MAX_ITEMS_PER_LIST) { + numModulesReq = MAX_ITEMS_PER_LIST; + } + unsigned int numModules = numModulesReq; + struct radio_properties *properties = + (struct radio_properties *)calloc(numModulesReq, + sizeof(struct radio_properties)); + if (properties == NULL) { + reply->writeInt32(NO_MEMORY); + reply->writeInt32(0); + return NO_ERROR; + } + + status_t status = listModules(properties, &numModules); + reply->writeInt32(status); + reply->writeInt32(numModules); + ALOGV("LIST_MODULES status %d got numModules %d", status, numModules); + + if (status == NO_ERROR) { + if (numModulesReq > numModules) { + numModulesReq = numModules; + } + reply->write(properties, + numModulesReq * sizeof(struct radio_properties)); + } + free(properties); + return NO_ERROR; + } break; + + case ATTACH: { + CHECK_INTERFACE(IRadioService, data, reply); + radio_handle_t handle = data.readInt32(); + sp<IRadioClient> client = + interface_cast<IRadioClient>(data.readStrongBinder()); + struct radio_band_config config; + struct radio_band_config *configPtr = NULL; + if (data.readInt32() != 0) { + data.read(&config, sizeof(struct radio_band_config)); + configPtr = &config; + } + bool withAudio = data.readInt32() != 0; + ALOGV("ATTACH configPtr %p withAudio %d", configPtr, withAudio); + sp<IRadio> radio; + status_t status = attach(handle, client, configPtr, withAudio, radio); + reply->writeInt32(status); + if (radio != 0) { + reply->writeInt32(1); + reply->writeStrongBinder(IInterface::asBinder(radio)); + } else { + reply->writeInt32(0); + } + return NO_ERROR; + } break; + default: + return BBinder::onTransact(code, data, reply, flags); + } +} + +// ---------------------------------------------------------------------------- + +}; // namespace android |