blob: 1fbe7f42fff3d9e7c1dd0966c69bea3bd6bcd2ef [file] [log] [blame]
shubang8ab43b12019-10-18 15:55:55 -07001/*
2 * Copyright 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 "TvTuner-JNI"
18#include <utils/Log.h>
19
20#include "android_media_tv_Tuner.h"
21#include "android_runtime/AndroidRuntime.h"
22
23#include <android/hardware/tv/tuner/1.0/ITuner.h>
24#include <media/stagefright/foundation/ADebug.h>
shubangba21a7f2019-12-05 16:58:55 -080025#include <nativehelper/JNIHelp.h>
shubang8ab43b12019-10-18 15:55:55 -070026
27#pragma GCC diagnostic ignored "-Wunused-function"
28
shubang6f473d62019-11-01 15:42:21 -070029using ::android::hardware::Void;
shubang7e849b02019-10-18 19:36:25 -070030using ::android::hardware::hidl_vec;
shubang030afb52019-11-27 16:09:02 -080031using ::android::hardware::tv::tuner::V1_0::DataFormat;
shubang6f473d62019-11-01 15:42:21 -070032using ::android::hardware::tv::tuner::V1_0::DemuxFilterMainType;
shubang75c87082019-11-15 11:26:56 -080033using ::android::hardware::tv::tuner::V1_0::DemuxFilterPesDataSettings;
34using ::android::hardware::tv::tuner::V1_0::DemuxFilterSettings;
shubang13f15e02019-11-04 17:51:02 -080035using ::android::hardware::tv::tuner::V1_0::DemuxMmtpPid;
shubang964e6132019-11-26 15:05:22 -080036using ::android::hardware::tv::tuner::V1_0::DemuxQueueNotifyBits;
shubang13f15e02019-11-04 17:51:02 -080037using ::android::hardware::tv::tuner::V1_0::DemuxTpid;
shubang75c87082019-11-15 11:26:56 -080038using ::android::hardware::tv::tuner::V1_0::DemuxTsFilterSettings;
shubang6f473d62019-11-01 15:42:21 -070039using ::android::hardware::tv::tuner::V1_0::DemuxTsFilterType;
shubang030afb52019-11-27 16:09:02 -080040using ::android::hardware::tv::tuner::V1_0::DvrSettings;
shubang74bfd482019-10-29 19:10:22 -070041using ::android::hardware::tv::tuner::V1_0::FrontendAnalogSettings;
42using ::android::hardware::tv::tuner::V1_0::FrontendAnalogSifStandard;
43using ::android::hardware::tv::tuner::V1_0::FrontendAnalogType;
shubangdeb067c2020-01-27 13:21:55 -080044using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3Bandwidth;
45using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3CodeRate;
46using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3DemodOutputFormat;
47using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3Fec;
48using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3Modulation;
49using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3PlpSettings;
50using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3Settings;
51using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3TimeInterleaveMode;
52using ::android::hardware::tv::tuner::V1_0::FrontendAtscSettings;
53using ::android::hardware::tv::tuner::V1_0::FrontendAtscModulation;
54using ::android::hardware::tv::tuner::V1_0::FrontendDvbcAnnex;
55using ::android::hardware::tv::tuner::V1_0::FrontendDvbcModulation;
56using ::android::hardware::tv::tuner::V1_0::FrontendDvbcOuterFec;
57using ::android::hardware::tv::tuner::V1_0::FrontendDvbcSettings;
58using ::android::hardware::tv::tuner::V1_0::FrontendDvbcSpectralInversion;
59using ::android::hardware::tv::tuner::V1_0::FrontendDvbsCodeRate;
60using ::android::hardware::tv::tuner::V1_0::FrontendDvbsModulation;
61using ::android::hardware::tv::tuner::V1_0::FrontendDvbsPilot;
62using ::android::hardware::tv::tuner::V1_0::FrontendDvbsRolloff;
63using ::android::hardware::tv::tuner::V1_0::FrontendDvbsSettings;
64using ::android::hardware::tv::tuner::V1_0::FrontendDvbsStandard;
65using ::android::hardware::tv::tuner::V1_0::FrontendDvbsVcmMode;
66using ::android::hardware::tv::tuner::V1_0::FrontendDvbtBandwidth;
67using ::android::hardware::tv::tuner::V1_0::FrontendDvbtCoderate;
68using ::android::hardware::tv::tuner::V1_0::FrontendDvbtConstellation;
69using ::android::hardware::tv::tuner::V1_0::FrontendDvbtGuardInterval;
70using ::android::hardware::tv::tuner::V1_0::FrontendDvbtHierarchy;
71using ::android::hardware::tv::tuner::V1_0::FrontendDvbtPlpMode;
72using ::android::hardware::tv::tuner::V1_0::FrontendDvbtSettings;
73using ::android::hardware::tv::tuner::V1_0::FrontendDvbtStandard;
74using ::android::hardware::tv::tuner::V1_0::FrontendDvbtTransmissionMode;
75using ::android::hardware::tv::tuner::V1_0::FrontendInnerFec;
76using ::android::hardware::tv::tuner::V1_0::FrontendIsdbs3Coderate;
77using ::android::hardware::tv::tuner::V1_0::FrontendIsdbs3Modulation;
78using ::android::hardware::tv::tuner::V1_0::FrontendIsdbs3Rolloff;
79using ::android::hardware::tv::tuner::V1_0::FrontendIsdbs3Settings;
80using ::android::hardware::tv::tuner::V1_0::FrontendIsdbsCoderate;
81using ::android::hardware::tv::tuner::V1_0::FrontendIsdbsModulation;
82using ::android::hardware::tv::tuner::V1_0::FrontendIsdbsRolloff;
83using ::android::hardware::tv::tuner::V1_0::FrontendIsdbsSettings;
84using ::android::hardware::tv::tuner::V1_0::FrontendIsdbsStreamIdType;
85using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtBandwidth;
86using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtCoderate;
87using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtGuardInterval;
88using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtMode;
89using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtModulation;
90using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtSettings;
91using ::android::hardware::tv::tuner::V1_0::FrontendType;
shubang8ab43b12019-10-18 15:55:55 -070092using ::android::hardware::tv::tuner::V1_0::ITuner;
shubang030afb52019-11-27 16:09:02 -080093using ::android::hardware::tv::tuner::V1_0::PlaybackSettings;
94using ::android::hardware::tv::tuner::V1_0::RecordSettings;
shubang7e849b02019-10-18 19:36:25 -070095using ::android::hardware::tv::tuner::V1_0::Result;
shubang8ab43b12019-10-18 15:55:55 -070096
97struct fields_t {
shubang13f15e02019-11-04 17:51:02 -080098 jfieldID tunerContext;
shubangcdf30de2019-11-06 17:28:38 -080099 jfieldID filterContext;
shubang13f15e02019-11-04 17:51:02 -0800100 jfieldID descramblerContext;
shubang4a0eddf2019-11-08 17:10:18 -0800101 jfieldID dvrContext;
shubang7e849b02019-10-18 19:36:25 -0700102 jmethodID frontendInitID;
shubang6f473d62019-11-01 15:42:21 -0700103 jmethodID filterInitID;
shubang4a0eddf2019-11-08 17:10:18 -0800104 jmethodID dvrInitID;
shubang4b8c5402019-10-24 17:49:53 -0700105 jmethodID onFrontendEventID;
shubangcdf30de2019-11-06 17:28:38 -0800106 jmethodID onFilterStatusID;
shubang760f0312019-11-12 17:11:28 -0800107 jmethodID lnbInitID;
108 jmethodID onLnbEventID;
shubang13f15e02019-11-04 17:51:02 -0800109 jmethodID descramblerInitID;
shubang8ab43b12019-10-18 15:55:55 -0700110};
111
112static fields_t gFields;
113
114namespace android {
shubang760f0312019-11-12 17:11:28 -0800115/////////////// LnbCallback ///////////////////////
116LnbCallback::LnbCallback(jweak tunerObj, LnbId id) : mObject(tunerObj), mId(id) {}
117
118Return<void> LnbCallback::onEvent(LnbEventType lnbEventType) {
119 ALOGD("LnbCallback::onEvent, type=%d", lnbEventType);
120 JNIEnv *env = AndroidRuntime::getJNIEnv();
121 env->CallVoidMethod(
122 mObject,
123 gFields.onLnbEventID,
124 (jint)lnbEventType);
125 return Void();
126}
127Return<void> LnbCallback::onDiseqcMessage(const hidl_vec<uint8_t>& /*diseqcMessage*/) {
128 ALOGD("LnbCallback::onDiseqcMessage");
129 return Void();
130}
131
shubang4a0eddf2019-11-08 17:10:18 -0800132/////////////// DvrCallback ///////////////////////
133Return<void> DvrCallback::onRecordStatus(RecordStatus /*status*/) {
134 ALOGD("DvrCallback::onRecordStatus");
135 return Void();
136}
137
138Return<void> DvrCallback::onPlaybackStatus(PlaybackStatus /*status*/) {
139 ALOGD("DvrCallback::onPlaybackStatus");
140 return Void();
141}
142
143void DvrCallback::setDvr(const jobject dvr) {
shubangba21a7f2019-12-05 16:58:55 -0800144 ALOGD("DvrCallback::setDvr");
shubang4a0eddf2019-11-08 17:10:18 -0800145 JNIEnv *env = AndroidRuntime::getJNIEnv();
146 mDvr = env->NewWeakGlobalRef(dvr);
147}
148
shubang9e700ff2019-12-04 16:26:51 -0800149/////////////// Dvr ///////////////////////
150
Greg Kaiser4aaee382020-01-07 09:42:10 -0800151Dvr::Dvr(sp<IDvr> sp, jweak obj) : mDvrSp(sp), mDvrObj(obj), mDvrMQEventFlag(nullptr) {}
shubang9e700ff2019-12-04 16:26:51 -0800152
shubangba21a7f2019-12-05 16:58:55 -0800153Dvr::~Dvr() {
154 EventFlag::deleteEventFlag(&mDvrMQEventFlag);
155}
156
157int Dvr::close() {
158 Result r = mDvrSp->close();
159 if (r == Result::SUCCESS) {
160 EventFlag::deleteEventFlag(&mDvrMQEventFlag);
161 }
162 return (int)r;
163}
164
shubang9e700ff2019-12-04 16:26:51 -0800165sp<IDvr> Dvr::getIDvr() {
166 return mDvrSp;
167}
168
shubang5f4ea352019-12-09 15:12:10 -0800169DvrMQ& Dvr::getDvrMQ() {
170 return *mDvrMQ;
171}
172
shubang6f473d62019-11-01 15:42:21 -0700173/////////////// FilterCallback ///////////////////////
174//TODO: implement filter callback
shubangcdf30de2019-11-06 17:28:38 -0800175Return<void> FilterCallback::onFilterEvent(const DemuxFilterEvent& /*filterEvent*/) {
shubang6f473d62019-11-01 15:42:21 -0700176 ALOGD("FilterCallback::onFilterEvent");
177 return Void();
178}
shubangcdf30de2019-11-06 17:28:38 -0800179
180Return<void> FilterCallback::onFilterStatus(const DemuxFilterStatus status) {
181 ALOGD("FilterCallback::onFilterStatus");
182 JNIEnv *env = AndroidRuntime::getJNIEnv();
183 env->CallVoidMethod(
184 mFilter,
185 gFields.onFilterStatusID,
186 (jint)status);
shubang6f473d62019-11-01 15:42:21 -0700187 return Void();
188}
shubang8ab43b12019-10-18 15:55:55 -0700189
shubangcdf30de2019-11-06 17:28:38 -0800190void FilterCallback::setFilter(const jobject filter) {
191 ALOGD("FilterCallback::setFilter");
192 JNIEnv *env = AndroidRuntime::getJNIEnv();
193 mFilter = env->NewWeakGlobalRef(filter);
194}
195
shubang7648a3c2019-11-25 18:16:45 -0800196/////////////// Filter ///////////////////////
197
198Filter::Filter(sp<IFilter> sp, jweak obj) : mFilterSp(sp), mFilterObj(obj) {}
199
shubang964e6132019-11-26 15:05:22 -0800200Filter::~Filter() {
201 EventFlag::deleteEventFlag(&mFilterMQEventFlag);
202}
203
204int Filter::close() {
205 Result r = mFilterSp->close();
206 if (r == Result::SUCCESS) {
207 EventFlag::deleteEventFlag(&mFilterMQEventFlag);
208 }
209 return (int)r;
210}
211
shubang7648a3c2019-11-25 18:16:45 -0800212sp<IFilter> Filter::getIFilter() {
213 return mFilterSp;
214}
215
shubang4b8c5402019-10-24 17:49:53 -0700216/////////////// FrontendCallback ///////////////////////
217
218FrontendCallback::FrontendCallback(jweak tunerObj, FrontendId id) : mObject(tunerObj), mId(id) {}
219
220Return<void> FrontendCallback::onEvent(FrontendEventType frontendEventType) {
221 ALOGD("FrontendCallback::onEvent, type=%d", frontendEventType);
222 JNIEnv *env = AndroidRuntime::getJNIEnv();
223 env->CallVoidMethod(
224 mObject,
225 gFields.onFrontendEventID,
226 (jint)frontendEventType);
227 return Void();
228}
229Return<void> FrontendCallback::onDiseqcMessage(const hidl_vec<uint8_t>& /*diseqcMessage*/) {
230 ALOGD("FrontendCallback::onDiseqcMessage");
231 return Void();
232}
233
234Return<void> FrontendCallback::onScanMessage(
235 FrontendScanMessageType type, const FrontendScanMessage& /*message*/) {
236 ALOGD("FrontendCallback::onScanMessage, type=%d", type);
237 return Void();
238}
239
shubang6f473d62019-11-01 15:42:21 -0700240/////////////// Tuner ///////////////////////
shubang4b8c5402019-10-24 17:49:53 -0700241
shubang8ab43b12019-10-18 15:55:55 -0700242sp<ITuner> JTuner::mTuner;
243
244JTuner::JTuner(JNIEnv *env, jobject thiz)
245 : mClass(NULL) {
246 jclass clazz = env->GetObjectClass(thiz);
247 CHECK(clazz != NULL);
248
249 mClass = (jclass)env->NewGlobalRef(clazz);
250 mObject = env->NewWeakGlobalRef(thiz);
251 if (mTuner == NULL) {
252 mTuner = getTunerService();
253 }
254}
255
256JTuner::~JTuner() {
257 JNIEnv *env = AndroidRuntime::getJNIEnv();
258
259 env->DeleteGlobalRef(mClass);
260 mTuner = NULL;
261 mClass = NULL;
262 mObject = NULL;
263}
264
265sp<ITuner> JTuner::getTunerService() {
266 if (mTuner == nullptr) {
267 mTuner = ITuner::getService();
268
269 if (mTuner == nullptr) {
270 ALOGW("Failed to get tuner service.");
271 }
272 }
273 return mTuner;
274}
275
shubang7e849b02019-10-18 19:36:25 -0700276jobject JTuner::getFrontendIds() {
277 ALOGD("JTuner::getFrontendIds()");
shubang7e849b02019-10-18 19:36:25 -0700278 mTuner->getFrontendIds([&](Result, const hidl_vec<FrontendId>& frontendIds) {
shubang4b8c5402019-10-24 17:49:53 -0700279 mFeIds = frontendIds;
shubang7e849b02019-10-18 19:36:25 -0700280 });
shubang4b8c5402019-10-24 17:49:53 -0700281 if (mFeIds.size() == 0) {
shubang7e849b02019-10-18 19:36:25 -0700282 ALOGW("Frontend isn't available");
283 return NULL;
284 }
285
286 JNIEnv *env = AndroidRuntime::getJNIEnv();
287 jclass arrayListClazz = env->FindClass("java/util/ArrayList");
288 jmethodID arrayListAdd = env->GetMethodID(arrayListClazz, "add", "(Ljava/lang/Object;)Z");
289 jobject obj = env->NewObject(arrayListClazz, env->GetMethodID(arrayListClazz, "<init>", "()V"));
290
291 jclass integerClazz = env->FindClass("java/lang/Integer");
292 jmethodID intInit = env->GetMethodID(integerClazz, "<init>", "(I)V");
293
shubang4b8c5402019-10-24 17:49:53 -0700294 for (int i=0; i < mFeIds.size(); i++) {
295 jobject idObj = env->NewObject(integerClazz, intInit, mFeIds[i]);
shubang7e849b02019-10-18 19:36:25 -0700296 env->CallBooleanMethod(obj, arrayListAdd, idObj);
297 }
298 return obj;
299}
300
301jobject JTuner::openFrontendById(int id) {
shubang4b8c5402019-10-24 17:49:53 -0700302 sp<IFrontend> fe;
shubang7e849b02019-10-18 19:36:25 -0700303 mTuner->openFrontendById(id, [&](Result, const sp<IFrontend>& frontend) {
shubang4b8c5402019-10-24 17:49:53 -0700304 fe = frontend;
shubang7e849b02019-10-18 19:36:25 -0700305 });
shubang4b8c5402019-10-24 17:49:53 -0700306 if (fe == nullptr) {
shubang7e849b02019-10-18 19:36:25 -0700307 ALOGE("Failed to open frontend");
308 return NULL;
309 }
shubang4b8c5402019-10-24 17:49:53 -0700310 mFe = fe;
311 sp<FrontendCallback> feCb = new FrontendCallback(mObject, id);
312 fe->setCallback(feCb);
shubang7e849b02019-10-18 19:36:25 -0700313
314 jint jId = (jint) id;
shubang964e6132019-11-26 15:05:22 -0800315
shubang7e849b02019-10-18 19:36:25 -0700316 JNIEnv *env = AndroidRuntime::getJNIEnv();
317 // TODO: add more fields to frontend
318 return env->NewObject(
319 env->FindClass("android/media/tv/tuner/Tuner$Frontend"),
320 gFields.frontendInitID,
shubang4b8c5402019-10-24 17:49:53 -0700321 mObject,
shubang7e849b02019-10-18 19:36:25 -0700322 (jint) jId);
323}
324
shubang760f0312019-11-12 17:11:28 -0800325jobject JTuner::getLnbIds() {
326 ALOGD("JTuner::getLnbIds()");
327 mTuner->getLnbIds([&](Result, const hidl_vec<FrontendId>& lnbIds) {
328 mLnbIds = lnbIds;
329 });
330 if (mLnbIds.size() == 0) {
331 ALOGW("Lnb isn't available");
332 return NULL;
333 }
334
335 JNIEnv *env = AndroidRuntime::getJNIEnv();
336 jclass arrayListClazz = env->FindClass("java/util/ArrayList");
337 jmethodID arrayListAdd = env->GetMethodID(arrayListClazz, "add", "(Ljava/lang/Object;)Z");
338 jobject obj = env->NewObject(arrayListClazz, env->GetMethodID(arrayListClazz, "<init>", "()V"));
339
340 jclass integerClazz = env->FindClass("java/lang/Integer");
341 jmethodID intInit = env->GetMethodID(integerClazz, "<init>", "(I)V");
342
343 for (int i=0; i < mLnbIds.size(); i++) {
344 jobject idObj = env->NewObject(integerClazz, intInit, mLnbIds[i]);
345 env->CallBooleanMethod(obj, arrayListAdd, idObj);
346 }
347 return obj;
348}
349
350jobject JTuner::openLnbById(int id) {
351 sp<ILnb> lnbSp;
352 mTuner->openLnbById(id, [&](Result, const sp<ILnb>& lnb) {
353 lnbSp = lnb;
354 });
355 if (lnbSp == nullptr) {
356 ALOGE("Failed to open lnb");
357 return NULL;
358 }
359 mLnb = lnbSp;
360 sp<LnbCallback> lnbCb = new LnbCallback(mObject, id);
361 mLnb->setCallback(lnbCb);
362
363 JNIEnv *env = AndroidRuntime::getJNIEnv();
364 return env->NewObject(
shubangd351b822020-01-22 17:29:18 -0800365 env->FindClass("android/media/tv/tuner/Lnb"),
shubang760f0312019-11-12 17:11:28 -0800366 gFields.lnbInitID,
367 mObject,
368 id);
369}
370
shubang74bfd482019-10-29 19:10:22 -0700371int JTuner::tune(const FrontendSettings& settings) {
372 if (mFe == NULL) {
373 ALOGE("frontend is not initialized");
374 return (int)Result::INVALID_STATE;
375 }
376 Result result = mFe->tune(settings);
377 return (int)result;
378}
379
shubangd5b845f2019-12-11 15:29:09 -0800380int JTuner::scan(const FrontendSettings& settings, FrontendScanType scanType) {
381 if (mFe == NULL) {
382 ALOGE("frontend is not initialized");
383 return (int)Result::INVALID_STATE;
384 }
385 Result result = mFe->scan(settings, scanType);
386 return (int)result;
387}
388
shubang6f473d62019-11-01 15:42:21 -0700389bool JTuner::openDemux() {
390 if (mTuner == nullptr) {
391 return false;
392 }
393 if (mDemux != nullptr) {
394 return true;
395 }
396 mTuner->openDemux([&](Result, uint32_t demuxId, const sp<IDemux>& demux) {
397 mDemux = demux;
398 mDemuxId = demuxId;
399 ALOGD("open demux, id = %d", demuxId);
400 });
401 if (mDemux == nullptr) {
402 return false;
403 }
404 return true;
405}
406
shubang13f15e02019-11-04 17:51:02 -0800407jobject JTuner::openDescrambler() {
408 ALOGD("JTuner::openDescrambler");
409 if (mTuner == nullptr) {
410 return NULL;
411 }
412 sp<IDescrambler> descramblerSp;
413 mTuner->openDescrambler([&](Result, const sp<IDescrambler>& descrambler) {
414 descramblerSp = descrambler;
415 });
416
417 if (descramblerSp == NULL) {
418 return NULL;
419 }
420
421 JNIEnv *env = AndroidRuntime::getJNIEnv();
422 jobject descramblerObj =
423 env->NewObject(
shubangd351b822020-01-22 17:29:18 -0800424 env->FindClass("android/media/tv/tuner/Descrambler"),
shubang13f15e02019-11-04 17:51:02 -0800425 gFields.descramblerInitID,
426 mObject);
427
428 descramblerSp->incStrong(descramblerObj);
429 env->SetLongField(descramblerObj, gFields.descramblerContext, (jlong)descramblerSp.get());
430
431 return descramblerObj;
432}
433
shubang6f473d62019-11-01 15:42:21 -0700434jobject JTuner::openFilter(DemuxFilterType type, int bufferSize) {
435 if (mDemux == NULL) {
436 if (!openDemux()) {
437 return NULL;
438 }
439 }
440
shubang7648a3c2019-11-25 18:16:45 -0800441 sp<IFilter> iFilterSp;
shubangcdf30de2019-11-06 17:28:38 -0800442 sp<FilterCallback> callback = new FilterCallback();
443 mDemux->openFilter(type, bufferSize, callback,
shubang6f473d62019-11-01 15:42:21 -0700444 [&](Result, const sp<IFilter>& filter) {
shubang7648a3c2019-11-25 18:16:45 -0800445 iFilterSp = filter;
shubang6f473d62019-11-01 15:42:21 -0700446 });
shubang7648a3c2019-11-25 18:16:45 -0800447 if (iFilterSp == NULL) {
shubang6f473d62019-11-01 15:42:21 -0700448 ALOGD("Failed to open filter, type = %d", type.mainType);
449 return NULL;
450 }
451 int fId;
shubang7648a3c2019-11-25 18:16:45 -0800452 iFilterSp->getId([&](Result, uint32_t filterId) {
shubang6f473d62019-11-01 15:42:21 -0700453 fId = filterId;
454 });
shubang6f473d62019-11-01 15:42:21 -0700455
456 JNIEnv *env = AndroidRuntime::getJNIEnv();
shubangcdf30de2019-11-06 17:28:38 -0800457 jobject filterObj =
458 env->NewObject(
shubangd351b822020-01-22 17:29:18 -0800459 env->FindClass("android/media/tv/tuner/filter/Filter"),
shubangcdf30de2019-11-06 17:28:38 -0800460 gFields.filterInitID,
461 mObject,
462 (jint) fId);
463
shubang7648a3c2019-11-25 18:16:45 -0800464 sp<Filter> filterSp = new Filter(iFilterSp, filterObj);
shubangcdf30de2019-11-06 17:28:38 -0800465 filterSp->incStrong(filterObj);
466 env->SetLongField(filterObj, gFields.filterContext, (jlong)filterSp.get());
467
468 callback->setFilter(filterObj);
469
470 return filterObj;
shubang6f473d62019-11-01 15:42:21 -0700471}
472
shubang4a0eddf2019-11-08 17:10:18 -0800473jobject JTuner::openDvr(DvrType type, int bufferSize) {
474 ALOGD("JTuner::openDvr");
475 if (mDemux == NULL) {
476 if (!openDemux()) {
477 return NULL;
478 }
479 }
shubang9e700ff2019-12-04 16:26:51 -0800480 sp<IDvr> iDvrSp;
shubang4a0eddf2019-11-08 17:10:18 -0800481 sp<DvrCallback> callback = new DvrCallback();
482 mDemux->openDvr(type, bufferSize, callback,
483 [&](Result, const sp<IDvr>& dvr) {
shubang9e700ff2019-12-04 16:26:51 -0800484 iDvrSp = dvr;
shubang4a0eddf2019-11-08 17:10:18 -0800485 });
486
shubang9e700ff2019-12-04 16:26:51 -0800487 if (iDvrSp == NULL) {
shubang4a0eddf2019-11-08 17:10:18 -0800488 return NULL;
489 }
490
491 JNIEnv *env = AndroidRuntime::getJNIEnv();
492 jobject dvrObj =
493 env->NewObject(
shubangd351b822020-01-22 17:29:18 -0800494 env->FindClass("android/media/tv/tuner/dvr/Dvr"),
shubang4a0eddf2019-11-08 17:10:18 -0800495 gFields.dvrInitID,
496 mObject);
shubang9e700ff2019-12-04 16:26:51 -0800497 sp<Dvr> dvrSp = new Dvr(iDvrSp, dvrObj);
shubang4a0eddf2019-11-08 17:10:18 -0800498 dvrSp->incStrong(dvrObj);
499 env->SetLongField(dvrObj, gFields.dvrContext, (jlong)dvrSp.get());
500
501 callback->setDvr(dvrObj);
502
503 return dvrObj;
504}
505
shubang8ab43b12019-10-18 15:55:55 -0700506} // namespace android
507
508////////////////////////////////////////////////////////////////////////////////
509
510using namespace android;
511
512static sp<JTuner> setTuner(JNIEnv *env, jobject thiz, const sp<JTuner> &tuner) {
shubang13f15e02019-11-04 17:51:02 -0800513 sp<JTuner> old = (JTuner *)env->GetLongField(thiz, gFields.tunerContext);
shubang8ab43b12019-10-18 15:55:55 -0700514
515 if (tuner != NULL) {
516 tuner->incStrong(thiz);
517 }
518 if (old != NULL) {
519 old->decStrong(thiz);
520 }
shubang13f15e02019-11-04 17:51:02 -0800521 env->SetLongField(thiz, gFields.tunerContext, (jlong)tuner.get());
shubang8ab43b12019-10-18 15:55:55 -0700522
523 return old;
524}
525
526static sp<JTuner> getTuner(JNIEnv *env, jobject thiz) {
shubang13f15e02019-11-04 17:51:02 -0800527 return (JTuner *)env->GetLongField(thiz, gFields.tunerContext);
528}
529
530static sp<IDescrambler> getDescrambler(JNIEnv *env, jobject descrambler) {
531 return (IDescrambler *)env->GetLongField(descrambler, gFields.descramblerContext);
532}
533
534static DemuxPid getDemuxPid(int pidType, int pid) {
535 DemuxPid demuxPid;
536 if ((int)pidType == 1) {
537 demuxPid.tPid(static_cast<DemuxTpid>(pid));
538 } else if ((int)pidType == 2) {
539 demuxPid.mmtpPid(static_cast<DemuxMmtpPid>(pid));
540 }
541 return demuxPid;
shubang8ab43b12019-10-18 15:55:55 -0700542}
543
shubangdeb067c2020-01-27 13:21:55 -0800544static uint32_t getFrontendSettingsFreq(JNIEnv *env, const jobject& settings) {
shubangd351b822020-01-22 17:29:18 -0800545 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/FrontendSettings");
shubang964e6132019-11-26 15:05:22 -0800546 jfieldID freqField = env->GetFieldID(clazz, "mFrequency", "I");
shubangdeb067c2020-01-27 13:21:55 -0800547 uint32_t freq = static_cast<uint32_t>(env->GetIntField(settings, freqField));
548 return freq;
549}
shubang74bfd482019-10-29 19:10:22 -0700550
shubangdeb067c2020-01-27 13:21:55 -0800551static FrontendSettings getAnalogFrontendSettings(JNIEnv *env, const jobject& settings) {
552 FrontendSettings frontendSettings;
553 uint32_t freq = getFrontendSettingsFreq(env, settings);
554 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/AnalogFrontendSettings");
555 FrontendAnalogType analogType =
556 static_cast<FrontendAnalogType>(
557 env->GetIntField(settings, env->GetFieldID(clazz, "mSignalType", "I")));
558 FrontendAnalogSifStandard sifStandard =
559 static_cast<FrontendAnalogSifStandard>(
560 env->GetIntField(settings, env->GetFieldID(clazz, "mSifStandard", "I")));
561 FrontendAnalogSettings frontendAnalogSettings {
562 .frequency = freq,
563 .type = analogType,
564 .sifStandard = sifStandard,
565 };
566 frontendSettings.analog(frontendAnalogSettings);
shubang74bfd482019-10-29 19:10:22 -0700567 return frontendSettings;
568}
569
shubangdeb067c2020-01-27 13:21:55 -0800570static hidl_vec<FrontendAtsc3PlpSettings> getAtsc3PlpSettings(
571 JNIEnv *env, const jobject& settings) {
572 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/Atsc3FrontendSettings");
573 jobjectArray plpSettings =
574 reinterpret_cast<jobjectArray>(
575 env->GetObjectField(settings,
576 env->GetFieldID(
577 clazz,
578 "mPlpSettings",
579 "[Landroid/media/tv/tuner/frontend/Atsc3PlpSettings;")));
580 int len = env->GetArrayLength(plpSettings);
581
582 jclass plpClazz = env->FindClass("android/media/tv/tuner/frontend/Atsc3PlpSettings");
583 hidl_vec<FrontendAtsc3PlpSettings> plps = hidl_vec<FrontendAtsc3PlpSettings>(len);
584 // parse PLP settings
585 for (int i = 0; i < len; i++) {
586 jobject plp = env->GetObjectArrayElement(plpSettings, i);
587 uint8_t plpId =
588 static_cast<uint8_t>(
589 env->GetIntField(plp, env->GetFieldID(plpClazz, "mPlpId", "I")));
590 FrontendAtsc3Modulation modulation =
591 static_cast<FrontendAtsc3Modulation>(
592 env->GetIntField(plp, env->GetFieldID(plpClazz, "mModulation", "I")));
593 FrontendAtsc3TimeInterleaveMode interleaveMode =
594 static_cast<FrontendAtsc3TimeInterleaveMode>(
595 env->GetIntField(
596 plp, env->GetFieldID(plpClazz, "mInterleaveMode", "I")));
597 FrontendAtsc3CodeRate codeRate =
598 static_cast<FrontendAtsc3CodeRate>(
599 env->GetIntField(plp, env->GetFieldID(plpClazz, "mCodeRate", "I")));
600 FrontendAtsc3Fec fec =
601 static_cast<FrontendAtsc3Fec>(
602 env->GetIntField(plp, env->GetFieldID(plpClazz, "mFec", "I")));
603 FrontendAtsc3PlpSettings frontendAtsc3PlpSettings {
604 .plpId = plpId,
605 .modulation = modulation,
606 .interleaveMode = interleaveMode,
607 .codeRate = codeRate,
608 .fec = fec,
609 };
610 plps[i] = frontendAtsc3PlpSettings;
611 }
612 return plps;
613}
614
615static FrontendSettings getAtsc3FrontendSettings(JNIEnv *env, const jobject& settings) {
616 FrontendSettings frontendSettings;
617 uint32_t freq = getFrontendSettingsFreq(env, settings);
618 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/Atsc3FrontendSettings");
619
620 FrontendAtsc3Bandwidth bandwidth =
621 static_cast<FrontendAtsc3Bandwidth>(
622 env->GetIntField(settings, env->GetFieldID(clazz, "mBandwidth", "I")));
623 FrontendAtsc3DemodOutputFormat demod =
624 static_cast<FrontendAtsc3DemodOutputFormat>(
625 env->GetIntField(
626 settings, env->GetFieldID(clazz, "mDemodOutputFormat", "I")));
627 hidl_vec<FrontendAtsc3PlpSettings> plps = getAtsc3PlpSettings(env, settings);
628 FrontendAtsc3Settings frontendAtsc3Settings {
629 .frequency = freq,
630 .bandwidth = bandwidth,
631 .demodOutputFormat = demod,
632 .plpSettings = plps,
633 };
634 frontendSettings.atsc3(frontendAtsc3Settings);
635 return frontendSettings;
636}
637
638static FrontendSettings getAtscFrontendSettings(JNIEnv *env, const jobject& settings) {
639 FrontendSettings frontendSettings;
640 uint32_t freq = getFrontendSettingsFreq(env, settings);
641 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/AtscFrontendSettings");
642 FrontendAtscModulation modulation =
643 static_cast<FrontendAtscModulation>(
644 env->GetIntField(settings, env->GetFieldID(clazz, "mModulation", "I")));
645 FrontendAtscSettings frontendAtscSettings {
646 .frequency = freq,
647 .modulation = modulation,
648 };
649 frontendSettings.atsc(frontendAtscSettings);
650 return frontendSettings;
651}
652
653static FrontendSettings getDvbcFrontendSettings(JNIEnv *env, const jobject& settings) {
654 FrontendSettings frontendSettings;
655 uint32_t freq = getFrontendSettingsFreq(env, settings);
656 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/DvbcFrontendSettings");
657 FrontendDvbcModulation modulation =
658 static_cast<FrontendDvbcModulation>(
659 env->GetIntField(settings, env->GetFieldID(clazz, "mModulation", "I")));
660 FrontendInnerFec innerFec =
661 static_cast<FrontendInnerFec>(
662 env->GetLongField(settings, env->GetFieldID(clazz, "mFec", "J")));
663 uint32_t symbolRate =
664 static_cast<uint32_t>(
665 env->GetIntField(settings, env->GetFieldID(clazz, "mSymbolRate", "I")));
666 FrontendDvbcOuterFec outerFec =
667 static_cast<FrontendDvbcOuterFec>(
668 env->GetIntField(settings, env->GetFieldID(clazz, "mOuterFec", "I")));
669 FrontendDvbcAnnex annex =
670 static_cast<FrontendDvbcAnnex>(
671 env->GetByteField(settings, env->GetFieldID(clazz, "mAnnex", "B")));
672 FrontendDvbcSpectralInversion spectralInversion =
673 static_cast<FrontendDvbcSpectralInversion>(
674 env->GetIntField(
675 settings, env->GetFieldID(clazz, "mSpectralInversion", "I")));
676 FrontendDvbcSettings frontendDvbcSettings {
677 .frequency = freq,
678 .modulation = modulation,
679 .fec = innerFec,
680 .symbolRate = symbolRate,
681 .outerFec = outerFec,
682 .annex = annex,
683 .spectralInversion = spectralInversion,
684 };
685 frontendSettings.dvbc(frontendDvbcSettings);
686 return frontendSettings;
687}
688
689static FrontendDvbsCodeRate getDvbsCodeRate(JNIEnv *env, const jobject& settings) {
690 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/DvbsFrontendSettings");
691 jobject jcodeRate =
692 env->GetObjectField(settings,
693 env->GetFieldID(
694 clazz,
695 "mCodeRate",
696 "Landroid/media/tv/tuner/frontend/DvbsCodeRate;"));
697
698 jclass codeRateClazz = env->FindClass("android/media/tv/tuner/frontend/DvbsCodeRate");
699 FrontendInnerFec innerFec =
700 static_cast<FrontendInnerFec>(
701 env->GetLongField(
702 jcodeRate, env->GetFieldID(codeRateClazz, "mInnerFec", "J")));
703 bool isLinear =
704 static_cast<bool>(
705 env->GetBooleanField(
706 jcodeRate, env->GetFieldID(codeRateClazz, "mIsLinear", "Z")));
707 bool isShortFrames =
708 static_cast<bool>(
709 env->GetBooleanField(
710 jcodeRate, env->GetFieldID(codeRateClazz, "mIsShortFrames", "Z")));
711 uint32_t bitsPer1000Symbol =
712 static_cast<uint32_t>(
713 env->GetIntField(
714 jcodeRate, env->GetFieldID(
715 codeRateClazz, "mBitsPer1000Symbol", "I")));
716 FrontendDvbsCodeRate coderate {
717 .fec = innerFec,
718 .isLinear = isLinear,
719 .isShortFrames = isShortFrames,
720 .bitsPer1000Symbol = bitsPer1000Symbol,
721 };
722 return coderate;
723}
724
725static FrontendSettings getDvbsFrontendSettings(JNIEnv *env, const jobject& settings) {
726 FrontendSettings frontendSettings;
727 uint32_t freq = getFrontendSettingsFreq(env, settings);
728 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/DvbsFrontendSettings");
729
730
731 FrontendDvbsModulation modulation =
732 static_cast<FrontendDvbsModulation>(
733 env->GetIntField(settings, env->GetFieldID(clazz, "mModulation", "I")));
734 uint32_t symbolRate =
735 static_cast<uint32_t>(
736 env->GetIntField(settings, env->GetFieldID(clazz, "mSymbolRate", "I")));
737 FrontendDvbsRolloff rolloff =
738 static_cast<FrontendDvbsRolloff>(
739 env->GetIntField(settings, env->GetFieldID(clazz, "mRolloff", "I")));
740 FrontendDvbsPilot pilot =
741 static_cast<FrontendDvbsPilot>(
742 env->GetIntField(settings, env->GetFieldID(clazz, "mPilot", "I")));
743 uint32_t inputStreamId =
744 static_cast<uint32_t>(
745 env->GetIntField(settings, env->GetFieldID(clazz, "mInputStreamId", "I")));
746 FrontendDvbsStandard standard =
747 static_cast<FrontendDvbsStandard>(
748 env->GetIntField(settings, env->GetFieldID(clazz, "mStandard", "I")));
749 FrontendDvbsVcmMode vcmMode =
750 static_cast<FrontendDvbsVcmMode>(
751 env->GetIntField(settings, env->GetFieldID(clazz, "mVcmMode", "I")));
752 FrontendDvbsCodeRate coderate = getDvbsCodeRate(env, settings);
753
754 FrontendDvbsSettings frontendDvbsSettings {
755 .frequency = freq,
756 .modulation = modulation,
757 .coderate = coderate,
758 .symbolRate = symbolRate,
759 .rolloff = rolloff,
760 .pilot = pilot,
761 .inputStreamId = inputStreamId,
762 .standard = standard,
763 .vcmMode = vcmMode,
764 };
765 frontendSettings.dvbs(frontendDvbsSettings);
766 return frontendSettings;
767}
768
769static FrontendSettings getDvbtFrontendSettings(JNIEnv *env, const jobject& settings) {
770 FrontendSettings frontendSettings;
771 uint32_t freq = getFrontendSettingsFreq(env, settings);
772 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/DvbtFrontendSettings");
773 FrontendDvbtTransmissionMode transmissionMode =
774 static_cast<FrontendDvbtTransmissionMode>(
775 env->GetIntField(
776 settings, env->GetFieldID(clazz, "mTransmissionMode", "I")));
777 FrontendDvbtBandwidth bandwidth =
778 static_cast<FrontendDvbtBandwidth>(
779 env->GetIntField(settings, env->GetFieldID(clazz, "mBandwidth", "I")));
780 FrontendDvbtConstellation constellation =
781 static_cast<FrontendDvbtConstellation>(
782 env->GetIntField(settings, env->GetFieldID(clazz, "mConstellation", "I")));
783 FrontendDvbtHierarchy hierarchy =
784 static_cast<FrontendDvbtHierarchy>(
785 env->GetIntField(settings, env->GetFieldID(clazz, "mHierarchy", "I")));
786 FrontendDvbtCoderate hpCoderate =
787 static_cast<FrontendDvbtCoderate>(
788 env->GetIntField(settings, env->GetFieldID(clazz, "mHpCodeRate", "I")));
789 FrontendDvbtCoderate lpCoderate =
790 static_cast<FrontendDvbtCoderate>(
791 env->GetIntField(settings, env->GetFieldID(clazz, "mLpCodeRate", "I")));
792 FrontendDvbtGuardInterval guardInterval =
793 static_cast<FrontendDvbtGuardInterval>(
794 env->GetIntField(settings, env->GetFieldID(clazz, "mGuardInterval", "I")));
795 bool isHighPriority =
796 static_cast<bool>(
797 env->GetBooleanField(
798 settings, env->GetFieldID(clazz, "mIsHighPriority", "Z")));
799 FrontendDvbtStandard standard =
800 static_cast<FrontendDvbtStandard>(
801 env->GetIntField(settings, env->GetFieldID(clazz, "mStandard", "I")));
802 bool isMiso =
803 static_cast<bool>(
804 env->GetBooleanField(settings, env->GetFieldID(clazz, "mIsMiso", "Z")));
805 FrontendDvbtPlpMode plpMode =
806 static_cast<FrontendDvbtPlpMode>(
807 env->GetIntField(settings, env->GetFieldID(clazz, "mPlpMode", "I")));
808 uint8_t plpId =
809 static_cast<uint8_t>(
810 env->GetIntField(settings, env->GetFieldID(clazz, "mPlpId", "I")));
811 uint8_t plpGroupId =
812 static_cast<uint8_t>(
813 env->GetIntField(settings, env->GetFieldID(clazz, "mPlpGroupId", "I")));
814
815 FrontendDvbtSettings frontendDvbtSettings {
816 .frequency = freq,
817 .transmissionMode = transmissionMode,
818 .bandwidth = bandwidth,
819 .constellation = constellation,
820 .hierarchy = hierarchy,
821 .hpCoderate = hpCoderate,
822 .lpCoderate = lpCoderate,
823 .guardInterval = guardInterval,
824 .isHighPriority = isHighPriority,
825 .standard = standard,
826 .isMiso = isMiso,
827 .plpMode = plpMode,
828 .plpId = plpId,
829 .plpGroupId = plpGroupId,
830 };
831 frontendSettings.dvbt(frontendDvbtSettings);
832 return frontendSettings;
833}
834
835static FrontendSettings getIsdbsFrontendSettings(JNIEnv *env, const jobject& settings) {
836 FrontendSettings frontendSettings;
837 uint32_t freq = getFrontendSettingsFreq(env, settings);
838 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/IsdbsFrontendSettings");
839 uint16_t streamId =
840 static_cast<uint16_t>(
841 env->GetIntField(settings, env->GetFieldID(clazz, "mStreamId", "I")));
842 FrontendIsdbsStreamIdType streamIdType =
843 static_cast<FrontendIsdbsStreamIdType>(
844 env->GetIntField(settings, env->GetFieldID(clazz, "mStreamIdType", "I")));
845 FrontendIsdbsModulation modulation =
846 static_cast<FrontendIsdbsModulation>(
847 env->GetIntField(settings, env->GetFieldID(clazz, "mModulation", "I")));
848 FrontendIsdbsCoderate coderate =
849 static_cast<FrontendIsdbsCoderate>(
850 env->GetIntField(settings, env->GetFieldID(clazz, "mCodeRate", "I")));
851 uint32_t symbolRate =
852 static_cast<uint32_t>(
853 env->GetIntField(settings, env->GetFieldID(clazz, "mSymbolRate", "I")));
854 FrontendIsdbsRolloff rolloff =
855 static_cast<FrontendIsdbsRolloff>(
856 env->GetIntField(settings, env->GetFieldID(clazz, "mRolloff", "I")));
857
858 FrontendIsdbsSettings frontendIsdbsSettings {
859 .frequency = freq,
860 .streamId = streamId,
861 .streamIdType = streamIdType,
862 .modulation = modulation,
863 .coderate = coderate,
864 .symbolRate = symbolRate,
865 .rolloff = rolloff,
866 };
867 frontendSettings.isdbs(frontendIsdbsSettings);
868 return frontendSettings;
869}
870
871static FrontendSettings getIsdbs3FrontendSettings(JNIEnv *env, const jobject& settings) {
872 FrontendSettings frontendSettings;
873 uint32_t freq = getFrontendSettingsFreq(env, settings);
874 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/Isdbs3FrontendSettings");
875 uint16_t streamId =
876 static_cast<uint16_t>(
877 env->GetIntField(settings, env->GetFieldID(clazz, "mStreamId", "I")));
878 FrontendIsdbsStreamIdType streamIdType =
879 static_cast<FrontendIsdbsStreamIdType>(
880 env->GetIntField(settings, env->GetFieldID(clazz, "mStreamIdType", "I")));
881 FrontendIsdbs3Modulation modulation =
882 static_cast<FrontendIsdbs3Modulation>(
883 env->GetIntField(settings, env->GetFieldID(clazz, "mModulation", "I")));
884 FrontendIsdbs3Coderate coderate =
885 static_cast<FrontendIsdbs3Coderate>(
886 env->GetIntField(settings, env->GetFieldID(clazz, "mCodeRate", "I")));
887 uint32_t symbolRate =
888 static_cast<uint32_t>(
889 env->GetIntField(settings, env->GetFieldID(clazz, "mSymbolRate", "I")));
890 FrontendIsdbs3Rolloff rolloff =
891 static_cast<FrontendIsdbs3Rolloff>(
892 env->GetIntField(settings, env->GetFieldID(clazz, "mRolloff", "I")));
893
894 FrontendIsdbs3Settings frontendIsdbs3Settings {
895 .frequency = freq,
896 .streamId = streamId,
897 .streamIdType = streamIdType,
898 .modulation = modulation,
899 .coderate = coderate,
900 .symbolRate = symbolRate,
901 .rolloff = rolloff,
902 };
903 frontendSettings.isdbs3(frontendIsdbs3Settings);
904 return frontendSettings;
905}
906
907static FrontendSettings getIsdbtFrontendSettings(JNIEnv *env, const jobject& settings) {
908 FrontendSettings frontendSettings;
909 uint32_t freq = getFrontendSettingsFreq(env, settings);
910 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/IsdbtFrontendSettings");
911 FrontendIsdbtModulation modulation =
912 static_cast<FrontendIsdbtModulation>(
913 env->GetIntField(settings, env->GetFieldID(clazz, "mModulation", "I")));
914 FrontendIsdbtBandwidth bandwidth =
915 static_cast<FrontendIsdbtBandwidth>(
916 env->GetIntField(settings, env->GetFieldID(clazz, "mBandwidth", "I")));
917 FrontendIsdbtMode mode =
918 static_cast<FrontendIsdbtMode>(
919 env->GetIntField(settings, env->GetFieldID(clazz, "mMode", "I")));
920 FrontendIsdbtCoderate coderate =
921 static_cast<FrontendIsdbtCoderate>(
922 env->GetIntField(settings, env->GetFieldID(clazz, "mCodeRate", "I")));
923 FrontendIsdbtGuardInterval guardInterval =
924 static_cast<FrontendIsdbtGuardInterval>(
925 env->GetIntField(settings, env->GetFieldID(clazz, "mGuardInterval", "I")));
926 uint32_t serviceAreaId =
927 static_cast<uint32_t>(
928 env->GetIntField(settings, env->GetFieldID(clazz, "mServiceAreaId", "I")));
929
930 FrontendIsdbtSettings frontendIsdbtSettings {
931 .frequency = freq,
932 .modulation = modulation,
933 .bandwidth = bandwidth,
934 .mode = mode,
935 .coderate = coderate,
936 .guardInterval = guardInterval,
937 .serviceAreaId = serviceAreaId,
938 };
939 frontendSettings.isdbt(frontendIsdbtSettings);
940 return frontendSettings;
941}
942
943static FrontendSettings getFrontendSettings(JNIEnv *env, int type, jobject settings) {
944 ALOGD("getFrontendSettings %d", type);
945
946 FrontendType feType = static_cast<FrontendType>(type);
947 switch(feType) {
948 case FrontendType::ANALOG:
949 return getAnalogFrontendSettings(env, settings);
950 case FrontendType::ATSC3:
951 return getAtsc3FrontendSettings(env, settings);
952 case FrontendType::ATSC:
953 return getAtscFrontendSettings(env, settings);
954 case FrontendType::DVBC:
955 return getDvbcFrontendSettings(env, settings);
956 case FrontendType::DVBS:
957 return getDvbsFrontendSettings(env, settings);
958 case FrontendType::DVBT:
959 return getDvbtFrontendSettings(env, settings);
960 case FrontendType::ISDBS:
961 return getIsdbsFrontendSettings(env, settings);
962 case FrontendType::ISDBS3:
963 return getIsdbs3FrontendSettings(env, settings);
964 case FrontendType::ISDBT:
965 return getIsdbtFrontendSettings(env, settings);
966 default:
967 // should never happen because a type is associated with a subclass of
968 // FrontendSettings and not set by users
969 jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
970 "Unsupported frontend type %d", type);
971 return FrontendSettings();
972 }
973}
974
shubang7648a3c2019-11-25 18:16:45 -0800975static sp<Filter> getFilter(JNIEnv *env, jobject filter) {
976 return (Filter *)env->GetLongField(filter, gFields.filterContext);
shubangcdf30de2019-11-06 17:28:38 -0800977}
978
shubang030afb52019-11-27 16:09:02 -0800979static DvrSettings getDvrSettings(JNIEnv *env, jobject settings) {
980 DvrSettings dvrSettings;
shubangd351b822020-01-22 17:29:18 -0800981 jclass clazz = env->FindClass("android/media/tv/tuner/dvr/DvrSettings");
shubang030afb52019-11-27 16:09:02 -0800982 uint32_t statusMask =
983 static_cast<uint32_t>(env->GetIntField(
984 settings, env->GetFieldID(clazz, "mStatusMask", "I")));
985 uint32_t lowThreshold =
986 static_cast<uint32_t>(env->GetIntField(
987 settings, env->GetFieldID(clazz, "mLowThreshold", "I")));
988 uint32_t highThreshold =
989 static_cast<uint32_t>(env->GetIntField(
990 settings, env->GetFieldID(clazz, "mHighThreshold", "I")));
991 uint8_t packetSize =
992 static_cast<uint8_t>(env->GetIntField(
993 settings, env->GetFieldID(clazz, "mPacketSize", "I")));
994 DataFormat dataFormat =
995 static_cast<DataFormat>(env->GetIntField(
996 settings, env->GetFieldID(clazz, "mDataFormat", "I")));
997 DvrType type =
998 static_cast<DvrType>(env->GetIntField(
999 settings, env->GetFieldID(clazz, "mType", "I")));
1000 if (type == DvrType::RECORD) {
1001 RecordSettings recordSettings {
1002 .statusMask = static_cast<unsigned char>(statusMask),
1003 .lowThreshold = lowThreshold,
1004 .highThreshold = highThreshold,
1005 .dataFormat = dataFormat,
1006 .packetSize = packetSize,
1007 };
1008 dvrSettings.record(recordSettings);
1009 } else if (type == DvrType::PLAYBACK) {
1010 PlaybackSettings PlaybackSettings {
1011 .statusMask = statusMask,
1012 .lowThreshold = lowThreshold,
1013 .highThreshold = highThreshold,
1014 .dataFormat = dataFormat,
1015 .packetSize = packetSize,
1016 };
1017 dvrSettings.playback(PlaybackSettings);
1018 }
1019 return dvrSettings;
1020}
1021
shubang9e700ff2019-12-04 16:26:51 -08001022static sp<Dvr> getDvr(JNIEnv *env, jobject dvr) {
1023 return (Dvr *)env->GetLongField(dvr, gFields.dvrContext);
shubang4a0eddf2019-11-08 17:10:18 -08001024}
1025
shubang8ab43b12019-10-18 15:55:55 -07001026static void android_media_tv_Tuner_native_init(JNIEnv *env) {
1027 jclass clazz = env->FindClass("android/media/tv/tuner/Tuner");
1028 CHECK(clazz != NULL);
1029
shubang13f15e02019-11-04 17:51:02 -08001030 gFields.tunerContext = env->GetFieldID(clazz, "mNativeContext", "J");
1031 CHECK(gFields.tunerContext != NULL);
shubang7e849b02019-10-18 19:36:25 -07001032
shubang4b8c5402019-10-24 17:49:53 -07001033 gFields.onFrontendEventID = env->GetMethodID(clazz, "onFrontendEvent", "(I)V");
1034
shubang760f0312019-11-12 17:11:28 -08001035 gFields.onLnbEventID = env->GetMethodID(clazz, "onLnbEvent", "(I)V");
1036
shubang7e849b02019-10-18 19:36:25 -07001037 jclass frontendClazz = env->FindClass("android/media/tv/tuner/Tuner$Frontend");
shubang4b8c5402019-10-24 17:49:53 -07001038 gFields.frontendInitID =
1039 env->GetMethodID(frontendClazz, "<init>", "(Landroid/media/tv/tuner/Tuner;I)V");
shubang6f473d62019-11-01 15:42:21 -07001040
shubangd351b822020-01-22 17:29:18 -08001041 jclass lnbClazz = env->FindClass("android/media/tv/tuner/Lnb");
shubang760f0312019-11-12 17:11:28 -08001042 gFields.lnbInitID =
shubangdeb067c2020-01-27 13:21:55 -08001043 env->GetMethodID(lnbClazz, "<init>", "(I)V");
shubang760f0312019-11-12 17:11:28 -08001044
shubangd351b822020-01-22 17:29:18 -08001045 jclass filterClazz = env->FindClass("android/media/tv/tuner/filter/Filter");
shubangcdf30de2019-11-06 17:28:38 -08001046 gFields.filterContext = env->GetFieldID(filterClazz, "mNativeContext", "J");
shubang6f473d62019-11-01 15:42:21 -07001047 gFields.filterInitID =
shubangdeb067c2020-01-27 13:21:55 -08001048 env->GetMethodID(filterClazz, "<init>", "(I)V");
shubangcdf30de2019-11-06 17:28:38 -08001049 gFields.onFilterStatusID =
1050 env->GetMethodID(filterClazz, "onFilterStatus", "(I)V");
shubang13f15e02019-11-04 17:51:02 -08001051
shubangd351b822020-01-22 17:29:18 -08001052 jclass descramblerClazz = env->FindClass("android/media/tv/tuner/Descrambler");
shubang13f15e02019-11-04 17:51:02 -08001053 gFields.descramblerContext = env->GetFieldID(descramblerClazz, "mNativeContext", "J");
1054 gFields.descramblerInitID =
shubangdeb067c2020-01-27 13:21:55 -08001055 env->GetMethodID(descramblerClazz, "<init>", "()V");
shubang4a0eddf2019-11-08 17:10:18 -08001056
shubangd351b822020-01-22 17:29:18 -08001057 jclass dvrClazz = env->FindClass("android/media/tv/tuner/dvr/Dvr");
shubang4a0eddf2019-11-08 17:10:18 -08001058 gFields.dvrContext = env->GetFieldID(dvrClazz, "mNativeContext", "J");
shubangdeb067c2020-01-27 13:21:55 -08001059 gFields.dvrInitID = env->GetMethodID(dvrClazz, "<init>", "()V");
shubang8ab43b12019-10-18 15:55:55 -07001060}
1061
1062static void android_media_tv_Tuner_native_setup(JNIEnv *env, jobject thiz) {
1063 sp<JTuner> tuner = new JTuner(env, thiz);
1064 setTuner(env,thiz, tuner);
1065}
1066
shubang7e849b02019-10-18 19:36:25 -07001067static jobject android_media_tv_Tuner_get_frontend_ids(JNIEnv *env, jobject thiz) {
1068 sp<JTuner> tuner = getTuner(env, thiz);
1069 return tuner->getFrontendIds();
1070}
1071
1072static jobject android_media_tv_Tuner_open_frontend_by_id(JNIEnv *env, jobject thiz, jint id) {
1073 sp<JTuner> tuner = getTuner(env, thiz);
1074 return tuner->openFrontendById(id);
1075}
1076
shubang74bfd482019-10-29 19:10:22 -07001077static int android_media_tv_Tuner_tune(JNIEnv *env, jobject thiz, jint type, jobject settings) {
1078 sp<JTuner> tuner = getTuner(env, thiz);
1079 return tuner->tune(getFrontendSettings(env, type, settings));
1080}
1081
shubang793e5702019-12-26 15:15:46 -08001082static int android_media_tv_Tuner_stop_tune(JNIEnv*, jobject) {
shubange65b6862019-12-17 15:43:35 -08001083 return 0;
1084}
1085
shubangd5b845f2019-12-11 15:29:09 -08001086static int android_media_tv_Tuner_scan(
1087 JNIEnv *env, jobject thiz, jint settingsType, jobject settings, jint scanType) {
1088 sp<JTuner> tuner = getTuner(env, thiz);
1089 return tuner->scan(getFrontendSettings(
1090 env, settingsType, settings), static_cast<FrontendScanType>(scanType));
1091}
1092
shubang793e5702019-12-26 15:15:46 -08001093static int android_media_tv_Tuner_stop_scan(JNIEnv*, jobject) {
shubange65b6862019-12-17 15:43:35 -08001094 return 0;
1095}
1096
shubang793e5702019-12-26 15:15:46 -08001097static int android_media_tv_Tuner_set_lnb(JNIEnv*, jobject, jint) {
1098 return 0;
1099}
1100
1101static int android_media_tv_Tuner_set_lna(JNIEnv*, jobject, jint, jboolean) {
shubange65b6862019-12-17 15:43:35 -08001102 return 0;
1103}
1104
shubangd351b822020-01-22 17:29:18 -08001105static jobject android_media_tv_Tuner_get_frontend_status(JNIEnv, jobject, jintArray) {
shubang1512ec12019-12-23 18:22:42 -08001106 return NULL;
1107}
1108
shubang7343fee2019-12-27 12:02:08 -08001109static int android_media_tv_Tuner_gat_av_sync_hw_id(JNIEnv*, jobject, jobject) {
1110 return 0;
1111}
1112
1113static jlong android_media_tv_Tuner_gat_av_sync_time(JNIEnv*, jobject, jint) {
1114 return 0;
1115}
1116
1117static int android_media_tv_Tuner_connect_cicam(JNIEnv*, jobject, jint) {
1118 return 0;
1119}
1120
1121static int android_media_tv_Tuner_disconnect_cicam(JNIEnv*, jobject) {
1122 return 0;
1123}
1124
shubang95c1f752019-12-27 16:29:48 -08001125static jobject android_media_tv_Tuner_get_frontend_info(JNIEnv*, jobject, jint) {
1126 return NULL;
1127}
1128
shubang760f0312019-11-12 17:11:28 -08001129static jobject android_media_tv_Tuner_get_lnb_ids(JNIEnv *env, jobject thiz) {
1130 sp<JTuner> tuner = getTuner(env, thiz);
1131 return tuner->getLnbIds();
1132}
1133
1134static jobject android_media_tv_Tuner_open_lnb_by_id(JNIEnv *env, jobject thiz, jint id) {
1135 sp<JTuner> tuner = getTuner(env, thiz);
1136 return tuner->openLnbById(id);
1137}
1138
shubang6f473d62019-11-01 15:42:21 -07001139static jobject android_media_tv_Tuner_open_filter(
shubangd351b822020-01-22 17:29:18 -08001140 JNIEnv *env, jobject thiz, jint type, jint subType, jlong bufferSize) {
shubang6f473d62019-11-01 15:42:21 -07001141 sp<JTuner> tuner = getTuner(env, thiz);
1142 DemuxFilterType filterType {
1143 .mainType = static_cast<DemuxFilterMainType>(type),
1144 };
1145
1146 // TODO: other sub types
1147 filterType.subType.tsFilterType(static_cast<DemuxTsFilterType>(subType));
1148
1149 return tuner->openFilter(filterType, bufferSize);
1150}
1151
shubang4347e2e2019-12-13 17:20:40 -08001152static jobject android_media_tv_Tuner_open_time_filter(JNIEnv, jobject) {
1153 return NULL;
1154}
1155
shubang75c87082019-11-15 11:26:56 -08001156static DemuxFilterSettings getFilterSettings(
1157 JNIEnv *env, int type, int subtype, jobject filterSettingsObj) {
1158 DemuxFilterSettings filterSettings;
1159 // TODO: more setting types
1160 jobject settingsObj =
1161 env->GetObjectField(
1162 filterSettingsObj,
1163 env->GetFieldID(
shubangd351b822020-01-22 17:29:18 -08001164 env->FindClass("android/media/tv/tuner/filter/FilterConfiguration"),
shubang75c87082019-11-15 11:26:56 -08001165 "mSettings",
shubangd351b822020-01-22 17:29:18 -08001166 "Landroid/media/tv/tuner/filter/Settings;"));
shubang75c87082019-11-15 11:26:56 -08001167 if (type == (int)DemuxFilterMainType::TS) {
1168 // DemuxTsFilterSettings
shubangd351b822020-01-22 17:29:18 -08001169 jclass clazz = env->FindClass("android/media/tv/tuner/filter/TsFilterConfiguration");
shubang75c87082019-11-15 11:26:56 -08001170 int tpid = env->GetIntField(filterSettingsObj, env->GetFieldID(clazz, "mTpid", "I"));
1171 if (subtype == (int)DemuxTsFilterType::PES) {
1172 // DemuxFilterPesDataSettings
1173 jclass settingClazz =
shubangd351b822020-01-22 17:29:18 -08001174 env->FindClass("android/media/tv/tuner/filter/PesSettings");
shubang75c87082019-11-15 11:26:56 -08001175 int streamId = env->GetIntField(
1176 settingsObj, env->GetFieldID(settingClazz, "mStreamId", "I"));
1177 bool isRaw = (bool)env->GetBooleanField(
1178 settingsObj, env->GetFieldID(settingClazz, "mIsRaw", "Z"));
1179 DemuxFilterPesDataSettings filterPesDataSettings {
1180 .streamId = static_cast<uint16_t>(streamId),
1181 .isRaw = isRaw,
1182 };
1183 DemuxTsFilterSettings tsFilterSettings {
1184 .tpid = static_cast<uint16_t>(tpid),
1185 };
1186 tsFilterSettings.filterSettings.pesData(filterPesDataSettings);
1187 filterSettings.ts(tsFilterSettings);
1188 }
1189 }
1190 return filterSettings;
1191}
1192
shubang964e6132019-11-26 15:05:22 -08001193static int copyData(JNIEnv *env, sp<Filter> filter, jbyteArray buffer, jint offset, int size) {
1194 ALOGD("copyData, size=%d, offset=%d", size, offset);
1195
1196 int available = filter->mFilterMQ->availableToRead();
1197 ALOGD("copyData, available=%d", available);
1198 size = std::min(size, available);
1199
1200 jboolean isCopy;
1201 jbyte *dst = env->GetByteArrayElements(buffer, &isCopy);
1202 ALOGD("copyData, isCopy=%d", isCopy);
1203 if (dst == nullptr) {
1204 ALOGD("Failed to GetByteArrayElements");
1205 return 0;
1206 }
1207
1208 if (filter->mFilterMQ->read(reinterpret_cast<unsigned char*>(dst) + offset, size)) {
1209 env->ReleaseByteArrayElements(buffer, dst, 0);
1210 filter->mFilterMQEventFlag->wake(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_CONSUMED));
1211 } else {
1212 ALOGD("Failed to read FMQ");
1213 env->ReleaseByteArrayElements(buffer, dst, 0);
1214 return 0;
1215 }
1216 return size;
1217}
1218
shubang75c87082019-11-15 11:26:56 -08001219static int android_media_tv_Tuner_configure_filter(
1220 JNIEnv *env, jobject filter, int type, int subtype, jobject settings) {
1221 ALOGD("configure filter type=%d, subtype=%d", type, subtype);
shubang964e6132019-11-26 15:05:22 -08001222 sp<Filter> filterSp = getFilter(env, filter);
1223 sp<IFilter> iFilterSp = filterSp->getIFilter();
1224 if (iFilterSp == NULL) {
shubang75c87082019-11-15 11:26:56 -08001225 ALOGD("Failed to configure filter: filter not found");
1226 return (int)Result::INVALID_STATE;
1227 }
1228 DemuxFilterSettings filterSettings = getFilterSettings(env, type, subtype, settings);
shubang964e6132019-11-26 15:05:22 -08001229 Result res = iFilterSp->configure(filterSettings);
1230 MQDescriptorSync<uint8_t> filterMQDesc;
1231 if (res == Result::SUCCESS && filterSp->mFilterMQ == NULL) {
1232 Result getQueueDescResult = Result::UNKNOWN_ERROR;
1233 iFilterSp->getQueueDesc(
1234 [&](Result r, const MQDescriptorSync<uint8_t>& desc) {
1235 filterMQDesc = desc;
1236 getQueueDescResult = r;
1237 ALOGD("getFilterQueueDesc");
1238 });
1239 if (getQueueDescResult == Result::SUCCESS) {
1240 filterSp->mFilterMQ = std::make_unique<FilterMQ>(filterMQDesc, true);
1241 EventFlag::createEventFlag(
1242 filterSp->mFilterMQ->getEventFlagWord(), &(filterSp->mFilterMQEventFlag));
1243 }
1244 }
shubang75c87082019-11-15 11:26:56 -08001245 return (int)res;
1246}
1247
shubang793e5702019-12-26 15:15:46 -08001248static int android_media_tv_Tuner_get_filter_id(JNIEnv*, jobject) {
1249 return 0;
1250}
1251
1252static int android_media_tv_Tuner_set_filter_data_source(JNIEnv*, jobject, jobject) {
1253 return 0;
1254}
1255
1256static int android_media_tv_Tuner_start_filter(JNIEnv *env, jobject filter) {
shubang7648a3c2019-11-25 18:16:45 -08001257 sp<IFilter> filterSp = getFilter(env, filter)->getIFilter();
shubangd0977902019-11-07 18:58:43 -08001258 if (filterSp == NULL) {
1259 ALOGD("Failed to start filter: filter not found");
1260 return false;
1261 }
shubang793e5702019-12-26 15:15:46 -08001262 Result r = filterSp->start();
1263 return (int) r;
shubangd0977902019-11-07 18:58:43 -08001264}
1265
shubang793e5702019-12-26 15:15:46 -08001266static int android_media_tv_Tuner_stop_filter(JNIEnv *env, jobject filter) {
shubang7648a3c2019-11-25 18:16:45 -08001267 sp<IFilter> filterSp = getFilter(env, filter)->getIFilter();
shubangd0977902019-11-07 18:58:43 -08001268 if (filterSp == NULL) {
1269 ALOGD("Failed to stop filter: filter not found");
1270 return false;
1271 }
shubang793e5702019-12-26 15:15:46 -08001272 Result r = filterSp->stop();
1273 return (int) r;
shubangd0977902019-11-07 18:58:43 -08001274}
1275
shubang793e5702019-12-26 15:15:46 -08001276static int android_media_tv_Tuner_flush_filter(JNIEnv *env, jobject filter) {
shubang7648a3c2019-11-25 18:16:45 -08001277 sp<IFilter> filterSp = getFilter(env, filter)->getIFilter();
shubangd0977902019-11-07 18:58:43 -08001278 if (filterSp == NULL) {
1279 ALOGD("Failed to flush filter: filter not found");
1280 return false;
1281 }
shubang793e5702019-12-26 15:15:46 -08001282 Result r = filterSp->flush();
1283 return (int) r;
shubangd0977902019-11-07 18:58:43 -08001284}
1285
shubang964e6132019-11-26 15:05:22 -08001286static int android_media_tv_Tuner_read_filter_fmq(
shubangd351b822020-01-22 17:29:18 -08001287 JNIEnv *env, jobject filter, jbyteArray buffer, jlong offset, jlong size) {
shubang964e6132019-11-26 15:05:22 -08001288 sp<Filter> filterSp = getFilter(env, filter);
1289 if (filterSp == NULL) {
1290 ALOGD("Failed to read filter FMQ: filter not found");
1291 return 0;
1292 }
1293 return copyData(env, filterSp, buffer, offset, size);
1294}
1295
shubang793e5702019-12-26 15:15:46 -08001296static int android_media_tv_Tuner_close_filter(JNIEnv*, jobject) {
1297 return 0;
1298}
1299
shubang4347e2e2019-12-13 17:20:40 -08001300// TODO: implement TimeFilter functions
1301static int android_media_tv_Tuner_time_filter_set_timestamp(
1302 JNIEnv, jobject, jlong) {
1303 return 0;
1304}
1305
1306static int android_media_tv_Tuner_time_filter_clear_timestamp(JNIEnv, jobject) {
1307 return 0;
1308}
1309
1310static jobject android_media_tv_Tuner_time_filter_get_timestamp(JNIEnv, jobject) {
1311 return NULL;
1312}
1313
1314static jobject android_media_tv_Tuner_time_filter_get_source_time(JNIEnv, jobject) {
1315 return NULL;
1316}
1317
1318static int android_media_tv_Tuner_time_filter_close(JNIEnv, jobject) {
1319 return 0;
1320}
1321
shubang13f15e02019-11-04 17:51:02 -08001322static jobject android_media_tv_Tuner_open_descrambler(JNIEnv *env, jobject thiz) {
1323 sp<JTuner> tuner = getTuner(env, thiz);
1324 return tuner->openDescrambler();
1325}
1326
shubang99c89922019-12-17 17:33:15 -08001327static int android_media_tv_Tuner_add_pid(
shubang13f15e02019-11-04 17:51:02 -08001328 JNIEnv *env, jobject descrambler, jint pidType, jint pid, jobject filter) {
1329 sp<IDescrambler> descramblerSp = getDescrambler(env, descrambler);
1330 if (descramblerSp == NULL) {
1331 return false;
1332 }
shubang7648a3c2019-11-25 18:16:45 -08001333 sp<IFilter> filterSp = getFilter(env, filter)->getIFilter();
shubang13f15e02019-11-04 17:51:02 -08001334 Result result = descramblerSp->addPid(getDemuxPid((int)pidType, (int)pid), filterSp);
shubang99c89922019-12-17 17:33:15 -08001335 return (int)result;
shubang13f15e02019-11-04 17:51:02 -08001336}
1337
shubang99c89922019-12-17 17:33:15 -08001338static int android_media_tv_Tuner_remove_pid(
shubang13f15e02019-11-04 17:51:02 -08001339 JNIEnv *env, jobject descrambler, jint pidType, jint pid, jobject filter) {
1340 sp<IDescrambler> descramblerSp = getDescrambler(env, descrambler);
1341 if (descramblerSp == NULL) {
1342 return false;
1343 }
shubang7648a3c2019-11-25 18:16:45 -08001344 sp<IFilter> filterSp = getFilter(env, filter)->getIFilter();
shubang13f15e02019-11-04 17:51:02 -08001345 Result result = descramblerSp->removePid(getDemuxPid((int)pidType, (int)pid), filterSp);
shubang99c89922019-12-17 17:33:15 -08001346 return (int)result;
1347}
1348
1349static int android_media_tv_Tuner_set_key_token(JNIEnv, jobject, jbyteArray) {
1350 return 0;
1351}
1352
1353static int android_media_tv_Tuner_close_descrambler(JNIEnv, jobject) {
1354 return 0;
shubang13f15e02019-11-04 17:51:02 -08001355}
1356
shubangd351b822020-01-22 17:29:18 -08001357static jobject android_media_tv_Tuner_open_dvr_recorder(
1358 JNIEnv* /* env */, jobject /* thiz */, jlong /* bufferSize */) {
1359 return NULL;
1360}
1361
1362static jobject android_media_tv_Tuner_open_dvr_playback(
1363 JNIEnv* /* env */, jobject /* thiz */, jlong /* bufferSize */) {
1364 return NULL;
shubang4a0eddf2019-11-08 17:10:18 -08001365}
1366
shubang34258932019-12-27 13:59:23 -08001367static jobject android_media_tv_Tuner_get_demux_caps(JNIEnv*, jobject) {
1368 return NULL;
1369}
1370
shubang793e5702019-12-26 15:15:46 -08001371static int android_media_tv_Tuner_attach_filter(JNIEnv *env, jobject dvr, jobject filter) {
shubang9e700ff2019-12-04 16:26:51 -08001372 sp<IDvr> dvrSp = getDvr(env, dvr)->getIDvr();
shubang7648a3c2019-11-25 18:16:45 -08001373 sp<IFilter> filterSp = getFilter(env, filter)->getIFilter();
shubang4a0eddf2019-11-08 17:10:18 -08001374 if (dvrSp == NULL || filterSp == NULL) {
1375 return false;
1376 }
1377 Result result = dvrSp->attachFilter(filterSp);
shubang793e5702019-12-26 15:15:46 -08001378 return (int) result;
shubang4a0eddf2019-11-08 17:10:18 -08001379}
1380
shubang793e5702019-12-26 15:15:46 -08001381static int android_media_tv_Tuner_detach_filter(JNIEnv *env, jobject dvr, jobject filter) {
shubang9e700ff2019-12-04 16:26:51 -08001382 sp<IDvr> dvrSp = getDvr(env, dvr)->getIDvr();
shubang7648a3c2019-11-25 18:16:45 -08001383 sp<IFilter> filterSp = getFilter(env, filter)->getIFilter();
shubang4a0eddf2019-11-08 17:10:18 -08001384 if (dvrSp == NULL || filterSp == NULL) {
1385 return false;
1386 }
1387 Result result = dvrSp->detachFilter(filterSp);
shubang793e5702019-12-26 15:15:46 -08001388 return (int) result;
shubang4a0eddf2019-11-08 17:10:18 -08001389}
1390
shubang030afb52019-11-27 16:09:02 -08001391static int android_media_tv_Tuner_configure_dvr(JNIEnv *env, jobject dvr, jobject settings) {
shubangba21a7f2019-12-05 16:58:55 -08001392 sp<Dvr> dvrSp = getDvr(env, dvr);
1393 sp<IDvr> iDvrSp = dvrSp->getIDvr();
shubang030afb52019-11-27 16:09:02 -08001394 if (dvrSp == NULL) {
1395 ALOGD("Failed to configure dvr: dvr not found");
1396 return (int)Result::INVALID_STATE;
1397 }
shubangba21a7f2019-12-05 16:58:55 -08001398 Result result = iDvrSp->configure(getDvrSettings(env, settings));
1399 MQDescriptorSync<uint8_t> dvrMQDesc;
1400 if (result == Result::SUCCESS) {
1401 Result getQueueDescResult = Result::UNKNOWN_ERROR;
1402 iDvrSp->getQueueDesc(
1403 [&](Result r, const MQDescriptorSync<uint8_t>& desc) {
1404 dvrMQDesc = desc;
1405 getQueueDescResult = r;
1406 ALOGD("getDvrQueueDesc");
1407 });
1408 if (getQueueDescResult == Result::SUCCESS) {
1409 dvrSp->mDvrMQ = std::make_unique<DvrMQ>(dvrMQDesc, true);
1410 EventFlag::createEventFlag(
1411 dvrSp->mDvrMQ->getEventFlagWord(), &(dvrSp->mDvrMQEventFlag));
1412 }
1413 }
shubang030afb52019-11-27 16:09:02 -08001414 return (int)result;
1415}
1416
shubang793e5702019-12-26 15:15:46 -08001417static int android_media_tv_Tuner_start_dvr(JNIEnv *env, jobject dvr) {
shubang9e700ff2019-12-04 16:26:51 -08001418 sp<IDvr> dvrSp = getDvr(env, dvr)->getIDvr();
shubang4a0eddf2019-11-08 17:10:18 -08001419 if (dvrSp == NULL) {
1420 ALOGD("Failed to start dvr: dvr not found");
1421 return false;
1422 }
shubang793e5702019-12-26 15:15:46 -08001423 Result result = dvrSp->start();
1424 return (int) result;
shubang4a0eddf2019-11-08 17:10:18 -08001425}
1426
shubang793e5702019-12-26 15:15:46 -08001427static int android_media_tv_Tuner_stop_dvr(JNIEnv *env, jobject dvr) {
shubang9e700ff2019-12-04 16:26:51 -08001428 sp<IDvr> dvrSp = getDvr(env, dvr)->getIDvr();
shubang4a0eddf2019-11-08 17:10:18 -08001429 if (dvrSp == NULL) {
1430 ALOGD("Failed to stop dvr: dvr not found");
1431 return false;
1432 }
shubang793e5702019-12-26 15:15:46 -08001433 Result result = dvrSp->stop();
1434 return (int) result;
shubang4a0eddf2019-11-08 17:10:18 -08001435}
1436
shubang793e5702019-12-26 15:15:46 -08001437static int android_media_tv_Tuner_flush_dvr(JNIEnv *env, jobject dvr) {
shubang9e700ff2019-12-04 16:26:51 -08001438 sp<IDvr> dvrSp = getDvr(env, dvr)->getIDvr();
shubang4a0eddf2019-11-08 17:10:18 -08001439 if (dvrSp == NULL) {
1440 ALOGD("Failed to flush dvr: dvr not found");
1441 return false;
1442 }
shubang793e5702019-12-26 15:15:46 -08001443 Result result = dvrSp->flush();
1444 return (int) result;
1445}
1446
1447static int android_media_tv_Tuner_close_dvr(JNIEnv*, jobject) {
1448 return 0;
shubang4a0eddf2019-11-08 17:10:18 -08001449}
1450
shubang847fc0a2019-12-26 16:54:10 -08001451static int android_media_tv_Tuner_lnb_set_voltage(JNIEnv*, jobject, jint) {
1452 return 0;
1453}
1454
1455static int android_media_tv_Tuner_lnb_set_tone(JNIEnv*, jobject, jint) {
1456 return 0;
1457}
1458
1459static int android_media_tv_Tuner_lnb_set_position(JNIEnv*, jobject, jint) {
1460 return 0;
1461}
1462
1463static int android_media_tv_Tuner_lnb_send_diseqc_msg(JNIEnv*, jobject, jbyteArray) {
1464 return 0;
1465}
1466
1467static int android_media_tv_Tuner_close_lnb(JNIEnv*, jobject) {
1468 return 0;
1469}
1470
shubangba21a7f2019-12-05 16:58:55 -08001471static void android_media_tv_Tuner_dvr_set_fd(JNIEnv *env, jobject dvr, jobject jfd) {
1472 sp<Dvr> dvrSp = getDvr(env, dvr);
1473 if (dvrSp == NULL) {
1474 ALOGD("Failed to set FD for dvr: dvr not found");
1475 }
1476 dvrSp->mFd = jniGetFDFromFileDescriptor(env, jfd);
1477 ALOGD("set fd = %d", dvrSp->mFd);
1478}
1479
shubangd351b822020-01-22 17:29:18 -08001480static jlong android_media_tv_Tuner_read_dvr(JNIEnv *env, jobject dvr, jlong size) {
shubangba21a7f2019-12-05 16:58:55 -08001481 sp<Dvr> dvrSp = getDvr(env, dvr);
1482 if (dvrSp == NULL) {
1483 ALOGD("Failed to read dvr: dvr not found");
1484 }
1485
shubangd351b822020-01-22 17:29:18 -08001486 long available = dvrSp->mDvrMQ->availableToWrite();
1487 long write = std::min((long) size, available);
shubangba21a7f2019-12-05 16:58:55 -08001488
1489 DvrMQ::MemTransaction tx;
shubangd351b822020-01-22 17:29:18 -08001490 long ret = 0;
shubangba21a7f2019-12-05 16:58:55 -08001491 if (dvrSp->mDvrMQ->beginWrite(write, &tx)) {
1492 auto first = tx.getFirstRegion();
1493 auto data = first.getAddress();
shubangd351b822020-01-22 17:29:18 -08001494 long length = first.getLength();
1495 long firstToWrite = std::min(length, write);
shubangba21a7f2019-12-05 16:58:55 -08001496 ret = read(dvrSp->mFd, data, firstToWrite);
1497 if (ret < firstToWrite) {
shubangd351b822020-01-22 17:29:18 -08001498 ALOGW("[DVR] file to MQ, first region: %ld bytes to write, but %ld bytes written",
shubangba21a7f2019-12-05 16:58:55 -08001499 firstToWrite, ret);
1500 } else if (firstToWrite < write) {
shubangd351b822020-01-22 17:29:18 -08001501 ALOGD("[DVR] write second region: %ld bytes written, %ld bytes in total", ret, write);
shubangba21a7f2019-12-05 16:58:55 -08001502 auto second = tx.getSecondRegion();
1503 data = second.getAddress();
1504 length = second.getLength();
1505 int secondToWrite = std::min(length, write - firstToWrite);
1506 ret += read(dvrSp->mFd, data, secondToWrite);
1507 }
shubangd351b822020-01-22 17:29:18 -08001508 ALOGD("[DVR] file to MQ: %ld bytes need to be written, %ld bytes written", write, ret);
shubangba21a7f2019-12-05 16:58:55 -08001509 if (!dvrSp->mDvrMQ->commitWrite(ret)) {
1510 ALOGE("[DVR] Error: failed to commit write!");
1511 }
1512
1513 } else {
1514 ALOGE("dvrMq.beginWrite failed");
1515 }
shubangd351b822020-01-22 17:29:18 -08001516 return (jlong) ret;
shubangba21a7f2019-12-05 16:58:55 -08001517}
1518
shubangd351b822020-01-22 17:29:18 -08001519static jlong android_media_tv_Tuner_read_dvr_from_array(
1520 JNIEnv /* *env */, jobject /* dvr */, jbyteArray /* bytes */, jlong /* offset */,
1521 jlong /* size */) {
shubangba21a7f2019-12-05 16:58:55 -08001522 //TODO: impl
1523 return 0;
1524}
1525
shubangd351b822020-01-22 17:29:18 -08001526static jlong android_media_tv_Tuner_write_dvr(JNIEnv *env, jobject dvr, jlong size) {
shubang5f4ea352019-12-09 15:12:10 -08001527 sp<Dvr> dvrSp = getDvr(env, dvr);
1528 if (dvrSp == NULL) {
1529 ALOGW("Failed to write dvr: dvr not found");
1530 return 0;
1531 }
1532
1533 if (dvrSp->mDvrMQ == NULL) {
1534 ALOGW("Failed to write dvr: dvr not configured");
1535 return 0;
1536 }
1537
1538 DvrMQ& dvrMq = dvrSp->getDvrMQ();
1539
shubangd351b822020-01-22 17:29:18 -08001540 long available = dvrMq.availableToRead();
1541 long toRead = std::min((long) size, available);
shubang5f4ea352019-12-09 15:12:10 -08001542
shubangd351b822020-01-22 17:29:18 -08001543 long ret = 0;
shubang5f4ea352019-12-09 15:12:10 -08001544 DvrMQ::MemTransaction tx;
1545 if (dvrMq.beginRead(toRead, &tx)) {
1546 auto first = tx.getFirstRegion();
1547 auto data = first.getAddress();
shubangd351b822020-01-22 17:29:18 -08001548 long length = first.getLength();
1549 long firstToRead = std::min(length, toRead);
shubang5f4ea352019-12-09 15:12:10 -08001550 ret = write(dvrSp->mFd, data, firstToRead);
1551 if (ret < firstToRead) {
shubangd351b822020-01-22 17:29:18 -08001552 ALOGW("[DVR] MQ to file: %ld bytes read, but %ld bytes written", firstToRead, ret);
shubang5f4ea352019-12-09 15:12:10 -08001553 } else if (firstToRead < toRead) {
shubangd351b822020-01-22 17:29:18 -08001554 ALOGD("[DVR] read second region: %ld bytes read, %ld bytes in total", ret, toRead);
shubang5f4ea352019-12-09 15:12:10 -08001555 auto second = tx.getSecondRegion();
1556 data = second.getAddress();
1557 length = second.getLength();
1558 int secondToRead = toRead - firstToRead;
1559 ret += write(dvrSp->mFd, data, secondToRead);
1560 }
shubangd351b822020-01-22 17:29:18 -08001561 ALOGD("[DVR] MQ to file: %ld bytes to be read, %ld bytes written", toRead, ret);
shubang5f4ea352019-12-09 15:12:10 -08001562 if (!dvrMq.commitRead(ret)) {
1563 ALOGE("[DVR] Error: failed to commit read!");
1564 }
1565
1566 } else {
1567 ALOGE("dvrMq.beginRead failed");
1568 }
1569
shubangd351b822020-01-22 17:29:18 -08001570 return (jlong) ret;
shubang5f4ea352019-12-09 15:12:10 -08001571}
1572
shubangd351b822020-01-22 17:29:18 -08001573static jlong android_media_tv_Tuner_write_dvr_to_array(
1574 JNIEnv /* *env */, jobject /* dvr */, jbyteArray /* bytes */, jlong /* offset */,
1575 jlong /* size */) {
shubang5f4ea352019-12-09 15:12:10 -08001576 //TODO: impl
1577 return 0;
1578}
shubangba21a7f2019-12-05 16:58:55 -08001579
shubangd0977902019-11-07 18:58:43 -08001580static const JNINativeMethod gTunerMethods[] = {
shubang8ab43b12019-10-18 15:55:55 -07001581 { "nativeInit", "()V", (void *)android_media_tv_Tuner_native_init },
1582 { "nativeSetup", "()V", (void *)android_media_tv_Tuner_native_setup },
shubang7e849b02019-10-18 19:36:25 -07001583 { "nativeGetFrontendIds", "()Ljava/util/List;",
1584 (void *)android_media_tv_Tuner_get_frontend_ids },
1585 { "nativeOpenFrontendById", "(I)Landroid/media/tv/tuner/Tuner$Frontend;",
1586 (void *)android_media_tv_Tuner_open_frontend_by_id },
shubangd351b822020-01-22 17:29:18 -08001587 { "nativeTune", "(ILandroid/media/tv/tuner/frontend/FrontendSettings;)I",
shubang74bfd482019-10-29 19:10:22 -07001588 (void *)android_media_tv_Tuner_tune },
shubange65b6862019-12-17 15:43:35 -08001589 { "nativeStopTune", "()I", (void *)android_media_tv_Tuner_stop_tune },
shubangd351b822020-01-22 17:29:18 -08001590 { "nativeScan", "(ILandroid/media/tv/tuner/frontend/FrontendSettings;I)I",
shubangd5b845f2019-12-11 15:29:09 -08001591 (void *)android_media_tv_Tuner_scan },
shubang793e5702019-12-26 15:15:46 -08001592 { "nativeStopScan", "()I", (void *)android_media_tv_Tuner_stop_scan },
shubange65b6862019-12-17 15:43:35 -08001593 { "nativeSetLnb", "(I)I", (void *)android_media_tv_Tuner_set_lnb },
1594 { "nativeSetLna", "(Z)I", (void *)android_media_tv_Tuner_set_lna },
shubangd351b822020-01-22 17:29:18 -08001595 { "nativeGetFrontendStatus", "([I)Landroid/media/tv/tuner/frontend/FrontendStatus;",
shubang1512ec12019-12-23 18:22:42 -08001596 (void *)android_media_tv_Tuner_get_frontend_status },
shubangdeb067c2020-01-27 13:21:55 -08001597 { "nativeGetAvSyncHwId", "(Landroid/media/tv/tuner/filter/Filter;)I",
shubang7343fee2019-12-27 12:02:08 -08001598 (void *)android_media_tv_Tuner_gat_av_sync_hw_id },
1599 { "nativeGetAvSyncTime", "(I)J", (void *)android_media_tv_Tuner_gat_av_sync_time },
1600 { "nativeConnectCiCam", "(I)I", (void *)android_media_tv_Tuner_connect_cicam },
1601 { "nativeDisconnectCiCam", "()I", (void *)android_media_tv_Tuner_disconnect_cicam },
shubangdeb067c2020-01-27 13:21:55 -08001602 { "nativeGetFrontendInfo", "(I)Landroid/media/tv/tuner/frontend/FrontendInfo;",
shubang95c1f752019-12-27 16:29:48 -08001603 (void *)android_media_tv_Tuner_get_frontend_info },
shubangdeb067c2020-01-27 13:21:55 -08001604 { "nativeOpenFilter", "(IIJ)Landroid/media/tv/tuner/filter/Filter;",
shubang6f473d62019-11-01 15:42:21 -07001605 (void *)android_media_tv_Tuner_open_filter },
shubangdeb067c2020-01-27 13:21:55 -08001606 { "nativeOpenTimeFilter", "()Landroid/media/tv/tuner/filter/TimeFilter;",
shubang4347e2e2019-12-13 17:20:40 -08001607 (void *)android_media_tv_Tuner_open_time_filter },
shubang760f0312019-11-12 17:11:28 -08001608 { "nativeGetLnbIds", "()Ljava/util/List;",
1609 (void *)android_media_tv_Tuner_get_lnb_ids },
shubangd351b822020-01-22 17:29:18 -08001610 { "nativeOpenLnbById", "(I)Landroid/media/tv/tuner/Lnb;",
shubang760f0312019-11-12 17:11:28 -08001611 (void *)android_media_tv_Tuner_open_lnb_by_id },
shubangd351b822020-01-22 17:29:18 -08001612 { "nativeOpenDescrambler", "()Landroid/media/tv/tuner/Descrambler;",
shubang13f15e02019-11-04 17:51:02 -08001613 (void *)android_media_tv_Tuner_open_descrambler },
shubangd351b822020-01-22 17:29:18 -08001614 { "nativeOpenDvrRecorder", "(J)Landroid/media/tv/tuner/dvr/DvrRecorder;",
1615 (void *)android_media_tv_Tuner_open_dvr_recorder },
1616 { "nativeOpenDvrPlayback", "(J)Landroid/media/tv/tuner/dvr/DvrPlayback;",
1617 (void *)android_media_tv_Tuner_open_dvr_playback },
shubang34258932019-12-27 13:59:23 -08001618 { "nativeGetDemuxCapabilities", "()Landroid/media/tv/tuner/DemuxCapabilities;",
1619 (void *)android_media_tv_Tuner_get_demux_caps },
shubang8ab43b12019-10-18 15:55:55 -07001620};
1621
shubangd0977902019-11-07 18:58:43 -08001622static const JNINativeMethod gFilterMethods[] = {
shubangd351b822020-01-22 17:29:18 -08001623 { "nativeConfigureFilter", "(IILandroid/media/tv/tuner/filter/FilterConfiguration;)I",
shubang75c87082019-11-15 11:26:56 -08001624 (void *)android_media_tv_Tuner_configure_filter },
shubang793e5702019-12-26 15:15:46 -08001625 { "nativeGetId", "()I", (void *)android_media_tv_Tuner_get_filter_id },
shubangd351b822020-01-22 17:29:18 -08001626 { "nativeSetDataSource", "(Landroid/media/tv/tuner/filter/Filter;)I",
shubang793e5702019-12-26 15:15:46 -08001627 (void *)android_media_tv_Tuner_set_filter_data_source },
1628 { "nativeStartFilter", "()I", (void *)android_media_tv_Tuner_start_filter },
1629 { "nativeStopFilter", "()I", (void *)android_media_tv_Tuner_stop_filter },
1630 { "nativeFlushFilter", "()I", (void *)android_media_tv_Tuner_flush_filter },
shubangd351b822020-01-22 17:29:18 -08001631 { "nativeRead", "([BJJ)I", (void *)android_media_tv_Tuner_read_filter_fmq },
Amy1b301f42020-01-02 11:07:56 -08001632 { "nativeClose", "()I", (void *)android_media_tv_Tuner_close_filter },
shubangd0977902019-11-07 18:58:43 -08001633};
1634
shubang4347e2e2019-12-13 17:20:40 -08001635static const JNINativeMethod gTimeFilterMethods[] = {
shubangdeb067c2020-01-27 13:21:55 -08001636 { "nativeSetTimestamp", "(J)I", (void *)android_media_tv_Tuner_time_filter_set_timestamp },
1637 { "nativeClearTimestamp", "()I", (void *)android_media_tv_Tuner_time_filter_clear_timestamp },
1638 { "nativeGetTimestamp", "()Ljava/lang/Long;",
shubang4347e2e2019-12-13 17:20:40 -08001639 (void *)android_media_tv_Tuner_time_filter_get_timestamp },
1640 { "nativeGetSourceTime", "()Ljava/lang/Long;",
1641 (void *)android_media_tv_Tuner_time_filter_get_source_time },
1642 { "nativeClose", "()I", (void *)android_media_tv_Tuner_time_filter_close },
1643};
1644
shubang13f15e02019-11-04 17:51:02 -08001645static const JNINativeMethod gDescramblerMethods[] = {
shubangd351b822020-01-22 17:29:18 -08001646 { "nativeAddPid", "(IILandroid/media/tv/tuner/filter/Filter;)I",
shubang13f15e02019-11-04 17:51:02 -08001647 (void *)android_media_tv_Tuner_add_pid },
shubangd351b822020-01-22 17:29:18 -08001648 { "nativeRemovePid", "(IILandroid/media/tv/tuner/filter/Filter;)I",
shubang13f15e02019-11-04 17:51:02 -08001649 (void *)android_media_tv_Tuner_remove_pid },
shubang99c89922019-12-17 17:33:15 -08001650 { "nativeSetKeyToken", "([B)I", (void *)android_media_tv_Tuner_set_key_token },
Amy1b301f42020-01-02 11:07:56 -08001651 { "nativeClose", "()I", (void *)android_media_tv_Tuner_close_descrambler },
shubang13f15e02019-11-04 17:51:02 -08001652};
1653
shubang4a0eddf2019-11-08 17:10:18 -08001654static const JNINativeMethod gDvrMethods[] = {
shubangd351b822020-01-22 17:29:18 -08001655 { "nativeAttachFilter", "(Landroid/media/tv/tuner/filter/Filter;)I",
shubang4a0eddf2019-11-08 17:10:18 -08001656 (void *)android_media_tv_Tuner_attach_filter },
shubangd351b822020-01-22 17:29:18 -08001657 { "nativeDetachFilter", "(Landroid/media/tv/tuner/filter/Filter;)I",
shubang4a0eddf2019-11-08 17:10:18 -08001658 (void *)android_media_tv_Tuner_detach_filter },
shubangd351b822020-01-22 17:29:18 -08001659 { "nativeConfigureDvr", "(Landroid/media/tv/tuner/dvr/DvrSettings;)I",
shubang030afb52019-11-27 16:09:02 -08001660 (void *)android_media_tv_Tuner_configure_dvr },
shubang793e5702019-12-26 15:15:46 -08001661 { "nativeStartDvr", "()I", (void *)android_media_tv_Tuner_start_dvr },
1662 { "nativeStopDvr", "()I", (void *)android_media_tv_Tuner_stop_dvr },
1663 { "nativeFlushDvr", "()I", (void *)android_media_tv_Tuner_flush_dvr },
1664 { "nativeClose", "()I", (void *)android_media_tv_Tuner_close_dvr },
shubangd351b822020-01-22 17:29:18 -08001665 { "nativeSetFileDescriptor", "(I)V", (void *)android_media_tv_Tuner_dvr_set_fd },
1666};
1667
1668static const JNINativeMethod gDvrRecorderMethods[] = {
1669 { "nativeWrite", "(J)J", (void *)android_media_tv_Tuner_write_dvr },
1670 { "nativeWrite", "([BJJ)J", (void *)android_media_tv_Tuner_write_dvr_to_array },
1671};
1672
1673static const JNINativeMethod gDvrPlaybackMethods[] = {
1674 { "nativeRead", "(J)J", (void *)android_media_tv_Tuner_read_dvr },
1675 { "nativeRead", "([BJJ)J", (void *)android_media_tv_Tuner_read_dvr_from_array },
shubang4a0eddf2019-11-08 17:10:18 -08001676};
1677
shubang847fc0a2019-12-26 16:54:10 -08001678static const JNINativeMethod gLnbMethods[] = {
1679 { "nativeSetVoltage", "(I)I", (void *)android_media_tv_Tuner_lnb_set_voltage },
1680 { "nativeSetTone", "(I)I", (void *)android_media_tv_Tuner_lnb_set_tone },
1681 { "nativeSetSatellitePosition", "(I)I", (void *)android_media_tv_Tuner_lnb_set_position },
1682 { "nativeSendDiseqcMessage", "([B)I", (void *)android_media_tv_Tuner_lnb_send_diseqc_msg },
1683 { "nativeClose", "()I", (void *)android_media_tv_Tuner_close_lnb },
1684};
1685
shubangd0977902019-11-07 18:58:43 -08001686static bool register_android_media_tv_Tuner(JNIEnv *env) {
1687 if (AndroidRuntime::registerNativeMethods(
1688 env, "android/media/tv/tuner/Tuner", gTunerMethods, NELEM(gTunerMethods)) != JNI_OK) {
1689 ALOGE("Failed to register tuner native methods");
1690 return false;
1691 }
1692 if (AndroidRuntime::registerNativeMethods(
shubangd351b822020-01-22 17:29:18 -08001693 env, "android/media/tv/tuner/filter/Filter",
shubangd0977902019-11-07 18:58:43 -08001694 gFilterMethods,
1695 NELEM(gFilterMethods)) != JNI_OK) {
1696 ALOGE("Failed to register filter native methods");
1697 return false;
1698 }
shubang13f15e02019-11-04 17:51:02 -08001699 if (AndroidRuntime::registerNativeMethods(
shubangd351b822020-01-22 17:29:18 -08001700 env, "android/media/tv/tuner/filter/TimeFilter",
shubang4347e2e2019-12-13 17:20:40 -08001701 gTimeFilterMethods,
1702 NELEM(gTimeFilterMethods)) != JNI_OK) {
1703 ALOGE("Failed to register time filter native methods");
1704 return false;
1705 }
1706 if (AndroidRuntime::registerNativeMethods(
shubangd351b822020-01-22 17:29:18 -08001707 env, "android/media/tv/tuner/Descrambler",
shubang13f15e02019-11-04 17:51:02 -08001708 gDescramblerMethods,
1709 NELEM(gDescramblerMethods)) != JNI_OK) {
1710 ALOGE("Failed to register descrambler native methods");
1711 return false;
1712 }
shubang4a0eddf2019-11-08 17:10:18 -08001713 if (AndroidRuntime::registerNativeMethods(
shubangd351b822020-01-22 17:29:18 -08001714 env, "android/media/tv/tuner/dvr/Dvr",
shubang4a0eddf2019-11-08 17:10:18 -08001715 gDvrMethods,
1716 NELEM(gDvrMethods)) != JNI_OK) {
1717 ALOGE("Failed to register dvr native methods");
1718 return false;
1719 }
shubang847fc0a2019-12-26 16:54:10 -08001720 if (AndroidRuntime::registerNativeMethods(
shubangd351b822020-01-22 17:29:18 -08001721 env, "android/media/tv/tuner/dvr/DvrRecorder",
1722 gDvrRecorderMethods,
1723 NELEM(gDvrRecorderMethods)) != JNI_OK) {
1724 ALOGE("Failed to register dvr recorder native methods");
1725 return false;
1726 }
1727 if (AndroidRuntime::registerNativeMethods(
1728 env, "android/media/tv/tuner/dvr/DvrPlayback",
1729 gDvrPlaybackMethods,
1730 NELEM(gDvrPlaybackMethods)) != JNI_OK) {
1731 ALOGE("Failed to register dvr playback native methods");
1732 return false;
1733 }
1734 if (AndroidRuntime::registerNativeMethods(
1735 env, "android/media/tv/tuner/Lnb",
shubang847fc0a2019-12-26 16:54:10 -08001736 gLnbMethods,
1737 NELEM(gLnbMethods)) != JNI_OK) {
1738 ALOGE("Failed to register lnb native methods");
1739 return false;
1740 }
shubangd0977902019-11-07 18:58:43 -08001741 return true;
shubang8ab43b12019-10-18 15:55:55 -07001742}
1743
1744jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
1745{
1746 JNIEnv* env = NULL;
1747 jint result = -1;
1748
1749 if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
1750 ALOGE("ERROR: GetEnv failed\n");
1751 return result;
1752 }
1753 assert(env != NULL);
1754
shubangd0977902019-11-07 18:58:43 -08001755 if (!register_android_media_tv_Tuner(env)) {
shubang8ab43b12019-10-18 15:55:55 -07001756 ALOGE("ERROR: Tuner native registration failed\n");
1757 return result;
1758 }
1759 return JNI_VERSION_1_4;
1760}