blob: e8f18a59049e1ed6479128a8cae68a93df16f164 [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
shubangd49681e2020-02-17 21:32:30 -080020#include "android_media_MediaCodecLinearBlock.h"
shubang8ab43b12019-10-18 15:55:55 -070021#include "android_media_tv_Tuner.h"
22#include "android_runtime/AndroidRuntime.h"
23
shubang3aef4fe2020-04-01 16:51:04 -070024#include <android-base/logging.h>
shubang8ab43b12019-10-18 15:55:55 -070025#include <android/hardware/tv/tuner/1.0/ITuner.h>
26#include <media/stagefright/foundation/ADebug.h>
shubangba21a7f2019-12-05 16:58:55 -080027#include <nativehelper/JNIHelp.h>
shubangd49681e2020-02-17 21:32:30 -080028#include <nativehelper/ScopedLocalRef.h>
29#include <utils/NativeHandle.h>
shubang8ab43b12019-10-18 15:55:55 -070030
31#pragma GCC diagnostic ignored "-Wunused-function"
32
shubang6f473d62019-11-01 15:42:21 -070033using ::android::hardware::Void;
shubang44fa1422020-01-30 11:42:59 -080034using ::android::hardware::hidl_bitfield;
shubang7e849b02019-10-18 19:36:25 -070035using ::android::hardware::hidl_vec;
shubang3e0c37b2020-02-19 19:09:10 -080036using ::android::hardware::tv::tuner::V1_0::AudioExtraMetaData;
37using ::android::hardware::tv::tuner::V1_0::Constant;
shubang030afb52019-11-27 16:09:02 -080038using ::android::hardware::tv::tuner::V1_0::DataFormat;
shubang44fa1422020-01-30 11:42:59 -080039using ::android::hardware::tv::tuner::V1_0::DemuxAlpFilterSettings;
40using ::android::hardware::tv::tuner::V1_0::DemuxAlpFilterType;
shubang87788c32020-02-04 13:55:23 -080041using ::android::hardware::tv::tuner::V1_0::DemuxAlpLengthType;
shubangc4b45702020-03-23 18:48:12 -070042using ::android::hardware::tv::tuner::V1_0::DemuxCapabilities;
shubang44fa1422020-01-30 11:42:59 -080043using ::android::hardware::tv::tuner::V1_0::DemuxFilterAvSettings;
shubang3e0c37b2020-02-19 19:09:10 -080044using ::android::hardware::tv::tuner::V1_0::DemuxFilterDownloadEvent;
shubang44fa1422020-01-30 11:42:59 -080045using ::android::hardware::tv::tuner::V1_0::DemuxFilterDownloadSettings;
shubang3e0c37b2020-02-19 19:09:10 -080046using ::android::hardware::tv::tuner::V1_0::DemuxFilterIpPayloadEvent;
shubang6f473d62019-11-01 15:42:21 -070047using ::android::hardware::tv::tuner::V1_0::DemuxFilterMainType;
shubangd49681e2020-02-17 21:32:30 -080048using ::android::hardware::tv::tuner::V1_0::DemuxFilterMediaEvent;
shubang3e0c37b2020-02-19 19:09:10 -080049using ::android::hardware::tv::tuner::V1_0::DemuxFilterMmtpRecordEvent;
shubang75c87082019-11-15 11:26:56 -080050using ::android::hardware::tv::tuner::V1_0::DemuxFilterPesDataSettings;
shubang3e0c37b2020-02-19 19:09:10 -080051using ::android::hardware::tv::tuner::V1_0::DemuxFilterPesEvent;
shubang44fa1422020-01-30 11:42:59 -080052using ::android::hardware::tv::tuner::V1_0::DemuxFilterRecordSettings;
53using ::android::hardware::tv::tuner::V1_0::DemuxFilterSectionBits;
shubang3e0c37b2020-02-19 19:09:10 -080054using ::android::hardware::tv::tuner::V1_0::DemuxFilterSectionEvent;
shubang44fa1422020-01-30 11:42:59 -080055using ::android::hardware::tv::tuner::V1_0::DemuxFilterSectionSettings;
shubang75c87082019-11-15 11:26:56 -080056using ::android::hardware::tv::tuner::V1_0::DemuxFilterSettings;
shubang3e0c37b2020-02-19 19:09:10 -080057using ::android::hardware::tv::tuner::V1_0::DemuxFilterTemiEvent;
58using ::android::hardware::tv::tuner::V1_0::DemuxFilterTsRecordEvent;
shubang87788c32020-02-04 13:55:23 -080059using ::android::hardware::tv::tuner::V1_0::DemuxIpAddress;
shubang44fa1422020-01-30 11:42:59 -080060using ::android::hardware::tv::tuner::V1_0::DemuxIpFilterSettings;
61using ::android::hardware::tv::tuner::V1_0::DemuxIpFilterType;
62using ::android::hardware::tv::tuner::V1_0::DemuxMmtpFilterSettings;
63using ::android::hardware::tv::tuner::V1_0::DemuxMmtpFilterType;
shubang13f15e02019-11-04 17:51:02 -080064using ::android::hardware::tv::tuner::V1_0::DemuxMmtpPid;
shubang964e6132019-11-26 15:05:22 -080065using ::android::hardware::tv::tuner::V1_0::DemuxQueueNotifyBits;
shubang44fa1422020-01-30 11:42:59 -080066using ::android::hardware::tv::tuner::V1_0::DemuxRecordScIndexType;
67using ::android::hardware::tv::tuner::V1_0::DemuxScHevcIndex;
68using ::android::hardware::tv::tuner::V1_0::DemuxScIndex;
69using ::android::hardware::tv::tuner::V1_0::DemuxTlvFilterSettings;
70using ::android::hardware::tv::tuner::V1_0::DemuxTlvFilterType;
shubang13f15e02019-11-04 17:51:02 -080071using ::android::hardware::tv::tuner::V1_0::DemuxTpid;
shubang75c87082019-11-15 11:26:56 -080072using ::android::hardware::tv::tuner::V1_0::DemuxTsFilterSettings;
shubang6f473d62019-11-01 15:42:21 -070073using ::android::hardware::tv::tuner::V1_0::DemuxTsFilterType;
shubang44fa1422020-01-30 11:42:59 -080074using ::android::hardware::tv::tuner::V1_0::DemuxTsIndex;
shubang030afb52019-11-27 16:09:02 -080075using ::android::hardware::tv::tuner::V1_0::DvrSettings;
shubang74bfd482019-10-29 19:10:22 -070076using ::android::hardware::tv::tuner::V1_0::FrontendAnalogSettings;
77using ::android::hardware::tv::tuner::V1_0::FrontendAnalogSifStandard;
78using ::android::hardware::tv::tuner::V1_0::FrontendAnalogType;
shubangdeb067c2020-01-27 13:21:55 -080079using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3Bandwidth;
80using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3CodeRate;
81using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3DemodOutputFormat;
82using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3Fec;
83using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3Modulation;
84using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3PlpSettings;
85using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3Settings;
86using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3TimeInterleaveMode;
87using ::android::hardware::tv::tuner::V1_0::FrontendAtscSettings;
88using ::android::hardware::tv::tuner::V1_0::FrontendAtscModulation;
89using ::android::hardware::tv::tuner::V1_0::FrontendDvbcAnnex;
90using ::android::hardware::tv::tuner::V1_0::FrontendDvbcModulation;
91using ::android::hardware::tv::tuner::V1_0::FrontendDvbcOuterFec;
92using ::android::hardware::tv::tuner::V1_0::FrontendDvbcSettings;
93using ::android::hardware::tv::tuner::V1_0::FrontendDvbcSpectralInversion;
94using ::android::hardware::tv::tuner::V1_0::FrontendDvbsCodeRate;
95using ::android::hardware::tv::tuner::V1_0::FrontendDvbsModulation;
96using ::android::hardware::tv::tuner::V1_0::FrontendDvbsPilot;
97using ::android::hardware::tv::tuner::V1_0::FrontendDvbsRolloff;
98using ::android::hardware::tv::tuner::V1_0::FrontendDvbsSettings;
99using ::android::hardware::tv::tuner::V1_0::FrontendDvbsStandard;
100using ::android::hardware::tv::tuner::V1_0::FrontendDvbsVcmMode;
101using ::android::hardware::tv::tuner::V1_0::FrontendDvbtBandwidth;
102using ::android::hardware::tv::tuner::V1_0::FrontendDvbtCoderate;
103using ::android::hardware::tv::tuner::V1_0::FrontendDvbtConstellation;
104using ::android::hardware::tv::tuner::V1_0::FrontendDvbtGuardInterval;
105using ::android::hardware::tv::tuner::V1_0::FrontendDvbtHierarchy;
106using ::android::hardware::tv::tuner::V1_0::FrontendDvbtPlpMode;
107using ::android::hardware::tv::tuner::V1_0::FrontendDvbtSettings;
108using ::android::hardware::tv::tuner::V1_0::FrontendDvbtStandard;
109using ::android::hardware::tv::tuner::V1_0::FrontendDvbtTransmissionMode;
110using ::android::hardware::tv::tuner::V1_0::FrontendInnerFec;
111using ::android::hardware::tv::tuner::V1_0::FrontendIsdbs3Coderate;
112using ::android::hardware::tv::tuner::V1_0::FrontendIsdbs3Modulation;
113using ::android::hardware::tv::tuner::V1_0::FrontendIsdbs3Rolloff;
114using ::android::hardware::tv::tuner::V1_0::FrontendIsdbs3Settings;
115using ::android::hardware::tv::tuner::V1_0::FrontendIsdbsCoderate;
116using ::android::hardware::tv::tuner::V1_0::FrontendIsdbsModulation;
117using ::android::hardware::tv::tuner::V1_0::FrontendIsdbsRolloff;
118using ::android::hardware::tv::tuner::V1_0::FrontendIsdbsSettings;
119using ::android::hardware::tv::tuner::V1_0::FrontendIsdbsStreamIdType;
120using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtBandwidth;
121using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtCoderate;
122using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtGuardInterval;
123using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtMode;
124using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtModulation;
125using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtSettings;
shubangb83f8232020-03-24 18:04:35 -0700126using ::android::hardware::tv::tuner::V1_0::FrontendModulationStatus;
shubangc8736b72020-02-11 18:27:53 -0800127using ::android::hardware::tv::tuner::V1_0::FrontendScanAtsc3PlpInfo;
shubangb83f8232020-03-24 18:04:35 -0700128using ::android::hardware::tv::tuner::V1_0::FrontendStatus;
129using ::android::hardware::tv::tuner::V1_0::FrontendStatusAtsc3PlpInfo;
130using ::android::hardware::tv::tuner::V1_0::FrontendStatusType;
shubangdeb067c2020-01-27 13:21:55 -0800131using ::android::hardware::tv::tuner::V1_0::FrontendType;
shubang8ab43b12019-10-18 15:55:55 -0700132using ::android::hardware::tv::tuner::V1_0::ITuner;
shubang1c1144e2020-03-03 18:00:17 -0800133using ::android::hardware::tv::tuner::V1_0::LnbPosition;
134using ::android::hardware::tv::tuner::V1_0::LnbTone;
135using ::android::hardware::tv::tuner::V1_0::LnbVoltage;
shubang030afb52019-11-27 16:09:02 -0800136using ::android::hardware::tv::tuner::V1_0::PlaybackSettings;
137using ::android::hardware::tv::tuner::V1_0::RecordSettings;
shubang8ab43b12019-10-18 15:55:55 -0700138
139struct fields_t {
shubang13f15e02019-11-04 17:51:02 -0800140 jfieldID tunerContext;
shubang1c1144e2020-03-03 18:00:17 -0800141 jfieldID lnbContext;
shubangcdf30de2019-11-06 17:28:38 -0800142 jfieldID filterContext;
shubangf657da22020-02-05 16:27:06 -0800143 jfieldID timeFilterContext;
shubang13f15e02019-11-04 17:51:02 -0800144 jfieldID descramblerContext;
shubang5637a662020-02-27 18:06:21 -0800145 jfieldID dvrRecorderContext;
146 jfieldID dvrPlaybackContext;
shubang3aef4fe2020-04-01 16:51:04 -0700147 jfieldID mediaEventContext;
shubang7e849b02019-10-18 19:36:25 -0700148 jmethodID frontendInitID;
shubang6f473d62019-11-01 15:42:21 -0700149 jmethodID filterInitID;
shubangf657da22020-02-05 16:27:06 -0800150 jmethodID timeFilterInitID;
shubang5637a662020-02-27 18:06:21 -0800151 jmethodID dvrRecorderInitID;
152 jmethodID dvrPlaybackInitID;
shubang4b8c5402019-10-24 17:49:53 -0700153 jmethodID onFrontendEventID;
shubangcdf30de2019-11-06 17:28:38 -0800154 jmethodID onFilterStatusID;
shubang3e0c37b2020-02-19 19:09:10 -0800155 jmethodID onFilterEventID;
shubang760f0312019-11-12 17:11:28 -0800156 jmethodID lnbInitID;
157 jmethodID onLnbEventID;
shubangd295be02020-03-27 17:08:11 -0700158 jmethodID onLnbDiseqcMessageID;
shubang431e5612020-03-30 21:24:56 -0700159 jmethodID onDvrRecordStatusID;
160 jmethodID onDvrPlaybackStatusID;
shubang13f15e02019-11-04 17:51:02 -0800161 jmethodID descramblerInitID;
shubangd49681e2020-02-17 21:32:30 -0800162 jmethodID linearBlockInitID;
163 jmethodID linearBlockSetInternalStateID;
shubang8ab43b12019-10-18 15:55:55 -0700164};
165
166static fields_t gFields;
167
shubangd49681e2020-02-17 21:32:30 -0800168
shubang87788c32020-02-04 13:55:23 -0800169static int IP_V4_LENGTH = 4;
170static int IP_V6_LENGTH = 16;
171
shubang3aef4fe2020-04-01 16:51:04 -0700172void DestroyCallback(const C2Buffer * /* buf */, void *arg) {
173 android::sp<android::MediaEvent> event = (android::MediaEvent *)arg;
174 event->mAvHandleRefCnt--;
175 event->finalize();
176}
177
shubang8ab43b12019-10-18 15:55:55 -0700178namespace android {
shubang760f0312019-11-12 17:11:28 -0800179/////////////// LnbCallback ///////////////////////
shubangd295be02020-03-27 17:08:11 -0700180LnbCallback::LnbCallback(jobject lnbObj, LnbId id) : mId(id) {
181 JNIEnv *env = AndroidRuntime::getJNIEnv();
182 mLnb = env->NewWeakGlobalRef(lnbObj);
183}
shubang760f0312019-11-12 17:11:28 -0800184
185Return<void> LnbCallback::onEvent(LnbEventType lnbEventType) {
186 ALOGD("LnbCallback::onEvent, type=%d", lnbEventType);
187 JNIEnv *env = AndroidRuntime::getJNIEnv();
188 env->CallVoidMethod(
shubangd295be02020-03-27 17:08:11 -0700189 mLnb,
shubang760f0312019-11-12 17:11:28 -0800190 gFields.onLnbEventID,
191 (jint)lnbEventType);
192 return Void();
193}
shubangd295be02020-03-27 17:08:11 -0700194Return<void> LnbCallback::onDiseqcMessage(const hidl_vec<uint8_t>& diseqcMessage) {
shubang760f0312019-11-12 17:11:28 -0800195 ALOGD("LnbCallback::onDiseqcMessage");
shubangd295be02020-03-27 17:08:11 -0700196 JNIEnv *env = AndroidRuntime::getJNIEnv();
197 jbyteArray array = env->NewByteArray(diseqcMessage.size());
198 env->SetByteArrayRegion(
199 array, 0, diseqcMessage.size(), reinterpret_cast<jbyte*>(diseqcMessage[0]));
200
201 env->CallVoidMethod(
202 mLnb,
203 gFields.onLnbDiseqcMessageID,
204 array);
shubang760f0312019-11-12 17:11:28 -0800205 return Void();
206}
207
shubang1c1144e2020-03-03 18:00:17 -0800208/////////////// Lnb ///////////////////////
209
210Lnb::Lnb(sp<ILnb> sp, jobject obj) : mLnbSp(sp) {
211 JNIEnv *env = AndroidRuntime::getJNIEnv();
212 mLnbObj = env->NewWeakGlobalRef(obj);
213}
214
215Lnb::~Lnb() {
216 JNIEnv *env = AndroidRuntime::getJNIEnv();
217 env->DeleteWeakGlobalRef(mLnbObj);
218 mLnbObj = NULL;
219}
220
221sp<ILnb> Lnb::getILnb() {
222 return mLnbSp;
223}
224
shubang4a0eddf2019-11-08 17:10:18 -0800225/////////////// DvrCallback ///////////////////////
shubang431e5612020-03-30 21:24:56 -0700226Return<void> DvrCallback::onRecordStatus(RecordStatus status) {
shubang4a0eddf2019-11-08 17:10:18 -0800227 ALOGD("DvrCallback::onRecordStatus");
shubang431e5612020-03-30 21:24:56 -0700228 JNIEnv *env = AndroidRuntime::getJNIEnv();
229 env->CallVoidMethod(
230 mDvr,
231 gFields.onDvrRecordStatusID,
232 (jint) status);
shubang4a0eddf2019-11-08 17:10:18 -0800233 return Void();
234}
235
shubang431e5612020-03-30 21:24:56 -0700236Return<void> DvrCallback::onPlaybackStatus(PlaybackStatus status) {
shubang4a0eddf2019-11-08 17:10:18 -0800237 ALOGD("DvrCallback::onPlaybackStatus");
shubang431e5612020-03-30 21:24:56 -0700238 JNIEnv *env = AndroidRuntime::getJNIEnv();
239 env->CallVoidMethod(
240 mDvr,
241 gFields.onDvrPlaybackStatusID,
242 (jint) status);
shubang4a0eddf2019-11-08 17:10:18 -0800243 return Void();
244}
245
246void DvrCallback::setDvr(const jobject dvr) {
shubangba21a7f2019-12-05 16:58:55 -0800247 ALOGD("DvrCallback::setDvr");
shubang4a0eddf2019-11-08 17:10:18 -0800248 JNIEnv *env = AndroidRuntime::getJNIEnv();
249 mDvr = env->NewWeakGlobalRef(dvr);
250}
251
shubang431e5612020-03-30 21:24:56 -0700252DvrCallback::~DvrCallback() {
253 JNIEnv *env = AndroidRuntime::getJNIEnv();
254 if (mDvr != NULL) {
255 env->DeleteWeakGlobalRef(mDvr);
256 mDvr = NULL;
257 }
shubangba21a7f2019-12-05 16:58:55 -0800258}
259
shubang431e5612020-03-30 21:24:56 -0700260/////////////// Dvr ///////////////////////
261
262Dvr::Dvr(sp<IDvr> sp, jobject obj) : mDvrSp(sp), mDvrMQEventFlag(nullptr) {
263 JNIEnv *env = AndroidRuntime::getJNIEnv();
264 mDvrObj = env->NewWeakGlobalRef(obj);
265}
266
267Dvr::~Dvr() {
268 JNIEnv *env = AndroidRuntime::getJNIEnv();
269 env->DeleteWeakGlobalRef(mDvrObj);
270 mDvrObj = NULL;
271}
272
273jint Dvr::close() {
shubangba21a7f2019-12-05 16:58:55 -0800274 Result r = mDvrSp->close();
275 if (r == Result::SUCCESS) {
276 EventFlag::deleteEventFlag(&mDvrMQEventFlag);
277 }
shubang431e5612020-03-30 21:24:56 -0700278 return (jint) r;
shubangba21a7f2019-12-05 16:58:55 -0800279}
280
shubang9e700ff2019-12-04 16:26:51 -0800281sp<IDvr> Dvr::getIDvr() {
282 return mDvrSp;
283}
284
shubang431e5612020-03-30 21:24:56 -0700285MQ& Dvr::getDvrMQ() {
shubang5f4ea352019-12-09 15:12:10 -0800286 return *mDvrMQ;
287}
288
shubang3aef4fe2020-04-01 16:51:04 -0700289/////////////// C2DataIdInfo ///////////////////////
290
291C2DataIdInfo::C2DataIdInfo(uint32_t index, uint64_t value) : C2Param(kParamSize, index) {
292 CHECK(isGlobal());
293 CHECK_EQ(C2Param::INFO, kind());
294 DummyInfo info{value};
295 memcpy(this + 1, static_cast<C2Param *>(&info) + 1, kParamSize - sizeof(C2Param));
296}
297
298/////////////// MediaEvent ///////////////////////
299
300MediaEvent::MediaEvent(sp<IFilter> iFilter, hidl_handle avHandle,
301 uint64_t dataId, uint64_t dataLength, jobject obj) : mIFilter(iFilter),
302 mDataId(dataId), mDataLength(dataLength), mBuffer(nullptr),
303 mDataIdRefCnt(0), mAvHandleRefCnt(0), mIonHandle(nullptr) {
304 JNIEnv *env = AndroidRuntime::getJNIEnv();
305 mMediaEventObj = env->NewWeakGlobalRef(obj);
306 mAvHandle = native_handle_clone(avHandle.getNativeHandle());
307}
308
309MediaEvent::~MediaEvent() {
310 JNIEnv *env = AndroidRuntime::getJNIEnv();
311 env->DeleteWeakGlobalRef(mMediaEventObj);
312 mMediaEventObj = NULL;
313 native_handle_delete(mAvHandle);
314 if (mIonHandle != NULL) {
315 delete mIonHandle;
316 }
shubangc84fe122020-06-17 11:00:11 -0700317 std::shared_ptr<C2Buffer> pC2Buffer = mC2Buffer.lock();
318 if (pC2Buffer != NULL) {
319 pC2Buffer->unregisterOnDestroyNotify(&DestroyCallback, this);
shubang3aef4fe2020-04-01 16:51:04 -0700320 }
321}
322
323void MediaEvent::finalize() {
324 if (mAvHandleRefCnt == 0) {
325 mIFilter->releaseAvHandle(hidl_handle(mAvHandle), mDataIdRefCnt == 0 ? mDataId : 0);
326 native_handle_close(mAvHandle);
327 }
328}
329
330jobject MediaEvent::getLinearBlock() {
331 ALOGD("MediaEvent::getLinearBlock");
332 if (mAvHandle == NULL) {
333 return NULL;
334 }
335 if (mLinearBlockObj != NULL) {
336 return mLinearBlockObj;
337 }
338 mIonHandle = new C2HandleIon(mAvHandle->data[0], mDataLength);
339 std::shared_ptr<C2LinearBlock> block = _C2BlockFactory::CreateLinearBlock(mIonHandle);
shubangd49681e2020-02-17 21:32:30 -0800340
341 JNIEnv *env = AndroidRuntime::getJNIEnv();
342 std::unique_ptr<JMediaCodecLinearBlock> context{new JMediaCodecLinearBlock};
343 context->mBlock = block;
shubangc84fe122020-06-17 11:00:11 -0700344 std::shared_ptr<C2Buffer> pC2Buffer = context->toC2Buffer(0, mDataLength);
345 context->mBuffer = pC2Buffer;
346 mC2Buffer = pC2Buffer;
shubang3aef4fe2020-04-01 16:51:04 -0700347 if (mAvHandle->numInts > 0) {
348 // use first int in the native_handle as the index
349 int index = mAvHandle->data[mAvHandle->numFds];
350 std::shared_ptr<C2Param> c2param = std::make_shared<C2DataIdInfo>(index, mDataId);
351 std::shared_ptr<C2Info> info(std::static_pointer_cast<C2Info>(c2param));
shubangc84fe122020-06-17 11:00:11 -0700352 pC2Buffer->setInfo(info);
shubang3aef4fe2020-04-01 16:51:04 -0700353 }
shubangc84fe122020-06-17 11:00:11 -0700354 pC2Buffer->registerOnDestroyNotify(&DestroyCallback, this);
shubangd49681e2020-02-17 21:32:30 -0800355 jobject linearBlock =
356 env->NewObject(
357 env->FindClass("android/media/MediaCodec$LinearBlock"),
358 gFields.linearBlockInitID);
359 env->CallVoidMethod(
360 linearBlock,
361 gFields.linearBlockSetInternalStateID,
362 (jlong)context.release(),
363 true);
shubang3aef4fe2020-04-01 16:51:04 -0700364 mLinearBlockObj = env->NewWeakGlobalRef(linearBlock);
365 mAvHandleRefCnt++;
366 return mLinearBlockObj;
shubangd49681e2020-02-17 21:32:30 -0800367}
368
shubang3aef4fe2020-04-01 16:51:04 -0700369uint64_t MediaEvent::getAudioHandle() {
370 mDataIdRefCnt++;
371 return mDataId;
372}
373
374/////////////// FilterCallback ///////////////////////
375
shubang3e0c37b2020-02-19 19:09:10 -0800376jobjectArray FilterCallback::getSectionEvent(
377 jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events) {
shubangd49681e2020-02-17 21:32:30 -0800378 JNIEnv *env = AndroidRuntime::getJNIEnv();
shubang3e0c37b2020-02-19 19:09:10 -0800379 jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/SectionEvent");
380 jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(IIII)V");
381
382 for (int i = 0; i < events.size(); i++) {
383 auto event = events[i];
384 DemuxFilterSectionEvent sectionEvent = event.section();
385
386 jint tableId = static_cast<jint>(sectionEvent.tableId);
387 jint version = static_cast<jint>(sectionEvent.version);
388 jint sectionNum = static_cast<jint>(sectionEvent.sectionNum);
389 jint dataLength = static_cast<jint>(sectionEvent.dataLength);
390
391 jobject obj =
392 env->NewObject(eventClazz, eventInit, tableId, version, sectionNum, dataLength);
393 env->SetObjectArrayElement(arr, i, obj);
394 }
395 return arr;
396}
397
398jobjectArray FilterCallback::getMediaEvent(
399 jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events) {
400 JNIEnv *env = AndroidRuntime::getJNIEnv();
401 jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/MediaEvent");
402 jmethodID eventInit = env->GetMethodID(eventClazz,
shubangd49681e2020-02-17 21:32:30 -0800403 "<init>",
404 "(IZJJJLandroid/media/MediaCodec$LinearBlock;"
405 "ZJIZLandroid/media/tv/tuner/filter/AudioDescriptor;)V");
shubang3aef4fe2020-04-01 16:51:04 -0700406 jfieldID eventContext = env->GetFieldID(eventClazz, "mNativeContext", "J");
shubangd49681e2020-02-17 21:32:30 -0800407
shubang3e0c37b2020-02-19 19:09:10 -0800408 for (int i = 0; i < events.size(); i++) {
409 auto event = events[i];
410 DemuxFilterMediaEvent mediaEvent = event.media();
shubangd49681e2020-02-17 21:32:30 -0800411
shubang3e0c37b2020-02-19 19:09:10 -0800412 jobject audioDescriptor = NULL;
413 if (mediaEvent.extraMetaData.getDiscriminator()
414 == DemuxFilterMediaEvent::ExtraMetaData::hidl_discriminator::audio) {
415 jclass adClazz = env->FindClass("android/media/tv/tuner/filter/AudioDescriptor");
416 jmethodID adInit = env->GetMethodID(adClazz, "<init>", "(BBCBBB)V");
417
418 AudioExtraMetaData ad = mediaEvent.extraMetaData.audio();
419 jbyte adFade = static_cast<jbyte>(ad.adFade);
420 jbyte adPan = static_cast<jbyte>(ad.adPan);
421 jchar versionTextTag = static_cast<jchar>(ad.versionTextTag);
422 jbyte adGainCenter = static_cast<jbyte>(ad.adGainCenter);
423 jbyte adGainFront = static_cast<jbyte>(ad.adGainFront);
424 jbyte adGainSurround = static_cast<jbyte>(ad.adGainSurround);
425
426 audioDescriptor =
427 env->NewObject(adClazz, adInit, adFade, adPan, versionTextTag, adGainCenter,
428 adGainFront, adGainSurround);
429 }
430
431 jlong dataLength = static_cast<jlong>(mediaEvent.dataLength);
shubang3e0c37b2020-02-19 19:09:10 -0800432
433 jint streamId = static_cast<jint>(mediaEvent.streamId);
434 jboolean isPtsPresent = static_cast<jboolean>(mediaEvent.isPtsPresent);
435 jlong pts = static_cast<jlong>(mediaEvent.pts);
436 jlong offset = static_cast<jlong>(mediaEvent.offset);
437 jboolean isSecureMemory = static_cast<jboolean>(mediaEvent.isSecureMemory);
438 jlong avDataId = static_cast<jlong>(mediaEvent.avDataId);
439 jint mpuSequenceNumber = static_cast<jint>(mediaEvent.mpuSequenceNumber);
440 jboolean isPesPrivateData = static_cast<jboolean>(mediaEvent.isPesPrivateData);
441
442 jobject obj =
443 env->NewObject(eventClazz, eventInit, streamId, isPtsPresent, pts, dataLength,
shubang3aef4fe2020-04-01 16:51:04 -0700444 offset, NULL, isSecureMemory, avDataId, mpuSequenceNumber, isPesPrivateData,
shubang3e0c37b2020-02-19 19:09:10 -0800445 audioDescriptor);
shubang3aef4fe2020-04-01 16:51:04 -0700446
447 if (mediaEvent.avMemory.getNativeHandle() != NULL || mediaEvent.avDataId != 0) {
448 sp<MediaEvent> mediaEventSp =
449 new MediaEvent(mIFilter, mediaEvent.avMemory,
450 mediaEvent.avDataId, dataLength, obj);
451 mediaEventSp->mAvHandleRefCnt++;
452 env->SetLongField(obj, eventContext, (jlong) mediaEventSp.get());
453 mediaEventSp->incStrong(obj);
454 }
455
shubang3e0c37b2020-02-19 19:09:10 -0800456 env->SetObjectArrayElement(arr, i, obj);
457 }
458 return arr;
459}
460
461jobjectArray FilterCallback::getPesEvent(
462 jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events) {
463 JNIEnv *env = AndroidRuntime::getJNIEnv();
464 jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/PesEvent");
465 jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(III)V");
466
467 for (int i = 0; i < events.size(); i++) {
468 auto event = events[i];
469 DemuxFilterPesEvent pesEvent = event.pes();
470
471 jint streamId = static_cast<jint>(pesEvent.streamId);
472 jint dataLength = static_cast<jint>(pesEvent.dataLength);
473 jint mpuSequenceNumber = static_cast<jint>(pesEvent.mpuSequenceNumber);
474
475 jobject obj =
476 env->NewObject(eventClazz, eventInit, streamId, dataLength, mpuSequenceNumber);
477 env->SetObjectArrayElement(arr, i, obj);
478 }
479 return arr;
480}
481
482jobjectArray FilterCallback::getTsRecordEvent(
483 jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events) {
484 JNIEnv *env = AndroidRuntime::getJNIEnv();
485 jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/TsRecordEvent");
486 jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(IIIJ)V");
487
488 for (int i = 0; i < events.size(); i++) {
489 auto event = events[i];
490 DemuxFilterTsRecordEvent tsRecordEvent = event.tsRecord();
491 DemuxPid pid = tsRecordEvent.pid;
492
493 jint jpid = static_cast<jint>(Constant::INVALID_TS_PID);
494
495 if (pid.getDiscriminator() == DemuxPid::hidl_discriminator::tPid) {
496 jpid = static_cast<jint>(pid.tPid());
497 } else if (pid.getDiscriminator() == DemuxPid::hidl_discriminator::mmtpPid) {
498 jpid = static_cast<jint>(pid.mmtpPid());
499 }
500
501 jint sc = 0;
502
503 if (tsRecordEvent.scIndexMask.getDiscriminator()
504 == DemuxFilterTsRecordEvent::ScIndexMask::hidl_discriminator::sc) {
505 sc = static_cast<jint>(tsRecordEvent.scIndexMask.sc());
506 } else if (tsRecordEvent.scIndexMask.getDiscriminator()
507 == DemuxFilterTsRecordEvent::ScIndexMask::hidl_discriminator::scHevc) {
508 sc = static_cast<jint>(tsRecordEvent.scIndexMask.scHevc());
509 }
510
511 jint ts = static_cast<jint>(tsRecordEvent.tsIndexMask);
512
513 jlong byteNumber = static_cast<jlong>(tsRecordEvent.byteNumber);
514
515 jobject obj =
516 env->NewObject(eventClazz, eventInit, jpid, ts, sc, byteNumber);
517 env->SetObjectArrayElement(arr, i, obj);
518 }
519 return arr;
520}
521
522jobjectArray FilterCallback::getMmtpRecordEvent(
523 jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events) {
524 JNIEnv *env = AndroidRuntime::getJNIEnv();
525 jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/MmtpRecordEvent");
526 jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(IJ)V");
527
528 for (int i = 0; i < events.size(); i++) {
529 auto event = events[i];
530 DemuxFilterMmtpRecordEvent mmtpRecordEvent = event.mmtpRecord();
531
532 jint scHevcIndexMask = static_cast<jint>(mmtpRecordEvent.scHevcIndexMask);
533 jlong byteNumber = static_cast<jlong>(mmtpRecordEvent.byteNumber);
534
535 jobject obj =
536 env->NewObject(eventClazz, eventInit, scHevcIndexMask, byteNumber);
537 env->SetObjectArrayElement(arr, i, obj);
538 }
539 return arr;
540}
541
542jobjectArray FilterCallback::getDownloadEvent(
543 jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events) {
544 JNIEnv *env = AndroidRuntime::getJNIEnv();
545 jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/DownloadEvent");
546 jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(IIIII)V");
547
548 for (int i = 0; i < events.size(); i++) {
549 auto event = events[i];
550 DemuxFilterDownloadEvent downloadEvent = event.download();
551
552 jint itemId = static_cast<jint>(downloadEvent.itemId);
553 jint mpuSequenceNumber = static_cast<jint>(downloadEvent.mpuSequenceNumber);
554 jint itemFragmentIndex = static_cast<jint>(downloadEvent.itemFragmentIndex);
555 jint lastItemFragmentIndex = static_cast<jint>(downloadEvent.lastItemFragmentIndex);
556 jint dataLength = static_cast<jint>(downloadEvent.dataLength);
557
558 jobject obj =
559 env->NewObject(eventClazz, eventInit, itemId, mpuSequenceNumber, itemFragmentIndex,
560 lastItemFragmentIndex, dataLength);
561 env->SetObjectArrayElement(arr, i, obj);
562 }
563 return arr;
564}
565
566jobjectArray FilterCallback::getIpPayloadEvent(
567 jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events) {
568 JNIEnv *env = AndroidRuntime::getJNIEnv();
569 jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/IpPayloadEvent");
570 jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(I)V");
571
572 for (int i = 0; i < events.size(); i++) {
573 auto event = events[i];
574 DemuxFilterIpPayloadEvent ipPayloadEvent = event.ipPayload();
575 jint dataLength = static_cast<jint>(ipPayloadEvent.dataLength);
576 jobject obj = env->NewObject(eventClazz, eventInit, dataLength);
577 env->SetObjectArrayElement(arr, i, obj);
578 }
579 return arr;
580}
581
582jobjectArray FilterCallback::getTemiEvent(
583 jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events) {
584 JNIEnv *env = AndroidRuntime::getJNIEnv();
585 jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/TemiEvent");
586 jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(JB[B)V");
587
588 for (int i = 0; i < events.size(); i++) {
589 auto event = events[i];
590 DemuxFilterTemiEvent temiEvent = event.temi();
591 jlong pts = static_cast<jlong>(temiEvent.pts);
592 jbyte descrTag = static_cast<jbyte>(temiEvent.descrTag);
593 std::vector<uint8_t> descrData = temiEvent.descrData;
594
595 jbyteArray array = env->NewByteArray(descrData.size());
596 env->SetByteArrayRegion(
597 array, 0, descrData.size(), reinterpret_cast<jbyte*>(&descrData[0]));
598
599 jobject obj = env->NewObject(eventClazz, eventInit, pts, descrTag, array);
600 env->SetObjectArrayElement(arr, i, obj);
601 }
602 return arr;
shubangd49681e2020-02-17 21:32:30 -0800603}
604
605Return<void> FilterCallback::onFilterEvent(const DemuxFilterEvent& filterEvent) {
shubang6f473d62019-11-01 15:42:21 -0700606 ALOGD("FilterCallback::onFilterEvent");
shubangd49681e2020-02-17 21:32:30 -0800607
608 JNIEnv *env = AndroidRuntime::getJNIEnv();
shubangd49681e2020-02-17 21:32:30 -0800609
610 std::vector<DemuxFilterEvent::Event> events = filterEvent.events;
611 jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/FilterEvent");
612 jobjectArray array = env->NewObjectArray(events.size(), eventClazz, NULL);
613
shubang3e0c37b2020-02-19 19:09:10 -0800614 if (!events.empty()) {
615 auto event = events[0];
616 switch (event.getDiscriminator()) {
617 case DemuxFilterEvent::Event::hidl_discriminator::media: {
618 array = getMediaEvent(array, events);
619 break;
620 }
621 case DemuxFilterEvent::Event::hidl_discriminator::section: {
622 array = getSectionEvent(array, events);
623 break;
624 }
625 case DemuxFilterEvent::Event::hidl_discriminator::pes: {
626 array = getPesEvent(array, events);
627 break;
628 }
629 case DemuxFilterEvent::Event::hidl_discriminator::tsRecord: {
630 array = getTsRecordEvent(array, events);
631 break;
632 }
633 case DemuxFilterEvent::Event::hidl_discriminator::mmtpRecord: {
634 array = getMmtpRecordEvent(array, events);
635 break;
636 }
637 case DemuxFilterEvent::Event::hidl_discriminator::download: {
638 array = getDownloadEvent(array, events);
639 break;
640 }
641 case DemuxFilterEvent::Event::hidl_discriminator::ipPayload: {
642 array = getIpPayloadEvent(array, events);
643 break;
644 }
645 case DemuxFilterEvent::Event::hidl_discriminator::temi: {
646 array = getTemiEvent(array, events);
647 break;
648 }
649 default: {
650 break;
651 }
shubangd49681e2020-02-17 21:32:30 -0800652 }
653 }
654 env->CallVoidMethod(
655 mFilter,
shubang3e0c37b2020-02-19 19:09:10 -0800656 gFields.onFilterEventID,
shubangd49681e2020-02-17 21:32:30 -0800657 array);
shubang6f473d62019-11-01 15:42:21 -0700658 return Void();
659}
shubangcdf30de2019-11-06 17:28:38 -0800660
shubang3e0c37b2020-02-19 19:09:10 -0800661
shubangcdf30de2019-11-06 17:28:38 -0800662Return<void> FilterCallback::onFilterStatus(const DemuxFilterStatus status) {
663 ALOGD("FilterCallback::onFilterStatus");
664 JNIEnv *env = AndroidRuntime::getJNIEnv();
665 env->CallVoidMethod(
666 mFilter,
667 gFields.onFilterStatusID,
668 (jint)status);
shubang6f473d62019-11-01 15:42:21 -0700669 return Void();
670}
shubang8ab43b12019-10-18 15:55:55 -0700671
shubang3aef4fe2020-04-01 16:51:04 -0700672void FilterCallback::setFilter(const sp<Filter> filter) {
shubangcdf30de2019-11-06 17:28:38 -0800673 ALOGD("FilterCallback::setFilter");
shubang3aef4fe2020-04-01 16:51:04 -0700674 mFilter = filter->mFilterObj;
675 mIFilter = filter->mFilterSp;
shubangcdf30de2019-11-06 17:28:38 -0800676}
677
shubang431e5612020-03-30 21:24:56 -0700678FilterCallback::~FilterCallback() {
679 JNIEnv *env = AndroidRuntime::getJNIEnv();
680 if (mFilter != NULL) {
681 env->DeleteWeakGlobalRef(mFilter);
682 mFilter = NULL;
683 }
684}
685
shubang7648a3c2019-11-25 18:16:45 -0800686/////////////// Filter ///////////////////////
687
shubang3e0c37b2020-02-19 19:09:10 -0800688Filter::Filter(sp<IFilter> sp, jobject obj) : mFilterSp(sp) {
689 JNIEnv *env = AndroidRuntime::getJNIEnv();
690 mFilterObj = env->NewWeakGlobalRef(obj);
691}
shubang7648a3c2019-11-25 18:16:45 -0800692
shubang964e6132019-11-26 15:05:22 -0800693Filter::~Filter() {
shubang3e0c37b2020-02-19 19:09:10 -0800694 JNIEnv *env = AndroidRuntime::getJNIEnv();
695
696 env->DeleteWeakGlobalRef(mFilterObj);
697 mFilterObj = NULL;
shubang964e6132019-11-26 15:05:22 -0800698 EventFlag::deleteEventFlag(&mFilterMQEventFlag);
699}
700
701int Filter::close() {
702 Result r = mFilterSp->close();
703 if (r == Result::SUCCESS) {
704 EventFlag::deleteEventFlag(&mFilterMQEventFlag);
705 }
706 return (int)r;
707}
708
shubang7648a3c2019-11-25 18:16:45 -0800709sp<IFilter> Filter::getIFilter() {
710 return mFilterSp;
711}
712
shubangf657da22020-02-05 16:27:06 -0800713/////////////// TimeFilter ///////////////////////
714
715TimeFilter::TimeFilter(sp<ITimeFilter> sp, jobject obj) : mTimeFilterSp(sp) {
716 JNIEnv *env = AndroidRuntime::getJNIEnv();
717 mTimeFilterObj = env->NewWeakGlobalRef(obj);
718}
719
720TimeFilter::~TimeFilter() {
721 ALOGD("~TimeFilter");
722 JNIEnv *env = AndroidRuntime::getJNIEnv();
723
724 env->DeleteWeakGlobalRef(mTimeFilterObj);
725 mTimeFilterObj = NULL;
726}
727
728sp<ITimeFilter> TimeFilter::getITimeFilter() {
729 return mTimeFilterSp;
730}
731
shubang4b8c5402019-10-24 17:49:53 -0700732/////////////// FrontendCallback ///////////////////////
733
734FrontendCallback::FrontendCallback(jweak tunerObj, FrontendId id) : mObject(tunerObj), mId(id) {}
735
736Return<void> FrontendCallback::onEvent(FrontendEventType frontendEventType) {
737 ALOGD("FrontendCallback::onEvent, type=%d", frontendEventType);
738 JNIEnv *env = AndroidRuntime::getJNIEnv();
739 env->CallVoidMethod(
740 mObject,
741 gFields.onFrontendEventID,
742 (jint)frontendEventType);
743 return Void();
744}
shubang4b8c5402019-10-24 17:49:53 -0700745
shubangc8736b72020-02-11 18:27:53 -0800746Return<void> FrontendCallback::onScanMessage(FrontendScanMessageType type, const FrontendScanMessage& message) {
shubang4b8c5402019-10-24 17:49:53 -0700747 ALOGD("FrontendCallback::onScanMessage, type=%d", type);
shubangc8736b72020-02-11 18:27:53 -0800748 JNIEnv *env = AndroidRuntime::getJNIEnv();
749 jclass clazz = env->FindClass("android/media/tv/tuner/Tuner");
750 switch(type) {
751 case FrontendScanMessageType::LOCKED: {
752 if (message.isLocked()) {
753 env->CallVoidMethod(
754 mObject,
755 env->GetMethodID(clazz, "onLocked", "()V"));
756 }
757 break;
758 }
759 case FrontendScanMessageType::END: {
760 if (message.isEnd()) {
761 env->CallVoidMethod(
762 mObject,
763 env->GetMethodID(clazz, "onScanStopped", "()V"));
764 }
765 break;
766 }
767 case FrontendScanMessageType::PROGRESS_PERCENT: {
768 env->CallVoidMethod(
769 mObject,
770 env->GetMethodID(clazz, "onProgress", "(I)V"),
771 (jint) message.progressPercent());
772 break;
773 }
774 case FrontendScanMessageType::FREQUENCY: {
775 std::vector<uint32_t> v = message.frequencies();
776 jintArray freqs = env->NewIntArray(v.size());
777 env->SetIntArrayRegion(freqs, 0, v.size(), reinterpret_cast<jint*>(&v[0]));
778
779 env->CallVoidMethod(
780 mObject,
781 env->GetMethodID(clazz, "onFrequenciesReport", "([I)V"),
782 freqs);
783 break;
784 }
785 case FrontendScanMessageType::SYMBOL_RATE: {
786 std::vector<uint32_t> v = message.symbolRates();
787 jintArray symbolRates = env->NewIntArray(v.size());
788 env->SetIntArrayRegion(symbolRates, 0, v.size(), reinterpret_cast<jint*>(&v[0]));
789
790 env->CallVoidMethod(
791 mObject,
792 env->GetMethodID(clazz, "onSymbolRates", "([I)V"),
793 symbolRates);
794 break;
795 }
796 case FrontendScanMessageType::HIERARCHY: {
797 env->CallVoidMethod(
798 mObject,
799 env->GetMethodID(clazz, "onHierarchy", "(I)V"),
800 (jint) message.hierarchy());
801 break;
802 }
803 case FrontendScanMessageType::ANALOG_TYPE: {
804 env->CallVoidMethod(
805 mObject,
806 env->GetMethodID(clazz, "onSignalType", "(I)V"),
807 (jint) message.analogType());
808 break;
809 }
810 case FrontendScanMessageType::PLP_IDS: {
811 std::vector<uint8_t> v = message.plpIds();
812 std::vector<jint> jintV(v.begin(), v.end());
813 jintArray plpIds = env->NewIntArray(v.size());
814 env->SetIntArrayRegion(plpIds, 0, jintV.size(), &jintV[0]);
815
816 env->CallVoidMethod(
817 mObject,
818 env->GetMethodID(clazz, "onPlpIds", "([I)V"),
819 plpIds);
820 break;
821 }
822 case FrontendScanMessageType::GROUP_IDS: {
823 std::vector<uint8_t> v = message.groupIds();
824 std::vector<jint> jintV(v.begin(), v.end());
825 jintArray groupIds = env->NewIntArray(v.size());
826 env->SetIntArrayRegion(groupIds, 0, jintV.size(), &jintV[0]);
827
828 env->CallVoidMethod(
829 mObject,
830 env->GetMethodID(clazz, "onGroupIds", "([I)V"),
831 groupIds);
832 break;
833 }
834 case FrontendScanMessageType::INPUT_STREAM_IDS: {
835 std::vector<uint16_t> v = message.inputStreamIds();
836 std::vector<jint> jintV(v.begin(), v.end());
837 jintArray streamIds = env->NewIntArray(v.size());
838 env->SetIntArrayRegion(streamIds, 0, jintV.size(), &jintV[0]);
839
840 env->CallVoidMethod(
841 mObject,
842 env->GetMethodID(clazz, "onInputStreamIds", "([I)V"),
843 streamIds);
844 break;
845 }
846 case FrontendScanMessageType::STANDARD: {
847 FrontendScanMessage::Standard std = message.std();
848 jint standard;
849 if (std.getDiscriminator() == FrontendScanMessage::Standard::hidl_discriminator::sStd) {
850 standard = (jint) std.sStd();
851 env->CallVoidMethod(
852 mObject,
853 env->GetMethodID(clazz, "onDvbsStandard", "(I)V"),
854 standard);
855 } else if (std.getDiscriminator() == FrontendScanMessage::Standard::hidl_discriminator::tStd) {
856 standard = (jint) std.tStd();
857 env->CallVoidMethod(
858 mObject,
859 env->GetMethodID(clazz, "onDvbtStandard", "(I)V"),
860 standard);
861 } else if (std.getDiscriminator() == FrontendScanMessage::Standard::hidl_discriminator::sifStd) {
862 standard = (jint) std.sifStd();
863 env->CallVoidMethod(
864 mObject,
865 env->GetMethodID(clazz, "onAnalogSifStandard", "(I)V"),
866 standard);
867 }
868 break;
869 }
870 case FrontendScanMessageType::ATSC3_PLP_INFO: {
871 jclass plpClazz = env->FindClass("android/media/tv/tuner/frontend/Atsc3PlpInfo");
872 jmethodID init = env->GetMethodID(plpClazz, "<init>", "(IZ)V");
873 std::vector<FrontendScanAtsc3PlpInfo> plpInfos = message.atsc3PlpInfos();
874 jobjectArray array = env->NewObjectArray(plpInfos.size(), plpClazz, NULL);
875
876 for (int i = 0; i < plpInfos.size(); i++) {
877 auto info = plpInfos[i];
878 jint plpId = (jint) info.plpId;
879 jboolean lls = (jboolean) info.bLlsFlag;
880
881 jobject obj = env->NewObject(plpClazz, init, plpId, lls);
882 env->SetObjectArrayElement(array, i, obj);
883 }
884 env->CallVoidMethod(
885 mObject,
886 env->GetMethodID(clazz, "onAtsc3PlpInfos", "([Landroid/media/tv/tuner/frontend/Atsc3PlpInfo;)V"),
887 array);
888 break;
889 }
890 }
shubang4b8c5402019-10-24 17:49:53 -0700891 return Void();
892}
893
shubang6f473d62019-11-01 15:42:21 -0700894/////////////// Tuner ///////////////////////
shubang4b8c5402019-10-24 17:49:53 -0700895
shubang8ab43b12019-10-18 15:55:55 -0700896sp<ITuner> JTuner::mTuner;
897
898JTuner::JTuner(JNIEnv *env, jobject thiz)
899 : mClass(NULL) {
900 jclass clazz = env->GetObjectClass(thiz);
901 CHECK(clazz != NULL);
902
903 mClass = (jclass)env->NewGlobalRef(clazz);
904 mObject = env->NewWeakGlobalRef(thiz);
905 if (mTuner == NULL) {
906 mTuner = getTunerService();
907 }
908}
909
910JTuner::~JTuner() {
shubang2f9cab32020-04-10 18:00:56 -0700911 if (mFe != NULL) {
912 mFe->close();
913 }
914 if (mDemux != NULL) {
915 mDemux->close();
916 }
shubang8ab43b12019-10-18 15:55:55 -0700917 JNIEnv *env = AndroidRuntime::getJNIEnv();
918
shubang431e5612020-03-30 21:24:56 -0700919 env->DeleteWeakGlobalRef(mObject);
shubang8ab43b12019-10-18 15:55:55 -0700920 env->DeleteGlobalRef(mClass);
921 mTuner = NULL;
922 mClass = NULL;
923 mObject = NULL;
924}
925
926sp<ITuner> JTuner::getTunerService() {
927 if (mTuner == nullptr) {
928 mTuner = ITuner::getService();
929
930 if (mTuner == nullptr) {
931 ALOGW("Failed to get tuner service.");
932 }
933 }
934 return mTuner;
935}
936
shubang7e849b02019-10-18 19:36:25 -0700937jobject JTuner::getFrontendIds() {
938 ALOGD("JTuner::getFrontendIds()");
shubang7e849b02019-10-18 19:36:25 -0700939 mTuner->getFrontendIds([&](Result, const hidl_vec<FrontendId>& frontendIds) {
shubang4b8c5402019-10-24 17:49:53 -0700940 mFeIds = frontendIds;
shubang7e849b02019-10-18 19:36:25 -0700941 });
shubang4b8c5402019-10-24 17:49:53 -0700942 if (mFeIds.size() == 0) {
shubang7e849b02019-10-18 19:36:25 -0700943 ALOGW("Frontend isn't available");
944 return NULL;
945 }
946
947 JNIEnv *env = AndroidRuntime::getJNIEnv();
948 jclass arrayListClazz = env->FindClass("java/util/ArrayList");
949 jmethodID arrayListAdd = env->GetMethodID(arrayListClazz, "add", "(Ljava/lang/Object;)Z");
950 jobject obj = env->NewObject(arrayListClazz, env->GetMethodID(arrayListClazz, "<init>", "()V"));
951
952 jclass integerClazz = env->FindClass("java/lang/Integer");
953 jmethodID intInit = env->GetMethodID(integerClazz, "<init>", "(I)V");
954
shubang4b8c5402019-10-24 17:49:53 -0700955 for (int i=0; i < mFeIds.size(); i++) {
956 jobject idObj = env->NewObject(integerClazz, intInit, mFeIds[i]);
shubang7e849b02019-10-18 19:36:25 -0700957 env->CallBooleanMethod(obj, arrayListAdd, idObj);
958 }
959 return obj;
960}
961
962jobject JTuner::openFrontendById(int id) {
shubang4b8c5402019-10-24 17:49:53 -0700963 sp<IFrontend> fe;
shubang66cc3aa2020-04-06 17:10:01 -0700964 Result res;
965 mTuner->openFrontendById(id, [&](Result r, const sp<IFrontend>& frontend) {
shubang4b8c5402019-10-24 17:49:53 -0700966 fe = frontend;
shubang66cc3aa2020-04-06 17:10:01 -0700967 res = r;
shubang7e849b02019-10-18 19:36:25 -0700968 });
shubang66cc3aa2020-04-06 17:10:01 -0700969 if (res != Result::SUCCESS || fe == nullptr) {
shubang7e849b02019-10-18 19:36:25 -0700970 ALOGE("Failed to open frontend");
971 return NULL;
972 }
shubang4b8c5402019-10-24 17:49:53 -0700973 mFe = fe;
shubangd295be02020-03-27 17:08:11 -0700974 mFeId = id;
975 if (mDemux != NULL) {
976 mDemux->setFrontendDataSource(mFeId);
977 }
shubang4b8c5402019-10-24 17:49:53 -0700978 sp<FrontendCallback> feCb = new FrontendCallback(mObject, id);
979 fe->setCallback(feCb);
shubang7e849b02019-10-18 19:36:25 -0700980
981 jint jId = (jint) id;
shubang964e6132019-11-26 15:05:22 -0800982
shubang7e849b02019-10-18 19:36:25 -0700983 JNIEnv *env = AndroidRuntime::getJNIEnv();
984 // TODO: add more fields to frontend
985 return env->NewObject(
986 env->FindClass("android/media/tv/tuner/Tuner$Frontend"),
987 gFields.frontendInitID,
shubang4b8c5402019-10-24 17:49:53 -0700988 mObject,
shubang7e849b02019-10-18 19:36:25 -0700989 (jint) jId);
990}
991
shubang2f9cab32020-04-10 18:00:56 -0700992jint JTuner::closeFrontendById(int id) {
993 if (mFe != NULL && mFeId == id) {
994 Result r = mFe->close();
995 return (jint) r;
996 }
997 return (jint) Result::SUCCESS;
998}
999
shubang66cc3aa2020-04-06 17:10:01 -07001000jobject JTuner::getAnalogFrontendCaps(JNIEnv *env, FrontendInfo::FrontendCapabilities& caps) {
shubang51cc62f2020-01-28 18:00:22 -08001001 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/AnalogFrontendCapabilities");
1002 jmethodID capsInit = env->GetMethodID(clazz, "<init>", "(II)V");
1003
1004 jint typeCap = caps.analogCaps().typeCap;
1005 jint sifStandardCap = caps.analogCaps().sifStandardCap;
1006 return env->NewObject(clazz, capsInit, typeCap, sifStandardCap);
1007}
1008
shubang66cc3aa2020-04-06 17:10:01 -07001009jobject JTuner::getAtsc3FrontendCaps(JNIEnv *env, FrontendInfo::FrontendCapabilities& caps) {
shubang51cc62f2020-01-28 18:00:22 -08001010 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/Atsc3FrontendCapabilities");
1011 jmethodID capsInit = env->GetMethodID(clazz, "<init>", "(IIIIII)V");
1012
1013 jint bandwidthCap = caps.atsc3Caps().bandwidthCap;
1014 jint modulationCap = caps.atsc3Caps().modulationCap;
1015 jint timeInterleaveModeCap = caps.atsc3Caps().timeInterleaveModeCap;
1016 jint codeRateCap = caps.atsc3Caps().codeRateCap;
1017 jint fecCap = caps.atsc3Caps().fecCap;
1018 jint demodOutputFormatCap = caps.atsc3Caps().demodOutputFormatCap;
1019
1020 return env->NewObject(clazz, capsInit, bandwidthCap, modulationCap, timeInterleaveModeCap,
1021 codeRateCap, fecCap, demodOutputFormatCap);
1022}
1023
shubang66cc3aa2020-04-06 17:10:01 -07001024jobject JTuner::getAtscFrontendCaps(JNIEnv *env, FrontendInfo::FrontendCapabilities& caps) {
shubang51cc62f2020-01-28 18:00:22 -08001025 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/AtscFrontendCapabilities");
1026 jmethodID capsInit = env->GetMethodID(clazz, "<init>", "(I)V");
1027
1028 jint modulationCap = caps.atscCaps().modulationCap;
1029
1030 return env->NewObject(clazz, capsInit, modulationCap);
1031}
1032
shubang66cc3aa2020-04-06 17:10:01 -07001033jobject JTuner::getDvbcFrontendCaps(JNIEnv *env, FrontendInfo::FrontendCapabilities& caps) {
shubang51cc62f2020-01-28 18:00:22 -08001034 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/DvbcFrontendCapabilities");
1035 jmethodID capsInit = env->GetMethodID(clazz, "<init>", "(III)V");
1036
1037 jint modulationCap = caps.dvbcCaps().modulationCap;
1038 jint fecCap = caps.dvbcCaps().fecCap;
1039 jint annexCap = caps.dvbcCaps().annexCap;
1040
1041 return env->NewObject(clazz, capsInit, modulationCap, fecCap, annexCap);
1042}
1043
shubang66cc3aa2020-04-06 17:10:01 -07001044jobject JTuner::getDvbsFrontendCaps(JNIEnv *env, FrontendInfo::FrontendCapabilities& caps) {
shubang51cc62f2020-01-28 18:00:22 -08001045 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/DvbsFrontendCapabilities");
1046 jmethodID capsInit = env->GetMethodID(clazz, "<init>", "(IJI)V");
1047
1048 jint modulationCap = caps.dvbsCaps().modulationCap;
1049 jlong innerfecCap = caps.dvbsCaps().innerfecCap;
1050 jint standard = caps.dvbsCaps().standard;
1051
1052 return env->NewObject(clazz, capsInit, modulationCap, innerfecCap, standard);
1053}
1054
shubang66cc3aa2020-04-06 17:10:01 -07001055jobject JTuner::getDvbtFrontendCaps(JNIEnv *env, FrontendInfo::FrontendCapabilities& caps) {
shubang51cc62f2020-01-28 18:00:22 -08001056 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/DvbtFrontendCapabilities");
1057 jmethodID capsInit = env->GetMethodID(clazz, "<init>", "(IIIIIIZZ)V");
1058
1059 jint transmissionModeCap = caps.dvbtCaps().transmissionModeCap;
1060 jint bandwidthCap = caps.dvbtCaps().bandwidthCap;
1061 jint constellationCap = caps.dvbtCaps().constellationCap;
1062 jint coderateCap = caps.dvbtCaps().coderateCap;
1063 jint hierarchyCap = caps.dvbtCaps().hierarchyCap;
1064 jint guardIntervalCap = caps.dvbtCaps().guardIntervalCap;
1065 jboolean isT2Supported = caps.dvbtCaps().isT2Supported;
1066 jboolean isMisoSupported = caps.dvbtCaps().isMisoSupported;
1067
1068 return env->NewObject(clazz, capsInit, transmissionModeCap, bandwidthCap, constellationCap,
1069 coderateCap, hierarchyCap, guardIntervalCap, isT2Supported, isMisoSupported);
1070}
1071
shubang66cc3aa2020-04-06 17:10:01 -07001072jobject JTuner::getIsdbs3FrontendCaps(JNIEnv *env, FrontendInfo::FrontendCapabilities& caps) {
shubang51cc62f2020-01-28 18:00:22 -08001073 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/Isdbs3FrontendCapabilities");
1074 jmethodID capsInit = env->GetMethodID(clazz, "<init>", "(II)V");
1075
1076 jint modulationCap = caps.isdbs3Caps().modulationCap;
1077 jint coderateCap = caps.isdbs3Caps().coderateCap;
1078
1079 return env->NewObject(clazz, capsInit, modulationCap, coderateCap);
1080}
1081
shubang66cc3aa2020-04-06 17:10:01 -07001082jobject JTuner::getIsdbsFrontendCaps(JNIEnv *env, FrontendInfo::FrontendCapabilities& caps) {
shubang51cc62f2020-01-28 18:00:22 -08001083 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/IsdbsFrontendCapabilities");
1084 jmethodID capsInit = env->GetMethodID(clazz, "<init>", "(II)V");
1085
1086 jint modulationCap = caps.isdbsCaps().modulationCap;
1087 jint coderateCap = caps.isdbsCaps().coderateCap;
1088
1089 return env->NewObject(clazz, capsInit, modulationCap, coderateCap);
1090}
1091
shubang66cc3aa2020-04-06 17:10:01 -07001092jobject JTuner::getIsdbtFrontendCaps(JNIEnv *env, FrontendInfo::FrontendCapabilities& caps) {
shubang51cc62f2020-01-28 18:00:22 -08001093 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/IsdbtFrontendCapabilities");
1094 jmethodID capsInit = env->GetMethodID(clazz, "<init>", "(IIIII)V");
1095
1096 jint modeCap = caps.isdbtCaps().modeCap;
1097 jint bandwidthCap = caps.isdbtCaps().bandwidthCap;
1098 jint modulationCap = caps.isdbtCaps().modulationCap;
1099 jint coderateCap = caps.isdbtCaps().coderateCap;
1100 jint guardIntervalCap = caps.isdbtCaps().guardIntervalCap;
1101
1102 return env->NewObject(clazz, capsInit, modeCap, bandwidthCap, modulationCap, coderateCap,
1103 guardIntervalCap);
1104}
1105
1106jobject JTuner::getFrontendInfo(int id) {
1107 FrontendInfo feInfo;
1108 Result res;
1109 mTuner->getFrontendInfo(id, [&](Result r, const FrontendInfo& info) {
1110 feInfo = info;
1111 res = r;
1112 });
1113 if (res != Result::SUCCESS) {
1114 return NULL;
1115 }
1116
1117 JNIEnv *env = AndroidRuntime::getJNIEnv();
1118 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/FrontendInfo");
1119 jmethodID infoInit = env->GetMethodID(clazz, "<init>",
1120 "(IIIIIIII[ILandroid/media/tv/tuner/frontend/FrontendCapabilities;)V");
1121
1122 jint type = (jint) feInfo.type;
1123 jint minFrequency = feInfo.minFrequency;
1124 jint maxFrequency = feInfo.maxFrequency;
1125 jint minSymbolRate = feInfo.minSymbolRate;
1126 jint maxSymbolRate = feInfo.maxSymbolRate;
1127 jint acquireRange = feInfo.acquireRange;
1128 jint exclusiveGroupId = feInfo.exclusiveGroupId;
1129 jintArray statusCaps = env->NewIntArray(feInfo.statusCaps.size());
1130 env->SetIntArrayRegion(
1131 statusCaps, 0, feInfo.statusCaps.size(),
1132 reinterpret_cast<jint*>(&feInfo.statusCaps[0]));
1133 FrontendInfo::FrontendCapabilities caps = feInfo.frontendCaps;
1134
1135 jobject jcaps = NULL;
1136 switch(feInfo.type) {
1137 case FrontendType::ANALOG:
shubang66cc3aa2020-04-06 17:10:01 -07001138 if (FrontendInfo::FrontendCapabilities::hidl_discriminator::analogCaps
1139 == caps.getDiscriminator()) {
1140 jcaps = getAnalogFrontendCaps(env, caps);
1141 }
shubang51cc62f2020-01-28 18:00:22 -08001142 break;
1143 case FrontendType::ATSC3:
shubang66cc3aa2020-04-06 17:10:01 -07001144 if (FrontendInfo::FrontendCapabilities::hidl_discriminator::atsc3Caps
1145 == caps.getDiscriminator()) {
1146 jcaps = getAtsc3FrontendCaps(env, caps);
1147 }
shubang51cc62f2020-01-28 18:00:22 -08001148 break;
1149 case FrontendType::ATSC:
shubang66cc3aa2020-04-06 17:10:01 -07001150 if (FrontendInfo::FrontendCapabilities::hidl_discriminator::atscCaps
1151 == caps.getDiscriminator()) {
1152 jcaps = getAtscFrontendCaps(env, caps);
1153 }
shubang51cc62f2020-01-28 18:00:22 -08001154 break;
1155 case FrontendType::DVBC:
shubang66cc3aa2020-04-06 17:10:01 -07001156 if (FrontendInfo::FrontendCapabilities::hidl_discriminator::dvbcCaps
1157 == caps.getDiscriminator()) {
1158 jcaps = getDvbcFrontendCaps(env, caps);
1159 }
shubang51cc62f2020-01-28 18:00:22 -08001160 break;
1161 case FrontendType::DVBS:
shubang66cc3aa2020-04-06 17:10:01 -07001162 if (FrontendInfo::FrontendCapabilities::hidl_discriminator::dvbsCaps
1163 == caps.getDiscriminator()) {
1164 jcaps = getDvbsFrontendCaps(env, caps);
1165 }
shubang51cc62f2020-01-28 18:00:22 -08001166 break;
1167 case FrontendType::DVBT:
shubang66cc3aa2020-04-06 17:10:01 -07001168 if (FrontendInfo::FrontendCapabilities::hidl_discriminator::dvbtCaps
1169 == caps.getDiscriminator()) {
1170 jcaps = getDvbtFrontendCaps(env, caps);
1171 }
shubang51cc62f2020-01-28 18:00:22 -08001172 break;
1173 case FrontendType::ISDBS:
shubang66cc3aa2020-04-06 17:10:01 -07001174 if (FrontendInfo::FrontendCapabilities::hidl_discriminator::isdbsCaps
1175 == caps.getDiscriminator()) {
1176 jcaps = getIsdbsFrontendCaps(env, caps);
1177 }
shubang51cc62f2020-01-28 18:00:22 -08001178 break;
1179 case FrontendType::ISDBS3:
shubang66cc3aa2020-04-06 17:10:01 -07001180 if (FrontendInfo::FrontendCapabilities::hidl_discriminator::isdbs3Caps
1181 == caps.getDiscriminator()) {
1182 jcaps = getIsdbs3FrontendCaps(env, caps);
1183 }
shubang51cc62f2020-01-28 18:00:22 -08001184 break;
1185 case FrontendType::ISDBT:
shubang66cc3aa2020-04-06 17:10:01 -07001186 if (FrontendInfo::FrontendCapabilities::hidl_discriminator::isdbtCaps
1187 == caps.getDiscriminator()) {
1188 jcaps = getIsdbtFrontendCaps(env, caps);
1189 }
shubang51cc62f2020-01-28 18:00:22 -08001190 break;
1191 default:
1192 break;
1193 }
1194
1195 return env->NewObject(
1196 clazz, infoInit, (jint) id, type, minFrequency, maxFrequency, minSymbolRate,
1197 maxSymbolRate, acquireRange, exclusiveGroupId, statusCaps, jcaps);
1198}
1199
shubang0dc83942020-04-02 17:19:31 -07001200jintArray JTuner::getLnbIds() {
shubang760f0312019-11-12 17:11:28 -08001201 ALOGD("JTuner::getLnbIds()");
shubang0dc83942020-04-02 17:19:31 -07001202 Result res;
1203 hidl_vec<LnbId> lnbIds;
1204 mTuner->getLnbIds([&](Result r, const hidl_vec<LnbId>& ids) {
1205 lnbIds = ids;
1206 res = r;
shubang760f0312019-11-12 17:11:28 -08001207 });
shubangb3bfffe2020-03-26 17:44:31 -07001208 if (res != Result::SUCCESS || lnbIds.size() == 0) {
shubang760f0312019-11-12 17:11:28 -08001209 ALOGW("Lnb isn't available");
1210 return NULL;
1211 }
1212
shubang0dc83942020-04-02 17:19:31 -07001213 mLnbIds = lnbIds;
shubang760f0312019-11-12 17:11:28 -08001214 JNIEnv *env = AndroidRuntime::getJNIEnv();
shubang760f0312019-11-12 17:11:28 -08001215
shubang0dc83942020-04-02 17:19:31 -07001216 jintArray ids = env->NewIntArray(mLnbIds.size());
1217 env->SetIntArrayRegion(ids, 0, mLnbIds.size(), reinterpret_cast<jint*>(&mLnbIds[0]));
shubang760f0312019-11-12 17:11:28 -08001218
shubang0dc83942020-04-02 17:19:31 -07001219 return ids;
shubang760f0312019-11-12 17:11:28 -08001220}
1221
1222jobject JTuner::openLnbById(int id) {
shubang1c1144e2020-03-03 18:00:17 -08001223 sp<ILnb> iLnbSp;
shubangd295be02020-03-27 17:08:11 -07001224 Result r;
1225 mTuner->openLnbById(id, [&](Result res, const sp<ILnb>& lnb) {
1226 r = res;
shubang1c1144e2020-03-03 18:00:17 -08001227 iLnbSp = lnb;
shubang760f0312019-11-12 17:11:28 -08001228 });
shubangd295be02020-03-27 17:08:11 -07001229 if (r != Result::SUCCESS || iLnbSp == nullptr) {
shubang760f0312019-11-12 17:11:28 -08001230 ALOGE("Failed to open lnb");
1231 return NULL;
1232 }
shubang1c1144e2020-03-03 18:00:17 -08001233 mLnb = iLnbSp;
shubang760f0312019-11-12 17:11:28 -08001234
1235 JNIEnv *env = AndroidRuntime::getJNIEnv();
shubang1c1144e2020-03-03 18:00:17 -08001236 jobject lnbObj = env->NewObject(
shubangd351b822020-01-22 17:29:18 -08001237 env->FindClass("android/media/tv/tuner/Lnb"),
shubang760f0312019-11-12 17:11:28 -08001238 gFields.lnbInitID,
shubang1c1144e2020-03-03 18:00:17 -08001239 (jint) id);
1240
shubangd295be02020-03-27 17:08:11 -07001241 sp<LnbCallback> lnbCb = new LnbCallback(lnbObj, id);
1242 mLnb->setCallback(lnbCb);
1243
shubang1c1144e2020-03-03 18:00:17 -08001244 sp<Lnb> lnbSp = new Lnb(iLnbSp, lnbObj);
1245 lnbSp->incStrong(lnbObj);
1246 env->SetLongField(lnbObj, gFields.lnbContext, (jlong) lnbSp.get());
1247
1248 return lnbObj;
shubang760f0312019-11-12 17:11:28 -08001249}
1250
shubang757602f2020-03-06 15:23:41 -08001251jobject JTuner::openLnbByName(jstring name) {
1252 JNIEnv *env = AndroidRuntime::getJNIEnv();
1253 std::string lnbName(env->GetStringUTFChars(name, nullptr));
1254 sp<ILnb> iLnbSp;
1255 Result res;
1256 LnbId id;
1257 mTuner->openLnbByName(lnbName, [&](Result r, LnbId lnbId, const sp<ILnb>& lnb) {
1258 res = r;
1259 iLnbSp = lnb;
1260 id = lnbId;
1261 });
1262 if (res != Result::SUCCESS || iLnbSp == nullptr) {
1263 ALOGE("Failed to open lnb");
1264 return NULL;
1265 }
1266 mLnb = iLnbSp;
shubang757602f2020-03-06 15:23:41 -08001267
1268 jobject lnbObj = env->NewObject(
1269 env->FindClass("android/media/tv/tuner/Lnb"),
1270 gFields.lnbInitID,
1271 id);
1272
shubangd295be02020-03-27 17:08:11 -07001273 sp<LnbCallback> lnbCb = new LnbCallback(lnbObj, id);
1274 mLnb->setCallback(lnbCb);
1275
shubang757602f2020-03-06 15:23:41 -08001276 sp<Lnb> lnbSp = new Lnb(iLnbSp, lnbObj);
1277 lnbSp->incStrong(lnbObj);
1278 env->SetLongField(lnbObj, gFields.lnbContext, (jlong) lnbSp.get());
1279
1280 return lnbObj;
1281}
1282
shubang74bfd482019-10-29 19:10:22 -07001283int JTuner::tune(const FrontendSettings& settings) {
1284 if (mFe == NULL) {
1285 ALOGE("frontend is not initialized");
1286 return (int)Result::INVALID_STATE;
1287 }
1288 Result result = mFe->tune(settings);
1289 return (int)result;
1290}
1291
shubange32fb412020-01-28 14:53:05 -08001292int JTuner::stopTune() {
1293 if (mFe == NULL) {
1294 ALOGE("frontend is not initialized");
1295 return (int)Result::INVALID_STATE;
1296 }
1297 Result result = mFe->stopTune();
1298 return (int)result;
1299}
1300
shubangd5b845f2019-12-11 15:29:09 -08001301int JTuner::scan(const FrontendSettings& settings, FrontendScanType scanType) {
1302 if (mFe == NULL) {
1303 ALOGE("frontend is not initialized");
1304 return (int)Result::INVALID_STATE;
1305 }
1306 Result result = mFe->scan(settings, scanType);
1307 return (int)result;
1308}
1309
shubange32fb412020-01-28 14:53:05 -08001310int JTuner::stopScan() {
1311 if (mFe == NULL) {
1312 ALOGE("frontend is not initialized");
1313 return (int)Result::INVALID_STATE;
1314 }
1315 Result result = mFe->stopScan();
1316 return (int)result;
1317}
1318
1319int JTuner::setLnb(int id) {
1320 if (mFe == NULL) {
1321 ALOGE("frontend is not initialized");
1322 return (int)Result::INVALID_STATE;
1323 }
1324 Result result = mFe->setLnb(id);
1325 return (int)result;
1326}
1327
1328int JTuner::setLna(bool enable) {
1329 if (mFe == NULL) {
1330 ALOGE("frontend is not initialized");
1331 return (int)Result::INVALID_STATE;
1332 }
1333 Result result = mFe->setLna(enable);
1334 return (int)result;
1335}
1336
shubangbee73462020-02-07 17:48:02 -08001337Result JTuner::openDemux() {
shubang6f473d62019-11-01 15:42:21 -07001338 if (mTuner == nullptr) {
shubangbee73462020-02-07 17:48:02 -08001339 return Result::NOT_INITIALIZED;
shubang6f473d62019-11-01 15:42:21 -07001340 }
1341 if (mDemux != nullptr) {
shubangbee73462020-02-07 17:48:02 -08001342 return Result::SUCCESS;
shubang6f473d62019-11-01 15:42:21 -07001343 }
shubangbee73462020-02-07 17:48:02 -08001344 Result res;
shubangd295be02020-03-27 17:08:11 -07001345 uint32_t id;
1346 sp<IDemux> demuxSp;
shubangbee73462020-02-07 17:48:02 -08001347 mTuner->openDemux([&](Result r, uint32_t demuxId, const sp<IDemux>& demux) {
shubangd295be02020-03-27 17:08:11 -07001348 demuxSp = demux;
1349 id = demuxId;
shubangbee73462020-02-07 17:48:02 -08001350 res = r;
shubang6f473d62019-11-01 15:42:21 -07001351 ALOGD("open demux, id = %d", demuxId);
1352 });
shubangd295be02020-03-27 17:08:11 -07001353 if (res == Result::SUCCESS) {
1354 mDemux = demuxSp;
1355 mDemuxId = id;
1356 if (mFe != NULL) {
1357 mDemux->setFrontendDataSource(mFeId);
1358 }
1359 }
shubangbee73462020-02-07 17:48:02 -08001360 return res;
1361}
1362
shubang2f9cab32020-04-10 18:00:56 -07001363jint JTuner::close() {
1364 Result res = Result::SUCCESS;
1365 if (mFe != NULL) {
1366 res = mFe->close();
1367 if (res != Result::SUCCESS) {
1368 return (jint) res;
1369 }
1370 }
1371 if (mDemux != NULL) {
1372 res = mDemux->close();
1373 if (res != Result::SUCCESS) {
1374 return (jint) res;
1375 }
1376 }
1377 return (jint) res;
1378}
1379
shubangbee73462020-02-07 17:48:02 -08001380jobject JTuner::getAvSyncHwId(sp<Filter> filter) {
1381 if (mDemux == NULL) {
1382 return NULL;
shubang6f473d62019-11-01 15:42:21 -07001383 }
shubangbee73462020-02-07 17:48:02 -08001384
1385 uint32_t avSyncHwId;
1386 Result res;
1387 sp<IFilter> iFilterSp = filter->getIFilter();
1388 mDemux->getAvSyncHwId(iFilterSp,
1389 [&](Result r, uint32_t id) {
1390 res = r;
1391 avSyncHwId = id;
1392 });
1393 if (res == Result::SUCCESS) {
1394 JNIEnv *env = AndroidRuntime::getJNIEnv();
1395 jclass integerClazz = env->FindClass("java/lang/Integer");
1396 jmethodID intInit = env->GetMethodID(integerClazz, "<init>", "(I)V");
1397 return env->NewObject(integerClazz, intInit, avSyncHwId);
1398 }
1399 return NULL;
1400}
1401
1402jobject JTuner::getAvSyncTime(jint id) {
1403 if (mDemux == NULL) {
1404 return NULL;
1405 }
1406 uint64_t time;
1407 Result res;
1408 mDemux->getAvSyncTime(static_cast<uint32_t>(id),
1409 [&](Result r, uint64_t ts) {
1410 res = r;
1411 time = ts;
1412 });
1413 if (res == Result::SUCCESS) {
1414 JNIEnv *env = AndroidRuntime::getJNIEnv();
1415 jclass longClazz = env->FindClass("java/lang/Long");
1416 jmethodID longInit = env->GetMethodID(longClazz, "<init>", "(J)V");
1417 return env->NewObject(longClazz, longInit, static_cast<jlong>(time));
1418 }
1419 return NULL;
1420}
1421
1422int JTuner::connectCiCam(jint id) {
1423 if (mDemux == NULL) {
1424 Result r = openDemux();
1425 if (r != Result::SUCCESS) {
1426 return (int) r;
1427 }
1428 }
1429 Result r = mDemux->connectCiCam(static_cast<uint32_t>(id));
1430 return (int) r;
1431}
1432
1433int JTuner::disconnectCiCam() {
1434 if (mDemux == NULL) {
1435 Result r = openDemux();
1436 if (r != Result::SUCCESS) {
1437 return (int) r;
1438 }
1439 }
1440 Result r = mDemux->disconnectCiCam();
1441 return (int) r;
shubang6f473d62019-11-01 15:42:21 -07001442}
1443
shubang13f15e02019-11-04 17:51:02 -08001444jobject JTuner::openDescrambler() {
1445 ALOGD("JTuner::openDescrambler");
shubang40454db2020-03-30 16:52:29 -07001446 if (mTuner == nullptr || mDemux == nullptr) {
shubang13f15e02019-11-04 17:51:02 -08001447 return NULL;
1448 }
1449 sp<IDescrambler> descramblerSp;
shubang40454db2020-03-30 16:52:29 -07001450 Result res;
1451 mTuner->openDescrambler([&](Result r, const sp<IDescrambler>& descrambler) {
1452 res = r;
shubang13f15e02019-11-04 17:51:02 -08001453 descramblerSp = descrambler;
1454 });
1455
shubang40454db2020-03-30 16:52:29 -07001456 if (res != Result::SUCCESS || descramblerSp == NULL) {
shubang13f15e02019-11-04 17:51:02 -08001457 return NULL;
1458 }
1459
shubang40454db2020-03-30 16:52:29 -07001460 descramblerSp->setDemuxSource(mDemuxId);
1461
shubang13f15e02019-11-04 17:51:02 -08001462 JNIEnv *env = AndroidRuntime::getJNIEnv();
1463 jobject descramblerObj =
1464 env->NewObject(
shubangd351b822020-01-22 17:29:18 -08001465 env->FindClass("android/media/tv/tuner/Descrambler"),
shubang40454db2020-03-30 16:52:29 -07001466 gFields.descramblerInitID);
shubang13f15e02019-11-04 17:51:02 -08001467
1468 descramblerSp->incStrong(descramblerObj);
1469 env->SetLongField(descramblerObj, gFields.descramblerContext, (jlong)descramblerSp.get());
1470
1471 return descramblerObj;
1472}
1473
shubang6f473d62019-11-01 15:42:21 -07001474jobject JTuner::openFilter(DemuxFilterType type, int bufferSize) {
1475 if (mDemux == NULL) {
shubangbee73462020-02-07 17:48:02 -08001476 if (openDemux() != Result::SUCCESS) {
shubang6f473d62019-11-01 15:42:21 -07001477 return NULL;
1478 }
1479 }
1480
shubang7648a3c2019-11-25 18:16:45 -08001481 sp<IFilter> iFilterSp;
shubangcdf30de2019-11-06 17:28:38 -08001482 sp<FilterCallback> callback = new FilterCallback();
shubang40454db2020-03-30 16:52:29 -07001483 Result res;
shubangcdf30de2019-11-06 17:28:38 -08001484 mDemux->openFilter(type, bufferSize, callback,
shubang40454db2020-03-30 16:52:29 -07001485 [&](Result r, const sp<IFilter>& filter) {
shubang7648a3c2019-11-25 18:16:45 -08001486 iFilterSp = filter;
shubang40454db2020-03-30 16:52:29 -07001487 res = r;
shubang6f473d62019-11-01 15:42:21 -07001488 });
shubang40454db2020-03-30 16:52:29 -07001489 if (res != Result::SUCCESS || iFilterSp == NULL) {
shubang6f473d62019-11-01 15:42:21 -07001490 ALOGD("Failed to open filter, type = %d", type.mainType);
1491 return NULL;
1492 }
1493 int fId;
shubang7648a3c2019-11-25 18:16:45 -08001494 iFilterSp->getId([&](Result, uint32_t filterId) {
shubang6f473d62019-11-01 15:42:21 -07001495 fId = filterId;
1496 });
shubang6f473d62019-11-01 15:42:21 -07001497
1498 JNIEnv *env = AndroidRuntime::getJNIEnv();
shubangcdf30de2019-11-06 17:28:38 -08001499 jobject filterObj =
1500 env->NewObject(
shubangd351b822020-01-22 17:29:18 -08001501 env->FindClass("android/media/tv/tuner/filter/Filter"),
shubangcdf30de2019-11-06 17:28:38 -08001502 gFields.filterInitID,
shubangcdf30de2019-11-06 17:28:38 -08001503 (jint) fId);
1504
shubang7648a3c2019-11-25 18:16:45 -08001505 sp<Filter> filterSp = new Filter(iFilterSp, filterObj);
shubangcdf30de2019-11-06 17:28:38 -08001506 filterSp->incStrong(filterObj);
1507 env->SetLongField(filterObj, gFields.filterContext, (jlong)filterSp.get());
1508
shubang3aef4fe2020-04-01 16:51:04 -07001509 callback->setFilter(filterSp);
shubangcdf30de2019-11-06 17:28:38 -08001510
1511 return filterObj;
shubang6f473d62019-11-01 15:42:21 -07001512}
1513
shubangf657da22020-02-05 16:27:06 -08001514jobject JTuner::openTimeFilter() {
1515 if (mDemux == NULL) {
shubangbee73462020-02-07 17:48:02 -08001516 if (openDemux() != Result::SUCCESS) {
shubangf657da22020-02-05 16:27:06 -08001517 return NULL;
1518 }
1519 }
1520 sp<ITimeFilter> iTimeFilterSp;
1521 Result res;
1522 mDemux->openTimeFilter(
1523 [&](Result r, const sp<ITimeFilter>& filter) {
1524 iTimeFilterSp = filter;
1525 res = r;
1526 });
1527
1528 if (res != Result::SUCCESS || iTimeFilterSp == NULL) {
1529 return NULL;
1530 }
1531
1532 JNIEnv *env = AndroidRuntime::getJNIEnv();
1533 jobject timeFilterObj =
1534 env->NewObject(
1535 env->FindClass("android/media/tv/tuner/filter/TimeFilter"),
1536 gFields.timeFilterInitID);
1537 sp<TimeFilter> timeFilterSp = new TimeFilter(iTimeFilterSp, timeFilterObj);
1538 timeFilterSp->incStrong(timeFilterObj);
1539 env->SetLongField(timeFilterObj, gFields.timeFilterContext, (jlong)timeFilterSp.get());
1540
1541 return timeFilterObj;
1542}
1543
shubang5637a662020-02-27 18:06:21 -08001544jobject JTuner::openDvr(DvrType type, jlong bufferSize) {
shubang4a0eddf2019-11-08 17:10:18 -08001545 ALOGD("JTuner::openDvr");
1546 if (mDemux == NULL) {
shubangbee73462020-02-07 17:48:02 -08001547 if (openDemux() != Result::SUCCESS) {
shubang4a0eddf2019-11-08 17:10:18 -08001548 return NULL;
1549 }
1550 }
shubang9e700ff2019-12-04 16:26:51 -08001551 sp<IDvr> iDvrSp;
shubang4a0eddf2019-11-08 17:10:18 -08001552 sp<DvrCallback> callback = new DvrCallback();
shubang5637a662020-02-27 18:06:21 -08001553 Result res;
1554 mDemux->openDvr(type, (uint32_t) bufferSize, callback,
1555 [&](Result r, const sp<IDvr>& dvr) {
1556 res = r;
shubang9e700ff2019-12-04 16:26:51 -08001557 iDvrSp = dvr;
shubang4a0eddf2019-11-08 17:10:18 -08001558 });
1559
shubang5637a662020-02-27 18:06:21 -08001560 if (res != Result::SUCCESS || iDvrSp == NULL) {
shubang4a0eddf2019-11-08 17:10:18 -08001561 return NULL;
1562 }
1563
1564 JNIEnv *env = AndroidRuntime::getJNIEnv();
shubang5637a662020-02-27 18:06:21 -08001565 jobject dvrObj;
1566 if (type == DvrType::RECORD) {
1567 dvrObj =
1568 env->NewObject(
1569 env->FindClass("android/media/tv/tuner/dvr/DvrRecorder"),
1570 gFields.dvrRecorderInitID,
1571 mObject);
1572 sp<Dvr> dvrSp = new Dvr(iDvrSp, dvrObj);
1573 dvrSp->incStrong(dvrObj);
1574 env->SetLongField(dvrObj, gFields.dvrRecorderContext, (jlong)dvrSp.get());
1575 } else {
1576 dvrObj =
1577 env->NewObject(
1578 env->FindClass("android/media/tv/tuner/dvr/DvrPlayback"),
1579 gFields.dvrPlaybackInitID,
1580 mObject);
1581 sp<Dvr> dvrSp = new Dvr(iDvrSp, dvrObj);
1582 dvrSp->incStrong(dvrObj);
1583 env->SetLongField(dvrObj, gFields.dvrPlaybackContext, (jlong)dvrSp.get());
1584 }
shubang4a0eddf2019-11-08 17:10:18 -08001585
1586 callback->setDvr(dvrObj);
1587
1588 return dvrObj;
1589}
1590
shubangc4b45702020-03-23 18:48:12 -07001591jobject JTuner::getDemuxCaps() {
1592 DemuxCapabilities caps;
1593 Result res;
1594 mTuner->getDemuxCaps([&](Result r, const DemuxCapabilities& demuxCaps) {
1595 caps = demuxCaps;
1596 res = r;
1597 });
1598 if (res != Result::SUCCESS) {
1599 return NULL;
1600 }
1601 JNIEnv *env = AndroidRuntime::getJNIEnv();
1602 jclass clazz = env->FindClass("android/media/tv/tuner/DemuxCapabilities");
1603 jmethodID capsInit = env->GetMethodID(clazz, "<init>", "(IIIIIIIIIJI[IZ)V");
1604
1605 jint numDemux = caps.numDemux;
1606 jint numRecord = caps.numRecord;
1607 jint numPlayback = caps.numPlayback;
1608 jint numTsFilter = caps.numTsFilter;
1609 jint numSectionFilter = caps.numSectionFilter;
1610 jint numAudioFilter = caps.numAudioFilter;
1611 jint numVideoFilter = caps.numVideoFilter;
1612 jint numPesFilter = caps.numPesFilter;
1613 jint numPcrFilter = caps.numPcrFilter;
1614 jlong numBytesInSectionFilter = caps.numBytesInSectionFilter;
1615 jint filterCaps = static_cast<jint>(caps.filterCaps);
1616 jboolean bTimeFilter = caps.bTimeFilter;
1617
1618 jintArray linkCaps = env->NewIntArray(caps.linkCaps.size());
1619 env->SetIntArrayRegion(
1620 linkCaps, 0, caps.linkCaps.size(), reinterpret_cast<jint*>(&caps.linkCaps[0]));
1621
1622 return env->NewObject(clazz, capsInit, numDemux, numRecord, numPlayback, numTsFilter,
1623 numSectionFilter, numAudioFilter, numVideoFilter, numPesFilter, numPcrFilter,
1624 numBytesInSectionFilter, filterCaps, linkCaps, bTimeFilter);
1625}
1626
shubangb83f8232020-03-24 18:04:35 -07001627jobject JTuner::getFrontendStatus(jintArray types) {
1628 if (mFe == NULL) {
1629 return NULL;
1630 }
1631 JNIEnv *env = AndroidRuntime::getJNIEnv();
1632 jsize size = env->GetArrayLength(types);
1633 std::vector<FrontendStatusType> v(size);
1634 env->GetIntArrayRegion(types, 0, size, reinterpret_cast<jint*>(&v[0]));
1635
1636 Result res;
1637 hidl_vec<FrontendStatus> status;
1638 mFe->getStatus(v,
1639 [&](Result r, const hidl_vec<FrontendStatus>& s) {
1640 res = r;
1641 status = s;
1642 });
1643 if (res != Result::SUCCESS) {
1644 return NULL;
1645 }
1646
1647 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/FrontendStatus");
1648 jmethodID init = env->GetMethodID(clazz, "<init>", "()V");
1649 jobject statusObj = env->NewObject(clazz, init);
1650
1651 jclass intClazz = env->FindClass("java/lang/Integer");
1652 jmethodID initInt = env->GetMethodID(intClazz, "<init>", "(I)V");
1653 jclass booleanClazz = env->FindClass("java/lang/Boolean");
1654 jmethodID initBoolean = env->GetMethodID(booleanClazz, "<init>", "(Z)V");
1655
1656 for (auto s : status) {
1657 switch(s.getDiscriminator()) {
1658 case FrontendStatus::hidl_discriminator::isDemodLocked: {
1659 jfieldID field = env->GetFieldID(clazz, "mIsDemodLocked", "Ljava/lang/Boolean;");
1660 jobject newBooleanObj = env->NewObject(
1661 booleanClazz, initBoolean, static_cast<jboolean>(s.isDemodLocked()));
1662 env->SetObjectField(statusObj, field, newBooleanObj);
1663 break;
1664 }
1665 case FrontendStatus::hidl_discriminator::snr: {
1666 jfieldID field = env->GetFieldID(clazz, "mSnr", "Ljava/lang/Integer;");
1667 jobject newIntegerObj = env->NewObject(
1668 intClazz, initInt, static_cast<jint>(s.snr()));
1669 env->SetObjectField(statusObj, field, newIntegerObj);
1670 break;
1671 }
1672 case FrontendStatus::hidl_discriminator::ber: {
1673 jfieldID field = env->GetFieldID(clazz, "mBer", "Ljava/lang/Integer;");
1674 jobject newIntegerObj = env->NewObject(
1675 intClazz, initInt, static_cast<jint>(s.ber()));
1676 env->SetObjectField(statusObj, field, newIntegerObj);
1677 break;
1678 }
1679 case FrontendStatus::hidl_discriminator::per: {
1680 jfieldID field = env->GetFieldID(clazz, "mPer", "Ljava/lang/Integer;");
1681 jobject newIntegerObj = env->NewObject(
1682 intClazz, initInt, static_cast<jint>(s.per()));
1683 env->SetObjectField(statusObj, field, newIntegerObj);
1684 break;
1685 }
1686 case FrontendStatus::hidl_discriminator::preBer: {
1687 jfieldID field = env->GetFieldID(clazz, "mPerBer", "Ljava/lang/Integer;");
1688 jobject newIntegerObj = env->NewObject(
1689 intClazz, initInt, static_cast<jint>(s.preBer()));
1690 env->SetObjectField(statusObj, field, newIntegerObj);
1691 break;
1692 }
1693 case FrontendStatus::hidl_discriminator::signalQuality: {
1694 jfieldID field = env->GetFieldID(clazz, "mSignalQuality", "Ljava/lang/Integer;");
1695 jobject newIntegerObj = env->NewObject(
1696 intClazz, initInt, static_cast<jint>(s.signalQuality()));
1697 env->SetObjectField(statusObj, field, newIntegerObj);
1698 break;
1699 }
1700 case FrontendStatus::hidl_discriminator::signalStrength: {
1701 jfieldID field = env->GetFieldID(clazz, "mSignalStrength", "Ljava/lang/Integer;");
1702 jobject newIntegerObj = env->NewObject(
1703 intClazz, initInt, static_cast<jint>(s.signalStrength()));
1704 env->SetObjectField(statusObj, field, newIntegerObj);
1705 break;
1706 }
1707 case FrontendStatus::hidl_discriminator::symbolRate: {
1708 jfieldID field = env->GetFieldID(clazz, "mSymbolRate", "Ljava/lang/Integer;");
1709 jobject newIntegerObj = env->NewObject(
1710 intClazz, initInt, static_cast<jint>(s.symbolRate()));
1711 env->SetObjectField(statusObj, field, newIntegerObj);
1712 break;
1713 }
1714 case FrontendStatus::hidl_discriminator::innerFec: {
1715 jfieldID field = env->GetFieldID(clazz, "mInnerFec", "Ljava/lang/Long;");
1716 jclass longClazz = env->FindClass("java/lang/Long");
1717 jmethodID initLong = env->GetMethodID(longClazz, "<init>", "(J)V");
1718 jobject newLongObj = env->NewObject(
1719 longClazz, initLong, static_cast<jlong>(s.innerFec()));
1720 env->SetObjectField(statusObj, field, newLongObj);
1721 break;
1722 }
1723 case FrontendStatus::hidl_discriminator::modulation: {
1724 jfieldID field = env->GetFieldID(clazz, "mModulation", "Ljava/lang/Integer;");
1725 FrontendModulationStatus modulation = s.modulation();
1726 jint intModulation;
1727 bool valid = true;
1728 switch(modulation.getDiscriminator()) {
1729 case FrontendModulationStatus::hidl_discriminator::dvbc: {
1730 intModulation = static_cast<jint>(modulation.dvbc());
1731 break;
1732 }
1733 case FrontendModulationStatus::hidl_discriminator::dvbs: {
1734 intModulation = static_cast<jint>(modulation.dvbs());
1735 break;
1736 }
1737 case FrontendModulationStatus::hidl_discriminator::isdbs: {
1738 intModulation = static_cast<jint>(modulation.isdbs());
1739 break;
1740 }
1741 case FrontendModulationStatus::hidl_discriminator::isdbs3: {
1742 intModulation = static_cast<jint>(modulation.isdbs3());
1743 break;
1744 }
1745 case FrontendModulationStatus::hidl_discriminator::isdbt: {
1746 intModulation = static_cast<jint>(modulation.isdbt());
1747 break;
1748 }
1749 default: {
1750 valid = false;
1751 break;
1752 }
1753 }
1754 if (valid) {
1755 jobject newIntegerObj = env->NewObject(intClazz, initInt, intModulation);
1756 env->SetObjectField(statusObj, field, newIntegerObj);
1757 }
1758 break;
1759 }
1760 case FrontendStatus::hidl_discriminator::inversion: {
1761 jfieldID field = env->GetFieldID(clazz, "mInversion", "Ljava/lang/Integer;");
1762 jobject newIntegerObj = env->NewObject(
1763 intClazz, initInt, static_cast<jint>(s.inversion()));
1764 env->SetObjectField(statusObj, field, newIntegerObj);
1765 break;
1766 }
1767 case FrontendStatus::hidl_discriminator::lnbVoltage: {
1768 jfieldID field = env->GetFieldID(clazz, "mLnbVoltage", "Ljava/lang/Integer;");
1769 jobject newIntegerObj = env->NewObject(
1770 intClazz, initInt, static_cast<jint>(s.lnbVoltage()));
1771 env->SetObjectField(statusObj, field, newIntegerObj);
1772 break;
1773 }
1774 case FrontendStatus::hidl_discriminator::plpId: {
1775 jfieldID field = env->GetFieldID(clazz, "mPlpId", "Ljava/lang/Integer;");
1776 jobject newIntegerObj = env->NewObject(
1777 intClazz, initInt, static_cast<jint>(s.plpId()));
1778 env->SetObjectField(statusObj, field, newIntegerObj);
1779 break;
1780 }
1781 case FrontendStatus::hidl_discriminator::isEWBS: {
1782 jfieldID field = env->GetFieldID(clazz, "mIsEwbs", "Ljava/lang/Boolean;");
1783 jobject newBooleanObj = env->NewObject(
1784 booleanClazz, initBoolean, static_cast<jboolean>(s.isEWBS()));
1785 env->SetObjectField(statusObj, field, newBooleanObj);
1786 break;
1787 }
1788 case FrontendStatus::hidl_discriminator::agc: {
1789 jfieldID field = env->GetFieldID(clazz, "mAgc", "Ljava/lang/Integer;");
1790 jobject newIntegerObj = env->NewObject(
1791 intClazz, initInt, static_cast<jint>(s.agc()));
1792 env->SetObjectField(statusObj, field, newIntegerObj);
1793 break;
1794 }
1795 case FrontendStatus::hidl_discriminator::isLnaOn: {
1796 jfieldID field = env->GetFieldID(clazz, "mIsLnaOn", "Ljava/lang/Boolean;");
1797 jobject newBooleanObj = env->NewObject(
1798 booleanClazz, initBoolean, static_cast<jboolean>(s.isLnaOn()));
1799 env->SetObjectField(statusObj, field, newBooleanObj);
1800 break;
1801 }
1802 case FrontendStatus::hidl_discriminator::isLayerError: {
1803 jfieldID field = env->GetFieldID(clazz, "mIsLayerErrors", "[Z");
1804 hidl_vec<bool> layerErr = s.isLayerError();
1805
1806 jbooleanArray valObj = env->NewBooleanArray(layerErr.size());
1807
1808 for (size_t i = 0; i < layerErr.size(); i++) {
1809 jboolean x = layerErr[i];
1810 env->SetBooleanArrayRegion(valObj, i, 1, &x);
1811 }
1812 env->SetObjectField(statusObj, field, valObj);
1813 break;
1814 }
1815 case FrontendStatus::hidl_discriminator::mer: {
1816 jfieldID field = env->GetFieldID(clazz, "mMer", "Ljava/lang/Integer;");
1817 jobject newIntegerObj = env->NewObject(
1818 intClazz, initInt, static_cast<jint>(s.mer()));
1819 env->SetObjectField(statusObj, field, newIntegerObj);
1820 break;
1821 }
1822 case FrontendStatus::hidl_discriminator::freqOffset: {
1823 jfieldID field = env->GetFieldID(clazz, "mFreqOffset", "Ljava/lang/Integer;");
1824 jobject newIntegerObj = env->NewObject(
1825 intClazz, initInt, static_cast<jint>(s.freqOffset()));
1826 env->SetObjectField(statusObj, field, newIntegerObj);
1827 break;
1828 }
1829 case FrontendStatus::hidl_discriminator::hierarchy: {
1830 jfieldID field = env->GetFieldID(clazz, "mHierarchy", "Ljava/lang/Integer;");
1831 jobject newIntegerObj = env->NewObject(
1832 intClazz, initInt, static_cast<jint>(s.hierarchy()));
1833 env->SetObjectField(statusObj, field, newIntegerObj);
1834 break;
1835 }
1836 case FrontendStatus::hidl_discriminator::isRfLocked: {
1837 jfieldID field = env->GetFieldID(clazz, "mIsRfLocked", "Ljava/lang/Boolean;");
1838 jobject newBooleanObj = env->NewObject(
1839 booleanClazz, initBoolean, static_cast<jboolean>(s.isRfLocked()));
1840 env->SetObjectField(statusObj, field, newBooleanObj);
1841 break;
1842 }
1843 case FrontendStatus::hidl_discriminator::plpInfo: {
1844 jfieldID field = env->GetFieldID(clazz, "mPlpInfo",
1845 "[Landroid/media/tv/tuner/frontend/FrontendStatus$Atsc3PlpTuningInfo;");
1846 jclass plpClazz = env->FindClass(
1847 "android/media/tv/tuner/frontend/FrontendStatus$Atsc3PlpTuningInfo");
1848 jmethodID initPlp = env->GetMethodID(plpClazz, "<init>", "(IZI)V");
1849
1850 hidl_vec<FrontendStatusAtsc3PlpInfo> plpInfos = s.plpInfo();
1851
1852 jobjectArray valObj = env->NewObjectArray(plpInfos.size(), plpClazz, NULL);
1853 for (int i = 0; i < plpInfos.size(); i++) {
1854 auto info = plpInfos[i];
1855 jint plpId = (jint) info.plpId;
1856 jboolean isLocked = (jboolean) info.isLocked;
1857 jint uec = (jint) info.uec;
1858
1859 jobject plpObj = env->NewObject(plpClazz, initPlp, plpId, isLocked, uec);
1860 env->SetObjectArrayElement(valObj, i, plpObj);
1861 }
1862
1863 env->SetObjectField(statusObj, field, valObj);
1864 break;
1865 }
1866 default: {
1867 break;
1868 }
1869 }
1870 }
1871
1872 return statusObj;
1873}
1874
shubangb3bfffe2020-03-26 17:44:31 -07001875jint JTuner::closeFrontend() {
1876 Result r = Result::SUCCESS;
1877 if (mFe != NULL) {
1878 r = mFe->close();
1879 }
1880 return (jint) r;
1881}
1882
1883jint JTuner::closeDemux() {
1884 Result r = Result::SUCCESS;
1885 if (mDemux != NULL) {
1886 r = mDemux->close();
1887 }
1888 return (jint) r;
1889}
1890
shubang8ab43b12019-10-18 15:55:55 -07001891} // namespace android
1892
1893////////////////////////////////////////////////////////////////////////////////
1894
1895using namespace android;
1896
1897static sp<JTuner> setTuner(JNIEnv *env, jobject thiz, const sp<JTuner> &tuner) {
shubang13f15e02019-11-04 17:51:02 -08001898 sp<JTuner> old = (JTuner *)env->GetLongField(thiz, gFields.tunerContext);
shubang8ab43b12019-10-18 15:55:55 -07001899
1900 if (tuner != NULL) {
1901 tuner->incStrong(thiz);
1902 }
1903 if (old != NULL) {
1904 old->decStrong(thiz);
1905 }
shubang13f15e02019-11-04 17:51:02 -08001906 env->SetLongField(thiz, gFields.tunerContext, (jlong)tuner.get());
shubang8ab43b12019-10-18 15:55:55 -07001907
1908 return old;
1909}
1910
1911static sp<JTuner> getTuner(JNIEnv *env, jobject thiz) {
shubang13f15e02019-11-04 17:51:02 -08001912 return (JTuner *)env->GetLongField(thiz, gFields.tunerContext);
1913}
1914
1915static sp<IDescrambler> getDescrambler(JNIEnv *env, jobject descrambler) {
1916 return (IDescrambler *)env->GetLongField(descrambler, gFields.descramblerContext);
1917}
1918
shubangc18cc102020-03-12 16:28:45 -07001919static uint32_t getResourceIdFromHandle(jint handle) {
1920 return (handle & 0x00ff0000) >> 16;
1921}
1922
shubang13f15e02019-11-04 17:51:02 -08001923static DemuxPid getDemuxPid(int pidType, int pid) {
1924 DemuxPid demuxPid;
1925 if ((int)pidType == 1) {
1926 demuxPid.tPid(static_cast<DemuxTpid>(pid));
1927 } else if ((int)pidType == 2) {
1928 demuxPid.mmtpPid(static_cast<DemuxMmtpPid>(pid));
1929 }
1930 return demuxPid;
shubang8ab43b12019-10-18 15:55:55 -07001931}
1932
shubangdeb067c2020-01-27 13:21:55 -08001933static uint32_t getFrontendSettingsFreq(JNIEnv *env, const jobject& settings) {
shubangd351b822020-01-22 17:29:18 -08001934 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/FrontendSettings");
shubang964e6132019-11-26 15:05:22 -08001935 jfieldID freqField = env->GetFieldID(clazz, "mFrequency", "I");
shubangdeb067c2020-01-27 13:21:55 -08001936 uint32_t freq = static_cast<uint32_t>(env->GetIntField(settings, freqField));
1937 return freq;
1938}
shubang74bfd482019-10-29 19:10:22 -07001939
shubangdeb067c2020-01-27 13:21:55 -08001940static FrontendSettings getAnalogFrontendSettings(JNIEnv *env, const jobject& settings) {
1941 FrontendSettings frontendSettings;
1942 uint32_t freq = getFrontendSettingsFreq(env, settings);
1943 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/AnalogFrontendSettings");
1944 FrontendAnalogType analogType =
1945 static_cast<FrontendAnalogType>(
1946 env->GetIntField(settings, env->GetFieldID(clazz, "mSignalType", "I")));
1947 FrontendAnalogSifStandard sifStandard =
1948 static_cast<FrontendAnalogSifStandard>(
1949 env->GetIntField(settings, env->GetFieldID(clazz, "mSifStandard", "I")));
1950 FrontendAnalogSettings frontendAnalogSettings {
1951 .frequency = freq,
1952 .type = analogType,
1953 .sifStandard = sifStandard,
1954 };
1955 frontendSettings.analog(frontendAnalogSettings);
shubang74bfd482019-10-29 19:10:22 -07001956 return frontendSettings;
1957}
1958
shubangdeb067c2020-01-27 13:21:55 -08001959static hidl_vec<FrontendAtsc3PlpSettings> getAtsc3PlpSettings(
1960 JNIEnv *env, const jobject& settings) {
1961 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/Atsc3FrontendSettings");
1962 jobjectArray plpSettings =
1963 reinterpret_cast<jobjectArray>(
1964 env->GetObjectField(settings,
1965 env->GetFieldID(
1966 clazz,
1967 "mPlpSettings",
1968 "[Landroid/media/tv/tuner/frontend/Atsc3PlpSettings;")));
1969 int len = env->GetArrayLength(plpSettings);
1970
1971 jclass plpClazz = env->FindClass("android/media/tv/tuner/frontend/Atsc3PlpSettings");
1972 hidl_vec<FrontendAtsc3PlpSettings> plps = hidl_vec<FrontendAtsc3PlpSettings>(len);
1973 // parse PLP settings
1974 for (int i = 0; i < len; i++) {
1975 jobject plp = env->GetObjectArrayElement(plpSettings, i);
1976 uint8_t plpId =
1977 static_cast<uint8_t>(
1978 env->GetIntField(plp, env->GetFieldID(plpClazz, "mPlpId", "I")));
1979 FrontendAtsc3Modulation modulation =
1980 static_cast<FrontendAtsc3Modulation>(
1981 env->GetIntField(plp, env->GetFieldID(plpClazz, "mModulation", "I")));
1982 FrontendAtsc3TimeInterleaveMode interleaveMode =
1983 static_cast<FrontendAtsc3TimeInterleaveMode>(
1984 env->GetIntField(
1985 plp, env->GetFieldID(plpClazz, "mInterleaveMode", "I")));
1986 FrontendAtsc3CodeRate codeRate =
1987 static_cast<FrontendAtsc3CodeRate>(
1988 env->GetIntField(plp, env->GetFieldID(plpClazz, "mCodeRate", "I")));
1989 FrontendAtsc3Fec fec =
1990 static_cast<FrontendAtsc3Fec>(
1991 env->GetIntField(plp, env->GetFieldID(plpClazz, "mFec", "I")));
1992 FrontendAtsc3PlpSettings frontendAtsc3PlpSettings {
1993 .plpId = plpId,
1994 .modulation = modulation,
1995 .interleaveMode = interleaveMode,
1996 .codeRate = codeRate,
1997 .fec = fec,
1998 };
1999 plps[i] = frontendAtsc3PlpSettings;
2000 }
2001 return plps;
2002}
2003
2004static FrontendSettings getAtsc3FrontendSettings(JNIEnv *env, const jobject& settings) {
2005 FrontendSettings frontendSettings;
2006 uint32_t freq = getFrontendSettingsFreq(env, settings);
2007 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/Atsc3FrontendSettings");
2008
2009 FrontendAtsc3Bandwidth bandwidth =
2010 static_cast<FrontendAtsc3Bandwidth>(
2011 env->GetIntField(settings, env->GetFieldID(clazz, "mBandwidth", "I")));
2012 FrontendAtsc3DemodOutputFormat demod =
2013 static_cast<FrontendAtsc3DemodOutputFormat>(
2014 env->GetIntField(
2015 settings, env->GetFieldID(clazz, "mDemodOutputFormat", "I")));
2016 hidl_vec<FrontendAtsc3PlpSettings> plps = getAtsc3PlpSettings(env, settings);
2017 FrontendAtsc3Settings frontendAtsc3Settings {
2018 .frequency = freq,
2019 .bandwidth = bandwidth,
2020 .demodOutputFormat = demod,
2021 .plpSettings = plps,
2022 };
2023 frontendSettings.atsc3(frontendAtsc3Settings);
2024 return frontendSettings;
2025}
2026
2027static FrontendSettings getAtscFrontendSettings(JNIEnv *env, const jobject& settings) {
2028 FrontendSettings frontendSettings;
2029 uint32_t freq = getFrontendSettingsFreq(env, settings);
2030 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/AtscFrontendSettings");
2031 FrontendAtscModulation modulation =
2032 static_cast<FrontendAtscModulation>(
2033 env->GetIntField(settings, env->GetFieldID(clazz, "mModulation", "I")));
2034 FrontendAtscSettings frontendAtscSettings {
2035 .frequency = freq,
2036 .modulation = modulation,
2037 };
2038 frontendSettings.atsc(frontendAtscSettings);
2039 return frontendSettings;
2040}
2041
2042static FrontendSettings getDvbcFrontendSettings(JNIEnv *env, const jobject& settings) {
2043 FrontendSettings frontendSettings;
2044 uint32_t freq = getFrontendSettingsFreq(env, settings);
2045 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/DvbcFrontendSettings");
2046 FrontendDvbcModulation modulation =
2047 static_cast<FrontendDvbcModulation>(
2048 env->GetIntField(settings, env->GetFieldID(clazz, "mModulation", "I")));
2049 FrontendInnerFec innerFec =
2050 static_cast<FrontendInnerFec>(
2051 env->GetLongField(settings, env->GetFieldID(clazz, "mFec", "J")));
2052 uint32_t symbolRate =
2053 static_cast<uint32_t>(
2054 env->GetIntField(settings, env->GetFieldID(clazz, "mSymbolRate", "I")));
2055 FrontendDvbcOuterFec outerFec =
2056 static_cast<FrontendDvbcOuterFec>(
2057 env->GetIntField(settings, env->GetFieldID(clazz, "mOuterFec", "I")));
2058 FrontendDvbcAnnex annex =
2059 static_cast<FrontendDvbcAnnex>(
2060 env->GetByteField(settings, env->GetFieldID(clazz, "mAnnex", "B")));
2061 FrontendDvbcSpectralInversion spectralInversion =
2062 static_cast<FrontendDvbcSpectralInversion>(
2063 env->GetIntField(
2064 settings, env->GetFieldID(clazz, "mSpectralInversion", "I")));
2065 FrontendDvbcSettings frontendDvbcSettings {
2066 .frequency = freq,
2067 .modulation = modulation,
2068 .fec = innerFec,
2069 .symbolRate = symbolRate,
2070 .outerFec = outerFec,
2071 .annex = annex,
2072 .spectralInversion = spectralInversion,
2073 };
2074 frontendSettings.dvbc(frontendDvbcSettings);
2075 return frontendSettings;
2076}
2077
2078static FrontendDvbsCodeRate getDvbsCodeRate(JNIEnv *env, const jobject& settings) {
2079 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/DvbsFrontendSettings");
2080 jobject jcodeRate =
2081 env->GetObjectField(settings,
2082 env->GetFieldID(
2083 clazz,
2084 "mCodeRate",
2085 "Landroid/media/tv/tuner/frontend/DvbsCodeRate;"));
2086
2087 jclass codeRateClazz = env->FindClass("android/media/tv/tuner/frontend/DvbsCodeRate");
2088 FrontendInnerFec innerFec =
2089 static_cast<FrontendInnerFec>(
2090 env->GetLongField(
2091 jcodeRate, env->GetFieldID(codeRateClazz, "mInnerFec", "J")));
2092 bool isLinear =
2093 static_cast<bool>(
2094 env->GetBooleanField(
2095 jcodeRate, env->GetFieldID(codeRateClazz, "mIsLinear", "Z")));
2096 bool isShortFrames =
2097 static_cast<bool>(
2098 env->GetBooleanField(
2099 jcodeRate, env->GetFieldID(codeRateClazz, "mIsShortFrames", "Z")));
2100 uint32_t bitsPer1000Symbol =
2101 static_cast<uint32_t>(
2102 env->GetIntField(
2103 jcodeRate, env->GetFieldID(
2104 codeRateClazz, "mBitsPer1000Symbol", "I")));
2105 FrontendDvbsCodeRate coderate {
2106 .fec = innerFec,
2107 .isLinear = isLinear,
2108 .isShortFrames = isShortFrames,
2109 .bitsPer1000Symbol = bitsPer1000Symbol,
2110 };
2111 return coderate;
2112}
2113
2114static FrontendSettings getDvbsFrontendSettings(JNIEnv *env, const jobject& settings) {
2115 FrontendSettings frontendSettings;
2116 uint32_t freq = getFrontendSettingsFreq(env, settings);
2117 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/DvbsFrontendSettings");
2118
2119
2120 FrontendDvbsModulation modulation =
2121 static_cast<FrontendDvbsModulation>(
2122 env->GetIntField(settings, env->GetFieldID(clazz, "mModulation", "I")));
2123 uint32_t symbolRate =
2124 static_cast<uint32_t>(
2125 env->GetIntField(settings, env->GetFieldID(clazz, "mSymbolRate", "I")));
2126 FrontendDvbsRolloff rolloff =
2127 static_cast<FrontendDvbsRolloff>(
2128 env->GetIntField(settings, env->GetFieldID(clazz, "mRolloff", "I")));
2129 FrontendDvbsPilot pilot =
2130 static_cast<FrontendDvbsPilot>(
2131 env->GetIntField(settings, env->GetFieldID(clazz, "mPilot", "I")));
2132 uint32_t inputStreamId =
2133 static_cast<uint32_t>(
2134 env->GetIntField(settings, env->GetFieldID(clazz, "mInputStreamId", "I")));
2135 FrontendDvbsStandard standard =
2136 static_cast<FrontendDvbsStandard>(
2137 env->GetIntField(settings, env->GetFieldID(clazz, "mStandard", "I")));
2138 FrontendDvbsVcmMode vcmMode =
2139 static_cast<FrontendDvbsVcmMode>(
2140 env->GetIntField(settings, env->GetFieldID(clazz, "mVcmMode", "I")));
2141 FrontendDvbsCodeRate coderate = getDvbsCodeRate(env, settings);
2142
2143 FrontendDvbsSettings frontendDvbsSettings {
2144 .frequency = freq,
2145 .modulation = modulation,
2146 .coderate = coderate,
2147 .symbolRate = symbolRate,
2148 .rolloff = rolloff,
2149 .pilot = pilot,
2150 .inputStreamId = inputStreamId,
2151 .standard = standard,
2152 .vcmMode = vcmMode,
2153 };
2154 frontendSettings.dvbs(frontendDvbsSettings);
2155 return frontendSettings;
2156}
2157
2158static FrontendSettings getDvbtFrontendSettings(JNIEnv *env, const jobject& settings) {
2159 FrontendSettings frontendSettings;
2160 uint32_t freq = getFrontendSettingsFreq(env, settings);
2161 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/DvbtFrontendSettings");
2162 FrontendDvbtTransmissionMode transmissionMode =
2163 static_cast<FrontendDvbtTransmissionMode>(
2164 env->GetIntField(
2165 settings, env->GetFieldID(clazz, "mTransmissionMode", "I")));
2166 FrontendDvbtBandwidth bandwidth =
2167 static_cast<FrontendDvbtBandwidth>(
2168 env->GetIntField(settings, env->GetFieldID(clazz, "mBandwidth", "I")));
2169 FrontendDvbtConstellation constellation =
2170 static_cast<FrontendDvbtConstellation>(
2171 env->GetIntField(settings, env->GetFieldID(clazz, "mConstellation", "I")));
2172 FrontendDvbtHierarchy hierarchy =
2173 static_cast<FrontendDvbtHierarchy>(
2174 env->GetIntField(settings, env->GetFieldID(clazz, "mHierarchy", "I")));
2175 FrontendDvbtCoderate hpCoderate =
2176 static_cast<FrontendDvbtCoderate>(
2177 env->GetIntField(settings, env->GetFieldID(clazz, "mHpCodeRate", "I")));
2178 FrontendDvbtCoderate lpCoderate =
2179 static_cast<FrontendDvbtCoderate>(
2180 env->GetIntField(settings, env->GetFieldID(clazz, "mLpCodeRate", "I")));
2181 FrontendDvbtGuardInterval guardInterval =
2182 static_cast<FrontendDvbtGuardInterval>(
2183 env->GetIntField(settings, env->GetFieldID(clazz, "mGuardInterval", "I")));
2184 bool isHighPriority =
2185 static_cast<bool>(
2186 env->GetBooleanField(
2187 settings, env->GetFieldID(clazz, "mIsHighPriority", "Z")));
2188 FrontendDvbtStandard standard =
2189 static_cast<FrontendDvbtStandard>(
2190 env->GetIntField(settings, env->GetFieldID(clazz, "mStandard", "I")));
2191 bool isMiso =
2192 static_cast<bool>(
2193 env->GetBooleanField(settings, env->GetFieldID(clazz, "mIsMiso", "Z")));
2194 FrontendDvbtPlpMode plpMode =
2195 static_cast<FrontendDvbtPlpMode>(
2196 env->GetIntField(settings, env->GetFieldID(clazz, "mPlpMode", "I")));
2197 uint8_t plpId =
2198 static_cast<uint8_t>(
2199 env->GetIntField(settings, env->GetFieldID(clazz, "mPlpId", "I")));
2200 uint8_t plpGroupId =
2201 static_cast<uint8_t>(
2202 env->GetIntField(settings, env->GetFieldID(clazz, "mPlpGroupId", "I")));
2203
2204 FrontendDvbtSettings frontendDvbtSettings {
2205 .frequency = freq,
2206 .transmissionMode = transmissionMode,
2207 .bandwidth = bandwidth,
2208 .constellation = constellation,
2209 .hierarchy = hierarchy,
2210 .hpCoderate = hpCoderate,
2211 .lpCoderate = lpCoderate,
2212 .guardInterval = guardInterval,
2213 .isHighPriority = isHighPriority,
2214 .standard = standard,
2215 .isMiso = isMiso,
2216 .plpMode = plpMode,
2217 .plpId = plpId,
2218 .plpGroupId = plpGroupId,
2219 };
2220 frontendSettings.dvbt(frontendDvbtSettings);
2221 return frontendSettings;
2222}
2223
2224static FrontendSettings getIsdbsFrontendSettings(JNIEnv *env, const jobject& settings) {
2225 FrontendSettings frontendSettings;
2226 uint32_t freq = getFrontendSettingsFreq(env, settings);
2227 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/IsdbsFrontendSettings");
2228 uint16_t streamId =
2229 static_cast<uint16_t>(
2230 env->GetIntField(settings, env->GetFieldID(clazz, "mStreamId", "I")));
2231 FrontendIsdbsStreamIdType streamIdType =
2232 static_cast<FrontendIsdbsStreamIdType>(
2233 env->GetIntField(settings, env->GetFieldID(clazz, "mStreamIdType", "I")));
2234 FrontendIsdbsModulation modulation =
2235 static_cast<FrontendIsdbsModulation>(
2236 env->GetIntField(settings, env->GetFieldID(clazz, "mModulation", "I")));
2237 FrontendIsdbsCoderate coderate =
2238 static_cast<FrontendIsdbsCoderate>(
2239 env->GetIntField(settings, env->GetFieldID(clazz, "mCodeRate", "I")));
2240 uint32_t symbolRate =
2241 static_cast<uint32_t>(
2242 env->GetIntField(settings, env->GetFieldID(clazz, "mSymbolRate", "I")));
2243 FrontendIsdbsRolloff rolloff =
2244 static_cast<FrontendIsdbsRolloff>(
2245 env->GetIntField(settings, env->GetFieldID(clazz, "mRolloff", "I")));
2246
2247 FrontendIsdbsSettings frontendIsdbsSettings {
2248 .frequency = freq,
2249 .streamId = streamId,
2250 .streamIdType = streamIdType,
2251 .modulation = modulation,
2252 .coderate = coderate,
2253 .symbolRate = symbolRate,
2254 .rolloff = rolloff,
2255 };
2256 frontendSettings.isdbs(frontendIsdbsSettings);
2257 return frontendSettings;
2258}
2259
2260static FrontendSettings getIsdbs3FrontendSettings(JNIEnv *env, const jobject& settings) {
2261 FrontendSettings frontendSettings;
2262 uint32_t freq = getFrontendSettingsFreq(env, settings);
2263 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/Isdbs3FrontendSettings");
2264 uint16_t streamId =
2265 static_cast<uint16_t>(
2266 env->GetIntField(settings, env->GetFieldID(clazz, "mStreamId", "I")));
2267 FrontendIsdbsStreamIdType streamIdType =
2268 static_cast<FrontendIsdbsStreamIdType>(
2269 env->GetIntField(settings, env->GetFieldID(clazz, "mStreamIdType", "I")));
2270 FrontendIsdbs3Modulation modulation =
2271 static_cast<FrontendIsdbs3Modulation>(
2272 env->GetIntField(settings, env->GetFieldID(clazz, "mModulation", "I")));
2273 FrontendIsdbs3Coderate coderate =
2274 static_cast<FrontendIsdbs3Coderate>(
2275 env->GetIntField(settings, env->GetFieldID(clazz, "mCodeRate", "I")));
2276 uint32_t symbolRate =
2277 static_cast<uint32_t>(
2278 env->GetIntField(settings, env->GetFieldID(clazz, "mSymbolRate", "I")));
2279 FrontendIsdbs3Rolloff rolloff =
2280 static_cast<FrontendIsdbs3Rolloff>(
2281 env->GetIntField(settings, env->GetFieldID(clazz, "mRolloff", "I")));
2282
2283 FrontendIsdbs3Settings frontendIsdbs3Settings {
2284 .frequency = freq,
2285 .streamId = streamId,
2286 .streamIdType = streamIdType,
2287 .modulation = modulation,
2288 .coderate = coderate,
2289 .symbolRate = symbolRate,
2290 .rolloff = rolloff,
2291 };
2292 frontendSettings.isdbs3(frontendIsdbs3Settings);
2293 return frontendSettings;
2294}
2295
2296static FrontendSettings getIsdbtFrontendSettings(JNIEnv *env, const jobject& settings) {
2297 FrontendSettings frontendSettings;
2298 uint32_t freq = getFrontendSettingsFreq(env, settings);
2299 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/IsdbtFrontendSettings");
2300 FrontendIsdbtModulation modulation =
2301 static_cast<FrontendIsdbtModulation>(
2302 env->GetIntField(settings, env->GetFieldID(clazz, "mModulation", "I")));
2303 FrontendIsdbtBandwidth bandwidth =
2304 static_cast<FrontendIsdbtBandwidth>(
2305 env->GetIntField(settings, env->GetFieldID(clazz, "mBandwidth", "I")));
2306 FrontendIsdbtMode mode =
2307 static_cast<FrontendIsdbtMode>(
2308 env->GetIntField(settings, env->GetFieldID(clazz, "mMode", "I")));
2309 FrontendIsdbtCoderate coderate =
2310 static_cast<FrontendIsdbtCoderate>(
2311 env->GetIntField(settings, env->GetFieldID(clazz, "mCodeRate", "I")));
2312 FrontendIsdbtGuardInterval guardInterval =
2313 static_cast<FrontendIsdbtGuardInterval>(
2314 env->GetIntField(settings, env->GetFieldID(clazz, "mGuardInterval", "I")));
2315 uint32_t serviceAreaId =
2316 static_cast<uint32_t>(
2317 env->GetIntField(settings, env->GetFieldID(clazz, "mServiceAreaId", "I")));
2318
2319 FrontendIsdbtSettings frontendIsdbtSettings {
2320 .frequency = freq,
2321 .modulation = modulation,
2322 .bandwidth = bandwidth,
2323 .mode = mode,
2324 .coderate = coderate,
2325 .guardInterval = guardInterval,
2326 .serviceAreaId = serviceAreaId,
2327 };
2328 frontendSettings.isdbt(frontendIsdbtSettings);
2329 return frontendSettings;
2330}
2331
2332static FrontendSettings getFrontendSettings(JNIEnv *env, int type, jobject settings) {
2333 ALOGD("getFrontendSettings %d", type);
2334
2335 FrontendType feType = static_cast<FrontendType>(type);
2336 switch(feType) {
2337 case FrontendType::ANALOG:
2338 return getAnalogFrontendSettings(env, settings);
2339 case FrontendType::ATSC3:
2340 return getAtsc3FrontendSettings(env, settings);
2341 case FrontendType::ATSC:
2342 return getAtscFrontendSettings(env, settings);
2343 case FrontendType::DVBC:
2344 return getDvbcFrontendSettings(env, settings);
2345 case FrontendType::DVBS:
2346 return getDvbsFrontendSettings(env, settings);
2347 case FrontendType::DVBT:
2348 return getDvbtFrontendSettings(env, settings);
2349 case FrontendType::ISDBS:
2350 return getIsdbsFrontendSettings(env, settings);
2351 case FrontendType::ISDBS3:
2352 return getIsdbs3FrontendSettings(env, settings);
2353 case FrontendType::ISDBT:
2354 return getIsdbtFrontendSettings(env, settings);
2355 default:
2356 // should never happen because a type is associated with a subclass of
2357 // FrontendSettings and not set by users
2358 jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
2359 "Unsupported frontend type %d", type);
2360 return FrontendSettings();
2361 }
2362}
2363
shubang7648a3c2019-11-25 18:16:45 -08002364static sp<Filter> getFilter(JNIEnv *env, jobject filter) {
2365 return (Filter *)env->GetLongField(filter, gFields.filterContext);
shubangcdf30de2019-11-06 17:28:38 -08002366}
2367
shubange8cb82c2020-05-19 15:12:01 -07002368static DvrSettings getDvrSettings(JNIEnv *env, jobject settings, bool isRecorder) {
shubang030afb52019-11-27 16:09:02 -08002369 DvrSettings dvrSettings;
shubangd351b822020-01-22 17:29:18 -08002370 jclass clazz = env->FindClass("android/media/tv/tuner/dvr/DvrSettings");
shubang030afb52019-11-27 16:09:02 -08002371 uint32_t statusMask =
2372 static_cast<uint32_t>(env->GetIntField(
2373 settings, env->GetFieldID(clazz, "mStatusMask", "I")));
2374 uint32_t lowThreshold =
shubange8cb82c2020-05-19 15:12:01 -07002375 static_cast<uint32_t>(env->GetLongField(
2376 settings, env->GetFieldID(clazz, "mLowThreshold", "J")));
shubang030afb52019-11-27 16:09:02 -08002377 uint32_t highThreshold =
shubange8cb82c2020-05-19 15:12:01 -07002378 static_cast<uint32_t>(env->GetLongField(
2379 settings, env->GetFieldID(clazz, "mHighThreshold", "J")));
shubang030afb52019-11-27 16:09:02 -08002380 uint8_t packetSize =
shubange8cb82c2020-05-19 15:12:01 -07002381 static_cast<uint8_t>(env->GetLongField(
2382 settings, env->GetFieldID(clazz, "mPacketSize", "J")));
shubang030afb52019-11-27 16:09:02 -08002383 DataFormat dataFormat =
2384 static_cast<DataFormat>(env->GetIntField(
2385 settings, env->GetFieldID(clazz, "mDataFormat", "I")));
shubange8cb82c2020-05-19 15:12:01 -07002386 if (isRecorder) {
shubang030afb52019-11-27 16:09:02 -08002387 RecordSettings recordSettings {
2388 .statusMask = static_cast<unsigned char>(statusMask),
2389 .lowThreshold = lowThreshold,
2390 .highThreshold = highThreshold,
2391 .dataFormat = dataFormat,
2392 .packetSize = packetSize,
2393 };
2394 dvrSettings.record(recordSettings);
shubange8cb82c2020-05-19 15:12:01 -07002395 } else {
shubang030afb52019-11-27 16:09:02 -08002396 PlaybackSettings PlaybackSettings {
2397 .statusMask = statusMask,
2398 .lowThreshold = lowThreshold,
2399 .highThreshold = highThreshold,
2400 .dataFormat = dataFormat,
2401 .packetSize = packetSize,
2402 };
2403 dvrSettings.playback(PlaybackSettings);
2404 }
2405 return dvrSettings;
2406}
2407
shubang9e700ff2019-12-04 16:26:51 -08002408static sp<Dvr> getDvr(JNIEnv *env, jobject dvr) {
shubang5637a662020-02-27 18:06:21 -08002409 bool isRecorder =
2410 env->IsInstanceOf(dvr, env->FindClass("android/media/tv/tuner/dvr/DvrRecorder"));
2411 jfieldID fieldId =
2412 isRecorder ? gFields.dvrRecorderContext : gFields.dvrPlaybackContext;
2413 return (Dvr *)env->GetLongField(dvr, fieldId);
shubang4a0eddf2019-11-08 17:10:18 -08002414}
2415
shubang8ab43b12019-10-18 15:55:55 -07002416static void android_media_tv_Tuner_native_init(JNIEnv *env) {
2417 jclass clazz = env->FindClass("android/media/tv/tuner/Tuner");
2418 CHECK(clazz != NULL);
2419
shubang13f15e02019-11-04 17:51:02 -08002420 gFields.tunerContext = env->GetFieldID(clazz, "mNativeContext", "J");
2421 CHECK(gFields.tunerContext != NULL);
shubang7e849b02019-10-18 19:36:25 -07002422
shubang4b8c5402019-10-24 17:49:53 -07002423 gFields.onFrontendEventID = env->GetMethodID(clazz, "onFrontendEvent", "(I)V");
2424
shubang7e849b02019-10-18 19:36:25 -07002425 jclass frontendClazz = env->FindClass("android/media/tv/tuner/Tuner$Frontend");
shubang4b8c5402019-10-24 17:49:53 -07002426 gFields.frontendInitID =
2427 env->GetMethodID(frontendClazz, "<init>", "(Landroid/media/tv/tuner/Tuner;I)V");
shubang6f473d62019-11-01 15:42:21 -07002428
shubangd351b822020-01-22 17:29:18 -08002429 jclass lnbClazz = env->FindClass("android/media/tv/tuner/Lnb");
shubang1c1144e2020-03-03 18:00:17 -08002430 gFields.lnbContext = env->GetFieldID(lnbClazz, "mNativeContext", "J");
shubang757602f2020-03-06 15:23:41 -08002431 gFields.lnbInitID = env->GetMethodID(lnbClazz, "<init>", "(I)V");
shubangd295be02020-03-27 17:08:11 -07002432 gFields.onLnbEventID = env->GetMethodID(lnbClazz, "onEvent", "(I)V");
2433 gFields.onLnbDiseqcMessageID = env->GetMethodID(lnbClazz, "onDiseqcMessage", "([B)V");
shubang760f0312019-11-12 17:11:28 -08002434
shubangd351b822020-01-22 17:29:18 -08002435 jclass filterClazz = env->FindClass("android/media/tv/tuner/filter/Filter");
shubangcdf30de2019-11-06 17:28:38 -08002436 gFields.filterContext = env->GetFieldID(filterClazz, "mNativeContext", "J");
shubang6f473d62019-11-01 15:42:21 -07002437 gFields.filterInitID =
shubangdeb067c2020-01-27 13:21:55 -08002438 env->GetMethodID(filterClazz, "<init>", "(I)V");
shubangcdf30de2019-11-06 17:28:38 -08002439 gFields.onFilterStatusID =
2440 env->GetMethodID(filterClazz, "onFilterStatus", "(I)V");
shubang3e0c37b2020-02-19 19:09:10 -08002441 gFields.onFilterEventID =
2442 env->GetMethodID(filterClazz, "onFilterEvent",
2443 "([Landroid/media/tv/tuner/filter/FilterEvent;)V");
shubang13f15e02019-11-04 17:51:02 -08002444
shubangf657da22020-02-05 16:27:06 -08002445 jclass timeFilterClazz = env->FindClass("android/media/tv/tuner/filter/TimeFilter");
2446 gFields.timeFilterContext = env->GetFieldID(timeFilterClazz, "mNativeContext", "J");
2447 gFields.timeFilterInitID = env->GetMethodID(timeFilterClazz, "<init>", "()V");
2448
shubangd351b822020-01-22 17:29:18 -08002449 jclass descramblerClazz = env->FindClass("android/media/tv/tuner/Descrambler");
shubang13f15e02019-11-04 17:51:02 -08002450 gFields.descramblerContext = env->GetFieldID(descramblerClazz, "mNativeContext", "J");
shubang40454db2020-03-30 16:52:29 -07002451 gFields.descramblerInitID = env->GetMethodID(descramblerClazz, "<init>", "()V");
shubang4a0eddf2019-11-08 17:10:18 -08002452
shubang5637a662020-02-27 18:06:21 -08002453 jclass dvrRecorderClazz = env->FindClass("android/media/tv/tuner/dvr/DvrRecorder");
2454 gFields.dvrRecorderContext = env->GetFieldID(dvrRecorderClazz, "mNativeContext", "J");
2455 gFields.dvrRecorderInitID = env->GetMethodID(dvrRecorderClazz, "<init>", "()V");
shubang431e5612020-03-30 21:24:56 -07002456 gFields.onDvrRecordStatusID =
2457 env->GetMethodID(dvrRecorderClazz, "onRecordStatusChanged", "(I)V");
shubang5637a662020-02-27 18:06:21 -08002458
2459 jclass dvrPlaybackClazz = env->FindClass("android/media/tv/tuner/dvr/DvrPlayback");
2460 gFields.dvrPlaybackContext = env->GetFieldID(dvrPlaybackClazz, "mNativeContext", "J");
2461 gFields.dvrPlaybackInitID = env->GetMethodID(dvrPlaybackClazz, "<init>", "()V");
shubang431e5612020-03-30 21:24:56 -07002462 gFields.onDvrPlaybackStatusID =
shubang66cc3aa2020-04-06 17:10:01 -07002463 env->GetMethodID(dvrPlaybackClazz, "onPlaybackStatusChanged", "(I)V");
shubangd49681e2020-02-17 21:32:30 -08002464
shubang3aef4fe2020-04-01 16:51:04 -07002465 jclass mediaEventClazz = env->FindClass("android/media/tv/tuner/filter/MediaEvent");
2466 gFields.mediaEventContext = env->GetFieldID(mediaEventClazz, "mNativeContext", "J");
2467
shubangd49681e2020-02-17 21:32:30 -08002468 jclass linearBlockClazz = env->FindClass("android/media/MediaCodec$LinearBlock");
2469 gFields.linearBlockInitID = env->GetMethodID(linearBlockClazz, "<init>", "()V");
2470 gFields.linearBlockSetInternalStateID =
2471 env->GetMethodID(linearBlockClazz, "setInternalStateLocked", "(JZ)V");
shubang8ab43b12019-10-18 15:55:55 -07002472}
2473
2474static void android_media_tv_Tuner_native_setup(JNIEnv *env, jobject thiz) {
2475 sp<JTuner> tuner = new JTuner(env, thiz);
2476 setTuner(env,thiz, tuner);
2477}
2478
shubang7e849b02019-10-18 19:36:25 -07002479static jobject android_media_tv_Tuner_get_frontend_ids(JNIEnv *env, jobject thiz) {
2480 sp<JTuner> tuner = getTuner(env, thiz);
2481 return tuner->getFrontendIds();
2482}
2483
shubangc18cc102020-03-12 16:28:45 -07002484static jobject android_media_tv_Tuner_open_frontend_by_handle(
2485 JNIEnv *env, jobject thiz, jint handle) {
shubang7e849b02019-10-18 19:36:25 -07002486 sp<JTuner> tuner = getTuner(env, thiz);
shubangc18cc102020-03-12 16:28:45 -07002487 uint32_t id = getResourceIdFromHandle(handle);
shubang7e849b02019-10-18 19:36:25 -07002488 return tuner->openFrontendById(id);
2489}
2490
shubang2f9cab32020-04-10 18:00:56 -07002491static jint android_media_tv_Tuner_close_frontend_by_handle(
2492 JNIEnv *env, jobject thiz, jint handle) {
2493 sp<JTuner> tuner = getTuner(env, thiz);
2494 uint32_t id = getResourceIdFromHandle(handle);
2495 return tuner->closeFrontendById(id);
2496}
2497
shubang74bfd482019-10-29 19:10:22 -07002498static int android_media_tv_Tuner_tune(JNIEnv *env, jobject thiz, jint type, jobject settings) {
2499 sp<JTuner> tuner = getTuner(env, thiz);
2500 return tuner->tune(getFrontendSettings(env, type, settings));
2501}
2502
shubange32fb412020-01-28 14:53:05 -08002503static int android_media_tv_Tuner_stop_tune(JNIEnv *env, jobject thiz) {
2504 sp<JTuner> tuner = getTuner(env, thiz);
2505 return tuner->stopTune();
shubange65b6862019-12-17 15:43:35 -08002506}
2507
shubangd5b845f2019-12-11 15:29:09 -08002508static int android_media_tv_Tuner_scan(
2509 JNIEnv *env, jobject thiz, jint settingsType, jobject settings, jint scanType) {
2510 sp<JTuner> tuner = getTuner(env, thiz);
2511 return tuner->scan(getFrontendSettings(
2512 env, settingsType, settings), static_cast<FrontendScanType>(scanType));
2513}
2514
shubange32fb412020-01-28 14:53:05 -08002515static int android_media_tv_Tuner_stop_scan(JNIEnv *env, jobject thiz) {
2516 sp<JTuner> tuner = getTuner(env, thiz);
2517 return tuner->stopScan();
shubange65b6862019-12-17 15:43:35 -08002518}
2519
shubange32fb412020-01-28 14:53:05 -08002520static int android_media_tv_Tuner_set_lnb(JNIEnv *env, jobject thiz, jint id) {
2521 sp<JTuner> tuner = getTuner(env, thiz);
2522 return tuner->setLnb(id);
shubang793e5702019-12-26 15:15:46 -08002523}
2524
shubange32fb412020-01-28 14:53:05 -08002525static int android_media_tv_Tuner_set_lna(JNIEnv *env, jobject thiz, jboolean enable) {
2526 sp<JTuner> tuner = getTuner(env, thiz);
2527 return tuner->setLna(enable);
shubange65b6862019-12-17 15:43:35 -08002528}
2529
shubangb83f8232020-03-24 18:04:35 -07002530static jobject android_media_tv_Tuner_get_frontend_status(
2531 JNIEnv* env, jobject thiz, jintArray types) {
2532 sp<JTuner> tuner = getTuner(env, thiz);
2533 return tuner->getFrontendStatus(types);
shubang1512ec12019-12-23 18:22:42 -08002534}
2535
shubangbee73462020-02-07 17:48:02 -08002536static jobject android_media_tv_Tuner_get_av_sync_hw_id(
2537 JNIEnv *env, jobject thiz, jobject filter) {
2538 sp<Filter> filterSp = getFilter(env, filter);
2539 if (filterSp == NULL) {
2540 ALOGD("Failed to get sync ID. Filter not found");
2541 return NULL;
2542 }
2543 sp<JTuner> tuner = getTuner(env, thiz);
2544 return tuner->getAvSyncHwId(filterSp);
shubang7343fee2019-12-27 12:02:08 -08002545}
2546
shubangbee73462020-02-07 17:48:02 -08002547static jobject android_media_tv_Tuner_get_av_sync_time(JNIEnv *env, jobject thiz, jint id) {
2548 sp<JTuner> tuner = getTuner(env, thiz);
2549 return tuner->getAvSyncTime(id);
shubang7343fee2019-12-27 12:02:08 -08002550}
2551
shubangbee73462020-02-07 17:48:02 -08002552static int android_media_tv_Tuner_connect_cicam(JNIEnv *env, jobject thiz, jint id) {
2553 sp<JTuner> tuner = getTuner(env, thiz);
2554 return tuner->connectCiCam(id);
shubang7343fee2019-12-27 12:02:08 -08002555}
2556
shubangbee73462020-02-07 17:48:02 -08002557static int android_media_tv_Tuner_disconnect_cicam(JNIEnv *env, jobject thiz) {
2558 sp<JTuner> tuner = getTuner(env, thiz);
2559 return tuner->disconnectCiCam();
shubang7343fee2019-12-27 12:02:08 -08002560}
2561
shubang51cc62f2020-01-28 18:00:22 -08002562static jobject android_media_tv_Tuner_get_frontend_info(JNIEnv *env, jobject thiz, jint id) {
2563 sp<JTuner> tuner = getTuner(env, thiz);
2564 return tuner->getFrontendInfo(id);
shubang95c1f752019-12-27 16:29:48 -08002565}
2566
shubang0dc83942020-04-02 17:19:31 -07002567static jintArray android_media_tv_Tuner_get_lnb_ids(JNIEnv *env, jobject thiz) {
shubang760f0312019-11-12 17:11:28 -08002568 sp<JTuner> tuner = getTuner(env, thiz);
2569 return tuner->getLnbIds();
2570}
2571
shubangc18cc102020-03-12 16:28:45 -07002572static jobject android_media_tv_Tuner_open_lnb_by_handle(JNIEnv *env, jobject thiz, jint handle) {
shubang760f0312019-11-12 17:11:28 -08002573 sp<JTuner> tuner = getTuner(env, thiz);
shubangc18cc102020-03-12 16:28:45 -07002574 uint32_t id = getResourceIdFromHandle(handle);
shubang760f0312019-11-12 17:11:28 -08002575 return tuner->openLnbById(id);
2576}
2577
shubang757602f2020-03-06 15:23:41 -08002578static jobject android_media_tv_Tuner_open_lnb_by_name(JNIEnv *env, jobject thiz, jstring name) {
2579 sp<JTuner> tuner = getTuner(env, thiz);
2580 return tuner->openLnbByName(name);
2581}
2582
2583
shubang6f473d62019-11-01 15:42:21 -07002584static jobject android_media_tv_Tuner_open_filter(
shubangd351b822020-01-22 17:29:18 -08002585 JNIEnv *env, jobject thiz, jint type, jint subType, jlong bufferSize) {
shubang6f473d62019-11-01 15:42:21 -07002586 sp<JTuner> tuner = getTuner(env, thiz);
shubangf657da22020-02-05 16:27:06 -08002587 DemuxFilterMainType mainType = static_cast<DemuxFilterMainType>(type);
shubang6f473d62019-11-01 15:42:21 -07002588 DemuxFilterType filterType {
shubangf657da22020-02-05 16:27:06 -08002589 .mainType = mainType,
shubang6f473d62019-11-01 15:42:21 -07002590 };
2591
shubangf657da22020-02-05 16:27:06 -08002592 switch(mainType) {
2593 case DemuxFilterMainType::TS:
2594 filterType.subType.tsFilterType(static_cast<DemuxTsFilterType>(subType));
2595 break;
2596 case DemuxFilterMainType::MMTP:
2597 filterType.subType.mmtpFilterType(static_cast<DemuxMmtpFilterType>(subType));
2598 break;
2599 case DemuxFilterMainType::IP:
2600 filterType.subType.ipFilterType(static_cast<DemuxIpFilterType>(subType));
2601 break;
2602 case DemuxFilterMainType::TLV:
2603 filterType.subType.tlvFilterType(static_cast<DemuxTlvFilterType>(subType));
2604 break;
2605 case DemuxFilterMainType::ALP:
2606 filterType.subType.alpFilterType(static_cast<DemuxAlpFilterType>(subType));
2607 break;
2608 }
shubang6f473d62019-11-01 15:42:21 -07002609
2610 return tuner->openFilter(filterType, bufferSize);
2611}
2612
shubangf657da22020-02-05 16:27:06 -08002613static jobject android_media_tv_Tuner_open_time_filter(JNIEnv *env, jobject thiz) {
2614 sp<JTuner> tuner = getTuner(env, thiz);
2615 return tuner->openTimeFilter();
shubang4347e2e2019-12-13 17:20:40 -08002616}
2617
shubang44fa1422020-01-30 11:42:59 -08002618static DemuxFilterSectionBits getFilterSectionBits(JNIEnv *env, const jobject& settings) {
2619 jclass clazz = env->FindClass("android/media/tv/tuner/filter/SectionSettingsWithSectionBits");
2620 jbyteArray jfilterBytes = static_cast<jbyteArray>(
2621 env->GetObjectField(settings, env->GetFieldID(clazz, "mFilter", "[B")));
2622 jsize size = env->GetArrayLength(jfilterBytes);
2623 std::vector<uint8_t> filterBytes(size);
2624 env->GetByteArrayRegion(
2625 jfilterBytes, 0, size, reinterpret_cast<jbyte*>(&filterBytes[0]));
2626
2627 jbyteArray jmask = static_cast<jbyteArray>(
2628 env->GetObjectField(settings, env->GetFieldID(clazz, "mMask", "[B")));
2629 size = env->GetArrayLength(jmask);
2630 std::vector<uint8_t> mask(size);
2631 env->GetByteArrayRegion(jmask, 0, size, reinterpret_cast<jbyte*>(&mask[0]));
2632
2633 jbyteArray jmode = static_cast<jbyteArray>(
2634 env->GetObjectField(settings, env->GetFieldID(clazz, "mMode", "[B")));
2635 size = env->GetArrayLength(jmode);
2636 std::vector<uint8_t> mode(size);
2637 env->GetByteArrayRegion(jmode, 0, size, reinterpret_cast<jbyte*>(&mode[0]));
2638
2639 DemuxFilterSectionBits filterSectionBits {
2640 .filter = filterBytes,
2641 .mask = mask,
2642 .mode = mode,
2643 };
2644 return filterSectionBits;
2645}
2646
2647static DemuxFilterSectionSettings::Condition::TableInfo getFilterTableInfo(
2648 JNIEnv *env, const jobject& settings) {
2649 jclass clazz = env->FindClass("android/media/tv/tuner/filter/SectionSettingsWithTableInfo");
2650 uint16_t tableId = static_cast<uint16_t>(
2651 env->GetIntField(settings, env->GetFieldID(clazz, "mTableId", "I")));
2652 uint16_t version = static_cast<uint16_t>(
2653 env->GetIntField(settings, env->GetFieldID(clazz, "mVersion", "I")));
2654 DemuxFilterSectionSettings::Condition::TableInfo tableInfo {
2655 .tableId = tableId,
2656 .version = version,
2657 };
2658 return tableInfo;
2659}
2660
2661static DemuxFilterSectionSettings getFilterSectionSettings(JNIEnv *env, const jobject& settings) {
2662 jclass clazz = env->FindClass("android/media/tv/tuner/filter/SectionSettings");
2663 bool isCheckCrc = static_cast<bool>(
2664 env->GetBooleanField(settings, env->GetFieldID(clazz, "mCrcEnabled", "Z")));
2665 bool isRepeat = static_cast<bool>(
2666 env->GetBooleanField(settings, env->GetFieldID(clazz, "mIsRepeat", "Z")));
2667 bool isRaw = static_cast<bool>(
2668 env->GetBooleanField(settings, env->GetFieldID(clazz, "mIsRaw", "Z")));
2669
2670 DemuxFilterSectionSettings filterSectionSettings {
2671 .isCheckCrc = isCheckCrc,
2672 .isRepeat = isRepeat,
2673 .isRaw = isRaw,
2674 };
2675 if (env->IsInstanceOf(
2676 settings,
2677 env->FindClass("android/media/tv/tuner/filter/SectionSettingsWithSectionBits"))) {
2678 filterSectionSettings.condition.sectionBits(getFilterSectionBits(env, settings));
2679 } else if (env->IsInstanceOf(
2680 settings,
2681 env->FindClass("android/media/tv/tuner/filter/SectionSettingsWithTableInfo"))) {
2682 filterSectionSettings.condition.tableInfo(getFilterTableInfo(env, settings));
2683 }
2684 return filterSectionSettings;
2685}
2686
2687static DemuxFilterAvSettings getFilterAvSettings(JNIEnv *env, const jobject& settings) {
2688 jclass clazz = env->FindClass("android/media/tv/tuner/filter/AvSettings");
2689 bool isPassthrough = static_cast<bool>(
2690 env->GetBooleanField(settings, env->GetFieldID(clazz, "mIsPassthrough", "Z")));
2691 DemuxFilterAvSettings filterAvSettings {
2692 .isPassthrough = isPassthrough,
2693 };
2694 return filterAvSettings;
2695}
2696
2697static DemuxFilterPesDataSettings getFilterPesDataSettings(JNIEnv *env, const jobject& settings) {
2698 jclass clazz = env->FindClass("android/media/tv/tuner/filter/PesSettings");
2699 uint16_t streamId = static_cast<uint16_t>(
2700 env->GetIntField(settings, env->GetFieldID(clazz, "mStreamId", "I")));
2701 bool isRaw = static_cast<bool>(
2702 env->GetBooleanField(settings, env->GetFieldID(clazz, "mIsRaw", "Z")));
2703 DemuxFilterPesDataSettings filterPesDataSettings {
2704 .streamId = streamId,
2705 .isRaw = isRaw,
2706 };
2707 return filterPesDataSettings;
2708}
2709
2710static DemuxFilterRecordSettings getFilterRecordSettings(JNIEnv *env, const jobject& settings) {
2711 jclass clazz = env->FindClass("android/media/tv/tuner/filter/RecordSettings");
2712 hidl_bitfield<DemuxTsIndex> tsIndexMask = static_cast<hidl_bitfield<DemuxTsIndex>>(
2713 env->GetIntField(settings, env->GetFieldID(clazz, "mTsIndexMask", "I")));
2714 DemuxRecordScIndexType scIndexType = static_cast<DemuxRecordScIndexType>(
2715 env->GetIntField(settings, env->GetFieldID(clazz, "mScIndexType", "I")));
2716 jint scIndexMask = env->GetIntField(settings, env->GetFieldID(clazz, "mScIndexMask", "I"));
2717
2718 DemuxFilterRecordSettings filterRecordSettings {
2719 .tsIndexMask = tsIndexMask,
2720 .scIndexType = scIndexType,
2721 };
2722 if (scIndexType == DemuxRecordScIndexType::SC) {
2723 filterRecordSettings.scIndexMask.sc(static_cast<hidl_bitfield<DemuxScIndex>>(scIndexMask));
2724 } else if (scIndexType == DemuxRecordScIndexType::SC_HEVC) {
2725 filterRecordSettings.scIndexMask.scHevc(
2726 static_cast<hidl_bitfield<DemuxScHevcIndex>>(scIndexMask));
2727 }
2728 return filterRecordSettings;
2729}
2730
2731static DemuxFilterDownloadSettings getFilterDownloadSettings(JNIEnv *env, const jobject& settings) {
2732 jclass clazz = env->FindClass("android/media/tv/tuner/filter/DownloadSettings");
2733 uint32_t downloadId = static_cast<uint32_t>(
2734 env->GetIntField(settings, env->GetFieldID(clazz, "mDownloadId", "I")));
2735
2736 DemuxFilterDownloadSettings filterDownloadSettings {
2737 .downloadId = downloadId,
2738 };
2739 return filterDownloadSettings;
2740}
2741
shubang87788c32020-02-04 13:55:23 -08002742static DemuxIpAddress getDemuxIpAddress(JNIEnv *env, const jobject& config) {
2743 jclass clazz = env->FindClass("android/media/tv/tuner/filter/IpFilterConfiguration");
2744
2745 jbyteArray jsrcIpAddress = static_cast<jbyteArray>(
2746 env->GetObjectField(config, env->GetFieldID(clazz, "mSrcIpAddress", "[B")));
2747 jsize srcSize = env->GetArrayLength(jsrcIpAddress);
2748 jbyteArray jdstIpAddress = static_cast<jbyteArray>(
2749 env->GetObjectField(config, env->GetFieldID(clazz, "mDstIpAddress", "[B")));
2750 jsize dstSize = env->GetArrayLength(jdstIpAddress);
2751
2752 DemuxIpAddress res;
2753
2754 if (srcSize != dstSize) {
2755 // should never happen. Validated on Java size.
2756 jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
2757 "IP address lengths don't match. srcLength=%d, dstLength=%d", srcSize, dstSize);
2758 return res;
2759 }
2760
2761 if (srcSize == IP_V4_LENGTH) {
2762 uint8_t srcAddr[IP_V4_LENGTH];
2763 uint8_t dstAddr[IP_V4_LENGTH];
2764 env->GetByteArrayRegion(
2765 jsrcIpAddress, 0, srcSize, reinterpret_cast<jbyte*>(srcAddr));
2766 env->GetByteArrayRegion(
2767 jdstIpAddress, 0, dstSize, reinterpret_cast<jbyte*>(dstAddr));
2768 res.srcIpAddress.v4(srcAddr);
2769 res.dstIpAddress.v4(dstAddr);
2770 } else if (srcSize == IP_V6_LENGTH) {
2771 uint8_t srcAddr[IP_V6_LENGTH];
2772 uint8_t dstAddr[IP_V6_LENGTH];
2773 env->GetByteArrayRegion(
2774 jsrcIpAddress, 0, srcSize, reinterpret_cast<jbyte*>(srcAddr));
2775 env->GetByteArrayRegion(
2776 jdstIpAddress, 0, dstSize, reinterpret_cast<jbyte*>(dstAddr));
2777 res.srcIpAddress.v6(srcAddr);
2778 res.dstIpAddress.v6(dstAddr);
2779 } else {
2780 // should never happen. Validated on Java size.
2781 jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
2782 "Invalid IP address length %d", srcSize);
2783 return res;
2784 }
2785
2786 uint16_t srcPort = static_cast<uint16_t>(
2787 env->GetIntField(config, env->GetFieldID(clazz, "mSrcPort", "I")));
2788 uint16_t dstPort = static_cast<uint16_t>(
2789 env->GetIntField(config, env->GetFieldID(clazz, "mDstPort", "I")));
2790
2791 res.srcPort = srcPort;
2792 res.dstPort = dstPort;
2793
2794 return res;
2795}
2796
shubang44fa1422020-01-30 11:42:59 -08002797static DemuxFilterSettings getFilterConfiguration(
shubang87788c32020-02-04 13:55:23 -08002798 JNIEnv *env, int type, int subtype, jobject filterConfigObj) {
shubang75c87082019-11-15 11:26:56 -08002799 DemuxFilterSettings filterSettings;
shubang75c87082019-11-15 11:26:56 -08002800 jobject settingsObj =
2801 env->GetObjectField(
shubang87788c32020-02-04 13:55:23 -08002802 filterConfigObj,
shubang75c87082019-11-15 11:26:56 -08002803 env->GetFieldID(
shubangd351b822020-01-22 17:29:18 -08002804 env->FindClass("android/media/tv/tuner/filter/FilterConfiguration"),
shubang75c87082019-11-15 11:26:56 -08002805 "mSettings",
shubangd351b822020-01-22 17:29:18 -08002806 "Landroid/media/tv/tuner/filter/Settings;"));
shubang44fa1422020-01-30 11:42:59 -08002807 DemuxFilterMainType mainType = static_cast<DemuxFilterMainType>(type);
2808 switch (mainType) {
2809 case DemuxFilterMainType::TS: {
2810 jclass clazz = env->FindClass("android/media/tv/tuner/filter/TsFilterConfiguration");
shubang87788c32020-02-04 13:55:23 -08002811 uint16_t tpid = static_cast<uint16_t>(
2812 env->GetIntField(filterConfigObj, env->GetFieldID(clazz, "mTpid", "I")));
shubang75c87082019-11-15 11:26:56 -08002813 DemuxTsFilterSettings tsFilterSettings {
shubang87788c32020-02-04 13:55:23 -08002814 .tpid = tpid,
shubang75c87082019-11-15 11:26:56 -08002815 };
shubang44fa1422020-01-30 11:42:59 -08002816
2817 DemuxTsFilterType tsType = static_cast<DemuxTsFilterType>(subtype);
2818 switch (tsType) {
2819 case DemuxTsFilterType::SECTION:
2820 tsFilterSettings.filterSettings.section(
2821 getFilterSectionSettings(env, settingsObj));
2822 break;
2823 case DemuxTsFilterType::AUDIO:
2824 case DemuxTsFilterType::VIDEO:
2825 tsFilterSettings.filterSettings.av(getFilterAvSettings(env, settingsObj));
2826 break;
2827 case DemuxTsFilterType::PES:
2828 tsFilterSettings.filterSettings.pesData(
2829 getFilterPesDataSettings(env, settingsObj));
2830 break;
2831 case DemuxTsFilterType::RECORD:
2832 tsFilterSettings.filterSettings.record(
2833 getFilterRecordSettings(env, settingsObj));
2834 break;
2835 default:
2836 break;
2837 }
shubang75c87082019-11-15 11:26:56 -08002838 filterSettings.ts(tsFilterSettings);
shubang44fa1422020-01-30 11:42:59 -08002839 break;
2840 }
2841 case DemuxFilterMainType::MMTP: {
shubang87788c32020-02-04 13:55:23 -08002842 jclass clazz = env->FindClass("android/media/tv/tuner/filter/MmtpFilterConfiguration");
2843 uint16_t mmtpPid = static_cast<uint16_t>(
2844 env->GetIntField(filterConfigObj, env->GetFieldID(clazz, "mMmtpPid", "I")));
2845 DemuxMmtpFilterSettings mmtpFilterSettings {
2846 .mmtpPid = mmtpPid,
2847 };
shubang44fa1422020-01-30 11:42:59 -08002848 DemuxMmtpFilterType mmtpType = static_cast<DemuxMmtpFilterType>(subtype);
2849 switch (mmtpType) {
2850 case DemuxMmtpFilterType::SECTION:
2851 mmtpFilterSettings.filterSettings.section(
2852 getFilterSectionSettings(env, settingsObj));
2853 break;
2854 case DemuxMmtpFilterType::AUDIO:
2855 case DemuxMmtpFilterType::VIDEO:
2856 mmtpFilterSettings.filterSettings.av(getFilterAvSettings(env, settingsObj));
2857 break;
2858 case DemuxMmtpFilterType::PES:
2859 mmtpFilterSettings.filterSettings.pesData(
2860 getFilterPesDataSettings(env, settingsObj));
2861 break;
2862 case DemuxMmtpFilterType::RECORD:
2863 mmtpFilterSettings.filterSettings.record(
2864 getFilterRecordSettings(env, settingsObj));
2865 break;
2866 case DemuxMmtpFilterType::DOWNLOAD:
2867 mmtpFilterSettings.filterSettings.download(
2868 getFilterDownloadSettings(env, settingsObj));
2869 break;
2870 default:
2871 break;
2872 }
2873 filterSettings.mmtp(mmtpFilterSettings);
2874 break;
2875 }
2876 case DemuxFilterMainType::IP: {
shubang87788c32020-02-04 13:55:23 -08002877 DemuxIpAddress ipAddr = getDemuxIpAddress(env, filterConfigObj);
2878
2879 DemuxIpFilterSettings ipFilterSettings {
2880 .ipAddr = ipAddr,
2881 };
shubang44fa1422020-01-30 11:42:59 -08002882 DemuxIpFilterType ipType = static_cast<DemuxIpFilterType>(subtype);
2883 switch (ipType) {
shubang87788c32020-02-04 13:55:23 -08002884 case DemuxIpFilterType::SECTION: {
shubang44fa1422020-01-30 11:42:59 -08002885 ipFilterSettings.filterSettings.section(
2886 getFilterSectionSettings(env, settingsObj));
2887 break;
shubang87788c32020-02-04 13:55:23 -08002888 }
2889 case DemuxIpFilterType::IP: {
2890 jclass clazz = env->FindClass(
2891 "android/media/tv/tuner/filter/IpFilterConfiguration");
2892 bool bPassthrough = static_cast<bool>(
2893 env->GetBooleanField(
2894 filterConfigObj, env->GetFieldID(
2895 clazz, "mPassthrough", "Z")));
2896 ipFilterSettings.filterSettings.bPassthrough(bPassthrough);
shubang44fa1422020-01-30 11:42:59 -08002897 break;
shubang87788c32020-02-04 13:55:23 -08002898 }
2899 default: {
shubang44fa1422020-01-30 11:42:59 -08002900 break;
shubang87788c32020-02-04 13:55:23 -08002901 }
shubang44fa1422020-01-30 11:42:59 -08002902 }
2903 filterSettings.ip(ipFilterSettings);
2904 break;
2905 }
2906 case DemuxFilterMainType::TLV: {
shubang87788c32020-02-04 13:55:23 -08002907 jclass clazz = env->FindClass("android/media/tv/tuner/filter/TlvFilterConfiguration");
2908 uint8_t packetType = static_cast<uint8_t>(
2909 env->GetIntField(filterConfigObj, env->GetFieldID(clazz, "mPacketType", "I")));
2910 bool isCompressedIpPacket = static_cast<bool>(
2911 env->GetBooleanField(
2912 filterConfigObj, env->GetFieldID(clazz, "mIsCompressedIpPacket", "Z")));
2913
2914 DemuxTlvFilterSettings tlvFilterSettings {
2915 .packetType = packetType,
2916 .isCompressedIpPacket = isCompressedIpPacket,
2917 };
shubang44fa1422020-01-30 11:42:59 -08002918 DemuxTlvFilterType tlvType = static_cast<DemuxTlvFilterType>(subtype);
2919 switch (tlvType) {
shubang87788c32020-02-04 13:55:23 -08002920 case DemuxTlvFilterType::SECTION: {
shubang44fa1422020-01-30 11:42:59 -08002921 tlvFilterSettings.filterSettings.section(
2922 getFilterSectionSettings(env, settingsObj));
2923 break;
shubang87788c32020-02-04 13:55:23 -08002924 }
2925 case DemuxTlvFilterType::TLV: {
2926 bool bPassthrough = static_cast<bool>(
2927 env->GetBooleanField(
2928 filterConfigObj, env->GetFieldID(
2929 clazz, "mPassthrough", "Z")));
2930 tlvFilterSettings.filterSettings.bPassthrough(bPassthrough);
shubang44fa1422020-01-30 11:42:59 -08002931 break;
shubang87788c32020-02-04 13:55:23 -08002932 }
2933 default: {
shubang44fa1422020-01-30 11:42:59 -08002934 break;
shubang87788c32020-02-04 13:55:23 -08002935 }
shubang44fa1422020-01-30 11:42:59 -08002936 }
2937 filterSettings.tlv(tlvFilterSettings);
2938 break;
2939 }
2940 case DemuxFilterMainType::ALP: {
shubang87788c32020-02-04 13:55:23 -08002941 jclass clazz = env->FindClass("android/media/tv/tuner/filter/AlpFilterConfiguration");
2942 uint8_t packetType = static_cast<uint8_t>(
2943 env->GetIntField(filterConfigObj, env->GetFieldID(clazz, "mPacketType", "I")));
2944 DemuxAlpLengthType lengthType = static_cast<DemuxAlpLengthType>(
2945 env->GetIntField(filterConfigObj, env->GetFieldID(clazz, "mLengthType", "I")));
2946 DemuxAlpFilterSettings alpFilterSettings {
2947 .packetType = packetType,
2948 .lengthType = lengthType,
2949 };
shubang44fa1422020-01-30 11:42:59 -08002950 DemuxAlpFilterType alpType = static_cast<DemuxAlpFilterType>(subtype);
2951 switch (alpType) {
2952 case DemuxAlpFilterType::SECTION:
2953 alpFilterSettings.filterSettings.section(
2954 getFilterSectionSettings(env, settingsObj));
2955 break;
2956 default:
2957 break;
2958 }
2959 filterSettings.alp(alpFilterSettings);
2960 break;
2961 }
2962 default: {
2963 break;
shubang75c87082019-11-15 11:26:56 -08002964 }
2965 }
2966 return filterSettings;
2967}
2968
shubang431e5612020-03-30 21:24:56 -07002969static jint copyData(JNIEnv *env, std::unique_ptr<MQ>& mq, EventFlag* flag, jbyteArray buffer,
2970 jlong offset, jlong size) {
shubanga06cfe52020-02-24 18:53:41 -08002971 ALOGD("copyData, size=%ld, offset=%ld", (long) size, (long) offset);
shubang964e6132019-11-26 15:05:22 -08002972
shubang431e5612020-03-30 21:24:56 -07002973 jlong available = mq->availableToRead();
shubanga06cfe52020-02-24 18:53:41 -08002974 ALOGD("copyData, available=%ld", (long) available);
shubang964e6132019-11-26 15:05:22 -08002975 size = std::min(size, available);
2976
2977 jboolean isCopy;
2978 jbyte *dst = env->GetByteArrayElements(buffer, &isCopy);
2979 ALOGD("copyData, isCopy=%d", isCopy);
2980 if (dst == nullptr) {
shubang491eaba2020-05-21 22:25:26 -07002981 jniThrowRuntimeException(env, "Failed to GetByteArrayElements");
shubang964e6132019-11-26 15:05:22 -08002982 return 0;
2983 }
2984
shubang431e5612020-03-30 21:24:56 -07002985 if (mq->read(reinterpret_cast<unsigned char*>(dst) + offset, size)) {
shubang964e6132019-11-26 15:05:22 -08002986 env->ReleaseByteArrayElements(buffer, dst, 0);
shubang431e5612020-03-30 21:24:56 -07002987 flag->wake(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_CONSUMED));
shubang964e6132019-11-26 15:05:22 -08002988 } else {
shubang491eaba2020-05-21 22:25:26 -07002989 jniThrowRuntimeException(env, "Failed to read FMQ");
shubang964e6132019-11-26 15:05:22 -08002990 env->ReleaseByteArrayElements(buffer, dst, 0);
2991 return 0;
2992 }
2993 return size;
2994}
2995
shubanga06cfe52020-02-24 18:53:41 -08002996static jint android_media_tv_Tuner_configure_filter(
shubang75c87082019-11-15 11:26:56 -08002997 JNIEnv *env, jobject filter, int type, int subtype, jobject settings) {
2998 ALOGD("configure filter type=%d, subtype=%d", type, subtype);
shubang964e6132019-11-26 15:05:22 -08002999 sp<Filter> filterSp = getFilter(env, filter);
3000 sp<IFilter> iFilterSp = filterSp->getIFilter();
3001 if (iFilterSp == NULL) {
shubang75c87082019-11-15 11:26:56 -08003002 ALOGD("Failed to configure filter: filter not found");
shubang40454db2020-03-30 16:52:29 -07003003 return (jint) Result::NOT_INITIALIZED;
shubang75c87082019-11-15 11:26:56 -08003004 }
shubang44fa1422020-01-30 11:42:59 -08003005 DemuxFilterSettings filterSettings = getFilterConfiguration(env, type, subtype, settings);
shubang964e6132019-11-26 15:05:22 -08003006 Result res = iFilterSp->configure(filterSettings);
shubanga06cfe52020-02-24 18:53:41 -08003007
3008 if (res != Result::SUCCESS) {
3009 return (jint) res;
3010 }
3011
shubang964e6132019-11-26 15:05:22 -08003012 MQDescriptorSync<uint8_t> filterMQDesc;
shubanga06cfe52020-02-24 18:53:41 -08003013 Result getQueueDescResult = Result::UNKNOWN_ERROR;
3014 if (filterSp->mFilterMQ == NULL) {
shubang964e6132019-11-26 15:05:22 -08003015 iFilterSp->getQueueDesc(
3016 [&](Result r, const MQDescriptorSync<uint8_t>& desc) {
3017 filterMQDesc = desc;
3018 getQueueDescResult = r;
3019 ALOGD("getFilterQueueDesc");
3020 });
3021 if (getQueueDescResult == Result::SUCCESS) {
shubang431e5612020-03-30 21:24:56 -07003022 filterSp->mFilterMQ = std::make_unique<MQ>(filterMQDesc, true);
shubang964e6132019-11-26 15:05:22 -08003023 EventFlag::createEventFlag(
3024 filterSp->mFilterMQ->getEventFlagWord(), &(filterSp->mFilterMQEventFlag));
3025 }
3026 }
shubanga06cfe52020-02-24 18:53:41 -08003027 return (jint) getQueueDescResult;
shubang75c87082019-11-15 11:26:56 -08003028}
3029
shubanga06cfe52020-02-24 18:53:41 -08003030static jint android_media_tv_Tuner_get_filter_id(JNIEnv* env, jobject filter) {
3031 sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter();
3032 if (iFilterSp == NULL) {
3033 ALOGD("Failed to get filter ID: filter not found");
shubang40454db2020-03-30 16:52:29 -07003034 return (int) Result::NOT_INITIALIZED;
shubanga06cfe52020-02-24 18:53:41 -08003035 }
3036 Result res;
3037 uint32_t id;
3038 iFilterSp->getId(
3039 [&](Result r, uint32_t filterId) {
3040 res = r;
3041 id = filterId;
3042 });
3043 if (res != Result::SUCCESS) {
3044 return (jint) Constant::INVALID_FILTER_ID;
3045 }
3046 return (jint) id;
shubang793e5702019-12-26 15:15:46 -08003047}
3048
shubanga06cfe52020-02-24 18:53:41 -08003049static jint android_media_tv_Tuner_set_filter_data_source(
3050 JNIEnv* env, jobject filter, jobject srcFilter) {
3051 sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter();
3052 if (iFilterSp == NULL) {
3053 ALOGD("Failed to set filter data source: filter not found");
shubang40454db2020-03-30 16:52:29 -07003054 return (jint) Result::NOT_INITIALIZED;
shubanga06cfe52020-02-24 18:53:41 -08003055 }
3056 Result r;
3057 if (srcFilter == NULL) {
3058 r = iFilterSp->setDataSource(NULL);
3059 } else {
3060 sp<IFilter> srcSp = getFilter(env, srcFilter)->getIFilter();
3061 if (iFilterSp == NULL) {
3062 ALOGD("Failed to set filter data source: src filter not found");
shubang40454db2020-03-30 16:52:29 -07003063 return (jint) Result::INVALID_ARGUMENT;
shubanga06cfe52020-02-24 18:53:41 -08003064 }
3065 r = iFilterSp->setDataSource(srcSp);
3066 }
3067 return (jint) r;
shubang793e5702019-12-26 15:15:46 -08003068}
3069
shubanga06cfe52020-02-24 18:53:41 -08003070static jint android_media_tv_Tuner_start_filter(JNIEnv *env, jobject filter) {
3071 sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter();
3072 if (iFilterSp == NULL) {
shubangd0977902019-11-07 18:58:43 -08003073 ALOGD("Failed to start filter: filter not found");
shubang40454db2020-03-30 16:52:29 -07003074 return (jint) Result::NOT_INITIALIZED;
shubangd0977902019-11-07 18:58:43 -08003075 }
shubanga06cfe52020-02-24 18:53:41 -08003076 Result r = iFilterSp->start();
3077 return (jint) r;
shubangd0977902019-11-07 18:58:43 -08003078}
3079
shubanga06cfe52020-02-24 18:53:41 -08003080static jint android_media_tv_Tuner_stop_filter(JNIEnv *env, jobject filter) {
3081 sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter();
3082 if (iFilterSp == NULL) {
shubangd0977902019-11-07 18:58:43 -08003083 ALOGD("Failed to stop filter: filter not found");
shubang40454db2020-03-30 16:52:29 -07003084 return (jint) Result::NOT_INITIALIZED;
shubangd0977902019-11-07 18:58:43 -08003085 }
shubanga06cfe52020-02-24 18:53:41 -08003086 Result r = iFilterSp->stop();
3087 return (jint) r;
shubangd0977902019-11-07 18:58:43 -08003088}
3089
shubanga06cfe52020-02-24 18:53:41 -08003090static jint android_media_tv_Tuner_flush_filter(JNIEnv *env, jobject filter) {
3091 sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter();
3092 if (iFilterSp == NULL) {
shubangd0977902019-11-07 18:58:43 -08003093 ALOGD("Failed to flush filter: filter not found");
shubang40454db2020-03-30 16:52:29 -07003094 return (jint) Result::NOT_INITIALIZED;
shubangd0977902019-11-07 18:58:43 -08003095 }
shubanga06cfe52020-02-24 18:53:41 -08003096 Result r = iFilterSp->flush();
3097 return (jint) r;
shubangd0977902019-11-07 18:58:43 -08003098}
3099
shubanga06cfe52020-02-24 18:53:41 -08003100static jint android_media_tv_Tuner_read_filter_fmq(
shubangd351b822020-01-22 17:29:18 -08003101 JNIEnv *env, jobject filter, jbyteArray buffer, jlong offset, jlong size) {
shubang964e6132019-11-26 15:05:22 -08003102 sp<Filter> filterSp = getFilter(env, filter);
3103 if (filterSp == NULL) {
shubange8cb82c2020-05-19 15:12:01 -07003104 jniThrowException(env, "java/lang/IllegalStateException",
3105 "Failed to read filter FMQ: filter not found");
3106 return 0;
shubang964e6132019-11-26 15:05:22 -08003107 }
shubang431e5612020-03-30 21:24:56 -07003108 return copyData(env, filterSp->mFilterMQ, filterSp->mFilterMQEventFlag, buffer, offset, size);
shubang964e6132019-11-26 15:05:22 -08003109}
3110
shubanga06cfe52020-02-24 18:53:41 -08003111static jint android_media_tv_Tuner_close_filter(JNIEnv *env, jobject filter) {
3112 sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter();
3113 if (iFilterSp == NULL) {
3114 ALOGD("Failed to close filter: filter not found");
shubang40454db2020-03-30 16:52:29 -07003115 return (jint) Result::NOT_INITIALIZED;
shubanga06cfe52020-02-24 18:53:41 -08003116 }
3117 Result r = iFilterSp->close();
3118 return (jint) r;
shubang793e5702019-12-26 15:15:46 -08003119}
3120
shubangf657da22020-02-05 16:27:06 -08003121static sp<TimeFilter> getTimeFilter(JNIEnv *env, jobject filter) {
3122 return (TimeFilter *)env->GetLongField(filter, gFields.timeFilterContext);
3123}
3124
shubang4347e2e2019-12-13 17:20:40 -08003125static int android_media_tv_Tuner_time_filter_set_timestamp(
shubangf657da22020-02-05 16:27:06 -08003126 JNIEnv *env, jobject filter, jlong timestamp) {
3127 sp<TimeFilter> filterSp = getTimeFilter(env, filter);
3128 if (filterSp == NULL) {
3129 ALOGD("Failed set timestamp: time filter not found");
3130 return (int) Result::INVALID_STATE;
3131 }
3132 sp<ITimeFilter> iFilterSp = filterSp->getITimeFilter();
3133 Result r = iFilterSp->setTimeStamp(static_cast<uint64_t>(timestamp));
3134 return (int) r;
shubang4347e2e2019-12-13 17:20:40 -08003135}
3136
shubangf657da22020-02-05 16:27:06 -08003137static int android_media_tv_Tuner_time_filter_clear_timestamp(JNIEnv *env, jobject filter) {
3138 sp<TimeFilter> filterSp = getTimeFilter(env, filter);
3139 if (filterSp == NULL) {
3140 ALOGD("Failed clear timestamp: time filter not found");
3141 return (int) Result::INVALID_STATE;
3142 }
3143 sp<ITimeFilter> iFilterSp = filterSp->getITimeFilter();
3144 Result r = iFilterSp->clearTimeStamp();
3145 return (int) r;
shubang4347e2e2019-12-13 17:20:40 -08003146}
3147
shubangf657da22020-02-05 16:27:06 -08003148static jobject android_media_tv_Tuner_time_filter_get_timestamp(JNIEnv *env, jobject filter) {
3149 sp<TimeFilter> filterSp = getTimeFilter(env, filter);
3150 if (filterSp == NULL) {
3151 ALOGD("Failed get timestamp: time filter not found");
3152 return NULL;
3153 }
3154
3155 sp<ITimeFilter> iFilterSp = filterSp->getITimeFilter();
3156 Result res;
3157 uint64_t timestamp;
3158 iFilterSp->getTimeStamp(
3159 [&](Result r, uint64_t t) {
3160 res = r;
3161 timestamp = t;
3162 });
3163 if (res != Result::SUCCESS) {
3164 return NULL;
3165 }
3166
3167 jclass longClazz = env->FindClass("java/lang/Long");
3168 jmethodID longInit = env->GetMethodID(longClazz, "<init>", "(J)V");
3169
3170 jobject longObj = env->NewObject(longClazz, longInit, static_cast<jlong>(timestamp));
3171 return longObj;
shubang4347e2e2019-12-13 17:20:40 -08003172}
3173
shubangf657da22020-02-05 16:27:06 -08003174static jobject android_media_tv_Tuner_time_filter_get_source_time(JNIEnv *env, jobject filter) {
3175 sp<TimeFilter> filterSp = getTimeFilter(env, filter);
3176 if (filterSp == NULL) {
3177 ALOGD("Failed get source time: time filter not found");
3178 return NULL;
3179 }
3180
3181 sp<ITimeFilter> iFilterSp = filterSp->getITimeFilter();
3182 Result res;
3183 uint64_t timestamp;
3184 iFilterSp->getSourceTime(
3185 [&](Result r, uint64_t t) {
3186 res = r;
3187 timestamp = t;
3188 });
3189 if (res != Result::SUCCESS) {
3190 return NULL;
3191 }
3192
3193 jclass longClazz = env->FindClass("java/lang/Long");
3194 jmethodID longInit = env->GetMethodID(longClazz, "<init>", "(J)V");
3195
3196 jobject longObj = env->NewObject(longClazz, longInit, static_cast<jlong>(timestamp));
3197 return longObj;
shubang4347e2e2019-12-13 17:20:40 -08003198}
3199
shubangf657da22020-02-05 16:27:06 -08003200static int android_media_tv_Tuner_time_filter_close(JNIEnv *env, jobject filter) {
3201 sp<TimeFilter> filterSp = getTimeFilter(env, filter);
3202 if (filterSp == NULL) {
3203 ALOGD("Failed close time filter: time filter not found");
3204 return (int) Result::INVALID_STATE;
3205 }
3206
3207 Result r = filterSp->getITimeFilter()->close();
3208 if (r == Result::SUCCESS) {
3209 filterSp->decStrong(filter);
3210 env->SetLongField(filter, gFields.timeFilterContext, 0);
3211 }
3212 return (int) r;
shubang4347e2e2019-12-13 17:20:40 -08003213}
3214
shubangf159a832020-03-18 21:57:49 -07003215static jobject android_media_tv_Tuner_open_descrambler(JNIEnv *env, jobject thiz, jint) {
shubang13f15e02019-11-04 17:51:02 -08003216 sp<JTuner> tuner = getTuner(env, thiz);
3217 return tuner->openDescrambler();
3218}
3219
shubang40454db2020-03-30 16:52:29 -07003220static jint android_media_tv_Tuner_descrambler_add_pid(
shubang13f15e02019-11-04 17:51:02 -08003221 JNIEnv *env, jobject descrambler, jint pidType, jint pid, jobject filter) {
3222 sp<IDescrambler> descramblerSp = getDescrambler(env, descrambler);
3223 if (descramblerSp == NULL) {
shubang40454db2020-03-30 16:52:29 -07003224 return (jint) Result::NOT_INITIALIZED;
shubang13f15e02019-11-04 17:51:02 -08003225 }
shubanga06cfe52020-02-24 18:53:41 -08003226 sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter();
3227 Result result = descramblerSp->addPid(getDemuxPid((int)pidType, (int)pid), iFilterSp);
shubang40454db2020-03-30 16:52:29 -07003228 return (jint) result;
shubang13f15e02019-11-04 17:51:02 -08003229}
3230
shubang40454db2020-03-30 16:52:29 -07003231static jint android_media_tv_Tuner_descrambler_remove_pid(
shubang13f15e02019-11-04 17:51:02 -08003232 JNIEnv *env, jobject descrambler, jint pidType, jint pid, jobject filter) {
3233 sp<IDescrambler> descramblerSp = getDescrambler(env, descrambler);
3234 if (descramblerSp == NULL) {
shubang40454db2020-03-30 16:52:29 -07003235 return (jint) Result::NOT_INITIALIZED;
shubang13f15e02019-11-04 17:51:02 -08003236 }
shubanga06cfe52020-02-24 18:53:41 -08003237 sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter();
3238 Result result = descramblerSp->removePid(getDemuxPid((int)pidType, (int)pid), iFilterSp);
shubang40454db2020-03-30 16:52:29 -07003239 return (jint) result;
shubang99c89922019-12-17 17:33:15 -08003240}
3241
shubang40454db2020-03-30 16:52:29 -07003242static jint android_media_tv_Tuner_descrambler_set_key_token(
3243 JNIEnv* env, jobject descrambler, jbyteArray keyToken) {
3244 sp<IDescrambler> descramblerSp = getDescrambler(env, descrambler);
3245 if (descramblerSp == NULL) {
3246 return (jint) Result::NOT_INITIALIZED;
3247 }
3248 int size = env->GetArrayLength(keyToken);
3249 std::vector<uint8_t> v(size);
3250 env->GetByteArrayRegion(keyToken, 0, size, reinterpret_cast<jbyte*>(&v[0]));
3251 Result result = descramblerSp->setKeyToken(v);
3252 return (jint) result;
shubang99c89922019-12-17 17:33:15 -08003253}
3254
shubang40454db2020-03-30 16:52:29 -07003255static jint android_media_tv_Tuner_close_descrambler(JNIEnv* env, jobject descrambler) {
3256 sp<IDescrambler> descramblerSp = getDescrambler(env, descrambler);
3257 if (descramblerSp == NULL) {
3258 return (jint) Result::NOT_INITIALIZED;
3259 }
3260 Result r = descramblerSp->close();
3261 if (r == Result::SUCCESS) {
3262 descramblerSp->decStrong(descrambler);
3263 }
3264 return (jint) r;
shubang13f15e02019-11-04 17:51:02 -08003265}
3266
shubangd351b822020-01-22 17:29:18 -08003267static jobject android_media_tv_Tuner_open_dvr_recorder(
shubang5637a662020-02-27 18:06:21 -08003268 JNIEnv* env, jobject thiz, jlong bufferSize) {
3269 sp<JTuner> tuner = getTuner(env, thiz);
3270 return tuner->openDvr(DvrType::RECORD, bufferSize);
shubangd351b822020-01-22 17:29:18 -08003271}
3272
3273static jobject android_media_tv_Tuner_open_dvr_playback(
shubang5637a662020-02-27 18:06:21 -08003274 JNIEnv* env, jobject thiz, jlong bufferSize) {
3275 sp<JTuner> tuner = getTuner(env, thiz);
3276 return tuner->openDvr(DvrType::PLAYBACK, bufferSize);
shubang4a0eddf2019-11-08 17:10:18 -08003277}
3278
shubangc4b45702020-03-23 18:48:12 -07003279static jobject android_media_tv_Tuner_get_demux_caps(JNIEnv* env, jobject thiz) {
3280 sp<JTuner> tuner = getTuner(env, thiz);
3281 return tuner->getDemuxCaps();
shubang34258932019-12-27 13:59:23 -08003282}
3283
shubang66cc3aa2020-04-06 17:10:01 -07003284static jint android_media_tv_Tuner_open_demux(JNIEnv* env, jobject thiz, jint /* handle */) {
3285 sp<JTuner> tuner = getTuner(env, thiz);
3286 return (jint) tuner->openDemux();
3287}
3288
shubang2f9cab32020-04-10 18:00:56 -07003289static jint android_media_tv_Tuner_close_tuner(JNIEnv* env, jobject thiz) {
3290 sp<JTuner> tuner = getTuner(env, thiz);
3291 return (jint) tuner->close();
3292}
3293
shubangb3bfffe2020-03-26 17:44:31 -07003294static jint android_media_tv_Tuner_close_demux(JNIEnv* env, jobject thiz, jint /* handle */) {
3295 sp<JTuner> tuner = getTuner(env, thiz);
3296 return tuner->closeDemux();
3297}
3298
3299static jint android_media_tv_Tuner_close_frontend(JNIEnv* env, jobject thiz, jint /* handle */) {
3300 sp<JTuner> tuner = getTuner(env, thiz);
3301 return tuner->closeFrontend();
3302}
3303
shubang431e5612020-03-30 21:24:56 -07003304static jint android_media_tv_Tuner_attach_filter(JNIEnv *env, jobject dvr, jobject filter) {
shubangba21a7f2019-12-05 16:58:55 -08003305 sp<Dvr> dvrSp = getDvr(env, dvr);
shubang431e5612020-03-30 21:24:56 -07003306 if (dvrSp == NULL) {
3307 return (jint) Result::NOT_INITIALIZED;
3308 }
3309 sp<Filter> filterSp = getFilter(env, filter);
3310 if (filterSp == NULL) {
3311 return (jint) Result::INVALID_ARGUMENT;
3312 }
shubangba21a7f2019-12-05 16:58:55 -08003313 sp<IDvr> iDvrSp = dvrSp->getIDvr();
shubang431e5612020-03-30 21:24:56 -07003314 sp<IFilter> iFilterSp = filterSp->getIFilter();
3315 Result result = iDvrSp->attachFilter(iFilterSp);
3316 return (jint) result;
3317}
3318
3319static jint android_media_tv_Tuner_detach_filter(JNIEnv *env, jobject dvr, jobject filter) {
3320 sp<Dvr> dvrSp = getDvr(env, dvr);
3321 if (dvrSp == NULL) {
3322 return (jint) Result::NOT_INITIALIZED;
3323 }
3324 sp<Filter> filterSp = getFilter(env, filter);
3325 if (filterSp == NULL) {
3326 return (jint) Result::INVALID_ARGUMENT;
3327 }
3328 sp<IDvr> iDvrSp = dvrSp->getIDvr();
3329 sp<IFilter> iFilterSp = filterSp->getIFilter();
3330 Result result = iDvrSp->detachFilter(iFilterSp);
3331 return (jint) result;
3332}
3333
3334static jint android_media_tv_Tuner_configure_dvr(JNIEnv *env, jobject dvr, jobject settings) {
3335 sp<Dvr> dvrSp = getDvr(env, dvr);
shubang030afb52019-11-27 16:09:02 -08003336 if (dvrSp == NULL) {
3337 ALOGD("Failed to configure dvr: dvr not found");
shubang431e5612020-03-30 21:24:56 -07003338 return (int)Result::NOT_INITIALIZED;
shubang030afb52019-11-27 16:09:02 -08003339 }
shubang431e5612020-03-30 21:24:56 -07003340 sp<IDvr> iDvrSp = dvrSp->getIDvr();
shubange8cb82c2020-05-19 15:12:01 -07003341 bool isRecorder =
3342 env->IsInstanceOf(dvr, env->FindClass("android/media/tv/tuner/dvr/DvrRecorder"));
3343 Result result = iDvrSp->configure(getDvrSettings(env, settings, isRecorder));
shubang431e5612020-03-30 21:24:56 -07003344 if (result != Result::SUCCESS) {
3345 return (jint) result;
shubangba21a7f2019-12-05 16:58:55 -08003346 }
shubang431e5612020-03-30 21:24:56 -07003347 MQDescriptorSync<uint8_t> dvrMQDesc;
3348 Result getQueueDescResult = Result::UNKNOWN_ERROR;
3349 iDvrSp->getQueueDesc(
3350 [&](Result r, const MQDescriptorSync<uint8_t>& desc) {
3351 dvrMQDesc = desc;
3352 getQueueDescResult = r;
3353 ALOGD("getDvrQueueDesc");
3354 });
3355 if (getQueueDescResult == Result::SUCCESS) {
3356 dvrSp->mDvrMQ = std::make_unique<MQ>(dvrMQDesc, true);
3357 EventFlag::createEventFlag(
3358 dvrSp->mDvrMQ->getEventFlagWord(), &(dvrSp->mDvrMQEventFlag));
3359 }
3360 return (jint) getQueueDescResult;
shubang030afb52019-11-27 16:09:02 -08003361}
3362
shubang431e5612020-03-30 21:24:56 -07003363static jint android_media_tv_Tuner_start_dvr(JNIEnv *env, jobject dvr) {
3364 sp<Dvr> dvrSp = getDvr(env, dvr);
shubang4a0eddf2019-11-08 17:10:18 -08003365 if (dvrSp == NULL) {
3366 ALOGD("Failed to start dvr: dvr not found");
shubang431e5612020-03-30 21:24:56 -07003367 return (jint) Result::NOT_INITIALIZED;
shubang4a0eddf2019-11-08 17:10:18 -08003368 }
shubang431e5612020-03-30 21:24:56 -07003369 sp<IDvr> iDvrSp = dvrSp->getIDvr();
3370 Result result = iDvrSp->start();
3371 return (jint) result;
shubang4a0eddf2019-11-08 17:10:18 -08003372}
3373
shubang431e5612020-03-30 21:24:56 -07003374static jint android_media_tv_Tuner_stop_dvr(JNIEnv *env, jobject dvr) {
3375 sp<Dvr> dvrSp = getDvr(env, dvr);
shubang4a0eddf2019-11-08 17:10:18 -08003376 if (dvrSp == NULL) {
3377 ALOGD("Failed to stop dvr: dvr not found");
shubang431e5612020-03-30 21:24:56 -07003378 return (jint) Result::NOT_INITIALIZED;
shubang4a0eddf2019-11-08 17:10:18 -08003379 }
shubang431e5612020-03-30 21:24:56 -07003380 sp<IDvr> iDvrSp = dvrSp->getIDvr();
3381 Result result = iDvrSp->stop();
3382 return (jint) result;
shubang4a0eddf2019-11-08 17:10:18 -08003383}
3384
shubang431e5612020-03-30 21:24:56 -07003385static jint android_media_tv_Tuner_flush_dvr(JNIEnv *env, jobject dvr) {
3386 sp<Dvr> dvrSp = getDvr(env, dvr);
shubang4a0eddf2019-11-08 17:10:18 -08003387 if (dvrSp == NULL) {
3388 ALOGD("Failed to flush dvr: dvr not found");
shubang431e5612020-03-30 21:24:56 -07003389 return (jint) Result::NOT_INITIALIZED;
shubang4a0eddf2019-11-08 17:10:18 -08003390 }
shubang431e5612020-03-30 21:24:56 -07003391 sp<IDvr> iDvrSp = dvrSp->getIDvr();
3392 Result result = iDvrSp->flush();
3393 return (jint) result;
shubang793e5702019-12-26 15:15:46 -08003394}
3395
shubang431e5612020-03-30 21:24:56 -07003396static jint android_media_tv_Tuner_close_dvr(JNIEnv* env, jobject dvr) {
3397 sp<Dvr> dvrSp = getDvr(env, dvr);
3398 if (dvrSp == NULL) {
3399 ALOGD("Failed to close dvr: dvr not found");
3400 return (jint) Result::NOT_INITIALIZED;
3401 }
3402 return dvrSp->close();
shubang4a0eddf2019-11-08 17:10:18 -08003403}
3404
shubang1c1144e2020-03-03 18:00:17 -08003405static sp<Lnb> getLnb(JNIEnv *env, jobject lnb) {
3406 return (Lnb *)env->GetLongField(lnb, gFields.lnbContext);
shubang847fc0a2019-12-26 16:54:10 -08003407}
3408
shubang1c1144e2020-03-03 18:00:17 -08003409static jint android_media_tv_Tuner_lnb_set_voltage(JNIEnv* env, jobject lnb, jint voltage) {
3410 sp<ILnb> iLnbSp = getLnb(env, lnb)->getILnb();
3411 Result r = iLnbSp->setVoltage(static_cast<LnbVoltage>(voltage));
3412 return (jint) r;
shubang847fc0a2019-12-26 16:54:10 -08003413}
3414
shubang1c1144e2020-03-03 18:00:17 -08003415static int android_media_tv_Tuner_lnb_set_tone(JNIEnv* env, jobject lnb, jint tone) {
3416 sp<ILnb> iLnbSp = getLnb(env, lnb)->getILnb();
3417 Result r = iLnbSp->setTone(static_cast<LnbTone>(tone));
3418 return (jint) r;
shubang847fc0a2019-12-26 16:54:10 -08003419}
3420
shubang1c1144e2020-03-03 18:00:17 -08003421static int android_media_tv_Tuner_lnb_set_position(JNIEnv* env, jobject lnb, jint position) {
3422 sp<ILnb> iLnbSp = getLnb(env, lnb)->getILnb();
3423 Result r = iLnbSp->setSatellitePosition(static_cast<LnbPosition>(position));
3424 return (jint) r;
3425}
3426
3427static int android_media_tv_Tuner_lnb_send_diseqc_msg(JNIEnv* env, jobject lnb, jbyteArray msg) {
3428 sp<ILnb> iLnbSp = getLnb(env, lnb)->getILnb();
3429 int size = env->GetArrayLength(msg);
3430 std::vector<uint8_t> v(size);
3431 env->GetByteArrayRegion(msg, 0, size, reinterpret_cast<jbyte*>(&v[0]));
3432 Result r = iLnbSp->sendDiseqcMessage(v);
3433 return (jint) r;
shubang847fc0a2019-12-26 16:54:10 -08003434}
3435
shubangd295be02020-03-27 17:08:11 -07003436static int android_media_tv_Tuner_close_lnb(JNIEnv* env, jobject lnb) {
3437 sp<Lnb> lnbSp = getLnb(env, lnb);
3438 Result r = lnbSp->getILnb()->close();
3439 if (r == Result::SUCCESS) {
3440 lnbSp->decStrong(lnb);
3441 env->SetLongField(lnb, gFields.lnbContext, 0);
3442 }
3443 return (jint) r;
shubang847fc0a2019-12-26 16:54:10 -08003444}
3445
shubange8cb82c2020-05-19 15:12:01 -07003446static void android_media_tv_Tuner_dvr_set_fd(JNIEnv *env, jobject dvr, jint fd) {
shubangba21a7f2019-12-05 16:58:55 -08003447 sp<Dvr> dvrSp = getDvr(env, dvr);
3448 if (dvrSp == NULL) {
3449 ALOGD("Failed to set FD for dvr: dvr not found");
3450 }
shubange8cb82c2020-05-19 15:12:01 -07003451 dvrSp->mFd = (int) fd;
shubangba21a7f2019-12-05 16:58:55 -08003452 ALOGD("set fd = %d", dvrSp->mFd);
3453}
3454
shubangd351b822020-01-22 17:29:18 -08003455static jlong android_media_tv_Tuner_read_dvr(JNIEnv *env, jobject dvr, jlong size) {
shubangba21a7f2019-12-05 16:58:55 -08003456 sp<Dvr> dvrSp = getDvr(env, dvr);
3457 if (dvrSp == NULL) {
shubange8cb82c2020-05-19 15:12:01 -07003458 jniThrowException(env, "java/lang/IllegalStateException",
3459 "Failed to read dvr: dvr not found");
3460 return 0;
shubangba21a7f2019-12-05 16:58:55 -08003461 }
3462
shubangd351b822020-01-22 17:29:18 -08003463 long available = dvrSp->mDvrMQ->availableToWrite();
3464 long write = std::min((long) size, available);
shubangba21a7f2019-12-05 16:58:55 -08003465
shubang431e5612020-03-30 21:24:56 -07003466 MQ::MemTransaction tx;
shubangd351b822020-01-22 17:29:18 -08003467 long ret = 0;
shubangba21a7f2019-12-05 16:58:55 -08003468 if (dvrSp->mDvrMQ->beginWrite(write, &tx)) {
3469 auto first = tx.getFirstRegion();
3470 auto data = first.getAddress();
shubangd351b822020-01-22 17:29:18 -08003471 long length = first.getLength();
3472 long firstToWrite = std::min(length, write);
shubangba21a7f2019-12-05 16:58:55 -08003473 ret = read(dvrSp->mFd, data, firstToWrite);
shubange8cb82c2020-05-19 15:12:01 -07003474
3475 if (ret < 0) {
3476 ALOGE("[DVR] Failed to read from FD: %s", strerror(errno));
3477 jniThrowRuntimeException(env, strerror(errno));
3478 return 0;
3479 }
shubangba21a7f2019-12-05 16:58:55 -08003480 if (ret < firstToWrite) {
shubangd351b822020-01-22 17:29:18 -08003481 ALOGW("[DVR] file to MQ, first region: %ld bytes to write, but %ld bytes written",
shubangba21a7f2019-12-05 16:58:55 -08003482 firstToWrite, ret);
3483 } else if (firstToWrite < write) {
shubangd351b822020-01-22 17:29:18 -08003484 ALOGD("[DVR] write second region: %ld bytes written, %ld bytes in total", ret, write);
shubangba21a7f2019-12-05 16:58:55 -08003485 auto second = tx.getSecondRegion();
3486 data = second.getAddress();
3487 length = second.getLength();
3488 int secondToWrite = std::min(length, write - firstToWrite);
3489 ret += read(dvrSp->mFd, data, secondToWrite);
3490 }
shubangd351b822020-01-22 17:29:18 -08003491 ALOGD("[DVR] file to MQ: %ld bytes need to be written, %ld bytes written", write, ret);
shubangba21a7f2019-12-05 16:58:55 -08003492 if (!dvrSp->mDvrMQ->commitWrite(ret)) {
3493 ALOGE("[DVR] Error: failed to commit write!");
shubange8cb82c2020-05-19 15:12:01 -07003494 return 0;
shubangba21a7f2019-12-05 16:58:55 -08003495 }
3496
3497 } else {
3498 ALOGE("dvrMq.beginWrite failed");
3499 }
shubangd351b822020-01-22 17:29:18 -08003500 return (jlong) ret;
shubangba21a7f2019-12-05 16:58:55 -08003501}
3502
shubangd351b822020-01-22 17:29:18 -08003503static jlong android_media_tv_Tuner_read_dvr_from_array(
shubang431e5612020-03-30 21:24:56 -07003504 JNIEnv* env, jobject dvr, jbyteArray buffer, jlong offset, jlong size) {
3505 sp<Dvr> dvrSp = getDvr(env, dvr);
3506 if (dvrSp == NULL) {
3507 ALOGW("Failed to read dvr: dvr not found");
3508 return 0;
3509 }
3510 if (dvrSp->mDvrMQ == NULL) {
3511 ALOGW("Failed to read dvr: dvr not configured");
3512 return 0;
3513 }
3514
3515 jlong available = dvrSp->mDvrMQ->availableToWrite();
3516 size = std::min(size, available);
3517
3518 jboolean isCopy;
3519 jbyte *src = env->GetByteArrayElements(buffer, &isCopy);
3520 if (src == nullptr) {
3521 ALOGD("Failed to GetByteArrayElements");
3522 return 0;
3523 }
3524
3525 if (dvrSp->mDvrMQ->write(reinterpret_cast<unsigned char*>(src) + offset, size)) {
3526 env->ReleaseByteArrayElements(buffer, src, 0);
3527 dvrSp->mDvrMQEventFlag->wake(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_CONSUMED));
3528 } else {
3529 ALOGD("Failed to write FMQ");
3530 env->ReleaseByteArrayElements(buffer, src, 0);
3531 return 0;
3532 }
3533 return size;
shubangba21a7f2019-12-05 16:58:55 -08003534}
3535
shubangd351b822020-01-22 17:29:18 -08003536static jlong android_media_tv_Tuner_write_dvr(JNIEnv *env, jobject dvr, jlong size) {
shubang5f4ea352019-12-09 15:12:10 -08003537 sp<Dvr> dvrSp = getDvr(env, dvr);
3538 if (dvrSp == NULL) {
shubange8cb82c2020-05-19 15:12:01 -07003539 jniThrowException(env, "java/lang/IllegalStateException",
3540 "Failed to write dvr: dvr not found");
shubang5f4ea352019-12-09 15:12:10 -08003541 return 0;
3542 }
3543
3544 if (dvrSp->mDvrMQ == NULL) {
shubange8cb82c2020-05-19 15:12:01 -07003545 jniThrowException(env, "java/lang/IllegalStateException",
3546 "Failed to write dvr: dvr not configured");
shubang5f4ea352019-12-09 15:12:10 -08003547 return 0;
3548 }
3549
shubang431e5612020-03-30 21:24:56 -07003550 MQ& dvrMq = dvrSp->getDvrMQ();
shubang5f4ea352019-12-09 15:12:10 -08003551
shubangd351b822020-01-22 17:29:18 -08003552 long available = dvrMq.availableToRead();
3553 long toRead = std::min((long) size, available);
shubang5f4ea352019-12-09 15:12:10 -08003554
shubangd351b822020-01-22 17:29:18 -08003555 long ret = 0;
shubang431e5612020-03-30 21:24:56 -07003556 MQ::MemTransaction tx;
shubang5f4ea352019-12-09 15:12:10 -08003557 if (dvrMq.beginRead(toRead, &tx)) {
3558 auto first = tx.getFirstRegion();
3559 auto data = first.getAddress();
shubangd351b822020-01-22 17:29:18 -08003560 long length = first.getLength();
3561 long firstToRead = std::min(length, toRead);
shubang5f4ea352019-12-09 15:12:10 -08003562 ret = write(dvrSp->mFd, data, firstToRead);
shubange8cb82c2020-05-19 15:12:01 -07003563
3564 if (ret < 0) {
3565 ALOGE("[DVR] Failed to write to FD: %s", strerror(errno));
3566 jniThrowRuntimeException(env, strerror(errno));
3567 return 0;
3568 }
shubang5f4ea352019-12-09 15:12:10 -08003569 if (ret < firstToRead) {
shubangd351b822020-01-22 17:29:18 -08003570 ALOGW("[DVR] MQ to file: %ld bytes read, but %ld bytes written", firstToRead, ret);
shubang5f4ea352019-12-09 15:12:10 -08003571 } else if (firstToRead < toRead) {
shubangd351b822020-01-22 17:29:18 -08003572 ALOGD("[DVR] read second region: %ld bytes read, %ld bytes in total", ret, toRead);
shubang5f4ea352019-12-09 15:12:10 -08003573 auto second = tx.getSecondRegion();
3574 data = second.getAddress();
3575 length = second.getLength();
3576 int secondToRead = toRead - firstToRead;
3577 ret += write(dvrSp->mFd, data, secondToRead);
3578 }
shubangd351b822020-01-22 17:29:18 -08003579 ALOGD("[DVR] MQ to file: %ld bytes to be read, %ld bytes written", toRead, ret);
shubang5f4ea352019-12-09 15:12:10 -08003580 if (!dvrMq.commitRead(ret)) {
3581 ALOGE("[DVR] Error: failed to commit read!");
shubange8cb82c2020-05-19 15:12:01 -07003582 return 0;
shubang5f4ea352019-12-09 15:12:10 -08003583 }
3584
3585 } else {
3586 ALOGE("dvrMq.beginRead failed");
3587 }
3588
shubangd351b822020-01-22 17:29:18 -08003589 return (jlong) ret;
shubang5f4ea352019-12-09 15:12:10 -08003590}
3591
shubangd351b822020-01-22 17:29:18 -08003592static jlong android_media_tv_Tuner_write_dvr_to_array(
shubang431e5612020-03-30 21:24:56 -07003593 JNIEnv *env, jobject dvr, jbyteArray buffer, jlong offset, jlong size) {
3594 sp<Dvr> dvrSp = getDvr(env, dvr);
3595 if (dvrSp == NULL) {
3596 ALOGW("Failed to write dvr: dvr not found");
3597 return 0;
3598 }
3599 if (dvrSp->mDvrMQ == NULL) {
3600 ALOGW("Failed to write dvr: dvr not configured");
3601 return 0;
3602 }
3603 return copyData(env, dvrSp->mDvrMQ, dvrSp->mDvrMQEventFlag, buffer, offset, size);
shubang5f4ea352019-12-09 15:12:10 -08003604}
shubangba21a7f2019-12-05 16:58:55 -08003605
shubang3aef4fe2020-04-01 16:51:04 -07003606static sp<MediaEvent> getMediaEventSp(JNIEnv *env, jobject mediaEventObj) {
3607 return (MediaEvent *)env->GetLongField(mediaEventObj, gFields.mediaEventContext);
3608}
3609
3610static jobject android_media_tv_Tuner_media_event_get_linear_block(
3611 JNIEnv* env, jobject mediaEventObj) {
3612 sp<MediaEvent> mediaEventSp = getMediaEventSp(env, mediaEventObj);
3613 if (mediaEventSp == NULL) {
3614 ALOGD("Failed get MediaEvent");
3615 return NULL;
3616 }
3617
3618 return mediaEventSp->getLinearBlock();
3619}
3620
3621static jobject android_media_tv_Tuner_media_event_get_audio_handle(
3622 JNIEnv* env, jobject mediaEventObj) {
3623 sp<MediaEvent> mediaEventSp = getMediaEventSp(env, mediaEventObj);
3624 if (mediaEventSp == NULL) {
3625 ALOGD("Failed get MediaEvent");
3626 return NULL;
3627 }
3628
3629 android::Mutex::Autolock autoLock(mediaEventSp->mLock);
3630 uint64_t audioHandle = mediaEventSp->getAudioHandle();
3631 jclass longClazz = env->FindClass("java/lang/Long");
3632 jmethodID longInit = env->GetMethodID(longClazz, "<init>", "(J)V");
3633
3634 jobject longObj = env->NewObject(longClazz, longInit, static_cast<jlong>(audioHandle));
3635 return longObj;
3636}
3637
3638static void android_media_tv_Tuner_media_event_finalize(JNIEnv* env, jobject mediaEventObj) {
3639 sp<MediaEvent> mediaEventSp = getMediaEventSp(env, mediaEventObj);
3640 if (mediaEventSp == NULL) {
3641 ALOGD("Failed get MediaEvent");
3642 return;
3643 }
3644
3645 android::Mutex::Autolock autoLock(mediaEventSp->mLock);
3646 mediaEventSp->mAvHandleRefCnt--;
3647 mediaEventSp->finalize();
3648
3649 mediaEventSp->decStrong(mediaEventObj);
3650}
3651
shubangd0977902019-11-07 18:58:43 -08003652static const JNINativeMethod gTunerMethods[] = {
shubang8ab43b12019-10-18 15:55:55 -07003653 { "nativeInit", "()V", (void *)android_media_tv_Tuner_native_init },
3654 { "nativeSetup", "()V", (void *)android_media_tv_Tuner_native_setup },
shubang7e849b02019-10-18 19:36:25 -07003655 { "nativeGetFrontendIds", "()Ljava/util/List;",
3656 (void *)android_media_tv_Tuner_get_frontend_ids },
shubangc18cc102020-03-12 16:28:45 -07003657 { "nativeOpenFrontendByHandle", "(I)Landroid/media/tv/tuner/Tuner$Frontend;",
3658 (void *)android_media_tv_Tuner_open_frontend_by_handle },
shubang2f9cab32020-04-10 18:00:56 -07003659 { "nativeCloseFrontendByHandle", "(I)I",
3660 (void *)android_media_tv_Tuner_close_frontend_by_handle },
shubangd351b822020-01-22 17:29:18 -08003661 { "nativeTune", "(ILandroid/media/tv/tuner/frontend/FrontendSettings;)I",
shubang74bfd482019-10-29 19:10:22 -07003662 (void *)android_media_tv_Tuner_tune },
shubange65b6862019-12-17 15:43:35 -08003663 { "nativeStopTune", "()I", (void *)android_media_tv_Tuner_stop_tune },
shubangd351b822020-01-22 17:29:18 -08003664 { "nativeScan", "(ILandroid/media/tv/tuner/frontend/FrontendSettings;I)I",
shubangd5b845f2019-12-11 15:29:09 -08003665 (void *)android_media_tv_Tuner_scan },
shubang793e5702019-12-26 15:15:46 -08003666 { "nativeStopScan", "()I", (void *)android_media_tv_Tuner_stop_scan },
shubange65b6862019-12-17 15:43:35 -08003667 { "nativeSetLnb", "(I)I", (void *)android_media_tv_Tuner_set_lnb },
3668 { "nativeSetLna", "(Z)I", (void *)android_media_tv_Tuner_set_lna },
shubangd351b822020-01-22 17:29:18 -08003669 { "nativeGetFrontendStatus", "([I)Landroid/media/tv/tuner/frontend/FrontendStatus;",
shubang1512ec12019-12-23 18:22:42 -08003670 (void *)android_media_tv_Tuner_get_frontend_status },
shubangbee73462020-02-07 17:48:02 -08003671 { "nativeGetAvSyncHwId", "(Landroid/media/tv/tuner/filter/Filter;)Ljava/lang/Integer;",
3672 (void *)android_media_tv_Tuner_get_av_sync_hw_id },
3673 { "nativeGetAvSyncTime", "(I)Ljava/lang/Long;",
3674 (void *)android_media_tv_Tuner_get_av_sync_time },
shubang7343fee2019-12-27 12:02:08 -08003675 { "nativeConnectCiCam", "(I)I", (void *)android_media_tv_Tuner_connect_cicam },
3676 { "nativeDisconnectCiCam", "()I", (void *)android_media_tv_Tuner_disconnect_cicam },
shubangdeb067c2020-01-27 13:21:55 -08003677 { "nativeGetFrontendInfo", "(I)Landroid/media/tv/tuner/frontend/FrontendInfo;",
shubang95c1f752019-12-27 16:29:48 -08003678 (void *)android_media_tv_Tuner_get_frontend_info },
shubangdeb067c2020-01-27 13:21:55 -08003679 { "nativeOpenFilter", "(IIJ)Landroid/media/tv/tuner/filter/Filter;",
shubang6f473d62019-11-01 15:42:21 -07003680 (void *)android_media_tv_Tuner_open_filter },
shubangdeb067c2020-01-27 13:21:55 -08003681 { "nativeOpenTimeFilter", "()Landroid/media/tv/tuner/filter/TimeFilter;",
shubang4347e2e2019-12-13 17:20:40 -08003682 (void *)android_media_tv_Tuner_open_time_filter },
shubang0dc83942020-04-02 17:19:31 -07003683 { "nativeGetLnbIds", "()[I", (void *)android_media_tv_Tuner_get_lnb_ids },
shubangc18cc102020-03-12 16:28:45 -07003684 { "nativeOpenLnbByHandle", "(I)Landroid/media/tv/tuner/Lnb;",
3685 (void *)android_media_tv_Tuner_open_lnb_by_handle },
shubang757602f2020-03-06 15:23:41 -08003686 { "nativeOpenLnbByName", "(Ljava/lang/String;)Landroid/media/tv/tuner/Lnb;",
3687 (void *)android_media_tv_Tuner_open_lnb_by_name },
shubangf159a832020-03-18 21:57:49 -07003688 { "nativeOpenDescramblerByHandle", "(I)Landroid/media/tv/tuner/Descrambler;",
shubang13f15e02019-11-04 17:51:02 -08003689 (void *)android_media_tv_Tuner_open_descrambler },
shubangd351b822020-01-22 17:29:18 -08003690 { "nativeOpenDvrRecorder", "(J)Landroid/media/tv/tuner/dvr/DvrRecorder;",
3691 (void *)android_media_tv_Tuner_open_dvr_recorder },
3692 { "nativeOpenDvrPlayback", "(J)Landroid/media/tv/tuner/dvr/DvrPlayback;",
3693 (void *)android_media_tv_Tuner_open_dvr_playback },
shubang34258932019-12-27 13:59:23 -08003694 { "nativeGetDemuxCapabilities", "()Landroid/media/tv/tuner/DemuxCapabilities;",
3695 (void *)android_media_tv_Tuner_get_demux_caps },
shubang66cc3aa2020-04-06 17:10:01 -07003696 { "nativeOpenDemuxByhandle", "(I)I", (void *)android_media_tv_Tuner_open_demux },
shubangb3bfffe2020-03-26 17:44:31 -07003697 { "nativeClose", "()I", (void *)android_media_tv_Tuner_close_tuner },
3698 { "nativeCloseFrontend", "(I)I", (void *)android_media_tv_Tuner_close_frontend },
3699 { "nativeCloseDemux", "(I)I", (void *)android_media_tv_Tuner_close_demux },
shubang8ab43b12019-10-18 15:55:55 -07003700};
3701
shubangd0977902019-11-07 18:58:43 -08003702static const JNINativeMethod gFilterMethods[] = {
shubangd351b822020-01-22 17:29:18 -08003703 { "nativeConfigureFilter", "(IILandroid/media/tv/tuner/filter/FilterConfiguration;)I",
shubang75c87082019-11-15 11:26:56 -08003704 (void *)android_media_tv_Tuner_configure_filter },
shubang793e5702019-12-26 15:15:46 -08003705 { "nativeGetId", "()I", (void *)android_media_tv_Tuner_get_filter_id },
shubangd351b822020-01-22 17:29:18 -08003706 { "nativeSetDataSource", "(Landroid/media/tv/tuner/filter/Filter;)I",
shubang793e5702019-12-26 15:15:46 -08003707 (void *)android_media_tv_Tuner_set_filter_data_source },
3708 { "nativeStartFilter", "()I", (void *)android_media_tv_Tuner_start_filter },
3709 { "nativeStopFilter", "()I", (void *)android_media_tv_Tuner_stop_filter },
3710 { "nativeFlushFilter", "()I", (void *)android_media_tv_Tuner_flush_filter },
shubangd351b822020-01-22 17:29:18 -08003711 { "nativeRead", "([BJJ)I", (void *)android_media_tv_Tuner_read_filter_fmq },
Amy1b301f42020-01-02 11:07:56 -08003712 { "nativeClose", "()I", (void *)android_media_tv_Tuner_close_filter },
shubangd0977902019-11-07 18:58:43 -08003713};
3714
shubang4347e2e2019-12-13 17:20:40 -08003715static const JNINativeMethod gTimeFilterMethods[] = {
shubangdeb067c2020-01-27 13:21:55 -08003716 { "nativeSetTimestamp", "(J)I", (void *)android_media_tv_Tuner_time_filter_set_timestamp },
3717 { "nativeClearTimestamp", "()I", (void *)android_media_tv_Tuner_time_filter_clear_timestamp },
3718 { "nativeGetTimestamp", "()Ljava/lang/Long;",
shubang4347e2e2019-12-13 17:20:40 -08003719 (void *)android_media_tv_Tuner_time_filter_get_timestamp },
3720 { "nativeGetSourceTime", "()Ljava/lang/Long;",
3721 (void *)android_media_tv_Tuner_time_filter_get_source_time },
3722 { "nativeClose", "()I", (void *)android_media_tv_Tuner_time_filter_close },
3723};
3724
shubang13f15e02019-11-04 17:51:02 -08003725static const JNINativeMethod gDescramblerMethods[] = {
shubangd351b822020-01-22 17:29:18 -08003726 { "nativeAddPid", "(IILandroid/media/tv/tuner/filter/Filter;)I",
shubang40454db2020-03-30 16:52:29 -07003727 (void *)android_media_tv_Tuner_descrambler_add_pid },
shubangd351b822020-01-22 17:29:18 -08003728 { "nativeRemovePid", "(IILandroid/media/tv/tuner/filter/Filter;)I",
shubang40454db2020-03-30 16:52:29 -07003729 (void *)android_media_tv_Tuner_descrambler_remove_pid },
3730 { "nativeSetKeyToken", "([B)I", (void *)android_media_tv_Tuner_descrambler_set_key_token },
Amy1b301f42020-01-02 11:07:56 -08003731 { "nativeClose", "()I", (void *)android_media_tv_Tuner_close_descrambler },
shubang13f15e02019-11-04 17:51:02 -08003732};
3733
shubang5637a662020-02-27 18:06:21 -08003734static const JNINativeMethod gDvrRecorderMethods[] = {
shubangd351b822020-01-22 17:29:18 -08003735 { "nativeAttachFilter", "(Landroid/media/tv/tuner/filter/Filter;)I",
shubang4a0eddf2019-11-08 17:10:18 -08003736 (void *)android_media_tv_Tuner_attach_filter },
shubangd351b822020-01-22 17:29:18 -08003737 { "nativeDetachFilter", "(Landroid/media/tv/tuner/filter/Filter;)I",
shubang4a0eddf2019-11-08 17:10:18 -08003738 (void *)android_media_tv_Tuner_detach_filter },
shubangd351b822020-01-22 17:29:18 -08003739 { "nativeConfigureDvr", "(Landroid/media/tv/tuner/dvr/DvrSettings;)I",
shubang030afb52019-11-27 16:09:02 -08003740 (void *)android_media_tv_Tuner_configure_dvr },
shubang793e5702019-12-26 15:15:46 -08003741 { "nativeStartDvr", "()I", (void *)android_media_tv_Tuner_start_dvr },
3742 { "nativeStopDvr", "()I", (void *)android_media_tv_Tuner_stop_dvr },
3743 { "nativeFlushDvr", "()I", (void *)android_media_tv_Tuner_flush_dvr },
3744 { "nativeClose", "()I", (void *)android_media_tv_Tuner_close_dvr },
shubangd351b822020-01-22 17:29:18 -08003745 { "nativeSetFileDescriptor", "(I)V", (void *)android_media_tv_Tuner_dvr_set_fd },
shubangd351b822020-01-22 17:29:18 -08003746 { "nativeWrite", "(J)J", (void *)android_media_tv_Tuner_write_dvr },
3747 { "nativeWrite", "([BJJ)J", (void *)android_media_tv_Tuner_write_dvr_to_array },
3748};
3749
3750static const JNINativeMethod gDvrPlaybackMethods[] = {
shubang5637a662020-02-27 18:06:21 -08003751 { "nativeAttachFilter", "(Landroid/media/tv/tuner/filter/Filter;)I",
3752 (void *)android_media_tv_Tuner_attach_filter },
3753 { "nativeDetachFilter", "(Landroid/media/tv/tuner/filter/Filter;)I",
3754 (void *)android_media_tv_Tuner_detach_filter },
3755 { "nativeConfigureDvr", "(Landroid/media/tv/tuner/dvr/DvrSettings;)I",
3756 (void *)android_media_tv_Tuner_configure_dvr },
3757 { "nativeStartDvr", "()I", (void *)android_media_tv_Tuner_start_dvr },
3758 { "nativeStopDvr", "()I", (void *)android_media_tv_Tuner_stop_dvr },
3759 { "nativeFlushDvr", "()I", (void *)android_media_tv_Tuner_flush_dvr },
3760 { "nativeClose", "()I", (void *)android_media_tv_Tuner_close_dvr },
3761 { "nativeSetFileDescriptor", "(I)V", (void *)android_media_tv_Tuner_dvr_set_fd },
shubangd351b822020-01-22 17:29:18 -08003762 { "nativeRead", "(J)J", (void *)android_media_tv_Tuner_read_dvr },
3763 { "nativeRead", "([BJJ)J", (void *)android_media_tv_Tuner_read_dvr_from_array },
shubang4a0eddf2019-11-08 17:10:18 -08003764};
3765
shubang847fc0a2019-12-26 16:54:10 -08003766static const JNINativeMethod gLnbMethods[] = {
3767 { "nativeSetVoltage", "(I)I", (void *)android_media_tv_Tuner_lnb_set_voltage },
3768 { "nativeSetTone", "(I)I", (void *)android_media_tv_Tuner_lnb_set_tone },
3769 { "nativeSetSatellitePosition", "(I)I", (void *)android_media_tv_Tuner_lnb_set_position },
3770 { "nativeSendDiseqcMessage", "([B)I", (void *)android_media_tv_Tuner_lnb_send_diseqc_msg },
3771 { "nativeClose", "()I", (void *)android_media_tv_Tuner_close_lnb },
3772};
3773
shubang3aef4fe2020-04-01 16:51:04 -07003774static const JNINativeMethod gMediaEventMethods[] = {
3775 { "nativeGetLinearBlock", "()Landroid/media/MediaCodec$LinearBlock;",
3776 (void *)android_media_tv_Tuner_media_event_get_linear_block },
3777 { "nativeGetAudioHandle", "()Ljava/lang/Long;",
3778 (void *)android_media_tv_Tuner_media_event_get_audio_handle },
3779 { "nativeFinalize", "()V",
3780 (void *)android_media_tv_Tuner_media_event_finalize },
3781};
3782
shubangd0977902019-11-07 18:58:43 -08003783static bool register_android_media_tv_Tuner(JNIEnv *env) {
3784 if (AndroidRuntime::registerNativeMethods(
3785 env, "android/media/tv/tuner/Tuner", gTunerMethods, NELEM(gTunerMethods)) != JNI_OK) {
3786 ALOGE("Failed to register tuner native methods");
3787 return false;
3788 }
3789 if (AndroidRuntime::registerNativeMethods(
shubangd351b822020-01-22 17:29:18 -08003790 env, "android/media/tv/tuner/filter/Filter",
shubangd0977902019-11-07 18:58:43 -08003791 gFilterMethods,
3792 NELEM(gFilterMethods)) != JNI_OK) {
3793 ALOGE("Failed to register filter native methods");
3794 return false;
3795 }
shubang13f15e02019-11-04 17:51:02 -08003796 if (AndroidRuntime::registerNativeMethods(
shubangd351b822020-01-22 17:29:18 -08003797 env, "android/media/tv/tuner/filter/TimeFilter",
shubang4347e2e2019-12-13 17:20:40 -08003798 gTimeFilterMethods,
3799 NELEM(gTimeFilterMethods)) != JNI_OK) {
3800 ALOGE("Failed to register time filter native methods");
3801 return false;
3802 }
3803 if (AndroidRuntime::registerNativeMethods(
shubangd351b822020-01-22 17:29:18 -08003804 env, "android/media/tv/tuner/Descrambler",
shubang13f15e02019-11-04 17:51:02 -08003805 gDescramblerMethods,
3806 NELEM(gDescramblerMethods)) != JNI_OK) {
3807 ALOGE("Failed to register descrambler native methods");
3808 return false;
3809 }
shubang4a0eddf2019-11-08 17:10:18 -08003810 if (AndroidRuntime::registerNativeMethods(
shubangd351b822020-01-22 17:29:18 -08003811 env, "android/media/tv/tuner/dvr/DvrRecorder",
3812 gDvrRecorderMethods,
3813 NELEM(gDvrRecorderMethods)) != JNI_OK) {
3814 ALOGE("Failed to register dvr recorder native methods");
3815 return false;
3816 }
3817 if (AndroidRuntime::registerNativeMethods(
3818 env, "android/media/tv/tuner/dvr/DvrPlayback",
3819 gDvrPlaybackMethods,
3820 NELEM(gDvrPlaybackMethods)) != JNI_OK) {
3821 ALOGE("Failed to register dvr playback native methods");
3822 return false;
3823 }
3824 if (AndroidRuntime::registerNativeMethods(
3825 env, "android/media/tv/tuner/Lnb",
shubang847fc0a2019-12-26 16:54:10 -08003826 gLnbMethods,
3827 NELEM(gLnbMethods)) != JNI_OK) {
3828 ALOGE("Failed to register lnb native methods");
3829 return false;
3830 }
shubang3aef4fe2020-04-01 16:51:04 -07003831 if (AndroidRuntime::registerNativeMethods(
3832 env, "android/media/tv/tuner/filter/MediaEvent",
3833 gMediaEventMethods,
3834 NELEM(gMediaEventMethods)) != JNI_OK) {
3835 ALOGE("Failed to register MediaEvent native methods");
3836 return false;
3837 }
shubangd0977902019-11-07 18:58:43 -08003838 return true;
shubang8ab43b12019-10-18 15:55:55 -07003839}
3840
3841jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
3842{
3843 JNIEnv* env = NULL;
3844 jint result = -1;
3845
3846 if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
3847 ALOGE("ERROR: GetEnv failed\n");
3848 return result;
3849 }
3850 assert(env != NULL);
3851
shubangd0977902019-11-07 18:58:43 -08003852 if (!register_android_media_tv_Tuner(env)) {
shubang8ab43b12019-10-18 15:55:55 -07003853 ALOGE("ERROR: Tuner native registration failed\n");
3854 return result;
3855 }
3856 return JNI_VERSION_1_4;
3857}