1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #include "BroadcastRadio.h" 17 18 #include "resources.h" 19 20 #include <android-base/logging.h> 21 22 namespace android { 23 namespace hardware { 24 namespace broadcastradio { 25 namespace V2_0 { 26 namespace implementation { 27 28 using std::lock_guard; 29 using std::map; 30 using std::mutex; 31 using std::vector; 32 33 static const AmFmRegionConfig gDefaultAmFmConfig = { // 34 { 35 {87500, 108000, 100, 100}, // FM 36 {153, 282, 3, 9}, // AM LW 37 {531, 1620, 9, 9}, // AM MW 38 {1600, 30000, 1, 5}, // AM SW 39 }, 40 static_cast<uint32_t>(Deemphasis::D50), 41 static_cast<uint32_t>(Rds::RDS)}; 42 43 static Properties initProperties(const VirtualRadio& virtualRadio) { 44 Properties prop = {}; 45 46 prop.maker = "Google"; 47 prop.product = virtualRadio.getName(); 48 prop.supportedIdentifierTypes = hidl_vec<uint32_t>({ 49 static_cast<uint32_t>(IdentifierType::AMFM_FREQUENCY), 50 static_cast<uint32_t>(IdentifierType::RDS_PI), 51 static_cast<uint32_t>(IdentifierType::HD_STATION_ID_EXT), 52 static_cast<uint32_t>(IdentifierType::DAB_SID_EXT), 53 }); 54 prop.vendorInfo = hidl_vec<VendorKeyValue>({ 55 {"com.google.dummy", "dummy"}, 56 }); 57 58 return prop; 59 } 60 61 BroadcastRadio::BroadcastRadio(const VirtualRadio& virtualRadio) 62 : mVirtualRadio(virtualRadio), 63 mProperties(initProperties(virtualRadio)), 64 mAmFmConfig(gDefaultAmFmConfig) {} 65 66 Return<void> BroadcastRadio::getProperties(getProperties_cb _hidl_cb) { 67 _hidl_cb(mProperties); 68 return {}; 69 } 70 71 AmFmRegionConfig BroadcastRadio::getAmFmConfig() const { 72 lock_guard<mutex> lk(mMut); 73 return mAmFmConfig; 74 } 75 76 Return<void> BroadcastRadio::getAmFmRegionConfig(bool full, getAmFmRegionConfig_cb _hidl_cb) { 77 if (full) { 78 AmFmRegionConfig config = {}; 79 config.ranges = hidl_vec<AmFmBandRange>({ 80 {65000, 108000, 10, 0}, // FM 81 {150, 30000, 1, 0}, // AM 82 }); 83 config.fmDeemphasis = Deemphasis::D50 | Deemphasis::D75; 84 config.fmRds = Rds::RDS | Rds::RBDS; 85 _hidl_cb(Result::OK, config); 86 return {}; 87 } else { 88 _hidl_cb(Result::OK, getAmFmConfig()); 89 return {}; 90 } 91 } 92 93 Return<void> BroadcastRadio::getDabRegionConfig(getDabRegionConfig_cb _hidl_cb) { 94 hidl_vec<DabTableEntry> config = { 95 {"5A", 174928}, {"7D", 194064}, {"8A", 195936}, {"8B", 197648}, {"9A", 202928}, 96 {"9B", 204640}, {"9C", 206352}, {"10B", 211648}, {"10C", 213360}, {"10D", 215072}, 97 {"11A", 216928}, {"11B", 218640}, {"11C", 220352}, {"11D", 222064}, {"12A", 223936}, 98 {"12B", 225648}, {"12C", 227360}, {"12D", 229072}, 99 }; 100 101 _hidl_cb(Result::OK, config); 102 return {}; 103 } 104 105 Return<void> BroadcastRadio::openSession(const sp<ITunerCallback>& callback, 106 openSession_cb _hidl_cb) { 107 LOG(DEBUG) << "opening new session..."; 108 109 /* For the needs of default implementation it's fine to instantiate new session object 110 * out of the lock scope. If your implementation needs it, use reentrant lock. 111 */ 112 sp<TunerSession> newSession = new TunerSession(*this, callback); 113 114 lock_guard<mutex> lk(mMut); 115 116 auto oldSession = mSession.promote(); 117 if (oldSession != nullptr) { 118 LOG(INFO) << "closing previously opened tuner"; 119 oldSession->close(); 120 mSession = nullptr; 121 } 122 123 mSession = newSession; 124 125 _hidl_cb(Result::OK, newSession); 126 return {}; 127 } 128 129 Return<void> BroadcastRadio::getImage(uint32_t id, getImage_cb _hidl_cb) { 130 LOG(DEBUG) << "fetching image " << std::hex << id; 131 132 if (id == resources::demoPngId) { 133 _hidl_cb(std::vector<uint8_t>(resources::demoPng, std::end(resources::demoPng))); 134 return {}; 135 } 136 137 LOG(INFO) << "image " << std::hex << id << " doesn't exists"; 138 _hidl_cb({}); 139 return {}; 140 } 141 142 Return<void> BroadcastRadio::registerAnnouncementListener( 143 const hidl_vec<AnnouncementType>& enabled, const sp<IAnnouncementListener>& /* listener */, 144 registerAnnouncementListener_cb _hidl_cb) { 145 LOG(DEBUG) << "registering announcement listener for " << toString(enabled); 146 147 _hidl_cb(Result::NOT_SUPPORTED, nullptr); 148 return {}; 149 } 150 151 } // namespace implementation 152 } // namespace V2_0 153 } // namespace broadcastradio 154 } // namespace hardware 155 } // namespace android 156