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