1dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent/* 2dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent** 3dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent** Copyright (C) 2015, The Android Open Source Project 4dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent** 5dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent** Licensed under the Apache License, Version 2.0 (the "License"); 6dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent** you may not use this file except in compliance with the License. 7dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent** You may obtain a copy of the License at 8dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent** 9dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent** http://www.apache.org/licenses/LICENSE-2.0 10dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent** 11dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent** Unless required by applicable law or agreed to in writing, software 12dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent** distributed under the License is distributed on an "AS IS" BASIS, 13dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent** See the License for the specific language governing permissions and 15dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent** limitations under the License. 16dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent*/ 17dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent 18dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent#define LOG_TAG "Radio" 19dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent//#define LOG_NDEBUG 0 20dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent 21dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent#include <utils/Log.h> 22dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent#include <utils/threads.h> 23dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent#include <binder/IPCThreadState.h> 24dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent#include <binder/IServiceManager.h> 25dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent#include <binder/IMemory.h> 26dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent 27dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent#include <radio/Radio.h> 28dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent#include <radio/IRadio.h> 29dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent#include <radio/IRadioService.h> 30dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent#include <radio/IRadioClient.h> 31dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent#include <radio/RadioCallback.h> 32dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent 33dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurentnamespace android { 34dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent 35dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurentnamespace { 36dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent sp<IRadioService> gRadioService; 37dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent const int kRadioServicePollDelay = 500000; // 0.5s 38dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent const char* kRadioServiceName = "media.radio"; 39dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent Mutex gLock; 40dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent 41dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent class DeathNotifier : public IBinder::DeathRecipient 42dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent { 43dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent public: 44dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent DeathNotifier() { 45dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent } 46dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent 47dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent virtual void binderDied(const wp<IBinder>& who __unused) { 48dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent ALOGV("binderDied"); 49dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent Mutex::Autolock _l(gLock); 50dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent gRadioService.clear(); 51dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent ALOGW("Radio service died!"); 52dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent } 53dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent }; 54dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent 55dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent sp<DeathNotifier> gDeathNotifier; 56dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent}; // namespace anonymous 57dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent 58dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurentconst sp<IRadioService>& Radio::getRadioService() 59dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent{ 60dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent Mutex::Autolock _l(gLock); 61dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent if (gRadioService.get() == 0) { 62dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent sp<IServiceManager> sm = defaultServiceManager(); 63dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent sp<IBinder> binder; 64dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent do { 65dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent binder = sm->getService(String16(kRadioServiceName)); 66dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent if (binder != 0) { 67dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent break; 68dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent } 69dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent ALOGW("RadioService not published, waiting..."); 70dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent usleep(kRadioServicePollDelay); 71dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent } while(true); 72dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent if (gDeathNotifier == NULL) { 73dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent gDeathNotifier = new DeathNotifier(); 74dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent } 75dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent binder->linkToDeath(gDeathNotifier); 76dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent gRadioService = interface_cast<IRadioService>(binder); 77dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent } 78dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent ALOGE_IF(gRadioService == 0, "no RadioService!?"); 79dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent return gRadioService; 80dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent} 81dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent 82dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent// Static methods 83dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurentstatus_t Radio::listModules(struct radio_properties *properties, 84dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent uint32_t *numModules) 85dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent{ 86dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent ALOGV("listModules()"); 87dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent const sp<IRadioService>& service = getRadioService(); 88dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent if (service == 0) { 89dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent return NO_INIT; 90dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent } 91dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent return service->listModules(properties, numModules); 92dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent} 93dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent 94dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurentsp<Radio> Radio::attach(radio_handle_t handle, 95dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent const struct radio_band_config *config, 96dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent bool withAudio, 97dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent const sp<RadioCallback>& callback) 98dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent{ 99dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent ALOGV("attach()"); 100dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent sp<Radio> radio; 101dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent const sp<IRadioService>& service = getRadioService(); 102dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent if (service == 0) { 103dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent return radio; 104dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent } 105dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent radio = new Radio(handle, callback); 106dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent status_t status = service->attach(handle, radio, config, withAudio, radio->mIRadio); 107dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent 108dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent if (status == NO_ERROR && radio->mIRadio != 0) { 109dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent IInterface::asBinder(radio->mIRadio)->linkToDeath(radio); 110dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent } else { 111dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent ALOGW("Error %d connecting to radio service", status); 112dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent radio.clear(); 113dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent } 114dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent return radio; 115dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent} 116dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent 117dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent 118dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent 119dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent// Radio 120dedc86dcb6d63e93518c8974c077e50912d15e9cEric LaurentRadio::Radio(radio_handle_t handle, const sp<RadioCallback>& callback) 121dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent : mHandle(handle), mCallback(callback) 122dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent{ 123dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent} 124dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent 125dedc86dcb6d63e93518c8974c077e50912d15e9cEric LaurentRadio::~Radio() 126dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent{ 127dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent if (mIRadio != 0) { 128dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent mIRadio->detach(); 129dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent } 130dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent} 131dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent 132dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent 133dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurentvoid Radio::detach() { 134dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent ALOGV("detach()"); 135dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent Mutex::Autolock _l(mLock); 136dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent mCallback.clear(); 137dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent if (mIRadio != 0) { 138dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent mIRadio->detach(); 139dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent IInterface::asBinder(mIRadio)->unlinkToDeath(this); 140dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent mIRadio = 0; 141dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent } 142dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent} 143dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent 144dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurentstatus_t Radio::setConfiguration(const struct radio_band_config *config) 145dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent{ 146dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent Mutex::Autolock _l(mLock); 147dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent if (mIRadio == 0) { 148dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent return NO_INIT; 149dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent } 150dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent return mIRadio->setConfiguration(config); 151dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent} 152dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent 153dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurentstatus_t Radio::getConfiguration(struct radio_band_config *config) 154dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent{ 155dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent Mutex::Autolock _l(mLock); 156dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent if (mIRadio == 0) { 157dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent return NO_INIT; 158dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent } 159dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent return mIRadio->getConfiguration(config); 160dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent} 161dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent 162dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurentstatus_t Radio::setMute(bool mute) 163dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent{ 164dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent Mutex::Autolock _l(mLock); 165dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent if (mIRadio == 0) { 166dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent return NO_INIT; 167dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent } 168dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent return mIRadio->setMute(mute); 169dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent} 170dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent 171dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurentstatus_t Radio::getMute(bool *mute) 172dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent{ 173dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent Mutex::Autolock _l(mLock); 174dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent if (mIRadio == 0) { 175dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent return NO_INIT; 176dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent } 177dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent return mIRadio->getMute(mute); 178dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent} 179dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent 180dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurentstatus_t Radio::scan(radio_direction_t direction, bool skipSubchannel) 181dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent{ 182dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent Mutex::Autolock _l(mLock); 183dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent if (mIRadio == 0) { 184dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent return NO_INIT; 185dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent } 186dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent return mIRadio->scan(direction, skipSubchannel); 187dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent} 188dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent 189dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurentstatus_t Radio::step(radio_direction_t direction, bool skipSubchannel) 190dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent{ 191dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent Mutex::Autolock _l(mLock); 192dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent if (mIRadio == 0) { 193dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent return NO_INIT; 194dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent } 195dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent return mIRadio->step(direction, skipSubchannel); 196dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent} 197dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent 198dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurentstatus_t Radio::tune(unsigned int channel, unsigned int subChannel) 199dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent{ 200dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent Mutex::Autolock _l(mLock); 201dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent if (mIRadio == 0) { 202dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent return NO_INIT; 203dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent } 204dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent return mIRadio->tune(channel, subChannel); 205dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent} 206dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent 207dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurentstatus_t Radio::cancel() 208dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent{ 209dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent Mutex::Autolock _l(mLock); 210dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent if (mIRadio == 0) { 211dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent return NO_INIT; 212dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent } 213dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent return mIRadio->cancel(); 214dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent} 215dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent 216dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurentstatus_t Radio::getProgramInformation(struct radio_program_info *info) 217dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent{ 218dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent Mutex::Autolock _l(mLock); 219dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent if (mIRadio == 0) { 220dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent return NO_INIT; 221dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent } 222dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent return mIRadio->getProgramInformation(info); 223dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent} 224dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent 225dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurentstatus_t Radio::hasControl(bool *hasControl) 226dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent{ 227dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent Mutex::Autolock _l(mLock); 228dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent if (mIRadio == 0) { 229dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent return NO_INIT; 230dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent } 231dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent return mIRadio->hasControl(hasControl); 232dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent} 233dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent 234dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent 235dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent// BpRadioClient 236dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurentvoid Radio::onEvent(const sp<IMemory>& eventMemory) 237dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent{ 238dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent Mutex::Autolock _l(mLock); 239dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent if (eventMemory == 0 || eventMemory->pointer() == NULL) { 240dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent return; 241dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent } 242dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent 243dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent struct radio_event *event = (struct radio_event *)eventMemory->pointer(); 244dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent // restore local metadata pointer from offset 245dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent switch (event->type) { 246dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent case RADIO_EVENT_TUNED: 247dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent case RADIO_EVENT_AF_SWITCH: 248dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent if (event->info.metadata != NULL) { 249dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent event->info.metadata = 250dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent (radio_metadata_t *)((char *)event + (size_t)event->info.metadata); 251dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent } 252dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent break; 253dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent case RADIO_EVENT_METADATA: 254dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent if (event->metadata != NULL) { 255dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent event->metadata = 256dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent (radio_metadata_t *)((char *)event + (size_t)event->metadata); 257dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent } 258dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent break; 259dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent default: 260dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent break; 261dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent } 262dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent 263dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent if (mCallback != 0) { 264dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent mCallback->onEvent(event); 265dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent } 266dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent} 267dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent 268dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent 269dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent//IBinder::DeathRecipient 270dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurentvoid Radio::binderDied(const wp<IBinder>& who __unused) { 271dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent Mutex::Autolock _l(mLock); 272dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent ALOGW("Radio server binder Died "); 273dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent mIRadio = 0; 274dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent struct radio_event event; 275dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent memset(&event, 0, sizeof(struct radio_event)); 276dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent event.type = RADIO_EVENT_SERVER_DIED; 277dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent event.status = DEAD_OBJECT; 278dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent if (mCallback != 0) { 279dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent mCallback->onEvent(&event); 280dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent } 281dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent} 282dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent 283dedc86dcb6d63e93518c8974c077e50912d15e9cEric Laurent}; // namespace android 284