14e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent/* 24e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent * Copyright (C) 2015 The Android Open Source Project 34e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent * 44e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent * Licensed under the Apache License, Version 2.0 (the "License"); 54e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent * you may not use this file except in compliance with the License. 64e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent * You may obtain a copy of the License at 74e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent * 84e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent * http://www.apache.org/licenses/LICENSE-2.0 94e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent * 104e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent * Unless required by applicable law or agreed to in writing, software 114e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent * distributed under the License is distributed on an "AS IS" BASIS, 124e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent * See the License for the specific language governing permissions and 144e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent * limitations under the License. 154e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent */ 164e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 174e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent#define LOG_TAG "RadioService" 184e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent//#define LOG_NDEBUG 0 194e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 204e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent#include <stdio.h> 214e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent#include <string.h> 224e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent#include <sys/types.h> 234e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent#include <pthread.h> 244e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 2553810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent#include <system/audio.h> 2653810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent#include <system/audio_policy.h> 274e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent#include <system/radio.h> 284e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent#include <system/radio_metadata.h> 294e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent#include <cutils/atomic.h> 304e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent#include <cutils/properties.h> 314e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent#include <hardware/hardware.h> 324e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent#include <utils/Errors.h> 334e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent#include <utils/Log.h> 344e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent#include <binder/IServiceManager.h> 354e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent#include <binder/MemoryBase.h> 364e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent#include <binder/MemoryHeapBase.h> 370e37854e54944892b15a72ed4633f0347dbc2cb8Keun-young Park#include <binder/PermissionCache.h> 384e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent#include <hardware/radio.h> 3953810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent#include <media/AudioSystem.h> 404e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent#include "RadioService.h" 414e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent#include "RadioRegions.h" 424e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 434e09069a29fc18d0799808cc26f71e9b068e98adEric Laurentnamespace android { 444e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 4553810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurentstatic const char kRadioTunerAudioDeviceName[] = "Radio tuner source"; 464e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 470e37854e54944892b15a72ed4633f0347dbc2cb8Keun-young Parkstatic const String16 RADIO_PERMISSION("android.permission.ACCESS_FM_RADIO"); 480e37854e54944892b15a72ed4633f0347dbc2cb8Keun-young Park 494e09069a29fc18d0799808cc26f71e9b068e98adEric LaurentRadioService::RadioService() 504e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent : BnRadioService(), mNextUniqueId(1) 514e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent{ 524e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent ALOGI("%s", __FUNCTION__); 534e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 544e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 554e09069a29fc18d0799808cc26f71e9b068e98adEric Laurentvoid RadioService::onFirstRef() 564e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent{ 574e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent ALOGI("%s", __FUNCTION__); 584e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 5901d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent sp<RadioInterface> dev = RadioInterface::connectModule(RADIO_CLASS_AM_FM); 6001d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent 6101d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent if (dev == 0) { 624e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return; 634e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 644e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent struct radio_hal_properties halProperties; 6501d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent int rc = dev->getProperties(&halProperties); 664e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (rc != 0) { 674e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent ALOGE("could not read implementation properties"); 684e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return; 694e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 704e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 714e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent radio_properties_t properties; 724e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent properties.handle = 734e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent (radio_handle_t)android_atomic_inc(&mNextUniqueId); 74164f36815fe5ff8bb3d0f0da013eca8a6408eab2Tomasz Wasilczyk convertProperties(&properties, &halProperties); 754e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 76164f36815fe5ff8bb3d0f0da013eca8a6408eab2Tomasz Wasilczyk ALOGI("loaded default module %s, ver %s, handle %d", properties.product, 77164f36815fe5ff8bb3d0f0da013eca8a6408eab2Tomasz Wasilczyk properties.version, properties.handle); 784e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 7953810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent sp<Module> module = new Module(dev, properties); 804e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent mModules.add(properties.handle, module); 814e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 824e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 834e09069a29fc18d0799808cc26f71e9b068e98adEric LaurentRadioService::~RadioService() 844e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent{ 854e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 864e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 874e09069a29fc18d0799808cc26f71e9b068e98adEric Laurentstatus_t RadioService::listModules(struct radio_properties *properties, 884e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent uint32_t *numModules) 894e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent{ 900e37854e54944892b15a72ed4633f0347dbc2cb8Keun-young Park if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) { 910e37854e54944892b15a72ed4633f0347dbc2cb8Keun-young Park return PERMISSION_DENIED; 920e37854e54944892b15a72ed4633f0347dbc2cb8Keun-young Park } 934e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent ALOGV("listModules"); 944e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 954e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent AutoMutex lock(mServiceLock); 964e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (numModules == NULL || (*numModules != 0 && properties == NULL)) { 974e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return BAD_VALUE; 984e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 9901d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent uint32_t maxModules = *numModules; 1004e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent *numModules = mModules.size(); 1014e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent for (size_t i = 0; i < mModules.size() && i < maxModules; i++) { 1024e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent properties[i] = mModules.valueAt(i)->properties(); 1034e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 1044e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return NO_ERROR; 1054e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 1064e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 1074e09069a29fc18d0799808cc26f71e9b068e98adEric Laurentstatus_t RadioService::attach(radio_handle_t handle, 1084e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent const sp<IRadioClient>& client, 1094e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent const struct radio_band_config *config, 1104e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent bool withAudio, 1114e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent sp<IRadio>& radio) 1124e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent{ 1130e37854e54944892b15a72ed4633f0347dbc2cb8Keun-young Park if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) { 1140e37854e54944892b15a72ed4633f0347dbc2cb8Keun-young Park return PERMISSION_DENIED; 1150e37854e54944892b15a72ed4633f0347dbc2cb8Keun-young Park } 1164e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent ALOGV("%s %d config %p withAudio %d", __FUNCTION__, handle, config, withAudio); 1174e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 1184e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent AutoMutex lock(mServiceLock); 1194e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent radio.clear(); 1204e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (client == 0) { 1214e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return BAD_VALUE; 1224e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 1234e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent ssize_t index = mModules.indexOfKey(handle); 1244e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (index < 0) { 1254e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return BAD_VALUE; 1264e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 1274e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent sp<Module> module = mModules.valueAt(index); 1284e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 1294e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (config == NULL) { 1304e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent config = module->getDefaultConfig(); 1314e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (config == NULL) { 1324e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return INVALID_OPERATION; 1334e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 1344e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 1354e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent ALOGV("%s region %d type %d", __FUNCTION__, config->region, config->band.type); 1364e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 1374e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent radio = module->addClient(client, config, withAudio); 1384e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 1394e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (radio == 0) { 140f2f79cfcdec89052f49b74f9aab48e58daf606c6Eric Laurent return NO_INIT; 1414e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 1424e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return NO_ERROR; 1434e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 1444e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 1454e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 1464e09069a29fc18d0799808cc26f71e9b068e98adEric Laurentstatic const int kDumpLockRetries = 50; 1474e09069a29fc18d0799808cc26f71e9b068e98adEric Laurentstatic const int kDumpLockSleep = 60000; 1484e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 1494e09069a29fc18d0799808cc26f71e9b068e98adEric Laurentstatic bool tryLock(Mutex& mutex) 1504e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent{ 1514e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent bool locked = false; 1524e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent for (int i = 0; i < kDumpLockRetries; ++i) { 1534e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (mutex.tryLock() == NO_ERROR) { 1544e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent locked = true; 1554e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent break; 1564e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 1574e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent usleep(kDumpLockSleep); 1584e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 1594e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return locked; 1604e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 1614e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 1624e09069a29fc18d0799808cc26f71e9b068e98adEric Laurentstatus_t RadioService::dump(int fd, const Vector<String16>& args __unused) { 1634e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent String8 result; 1644e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (checkCallingPermission(String16("android.permission.DUMP")) == false) { 1654e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent result.appendFormat("Permission Denial: can't dump RadioService"); 1664e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent write(fd, result.string(), result.size()); 1674e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } else { 1684e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent bool locked = tryLock(mServiceLock); 1694e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent // failed to lock - RadioService is probably deadlocked 1704e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (!locked) { 1714e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent result.append("RadioService may be deadlocked\n"); 1724e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent write(fd, result.string(), result.size()); 1734e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 1744e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 1754e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (locked) mServiceLock.unlock(); 1764e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 1774e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return NO_ERROR; 1784e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 1794e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 1804e09069a29fc18d0799808cc26f71e9b068e98adEric Laurentstatus_t RadioService::onTransact( 1814e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { 1824e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return BnRadioService::onTransact(code, data, reply, flags); 1834e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 1844e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 1854e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 1864e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent/* static */ 1874e09069a29fc18d0799808cc26f71e9b068e98adEric Laurentvoid RadioService::convertProperties(radio_properties_t *properties, 1884e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent const radio_hal_properties_t *halProperties) 1894e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent{ 1904e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent memset(properties, 0, sizeof(struct radio_properties)); 1914e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent properties->class_id = halProperties->class_id; 1924e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent strlcpy(properties->implementor, halProperties->implementor, 1934e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent RADIO_STRING_LEN_MAX); 1944e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent strlcpy(properties->product, halProperties->product, 1954e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent RADIO_STRING_LEN_MAX); 1964e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent strlcpy(properties->version, halProperties->version, 1974e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent RADIO_STRING_LEN_MAX); 1984e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent strlcpy(properties->serial, halProperties->serial, 1994e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent RADIO_STRING_LEN_MAX); 2004e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent properties->num_tuners = halProperties->num_tuners; 2014e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent properties->num_audio_sources = halProperties->num_audio_sources; 2024e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent properties->supports_capture = halProperties->supports_capture; 2034e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 2044e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent for (size_t i = 0; i < ARRAY_SIZE(sKnownRegionConfigs); i++) { 2054e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent const radio_hal_band_config_t *band = &sKnownRegionConfigs[i].band; 2064e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent size_t j; 2074e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent for (j = 0; j < halProperties->num_bands; j++) { 2084e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent const radio_hal_band_config_t *halBand = &halProperties->bands[j]; 2094e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent size_t k; 2104e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (band->type != halBand->type) continue; 2114e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (band->lower_limit < halBand->lower_limit) continue; 2124e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (band->upper_limit > halBand->upper_limit) continue; 2134e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent for (k = 0; k < halBand->num_spacings; k++) { 2144e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (band->spacings[0] == halBand->spacings[k]) break; 2154e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 2164e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (k == halBand->num_spacings) continue; 2174e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (band->type == RADIO_BAND_AM) break; 2184e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if ((band->fm.deemphasis & halBand->fm.deemphasis) == 0) continue; 2194e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (halBand->fm.rds == 0) break; 2204e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if ((band->fm.rds & halBand->fm.rds) != 0) break; 2214e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 2224e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (j == halProperties->num_bands) continue; 2234e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 2244e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent ALOGI("convertProperties() Adding band type %d region %d", 2254e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent sKnownRegionConfigs[i].band.type , sKnownRegionConfigs[i].region); 2264e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 2274e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent memcpy(&properties->bands[properties->num_bands++], 2284e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent &sKnownRegionConfigs[i], 2294e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent sizeof(radio_band_config_t)); 2304e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 2314e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 2324e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 2334e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent#undef LOG_TAG 2344e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent#define LOG_TAG "RadioService::CallbackThread" 2354e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 2364e09069a29fc18d0799808cc26f71e9b068e98adEric LaurentRadioService::CallbackThread::CallbackThread(const wp<ModuleClient>& moduleClient) 2374e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent : mModuleClient(moduleClient), mMemoryDealer(new MemoryDealer(1024 * 1024, "RadioService")) 2384e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent{ 2394e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 2404e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 2414e09069a29fc18d0799808cc26f71e9b068e98adEric LaurentRadioService::CallbackThread::~CallbackThread() 2424e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent{ 2434e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent mEventQueue.clear(); 2444e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 2454e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 2464e09069a29fc18d0799808cc26f71e9b068e98adEric Laurentvoid RadioService::CallbackThread::onFirstRef() 2474e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent{ 2484e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent run("RadioService cbk", ANDROID_PRIORITY_URGENT_AUDIO); 2494e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 2504e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 2514e09069a29fc18d0799808cc26f71e9b068e98adEric Laurentbool RadioService::CallbackThread::threadLoop() 2524e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent{ 2534e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent while (!exitPending()) { 2544e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent sp<IMemory> eventMemory; 2554e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent sp<ModuleClient> moduleClient; 2564e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent { 2574e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent Mutex::Autolock _l(mCallbackLock); 2584e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent while (mEventQueue.isEmpty() && !exitPending()) { 2594e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent ALOGV("CallbackThread::threadLoop() sleep"); 2604e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent mCallbackCond.wait(mCallbackLock); 2614e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent ALOGV("CallbackThread::threadLoop() wake up"); 2624e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 2634e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (exitPending()) { 2644e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent break; 2654e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 2664e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent eventMemory = mEventQueue[0]; 2674e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent mEventQueue.removeAt(0); 2684e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent moduleClient = mModuleClient.promote(); 2694e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 2704e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (moduleClient != 0) { 2714e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent moduleClient->onCallbackEvent(eventMemory); 2724e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent eventMemory.clear(); 2734e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 2744e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 2754e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return false; 2764e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 2774e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 2784e09069a29fc18d0799808cc26f71e9b068e98adEric Laurentvoid RadioService::CallbackThread::exit() 2794e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent{ 2804e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent Mutex::Autolock _l(mCallbackLock); 2814e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent requestExit(); 2824e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent mCallbackCond.broadcast(); 2834e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 2844e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 2854e09069a29fc18d0799808cc26f71e9b068e98adEric Laurentsp<IMemory> RadioService::CallbackThread::prepareEvent(radio_hal_event_t *halEvent) 2864e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent{ 2874e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent sp<IMemory> eventMemory; 2884e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 289aebf5fbc6978ba6791690696e22a277be7eefa9bEric Laurent // The event layout in shared memory is: 290aebf5fbc6978ba6791690696e22a277be7eefa9bEric Laurent // sizeof(struct radio_event) bytes : the event itself 291aebf5fbc6978ba6791690696e22a277be7eefa9bEric Laurent // 4 bytes : metadata size or 0 292aebf5fbc6978ba6791690696e22a277be7eefa9bEric Laurent // N bytes : metadata if present 293aebf5fbc6978ba6791690696e22a277be7eefa9bEric Laurent uint32_t metadataOffset = sizeof(struct radio_event) + sizeof(uint32_t); 294aebf5fbc6978ba6791690696e22a277be7eefa9bEric Laurent uint32_t metadataSize = 0; 295aebf5fbc6978ba6791690696e22a277be7eefa9bEric Laurent 2964e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent switch (halEvent->type) { 2974e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent case RADIO_EVENT_TUNED: 2984e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent case RADIO_EVENT_AF_SWITCH: 2994e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (radio_metadata_check(halEvent->info.metadata) == 0) { 300aebf5fbc6978ba6791690696e22a277be7eefa9bEric Laurent metadataSize = (uint32_t)radio_metadata_get_size(halEvent->info.metadata); 3014e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 3024e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent break; 3034e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent case RADIO_EVENT_METADATA: 3044e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (radio_metadata_check(halEvent->metadata) != 0) { 3054e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return eventMemory; 3064e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 307aebf5fbc6978ba6791690696e22a277be7eefa9bEric Laurent metadataSize = (uint32_t)radio_metadata_get_size(halEvent->metadata); 3084e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent break; 3094e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent default: 3104e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent break; 3114e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 312aebf5fbc6978ba6791690696e22a277be7eefa9bEric Laurent 313aebf5fbc6978ba6791690696e22a277be7eefa9bEric Laurent eventMemory = mMemoryDealer->allocate(metadataOffset + metadataSize); 3144e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (eventMemory == 0 || eventMemory->pointer() == NULL) { 3154e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent eventMemory.clear(); 3164e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return eventMemory; 3174e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 318aebf5fbc6978ba6791690696e22a277be7eefa9bEric Laurent 3194e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent struct radio_event *event = (struct radio_event *)eventMemory->pointer(); 320aebf5fbc6978ba6791690696e22a277be7eefa9bEric Laurent 321aebf5fbc6978ba6791690696e22a277be7eefa9bEric Laurent *(uint32_t *)((uint8_t *)event + metadataOffset - sizeof(uint32_t)) = metadataSize; 322aebf5fbc6978ba6791690696e22a277be7eefa9bEric Laurent 3234e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent event->type = halEvent->type; 3244e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent event->status = halEvent->status; 3254e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 3264e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent switch (event->type) { 3274e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent case RADIO_EVENT_CONFIG: 3284e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent event->config.band = halEvent->config; 3294e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent break; 3304e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent case RADIO_EVENT_TUNED: 3314e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent case RADIO_EVENT_AF_SWITCH: 3324e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent event->info = halEvent->info; 3334e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (metadataSize != 0) { 334aebf5fbc6978ba6791690696e22a277be7eefa9bEric Laurent memcpy((uint8_t *)event + metadataOffset, halEvent->info.metadata, metadataSize); 3354e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 3364e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent break; 3374e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent case RADIO_EVENT_TA: 338f639ba1fdd4fd51d7ab97d2d8891a510615645f3Sanket Agarwal case RADIO_EVENT_EA: 3394e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent case RADIO_EVENT_ANTENNA: 3404e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent case RADIO_EVENT_CONTROL: 3414e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent event->on = halEvent->on; 3424e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent break; 3434e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent case RADIO_EVENT_METADATA: 344aebf5fbc6978ba6791690696e22a277be7eefa9bEric Laurent if (metadataSize != 0) { 345aebf5fbc6978ba6791690696e22a277be7eefa9bEric Laurent memcpy((uint8_t *)event + metadataOffset, halEvent->metadata, metadataSize); 346aebf5fbc6978ba6791690696e22a277be7eefa9bEric Laurent } 3474e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent break; 3484e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent case RADIO_EVENT_HW_FAILURE: 3494e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent default: 3504e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent break; 3514e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 3524e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 3534e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return eventMemory; 3544e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 3554e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 3564e09069a29fc18d0799808cc26f71e9b068e98adEric Laurentvoid RadioService::CallbackThread::sendEvent(radio_hal_event_t *event) 3574e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent { 3584e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent sp<IMemory> eventMemory = prepareEvent(event); 3594e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (eventMemory == 0) { 3604e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return; 3614e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 3624e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 3634e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent AutoMutex lock(mCallbackLock); 3644e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent mEventQueue.add(eventMemory); 3654e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent mCallbackCond.signal(); 3664e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent ALOGV("%s DONE", __FUNCTION__); 3674e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 3684e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 3694e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 3704e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent#undef LOG_TAG 3714e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent#define LOG_TAG "RadioService::Module" 3724e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 37301d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric LaurentRadioService::Module::Module(sp<RadioInterface> hwDevice, radio_properties properties) 37453810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent : mHwDevice(hwDevice), mProperties(properties), mMute(true) 3754e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent{ 3764e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 3774e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 3784e09069a29fc18d0799808cc26f71e9b068e98adEric LaurentRadioService::Module::~Module() { 37901d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent mHwDevice.clear(); 3804e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent mModuleClients.clear(); 3814e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 3824e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 3834e09069a29fc18d0799808cc26f71e9b068e98adEric Laurentstatus_t RadioService::Module::dump(int fd __unused, const Vector<String16>& args __unused) { 3844e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent String8 result; 3854e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return NO_ERROR; 3864e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 3874e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 3884e09069a29fc18d0799808cc26f71e9b068e98adEric Laurentsp<RadioService::ModuleClient> RadioService::Module::addClient(const sp<IRadioClient>& client, 3894e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent const struct radio_band_config *config, 3904e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent bool audio) 3914e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent{ 3924e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent ALOGV("addClient() %p config %p product %s", this, config, mProperties.product); 39301d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent 3944e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent AutoMutex lock(mLock); 3954e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent sp<ModuleClient> moduleClient; 3964e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent int ret; 3974e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 39801d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent if (mHwDevice == 0) { 39901d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent return moduleClient; 40001d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent } 40101d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent 4024e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent for (size_t i = 0; i < mModuleClients.size(); i++) { 4034e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (mModuleClients[i]->client() == client) { 4044e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent // client already connected: reject 4054e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return moduleClient; 4064e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 4074e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 4084e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent moduleClient = new ModuleClient(this, client, config, audio); 4094e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 4104e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent struct radio_hal_band_config halConfig; 4114e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent halConfig = config->band; 4124e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 41353810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent // Tuner preemption logic: 41453810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent // There is a limited amount of tuners and a limited amount of radio audio sources per module. 41553810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent // The minimum is one tuner and one audio source. 41653810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent // The numbers of tuners and sources are indicated in the module properties. 41753810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent // NOTE: current framework implementation only supports one radio audio source. 41853810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent // It is possible to open more than one tuner at a time but only one tuner can be connected 41953810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent // to the radio audio source (AUDIO_DEVICE_IN_FM_TUNER). 42053810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent // The base rule is that a newly connected tuner always wins, i.e. always gets a tuner 42153810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent // and can use the audio source if requested. 42253810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent // If another client is preempted, it is notified by a callback with RADIO_EVENT_CONTROL 42353810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent // indicating loss of control. 42453810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent // - If the newly connected client requests the audio source (audio == true): 42553810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent // - if an audio source is available 42653810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent // no problem 42753810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent // - if not: 42853810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent // the oldest client in the list using audio is preempted. 42953810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent // - If the newly connected client does not request the audio source (audio == false): 43053810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent // - if a tuner is available 43153810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent // no problem 43253810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent // - if not: 43353810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent // The oldest client not using audio is preempted first and if none is found the 43453810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent // the oldest client using audio is preempted. 43553810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent // Each time a tuner using the audio source is opened or closed, the audio policy manager is 43653810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent // notified of the connection or disconnection of AUDIO_DEVICE_IN_FM_TUNER. 43753810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent 4384e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent sp<ModuleClient> oldestTuner; 4394e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent sp<ModuleClient> oldestAudio; 4404e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent size_t allocatedTuners = 0; 4414e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent size_t allocatedAudio = 0; 4424e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent for (size_t i = 0; i < mModuleClients.size(); i++) { 4434e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (mModuleClients[i]->getTuner() != NULL) { 4444e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (mModuleClients[i]->audio()) { 4454e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (oldestAudio == 0) { 4464e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent oldestAudio = mModuleClients[i]; 4474e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 4484e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent allocatedAudio++; 4494e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } else { 4504e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (oldestTuner == 0) { 4514e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent oldestTuner = mModuleClients[i]; 4524e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 4534e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent allocatedTuners++; 4544e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 4554e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 4564e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 4574e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 45801d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent sp<TunerInterface> halTuner; 45953810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent sp<ModuleClient> preemtedClient; 4604e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (audio) { 4614e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (allocatedAudio >= mProperties.num_audio_sources) { 4624e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent ALOG_ASSERT(oldestAudio != 0, "addClient() allocatedAudio/oldestAudio mismatch"); 46353810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent preemtedClient = oldestAudio; 4644e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 4654e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } else { 4664e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (allocatedAudio + allocatedTuners >= mProperties.num_tuners) { 4674e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (allocatedTuners != 0) { 4684e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent ALOG_ASSERT(oldestTuner != 0, "addClient() allocatedTuners/oldestTuner mismatch"); 46953810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent preemtedClient = oldestTuner; 4704e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } else { 4714e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent ALOG_ASSERT(oldestAudio != 0, "addClient() allocatedAudio/oldestAudio mismatch"); 47253810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent preemtedClient = oldestAudio; 4734e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 4744e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 4754e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 47653810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent if (preemtedClient != 0) { 47753810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent halTuner = preemtedClient->getTuner(); 47801d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent sp<TunerInterface> clear; 47901d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent preemtedClient->setTuner(clear); 48001d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent mHwDevice->closeTuner(halTuner); 48153810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent if (preemtedClient->audio()) { 48253810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent notifyDeviceConnection(false, ""); 48353810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent } 48453810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent } 4854e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 48601d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent ret = mHwDevice->openTuner(&halConfig, audio, 48701d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent moduleClient, 48801d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent halTuner); 4894e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (ret == 0) { 49001d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent ALOGV("addClient() setTuner %p", halTuner.get()); 4914e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent moduleClient->setTuner(halTuner); 4924e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent mModuleClients.add(moduleClient); 49353810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent if (audio) { 49453810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent notifyDeviceConnection(true, ""); 49553810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent } 496f2f79cfcdec89052f49b74f9aab48e58daf606c6Eric Laurent ALOGV("addClient() DONE moduleClient %p", moduleClient.get()); 4974e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } else { 498f2f79cfcdec89052f49b74f9aab48e58daf606c6Eric Laurent ALOGW("%s open_tuner failed with error %d", __FUNCTION__, ret); 4994e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent moduleClient.clear(); 5004e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 5014e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 5024e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return moduleClient; 5034e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 5044e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 5054e09069a29fc18d0799808cc26f71e9b068e98adEric Laurentvoid RadioService::Module::removeClient(const sp<ModuleClient>& moduleClient) { 5064e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent ALOGV("removeClient()"); 5074e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent AutoMutex lock(mLock); 5084e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent int ret; 5094e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent ssize_t index = -1; 5104e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 5114e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent for (size_t i = 0; i < mModuleClients.size(); i++) { 5124e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (mModuleClients[i] == moduleClient) { 5134e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent index = i; 5144e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent break; 5154e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 5164e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 5174e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (index == -1) { 5184e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return; 5194e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 5204e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 5214e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent mModuleClients.removeAt(index); 52201d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent sp<TunerInterface> halTuner = moduleClient->getTuner(); 5234e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (halTuner == NULL) { 5244e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return; 5254e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 5264e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 52701d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent if (mHwDevice != 0) { 52801d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent mHwDevice->closeTuner(halTuner); 52901d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent } 53001d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent 53153810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent if (moduleClient->audio()) { 53253810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent notifyDeviceConnection(false, ""); 53353810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent } 5344e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 5354e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent mMute = true; 5364e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 5374e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (mModuleClients.isEmpty()) { 5384e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return; 5394e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 5404e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 54101d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent if (mHwDevice == 0) { 54201d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent return; 54301d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent } 54401d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent 54553810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent // Tuner reallocation logic: 54653810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent // When a client is removed and was controlling a tuner, this tuner will be allocated to a 54753810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent // previously preempted client. This client will be notified by a callback with 54853810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent // RADIO_EVENT_CONTROL indicating gain of control. 54953810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent // - If a preempted client is waiting for an audio source and one becomes available: 55053810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent // Allocate the tuner to the most recently added client waiting for an audio source 55153810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent // - If not: 55253810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent // Allocate the tuner to the most recently added client. 55353810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent // Each time a tuner using the audio source is opened or closed, the audio policy manager is 55453810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent // notified of the connection or disconnection of AUDIO_DEVICE_IN_FM_TUNER. 55553810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent 5564e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent sp<ModuleClient> youngestClient; 5574e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent sp<ModuleClient> youngestClientAudio; 5584e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent size_t allocatedTuners = 0; 5594e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent size_t allocatedAudio = 0; 56053810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent for (ssize_t i = mModuleClients.size() - 1; i >= 0; i--) { 5614e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (mModuleClients[i]->getTuner() == NULL) { 5624e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (mModuleClients[i]->audio()) { 5634e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (youngestClientAudio == 0) { 5644e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent youngestClientAudio = mModuleClients[i]; 5654e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 5664e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } else { 5674e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (youngestClient == 0) { 5684e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent youngestClient = mModuleClients[i]; 5694e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 5704e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 5714e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } else { 5724e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (mModuleClients[i]->audio()) { 5734e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent allocatedAudio++; 5744e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } else { 5754e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent allocatedTuners++; 5764e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 5774e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 5784e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 5794e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 5804e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent ALOG_ASSERT(allocatedTuners + allocatedAudio < mProperties.num_tuners, 5814e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent "removeClient() removed client but no tuner available"); 5824e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 5834e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent ALOG_ASSERT(!moduleClient->audio() || allocatedAudio < mProperties.num_audio_sources, 5844e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent "removeClient() removed audio client but no tuner with audio available"); 5854e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 5864e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (allocatedAudio < mProperties.num_audio_sources && youngestClientAudio != 0) { 5874e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent youngestClient = youngestClientAudio; 5884e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 5894e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 5904e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent ALOG_ASSERT(youngestClient != 0, "removeClient() removed client no candidate found for tuner"); 5914e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 5924e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent struct radio_hal_band_config halConfig = youngestClient->halConfig(); 59301d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent ret = mHwDevice->openTuner(&halConfig, youngestClient->audio(), 59401d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent moduleClient, 59501d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent halTuner); 5964e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 5974e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (ret == 0) { 5984e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent youngestClient->setTuner(halTuner); 59953810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent if (youngestClient->audio()) { 60053810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent notifyDeviceConnection(true, ""); 60153810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent } 6024e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 6034e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 6044e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 6054e09069a29fc18d0799808cc26f71e9b068e98adEric Laurentstatus_t RadioService::Module::setMute(bool mute) 6064e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent{ 6074e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent Mutex::Autolock _l(mLock); 6084e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (mute != mMute) { 6094e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent mMute = mute; 6104e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent //TODO notifify audio policy manager of media activity on radio audio device 6114e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 6124e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return NO_ERROR; 6134e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 6144e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 6154e09069a29fc18d0799808cc26f71e9b068e98adEric Laurentstatus_t RadioService::Module::getMute(bool *mute) 6164e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent{ 6174e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent Mutex::Autolock _l(mLock); 6184e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent *mute = mMute; 6194e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return NO_ERROR; 6204e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 6214e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 6224e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 6234e09069a29fc18d0799808cc26f71e9b068e98adEric Laurentconst struct radio_band_config *RadioService::Module::getDefaultConfig() const 6244e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent{ 6254e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (mProperties.num_bands == 0) { 6264e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return NULL; 6274e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 6284e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return &mProperties.bands[0]; 6294e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 6304e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 63153810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurentvoid RadioService::Module::notifyDeviceConnection(bool connected, 63253810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent const char *address) { 63353810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent int64_t token = IPCThreadState::self()->clearCallingIdentity(); 63453810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent AudioSystem::setDeviceConnectionState(AUDIO_DEVICE_IN_FM_TUNER, 63553810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent connected ? AUDIO_POLICY_DEVICE_STATE_AVAILABLE : 63653810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, 63753810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent address, kRadioTunerAudioDeviceName); 63853810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent IPCThreadState::self()->restoreCallingIdentity(token); 63953810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent} 64053810823a6613f54fc0b3c3bc0de267dc1f4e1e5Eric Laurent 6414e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent#undef LOG_TAG 6424e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent#define LOG_TAG "RadioService::ModuleClient" 6434e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 6444e09069a29fc18d0799808cc26f71e9b068e98adEric LaurentRadioService::ModuleClient::ModuleClient(const sp<Module>& module, 6454e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent const sp<IRadioClient>& client, 6464e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent const struct radio_band_config *config, 6474e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent bool audio) 64801d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent : mModule(module), mClient(client), mConfig(*config), mAudio(audio), mTuner(0) 6494e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent{ 6504e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 6514e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 6524e09069a29fc18d0799808cc26f71e9b068e98adEric Laurentvoid RadioService::ModuleClient::onFirstRef() 6534e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent{ 6544e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent mCallbackThread = new CallbackThread(this); 6554e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent IInterface::asBinder(mClient)->linkToDeath(this); 6564e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 6574e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 6584e09069a29fc18d0799808cc26f71e9b068e98adEric LaurentRadioService::ModuleClient::~ModuleClient() { 6594e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (mClient != 0) { 6604e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent IInterface::asBinder(mClient)->unlinkToDeath(this); 6614e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent mClient.clear(); 6624e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 6634e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (mCallbackThread != 0) { 6644e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent mCallbackThread->exit(); 6654e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 6664e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 6674e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 66801d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurentvoid RadioService::ModuleClient::onEvent(radio_hal_event_t *halEvent) 66901d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent{ 67001d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent mCallbackThread->sendEvent(halEvent); 67101d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent} 67201d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent 6734e09069a29fc18d0799808cc26f71e9b068e98adEric Laurentstatus_t RadioService::ModuleClient::dump(int fd __unused, 6744e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent const Vector<String16>& args __unused) { 6754e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent String8 result; 6764e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return NO_ERROR; 6774e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 6784e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 6794e09069a29fc18d0799808cc26f71e9b068e98adEric Laurentvoid RadioService::ModuleClient::detach() { 6804e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent ALOGV("%s", __FUNCTION__); 6814e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent sp<ModuleClient> strongMe = this; 6824e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent { 6834e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent AutoMutex lock(mLock); 6844e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (mClient != 0) { 6854e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent IInterface::asBinder(mClient)->unlinkToDeath(this); 6864e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent mClient.clear(); 6874e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 6884e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 6894e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent sp<Module> module = mModule.promote(); 6904e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (module == 0) { 6914e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return; 6924e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 6934e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent module->removeClient(this); 6944e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 6954e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 6964e09069a29fc18d0799808cc26f71e9b068e98adEric Laurentradio_hal_band_config_t RadioService::ModuleClient::halConfig() const 6974e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent{ 6984e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent AutoMutex lock(mLock); 6994e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent ALOGV("%s locked", __FUNCTION__); 7004e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return mConfig.band; 7014e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 7024e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 70301d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurentsp<TunerInterface>& RadioService::ModuleClient::getTuner() 7044e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent{ 7054e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent AutoMutex lock(mLock); 7064e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent ALOGV("%s locked", __FUNCTION__); 7074e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return mTuner; 7084e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 7094e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 71001d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurentvoid RadioService::ModuleClient::setTuner(sp<TunerInterface>& tuner) 7114e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent{ 7124e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent ALOGV("%s %p", __FUNCTION__, this); 7134e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 7144e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent AutoMutex lock(mLock); 7154e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent mTuner = tuner; 7164e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent ALOGV("%s locked", __FUNCTION__); 7174e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 7184e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent radio_hal_event_t event; 7194e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent event.type = RADIO_EVENT_CONTROL; 7204e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent event.status = 0; 72101d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent event.on = mTuner != 0; 7224e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent mCallbackThread->sendEvent(&event); 7234e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent ALOGV("%s DONE", __FUNCTION__); 7244e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 7254e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 7264e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 7274e09069a29fc18d0799808cc26f71e9b068e98adEric Laurentstatus_t RadioService::ModuleClient::setConfiguration(const struct radio_band_config *config) 7284e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent{ 7290e37854e54944892b15a72ed4633f0347dbc2cb8Keun-young Park if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) { 7300e37854e54944892b15a72ed4633f0347dbc2cb8Keun-young Park return PERMISSION_DENIED; 7310e37854e54944892b15a72ed4633f0347dbc2cb8Keun-young Park } 7324e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent AutoMutex lock(mLock); 7334e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent status_t status = NO_ERROR; 7344e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent ALOGV("%s locked", __FUNCTION__); 7354e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 73601d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent if (mTuner != 0) { 7374e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent struct radio_hal_band_config halConfig; 7384e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent halConfig = config->band; 73901d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent status = (status_t)mTuner->setConfiguration(&halConfig); 7404e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (status == NO_ERROR) { 7414e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent mConfig = *config; 7424e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 7434e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } else { 7444e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent mConfig = *config; 7451395874b91ddcd29e36d2bb6b86567f6f2319efcAurimas Liutikas status = INVALID_OPERATION; 7464e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 7474e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 7484e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return status; 7494e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 7504e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 7514e09069a29fc18d0799808cc26f71e9b068e98adEric Laurentstatus_t RadioService::ModuleClient::getConfiguration(struct radio_band_config *config) 7524e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent{ 7530e37854e54944892b15a72ed4633f0347dbc2cb8Keun-young Park if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) { 7540e37854e54944892b15a72ed4633f0347dbc2cb8Keun-young Park return PERMISSION_DENIED; 7550e37854e54944892b15a72ed4633f0347dbc2cb8Keun-young Park } 7564e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent AutoMutex lock(mLock); 7574e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent status_t status = NO_ERROR; 7584e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent ALOGV("%s locked", __FUNCTION__); 7594e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 76001d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent if (mTuner != 0) { 7614e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent struct radio_hal_band_config halConfig; 76201d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent status = (status_t)mTuner->getConfiguration(&halConfig); 7634e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (status == NO_ERROR) { 7644e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent mConfig.band = halConfig; 7654e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 7664e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 7674e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent *config = mConfig; 7684e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 7694e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return status; 7704e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 7714e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 7724e09069a29fc18d0799808cc26f71e9b068e98adEric Laurentstatus_t RadioService::ModuleClient::setMute(bool mute) 7734e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent{ 7740e37854e54944892b15a72ed4633f0347dbc2cb8Keun-young Park if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) { 7750e37854e54944892b15a72ed4633f0347dbc2cb8Keun-young Park return PERMISSION_DENIED; 7760e37854e54944892b15a72ed4633f0347dbc2cb8Keun-young Park } 7774e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent sp<Module> module; 7784e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent { 7794e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent Mutex::Autolock _l(mLock); 7804e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent ALOGV("%s locked", __FUNCTION__); 78101d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent if (mTuner == 0 || !mAudio) { 7824e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return INVALID_OPERATION; 7834e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 7844e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent module = mModule.promote(); 7854e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (module == 0) { 7864e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return NO_INIT; 7874e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 7884e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 7894e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent module->setMute(mute); 7904e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return NO_ERROR; 7914e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 7924e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 7934e09069a29fc18d0799808cc26f71e9b068e98adEric Laurentstatus_t RadioService::ModuleClient::getMute(bool *mute) 7944e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent{ 7950e37854e54944892b15a72ed4633f0347dbc2cb8Keun-young Park if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) { 7960e37854e54944892b15a72ed4633f0347dbc2cb8Keun-young Park return PERMISSION_DENIED; 7970e37854e54944892b15a72ed4633f0347dbc2cb8Keun-young Park } 7984e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent sp<Module> module; 7994e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent { 8004e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent Mutex::Autolock _l(mLock); 8014e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent ALOGV("%s locked", __FUNCTION__); 8024e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent module = mModule.promote(); 8034e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (module == 0) { 8044e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return NO_INIT; 8054e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 8064e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 8074e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return module->getMute(mute); 8084e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 8094e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 8104e09069a29fc18d0799808cc26f71e9b068e98adEric Laurentstatus_t RadioService::ModuleClient::scan(radio_direction_t direction, bool skipSubChannel) 8114e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent{ 8120e37854e54944892b15a72ed4633f0347dbc2cb8Keun-young Park if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) { 8130e37854e54944892b15a72ed4633f0347dbc2cb8Keun-young Park return PERMISSION_DENIED; 8140e37854e54944892b15a72ed4633f0347dbc2cb8Keun-young Park } 8154e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent AutoMutex lock(mLock); 8164e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent ALOGV("%s locked", __FUNCTION__); 8174e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent status_t status; 81801d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent if (mTuner != 0) { 81901d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent status = (status_t)mTuner->scan(direction, skipSubChannel); 8204e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } else { 8214e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent status = INVALID_OPERATION; 8224e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 8234e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return status; 8244e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 8254e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 8264e09069a29fc18d0799808cc26f71e9b068e98adEric Laurentstatus_t RadioService::ModuleClient::step(radio_direction_t direction, bool skipSubChannel) 8274e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent{ 8280e37854e54944892b15a72ed4633f0347dbc2cb8Keun-young Park if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) { 8290e37854e54944892b15a72ed4633f0347dbc2cb8Keun-young Park return PERMISSION_DENIED; 8300e37854e54944892b15a72ed4633f0347dbc2cb8Keun-young Park } 8314e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent AutoMutex lock(mLock); 8324e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent ALOGV("%s locked", __FUNCTION__); 8334e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent status_t status; 83401d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent if (mTuner != 0) { 83501d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent status = (status_t)mTuner->step(direction, skipSubChannel); 8364e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } else { 8374e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent status = INVALID_OPERATION; 8384e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 8394e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return status; 8404e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 8414e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 84201d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurentstatus_t RadioService::ModuleClient::tune(uint32_t channel, uint32_t subChannel) 8434e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent{ 8440e37854e54944892b15a72ed4633f0347dbc2cb8Keun-young Park if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) { 8450e37854e54944892b15a72ed4633f0347dbc2cb8Keun-young Park return PERMISSION_DENIED; 8460e37854e54944892b15a72ed4633f0347dbc2cb8Keun-young Park } 8474e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent AutoMutex lock(mLock); 8484e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent ALOGV("%s locked", __FUNCTION__); 8494e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent status_t status; 85001d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent if (mTuner != 0) { 85101d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent status = (status_t)mTuner->tune(channel, subChannel); 8524e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } else { 8534e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent status = INVALID_OPERATION; 8544e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 8554e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return status; 8564e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 8574e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 8584e09069a29fc18d0799808cc26f71e9b068e98adEric Laurentstatus_t RadioService::ModuleClient::cancel() 8594e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent{ 8600e37854e54944892b15a72ed4633f0347dbc2cb8Keun-young Park if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) { 8610e37854e54944892b15a72ed4633f0347dbc2cb8Keun-young Park return PERMISSION_DENIED; 8620e37854e54944892b15a72ed4633f0347dbc2cb8Keun-young Park } 8634e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent AutoMutex lock(mLock); 8644e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent ALOGV("%s locked", __FUNCTION__); 8654e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent status_t status; 86601d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent if (mTuner != 0) { 86701d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent status = (status_t)mTuner->cancel(); 8684e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } else { 8694e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent status = INVALID_OPERATION; 8704e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 8714e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return status; 8724e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 8734e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 8744e09069a29fc18d0799808cc26f71e9b068e98adEric Laurentstatus_t RadioService::ModuleClient::getProgramInformation(struct radio_program_info *info) 8754e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent{ 8760e37854e54944892b15a72ed4633f0347dbc2cb8Keun-young Park if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) { 8770e37854e54944892b15a72ed4633f0347dbc2cb8Keun-young Park return PERMISSION_DENIED; 8780e37854e54944892b15a72ed4633f0347dbc2cb8Keun-young Park } 8794e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent AutoMutex lock(mLock); 8804e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent ALOGV("%s locked", __FUNCTION__); 8814e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent status_t status; 8824e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (mTuner != NULL) { 88301d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent status = (status_t)mTuner->getProgramInformation(info); 8844e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } else { 8854e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent status = INVALID_OPERATION; 8864e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 887aebf5fbc6978ba6791690696e22a277be7eefa9bEric Laurent 8884e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return status; 8894e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 8904e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 8914e09069a29fc18d0799808cc26f71e9b068e98adEric Laurentstatus_t RadioService::ModuleClient::hasControl(bool *hasControl) 8924e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent{ 8930e37854e54944892b15a72ed4633f0347dbc2cb8Keun-young Park if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) { 8940e37854e54944892b15a72ed4633f0347dbc2cb8Keun-young Park return PERMISSION_DENIED; 8950e37854e54944892b15a72ed4633f0347dbc2cb8Keun-young Park } 8964e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent Mutex::Autolock lock(mLock); 8974e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent ALOGV("%s locked", __FUNCTION__); 89801d267e3a78e1fa78d27f6d3e745914a5ac56ffaEric Laurent *hasControl = mTuner != 0; 8994e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return NO_ERROR; 9004e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 9014e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 9024e09069a29fc18d0799808cc26f71e9b068e98adEric Laurentvoid RadioService::ModuleClient::onCallbackEvent(const sp<IMemory>& eventMemory) 9034e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent{ 9044e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (eventMemory == 0 || eventMemory->pointer() == NULL) { 9054e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent return; 9064e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 9074e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 9084e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent sp<IRadioClient> client; 9094e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent { 9104e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent AutoMutex lock(mLock); 9114e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent ALOGV("%s locked", __FUNCTION__); 9124e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent radio_event_t *event = (radio_event_t *)eventMemory->pointer(); 9134e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent switch (event->type) { 9144e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent case RADIO_EVENT_CONFIG: 9154e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent mConfig.band = event->config.band; 9164e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent event->config.region = mConfig.region; 9174e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent break; 9184e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent default: 9194e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent break; 9204e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 9214e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 9224e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent client = mClient; 9234e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 9244e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent if (client != 0) { 9254e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent client->onEvent(eventMemory); 9264e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent } 9274e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 9284e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 9294e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 9304e09069a29fc18d0799808cc26f71e9b068e98adEric Laurentvoid RadioService::ModuleClient::binderDied( 9314e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent const wp<IBinder> &who __unused) { 9324e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent ALOGW("client binder died for client %p", this); 9334e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent detach(); 9344e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent} 9354e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent 9364e09069a29fc18d0799808cc26f71e9b068e98adEric Laurent}; // namespace android 937