blob: 6e82b8b978589d1b754de534a6fb2c19d94299be [file] [log] [blame]
Amy126ee922019-08-09 16:25:12 -07001/*
2 * Copyright (C) 2019 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
17#define LOG_TAG "android.hardware.tv.tuner@1.0-Frontend"
18
19#include "Frontend.h"
20#include <android/hardware/tv/tuner/1.0/IFrontendCallback.h>
21#include <utils/Log.h>
22
23namespace android {
24namespace hardware {
25namespace tv {
26namespace tuner {
27namespace V1_0 {
28namespace implementation {
29
Amy5094ae12019-10-04 18:43:21 -070030Frontend::Frontend(FrontendType type, FrontendId id, sp<Tuner> tuner) {
Amy126ee922019-08-09 16:25:12 -070031 mType = type;
32 mId = id;
Amy5094ae12019-10-04 18:43:21 -070033 mTunerService = tuner;
Amy126ee922019-08-09 16:25:12 -070034 // Init callback to nullptr
35 mCallback = nullptr;
36}
37
38Frontend::~Frontend() {}
39
40Return<Result> Frontend::close() {
41 ALOGV("%s", __FUNCTION__);
42 // Reset callback
43 mCallback = nullptr;
Amy Zhang050bf782020-03-27 14:54:48 -070044 mIsLocked = false;
Amy Zhang45c12632020-07-16 14:06:25 -070045 mTunerService->removeFrontend(mId);
Amy126ee922019-08-09 16:25:12 -070046
47 return Result::SUCCESS;
48}
49
50Return<Result> Frontend::setCallback(const sp<IFrontendCallback>& callback) {
51 ALOGV("%s", __FUNCTION__);
52 if (callback == nullptr) {
53 ALOGW("[ WARN ] Set Frontend callback with nullptr");
54 return Result::INVALID_ARGUMENT;
55 }
56
57 mCallback = callback;
58 return Result::SUCCESS;
59}
60
61Return<Result> Frontend::tune(const FrontendSettings& /* settings */) {
62 ALOGV("%s", __FUNCTION__);
63 if (mCallback == nullptr) {
64 ALOGW("[ WARN ] Frontend callback is not set when tune");
65 return Result::INVALID_STATE;
66 }
67
Amy Zhang0fe25be2020-04-08 17:30:52 -070068 mTunerService->frontendStartTune(mId);
Amy5094ae12019-10-04 18:43:21 -070069 mCallback->onEvent(FrontendEventType::LOCKED);
Amy Zhange0422232020-06-12 12:53:12 -070070 mIsLocked = true;
Amy126ee922019-08-09 16:25:12 -070071 return Result::SUCCESS;
72}
73
74Return<Result> Frontend::stopTune() {
75 ALOGV("%s", __FUNCTION__);
76
Amy5094ae12019-10-04 18:43:21 -070077 mTunerService->frontendStopTune(mId);
Amy Zhang050bf782020-03-27 14:54:48 -070078 mIsLocked = false;
Amy5094ae12019-10-04 18:43:21 -070079
Amy126ee922019-08-09 16:25:12 -070080 return Result::SUCCESS;
81}
82
Amy Zhang050bf782020-03-27 14:54:48 -070083Return<Result> Frontend::scan(const FrontendSettings& settings, FrontendScanType type) {
Amy016b7312019-09-16 15:51:28 -070084 ALOGV("%s", __FUNCTION__);
85
shubang71d60592020-04-10 18:08:49 -070086 if (mType == FrontendType::ATSC) {
shubanga990ece2020-04-17 18:25:45 -070087 FrontendScanMessage msg;
88 msg.isLocked(true);
89 mCallback->onScanMessage(FrontendScanMessageType::LOCKED, msg);
90 mIsLocked = true;
shubang71d60592020-04-10 18:08:49 -070091 return Result::SUCCESS;
92 }
Amy Zhang050bf782020-03-27 14:54:48 -070093 if (mType != FrontendType::DVBT) {
94 return Result::UNAVAILABLE;
95 }
96
Amyc830cfb2020-02-06 15:47:20 -080097 FrontendScanMessage msg;
Amy Zhang050bf782020-03-27 14:54:48 -070098
99 if (mIsLocked) {
100 msg.isEnd(true);
101 mCallback->onScanMessage(FrontendScanMessageType::END, msg);
102 return Result::SUCCESS;
103 }
104
105 uint32_t frequency = settings.dvbt().frequency;
106 if (type == FrontendScanType::SCAN_BLIND) {
Gareth Fennb629a5d2021-09-27 15:14:11 +0100107 frequency += 100 * 1000;
Amy Zhang050bf782020-03-27 14:54:48 -0700108 }
109 msg.frequencies({frequency});
110 mCallback->onScanMessage(FrontendScanMessageType::FREQUENCY, msg);
Amyc830cfb2020-02-06 15:47:20 -0800111 msg.isLocked(true);
112 mCallback->onScanMessage(FrontendScanMessageType::LOCKED, msg);
Amy Zhang050bf782020-03-27 14:54:48 -0700113 mIsLocked = true;
Amyc830cfb2020-02-06 15:47:20 -0800114
Amy016b7312019-09-16 15:51:28 -0700115 return Result::SUCCESS;
116}
117
118Return<Result> Frontend::stopScan() {
119 ALOGV("%s", __FUNCTION__);
120
Amy Zhang050bf782020-03-27 14:54:48 -0700121 mIsLocked = false;
Amy016b7312019-09-16 15:51:28 -0700122 return Result::SUCCESS;
123}
124
shubangba232e42020-01-29 10:49:10 -0800125Return<void> Frontend::getStatus(const hidl_vec<FrontendStatusType>& statusTypes,
Amy016b7312019-09-16 15:51:28 -0700126 getStatus_cb _hidl_cb) {
127 ALOGV("%s", __FUNCTION__);
128
129 vector<FrontendStatus> statuses;
shubangba232e42020-01-29 10:49:10 -0800130 for (int i = 0; i < statusTypes.size(); i++) {
131 FrontendStatusType type = statusTypes[i];
132 FrontendStatus status;
133 // assign randomly selected values for testing.
134 switch (type) {
135 case FrontendStatusType::DEMOD_LOCK: {
136 status.isDemodLocked(true);
137 break;
138 }
139 case FrontendStatusType::SNR: {
140 status.snr(221);
141 break;
142 }
shubang6ab3f082020-05-01 17:26:08 -0700143 case FrontendStatusType::BER: {
144 status.ber(1);
145 break;
146 }
147 case FrontendStatusType::PER: {
148 status.per(2);
149 break;
150 }
151 case FrontendStatusType::PRE_BER: {
152 status.preBer(3);
153 break;
154 }
155 case FrontendStatusType::SIGNAL_QUALITY: {
156 status.signalQuality(4);
157 break;
158 }
159 case FrontendStatusType::SIGNAL_STRENGTH: {
160 status.signalStrength(5);
161 break;
162 }
163 case FrontendStatusType::SYMBOL_RATE: {
164 status.symbolRate(6);
165 break;
166 }
shubangba232e42020-01-29 10:49:10 -0800167 case FrontendStatusType::FEC: {
168 status.innerFec(FrontendInnerFec::FEC_2_9); // value = 1 << 7
169 break;
170 }
171 case FrontendStatusType::MODULATION: {
172 FrontendModulationStatus modulationStatus;
173 modulationStatus.isdbt(FrontendIsdbtModulation::MOD_16QAM); // value = 1 << 3
174 status.modulation(modulationStatus);
175 break;
176 }
shubang6ab3f082020-05-01 17:26:08 -0700177 case FrontendStatusType::SPECTRAL: {
178 status.inversion(FrontendDvbcSpectralInversion::NORMAL);
179 break;
180 }
181 case FrontendStatusType::LNB_VOLTAGE: {
182 status.lnbVoltage(LnbVoltage::VOLTAGE_5V);
183 break;
184 }
shubangba232e42020-01-29 10:49:10 -0800185 case FrontendStatusType::PLP_ID: {
186 status.plpId(101); // type uint8_t
187 break;
188 }
shubang6ab3f082020-05-01 17:26:08 -0700189 case FrontendStatusType::EWBS: {
190 status.isEWBS(false);
191 break;
192 }
193 case FrontendStatusType::AGC: {
194 status.agc(7);
195 break;
196 }
197 case FrontendStatusType::LNA: {
198 status.isLnaOn(false);
199 break;
200 }
shubangba232e42020-01-29 10:49:10 -0800201 case FrontendStatusType::LAYER_ERROR: {
202 vector<bool> v = {false, true, true};
203 status.isLayerError(v);
204 break;
205 }
shubang6ab3f082020-05-01 17:26:08 -0700206 case FrontendStatusType::MER: {
207 status.mer(8);
208 break;
209 }
210 case FrontendStatusType::FREQ_OFFSET: {
211 status.freqOffset(9);
212 break;
213 }
214 case FrontendStatusType::HIERARCHY: {
215 status.hierarchy(FrontendDvbtHierarchy::HIERARCHY_1_NATIVE);
216 break;
217 }
218 case FrontendStatusType::RF_LOCK: {
219 status.isRfLocked(false);
220 break;
221 }
shubangba232e42020-01-29 10:49:10 -0800222 case FrontendStatusType::ATSC3_PLP_INFO: {
223 vector<FrontendStatusAtsc3PlpInfo> v;
224 FrontendStatusAtsc3PlpInfo info1{
225 .plpId = 3,
226 .isLocked = false,
227 .uec = 313,
228 };
229 FrontendStatusAtsc3PlpInfo info2{
230 .plpId = 5,
231 .isLocked = true,
232 .uec = 515,
233 };
234 v.push_back(info1);
235 v.push_back(info2);
236 status.plpInfo(v);
237 break;
238 }
239 default: {
240 continue;
241 }
242 }
243 statuses.push_back(status);
244 }
Amy016b7312019-09-16 15:51:28 -0700245 _hidl_cb(Result::SUCCESS, statuses);
246
247 return Void();
248}
249
250Return<Result> Frontend::setLna(bool /* bEnable */) {
251 ALOGV("%s", __FUNCTION__);
252
253 return Result::SUCCESS;
254}
255
Amy42a5b4b2019-10-03 16:49:48 -0700256Return<Result> Frontend::setLnb(uint32_t /* lnb */) {
Amy016b7312019-09-16 15:51:28 -0700257 ALOGV("%s", __FUNCTION__);
Amy Zhangcda23ea2020-06-02 18:57:42 -0700258 if (!supportsSatellite()) {
259 return Result::INVALID_STATE;
260 }
Amy016b7312019-09-16 15:51:28 -0700261 return Result::SUCCESS;
262}
263
Amy126ee922019-08-09 16:25:12 -0700264FrontendType Frontend::getFrontendType() {
265 return mType;
266}
267
268FrontendId Frontend::getFrontendId() {
269 return mId;
270}
271
Amy Zhangcda23ea2020-06-02 18:57:42 -0700272bool Frontend::supportsSatellite() {
273 return mType == FrontendType::DVBS || mType == FrontendType::ISDBS ||
274 mType == FrontendType::ISDBS3;
275}
Amy Zhange0422232020-06-12 12:53:12 -0700276
277bool Frontend::isLocked() {
278 return mIsLocked;
279}
Amy126ee922019-08-09 16:25:12 -0700280} // namespace implementation
281} // namespace V1_0
282} // namespace tuner
283} // namespace tv
284} // namespace hardware
285} // namespace android