1 /* 2 * Copyright 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #define LOG_TAG "TvTuner-JNI" 18 #include <utils/Log.h> 19 20 #include "android_media_MediaCodecLinearBlock.h" 21 #include "android_media_tv_Tuner.h" 22 #include "android_runtime/AndroidRuntime.h" 23 24 #include <android-base/logging.h> 25 #include <media/stagefright/foundation/ADebug.h> 26 #include <nativehelper/JNIHelp.h> 27 #include <nativehelper/ScopedLocalRef.h> 28 #include <utils/NativeHandle.h> 29 30 #pragma GCC diagnostic ignored "-Wunused-function" 31 32 using ::android::hardware::Void; 33 using ::android::hardware::hidl_bitfield; 34 using ::android::hardware::hidl_vec; 35 using ::android::hardware::tv::tuner::V1_0::AudioExtraMetaData; 36 using ::android::hardware::tv::tuner::V1_0::DataFormat; 37 using ::android::hardware::tv::tuner::V1_0::DemuxAlpFilterSettings; 38 using ::android::hardware::tv::tuner::V1_0::DemuxAlpFilterType; 39 using ::android::hardware::tv::tuner::V1_0::DemuxAlpLengthType; 40 using ::android::hardware::tv::tuner::V1_0::DemuxCapabilities; 41 using ::android::hardware::tv::tuner::V1_0::DemuxFilterAvSettings; 42 using ::android::hardware::tv::tuner::V1_0::DemuxFilterDownloadEvent; 43 using ::android::hardware::tv::tuner::V1_0::DemuxFilterDownloadSettings; 44 using ::android::hardware::tv::tuner::V1_0::DemuxFilterIpPayloadEvent; 45 using ::android::hardware::tv::tuner::V1_0::DemuxFilterMainType; 46 using ::android::hardware::tv::tuner::V1_0::DemuxFilterMediaEvent; 47 using ::android::hardware::tv::tuner::V1_0::DemuxFilterMmtpRecordEvent; 48 using ::android::hardware::tv::tuner::V1_0::DemuxFilterPesDataSettings; 49 using ::android::hardware::tv::tuner::V1_0::DemuxFilterPesEvent; 50 using ::android::hardware::tv::tuner::V1_0::DemuxFilterRecordSettings; 51 using ::android::hardware::tv::tuner::V1_0::DemuxFilterSectionBits; 52 using ::android::hardware::tv::tuner::V1_0::DemuxFilterSectionEvent; 53 using ::android::hardware::tv::tuner::V1_0::DemuxFilterSectionSettings; 54 using ::android::hardware::tv::tuner::V1_0::DemuxFilterSettings; 55 using ::android::hardware::tv::tuner::V1_0::DemuxFilterTemiEvent; 56 using ::android::hardware::tv::tuner::V1_0::DemuxFilterTsRecordEvent; 57 using ::android::hardware::tv::tuner::V1_0::DemuxIpAddress; 58 using ::android::hardware::tv::tuner::V1_0::DemuxIpFilterSettings; 59 using ::android::hardware::tv::tuner::V1_0::DemuxIpFilterType; 60 using ::android::hardware::tv::tuner::V1_0::DemuxMmtpFilterSettings; 61 using ::android::hardware::tv::tuner::V1_0::DemuxMmtpFilterType; 62 using ::android::hardware::tv::tuner::V1_0::DemuxMmtpPid; 63 using ::android::hardware::tv::tuner::V1_0::DemuxQueueNotifyBits; 64 using ::android::hardware::tv::tuner::V1_0::DemuxRecordScIndexType; 65 using ::android::hardware::tv::tuner::V1_0::DemuxScHevcIndex; 66 using ::android::hardware::tv::tuner::V1_0::DemuxScIndex; 67 using ::android::hardware::tv::tuner::V1_0::DemuxTlvFilterSettings; 68 using ::android::hardware::tv::tuner::V1_0::DemuxTlvFilterType; 69 using ::android::hardware::tv::tuner::V1_0::DemuxTpid; 70 using ::android::hardware::tv::tuner::V1_0::DemuxTsFilterSettings; 71 using ::android::hardware::tv::tuner::V1_0::DemuxTsFilterType; 72 using ::android::hardware::tv::tuner::V1_0::DemuxTsIndex; 73 using ::android::hardware::tv::tuner::V1_0::DvrSettings; 74 using ::android::hardware::tv::tuner::V1_0::FrontendAnalogSettings; 75 using ::android::hardware::tv::tuner::V1_0::FrontendAnalogSifStandard; 76 using ::android::hardware::tv::tuner::V1_0::FrontendAnalogType; 77 using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3Bandwidth; 78 using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3CodeRate; 79 using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3DemodOutputFormat; 80 using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3Fec; 81 using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3Modulation; 82 using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3PlpSettings; 83 using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3Settings; 84 using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3TimeInterleaveMode; 85 using ::android::hardware::tv::tuner::V1_0::FrontendAtscSettings; 86 using ::android::hardware::tv::tuner::V1_0::FrontendAtscModulation; 87 using ::android::hardware::tv::tuner::V1_0::FrontendDvbcAnnex; 88 using ::android::hardware::tv::tuner::V1_0::FrontendDvbcModulation; 89 using ::android::hardware::tv::tuner::V1_0::FrontendDvbcOuterFec; 90 using ::android::hardware::tv::tuner::V1_0::FrontendDvbcSettings; 91 using ::android::hardware::tv::tuner::V1_0::FrontendDvbcSpectralInversion; 92 using ::android::hardware::tv::tuner::V1_0::FrontendDvbsCodeRate; 93 using ::android::hardware::tv::tuner::V1_0::FrontendDvbsModulation; 94 using ::android::hardware::tv::tuner::V1_0::FrontendDvbsPilot; 95 using ::android::hardware::tv::tuner::V1_0::FrontendDvbsRolloff; 96 using ::android::hardware::tv::tuner::V1_0::FrontendDvbsSettings; 97 using ::android::hardware::tv::tuner::V1_0::FrontendDvbsStandard; 98 using ::android::hardware::tv::tuner::V1_0::FrontendDvbsVcmMode; 99 using ::android::hardware::tv::tuner::V1_0::FrontendDvbtBandwidth; 100 using ::android::hardware::tv::tuner::V1_0::FrontendDvbtCoderate; 101 using ::android::hardware::tv::tuner::V1_0::FrontendDvbtConstellation; 102 using ::android::hardware::tv::tuner::V1_0::FrontendDvbtGuardInterval; 103 using ::android::hardware::tv::tuner::V1_0::FrontendDvbtHierarchy; 104 using ::android::hardware::tv::tuner::V1_0::FrontendDvbtPlpMode; 105 using ::android::hardware::tv::tuner::V1_0::FrontendDvbtSettings; 106 using ::android::hardware::tv::tuner::V1_0::FrontendDvbtStandard; 107 using ::android::hardware::tv::tuner::V1_0::FrontendDvbtTransmissionMode; 108 using ::android::hardware::tv::tuner::V1_0::FrontendInnerFec; 109 using ::android::hardware::tv::tuner::V1_0::FrontendIsdbs3Coderate; 110 using ::android::hardware::tv::tuner::V1_0::FrontendIsdbs3Modulation; 111 using ::android::hardware::tv::tuner::V1_0::FrontendIsdbs3Rolloff; 112 using ::android::hardware::tv::tuner::V1_0::FrontendIsdbs3Settings; 113 using ::android::hardware::tv::tuner::V1_0::FrontendIsdbsCoderate; 114 using ::android::hardware::tv::tuner::V1_0::FrontendIsdbsModulation; 115 using ::android::hardware::tv::tuner::V1_0::FrontendIsdbsRolloff; 116 using ::android::hardware::tv::tuner::V1_0::FrontendIsdbsSettings; 117 using ::android::hardware::tv::tuner::V1_0::FrontendIsdbsStreamIdType; 118 using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtBandwidth; 119 using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtCoderate; 120 using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtGuardInterval; 121 using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtMode; 122 using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtModulation; 123 using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtSettings; 124 using ::android::hardware::tv::tuner::V1_0::FrontendModulationStatus; 125 using ::android::hardware::tv::tuner::V1_0::FrontendScanAtsc3PlpInfo; 126 using ::android::hardware::tv::tuner::V1_0::FrontendStatus; 127 using ::android::hardware::tv::tuner::V1_0::FrontendStatusAtsc3PlpInfo; 128 using ::android::hardware::tv::tuner::V1_0::FrontendStatusType; 129 using ::android::hardware::tv::tuner::V1_0::FrontendType; 130 using ::android::hardware::tv::tuner::V1_0::LnbPosition; 131 using ::android::hardware::tv::tuner::V1_0::LnbTone; 132 using ::android::hardware::tv::tuner::V1_0::LnbVoltage; 133 using ::android::hardware::tv::tuner::V1_0::PlaybackSettings; 134 using ::android::hardware::tv::tuner::V1_0::RecordSettings; 135 using ::android::hardware::tv::tuner::V1_1::AudioStreamType; 136 using ::android::hardware::tv::tuner::V1_1::AvStreamType; 137 using ::android::hardware::tv::tuner::V1_1::Constant; 138 using ::android::hardware::tv::tuner::V1_1::Constant64Bit; 139 using ::android::hardware::tv::tuner::V1_1::FrontendAnalogAftFlag; 140 using ::android::hardware::tv::tuner::V1_1::FrontendAnalogSettingsExt1_1; 141 using ::android::hardware::tv::tuner::V1_1::FrontendBandwidth; 142 using ::android::hardware::tv::tuner::V1_1::FrontendCableTimeInterleaveMode; 143 using ::android::hardware::tv::tuner::V1_1::FrontendDvbcBandwidth; 144 using ::android::hardware::tv::tuner::V1_1::FrontendDvbsScanType; 145 using ::android::hardware::tv::tuner::V1_1::FrontendDvbcSettingsExt1_1; 146 using ::android::hardware::tv::tuner::V1_1::FrontendDvbsSettingsExt1_1; 147 using ::android::hardware::tv::tuner::V1_1::FrontendDvbtSettingsExt1_1; 148 using ::android::hardware::tv::tuner::V1_1::FrontendDtmbBandwidth; 149 using ::android::hardware::tv::tuner::V1_1::FrontendDtmbCapabilities; 150 using ::android::hardware::tv::tuner::V1_1::FrontendDtmbCodeRate; 151 using ::android::hardware::tv::tuner::V1_1::FrontendDtmbGuardInterval; 152 using ::android::hardware::tv::tuner::V1_1::FrontendDtmbModulation; 153 using ::android::hardware::tv::tuner::V1_1::FrontendDtmbSettings; 154 using ::android::hardware::tv::tuner::V1_1::FrontendDtmbTimeInterleaveMode; 155 using ::android::hardware::tv::tuner::V1_1::FrontendDtmbTransmissionMode; 156 using ::android::hardware::tv::tuner::V1_1::FrontendGuardInterval; 157 using ::android::hardware::tv::tuner::V1_1::FrontendInterleaveMode; 158 using ::android::hardware::tv::tuner::V1_1::FrontendModulation; 159 using ::android::hardware::tv::tuner::V1_1::FrontendRollOff; 160 using ::android::hardware::tv::tuner::V1_1::FrontendSpectralInversion; 161 using ::android::hardware::tv::tuner::V1_1::FrontendStatusExt1_1; 162 using ::android::hardware::tv::tuner::V1_1::FrontendStatusTypeExt1_1; 163 using ::android::hardware::tv::tuner::V1_1::FrontendTransmissionMode; 164 using ::android::hardware::tv::tuner::V1_1::VideoStreamType; 165 166 struct fields_t { 167 jfieldID tunerContext; 168 jfieldID lnbContext; 169 jfieldID filterContext; 170 jfieldID timeFilterContext; 171 jfieldID descramblerContext; 172 jfieldID dvrRecorderContext; 173 jfieldID dvrPlaybackContext; 174 jfieldID mediaEventContext; 175 jmethodID frontendInitID; 176 jmethodID filterInitID; 177 jmethodID timeFilterInitID; 178 jmethodID dvrRecorderInitID; 179 jmethodID dvrPlaybackInitID; 180 jmethodID onFrontendEventID; 181 jmethodID onFilterStatusID; 182 jmethodID onFilterEventID; 183 jmethodID lnbInitID; 184 jmethodID onLnbEventID; 185 jmethodID onLnbDiseqcMessageID; 186 jmethodID onDvrRecordStatusID; 187 jmethodID onDvrPlaybackStatusID; 188 jmethodID descramblerInitID; 189 jmethodID linearBlockInitID; 190 jmethodID linearBlockSetInternalStateID; 191 }; 192 193 static fields_t gFields; 194 195 196 static int IP_V4_LENGTH = 4; 197 static int IP_V6_LENGTH = 16; 198 199 void DestroyCallback(const C2Buffer * buf, void *arg) { 200 android::sp<android::MediaEvent> event = (android::MediaEvent *)arg; 201 android::Mutex::Autolock autoLock(event->mLock); 202 if (event->mLinearBlockObj != NULL) { 203 JNIEnv *env = android::AndroidRuntime::getJNIEnv(); 204 env->DeleteWeakGlobalRef(event->mLinearBlockObj); 205 event->mLinearBlockObj = NULL; 206 } 207 208 event->mAvHandleRefCnt--; 209 event->finalize(); 210 event->decStrong(buf); 211 } 212 213 namespace android { 214 215 /////////////// LnbClientCallbackImpl /////////////////////// 216 217 void LnbClientCallbackImpl::onEvent(const LnbEventType lnbEventType) { 218 ALOGD("LnbClientCallbackImpl::onEvent, type=%d", lnbEventType); 219 JNIEnv *env = AndroidRuntime::getJNIEnv(); 220 jobject lnb(env->NewLocalRef(mLnbObj)); 221 if (!env->IsSameObject(lnb, nullptr)) { 222 env->CallVoidMethod( 223 lnb, 224 gFields.onLnbEventID, 225 (jint)lnbEventType); 226 } else { 227 ALOGE("LnbClientCallbackImpl::onEvent:" 228 "Lnb object has been freed. Ignoring callback."); 229 } 230 } 231 232 void LnbClientCallbackImpl::onDiseqcMessage(const hidl_vec<uint8_t>& diseqcMessage) { 233 ALOGD("LnbClientCallbackImpl::onDiseqcMessage"); 234 JNIEnv *env = AndroidRuntime::getJNIEnv(); 235 jobject lnb(env->NewLocalRef(mLnbObj)); 236 if (!env->IsSameObject(lnb, nullptr)) { 237 jbyteArray array = env->NewByteArray(diseqcMessage.size()); 238 env->SetByteArrayRegion( 239 array, 0, diseqcMessage.size(), reinterpret_cast<jbyte*>(diseqcMessage[0])); 240 env->CallVoidMethod( 241 lnb, 242 gFields.onLnbDiseqcMessageID, 243 array); 244 } else { 245 ALOGE("LnbClientCallbackImpl::onDiseqcMessage:" 246 "Lnb object has been freed. Ignoring callback."); 247 } 248 } 249 250 void LnbClientCallbackImpl::setLnb(jweak lnbObj) { 251 ALOGD("LnbClientCallbackImpl::setLnb"); 252 mLnbObj = lnbObj; 253 } 254 255 LnbClientCallbackImpl::~LnbClientCallbackImpl() { 256 JNIEnv *env = AndroidRuntime::getJNIEnv(); 257 if (mLnbObj != NULL) { 258 env->DeleteWeakGlobalRef(mLnbObj); 259 mLnbObj = NULL; 260 } 261 } 262 263 /////////////// DvrClientCallbackImpl /////////////////////// 264 265 void DvrClientCallbackImpl::onRecordStatus(RecordStatus status) { 266 ALOGD("DvrClientCallbackImpl::onRecordStatus"); 267 JNIEnv *env = AndroidRuntime::getJNIEnv(); 268 jobject dvr(env->NewLocalRef(mDvrObj)); 269 if (!env->IsSameObject(dvr, nullptr)) { 270 env->CallVoidMethod( 271 dvr, 272 gFields.onDvrRecordStatusID, 273 (jint) status); 274 } else { 275 ALOGE("DvrClientCallbackImpl::onRecordStatus:" 276 "Dvr object has been freed. Ignoring callback."); 277 } 278 } 279 280 void DvrClientCallbackImpl::onPlaybackStatus(PlaybackStatus status) { 281 ALOGD("DvrClientCallbackImpl::onPlaybackStatus"); 282 JNIEnv *env = AndroidRuntime::getJNIEnv(); 283 jobject dvr(env->NewLocalRef(mDvrObj)); 284 if (!env->IsSameObject(dvr, nullptr)) { 285 env->CallVoidMethod( 286 dvr, 287 gFields.onDvrPlaybackStatusID, 288 (jint) status); 289 } else { 290 ALOGE("DvrClientCallbackImpl::onPlaybackStatus:" 291 "Dvr object has been freed. Ignoring callback."); 292 } 293 } 294 295 void DvrClientCallbackImpl::setDvr(jweak dvrObj) { 296 ALOGD("DvrClientCallbackImpl::setDvr"); 297 mDvrObj = dvrObj; 298 } 299 300 DvrClientCallbackImpl::~DvrClientCallbackImpl() { 301 JNIEnv *env = AndroidRuntime::getJNIEnv(); 302 if (mDvrObj != NULL) { 303 env->DeleteWeakGlobalRef(mDvrObj); 304 mDvrObj = NULL; 305 } 306 } 307 308 /////////////// C2DataIdInfo /////////////////////// 309 310 C2DataIdInfo::C2DataIdInfo(uint32_t index, uint64_t value) : C2Param(kParamSize, index) { 311 CHECK(isGlobal()); 312 CHECK_EQ(C2Param::INFO, kind()); 313 mInfo = StubInfo(value); 314 memcpy(static_cast<C2Param *>(this) + 1, static_cast<C2Param *>(&mInfo) + 1, 315 kParamSize - sizeof(C2Param)); 316 } 317 318 /////////////// MediaEvent /////////////////////// 319 320 MediaEvent::MediaEvent(sp<FilterClient> filterClient, hidl_handle avHandle, 321 uint64_t dataId, uint64_t dataSize, jobject obj) : mFilterClient(filterClient), 322 mDataId(dataId), mDataSize(dataSize), mBuffer(nullptr), 323 mDataIdRefCnt(0), mAvHandleRefCnt(0), mIonHandle(nullptr) { 324 JNIEnv *env = AndroidRuntime::getJNIEnv(); 325 mMediaEventObj = env->NewWeakGlobalRef(obj); 326 mAvHandle = native_handle_clone(avHandle.getNativeHandle()); 327 mLinearBlockObj = NULL; 328 } 329 330 MediaEvent::~MediaEvent() { 331 JNIEnv *env = AndroidRuntime::getJNIEnv(); 332 env->DeleteWeakGlobalRef(mMediaEventObj); 333 mMediaEventObj = NULL; 334 native_handle_delete(mAvHandle); 335 if (mIonHandle != NULL) { 336 delete mIonHandle; 337 } 338 std::shared_ptr<C2Buffer> pC2Buffer = mC2Buffer.lock(); 339 if (pC2Buffer != NULL) { 340 pC2Buffer->unregisterOnDestroyNotify(&DestroyCallback, this); 341 } 342 343 if (mLinearBlockObj != NULL) { 344 env->DeleteWeakGlobalRef(mLinearBlockObj); 345 mLinearBlockObj = NULL; 346 } 347 348 mFilterClient = NULL; 349 } 350 351 void MediaEvent::finalize() { 352 if (mAvHandleRefCnt == 0 && mFilterClient != NULL) { 353 mFilterClient->releaseAvHandle( 354 mAvHandle, mDataIdRefCnt == 0 ? mDataId : 0); 355 native_handle_close(mAvHandle); 356 } 357 } 358 359 jobject MediaEvent::getLinearBlock() { 360 ALOGD("MediaEvent::getLinearBlock"); 361 if (mAvHandle == NULL) { 362 return NULL; 363 } 364 if (mLinearBlockObj != NULL) { 365 return mLinearBlockObj; 366 } 367 368 int fd; 369 int numInts = 0; 370 int memIndex; 371 int dataSize; 372 SharedHandleInfo info = mFilterClient->getAvSharedHandleInfo(); 373 native_handle_t* avSharedHandle = info.sharedHandle; 374 uint64_t avSharedMemSize = info.size; 375 376 if (mAvHandle->numFds == 0) { 377 if (avSharedHandle == NULL) { 378 ALOGE("Shared AV memory handle is not initialized."); 379 return NULL; 380 } 381 if (avSharedHandle->numFds == 0) { 382 ALOGE("Shared AV memory handle is empty."); 383 return NULL; 384 } 385 fd = avSharedHandle->data[0]; 386 dataSize = avSharedMemSize; 387 numInts = avSharedHandle->numInts; 388 if (numInts > 0) { 389 // If the first int in the shared native handle has value, use it as the index 390 memIndex = avSharedHandle->data[avSharedHandle->numFds]; 391 } 392 } else { 393 fd = mAvHandle->data[0]; 394 dataSize = mDataSize; 395 numInts = mAvHandle->numInts; 396 if (numInts > 0) { 397 // Otherwise if the first int in the av native handle returned from the filter 398 // event has value, use it as the index 399 memIndex = mAvHandle->data[mAvHandle->numFds]; 400 } else { 401 if (avSharedHandle != NULL) { 402 numInts = avSharedHandle->numInts; 403 if (numInts > 0) { 404 // If the first int in the shared native handle has value, use it as the index 405 memIndex = avSharedHandle->data[avSharedHandle->numFds]; 406 } 407 } 408 } 409 } 410 411 mIonHandle = new C2HandleIon(dup(fd), dataSize); 412 std::shared_ptr<C2LinearBlock> block = _C2BlockFactory::CreateLinearBlock(mIonHandle); 413 if (block != nullptr) { 414 // CreateLinearBlock delete mIonHandle after it create block successfully. 415 // ToDo: coordinate who is response to delete mIonHandle 416 mIonHandle = NULL; 417 JNIEnv *env = AndroidRuntime::getJNIEnv(); 418 std::unique_ptr<JMediaCodecLinearBlock> context{new JMediaCodecLinearBlock}; 419 context->mBlock = block; 420 std::shared_ptr<C2Buffer> pC2Buffer = context->toC2Buffer(0, dataSize); 421 context->mBuffer = pC2Buffer; 422 mC2Buffer = pC2Buffer; 423 if (numInts > 0) { 424 std::shared_ptr<C2Param> c2param = std::make_shared<C2DataIdInfo>(memIndex, mDataId); 425 std::shared_ptr<C2Info> info(std::static_pointer_cast<C2Info>(c2param)); 426 pC2Buffer->setInfo(info); 427 } 428 pC2Buffer->registerOnDestroyNotify(&DestroyCallback, this); 429 incStrong(pC2Buffer.get()); 430 jobject linearBlock = 431 env->NewObject( 432 env->FindClass("android/media/MediaCodec$LinearBlock"), 433 gFields.linearBlockInitID); 434 env->CallVoidMethod( 435 linearBlock, 436 gFields.linearBlockSetInternalStateID, 437 (jlong)context.release(), 438 true); 439 mLinearBlockObj = env->NewWeakGlobalRef(linearBlock); 440 mAvHandleRefCnt++; 441 return linearBlock; 442 } else { 443 native_handle_close(const_cast<native_handle_t*>( 444 reinterpret_cast<const native_handle_t*>(mIonHandle))); 445 native_handle_delete(const_cast<native_handle_t*>( 446 reinterpret_cast<const native_handle_t*>(mIonHandle))); 447 mIonHandle = NULL; 448 return NULL; 449 } 450 } 451 452 uint64_t MediaEvent::getAudioHandle() { 453 mDataIdRefCnt++; 454 return mDataId; 455 } 456 457 /////////////// FilterClientCallbackImpl /////////////////////// 458 459 jobjectArray FilterClientCallbackImpl::getSectionEvent( 460 jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events) { 461 JNIEnv *env = AndroidRuntime::getJNIEnv(); 462 jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/SectionEvent"); 463 jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(IIII)V"); 464 465 for (int i = 0; i < events.size(); i++) { 466 auto event = events[i]; 467 DemuxFilterSectionEvent sectionEvent = event.section(); 468 469 jint tableId = static_cast<jint>(sectionEvent.tableId); 470 jint version = static_cast<jint>(sectionEvent.version); 471 jint sectionNum = static_cast<jint>(sectionEvent.sectionNum); 472 jint dataLength = static_cast<jint>(sectionEvent.dataLength); 473 474 jobject obj = 475 env->NewObject(eventClazz, eventInit, tableId, version, sectionNum, dataLength); 476 env->SetObjectArrayElement(arr, i, obj); 477 } 478 return arr; 479 } 480 481 jobjectArray FilterClientCallbackImpl::getMediaEvent( 482 jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events) { 483 JNIEnv *env = AndroidRuntime::getJNIEnv(); 484 jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/MediaEvent"); 485 jmethodID eventInit = env->GetMethodID(eventClazz, 486 "<init>", 487 "(IZJJJLandroid/media/MediaCodec$LinearBlock;" 488 "ZJIZLandroid/media/tv/tuner/filter/AudioDescriptor;)V"); 489 jfieldID eventContext = env->GetFieldID(eventClazz, "mNativeContext", "J"); 490 491 for (int i = 0; i < events.size(); i++) { 492 auto event = events[i]; 493 DemuxFilterMediaEvent mediaEvent = event.media(); 494 495 jobject audioDescriptor = NULL; 496 if (mediaEvent.extraMetaData.getDiscriminator() 497 == DemuxFilterMediaEvent::ExtraMetaData::hidl_discriminator::audio) { 498 jclass adClazz = env->FindClass("android/media/tv/tuner/filter/AudioDescriptor"); 499 jmethodID adInit = env->GetMethodID(adClazz, "<init>", "(BBCBBB)V"); 500 501 AudioExtraMetaData ad = mediaEvent.extraMetaData.audio(); 502 jbyte adFade = static_cast<jbyte>(ad.adFade); 503 jbyte adPan = static_cast<jbyte>(ad.adPan); 504 jchar versionTextTag = static_cast<jchar>(ad.versionTextTag); 505 jbyte adGainCenter = static_cast<jbyte>(ad.adGainCenter); 506 jbyte adGainFront = static_cast<jbyte>(ad.adGainFront); 507 jbyte adGainSurround = static_cast<jbyte>(ad.adGainSurround); 508 509 audioDescriptor = 510 env->NewObject(adClazz, adInit, adFade, adPan, versionTextTag, adGainCenter, 511 adGainFront, adGainSurround); 512 } 513 514 jlong dataLength = static_cast<jlong>(mediaEvent.dataLength); 515 516 jint streamId = static_cast<jint>(mediaEvent.streamId); 517 jboolean isPtsPresent = static_cast<jboolean>(mediaEvent.isPtsPresent); 518 jlong pts = static_cast<jlong>(mediaEvent.pts); 519 jlong offset = static_cast<jlong>(mediaEvent.offset); 520 jboolean isSecureMemory = static_cast<jboolean>(mediaEvent.isSecureMemory); 521 jlong avDataId = static_cast<jlong>(mediaEvent.avDataId); 522 jint mpuSequenceNumber = static_cast<jint>(mediaEvent.mpuSequenceNumber); 523 jboolean isPesPrivateData = static_cast<jboolean>(mediaEvent.isPesPrivateData); 524 525 jobject obj = 526 env->NewObject(eventClazz, eventInit, streamId, isPtsPresent, pts, dataLength, 527 offset, NULL, isSecureMemory, avDataId, mpuSequenceNumber, isPesPrivateData, 528 audioDescriptor); 529 530 if (mediaEvent.avMemory.getNativeHandle() != NULL || mediaEvent.avDataId != 0) { 531 sp<MediaEvent> mediaEventSp = 532 new MediaEvent(mFilterClient, mediaEvent.avMemory, 533 mediaEvent.avDataId, dataLength + offset, obj); 534 mediaEventSp->mAvHandleRefCnt++; 535 env->SetLongField(obj, eventContext, (jlong) mediaEventSp.get()); 536 mediaEventSp->incStrong(obj); 537 } 538 539 env->SetObjectArrayElement(arr, i, obj); 540 } 541 return arr; 542 } 543 544 jobjectArray FilterClientCallbackImpl::getPesEvent( 545 jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events) { 546 JNIEnv *env = AndroidRuntime::getJNIEnv(); 547 jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/PesEvent"); 548 jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(III)V"); 549 550 for (int i = 0; i < events.size(); i++) { 551 auto event = events[i]; 552 DemuxFilterPesEvent pesEvent = event.pes(); 553 554 jint streamId = static_cast<jint>(pesEvent.streamId); 555 jint dataLength = static_cast<jint>(pesEvent.dataLength); 556 jint mpuSequenceNumber = static_cast<jint>(pesEvent.mpuSequenceNumber); 557 558 jobject obj = 559 env->NewObject(eventClazz, eventInit, streamId, dataLength, mpuSequenceNumber); 560 env->SetObjectArrayElement(arr, i, obj); 561 } 562 return arr; 563 } 564 565 jobjectArray FilterClientCallbackImpl::getTsRecordEvent( 566 jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events, 567 const std::vector<DemuxFilterEventExt::Event>& eventsExt) { 568 JNIEnv *env = AndroidRuntime::getJNIEnv(); 569 jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/TsRecordEvent"); 570 jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(IIIJJI)V"); 571 572 for (int i = 0; i < events.size(); i++) { 573 auto event = events[i]; 574 DemuxFilterTsRecordEvent tsRecordEvent = event.tsRecord(); 575 DemuxPid pid = tsRecordEvent.pid; 576 577 jint jpid = static_cast<jint>(Constant::INVALID_TS_PID); 578 579 if (pid.getDiscriminator() == DemuxPid::hidl_discriminator::tPid) { 580 jpid = static_cast<jint>(pid.tPid()); 581 } else if (pid.getDiscriminator() == DemuxPid::hidl_discriminator::mmtpPid) { 582 jpid = static_cast<jint>(pid.mmtpPid()); 583 } 584 585 jint sc = 0; 586 587 if (tsRecordEvent.scIndexMask.getDiscriminator() 588 == DemuxFilterTsRecordEvent::ScIndexMask::hidl_discriminator::sc) { 589 sc = static_cast<jint>(tsRecordEvent.scIndexMask.sc()); 590 } else if (tsRecordEvent.scIndexMask.getDiscriminator() 591 == DemuxFilterTsRecordEvent::ScIndexMask::hidl_discriminator::scHevc) { 592 sc = static_cast<jint>(tsRecordEvent.scIndexMask.scHevc()); 593 } 594 595 jint ts = static_cast<jint>(tsRecordEvent.tsIndexMask); 596 597 jlong byteNumber = static_cast<jlong>(tsRecordEvent.byteNumber); 598 599 jlong pts; 600 jlong firstMbInSlice; 601 if (eventsExt.size() > i && eventsExt[i].getDiscriminator() == 602 DemuxFilterEventExt::Event::hidl_discriminator::tsRecord) { 603 pts = static_cast<jlong>(eventsExt[i].tsRecord().pts); 604 firstMbInSlice = static_cast<jint>(eventsExt[i].tsRecord().firstMbInSlice); 605 } else { 606 pts = static_cast<jlong>(Constant64Bit::INVALID_PRESENTATION_TIME_STAMP); 607 firstMbInSlice = static_cast<jint>(Constant::INVALID_FIRST_MACROBLOCK_IN_SLICE); 608 } 609 610 jobject obj = 611 env->NewObject(eventClazz, eventInit, jpid, ts, sc, byteNumber, 612 pts, firstMbInSlice); 613 env->SetObjectArrayElement(arr, i, obj); 614 } 615 return arr; 616 } 617 618 jobjectArray FilterClientCallbackImpl::getMmtpRecordEvent( 619 jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events, 620 const std::vector<DemuxFilterEventExt::Event>& eventsExt) { 621 JNIEnv *env = AndroidRuntime::getJNIEnv(); 622 jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/MmtpRecordEvent"); 623 jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(IJIJII)V"); 624 625 for (int i = 0; i < events.size(); i++) { 626 auto event = events[i]; 627 628 DemuxFilterMmtpRecordEvent mmtpRecordEvent = event.mmtpRecord(); 629 630 jint scHevcIndexMask = static_cast<jint>(mmtpRecordEvent.scHevcIndexMask); 631 jlong byteNumber = static_cast<jlong>(mmtpRecordEvent.byteNumber); 632 633 jint mpuSequenceNumber; 634 jlong pts; 635 jlong firstMbInSlice; 636 jlong tsIndexMask; 637 638 if (eventsExt.size() > i && eventsExt[i].getDiscriminator() == 639 DemuxFilterEventExt::Event::hidl_discriminator::mmtpRecord) { 640 mpuSequenceNumber = static_cast<jint>(eventsExt[i].mmtpRecord().mpuSequenceNumber); 641 pts = static_cast<jlong>(eventsExt[i].mmtpRecord().pts); 642 firstMbInSlice = static_cast<jint>(eventsExt[i].mmtpRecord().firstMbInSlice); 643 tsIndexMask = static_cast<jint>(eventsExt[i].mmtpRecord().tsIndexMask); 644 } else { 645 mpuSequenceNumber = 646 static_cast<jint>(Constant::INVALID_MMTP_RECORD_EVENT_MPT_SEQUENCE_NUM); 647 pts = static_cast<jlong>(Constant64Bit::INVALID_PRESENTATION_TIME_STAMP); 648 firstMbInSlice = static_cast<jint>(Constant::INVALID_FIRST_MACROBLOCK_IN_SLICE); 649 tsIndexMask = 0; 650 } 651 652 jobject obj = 653 env->NewObject(eventClazz, eventInit, scHevcIndexMask, byteNumber, 654 mpuSequenceNumber, pts, firstMbInSlice, tsIndexMask); 655 env->SetObjectArrayElement(arr, i, obj); 656 } 657 return arr; 658 } 659 660 jobjectArray FilterClientCallbackImpl::getDownloadEvent( 661 jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events) { 662 JNIEnv *env = AndroidRuntime::getJNIEnv(); 663 jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/DownloadEvent"); 664 jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(IIIII)V"); 665 666 for (int i = 0; i < events.size(); i++) { 667 auto event = events[i]; 668 DemuxFilterDownloadEvent downloadEvent = event.download(); 669 670 jint itemId = static_cast<jint>(downloadEvent.itemId); 671 jint mpuSequenceNumber = static_cast<jint>(downloadEvent.mpuSequenceNumber); 672 jint itemFragmentIndex = static_cast<jint>(downloadEvent.itemFragmentIndex); 673 jint lastItemFragmentIndex = static_cast<jint>(downloadEvent.lastItemFragmentIndex); 674 jint dataLength = static_cast<jint>(downloadEvent.dataLength); 675 676 jobject obj = 677 env->NewObject(eventClazz, eventInit, itemId, mpuSequenceNumber, itemFragmentIndex, 678 lastItemFragmentIndex, dataLength); 679 env->SetObjectArrayElement(arr, i, obj); 680 } 681 return arr; 682 } 683 684 jobjectArray FilterClientCallbackImpl::getIpPayloadEvent( 685 jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events) { 686 JNIEnv *env = AndroidRuntime::getJNIEnv(); 687 jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/IpPayloadEvent"); 688 jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(I)V"); 689 690 for (int i = 0; i < events.size(); i++) { 691 auto event = events[i]; 692 DemuxFilterIpPayloadEvent ipPayloadEvent = event.ipPayload(); 693 jint dataLength = static_cast<jint>(ipPayloadEvent.dataLength); 694 jobject obj = env->NewObject(eventClazz, eventInit, dataLength); 695 env->SetObjectArrayElement(arr, i, obj); 696 } 697 return arr; 698 } 699 700 jobjectArray FilterClientCallbackImpl::getTemiEvent( 701 jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events) { 702 JNIEnv *env = AndroidRuntime::getJNIEnv(); 703 jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/TemiEvent"); 704 jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(JB[B)V"); 705 706 for (int i = 0; i < events.size(); i++) { 707 auto event = events[i]; 708 DemuxFilterTemiEvent temiEvent = event.temi(); 709 jlong pts = static_cast<jlong>(temiEvent.pts); 710 jbyte descrTag = static_cast<jbyte>(temiEvent.descrTag); 711 std::vector<uint8_t> descrData = temiEvent.descrData; 712 713 jbyteArray array = env->NewByteArray(descrData.size()); 714 env->SetByteArrayRegion( 715 array, 0, descrData.size(), reinterpret_cast<jbyte*>(&descrData[0])); 716 717 jobject obj = env->NewObject(eventClazz, eventInit, pts, descrTag, array); 718 env->SetObjectArrayElement(arr, i, obj); 719 } 720 return arr; 721 } 722 723 jobjectArray FilterClientCallbackImpl::getScramblingStatusEvent( 724 jobjectArray& arr, const std::vector<DemuxFilterEventExt::Event>& eventsExt) { 725 JNIEnv *env = AndroidRuntime::getJNIEnv(); 726 jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/ScramblingStatusEvent"); 727 jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(I)V"); 728 729 auto scramblingStatus = eventsExt[0].monitorEvent().scramblingStatus(); 730 jobject obj = env->NewObject(eventClazz, eventInit, static_cast<jint>(scramblingStatus)); 731 env->SetObjectArrayElement(arr, 0, obj); 732 return arr; 733 } 734 735 jobjectArray FilterClientCallbackImpl::getIpCidChangeEvent( 736 jobjectArray& arr, const std::vector<DemuxFilterEventExt::Event>& eventsExt) { 737 JNIEnv *env = AndroidRuntime::getJNIEnv(); 738 jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/IpCidChangeEvent"); 739 jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(I)V"); 740 741 auto cid = eventsExt[0].monitorEvent().cid(); 742 jobject obj = env->NewObject(eventClazz, eventInit, static_cast<jint>(cid)); 743 env->SetObjectArrayElement(arr, 0, obj); 744 return arr; 745 } 746 747 jobjectArray FilterClientCallbackImpl::getRestartEvent( 748 jobjectArray& arr, const std::vector<DemuxFilterEventExt::Event>& eventsExt) { 749 JNIEnv *env = AndroidRuntime::getJNIEnv(); 750 jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/RestartEvent"); 751 jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(I)V"); 752 753 auto startId = eventsExt[0].startId(); 754 jobject obj = env->NewObject(eventClazz, eventInit, static_cast<jint>(startId)); 755 env->SetObjectArrayElement(arr, 0, obj); 756 return arr; 757 } 758 759 void FilterClientCallbackImpl::onFilterEvent_1_1(const DemuxFilterEvent& filterEvent, 760 const DemuxFilterEventExt& filterEventExt) { 761 ALOGD("FilterClientCallbackImpl::onFilterEvent_1_1"); 762 763 JNIEnv *env = AndroidRuntime::getJNIEnv(); 764 jobjectArray array; 765 766 std::vector<DemuxFilterEvent::Event> events = filterEvent.events; 767 std::vector<DemuxFilterEventExt::Event> eventsExt = filterEventExt.events; 768 jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/FilterEvent"); 769 770 if (events.empty() && !eventsExt.empty()) { 771 // Monitor event should be sent with one DemuxFilterMonitorEvent in DemuxFilterEventExt. 772 array = env->NewObjectArray(1, eventClazz, NULL); 773 auto eventExt = eventsExt[0]; 774 switch (eventExt.getDiscriminator()) { 775 case DemuxFilterEventExt::Event::hidl_discriminator::monitorEvent: { 776 switch (eventExt.monitorEvent().getDiscriminator()) { 777 case DemuxFilterMonitorEvent::hidl_discriminator::scramblingStatus: { 778 array = getScramblingStatusEvent(array, eventsExt); 779 break; 780 } 781 case DemuxFilterMonitorEvent::hidl_discriminator::cid: { 782 array = getIpCidChangeEvent(array, eventsExt); 783 break; 784 } 785 default: { 786 break; 787 } 788 } 789 break; 790 } 791 case DemuxFilterEventExt::Event::hidl_discriminator::startId: { 792 array = getRestartEvent(array, eventsExt); 793 break; 794 } 795 default: { 796 break; 797 } 798 } 799 } 800 801 if (!events.empty()) { 802 array = env->NewObjectArray(events.size(), eventClazz, NULL); 803 auto event = events[0]; 804 switch (event.getDiscriminator()) { 805 case DemuxFilterEvent::Event::hidl_discriminator::media: { 806 array = getMediaEvent(array, events); 807 break; 808 } 809 case DemuxFilterEvent::Event::hidl_discriminator::section: { 810 array = getSectionEvent(array, events); 811 break; 812 } 813 case DemuxFilterEvent::Event::hidl_discriminator::pes: { 814 array = getPesEvent(array, events); 815 break; 816 } 817 case DemuxFilterEvent::Event::hidl_discriminator::tsRecord: { 818 array = getTsRecordEvent(array, events, eventsExt); 819 break; 820 } 821 case DemuxFilterEvent::Event::hidl_discriminator::mmtpRecord: { 822 array = getMmtpRecordEvent(array, events, eventsExt); 823 break; 824 } 825 case DemuxFilterEvent::Event::hidl_discriminator::download: { 826 array = getDownloadEvent(array, events); 827 break; 828 } 829 case DemuxFilterEvent::Event::hidl_discriminator::ipPayload: { 830 array = getIpPayloadEvent(array, events); 831 break; 832 } 833 case DemuxFilterEvent::Event::hidl_discriminator::temi: { 834 array = getTemiEvent(array, events); 835 break; 836 } 837 default: { 838 break; 839 } 840 } 841 } 842 jobject filter(env->NewLocalRef(mFilterObj)); 843 if (!env->IsSameObject(filter, nullptr)) { 844 env->CallVoidMethod( 845 filter, 846 gFields.onFilterEventID, 847 array); 848 } else { 849 ALOGE("FilterClientCallbackImpl::onFilterEvent_1_1:" 850 "Filter object has been freed. Ignoring callback."); 851 } 852 } 853 854 void FilterClientCallbackImpl::onFilterEvent(const DemuxFilterEvent& filterEvent) { 855 ALOGD("FilterClientCallbackImpl::onFilterEvent"); 856 std::vector<DemuxFilterEventExt::Event> emptyEventsExt; 857 DemuxFilterEventExt emptyFilterEventExt { 858 .events = emptyEventsExt, 859 }; 860 return onFilterEvent_1_1(filterEvent, emptyFilterEventExt); 861 } 862 863 void FilterClientCallbackImpl::onFilterStatus(const DemuxFilterStatus status) { 864 ALOGD("FilterClientCallbackImpl::onFilterStatus"); 865 JNIEnv *env = AndroidRuntime::getJNIEnv(); 866 jobject filter(env->NewLocalRef(mFilterObj)); 867 if (!env->IsSameObject(filter, nullptr)) { 868 env->CallVoidMethod( 869 filter, 870 gFields.onFilterStatusID, 871 (jint)status); 872 } else { 873 ALOGE("FilterClientCallbackImpl::onFilterStatus:" 874 "Filter object has been freed. Ignoring callback."); 875 } 876 } 877 878 void FilterClientCallbackImpl::setFilter(jweak filterObj, sp<FilterClient> filterClient) { 879 ALOGD("FilterClientCallbackImpl::setFilter"); 880 // Java Object 881 mFilterObj = filterObj; 882 mFilterClient = filterClient; 883 } 884 885 FilterClientCallbackImpl::~FilterClientCallbackImpl() { 886 JNIEnv *env = AndroidRuntime::getJNIEnv(); 887 if (mFilterObj != NULL) { 888 env->DeleteWeakGlobalRef(mFilterObj); 889 mFilterObj = NULL; 890 } 891 mFilterClient = NULL; 892 } 893 894 /////////////// FrontendClientCallbackImpl /////////////////////// 895 896 FrontendClientCallbackImpl::FrontendClientCallbackImpl(jweak tunerObj) : mObject(tunerObj) {} 897 898 void FrontendClientCallbackImpl::onEvent(FrontendEventType frontendEventType) { 899 ALOGD("FrontendClientCallbackImpl::onEvent, type=%d", frontendEventType); 900 JNIEnv *env = AndroidRuntime::getJNIEnv(); 901 jobject frontend(env->NewLocalRef(mObject)); 902 if (!env->IsSameObject(frontend, nullptr)) { 903 env->CallVoidMethod( 904 frontend, 905 gFields.onFrontendEventID, 906 (jint)frontendEventType); 907 } else { 908 ALOGE("FrontendClientCallbackImpl::onEvent:" 909 "Frontend object has been freed. Ignoring callback."); 910 } 911 } 912 913 void FrontendClientCallbackImpl::onScanMessage( 914 FrontendScanMessageType type, const FrontendScanMessage& message) { 915 ALOGD("FrontendClientCallbackImpl::onScanMessage, type=%d", type); 916 JNIEnv *env = AndroidRuntime::getJNIEnv(); 917 jclass clazz = env->FindClass("android/media/tv/tuner/Tuner"); 918 jobject frontend(env->NewLocalRef(mObject)); 919 if (env->IsSameObject(frontend, nullptr)) { 920 ALOGE("FrontendClientCallbackImpl::onScanMessage:" 921 "Frontend object has been freed. Ignoring callback."); 922 return; 923 } 924 switch(type) { 925 case FrontendScanMessageType::LOCKED: { 926 if (message.isLocked()) { 927 env->CallVoidMethod( 928 frontend, 929 env->GetMethodID(clazz, "onLocked", "()V")); 930 } 931 break; 932 } 933 case FrontendScanMessageType::END: { 934 if (message.isEnd()) { 935 env->CallVoidMethod( 936 frontend, 937 env->GetMethodID(clazz, "onScanStopped", "()V")); 938 } 939 break; 940 } 941 case FrontendScanMessageType::PROGRESS_PERCENT: { 942 env->CallVoidMethod( 943 frontend, 944 env->GetMethodID(clazz, "onProgress", "(I)V"), 945 (jint) message.progressPercent()); 946 break; 947 } 948 case FrontendScanMessageType::FREQUENCY: { 949 std::vector<uint32_t> v = message.frequencies(); 950 jintArray freqs = env->NewIntArray(v.size()); 951 env->SetIntArrayRegion(freqs, 0, v.size(), reinterpret_cast<jint*>(&v[0])); 952 953 env->CallVoidMethod( 954 frontend, 955 env->GetMethodID(clazz, "onFrequenciesReport", "([I)V"), 956 freqs); 957 break; 958 } 959 case FrontendScanMessageType::SYMBOL_RATE: { 960 std::vector<uint32_t> v = message.symbolRates(); 961 jintArray symbolRates = env->NewIntArray(v.size()); 962 env->SetIntArrayRegion(symbolRates, 0, v.size(), reinterpret_cast<jint*>(&v[0])); 963 964 env->CallVoidMethod( 965 frontend, 966 env->GetMethodID(clazz, "onSymbolRates", "([I)V"), 967 symbolRates); 968 break; 969 } 970 case FrontendScanMessageType::HIERARCHY: { 971 env->CallVoidMethod( 972 frontend, 973 env->GetMethodID(clazz, "onHierarchy", "(I)V"), 974 (jint) message.hierarchy()); 975 break; 976 } 977 case FrontendScanMessageType::ANALOG_TYPE: { 978 env->CallVoidMethod( 979 frontend, 980 env->GetMethodID(clazz, "onSignalType", "(I)V"), 981 (jint) message.analogType()); 982 break; 983 } 984 case FrontendScanMessageType::PLP_IDS: { 985 std::vector<uint8_t> v = message.plpIds(); 986 std::vector<jint> jintV(v.begin(), v.end()); 987 jintArray plpIds = env->NewIntArray(v.size()); 988 env->SetIntArrayRegion(plpIds, 0, jintV.size(), &jintV[0]); 989 990 env->CallVoidMethod( 991 frontend, 992 env->GetMethodID(clazz, "onPlpIds", "([I)V"), 993 plpIds); 994 break; 995 } 996 case FrontendScanMessageType::GROUP_IDS: { 997 std::vector<uint8_t> v = message.groupIds(); 998 std::vector<jint> jintV(v.begin(), v.end()); 999 jintArray groupIds = env->NewIntArray(v.size()); 1000 env->SetIntArrayRegion(groupIds, 0, jintV.size(), &jintV[0]); 1001 1002 env->CallVoidMethod( 1003 frontend, 1004 env->GetMethodID(clazz, "onGroupIds", "([I)V"), 1005 groupIds); 1006 break; 1007 } 1008 case FrontendScanMessageType::INPUT_STREAM_IDS: { 1009 std::vector<uint16_t> v = message.inputStreamIds(); 1010 std::vector<jint> jintV(v.begin(), v.end()); 1011 jintArray streamIds = env->NewIntArray(v.size()); 1012 env->SetIntArrayRegion(streamIds, 0, jintV.size(), &jintV[0]); 1013 1014 env->CallVoidMethod( 1015 frontend, 1016 env->GetMethodID(clazz, "onInputStreamIds", "([I)V"), 1017 streamIds); 1018 break; 1019 } 1020 case FrontendScanMessageType::STANDARD: { 1021 FrontendScanMessage::Standard std = message.std(); 1022 jint standard; 1023 if (std.getDiscriminator() == FrontendScanMessage::Standard::hidl_discriminator::sStd) { 1024 standard = (jint) std.sStd(); 1025 env->CallVoidMethod( 1026 frontend, 1027 env->GetMethodID(clazz, "onDvbsStandard", "(I)V"), 1028 standard); 1029 } else if (std.getDiscriminator() == 1030 FrontendScanMessage::Standard::hidl_discriminator::tStd) { 1031 standard = (jint) std.tStd(); 1032 env->CallVoidMethod( 1033 frontend, 1034 env->GetMethodID(clazz, "onDvbtStandard", "(I)V"), 1035 standard); 1036 } else if (std.getDiscriminator() == 1037 FrontendScanMessage::Standard::hidl_discriminator::sifStd) { 1038 standard = (jint) std.sifStd(); 1039 env->CallVoidMethod( 1040 frontend, 1041 env->GetMethodID(clazz, "onAnalogSifStandard", "(I)V"), 1042 standard); 1043 } 1044 break; 1045 } 1046 case FrontendScanMessageType::ATSC3_PLP_INFO: { 1047 jclass plpClazz = env->FindClass("android/media/tv/tuner/frontend/Atsc3PlpInfo"); 1048 jmethodID init = env->GetMethodID(plpClazz, "<init>", "(IZ)V"); 1049 std::vector<FrontendScanAtsc3PlpInfo> plpInfos = message.atsc3PlpInfos(); 1050 jobjectArray array = env->NewObjectArray(plpInfos.size(), plpClazz, NULL); 1051 1052 for (int i = 0; i < plpInfos.size(); i++) { 1053 auto info = plpInfos[i]; 1054 jint plpId = (jint) info.plpId; 1055 jboolean lls = (jboolean) info.bLlsFlag; 1056 1057 jobject obj = env->NewObject(plpClazz, init, plpId, lls); 1058 env->SetObjectArrayElement(array, i, obj); 1059 } 1060 env->CallVoidMethod( 1061 frontend, 1062 env->GetMethodID(clazz, "onAtsc3PlpInfos", 1063 "([Landroid/media/tv/tuner/frontend/Atsc3PlpInfo;)V"), 1064 array); 1065 break; 1066 } 1067 } 1068 } 1069 1070 void FrontendClientCallbackImpl::onScanMessageExt1_1(FrontendScanMessageTypeExt1_1 type, 1071 const FrontendScanMessageExt1_1& message) { 1072 ALOGD("FrontendClientCallbackImpl::onScanMessageExt1_1, type=%d", type); 1073 JNIEnv *env = AndroidRuntime::getJNIEnv(); 1074 jclass clazz = env->FindClass("android/media/tv/tuner/Tuner"); 1075 jobject frontend(env->NewLocalRef(mObject)); 1076 if (env->IsSameObject(frontend, nullptr)) { 1077 ALOGE("FrontendClientCallbackImpl::onScanMessageExt1_1:" 1078 "Frontend object has been freed. Ignoring callback."); 1079 return; 1080 } 1081 switch(type) { 1082 case FrontendScanMessageTypeExt1_1::MODULATION: { 1083 jint modulation = -1; 1084 switch (message.modulation().getDiscriminator()) { 1085 case FrontendModulation::hidl_discriminator::dvbc: { 1086 modulation = (jint) message.modulation().dvbc(); 1087 break; 1088 } 1089 case FrontendModulation::hidl_discriminator::dvbt: { 1090 modulation = (jint) message.modulation().dvbt(); 1091 break; 1092 } 1093 case FrontendModulation::hidl_discriminator::dvbs: { 1094 modulation = (jint) message.modulation().dvbs(); 1095 break; 1096 } 1097 case FrontendModulation::hidl_discriminator::isdbs: { 1098 modulation = (jint) message.modulation().isdbs(); 1099 break; 1100 } 1101 case FrontendModulation::hidl_discriminator::isdbs3: { 1102 modulation = (jint) message.modulation().isdbs3(); 1103 break; 1104 } 1105 case FrontendModulation::hidl_discriminator::isdbt: { 1106 modulation = (jint) message.modulation().isdbt(); 1107 break; 1108 } 1109 case FrontendModulation::hidl_discriminator::atsc: { 1110 modulation = (jint) message.modulation().atsc(); 1111 break; 1112 } 1113 case FrontendModulation::hidl_discriminator::atsc3: { 1114 modulation = (jint) message.modulation().atsc3(); 1115 break; 1116 } 1117 case FrontendModulation::hidl_discriminator::dtmb: { 1118 modulation = (jint) message.modulation().dtmb(); 1119 break; 1120 } 1121 default: { 1122 break; 1123 } 1124 } 1125 if (modulation > 0) { 1126 env->CallVoidMethod( 1127 frontend, 1128 env->GetMethodID(clazz, "onModulationReported", "(I)V"), 1129 modulation); 1130 } 1131 break; 1132 } 1133 case FrontendScanMessageTypeExt1_1::HIGH_PRIORITY: { 1134 bool isHighPriority = message.isHighPriority(); 1135 env->CallVoidMethod( 1136 frontend, 1137 env->GetMethodID(clazz, "onPriorityReported", "(Z)V"), 1138 isHighPriority); 1139 break; 1140 } 1141 case FrontendScanMessageTypeExt1_1::DVBC_ANNEX: { 1142 jint dvbcAnnex = (jint) message.annex(); 1143 env->CallVoidMethod( 1144 frontend, 1145 env->GetMethodID(clazz, "onDvbcAnnexReported", "(I)V"), 1146 dvbcAnnex); 1147 break; 1148 } 1149 default: 1150 break; 1151 } 1152 } 1153 1154 FrontendClientCallbackImpl::~FrontendClientCallbackImpl() { 1155 JNIEnv *env = AndroidRuntime::getJNIEnv(); 1156 if (mObject != NULL) { 1157 env->DeleteWeakGlobalRef(mObject); 1158 mObject = NULL; 1159 } 1160 } 1161 1162 /////////////// Tuner /////////////////////// 1163 1164 sp<TunerClient> JTuner::mTunerClient; 1165 1166 JTuner::JTuner(JNIEnv *env, jobject thiz) 1167 : mClass(NULL) { 1168 jclass clazz = env->GetObjectClass(thiz); 1169 CHECK(clazz != NULL); 1170 1171 mClass = (jclass)env->NewGlobalRef(clazz); 1172 mObject = env->NewWeakGlobalRef(thiz); 1173 if (mTunerClient == NULL) { 1174 mTunerClient = new TunerClient(); 1175 } 1176 } 1177 1178 JTuner::~JTuner() { 1179 if (mFeClient != NULL) { 1180 mFeClient->close(); 1181 } 1182 if (mDemuxClient != NULL) { 1183 mDemuxClient->close(); 1184 } 1185 JNIEnv *env = AndroidRuntime::getJNIEnv(); 1186 1187 env->DeleteWeakGlobalRef(mObject); 1188 env->DeleteGlobalRef(mClass); 1189 mTunerClient = NULL; 1190 mFeClient = NULL; 1191 mDemuxClient = NULL; 1192 mClass = NULL; 1193 mObject = NULL; 1194 } 1195 1196 jint JTuner::getTunerVersion() { 1197 ALOGD("JTuner::getTunerVersion()"); 1198 return (jint) mTunerClient->getHalTunerVersion(); 1199 } 1200 1201 jobject JTuner::getFrontendIds() { 1202 ALOGD("JTuner::getFrontendIds()"); 1203 vector<FrontendId> ids = mTunerClient->getFrontendIds(); 1204 if (ids.size() == 0) { 1205 ALOGW("Frontend isn't available"); 1206 return NULL; 1207 } 1208 1209 JNIEnv *env = AndroidRuntime::getJNIEnv(); 1210 jclass arrayListClazz = env->FindClass("java/util/ArrayList"); 1211 jmethodID arrayListAdd = env->GetMethodID(arrayListClazz, "add", "(Ljava/lang/Object;)Z"); 1212 jobject obj = env->NewObject(arrayListClazz, env->GetMethodID(arrayListClazz, "<init>", "()V")); 1213 1214 jclass integerClazz = env->FindClass("java/lang/Integer"); 1215 jmethodID intInit = env->GetMethodID(integerClazz, "<init>", "(I)V"); 1216 1217 for (int i=0; i < ids.size(); i++) { 1218 jobject idObj = env->NewObject(integerClazz, intInit, ids[i]); 1219 env->CallBooleanMethod(obj, arrayListAdd, idObj); 1220 } 1221 return obj; 1222 } 1223 1224 jobject JTuner::openFrontendByHandle(int feHandle) { 1225 // TODO: Handle reopening frontend with different handle 1226 sp<FrontendClient> feClient = mTunerClient->openFrontend(feHandle); 1227 if (feClient == NULL) { 1228 ALOGE("Failed to open frontend"); 1229 return NULL; 1230 } 1231 mFeClient = feClient; 1232 1233 mFeId = mFeClient->getId(); 1234 if (mDemuxClient != NULL) { 1235 mDemuxClient->setFrontendDataSource(mFeClient); 1236 } 1237 1238 JNIEnv *env = AndroidRuntime::getJNIEnv(); 1239 jobject tuner(env->NewLocalRef(mObject)); 1240 if (env->IsSameObject(tuner, nullptr)) { 1241 ALOGE("openFrontendByHandle" 1242 "Tuner object has been freed. Failed to open frontend."); 1243 return NULL; 1244 } 1245 1246 sp<FrontendClientCallbackImpl> feClientCb = new FrontendClientCallbackImpl(mObject); 1247 mFeClient->setCallback(feClientCb); 1248 // TODO: add more fields to frontend 1249 return env->NewObject( 1250 env->FindClass("android/media/tv/tuner/Tuner$Frontend"), 1251 gFields.frontendInitID, 1252 tuner, 1253 (jint) mFeId); 1254 } 1255 1256 jobject JTuner::getAnalogFrontendCaps(JNIEnv *env, FrontendInfo::FrontendCapabilities& caps) { 1257 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/AnalogFrontendCapabilities"); 1258 jmethodID capsInit = env->GetMethodID(clazz, "<init>", "(II)V"); 1259 1260 jint typeCap = caps.analogCaps().typeCap; 1261 jint sifStandardCap = caps.analogCaps().sifStandardCap; 1262 return env->NewObject(clazz, capsInit, typeCap, sifStandardCap); 1263 } 1264 1265 jobject JTuner::getAtsc3FrontendCaps(JNIEnv *env, FrontendInfo::FrontendCapabilities& caps) { 1266 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/Atsc3FrontendCapabilities"); 1267 jmethodID capsInit = env->GetMethodID(clazz, "<init>", "(IIIIII)V"); 1268 1269 jint bandwidthCap = caps.atsc3Caps().bandwidthCap; 1270 jint modulationCap = caps.atsc3Caps().modulationCap; 1271 jint timeInterleaveModeCap = caps.atsc3Caps().timeInterleaveModeCap; 1272 jint codeRateCap = caps.atsc3Caps().codeRateCap; 1273 jint fecCap = caps.atsc3Caps().fecCap; 1274 jint demodOutputFormatCap = caps.atsc3Caps().demodOutputFormatCap; 1275 1276 return env->NewObject(clazz, capsInit, bandwidthCap, modulationCap, timeInterleaveModeCap, 1277 codeRateCap, fecCap, demodOutputFormatCap); 1278 } 1279 1280 jobject JTuner::getAtscFrontendCaps(JNIEnv *env, FrontendInfo::FrontendCapabilities& caps) { 1281 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/AtscFrontendCapabilities"); 1282 jmethodID capsInit = env->GetMethodID(clazz, "<init>", "(I)V"); 1283 1284 jint modulationCap = caps.atscCaps().modulationCap; 1285 1286 return env->NewObject(clazz, capsInit, modulationCap); 1287 } 1288 1289 jobject JTuner::getDvbcFrontendCaps(JNIEnv *env, FrontendInfo::FrontendCapabilities& caps) { 1290 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/DvbcFrontendCapabilities"); 1291 jmethodID capsInit = env->GetMethodID(clazz, "<init>", "(IJI)V"); 1292 1293 jint modulationCap = caps.dvbcCaps().modulationCap; 1294 jlong fecCap = caps.dvbcCaps().fecCap; 1295 jint annexCap = caps.dvbcCaps().annexCap; 1296 1297 return env->NewObject(clazz, capsInit, modulationCap, fecCap, annexCap); 1298 } 1299 1300 jobject JTuner::getDvbsFrontendCaps(JNIEnv *env, FrontendInfo::FrontendCapabilities& caps) { 1301 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/DvbsFrontendCapabilities"); 1302 jmethodID capsInit = env->GetMethodID(clazz, "<init>", "(IJI)V"); 1303 1304 jint modulationCap = caps.dvbsCaps().modulationCap; 1305 jlong innerfecCap = caps.dvbsCaps().innerfecCap; 1306 jint standard = caps.dvbsCaps().standard; 1307 1308 return env->NewObject(clazz, capsInit, modulationCap, innerfecCap, standard); 1309 } 1310 1311 jobject JTuner::getDvbtFrontendCaps(JNIEnv *env, FrontendInfo::FrontendCapabilities& caps) { 1312 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/DvbtFrontendCapabilities"); 1313 jmethodID capsInit = env->GetMethodID(clazz, "<init>", "(IIIIIIZZ)V"); 1314 1315 jint transmissionModeCap = caps.dvbtCaps().transmissionModeCap; 1316 jint bandwidthCap = caps.dvbtCaps().bandwidthCap; 1317 jint constellationCap = caps.dvbtCaps().constellationCap; 1318 jint coderateCap = caps.dvbtCaps().coderateCap; 1319 jint hierarchyCap = caps.dvbtCaps().hierarchyCap; 1320 jint guardIntervalCap = caps.dvbtCaps().guardIntervalCap; 1321 jboolean isT2Supported = caps.dvbtCaps().isT2Supported; 1322 jboolean isMisoSupported = caps.dvbtCaps().isMisoSupported; 1323 1324 return env->NewObject(clazz, capsInit, transmissionModeCap, bandwidthCap, constellationCap, 1325 coderateCap, hierarchyCap, guardIntervalCap, isT2Supported, isMisoSupported); 1326 } 1327 1328 jobject JTuner::getIsdbs3FrontendCaps(JNIEnv *env, FrontendInfo::FrontendCapabilities& caps) { 1329 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/Isdbs3FrontendCapabilities"); 1330 jmethodID capsInit = env->GetMethodID(clazz, "<init>", "(II)V"); 1331 1332 jint modulationCap = caps.isdbs3Caps().modulationCap; 1333 jint coderateCap = caps.isdbs3Caps().coderateCap; 1334 1335 return env->NewObject(clazz, capsInit, modulationCap, coderateCap); 1336 } 1337 1338 jobject JTuner::getIsdbsFrontendCaps(JNIEnv *env, FrontendInfo::FrontendCapabilities& caps) { 1339 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/IsdbsFrontendCapabilities"); 1340 jmethodID capsInit = env->GetMethodID(clazz, "<init>", "(II)V"); 1341 1342 jint modulationCap = caps.isdbsCaps().modulationCap; 1343 jint coderateCap = caps.isdbsCaps().coderateCap; 1344 1345 return env->NewObject(clazz, capsInit, modulationCap, coderateCap); 1346 } 1347 1348 jobject JTuner::getIsdbtFrontendCaps(JNIEnv *env, FrontendInfo::FrontendCapabilities& caps) { 1349 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/IsdbtFrontendCapabilities"); 1350 jmethodID capsInit = env->GetMethodID(clazz, "<init>", "(IIIII)V"); 1351 1352 jint modeCap = caps.isdbtCaps().modeCap; 1353 jint bandwidthCap = caps.isdbtCaps().bandwidthCap; 1354 jint modulationCap = caps.isdbtCaps().modulationCap; 1355 jint coderateCap = caps.isdbtCaps().coderateCap; 1356 jint guardIntervalCap = caps.isdbtCaps().guardIntervalCap; 1357 1358 return env->NewObject(clazz, capsInit, modeCap, bandwidthCap, modulationCap, coderateCap, 1359 guardIntervalCap); 1360 } 1361 1362 jobject JTuner::getDtmbFrontendCaps(JNIEnv *env, int id) { 1363 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/DtmbFrontendCapabilities"); 1364 jmethodID capsInit = env->GetMethodID(clazz, "<init>", "(IIIIII)V"); 1365 1366 shared_ptr<FrontendDtmbCapabilities> dtmbCaps = mTunerClient->getFrontendDtmbCapabilities(id); 1367 if (dtmbCaps == NULL) { 1368 return NULL; 1369 } 1370 1371 jint modulationCap = dtmbCaps->modulationCap; 1372 jint transmissionModeCap = dtmbCaps->transmissionModeCap; 1373 jint guardIntervalCap = dtmbCaps->guardIntervalCap; 1374 jint interleaveModeCap = dtmbCaps->interleaveModeCap; 1375 jint codeRateCap = dtmbCaps->codeRateCap; 1376 jint bandwidthCap = dtmbCaps->bandwidthCap; 1377 1378 return env->NewObject(clazz, capsInit, modulationCap, transmissionModeCap, guardIntervalCap, 1379 interleaveModeCap, codeRateCap, bandwidthCap); 1380 } 1381 1382 jobject JTuner::getFrontendInfo(int id) { 1383 shared_ptr<FrontendInfo> feInfo; 1384 feInfo = mTunerClient->getFrontendInfo(id); 1385 if (feInfo == NULL) { 1386 return NULL; 1387 } 1388 1389 JNIEnv *env = AndroidRuntime::getJNIEnv(); 1390 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/FrontendInfo"); 1391 jmethodID infoInit = env->GetMethodID(clazz, "<init>", 1392 "(IIIIIIII[ILandroid/media/tv/tuner/frontend/FrontendCapabilities;)V"); 1393 1394 jint type = (jint) feInfo->type; 1395 jint minFrequency = feInfo->minFrequency; 1396 jint maxFrequency = feInfo->maxFrequency; 1397 jint minSymbolRate = feInfo->minSymbolRate; 1398 jint maxSymbolRate = feInfo->maxSymbolRate; 1399 jint acquireRange = feInfo->acquireRange; 1400 jint exclusiveGroupId = feInfo->exclusiveGroupId; 1401 jintArray statusCaps = env->NewIntArray(feInfo->statusCaps.size()); 1402 env->SetIntArrayRegion( 1403 statusCaps, 0, feInfo->statusCaps.size(), 1404 reinterpret_cast<jint*>(&feInfo->statusCaps[0])); 1405 FrontendInfo::FrontendCapabilities caps = feInfo->frontendCaps; 1406 1407 jobject jcaps = NULL; 1408 1409 if (feInfo->type == static_cast<FrontendType>( 1410 ::android::hardware::tv::tuner::V1_1::FrontendType::DTMB)) { 1411 jcaps = getDtmbFrontendCaps(env, id); 1412 } 1413 1414 switch(feInfo->type) { 1415 case FrontendType::ANALOG: 1416 if (FrontendInfo::FrontendCapabilities::hidl_discriminator::analogCaps 1417 == caps.getDiscriminator()) { 1418 jcaps = getAnalogFrontendCaps(env, caps); 1419 } 1420 break; 1421 case FrontendType::ATSC3: 1422 if (FrontendInfo::FrontendCapabilities::hidl_discriminator::atsc3Caps 1423 == caps.getDiscriminator()) { 1424 jcaps = getAtsc3FrontendCaps(env, caps); 1425 } 1426 break; 1427 case FrontendType::ATSC: 1428 if (FrontendInfo::FrontendCapabilities::hidl_discriminator::atscCaps 1429 == caps.getDiscriminator()) { 1430 jcaps = getAtscFrontendCaps(env, caps); 1431 } 1432 break; 1433 case FrontendType::DVBC: 1434 if (FrontendInfo::FrontendCapabilities::hidl_discriminator::dvbcCaps 1435 == caps.getDiscriminator()) { 1436 jcaps = getDvbcFrontendCaps(env, caps); 1437 } 1438 break; 1439 case FrontendType::DVBS: 1440 if (FrontendInfo::FrontendCapabilities::hidl_discriminator::dvbsCaps 1441 == caps.getDiscriminator()) { 1442 jcaps = getDvbsFrontendCaps(env, caps); 1443 } 1444 break; 1445 case FrontendType::DVBT: 1446 if (FrontendInfo::FrontendCapabilities::hidl_discriminator::dvbtCaps 1447 == caps.getDiscriminator()) { 1448 jcaps = getDvbtFrontendCaps(env, caps); 1449 } 1450 break; 1451 case FrontendType::ISDBS: 1452 if (FrontendInfo::FrontendCapabilities::hidl_discriminator::isdbsCaps 1453 == caps.getDiscriminator()) { 1454 jcaps = getIsdbsFrontendCaps(env, caps); 1455 } 1456 break; 1457 case FrontendType::ISDBS3: 1458 if (FrontendInfo::FrontendCapabilities::hidl_discriminator::isdbs3Caps 1459 == caps.getDiscriminator()) { 1460 jcaps = getIsdbs3FrontendCaps(env, caps); 1461 } 1462 break; 1463 case FrontendType::ISDBT: 1464 if (FrontendInfo::FrontendCapabilities::hidl_discriminator::isdbtCaps 1465 == caps.getDiscriminator()) { 1466 jcaps = getIsdbtFrontendCaps(env, caps); 1467 } 1468 break; 1469 default: 1470 break; 1471 } 1472 1473 return env->NewObject( 1474 clazz, infoInit, (jint) id, type, minFrequency, maxFrequency, minSymbolRate, 1475 maxSymbolRate, acquireRange, exclusiveGroupId, statusCaps, jcaps); 1476 } 1477 1478 jobject JTuner::openLnbByHandle(int handle) { 1479 if (mTunerClient == NULL) { 1480 return NULL; 1481 } 1482 1483 sp<LnbClient> lnbClient; 1484 sp<LnbClientCallbackImpl> callback = new LnbClientCallbackImpl(); 1485 lnbClient = mTunerClient->openLnb(handle); 1486 if (lnbClient == NULL) { 1487 ALOGD("Failed to open lnb, handle = %d", handle); 1488 return NULL; 1489 } 1490 1491 if (lnbClient->setCallback(callback) != Result::SUCCESS) { 1492 ALOGD("Failed to set lnb callback"); 1493 return NULL; 1494 } 1495 1496 JNIEnv *env = AndroidRuntime::getJNIEnv(); 1497 jobject lnbObj = env->NewObject( 1498 env->FindClass("android/media/tv/tuner/Lnb"), 1499 gFields.lnbInitID); 1500 1501 lnbClient->incStrong(lnbObj); 1502 env->SetLongField(lnbObj, gFields.lnbContext, (jlong)lnbClient.get()); 1503 callback->setLnb(env->NewWeakGlobalRef(lnbObj)); 1504 1505 return lnbObj; 1506 } 1507 1508 jobject JTuner::openLnbByName(jstring name) { 1509 if (mTunerClient == NULL) { 1510 return NULL; 1511 } 1512 1513 JNIEnv *env = AndroidRuntime::getJNIEnv(); 1514 std::string lnbName(env->GetStringUTFChars(name, nullptr)); 1515 sp<LnbClient> lnbClient; 1516 sp<LnbClientCallbackImpl> callback = new LnbClientCallbackImpl(); 1517 lnbClient = mTunerClient->openLnbByName(lnbName); 1518 if (lnbClient == NULL) { 1519 ALOGD("Failed to open lnb by name, name = %s", lnbName.c_str()); 1520 return NULL; 1521 } 1522 1523 if (lnbClient->setCallback(callback) != Result::SUCCESS) { 1524 ALOGD("Failed to set lnb callback"); 1525 return NULL; 1526 } 1527 1528 jobject lnbObj = env->NewObject( 1529 env->FindClass("android/media/tv/tuner/Lnb"), 1530 gFields.lnbInitID); 1531 1532 lnbClient->incStrong(lnbObj); 1533 env->SetLongField(lnbObj, gFields.lnbContext, (jlong)lnbClient.get()); 1534 callback->setLnb(env->NewWeakGlobalRef(lnbObj)); 1535 1536 return lnbObj; 1537 } 1538 1539 int JTuner::tune(const FrontendSettings& settings, const FrontendSettingsExt1_1& settingsExt1_1) { 1540 if (mFeClient == nullptr) { 1541 ALOGE("frontend is not initialized"); 1542 return (int)Result::INVALID_STATE; 1543 } 1544 return (int) mFeClient->tune(settings, settingsExt1_1); 1545 } 1546 1547 int JTuner::stopTune() { 1548 if (mFeClient == nullptr) { 1549 ALOGE("frontend is not initialized"); 1550 return (int)Result::INVALID_STATE; 1551 } 1552 return (int) mFeClient->stopTune(); 1553 } 1554 1555 int JTuner::scan(const FrontendSettings& settings, FrontendScanType scanType, 1556 const FrontendSettingsExt1_1& settingsExt1_1) { 1557 if (mFeClient == NULL) { 1558 ALOGE("frontend client is not initialized"); 1559 return (int)Result::INVALID_STATE; 1560 } 1561 Result result = mFeClient->scan(settings, scanType, settingsExt1_1); 1562 return (int)result; 1563 } 1564 1565 int JTuner::stopScan() { 1566 if (mFeClient == NULL) { 1567 ALOGE("frontend client is not initialized"); 1568 return (int)Result::INVALID_STATE; 1569 } 1570 Result result = mFeClient->stopScan(); 1571 return (int)result; 1572 } 1573 1574 int JTuner::setLnb(sp<LnbClient> lnbClient) { 1575 if (mFeClient == NULL) { 1576 ALOGE("frontend client is not initialized"); 1577 return (int)Result::INVALID_STATE; 1578 } 1579 if (lnbClient == NULL) { 1580 ALOGE("lnb is not initialized"); 1581 return (int)Result::INVALID_STATE; 1582 } 1583 Result result = mFeClient->setLnb(lnbClient); 1584 return (int)result; 1585 } 1586 1587 int JTuner::setLna(bool enable) { 1588 if (mFeClient == NULL) { 1589 ALOGE("frontend client is not initialized"); 1590 return (int)Result::INVALID_STATE; 1591 } 1592 Result result = mFeClient->setLna(enable); 1593 return (int)result; 1594 } 1595 1596 Result JTuner::openDemux(int handle) { 1597 if (mTunerClient == nullptr) { 1598 return Result::NOT_INITIALIZED; 1599 } 1600 1601 if (mDemuxClient == nullptr) { 1602 mDemuxClient = mTunerClient->openDemux(handle); 1603 if (mDemuxClient == NULL) { 1604 ALOGE("Failed to open demux"); 1605 return Result::UNKNOWN_ERROR; 1606 } 1607 if (mFeClient != NULL) { 1608 mDemuxClient->setFrontendDataSource(mFeClient); 1609 } 1610 } 1611 1612 return Result::SUCCESS; 1613 } 1614 1615 jint JTuner::close() { 1616 Result res = Result::SUCCESS; 1617 1618 if (mFeClient != NULL) { 1619 res = mFeClient->close(); 1620 if (res != Result::SUCCESS) { 1621 return (jint) res; 1622 } 1623 mFeClient = NULL; 1624 } 1625 if (mDemuxClient != NULL) { 1626 res = mDemuxClient->close(); 1627 if (res != Result::SUCCESS) { 1628 return (jint) res; 1629 } 1630 mDemuxClient = NULL; 1631 } 1632 return (jint) res; 1633 } 1634 1635 jobject JTuner::getAvSyncHwId(sp<FilterClient> filterClient) { 1636 if (mDemuxClient == NULL) { 1637 return NULL; 1638 } 1639 1640 int avSyncHwId = mDemuxClient->getAvSyncHwId(filterClient); 1641 if (avSyncHwId >= 0) { 1642 JNIEnv *env = AndroidRuntime::getJNIEnv(); 1643 jclass integerClazz = env->FindClass("java/lang/Integer"); 1644 jmethodID intInit = env->GetMethodID(integerClazz, "<init>", "(I)V"); 1645 return env->NewObject(integerClazz, intInit, avSyncHwId); 1646 } 1647 return NULL; 1648 } 1649 1650 jobject JTuner::getAvSyncTime(jint id) { 1651 if (mDemuxClient == NULL) { 1652 return NULL; 1653 } 1654 long time = mDemuxClient->getAvSyncTime((int)id); 1655 if (time >= 0) { 1656 JNIEnv *env = AndroidRuntime::getJNIEnv(); 1657 jclass longClazz = env->FindClass("java/lang/Long"); 1658 jmethodID longInit = env->GetMethodID(longClazz, "<init>", "(J)V"); 1659 return env->NewObject(longClazz, longInit, static_cast<jlong>(time)); 1660 } 1661 return NULL; 1662 } 1663 1664 int JTuner::connectCiCam(jint id) { 1665 if (mDemuxClient == NULL) { 1666 return (int)Result::NOT_INITIALIZED; 1667 } 1668 Result r = mDemuxClient->connectCiCam((int)id); 1669 return (int) r; 1670 } 1671 1672 int JTuner::linkCiCam(int id) { 1673 if (mFeClient == NULL) { 1674 ALOGE("frontend client is not initialized"); 1675 return (int)Constant::INVALID_LTS_ID; 1676 } 1677 return mFeClient->linkCiCamToFrontend(id); 1678 } 1679 1680 int JTuner::disconnectCiCam() { 1681 if (mDemuxClient == NULL) { 1682 return (int)Result::NOT_INITIALIZED; 1683 } 1684 Result r = mDemuxClient->disconnectCiCam(); 1685 return (int) r; 1686 } 1687 1688 1689 int JTuner::unlinkCiCam(int id) { 1690 if (mFeClient == NULL) { 1691 ALOGE("frontend client is not initialized"); 1692 return (int)Result::INVALID_STATE; 1693 } 1694 1695 Result r = mFeClient->unlinkCiCamToFrontend(id); 1696 1697 return (int) r; 1698 } 1699 1700 jobject JTuner::openDescrambler() { 1701 ALOGD("JTuner::openDescrambler"); 1702 if (mTunerClient == nullptr || mDemuxClient == nullptr) { 1703 return NULL; 1704 } 1705 sp<DescramblerClient> descramblerClient = mTunerClient->openDescrambler(0/*unused*/); 1706 1707 if (descramblerClient == NULL) { 1708 ALOGD("Failed to open descrambler"); 1709 return NULL; 1710 } 1711 1712 descramblerClient->setDemuxSource(mDemuxClient); 1713 1714 JNIEnv *env = AndroidRuntime::getJNIEnv(); 1715 jobject descramblerObj = 1716 env->NewObject( 1717 env->FindClass("android/media/tv/tuner/Descrambler"), 1718 gFields.descramblerInitID); 1719 1720 descramblerClient->incStrong(descramblerObj); 1721 env->SetLongField(descramblerObj, gFields.descramblerContext, (jlong)descramblerClient.get()); 1722 1723 return descramblerObj; 1724 } 1725 1726 jobject JTuner::openFilter(DemuxFilterType type, int bufferSize) { 1727 if (mDemuxClient == NULL) { 1728 return NULL; 1729 } 1730 1731 sp<FilterClient> filterClient; 1732 sp<FilterClientCallbackImpl> callback = new FilterClientCallbackImpl(); 1733 filterClient = mDemuxClient->openFilter(type, bufferSize, callback); 1734 if (filterClient == NULL) { 1735 ALOGD("Failed to open filter, type = %d", type.mainType); 1736 return NULL; 1737 } 1738 uint64_t fId; 1739 Result res = filterClient->getId64Bit(fId); 1740 if (res != Result::SUCCESS) { 1741 uint32_t id; 1742 filterClient->getId(id); 1743 fId = static_cast<uint64_t>(id); 1744 } 1745 1746 JNIEnv *env = AndroidRuntime::getJNIEnv(); 1747 jobject filterObj = 1748 env->NewObject( 1749 env->FindClass("android/media/tv/tuner/filter/Filter"), 1750 gFields.filterInitID, 1751 (jlong) fId); 1752 1753 filterClient->incStrong(filterObj); 1754 env->SetLongField(filterObj, gFields.filterContext, (jlong)filterClient.get()); 1755 callback->setFilter(env->NewWeakGlobalRef(filterObj), filterClient); 1756 1757 return filterObj; 1758 } 1759 1760 jobject JTuner::openTimeFilter() { 1761 if (mDemuxClient == NULL) { 1762 return NULL; 1763 } 1764 1765 JNIEnv *env = AndroidRuntime::getJNIEnv(); 1766 jobject timeFilterObj = 1767 env->NewObject( 1768 env->FindClass("android/media/tv/tuner/filter/TimeFilter"), 1769 gFields.timeFilterInitID); 1770 sp<TimeFilterClient> timeFilterClient = mDemuxClient->openTimeFilter(); 1771 if (timeFilterClient == NULL) { 1772 ALOGD("Failed to open time filter."); 1773 return NULL; 1774 } 1775 timeFilterClient->incStrong(timeFilterObj); 1776 env->SetLongField(timeFilterObj, gFields.timeFilterContext, (jlong)timeFilterClient.get()); 1777 1778 return timeFilterObj; 1779 } 1780 1781 jobject JTuner::openDvr(DvrType type, jlong bufferSize) { 1782 ALOGD("JTuner::openDvr"); 1783 if (mDemuxClient == NULL) { 1784 return NULL; 1785 } 1786 sp<DvrClient> dvrClient; 1787 sp<DvrClientCallbackImpl> callback = new DvrClientCallbackImpl(); 1788 dvrClient = mDemuxClient->openDvr(type, (int) bufferSize, callback); 1789 1790 if (dvrClient == NULL) { 1791 return NULL; 1792 } 1793 1794 JNIEnv *env = AndroidRuntime::getJNIEnv(); 1795 jobject dvrObj; 1796 if (type == DvrType::RECORD) { 1797 dvrObj = 1798 env->NewObject( 1799 env->FindClass("android/media/tv/tuner/dvr/DvrRecorder"), 1800 gFields.dvrRecorderInitID); 1801 dvrClient->incStrong(dvrObj); 1802 env->SetLongField(dvrObj, gFields.dvrRecorderContext, (jlong)dvrClient.get()); 1803 } else { 1804 dvrObj = 1805 env->NewObject( 1806 env->FindClass("android/media/tv/tuner/dvr/DvrPlayback"), 1807 gFields.dvrPlaybackInitID); 1808 dvrClient->incStrong(dvrObj); 1809 env->SetLongField(dvrObj, gFields.dvrPlaybackContext, (jlong)dvrClient.get()); 1810 } 1811 1812 callback->setDvr(env->NewWeakGlobalRef(dvrObj)); 1813 1814 return dvrObj; 1815 } 1816 1817 jobject JTuner::getDemuxCaps() { 1818 if (mTunerClient == NULL) { 1819 return NULL; 1820 } 1821 1822 shared_ptr<DemuxCapabilities> caps; 1823 caps = mTunerClient->getDemuxCaps(); 1824 if (caps == NULL) { 1825 return NULL; 1826 } 1827 1828 JNIEnv *env = AndroidRuntime::getJNIEnv(); 1829 jclass clazz = env->FindClass("android/media/tv/tuner/DemuxCapabilities"); 1830 jmethodID capsInit = env->GetMethodID(clazz, "<init>", "(IIIIIIIIIJI[IZ)V"); 1831 1832 jint numDemux = caps->numDemux; 1833 jint numRecord = caps->numRecord; 1834 jint numPlayback = caps->numPlayback; 1835 jint numTsFilter = caps->numTsFilter; 1836 jint numSectionFilter = caps->numSectionFilter; 1837 jint numAudioFilter = caps->numAudioFilter; 1838 jint numVideoFilter = caps->numVideoFilter; 1839 jint numPesFilter = caps->numPesFilter; 1840 jint numPcrFilter = caps->numPcrFilter; 1841 jlong numBytesInSectionFilter = caps->numBytesInSectionFilter; 1842 jint filterCaps = static_cast<jint>(caps->filterCaps); 1843 jboolean bTimeFilter = caps->bTimeFilter; 1844 1845 jintArray linkCaps = env->NewIntArray(caps->linkCaps.size()); 1846 env->SetIntArrayRegion( 1847 linkCaps, 0, caps->linkCaps.size(), reinterpret_cast<jint*>(&caps->linkCaps[0])); 1848 1849 return env->NewObject(clazz, capsInit, numDemux, numRecord, numPlayback, numTsFilter, 1850 numSectionFilter, numAudioFilter, numVideoFilter, numPesFilter, numPcrFilter, 1851 numBytesInSectionFilter, filterCaps, linkCaps, bTimeFilter); 1852 } 1853 1854 jobject JTuner::getFrontendStatus(jintArray types) { 1855 if (mFeClient == NULL) { 1856 return NULL; 1857 } 1858 JNIEnv *env = AndroidRuntime::getJNIEnv(); 1859 jsize size = env->GetArrayLength(types); 1860 jint intTypes[size]; 1861 env->GetIntArrayRegion(types, 0, size, intTypes); 1862 std::vector<FrontendStatusType> v; 1863 std::vector<FrontendStatusTypeExt1_1> v_1_1; 1864 for (int i = 0; i < size; i++) { 1865 if (isV1_1ExtendedStatusType(intTypes[i])) { 1866 v_1_1.push_back(static_cast<FrontendStatusTypeExt1_1>(intTypes[i])); 1867 } else { 1868 v.push_back(static_cast<FrontendStatusType>(intTypes[i])); 1869 } 1870 } 1871 1872 hidl_vec<FrontendStatus> status = mFeClient->getStatus(v); 1873 hidl_vec<FrontendStatusExt1_1> status_1_1 = mFeClient->getStatusExtended_1_1(v_1_1); 1874 1875 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/FrontendStatus"); 1876 jmethodID init = env->GetMethodID(clazz, "<init>", "()V"); 1877 jobject statusObj = env->NewObject(clazz, init); 1878 1879 jclass intClazz = env->FindClass("java/lang/Integer"); 1880 jmethodID initInt = env->GetMethodID(intClazz, "<init>", "(I)V"); 1881 jclass booleanClazz = env->FindClass("java/lang/Boolean"); 1882 jmethodID initBoolean = env->GetMethodID(booleanClazz, "<init>", "(Z)V"); 1883 1884 for (auto s : status) { 1885 switch(s.getDiscriminator()) { 1886 case FrontendStatus::hidl_discriminator::isDemodLocked: { 1887 jfieldID field = env->GetFieldID(clazz, "mIsDemodLocked", "Ljava/lang/Boolean;"); 1888 jobject newBooleanObj = env->NewObject( 1889 booleanClazz, initBoolean, static_cast<jboolean>(s.isDemodLocked())); 1890 env->SetObjectField(statusObj, field, newBooleanObj); 1891 break; 1892 } 1893 case FrontendStatus::hidl_discriminator::snr: { 1894 jfieldID field = env->GetFieldID(clazz, "mSnr", "Ljava/lang/Integer;"); 1895 jobject newIntegerObj = env->NewObject( 1896 intClazz, initInt, static_cast<jint>(s.snr())); 1897 env->SetObjectField(statusObj, field, newIntegerObj); 1898 break; 1899 } 1900 case FrontendStatus::hidl_discriminator::ber: { 1901 jfieldID field = env->GetFieldID(clazz, "mBer", "Ljava/lang/Integer;"); 1902 jobject newIntegerObj = env->NewObject( 1903 intClazz, initInt, static_cast<jint>(s.ber())); 1904 env->SetObjectField(statusObj, field, newIntegerObj); 1905 break; 1906 } 1907 case FrontendStatus::hidl_discriminator::per: { 1908 jfieldID field = env->GetFieldID(clazz, "mPer", "Ljava/lang/Integer;"); 1909 jobject newIntegerObj = env->NewObject( 1910 intClazz, initInt, static_cast<jint>(s.per())); 1911 env->SetObjectField(statusObj, field, newIntegerObj); 1912 break; 1913 } 1914 case FrontendStatus::hidl_discriminator::preBer: { 1915 jfieldID field = env->GetFieldID(clazz, "mPerBer", "Ljava/lang/Integer;"); 1916 jobject newIntegerObj = env->NewObject( 1917 intClazz, initInt, static_cast<jint>(s.preBer())); 1918 env->SetObjectField(statusObj, field, newIntegerObj); 1919 break; 1920 } 1921 case FrontendStatus::hidl_discriminator::signalQuality: { 1922 jfieldID field = env->GetFieldID(clazz, "mSignalQuality", "Ljava/lang/Integer;"); 1923 jobject newIntegerObj = env->NewObject( 1924 intClazz, initInt, static_cast<jint>(s.signalQuality())); 1925 env->SetObjectField(statusObj, field, newIntegerObj); 1926 break; 1927 } 1928 case FrontendStatus::hidl_discriminator::signalStrength: { 1929 jfieldID field = env->GetFieldID(clazz, "mSignalStrength", "Ljava/lang/Integer;"); 1930 jobject newIntegerObj = env->NewObject( 1931 intClazz, initInt, static_cast<jint>(s.signalStrength())); 1932 env->SetObjectField(statusObj, field, newIntegerObj); 1933 break; 1934 } 1935 case FrontendStatus::hidl_discriminator::symbolRate: { 1936 jfieldID field = env->GetFieldID(clazz, "mSymbolRate", "Ljava/lang/Integer;"); 1937 jobject newIntegerObj = env->NewObject( 1938 intClazz, initInt, static_cast<jint>(s.symbolRate())); 1939 env->SetObjectField(statusObj, field, newIntegerObj); 1940 break; 1941 } 1942 case FrontendStatus::hidl_discriminator::innerFec: { 1943 jfieldID field = env->GetFieldID(clazz, "mInnerFec", "Ljava/lang/Long;"); 1944 jclass longClazz = env->FindClass("java/lang/Long"); 1945 jmethodID initLong = env->GetMethodID(longClazz, "<init>", "(J)V"); 1946 jobject newLongObj = env->NewObject( 1947 longClazz, initLong, static_cast<jlong>(s.innerFec())); 1948 env->SetObjectField(statusObj, field, newLongObj); 1949 break; 1950 } 1951 case FrontendStatus::hidl_discriminator::modulation: { 1952 jfieldID field = env->GetFieldID(clazz, "mModulation", "Ljava/lang/Integer;"); 1953 FrontendModulationStatus modulation = s.modulation(); 1954 jint intModulation; 1955 bool valid = true; 1956 switch(modulation.getDiscriminator()) { 1957 case FrontendModulationStatus::hidl_discriminator::dvbc: { 1958 intModulation = static_cast<jint>(modulation.dvbc()); 1959 break; 1960 } 1961 case FrontendModulationStatus::hidl_discriminator::dvbs: { 1962 intModulation = static_cast<jint>(modulation.dvbs()); 1963 break; 1964 } 1965 case FrontendModulationStatus::hidl_discriminator::isdbs: { 1966 intModulation = static_cast<jint>(modulation.isdbs()); 1967 break; 1968 } 1969 case FrontendModulationStatus::hidl_discriminator::isdbs3: { 1970 intModulation = static_cast<jint>(modulation.isdbs3()); 1971 break; 1972 } 1973 case FrontendModulationStatus::hidl_discriminator::isdbt: { 1974 intModulation = static_cast<jint>(modulation.isdbt()); 1975 break; 1976 } 1977 default: { 1978 valid = false; 1979 break; 1980 } 1981 } 1982 if (valid) { 1983 jobject newIntegerObj = env->NewObject(intClazz, initInt, intModulation); 1984 env->SetObjectField(statusObj, field, newIntegerObj); 1985 } 1986 break; 1987 } 1988 case FrontendStatus::hidl_discriminator::inversion: { 1989 jfieldID field = env->GetFieldID(clazz, "mInversion", "Ljava/lang/Integer;"); 1990 jobject newIntegerObj = env->NewObject( 1991 intClazz, initInt, static_cast<jint>(s.inversion())); 1992 env->SetObjectField(statusObj, field, newIntegerObj); 1993 break; 1994 } 1995 case FrontendStatus::hidl_discriminator::lnbVoltage: { 1996 jfieldID field = env->GetFieldID(clazz, "mLnbVoltage", "Ljava/lang/Integer;"); 1997 jobject newIntegerObj = env->NewObject( 1998 intClazz, initInt, static_cast<jint>(s.lnbVoltage())); 1999 env->SetObjectField(statusObj, field, newIntegerObj); 2000 break; 2001 } 2002 case FrontendStatus::hidl_discriminator::plpId: { 2003 jfieldID field = env->GetFieldID(clazz, "mPlpId", "Ljava/lang/Integer;"); 2004 jobject newIntegerObj = env->NewObject( 2005 intClazz, initInt, static_cast<jint>(s.plpId())); 2006 env->SetObjectField(statusObj, field, newIntegerObj); 2007 break; 2008 } 2009 case FrontendStatus::hidl_discriminator::isEWBS: { 2010 jfieldID field = env->GetFieldID(clazz, "mIsEwbs", "Ljava/lang/Boolean;"); 2011 jobject newBooleanObj = env->NewObject( 2012 booleanClazz, initBoolean, static_cast<jboolean>(s.isEWBS())); 2013 env->SetObjectField(statusObj, field, newBooleanObj); 2014 break; 2015 } 2016 case FrontendStatus::hidl_discriminator::agc: { 2017 jfieldID field = env->GetFieldID(clazz, "mAgc", "Ljava/lang/Integer;"); 2018 jobject newIntegerObj = env->NewObject( 2019 intClazz, initInt, static_cast<jint>(s.agc())); 2020 env->SetObjectField(statusObj, field, newIntegerObj); 2021 break; 2022 } 2023 case FrontendStatus::hidl_discriminator::isLnaOn: { 2024 jfieldID field = env->GetFieldID(clazz, "mIsLnaOn", "Ljava/lang/Boolean;"); 2025 jobject newBooleanObj = env->NewObject( 2026 booleanClazz, initBoolean, static_cast<jboolean>(s.isLnaOn())); 2027 env->SetObjectField(statusObj, field, newBooleanObj); 2028 break; 2029 } 2030 case FrontendStatus::hidl_discriminator::isLayerError: { 2031 jfieldID field = env->GetFieldID(clazz, "mIsLayerErrors", "[Z"); 2032 hidl_vec<bool> layerErr = s.isLayerError(); 2033 2034 jbooleanArray valObj = env->NewBooleanArray(layerErr.size()); 2035 2036 for (size_t i = 0; i < layerErr.size(); i++) { 2037 jboolean x = layerErr[i]; 2038 env->SetBooleanArrayRegion(valObj, i, 1, &x); 2039 } 2040 env->SetObjectField(statusObj, field, valObj); 2041 break; 2042 } 2043 case FrontendStatus::hidl_discriminator::mer: { 2044 jfieldID field = env->GetFieldID(clazz, "mMer", "Ljava/lang/Integer;"); 2045 jobject newIntegerObj = env->NewObject( 2046 intClazz, initInt, static_cast<jint>(s.mer())); 2047 env->SetObjectField(statusObj, field, newIntegerObj); 2048 break; 2049 } 2050 case FrontendStatus::hidl_discriminator::freqOffset: { 2051 jfieldID field = env->GetFieldID(clazz, "mFreqOffset", "Ljava/lang/Integer;"); 2052 jobject newIntegerObj = env->NewObject( 2053 intClazz, initInt, static_cast<jint>(s.freqOffset())); 2054 env->SetObjectField(statusObj, field, newIntegerObj); 2055 break; 2056 } 2057 case FrontendStatus::hidl_discriminator::hierarchy: { 2058 jfieldID field = env->GetFieldID(clazz, "mHierarchy", "Ljava/lang/Integer;"); 2059 jobject newIntegerObj = env->NewObject( 2060 intClazz, initInt, static_cast<jint>(s.hierarchy())); 2061 env->SetObjectField(statusObj, field, newIntegerObj); 2062 break; 2063 } 2064 case FrontendStatus::hidl_discriminator::isRfLocked: { 2065 jfieldID field = env->GetFieldID(clazz, "mIsRfLocked", "Ljava/lang/Boolean;"); 2066 jobject newBooleanObj = env->NewObject( 2067 booleanClazz, initBoolean, static_cast<jboolean>(s.isRfLocked())); 2068 env->SetObjectField(statusObj, field, newBooleanObj); 2069 break; 2070 } 2071 case FrontendStatus::hidl_discriminator::plpInfo: { 2072 jfieldID field = env->GetFieldID(clazz, "mPlpInfo", 2073 "[Landroid/media/tv/tuner/frontend/FrontendStatus$Atsc3PlpTuningInfo;"); 2074 jclass plpClazz = env->FindClass( 2075 "android/media/tv/tuner/frontend/FrontendStatus$Atsc3PlpTuningInfo"); 2076 jmethodID initPlp = env->GetMethodID(plpClazz, "<init>", "(IZI)V"); 2077 2078 hidl_vec<FrontendStatusAtsc3PlpInfo> plpInfos = s.plpInfo(); 2079 2080 jobjectArray valObj = env->NewObjectArray(plpInfos.size(), plpClazz, NULL); 2081 for (int i = 0; i < plpInfos.size(); i++) { 2082 auto info = plpInfos[i]; 2083 jint plpId = (jint) info.plpId; 2084 jboolean isLocked = (jboolean) info.isLocked; 2085 jint uec = (jint) info.uec; 2086 2087 jobject plpObj = env->NewObject(plpClazz, initPlp, plpId, isLocked, uec); 2088 env->SetObjectArrayElement(valObj, i, plpObj); 2089 } 2090 2091 env->SetObjectField(statusObj, field, valObj); 2092 break; 2093 } 2094 default: { 2095 break; 2096 } 2097 } 2098 } 2099 2100 for (auto s : status_1_1) { 2101 switch(s.getDiscriminator()) { 2102 case FrontendStatusExt1_1::hidl_discriminator::modulations: { 2103 jfieldID field = env->GetFieldID(clazz, "mModulationsExt", "[I"); 2104 std::vector<FrontendModulation> v = s.modulations(); 2105 2106 jintArray valObj = env->NewIntArray(v.size()); 2107 bool valid = false; 2108 jint m[1]; 2109 for (int i = 0; i < v.size(); i++) { 2110 auto modulation = v[i]; 2111 switch(modulation.getDiscriminator()) { 2112 case FrontendModulation::hidl_discriminator::dvbc: { 2113 m[0] = static_cast<jint>(modulation.dvbc()); 2114 env->SetIntArrayRegion(valObj, i, 1, m); 2115 valid = true; 2116 break; 2117 } 2118 case FrontendModulation::hidl_discriminator::dvbs: { 2119 m[0] = static_cast<jint>(modulation.dvbs()); 2120 env->SetIntArrayRegion(valObj, i, 1, m); 2121 valid = true; 2122 break; 2123 } 2124 case FrontendModulation::hidl_discriminator::dvbt: { 2125 m[0] = static_cast<jint>(modulation.dvbt()); 2126 env->SetIntArrayRegion(valObj, i, 1, m); 2127 valid = true; 2128 break; 2129 } 2130 case FrontendModulation::hidl_discriminator::isdbs: { 2131 m[0] = static_cast<jint>(modulation.isdbs()); 2132 env->SetIntArrayRegion(valObj, i, 1, m); 2133 valid = true; 2134 break; 2135 } 2136 case FrontendModulation::hidl_discriminator::isdbs3: { 2137 m[0] = static_cast<jint>(modulation.isdbs3()); 2138 env->SetIntArrayRegion(valObj, i, 1, m); 2139 valid = true; 2140 break; 2141 } 2142 case FrontendModulation::hidl_discriminator::isdbt: { 2143 m[0] = static_cast<jint>(modulation.isdbt()); 2144 env->SetIntArrayRegion(valObj, i, 1, m); 2145 valid = true; 2146 break; 2147 } 2148 case FrontendModulation::hidl_discriminator::atsc: { 2149 m[0] = static_cast<jint>(modulation.atsc()); 2150 env->SetIntArrayRegion(valObj, i, 1, m); 2151 valid = true; 2152 break; 2153 } 2154 case FrontendModulation::hidl_discriminator::atsc3: { 2155 m[0] = static_cast<jint>(modulation.atsc3()); 2156 env->SetIntArrayRegion(valObj, i, 1, m); 2157 valid = true; 2158 break; 2159 } 2160 case FrontendModulation::hidl_discriminator::dtmb: { 2161 m[0] = static_cast<jint>(modulation.dtmb()); 2162 env->SetIntArrayRegion(valObj, i, 1, m); 2163 valid = true; 2164 break; 2165 } 2166 default: 2167 break; 2168 } 2169 } 2170 if (valid) { 2171 env->SetObjectField(statusObj, field, valObj); 2172 } 2173 break; 2174 } 2175 case FrontendStatusExt1_1::hidl_discriminator::bers: { 2176 jfieldID field = env->GetFieldID(clazz, "mBers", "[I"); 2177 std::vector<uint32_t> v = s.bers(); 2178 2179 jintArray valObj = env->NewIntArray(v.size()); 2180 env->SetIntArrayRegion(valObj, 0, v.size(), reinterpret_cast<jint*>(&v[0])); 2181 2182 env->SetObjectField(statusObj, field, valObj); 2183 break; 2184 } 2185 case FrontendStatusExt1_1::hidl_discriminator::codeRates: { 2186 jfieldID field = env->GetFieldID(clazz, "mCodeRates", "[I"); 2187 std::vector<::android::hardware::tv::tuner::V1_1::FrontendInnerFec> v 2188 = s.codeRates(); 2189 2190 jintArray valObj = env->NewIntArray(v.size()); 2191 env->SetIntArrayRegion(valObj, 0, v.size(), reinterpret_cast<jint*>(&v[0])); 2192 2193 env->SetObjectField(statusObj, field, valObj); 2194 break; 2195 } 2196 case FrontendStatusExt1_1::hidl_discriminator::bandwidth: { 2197 jfieldID field = env->GetFieldID(clazz, "mBandwidth", "Ljava/lang/Integer;"); 2198 auto bandwidth = s.bandwidth(); 2199 jint intBandwidth; 2200 bool valid = true; 2201 switch(bandwidth.getDiscriminator()) { 2202 case FrontendBandwidth::hidl_discriminator::atsc3: { 2203 intBandwidth = static_cast<jint>(bandwidth.atsc3()); 2204 break; 2205 } 2206 case FrontendBandwidth::hidl_discriminator::dvbt: { 2207 intBandwidth = static_cast<jint>(bandwidth.dvbt()); 2208 break; 2209 } 2210 case FrontendBandwidth::hidl_discriminator::dvbc: { 2211 intBandwidth = static_cast<jint>(bandwidth.dvbc()); 2212 break; 2213 } 2214 case FrontendBandwidth::hidl_discriminator::isdbt: { 2215 intBandwidth = static_cast<jint>(bandwidth.isdbt()); 2216 break; 2217 } 2218 case FrontendBandwidth::hidl_discriminator::dtmb: { 2219 intBandwidth = static_cast<jint>(bandwidth.dtmb()); 2220 break; 2221 } 2222 default: 2223 valid = false; 2224 break; 2225 } 2226 if (valid) { 2227 jobject newIntegerObj = env->NewObject(intClazz, initInt, intBandwidth); 2228 env->SetObjectField(statusObj, field, newIntegerObj); 2229 } 2230 break; 2231 } 2232 case FrontendStatusExt1_1::hidl_discriminator::interval: { 2233 jfieldID field = env->GetFieldID(clazz, "mGuardInterval", "Ljava/lang/Integer;"); 2234 auto interval = s.interval(); 2235 jint intInterval; 2236 bool valid = true; 2237 switch(interval.getDiscriminator()) { 2238 case FrontendGuardInterval::hidl_discriminator::dvbt: { 2239 intInterval = static_cast<jint>(interval.dvbt()); 2240 break; 2241 } 2242 case FrontendGuardInterval::hidl_discriminator::isdbt: { 2243 intInterval = static_cast<jint>(interval.isdbt()); 2244 break; 2245 } 2246 case FrontendGuardInterval::hidl_discriminator::dtmb: { 2247 intInterval = static_cast<jint>(interval.dtmb()); 2248 break; 2249 } 2250 default: 2251 valid = false; 2252 break; 2253 } 2254 if (valid) { 2255 jobject newIntegerObj = env->NewObject(intClazz, initInt, intInterval); 2256 env->SetObjectField(statusObj, field, newIntegerObj); 2257 } 2258 break; 2259 } 2260 case FrontendStatusExt1_1::hidl_discriminator::transmissionMode: { 2261 jfieldID field = env->GetFieldID(clazz, "mTransmissionMode", "Ljava/lang/Integer;"); 2262 auto transmissionMode = s.transmissionMode(); 2263 jint intTransmissionMode; 2264 bool valid = true; 2265 switch(transmissionMode.getDiscriminator()) { 2266 case FrontendTransmissionMode::hidl_discriminator::dvbt: { 2267 intTransmissionMode = static_cast<jint>(transmissionMode.dvbt()); 2268 break; 2269 } 2270 case FrontendTransmissionMode::hidl_discriminator::isdbt: { 2271 intTransmissionMode = static_cast<jint>(transmissionMode.isdbt()); 2272 break; 2273 } 2274 case FrontendTransmissionMode::hidl_discriminator::dtmb: { 2275 intTransmissionMode = static_cast<jint>(transmissionMode.dtmb()); 2276 break; 2277 } 2278 default: 2279 valid = false; 2280 break; 2281 } 2282 if (valid) { 2283 jobject newIntegerObj = env->NewObject(intClazz, initInt, intTransmissionMode); 2284 env->SetObjectField(statusObj, field, newIntegerObj); 2285 } 2286 break; 2287 } 2288 case FrontendStatusExt1_1::hidl_discriminator::uec: { 2289 jfieldID field = env->GetFieldID(clazz, "mUec", "Ljava/lang/Integer;"); 2290 jobject newIntegerObj = env->NewObject( 2291 intClazz, initInt, static_cast<jint>(s.uec())); 2292 env->SetObjectField(statusObj, field, newIntegerObj); 2293 break; 2294 } 2295 case FrontendStatusExt1_1::hidl_discriminator::systemId: { 2296 jfieldID field = env->GetFieldID(clazz, "mSystemId", "Ljava/lang/Integer;"); 2297 jobject newIntegerObj = env->NewObject( 2298 intClazz, initInt, static_cast<jint>(s.systemId())); 2299 env->SetObjectField(statusObj, field, newIntegerObj); 2300 break; 2301 } 2302 case FrontendStatusExt1_1::hidl_discriminator::interleaving: { 2303 jfieldID field = env->GetFieldID(clazz, "mInterleaving", "[I"); 2304 2305 std::vector<FrontendInterleaveMode> v = s.interleaving(); 2306 jintArray valObj = env->NewIntArray(v.size()); 2307 bool valid = false; 2308 jint in[1]; 2309 for (int i = 0; i < v.size(); i++) { 2310 auto interleaving = v[i]; 2311 switch(interleaving.getDiscriminator()) { 2312 case FrontendInterleaveMode::hidl_discriminator::atsc3: { 2313 in[0] = static_cast<jint>(interleaving.atsc3()); 2314 env->SetIntArrayRegion(valObj, i, 1, in); 2315 valid = true; 2316 break; 2317 } 2318 case FrontendInterleaveMode::hidl_discriminator::dvbc: { 2319 in[0] = static_cast<jint>(interleaving.dvbc()); 2320 env->SetIntArrayRegion(valObj, i, 1, in); 2321 valid = true; 2322 break; 2323 } 2324 case FrontendInterleaveMode::hidl_discriminator::dtmb: { 2325 in[0] = static_cast<jint>(interleaving.dtmb()); 2326 env->SetIntArrayRegion(valObj, i, 1, in); 2327 valid = true; 2328 break; 2329 } 2330 default: 2331 break; 2332 } 2333 } 2334 if (valid) { 2335 env->SetObjectField(statusObj, field, valObj); 2336 } 2337 break; 2338 } 2339 case FrontendStatusExt1_1::hidl_discriminator::isdbtSegment: { 2340 jfieldID field = env->GetFieldID(clazz, "mIsdbtSegment", "[I"); 2341 std::vector<uint8_t> v = s.isdbtSegment(); 2342 2343 jintArray valObj = env->NewIntArray(v.size()); 2344 env->SetIntArrayRegion(valObj, 0, v.size(), reinterpret_cast<jint*>(&v[0])); 2345 2346 env->SetObjectField(statusObj, field, valObj); 2347 break; 2348 } 2349 case FrontendStatusExt1_1::hidl_discriminator::tsDataRate: { 2350 jfieldID field = env->GetFieldID(clazz, "mTsDataRate", "[I"); 2351 std::vector<uint32_t> v = s.tsDataRate(); 2352 2353 jintArray valObj = env->NewIntArray(v.size()); 2354 env->SetIntArrayRegion(valObj, 0, v.size(), reinterpret_cast<jint*>(&v[0])); 2355 2356 env->SetObjectField(statusObj, field, valObj); 2357 break; 2358 } 2359 case FrontendStatusExt1_1::hidl_discriminator::rollOff: { 2360 jfieldID field = env->GetFieldID(clazz, "mRollOff", "Ljava/lang/Integer;"); 2361 auto rollOff = s.rollOff(); 2362 jint intRollOff; 2363 bool valid = true; 2364 switch(rollOff.getDiscriminator()) { 2365 case FrontendRollOff::hidl_discriminator::dvbs: { 2366 intRollOff = static_cast<jint>(rollOff.dvbs()); 2367 break; 2368 } 2369 case FrontendRollOff::hidl_discriminator::isdbs: { 2370 intRollOff = static_cast<jint>(rollOff.isdbs()); 2371 break; 2372 } 2373 case FrontendRollOff::hidl_discriminator::isdbs3: { 2374 intRollOff = static_cast<jint>(rollOff.isdbs3()); 2375 break; 2376 } 2377 default: 2378 valid = false; 2379 break; 2380 } 2381 if (valid) { 2382 jobject newIntegerObj = env->NewObject(intClazz, initInt, intRollOff); 2383 env->SetObjectField(statusObj, field, newIntegerObj); 2384 } 2385 break; 2386 } 2387 case FrontendStatusExt1_1::hidl_discriminator::isMiso: { 2388 jfieldID field = env->GetFieldID(clazz, "mIsMisoEnabled", "Ljava/lang/Boolean;"); 2389 jobject newBooleanObj = env->NewObject( 2390 booleanClazz, initBoolean, static_cast<jboolean>(s.isMiso())); 2391 env->SetObjectField(statusObj, field, newBooleanObj); 2392 break; 2393 } 2394 case FrontendStatusExt1_1::hidl_discriminator::isLinear: { 2395 jfieldID field = env->GetFieldID(clazz, "mIsLinear", "Ljava/lang/Boolean;"); 2396 jobject newBooleanObj = env->NewObject( 2397 booleanClazz, initBoolean, static_cast<jboolean>(s.isLinear())); 2398 env->SetObjectField(statusObj, field, newBooleanObj); 2399 break; 2400 } 2401 case FrontendStatusExt1_1::hidl_discriminator::isShortFrames: { 2402 jfieldID field = env->GetFieldID(clazz, "mIsShortFrames", "Ljava/lang/Boolean;"); 2403 jobject newBooleanObj = env->NewObject( 2404 booleanClazz, initBoolean, static_cast<jboolean>(s.isShortFrames())); 2405 env->SetObjectField(statusObj, field, newBooleanObj); 2406 break; 2407 } 2408 default: { 2409 break; 2410 } 2411 } 2412 } 2413 return statusObj; 2414 } 2415 2416 bool JTuner::isV1_1ExtendedStatusType(int type) { 2417 return (type > static_cast<int>(FrontendStatusType::ATSC3_PLP_INFO) 2418 && type <= static_cast<int>(FrontendStatusTypeExt1_1::IS_SHORT_FRAMES)); 2419 } 2420 2421 jint JTuner::closeFrontend() { 2422 Result r = Result::SUCCESS; 2423 2424 if (mFeClient != NULL) { 2425 r = mFeClient->close(); 2426 } 2427 if (r == Result::SUCCESS) { 2428 mFeClient = NULL; 2429 } 2430 return (jint) r; 2431 } 2432 2433 jint JTuner::closeDemux() { 2434 Result r = Result::SUCCESS; 2435 2436 if (mDemuxClient != NULL) { 2437 r = mDemuxClient->close(); 2438 } 2439 if (r == Result::SUCCESS) { 2440 mDemuxClient = NULL; 2441 } 2442 return (jint) r; 2443 } 2444 } // namespace android 2445 2446 //////////////////////////////////////////////////////////////////////////////// 2447 2448 using namespace android; 2449 2450 static sp<JTuner> setTuner(JNIEnv *env, jobject thiz, const sp<JTuner> &tuner) { 2451 sp<JTuner> old = (JTuner *)env->GetLongField(thiz, gFields.tunerContext); 2452 2453 if (tuner != NULL) { 2454 tuner->incStrong(thiz); 2455 } 2456 if (old != NULL) { 2457 old->decStrong(thiz); 2458 } 2459 2460 if (tuner != NULL) { 2461 env->SetLongField(thiz, gFields.tunerContext, (jlong)tuner.get()); 2462 } 2463 2464 return old; 2465 } 2466 2467 static sp<JTuner> getTuner(JNIEnv *env, jobject thiz) { 2468 return (JTuner *)env->GetLongField(thiz, gFields.tunerContext); 2469 } 2470 2471 static sp<DescramblerClient> getDescramblerClient(JNIEnv *env, jobject descrambler) { 2472 return (DescramblerClient *)env->GetLongField(descrambler, gFields.descramblerContext); 2473 } 2474 2475 static DemuxPid getDemuxPid(int pidType, int pid) { 2476 DemuxPid demuxPid; 2477 if ((int)pidType == 1) { 2478 demuxPid.tPid(static_cast<DemuxTpid>(pid)); 2479 } else if ((int)pidType == 2) { 2480 demuxPid.mmtpPid(static_cast<DemuxMmtpPid>(pid)); 2481 } 2482 return demuxPid; 2483 } 2484 2485 static uint32_t getFrontendSettingsFreq(JNIEnv *env, const jobject& settings) { 2486 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/FrontendSettings"); 2487 jfieldID freqField = env->GetFieldID(clazz, "mFrequency", "I"); 2488 uint32_t freq = static_cast<uint32_t>(env->GetIntField(settings, freqField)); 2489 return freq; 2490 } 2491 2492 static uint32_t getFrontendSettingsEndFreq(JNIEnv *env, const jobject& settings) { 2493 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/FrontendSettings"); 2494 jfieldID endFreqField = env->GetFieldID(clazz, "mEndFrequency", "I"); 2495 uint32_t endFreq = static_cast<uint32_t>(env->GetIntField(settings, endFreqField)); 2496 return endFreq; 2497 } 2498 2499 static FrontendSpectralInversion getFrontendSettingsSpectralInversion( 2500 JNIEnv *env, const jobject& settings) { 2501 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/FrontendSettings"); 2502 jfieldID inversionField = env->GetFieldID(clazz, "mSpectralInversion", "I"); 2503 FrontendSpectralInversion inversion = 2504 static_cast<FrontendSpectralInversion>(env->GetIntField(settings, inversionField)); 2505 return inversion; 2506 } 2507 2508 static FrontendSettings getAnalogFrontendSettings(JNIEnv *env, const jobject& settings) { 2509 FrontendSettings frontendSettings; 2510 uint32_t freq = getFrontendSettingsFreq(env, settings); 2511 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/AnalogFrontendSettings"); 2512 FrontendAnalogType analogType = 2513 static_cast<FrontendAnalogType>( 2514 env->GetIntField(settings, env->GetFieldID(clazz, "mSignalType", "I"))); 2515 FrontendAnalogSifStandard sifStandard = 2516 static_cast<FrontendAnalogSifStandard>( 2517 env->GetIntField(settings, env->GetFieldID(clazz, "mSifStandard", "I"))); 2518 FrontendAnalogSettings frontendAnalogSettings { 2519 .frequency = freq, 2520 .type = analogType, 2521 .sifStandard = sifStandard, 2522 }; 2523 frontendSettings.analog(frontendAnalogSettings); 2524 return frontendSettings; 2525 } 2526 2527 static void getAnalogFrontendSettingsExt1_1(JNIEnv *env, const jobject& settings, 2528 FrontendSettingsExt1_1& settingsExt1_1) { 2529 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/AnalogFrontendSettings"); 2530 FrontendAnalogAftFlag aftFlag = 2531 static_cast<FrontendAnalogAftFlag>( 2532 env->GetIntField(settings, env->GetFieldID(clazz, "mAftFlag", "I"))); 2533 FrontendAnalogSettingsExt1_1 analogExt1_1 { 2534 .aftFlag = aftFlag, 2535 }; 2536 settingsExt1_1.settingExt.analog(analogExt1_1); 2537 } 2538 2539 static hidl_vec<FrontendAtsc3PlpSettings> getAtsc3PlpSettings( 2540 JNIEnv *env, const jobject& settings) { 2541 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/Atsc3FrontendSettings"); 2542 jobjectArray plpSettings = 2543 reinterpret_cast<jobjectArray>( 2544 env->GetObjectField(settings, 2545 env->GetFieldID( 2546 clazz, 2547 "mPlpSettings", 2548 "[Landroid/media/tv/tuner/frontend/Atsc3PlpSettings;"))); 2549 int len = env->GetArrayLength(plpSettings); 2550 2551 jclass plpClazz = env->FindClass("android/media/tv/tuner/frontend/Atsc3PlpSettings"); 2552 hidl_vec<FrontendAtsc3PlpSettings> plps = hidl_vec<FrontendAtsc3PlpSettings>(len); 2553 // parse PLP settings 2554 for (int i = 0; i < len; i++) { 2555 jobject plp = env->GetObjectArrayElement(plpSettings, i); 2556 uint8_t plpId = 2557 static_cast<uint8_t>( 2558 env->GetIntField(plp, env->GetFieldID(plpClazz, "mPlpId", "I"))); 2559 FrontendAtsc3Modulation modulation = 2560 static_cast<FrontendAtsc3Modulation>( 2561 env->GetIntField(plp, env->GetFieldID(plpClazz, "mModulation", "I"))); 2562 FrontendAtsc3TimeInterleaveMode interleaveMode = 2563 static_cast<FrontendAtsc3TimeInterleaveMode>( 2564 env->GetIntField( 2565 plp, env->GetFieldID(plpClazz, "mInterleaveMode", "I"))); 2566 FrontendAtsc3CodeRate codeRate = 2567 static_cast<FrontendAtsc3CodeRate>( 2568 env->GetIntField(plp, env->GetFieldID(plpClazz, "mCodeRate", "I"))); 2569 FrontendAtsc3Fec fec = 2570 static_cast<FrontendAtsc3Fec>( 2571 env->GetIntField(plp, env->GetFieldID(plpClazz, "mFec", "I"))); 2572 FrontendAtsc3PlpSettings frontendAtsc3PlpSettings { 2573 .plpId = plpId, 2574 .modulation = modulation, 2575 .interleaveMode = interleaveMode, 2576 .codeRate = codeRate, 2577 .fec = fec, 2578 }; 2579 plps[i] = frontendAtsc3PlpSettings; 2580 } 2581 return plps; 2582 } 2583 2584 static FrontendSettings getAtsc3FrontendSettings(JNIEnv *env, const jobject& settings) { 2585 FrontendSettings frontendSettings; 2586 uint32_t freq = getFrontendSettingsFreq(env, settings); 2587 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/Atsc3FrontendSettings"); 2588 2589 FrontendAtsc3Bandwidth bandwidth = 2590 static_cast<FrontendAtsc3Bandwidth>( 2591 env->GetIntField(settings, env->GetFieldID(clazz, "mBandwidth", "I"))); 2592 FrontendAtsc3DemodOutputFormat demod = 2593 static_cast<FrontendAtsc3DemodOutputFormat>( 2594 env->GetIntField( 2595 settings, env->GetFieldID(clazz, "mDemodOutputFormat", "I"))); 2596 hidl_vec<FrontendAtsc3PlpSettings> plps = getAtsc3PlpSettings(env, settings); 2597 FrontendAtsc3Settings frontendAtsc3Settings { 2598 .frequency = freq, 2599 .bandwidth = bandwidth, 2600 .demodOutputFormat = demod, 2601 .plpSettings = plps, 2602 }; 2603 frontendSettings.atsc3(frontendAtsc3Settings); 2604 return frontendSettings; 2605 } 2606 2607 static FrontendSettings getAtscFrontendSettings(JNIEnv *env, const jobject& settings) { 2608 FrontendSettings frontendSettings; 2609 uint32_t freq = getFrontendSettingsFreq(env, settings); 2610 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/AtscFrontendSettings"); 2611 FrontendAtscModulation modulation = 2612 static_cast<FrontendAtscModulation>( 2613 env->GetIntField(settings, env->GetFieldID(clazz, "mModulation", "I"))); 2614 FrontendAtscSettings frontendAtscSettings { 2615 .frequency = freq, 2616 .modulation = modulation, 2617 }; 2618 frontendSettings.atsc(frontendAtscSettings); 2619 return frontendSettings; 2620 } 2621 2622 static FrontendSettings getDvbcFrontendSettings(JNIEnv *env, const jobject& settings) { 2623 FrontendSettings frontendSettings; 2624 uint32_t freq = getFrontendSettingsFreq(env, settings); 2625 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/DvbcFrontendSettings"); 2626 FrontendDvbcModulation modulation = 2627 static_cast<FrontendDvbcModulation>( 2628 env->GetIntField(settings, env->GetFieldID(clazz, "mModulation", "I"))); 2629 FrontendInnerFec innerFec = 2630 static_cast<FrontendInnerFec>( 2631 env->GetLongField(settings, env->GetFieldID(clazz, "mInnerFec", "J"))); 2632 uint32_t symbolRate = 2633 static_cast<uint32_t>( 2634 env->GetIntField(settings, env->GetFieldID(clazz, "mSymbolRate", "I"))); 2635 FrontendDvbcOuterFec outerFec = 2636 static_cast<FrontendDvbcOuterFec>( 2637 env->GetIntField(settings, env->GetFieldID(clazz, "mOuterFec", "I"))); 2638 FrontendDvbcAnnex annex = 2639 static_cast<FrontendDvbcAnnex>( 2640 env->GetIntField(settings, env->GetFieldID(clazz, "mAnnex", "I"))); 2641 FrontendDvbcSpectralInversion spectralInversion = 2642 static_cast<FrontendDvbcSpectralInversion>( 2643 env->GetIntField( 2644 settings, env->GetFieldID(clazz, "mSpectralInversion", "I"))); 2645 FrontendDvbcSettings frontendDvbcSettings { 2646 .frequency = freq, 2647 .modulation = modulation, 2648 .fec = innerFec, 2649 .symbolRate = symbolRate, 2650 .outerFec = outerFec, 2651 .annex = annex, 2652 .spectralInversion = spectralInversion, 2653 }; 2654 frontendSettings.dvbc(frontendDvbcSettings); 2655 return frontendSettings; 2656 } 2657 2658 static void getDvbcFrontendSettingsExt1_1(JNIEnv *env, const jobject& settings, 2659 FrontendSettingsExt1_1& settingsExt1_1) { 2660 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/DvbcFrontendSettings"); 2661 FrontendCableTimeInterleaveMode interleaveMode = 2662 static_cast<FrontendCableTimeInterleaveMode>( 2663 env->GetIntField(settings, env->GetFieldID(clazz, "mInterleaveMode", "I"))); 2664 FrontendDvbcBandwidth bandwidth = 2665 static_cast<FrontendDvbcBandwidth>( 2666 env->GetIntField(settings, env->GetFieldID(clazz, "mBandwidth", "I"))); 2667 2668 FrontendDvbcSettingsExt1_1 dvbcExt1_1 { 2669 .interleaveMode = interleaveMode, 2670 .bandwidth = bandwidth, 2671 }; 2672 settingsExt1_1.settingExt.dvbc(dvbcExt1_1); 2673 } 2674 2675 static FrontendDvbsCodeRate getDvbsCodeRate(JNIEnv *env, const jobject& settings) { 2676 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/DvbsFrontendSettings"); 2677 jobject jcodeRate = 2678 env->GetObjectField(settings, 2679 env->GetFieldID( 2680 clazz, 2681 "mCodeRate", 2682 "Landroid/media/tv/tuner/frontend/DvbsCodeRate;")); 2683 2684 jclass codeRateClazz = env->FindClass("android/media/tv/tuner/frontend/DvbsCodeRate"); 2685 FrontendInnerFec innerFec = 2686 static_cast<FrontendInnerFec>( 2687 env->GetLongField( 2688 jcodeRate, env->GetFieldID(codeRateClazz, "mInnerFec", "J"))); 2689 bool isLinear = 2690 static_cast<bool>( 2691 env->GetBooleanField( 2692 jcodeRate, env->GetFieldID(codeRateClazz, "mIsLinear", "Z"))); 2693 bool isShortFrames = 2694 static_cast<bool>( 2695 env->GetBooleanField( 2696 jcodeRate, env->GetFieldID(codeRateClazz, "mIsShortFrames", "Z"))); 2697 uint32_t bitsPer1000Symbol = 2698 static_cast<uint32_t>( 2699 env->GetIntField( 2700 jcodeRate, env->GetFieldID( 2701 codeRateClazz, "mBitsPer1000Symbol", "I"))); 2702 FrontendDvbsCodeRate coderate { 2703 .fec = innerFec, 2704 .isLinear = isLinear, 2705 .isShortFrames = isShortFrames, 2706 .bitsPer1000Symbol = bitsPer1000Symbol, 2707 }; 2708 return coderate; 2709 } 2710 2711 static FrontendSettings getDvbsFrontendSettings(JNIEnv *env, const jobject& settings) { 2712 FrontendSettings frontendSettings; 2713 uint32_t freq = getFrontendSettingsFreq(env, settings); 2714 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/DvbsFrontendSettings"); 2715 2716 FrontendDvbsModulation modulation = 2717 static_cast<FrontendDvbsModulation>( 2718 env->GetIntField(settings, env->GetFieldID(clazz, "mModulation", "I"))); 2719 uint32_t symbolRate = 2720 static_cast<uint32_t>( 2721 env->GetIntField(settings, env->GetFieldID(clazz, "mSymbolRate", "I"))); 2722 FrontendDvbsRolloff rolloff = 2723 static_cast<FrontendDvbsRolloff>( 2724 env->GetIntField(settings, env->GetFieldID(clazz, "mRolloff", "I"))); 2725 FrontendDvbsPilot pilot = 2726 static_cast<FrontendDvbsPilot>( 2727 env->GetIntField(settings, env->GetFieldID(clazz, "mPilot", "I"))); 2728 uint32_t inputStreamId = 2729 static_cast<uint32_t>( 2730 env->GetIntField(settings, env->GetFieldID(clazz, "mInputStreamId", "I"))); 2731 FrontendDvbsStandard standard = 2732 static_cast<FrontendDvbsStandard>( 2733 env->GetIntField(settings, env->GetFieldID(clazz, "mStandard", "I"))); 2734 FrontendDvbsVcmMode vcmMode = 2735 static_cast<FrontendDvbsVcmMode>( 2736 env->GetIntField(settings, env->GetFieldID(clazz, "mVcmMode", "I"))); 2737 2738 FrontendDvbsSettings frontendDvbsSettings { 2739 .frequency = freq, 2740 .modulation = modulation, 2741 .symbolRate = symbolRate, 2742 .rolloff = rolloff, 2743 .pilot = pilot, 2744 .inputStreamId = inputStreamId, 2745 .standard = standard, 2746 .vcmMode = vcmMode, 2747 }; 2748 2749 jobject jcodeRate = env->GetObjectField(settings, env->GetFieldID(clazz, "mCodeRate", 2750 "Landroid/media/tv/tuner/frontend/DvbsCodeRate;")); 2751 if (jcodeRate != NULL) { 2752 frontendDvbsSettings.coderate = getDvbsCodeRate(env, settings); 2753 } 2754 2755 frontendSettings.dvbs(frontendDvbsSettings); 2756 return frontendSettings; 2757 } 2758 2759 static void getDvbsFrontendSettingsExt1_1(JNIEnv *env, const jobject& settings, 2760 FrontendSettingsExt1_1& settingsExt1_1) { 2761 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/DvbsFrontendSettings"); 2762 FrontendDvbsScanType scanType = 2763 static_cast<FrontendDvbsScanType>( 2764 env->GetIntField(settings, env->GetFieldID(clazz, "mScanType", "I"))); 2765 bool isDiseqcRxMessage = static_cast<bool>(env->GetBooleanField( 2766 settings, env->GetFieldID(clazz, "mIsDiseqcRxMessage", "Z"))); 2767 2768 FrontendDvbsSettingsExt1_1 dvbsExt1_1 { 2769 .scanType = scanType, 2770 .isDiseqcRxMessage = isDiseqcRxMessage, 2771 }; 2772 settingsExt1_1.settingExt.dvbs(dvbsExt1_1); 2773 } 2774 2775 static FrontendSettings getDvbtFrontendSettings(JNIEnv *env, const jobject& settings) { 2776 FrontendSettings frontendSettings; 2777 uint32_t freq = getFrontendSettingsFreq(env, settings); 2778 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/DvbtFrontendSettings"); 2779 FrontendDvbtTransmissionMode transmissionMode = 2780 static_cast<FrontendDvbtTransmissionMode>( 2781 env->GetIntField( 2782 settings, env->GetFieldID(clazz, "mTransmissionMode", "I"))); 2783 FrontendDvbtBandwidth bandwidth = 2784 static_cast<FrontendDvbtBandwidth>( 2785 env->GetIntField(settings, env->GetFieldID(clazz, "mBandwidth", "I"))); 2786 FrontendDvbtConstellation constellation = 2787 static_cast<FrontendDvbtConstellation>( 2788 env->GetIntField(settings, env->GetFieldID(clazz, "mConstellation", "I"))); 2789 FrontendDvbtHierarchy hierarchy = 2790 static_cast<FrontendDvbtHierarchy>( 2791 env->GetIntField(settings, env->GetFieldID(clazz, "mHierarchy", "I"))); 2792 FrontendDvbtCoderate hpCoderate = 2793 static_cast<FrontendDvbtCoderate>( 2794 env->GetIntField(settings, env->GetFieldID(clazz, "mHpCodeRate", "I"))); 2795 FrontendDvbtCoderate lpCoderate = 2796 static_cast<FrontendDvbtCoderate>( 2797 env->GetIntField(settings, env->GetFieldID(clazz, "mLpCodeRate", "I"))); 2798 FrontendDvbtGuardInterval guardInterval = 2799 static_cast<FrontendDvbtGuardInterval>( 2800 env->GetIntField(settings, env->GetFieldID(clazz, "mGuardInterval", "I"))); 2801 bool isHighPriority = 2802 static_cast<bool>( 2803 env->GetBooleanField( 2804 settings, env->GetFieldID(clazz, "mIsHighPriority", "Z"))); 2805 FrontendDvbtStandard standard = 2806 static_cast<FrontendDvbtStandard>( 2807 env->GetIntField(settings, env->GetFieldID(clazz, "mStandard", "I"))); 2808 bool isMiso = 2809 static_cast<bool>( 2810 env->GetBooleanField(settings, env->GetFieldID(clazz, "mIsMiso", "Z"))); 2811 FrontendDvbtPlpMode plpMode = 2812 static_cast<FrontendDvbtPlpMode>( 2813 env->GetIntField(settings, env->GetFieldID(clazz, "mPlpMode", "I"))); 2814 uint8_t plpId = 2815 static_cast<uint8_t>( 2816 env->GetIntField(settings, env->GetFieldID(clazz, "mPlpId", "I"))); 2817 uint8_t plpGroupId = 2818 static_cast<uint8_t>( 2819 env->GetIntField(settings, env->GetFieldID(clazz, "mPlpGroupId", "I"))); 2820 2821 FrontendDvbtSettings frontendDvbtSettings { 2822 .frequency = freq, 2823 .transmissionMode = transmissionMode, 2824 .bandwidth = bandwidth, 2825 .constellation = constellation, 2826 .hierarchy = hierarchy, 2827 .hpCoderate = hpCoderate, 2828 .lpCoderate = lpCoderate, 2829 .guardInterval = guardInterval, 2830 .isHighPriority = isHighPriority, 2831 .standard = standard, 2832 .isMiso = isMiso, 2833 .plpMode = plpMode, 2834 .plpId = plpId, 2835 .plpGroupId = plpGroupId, 2836 }; 2837 frontendSettings.dvbt(frontendDvbtSettings); 2838 return frontendSettings; 2839 } 2840 2841 static void getDvbtFrontendSettingsExt1_1(JNIEnv *env, const jobject& settings, 2842 FrontendSettingsExt1_1& settingsExt1_1) { 2843 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/DvbtFrontendSettings"); 2844 2845 FrontendDvbtSettingsExt1_1 dvbtExt1_1; 2846 int transmissionMode = 2847 env->GetIntField(settings, env->GetFieldID(clazz, "mTransmissionMode", "I")); 2848 dvbtExt1_1.transmissionMode = static_cast< 2849 ::android::hardware::tv::tuner::V1_1::FrontendDvbtTransmissionMode>( 2850 transmissionMode); 2851 2852 int constellation = 2853 env->GetIntField(settings, env->GetFieldID(clazz, "mConstellation", "I")); 2854 dvbtExt1_1.constellation = static_cast< 2855 ::android::hardware::tv::tuner::V1_1::FrontendDvbtConstellation>(constellation); 2856 2857 settingsExt1_1.settingExt.dvbt(dvbtExt1_1); 2858 } 2859 2860 static FrontendSettings getIsdbsFrontendSettings(JNIEnv *env, const jobject& settings) { 2861 FrontendSettings frontendSettings; 2862 uint32_t freq = getFrontendSettingsFreq(env, settings); 2863 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/IsdbsFrontendSettings"); 2864 uint16_t streamId = 2865 static_cast<uint16_t>( 2866 env->GetIntField(settings, env->GetFieldID(clazz, "mStreamId", "I"))); 2867 FrontendIsdbsStreamIdType streamIdType = 2868 static_cast<FrontendIsdbsStreamIdType>( 2869 env->GetIntField(settings, env->GetFieldID(clazz, "mStreamIdType", "I"))); 2870 FrontendIsdbsModulation modulation = 2871 static_cast<FrontendIsdbsModulation>( 2872 env->GetIntField(settings, env->GetFieldID(clazz, "mModulation", "I"))); 2873 FrontendIsdbsCoderate coderate = 2874 static_cast<FrontendIsdbsCoderate>( 2875 env->GetIntField(settings, env->GetFieldID(clazz, "mCodeRate", "I"))); 2876 uint32_t symbolRate = 2877 static_cast<uint32_t>( 2878 env->GetIntField(settings, env->GetFieldID(clazz, "mSymbolRate", "I"))); 2879 FrontendIsdbsRolloff rolloff = 2880 static_cast<FrontendIsdbsRolloff>( 2881 env->GetIntField(settings, env->GetFieldID(clazz, "mRolloff", "I"))); 2882 2883 FrontendIsdbsSettings frontendIsdbsSettings { 2884 .frequency = freq, 2885 .streamId = streamId, 2886 .streamIdType = streamIdType, 2887 .modulation = modulation, 2888 .coderate = coderate, 2889 .symbolRate = symbolRate, 2890 .rolloff = rolloff, 2891 }; 2892 frontendSettings.isdbs(frontendIsdbsSettings); 2893 return frontendSettings; 2894 } 2895 2896 static FrontendSettings getIsdbs3FrontendSettings(JNIEnv *env, const jobject& settings) { 2897 FrontendSettings frontendSettings; 2898 uint32_t freq = getFrontendSettingsFreq(env, settings); 2899 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/Isdbs3FrontendSettings"); 2900 uint16_t streamId = 2901 static_cast<uint16_t>( 2902 env->GetIntField(settings, env->GetFieldID(clazz, "mStreamId", "I"))); 2903 FrontendIsdbsStreamIdType streamIdType = 2904 static_cast<FrontendIsdbsStreamIdType>( 2905 env->GetIntField(settings, env->GetFieldID(clazz, "mStreamIdType", "I"))); 2906 FrontendIsdbs3Modulation modulation = 2907 static_cast<FrontendIsdbs3Modulation>( 2908 env->GetIntField(settings, env->GetFieldID(clazz, "mModulation", "I"))); 2909 FrontendIsdbs3Coderate coderate = 2910 static_cast<FrontendIsdbs3Coderate>( 2911 env->GetIntField(settings, env->GetFieldID(clazz, "mCodeRate", "I"))); 2912 uint32_t symbolRate = 2913 static_cast<uint32_t>( 2914 env->GetIntField(settings, env->GetFieldID(clazz, "mSymbolRate", "I"))); 2915 FrontendIsdbs3Rolloff rolloff = 2916 static_cast<FrontendIsdbs3Rolloff>( 2917 env->GetIntField(settings, env->GetFieldID(clazz, "mRolloff", "I"))); 2918 2919 FrontendIsdbs3Settings frontendIsdbs3Settings { 2920 .frequency = freq, 2921 .streamId = streamId, 2922 .streamIdType = streamIdType, 2923 .modulation = modulation, 2924 .coderate = coderate, 2925 .symbolRate = symbolRate, 2926 .rolloff = rolloff, 2927 }; 2928 frontendSettings.isdbs3(frontendIsdbs3Settings); 2929 return frontendSettings; 2930 } 2931 2932 static FrontendSettings getIsdbtFrontendSettings(JNIEnv *env, const jobject& settings) { 2933 FrontendSettings frontendSettings; 2934 uint32_t freq = getFrontendSettingsFreq(env, settings); 2935 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/IsdbtFrontendSettings"); 2936 FrontendIsdbtModulation modulation = 2937 static_cast<FrontendIsdbtModulation>( 2938 env->GetIntField(settings, env->GetFieldID(clazz, "mModulation", "I"))); 2939 FrontendIsdbtBandwidth bandwidth = 2940 static_cast<FrontendIsdbtBandwidth>( 2941 env->GetIntField(settings, env->GetFieldID(clazz, "mBandwidth", "I"))); 2942 FrontendIsdbtMode mode = 2943 static_cast<FrontendIsdbtMode>( 2944 env->GetIntField(settings, env->GetFieldID(clazz, "mMode", "I"))); 2945 FrontendIsdbtCoderate coderate = 2946 static_cast<FrontendIsdbtCoderate>( 2947 env->GetIntField(settings, env->GetFieldID(clazz, "mCodeRate", "I"))); 2948 FrontendIsdbtGuardInterval guardInterval = 2949 static_cast<FrontendIsdbtGuardInterval>( 2950 env->GetIntField(settings, env->GetFieldID(clazz, "mGuardInterval", "I"))); 2951 uint32_t serviceAreaId = 2952 static_cast<uint32_t>( 2953 env->GetIntField(settings, env->GetFieldID(clazz, "mServiceAreaId", "I"))); 2954 2955 FrontendIsdbtSettings frontendIsdbtSettings { 2956 .frequency = freq, 2957 .modulation = modulation, 2958 .bandwidth = bandwidth, 2959 .mode = mode, 2960 .coderate = coderate, 2961 .guardInterval = guardInterval, 2962 .serviceAreaId = serviceAreaId, 2963 }; 2964 frontendSettings.isdbt(frontendIsdbtSettings); 2965 return frontendSettings; 2966 } 2967 2968 static void getDtmbFrontendSettings(JNIEnv *env, const jobject& settings, 2969 FrontendSettingsExt1_1& settingsExt1_1) { 2970 uint32_t freq = getFrontendSettingsFreq(env, settings); 2971 jclass clazz = env->FindClass("android/media/tv/tuner/frontend/DtmbFrontendSettings"); 2972 FrontendDtmbModulation modulation = 2973 static_cast<FrontendDtmbModulation>( 2974 env->GetIntField(settings, env->GetFieldID(clazz, "mModulation", "I"))); 2975 FrontendDtmbBandwidth bandwidth = 2976 static_cast<FrontendDtmbBandwidth>( 2977 env->GetIntField(settings, env->GetFieldID(clazz, "mBandwidth", "I"))); 2978 FrontendDtmbTransmissionMode transmissionMode = 2979 static_cast<FrontendDtmbTransmissionMode>( 2980 env->GetIntField(settings, env->GetFieldID(clazz, "mTransmissionMode", "I"))); 2981 FrontendDtmbCodeRate codeRate = 2982 static_cast<FrontendDtmbCodeRate>( 2983 env->GetIntField(settings, env->GetFieldID(clazz, "mCodeRate", "I"))); 2984 FrontendDtmbGuardInterval guardInterval = 2985 static_cast<FrontendDtmbGuardInterval>( 2986 env->GetIntField(settings, env->GetFieldID(clazz, "mGuardInterval", "I"))); 2987 FrontendDtmbTimeInterleaveMode interleaveMode = 2988 static_cast<FrontendDtmbTimeInterleaveMode>( 2989 env->GetIntField(settings, env->GetFieldID(clazz, "mTimeInterleaveMode", "I"))); 2990 2991 FrontendDtmbSettings frontendDtmbSettings { 2992 .frequency = freq, 2993 .modulation = modulation, 2994 .bandwidth = bandwidth, 2995 .transmissionMode = transmissionMode, 2996 .codeRate = codeRate, 2997 .guardInterval = guardInterval, 2998 .interleaveMode = interleaveMode, 2999 }; 3000 settingsExt1_1.settingExt.dtmb(frontendDtmbSettings); 3001 } 3002 3003 static FrontendSettings getFrontendSettings(JNIEnv *env, int type, jobject settings) { 3004 ALOGD("getFrontendSettings %d", type); 3005 3006 if (type == static_cast<int>(::android::hardware::tv::tuner::V1_1::FrontendType::DTMB)) { 3007 return FrontendSettings(); 3008 } 3009 3010 FrontendType feType = static_cast<FrontendType>(type); 3011 switch(feType) { 3012 case FrontendType::ANALOG: 3013 return getAnalogFrontendSettings(env, settings); 3014 case FrontendType::ATSC3: 3015 return getAtsc3FrontendSettings(env, settings); 3016 case FrontendType::ATSC: 3017 return getAtscFrontendSettings(env, settings); 3018 case FrontendType::DVBC: 3019 return getDvbcFrontendSettings(env, settings); 3020 case FrontendType::DVBS: 3021 return getDvbsFrontendSettings(env, settings); 3022 case FrontendType::DVBT: 3023 return getDvbtFrontendSettings(env, settings); 3024 case FrontendType::ISDBS: 3025 return getIsdbsFrontendSettings(env, settings); 3026 case FrontendType::ISDBS3: 3027 return getIsdbs3FrontendSettings(env, settings); 3028 case FrontendType::ISDBT: 3029 return getIsdbtFrontendSettings(env, settings); 3030 default: 3031 // should never happen because a type is associated with a subclass of 3032 // FrontendSettings and not set by users 3033 jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", 3034 "Unsupported frontend type %d", type); 3035 return FrontendSettings(); 3036 } 3037 } 3038 3039 static FrontendSettingsExt1_1 getFrontendSettingsExt1_1( 3040 JNIEnv *env, int type, jobject settings, int tunerVersion) { 3041 ALOGD("getFrontendSettingsExt1_1 %d", type); 3042 3043 FrontendSettingsExt1_1 settingsExt1_1 { 3044 .endFrequency = static_cast<uint32_t>(Constant::INVALID_FRONTEND_SETTING_FREQUENCY), 3045 .inversion = FrontendSpectralInversion::UNDEFINED, 3046 }; 3047 settingsExt1_1.settingExt.noinit(); 3048 3049 if (tunerVersion < TUNER_VERSION_1_1) { 3050 return settingsExt1_1; 3051 } 3052 3053 if (type == static_cast<int>(::android::hardware::tv::tuner::V1_1::FrontendType::DTMB)) { 3054 getDtmbFrontendSettings(env, settings, settingsExt1_1); 3055 } else { 3056 FrontendType feType = static_cast<FrontendType>(type); 3057 switch(feType) { 3058 case FrontendType::DVBS: 3059 getDvbsFrontendSettingsExt1_1(env, settings, settingsExt1_1); 3060 break; 3061 case FrontendType::DVBT: 3062 getDvbtFrontendSettingsExt1_1(env, settings, settingsExt1_1); 3063 break; 3064 case FrontendType::ANALOG: 3065 getAnalogFrontendSettingsExt1_1(env, settings, settingsExt1_1); 3066 break; 3067 case FrontendType::ATSC3: 3068 break; 3069 case FrontendType::ATSC: 3070 break; 3071 case FrontendType::DVBC: 3072 getDvbcFrontendSettingsExt1_1(env, settings, settingsExt1_1); 3073 break; 3074 case FrontendType::ISDBS: 3075 break; 3076 case FrontendType::ISDBS3: 3077 break; 3078 case FrontendType::ISDBT: 3079 break; 3080 default: 3081 // should never happen because a type is associated with a subclass of 3082 // FrontendSettings and not set by users 3083 jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", 3084 "Unsupported frontend type %d", type); 3085 return FrontendSettingsExt1_1(); 3086 } 3087 } 3088 3089 uint32_t endFreq = getFrontendSettingsEndFreq(env, settings); 3090 FrontendSpectralInversion inversion = getFrontendSettingsSpectralInversion(env, settings); 3091 settingsExt1_1.endFrequency = endFreq; 3092 settingsExt1_1.inversion = inversion; 3093 3094 return settingsExt1_1; 3095 } 3096 3097 static sp<FilterClient> getFilterClient(JNIEnv *env, jobject filter) { 3098 return (FilterClient *)env->GetLongField(filter, gFields.filterContext); 3099 } 3100 3101 static sp<LnbClient> getLnbClient(JNIEnv *env, jobject lnb) { 3102 return (LnbClient *)env->GetLongField(lnb, gFields.lnbContext); 3103 } 3104 3105 static DvrSettings getDvrSettings(JNIEnv *env, jobject settings, bool isRecorder) { 3106 DvrSettings dvrSettings; 3107 jclass clazz = env->FindClass("android/media/tv/tuner/dvr/DvrSettings"); 3108 uint32_t statusMask = 3109 static_cast<uint32_t>(env->GetIntField( 3110 settings, env->GetFieldID(clazz, "mStatusMask", "I"))); 3111 uint32_t lowThreshold = 3112 static_cast<uint32_t>(env->GetLongField( 3113 settings, env->GetFieldID(clazz, "mLowThreshold", "J"))); 3114 uint32_t highThreshold = 3115 static_cast<uint32_t>(env->GetLongField( 3116 settings, env->GetFieldID(clazz, "mHighThreshold", "J"))); 3117 uint8_t packetSize = 3118 static_cast<uint8_t>(env->GetLongField( 3119 settings, env->GetFieldID(clazz, "mPacketSize", "J"))); 3120 DataFormat dataFormat = 3121 static_cast<DataFormat>(env->GetIntField( 3122 settings, env->GetFieldID(clazz, "mDataFormat", "I"))); 3123 if (isRecorder) { 3124 RecordSettings recordSettings { 3125 .statusMask = static_cast<unsigned char>(statusMask), 3126 .lowThreshold = lowThreshold, 3127 .highThreshold = highThreshold, 3128 .dataFormat = dataFormat, 3129 .packetSize = packetSize, 3130 }; 3131 dvrSettings.record(recordSettings); 3132 } else { 3133 PlaybackSettings PlaybackSettings { 3134 .statusMask = statusMask, 3135 .lowThreshold = lowThreshold, 3136 .highThreshold = highThreshold, 3137 .dataFormat = dataFormat, 3138 .packetSize = packetSize, 3139 }; 3140 dvrSettings.playback(PlaybackSettings); 3141 } 3142 return dvrSettings; 3143 } 3144 3145 static sp<DvrClient> getDvrClient(JNIEnv *env, jobject dvr) { 3146 bool isRecorder = 3147 env->IsInstanceOf(dvr, env->FindClass("android/media/tv/tuner/dvr/DvrRecorder")); 3148 jfieldID fieldId = 3149 isRecorder ? gFields.dvrRecorderContext : gFields.dvrPlaybackContext; 3150 return (DvrClient *)env->GetLongField(dvr, fieldId); 3151 } 3152 3153 static void android_media_tv_Tuner_native_init(JNIEnv *env) { 3154 jclass clazz = env->FindClass("android/media/tv/tuner/Tuner"); 3155 CHECK(clazz != NULL); 3156 3157 gFields.tunerContext = env->GetFieldID(clazz, "mNativeContext", "J"); 3158 CHECK(gFields.tunerContext != NULL); 3159 3160 gFields.onFrontendEventID = env->GetMethodID(clazz, "onFrontendEvent", "(I)V"); 3161 3162 jclass frontendClazz = env->FindClass("android/media/tv/tuner/Tuner$Frontend"); 3163 gFields.frontendInitID = 3164 env->GetMethodID(frontendClazz, "<init>", "(Landroid/media/tv/tuner/Tuner;I)V"); 3165 3166 jclass lnbClazz = env->FindClass("android/media/tv/tuner/Lnb"); 3167 gFields.lnbContext = env->GetFieldID(lnbClazz, "mNativeContext", "J"); 3168 gFields.lnbInitID = env->GetMethodID(lnbClazz, "<init>", "()V"); 3169 gFields.onLnbEventID = env->GetMethodID(lnbClazz, "onEvent", "(I)V"); 3170 gFields.onLnbDiseqcMessageID = env->GetMethodID(lnbClazz, "onDiseqcMessage", "([B)V"); 3171 3172 jclass filterClazz = env->FindClass("android/media/tv/tuner/filter/Filter"); 3173 gFields.filterContext = env->GetFieldID(filterClazz, "mNativeContext", "J"); 3174 gFields.filterInitID = 3175 env->GetMethodID(filterClazz, "<init>", "(J)V"); 3176 gFields.onFilterStatusID = 3177 env->GetMethodID(filterClazz, "onFilterStatus", "(I)V"); 3178 gFields.onFilterEventID = 3179 env->GetMethodID(filterClazz, "onFilterEvent", 3180 "([Landroid/media/tv/tuner/filter/FilterEvent;)V"); 3181 3182 jclass timeFilterClazz = env->FindClass("android/media/tv/tuner/filter/TimeFilter"); 3183 gFields.timeFilterContext = env->GetFieldID(timeFilterClazz, "mNativeContext", "J"); 3184 gFields.timeFilterInitID = env->GetMethodID(timeFilterClazz, "<init>", "()V"); 3185 3186 jclass descramblerClazz = env->FindClass("android/media/tv/tuner/Descrambler"); 3187 gFields.descramblerContext = env->GetFieldID(descramblerClazz, "mNativeContext", "J"); 3188 gFields.descramblerInitID = env->GetMethodID(descramblerClazz, "<init>", "()V"); 3189 3190 jclass dvrRecorderClazz = env->FindClass("android/media/tv/tuner/dvr/DvrRecorder"); 3191 gFields.dvrRecorderContext = env->GetFieldID(dvrRecorderClazz, "mNativeContext", "J"); 3192 gFields.dvrRecorderInitID = env->GetMethodID(dvrRecorderClazz, "<init>", "()V"); 3193 gFields.onDvrRecordStatusID = 3194 env->GetMethodID(dvrRecorderClazz, "onRecordStatusChanged", "(I)V"); 3195 3196 jclass dvrPlaybackClazz = env->FindClass("android/media/tv/tuner/dvr/DvrPlayback"); 3197 gFields.dvrPlaybackContext = env->GetFieldID(dvrPlaybackClazz, "mNativeContext", "J"); 3198 gFields.dvrPlaybackInitID = env->GetMethodID(dvrPlaybackClazz, "<init>", "()V"); 3199 gFields.onDvrPlaybackStatusID = 3200 env->GetMethodID(dvrPlaybackClazz, "onPlaybackStatusChanged", "(I)V"); 3201 3202 jclass mediaEventClazz = env->FindClass("android/media/tv/tuner/filter/MediaEvent"); 3203 gFields.mediaEventContext = env->GetFieldID(mediaEventClazz, "mNativeContext", "J"); 3204 3205 jclass linearBlockClazz = env->FindClass("android/media/MediaCodec$LinearBlock"); 3206 gFields.linearBlockInitID = env->GetMethodID(linearBlockClazz, "<init>", "()V"); 3207 gFields.linearBlockSetInternalStateID = 3208 env->GetMethodID(linearBlockClazz, "setInternalStateLocked", "(JZ)V"); 3209 } 3210 3211 static void android_media_tv_Tuner_native_setup(JNIEnv *env, jobject thiz) { 3212 sp<JTuner> tuner = new JTuner(env, thiz); 3213 setTuner(env, thiz, tuner); 3214 } 3215 3216 static jint android_media_tv_Tuner_native_get_tuner_version(JNIEnv *env, jobject thiz) { 3217 sp<JTuner> tuner = getTuner(env, thiz); 3218 return tuner->getTunerVersion(); 3219 } 3220 3221 static jobject android_media_tv_Tuner_get_frontend_ids(JNIEnv *env, jobject thiz) { 3222 sp<JTuner> tuner = getTuner(env, thiz); 3223 return tuner->getFrontendIds(); 3224 } 3225 3226 static jobject android_media_tv_Tuner_open_frontend_by_handle( 3227 JNIEnv *env, jobject thiz, jint handle) { 3228 sp<JTuner> tuner = getTuner(env, thiz); 3229 return tuner->openFrontendByHandle(handle); 3230 } 3231 3232 static int android_media_tv_Tuner_tune(JNIEnv *env, jobject thiz, jint type, jobject settings) { 3233 sp<JTuner> tuner = getTuner(env, thiz); 3234 FrontendSettings setting = getFrontendSettings(env, type, settings); 3235 FrontendSettingsExt1_1 settingExt = getFrontendSettingsExt1_1( 3236 env, type, settings, tuner->getTunerVersion()); 3237 return tuner->tune(setting, settingExt); 3238 } 3239 3240 static int android_media_tv_Tuner_stop_tune(JNIEnv *env, jobject thiz) { 3241 sp<JTuner> tuner = getTuner(env, thiz); 3242 return tuner->stopTune(); 3243 } 3244 3245 static int android_media_tv_Tuner_scan( 3246 JNIEnv *env, jobject thiz, jint settingsType, jobject settings, jint scanType) { 3247 sp<JTuner> tuner = getTuner(env, thiz); 3248 FrontendSettings setting = getFrontendSettings(env, settingsType, settings); 3249 FrontendSettingsExt1_1 settingExt = getFrontendSettingsExt1_1( 3250 env, settingsType, settings, tuner->getTunerVersion()); 3251 return tuner->scan(setting, static_cast<FrontendScanType>(scanType), settingExt); 3252 } 3253 3254 static int android_media_tv_Tuner_stop_scan(JNIEnv *env, jobject thiz) { 3255 sp<JTuner> tuner = getTuner(env, thiz); 3256 return tuner->stopScan(); 3257 } 3258 3259 static int android_media_tv_Tuner_set_lnb(JNIEnv *env, jobject thiz, jobject lnb) { 3260 sp<JTuner> tuner = getTuner(env, thiz); 3261 sp<LnbClient> lnbClient = getLnbClient(env, lnb); 3262 if (lnbClient == NULL) { 3263 ALOGE("lnb is not initialized"); 3264 return (int)Result::INVALID_STATE; 3265 } 3266 return tuner->setLnb(lnbClient); 3267 } 3268 3269 static int android_media_tv_Tuner_set_lna(JNIEnv *env, jobject thiz, jboolean enable) { 3270 sp<JTuner> tuner = getTuner(env, thiz); 3271 return tuner->setLna(enable); 3272 } 3273 3274 static jobject android_media_tv_Tuner_get_frontend_status( 3275 JNIEnv* env, jobject thiz, jintArray types) { 3276 sp<JTuner> tuner = getTuner(env, thiz); 3277 return tuner->getFrontendStatus(types); 3278 } 3279 3280 static jobject android_media_tv_Tuner_get_av_sync_hw_id( 3281 JNIEnv *env, jobject thiz, jobject filter) { 3282 sp<FilterClient> filterClient = getFilterClient(env, filter); 3283 if (filterClient == NULL) { 3284 ALOGD("Failed to get sync ID. Filter client not found"); 3285 return NULL; 3286 } 3287 sp<JTuner> tuner = getTuner(env, thiz); 3288 return tuner->getAvSyncHwId(filterClient); 3289 } 3290 3291 static jobject android_media_tv_Tuner_get_av_sync_time(JNIEnv *env, jobject thiz, jint id) { 3292 sp<JTuner> tuner = getTuner(env, thiz); 3293 return tuner->getAvSyncTime(id); 3294 } 3295 3296 static int android_media_tv_Tuner_connect_cicam(JNIEnv *env, jobject thiz, jint id) { 3297 sp<JTuner> tuner = getTuner(env, thiz); 3298 return tuner->connectCiCam(id); 3299 } 3300 3301 static int android_media_tv_Tuner_link_cicam(JNIEnv *env, jobject thiz, jint id) { 3302 sp<JTuner> tuner = getTuner(env, thiz); 3303 return tuner->linkCiCam(id); 3304 } 3305 3306 static int android_media_tv_Tuner_disconnect_cicam(JNIEnv *env, jobject thiz) { 3307 sp<JTuner> tuner = getTuner(env, thiz); 3308 return tuner->disconnectCiCam(); 3309 } 3310 3311 static int android_media_tv_Tuner_unlink_cicam(JNIEnv *env, jobject thiz, jint id) { 3312 sp<JTuner> tuner = getTuner(env, thiz); 3313 return tuner->unlinkCiCam(id); 3314 } 3315 3316 static jobject android_media_tv_Tuner_get_frontend_info(JNIEnv *env, jobject thiz, jint id) { 3317 sp<JTuner> tuner = getTuner(env, thiz); 3318 return tuner->getFrontendInfo(id); 3319 } 3320 3321 static jobject android_media_tv_Tuner_open_lnb_by_handle(JNIEnv *env, jobject thiz, jint handle) { 3322 sp<JTuner> tuner = getTuner(env, thiz); 3323 return tuner->openLnbByHandle(handle); 3324 } 3325 3326 static jobject android_media_tv_Tuner_open_lnb_by_name(JNIEnv *env, jobject thiz, jstring name) { 3327 sp<JTuner> tuner = getTuner(env, thiz); 3328 return tuner->openLnbByName(name); 3329 } 3330 3331 3332 static jobject android_media_tv_Tuner_open_filter( 3333 JNIEnv *env, jobject thiz, jint type, jint subType, jlong bufferSize) { 3334 sp<JTuner> tuner = getTuner(env, thiz); 3335 DemuxFilterMainType mainType = static_cast<DemuxFilterMainType>(type); 3336 DemuxFilterType filterType { 3337 .mainType = mainType, 3338 }; 3339 3340 switch(mainType) { 3341 case DemuxFilterMainType::TS: 3342 filterType.subType.tsFilterType(static_cast<DemuxTsFilterType>(subType)); 3343 break; 3344 case DemuxFilterMainType::MMTP: 3345 filterType.subType.mmtpFilterType(static_cast<DemuxMmtpFilterType>(subType)); 3346 break; 3347 case DemuxFilterMainType::IP: 3348 filterType.subType.ipFilterType(static_cast<DemuxIpFilterType>(subType)); 3349 break; 3350 case DemuxFilterMainType::TLV: 3351 filterType.subType.tlvFilterType(static_cast<DemuxTlvFilterType>(subType)); 3352 break; 3353 case DemuxFilterMainType::ALP: 3354 filterType.subType.alpFilterType(static_cast<DemuxAlpFilterType>(subType)); 3355 break; 3356 } 3357 3358 return tuner->openFilter(filterType, bufferSize); 3359 } 3360 3361 static jobject android_media_tv_Tuner_open_time_filter(JNIEnv *env, jobject thiz) { 3362 sp<JTuner> tuner = getTuner(env, thiz); 3363 return tuner->openTimeFilter(); 3364 } 3365 3366 static DemuxFilterSectionBits getFilterSectionBits(JNIEnv *env, const jobject& settings) { 3367 jclass clazz = env->FindClass("android/media/tv/tuner/filter/SectionSettingsWithSectionBits"); 3368 jbyteArray jfilterBytes = static_cast<jbyteArray>( 3369 env->GetObjectField(settings, env->GetFieldID(clazz, "mFilter", "[B"))); 3370 jsize size = env->GetArrayLength(jfilterBytes); 3371 std::vector<uint8_t> filterBytes(size); 3372 env->GetByteArrayRegion( 3373 jfilterBytes, 0, size, reinterpret_cast<jbyte*>(&filterBytes[0])); 3374 3375 jbyteArray jmask = static_cast<jbyteArray>( 3376 env->GetObjectField(settings, env->GetFieldID(clazz, "mMask", "[B"))); 3377 size = env->GetArrayLength(jmask); 3378 std::vector<uint8_t> mask(size); 3379 env->GetByteArrayRegion(jmask, 0, size, reinterpret_cast<jbyte*>(&mask[0])); 3380 3381 jbyteArray jmode = static_cast<jbyteArray>( 3382 env->GetObjectField(settings, env->GetFieldID(clazz, "mMode", "[B"))); 3383 size = env->GetArrayLength(jmode); 3384 std::vector<uint8_t> mode(size); 3385 env->GetByteArrayRegion(jmode, 0, size, reinterpret_cast<jbyte*>(&mode[0])); 3386 3387 DemuxFilterSectionBits filterSectionBits { 3388 .filter = filterBytes, 3389 .mask = mask, 3390 .mode = mode, 3391 }; 3392 return filterSectionBits; 3393 } 3394 3395 static DemuxFilterSectionSettings::Condition::TableInfo getFilterTableInfo( 3396 JNIEnv *env, const jobject& settings) { 3397 jclass clazz = env->FindClass("android/media/tv/tuner/filter/SectionSettingsWithTableInfo"); 3398 uint16_t tableId = static_cast<uint16_t>( 3399 env->GetIntField(settings, env->GetFieldID(clazz, "mTableId", "I"))); 3400 uint16_t version = static_cast<uint16_t>( 3401 env->GetIntField(settings, env->GetFieldID(clazz, "mVersion", "I"))); 3402 DemuxFilterSectionSettings::Condition::TableInfo tableInfo { 3403 .tableId = tableId, 3404 .version = version, 3405 }; 3406 return tableInfo; 3407 } 3408 3409 static DemuxFilterSectionSettings getFilterSectionSettings(JNIEnv *env, const jobject& settings) { 3410 jclass clazz = env->FindClass("android/media/tv/tuner/filter/SectionSettings"); 3411 bool isCheckCrc = static_cast<bool>( 3412 env->GetBooleanField(settings, env->GetFieldID(clazz, "mCrcEnabled", "Z"))); 3413 bool isRepeat = static_cast<bool>( 3414 env->GetBooleanField(settings, env->GetFieldID(clazz, "mIsRepeat", "Z"))); 3415 bool isRaw = static_cast<bool>( 3416 env->GetBooleanField(settings, env->GetFieldID(clazz, "mIsRaw", "Z"))); 3417 3418 DemuxFilterSectionSettings filterSectionSettings { 3419 .isCheckCrc = isCheckCrc, 3420 .isRepeat = isRepeat, 3421 .isRaw = isRaw, 3422 }; 3423 if (env->IsInstanceOf( 3424 settings, 3425 env->FindClass("android/media/tv/tuner/filter/SectionSettingsWithSectionBits"))) { 3426 filterSectionSettings.condition.sectionBits(getFilterSectionBits(env, settings)); 3427 } else if (env->IsInstanceOf( 3428 settings, 3429 env->FindClass("android/media/tv/tuner/filter/SectionSettingsWithTableInfo"))) { 3430 filterSectionSettings.condition.tableInfo(getFilterTableInfo(env, settings)); 3431 } 3432 return filterSectionSettings; 3433 } 3434 3435 static DemuxFilterAvSettings getFilterAvSettings(JNIEnv *env, const jobject& settings) { 3436 jclass clazz = env->FindClass("android/media/tv/tuner/filter/AvSettings"); 3437 bool isPassthrough = static_cast<bool>( 3438 env->GetBooleanField(settings, env->GetFieldID(clazz, "mIsPassthrough", "Z"))); 3439 DemuxFilterAvSettings filterAvSettings { 3440 .isPassthrough = isPassthrough, 3441 }; 3442 return filterAvSettings; 3443 } 3444 3445 static bool getAvStreamType(JNIEnv *env, jobject filterConfigObj, AvStreamType& type) { 3446 jobject settingsObj = 3447 env->GetObjectField( 3448 filterConfigObj, 3449 env->GetFieldID( 3450 env->FindClass("android/media/tv/tuner/filter/FilterConfiguration"), 3451 "mSettings", 3452 "Landroid/media/tv/tuner/filter/Settings;")); 3453 jclass clazz = env->FindClass("android/media/tv/tuner/filter/AvSettings"); 3454 AvStreamType streamType; 3455 AudioStreamType audioStreamType = static_cast<AudioStreamType>( 3456 env->GetIntField(settingsObj, env->GetFieldID(clazz, "mAudioStreamType", "I"))); 3457 if (audioStreamType != AudioStreamType::UNDEFINED) { 3458 type.audio(audioStreamType); 3459 return true; 3460 } 3461 VideoStreamType videoStreamType = static_cast<VideoStreamType>( 3462 env->GetIntField(settingsObj, env->GetFieldID(clazz, "mVideoStreamType", "I"))); 3463 if (videoStreamType != VideoStreamType::UNDEFINED) { 3464 type.video(videoStreamType); 3465 return true; 3466 } 3467 return false; 3468 } 3469 3470 static DemuxFilterPesDataSettings getFilterPesDataSettings(JNIEnv *env, const jobject& settings) { 3471 jclass clazz = env->FindClass("android/media/tv/tuner/filter/PesSettings"); 3472 uint16_t streamId = static_cast<uint16_t>( 3473 env->GetIntField(settings, env->GetFieldID(clazz, "mStreamId", "I"))); 3474 bool isRaw = static_cast<bool>( 3475 env->GetBooleanField(settings, env->GetFieldID(clazz, "mIsRaw", "Z"))); 3476 DemuxFilterPesDataSettings filterPesDataSettings { 3477 .streamId = streamId, 3478 .isRaw = isRaw, 3479 }; 3480 return filterPesDataSettings; 3481 } 3482 3483 static DemuxFilterRecordSettings getFilterRecordSettings(JNIEnv *env, const jobject& settings) { 3484 jclass clazz = env->FindClass("android/media/tv/tuner/filter/RecordSettings"); 3485 hidl_bitfield<DemuxTsIndex> tsIndexMask = static_cast<hidl_bitfield<DemuxTsIndex>>( 3486 env->GetIntField(settings, env->GetFieldID(clazz, "mTsIndexMask", "I"))); 3487 DemuxRecordScIndexType scIndexType = static_cast<DemuxRecordScIndexType>( 3488 env->GetIntField(settings, env->GetFieldID(clazz, "mScIndexType", "I"))); 3489 jint scIndexMask = env->GetIntField(settings, env->GetFieldID(clazz, "mScIndexMask", "I")); 3490 3491 DemuxFilterRecordSettings filterRecordSettings { 3492 .tsIndexMask = tsIndexMask, 3493 .scIndexType = scIndexType, 3494 }; 3495 if (scIndexType == DemuxRecordScIndexType::SC) { 3496 filterRecordSettings.scIndexMask.sc(static_cast<hidl_bitfield<DemuxScIndex>>(scIndexMask)); 3497 } else if (scIndexType == DemuxRecordScIndexType::SC_HEVC) { 3498 filterRecordSettings.scIndexMask.scHevc( 3499 static_cast<hidl_bitfield<DemuxScHevcIndex>>(scIndexMask)); 3500 } 3501 return filterRecordSettings; 3502 } 3503 3504 static DemuxFilterDownloadSettings getFilterDownloadSettings(JNIEnv *env, const jobject& settings) { 3505 jclass clazz = env->FindClass("android/media/tv/tuner/filter/DownloadSettings"); 3506 uint32_t downloadId = static_cast<uint32_t>( 3507 env->GetIntField(settings, env->GetFieldID(clazz, "mDownloadId", "I"))); 3508 3509 DemuxFilterDownloadSettings filterDownloadSettings { 3510 .downloadId = downloadId, 3511 }; 3512 return filterDownloadSettings; 3513 } 3514 3515 static DemuxIpAddress getDemuxIpAddress(JNIEnv *env, const jobject& config) { 3516 jclass clazz = env->FindClass("android/media/tv/tuner/filter/IpFilterConfiguration"); 3517 3518 jbyteArray jsrcIpAddress = static_cast<jbyteArray>( 3519 env->GetObjectField(config, env->GetFieldID(clazz, "mSrcIpAddress", "[B"))); 3520 jsize srcSize = env->GetArrayLength(jsrcIpAddress); 3521 jbyteArray jdstIpAddress = static_cast<jbyteArray>( 3522 env->GetObjectField(config, env->GetFieldID(clazz, "mDstIpAddress", "[B"))); 3523 jsize dstSize = env->GetArrayLength(jdstIpAddress); 3524 3525 DemuxIpAddress res; 3526 3527 if (srcSize != dstSize) { 3528 // should never happen. Validated on Java size. 3529 jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", 3530 "IP address lengths don't match. srcLength=%d, dstLength=%d", srcSize, dstSize); 3531 return res; 3532 } 3533 3534 if (srcSize == IP_V4_LENGTH) { 3535 uint8_t srcAddr[IP_V4_LENGTH]; 3536 uint8_t dstAddr[IP_V4_LENGTH]; 3537 env->GetByteArrayRegion( 3538 jsrcIpAddress, 0, srcSize, reinterpret_cast<jbyte*>(srcAddr)); 3539 env->GetByteArrayRegion( 3540 jdstIpAddress, 0, dstSize, reinterpret_cast<jbyte*>(dstAddr)); 3541 res.srcIpAddress.v4(srcAddr); 3542 res.dstIpAddress.v4(dstAddr); 3543 } else if (srcSize == IP_V6_LENGTH) { 3544 uint8_t srcAddr[IP_V6_LENGTH]; 3545 uint8_t dstAddr[IP_V6_LENGTH]; 3546 env->GetByteArrayRegion( 3547 jsrcIpAddress, 0, srcSize, reinterpret_cast<jbyte*>(srcAddr)); 3548 env->GetByteArrayRegion( 3549 jdstIpAddress, 0, dstSize, reinterpret_cast<jbyte*>(dstAddr)); 3550 res.srcIpAddress.v6(srcAddr); 3551 res.dstIpAddress.v6(dstAddr); 3552 } else { 3553 // should never happen. Validated on Java size. 3554 jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", 3555 "Invalid IP address length %d", srcSize); 3556 return res; 3557 } 3558 3559 uint16_t srcPort = static_cast<uint16_t>( 3560 env->GetIntField(config, env->GetFieldID(clazz, "mSrcPort", "I"))); 3561 uint16_t dstPort = static_cast<uint16_t>( 3562 env->GetIntField(config, env->GetFieldID(clazz, "mDstPort", "I"))); 3563 3564 res.srcPort = srcPort; 3565 res.dstPort = dstPort; 3566 3567 return res; 3568 } 3569 3570 static DemuxFilterSettings getFilterConfiguration( 3571 JNIEnv *env, int type, int subtype, jobject filterConfigObj) { 3572 DemuxFilterSettings filterSettings; 3573 jobject settingsObj = 3574 env->GetObjectField( 3575 filterConfigObj, 3576 env->GetFieldID( 3577 env->FindClass("android/media/tv/tuner/filter/FilterConfiguration"), 3578 "mSettings", 3579 "Landroid/media/tv/tuner/filter/Settings;")); 3580 DemuxFilterMainType mainType = static_cast<DemuxFilterMainType>(type); 3581 switch (mainType) { 3582 case DemuxFilterMainType::TS: { 3583 jclass clazz = env->FindClass("android/media/tv/tuner/filter/TsFilterConfiguration"); 3584 uint16_t tpid = static_cast<uint16_t>( 3585 env->GetIntField(filterConfigObj, env->GetFieldID(clazz, "mTpid", "I"))); 3586 DemuxTsFilterSettings tsFilterSettings { 3587 .tpid = tpid, 3588 }; 3589 3590 if (settingsObj != NULL) { 3591 DemuxTsFilterType tsType = static_cast<DemuxTsFilterType>(subtype); 3592 switch (tsType) { 3593 case DemuxTsFilterType::SECTION: 3594 tsFilterSettings.filterSettings.section( 3595 getFilterSectionSettings(env, settingsObj)); 3596 break; 3597 case DemuxTsFilterType::AUDIO: 3598 case DemuxTsFilterType::VIDEO: 3599 tsFilterSettings.filterSettings.av(getFilterAvSettings(env, settingsObj)); 3600 break; 3601 case DemuxTsFilterType::PES: 3602 tsFilterSettings.filterSettings.pesData( 3603 getFilterPesDataSettings(env, settingsObj)); 3604 break; 3605 case DemuxTsFilterType::RECORD: 3606 tsFilterSettings.filterSettings.record( 3607 getFilterRecordSettings(env, settingsObj)); 3608 break; 3609 default: 3610 break; 3611 } 3612 } 3613 filterSettings.ts(tsFilterSettings); 3614 break; 3615 } 3616 case DemuxFilterMainType::MMTP: { 3617 jclass clazz = env->FindClass("android/media/tv/tuner/filter/MmtpFilterConfiguration"); 3618 uint16_t mmtpPid = static_cast<uint16_t>( 3619 env->GetIntField(filterConfigObj, env->GetFieldID(clazz, "mMmtpPid", "I"))); 3620 DemuxMmtpFilterSettings mmtpFilterSettings { 3621 .mmtpPid = mmtpPid, 3622 }; 3623 3624 if (settingsObj != NULL) { 3625 DemuxMmtpFilterType mmtpType = static_cast<DemuxMmtpFilterType>(subtype); 3626 switch (mmtpType) { 3627 case DemuxMmtpFilterType::SECTION: 3628 mmtpFilterSettings.filterSettings.section( 3629 getFilterSectionSettings(env, settingsObj)); 3630 break; 3631 case DemuxMmtpFilterType::AUDIO: 3632 case DemuxMmtpFilterType::VIDEO: 3633 mmtpFilterSettings.filterSettings.av(getFilterAvSettings(env, settingsObj)); 3634 break; 3635 case DemuxMmtpFilterType::PES: 3636 mmtpFilterSettings.filterSettings.pesData( 3637 getFilterPesDataSettings(env, settingsObj)); 3638 break; 3639 case DemuxMmtpFilterType::RECORD: 3640 mmtpFilterSettings.filterSettings.record( 3641 getFilterRecordSettings(env, settingsObj)); 3642 break; 3643 case DemuxMmtpFilterType::DOWNLOAD: 3644 mmtpFilterSettings.filterSettings.download( 3645 getFilterDownloadSettings(env, settingsObj)); 3646 break; 3647 default: 3648 break; 3649 } 3650 } 3651 filterSettings.mmtp(mmtpFilterSettings); 3652 break; 3653 } 3654 case DemuxFilterMainType::IP: { 3655 DemuxIpAddress ipAddr = getDemuxIpAddress(env, filterConfigObj); 3656 DemuxIpFilterSettings ipFilterSettings { 3657 .ipAddr = ipAddr, 3658 }; 3659 3660 DemuxIpFilterType ipType = static_cast<DemuxIpFilterType>(subtype); 3661 if (ipType == DemuxIpFilterType::SECTION && settingsObj != NULL) { 3662 ipFilterSettings.filterSettings.section( 3663 getFilterSectionSettings(env, settingsObj)); 3664 } else if (ipType == DemuxIpFilterType::IP) { 3665 jclass clazz = env->FindClass( 3666 "android/media/tv/tuner/filter/IpFilterConfiguration"); 3667 bool bPassthrough = static_cast<bool>( 3668 env->GetBooleanField( 3669 filterConfigObj, env->GetFieldID( 3670 clazz, "mPassthrough", "Z"))); 3671 ipFilterSettings.filterSettings.bPassthrough(bPassthrough); 3672 } 3673 filterSettings.ip(ipFilterSettings); 3674 break; 3675 } 3676 case DemuxFilterMainType::TLV: { 3677 jclass clazz = env->FindClass("android/media/tv/tuner/filter/TlvFilterConfiguration"); 3678 uint8_t packetType = static_cast<uint8_t>( 3679 env->GetIntField(filterConfigObj, env->GetFieldID(clazz, "mPacketType", "I"))); 3680 bool isCompressedIpPacket = static_cast<bool>( 3681 env->GetBooleanField( 3682 filterConfigObj, env->GetFieldID(clazz, "mIsCompressedIpPacket", "Z"))); 3683 3684 DemuxTlvFilterSettings tlvFilterSettings { 3685 .packetType = packetType, 3686 .isCompressedIpPacket = isCompressedIpPacket, 3687 }; 3688 3689 DemuxTlvFilterType tlvType = static_cast<DemuxTlvFilterType>(subtype); 3690 if (tlvType == DemuxTlvFilterType::SECTION && settingsObj != NULL) { 3691 tlvFilterSettings.filterSettings.section( 3692 getFilterSectionSettings(env, settingsObj)); 3693 } else if (tlvType == DemuxTlvFilterType::TLV) { 3694 bool bPassthrough = static_cast<bool>( 3695 env->GetBooleanField( 3696 filterConfigObj, env->GetFieldID( 3697 clazz, "mPassthrough", "Z"))); 3698 tlvFilterSettings.filterSettings.bPassthrough(bPassthrough); 3699 } 3700 filterSettings.tlv(tlvFilterSettings); 3701 break; 3702 } 3703 case DemuxFilterMainType::ALP: { 3704 jclass clazz = env->FindClass("android/media/tv/tuner/filter/AlpFilterConfiguration"); 3705 uint8_t packetType = static_cast<uint8_t>( 3706 env->GetIntField(filterConfigObj, env->GetFieldID(clazz, "mPacketType", "I"))); 3707 DemuxAlpLengthType lengthType = static_cast<DemuxAlpLengthType>( 3708 env->GetIntField(filterConfigObj, env->GetFieldID(clazz, "mLengthType", "I"))); 3709 DemuxAlpFilterSettings alpFilterSettings { 3710 .packetType = packetType, 3711 .lengthType = lengthType, 3712 }; 3713 3714 if (settingsObj != NULL) { 3715 DemuxAlpFilterType alpType = static_cast<DemuxAlpFilterType>(subtype); 3716 switch (alpType) { 3717 case DemuxAlpFilterType::SECTION: 3718 alpFilterSettings.filterSettings.section( 3719 getFilterSectionSettings(env, settingsObj)); 3720 break; 3721 default: 3722 break; 3723 } 3724 } 3725 filterSettings.alp(alpFilterSettings); 3726 break; 3727 } 3728 default: { 3729 break; 3730 } 3731 } 3732 return filterSettings; 3733 } 3734 3735 static Result configureIpFilterContextId( 3736 JNIEnv *env, sp<FilterClient> filterClient, jobject ipFilterConfigObj) { 3737 jclass clazz = env->FindClass( 3738 "android/media/tv/tuner/filter/IpFilterConfiguration"); 3739 uint32_t cid = env->GetIntField(ipFilterConfigObj, env->GetFieldID( 3740 clazz, "mIpFilterContextId", "I")); 3741 3742 return filterClient->configureIpFilterContextId(cid); 3743 } 3744 3745 static bool isAvFilterSettings(DemuxFilterSettings filterSettings) { 3746 return (filterSettings.getDiscriminator() == DemuxFilterSettings::hidl_discriminator::ts 3747 && filterSettings.ts().filterSettings.getDiscriminator() 3748 == DemuxTsFilterSettings::FilterSettings::hidl_discriminator::av) 3749 || 3750 (filterSettings.getDiscriminator() == DemuxFilterSettings::hidl_discriminator::mmtp 3751 && filterSettings.mmtp().filterSettings.getDiscriminator() 3752 == DemuxMmtpFilterSettings::FilterSettings::hidl_discriminator::av); 3753 } 3754 3755 static jint android_media_tv_Tuner_configure_filter( 3756 JNIEnv *env, jobject filter, int type, int subtype, jobject settings) { 3757 ALOGD("configure filter type=%d, subtype=%d", type, subtype); 3758 sp<FilterClient> filterClient = getFilterClient(env, filter); 3759 if (filterClient == NULL) { 3760 ALOGD("Failed to configure filter: filter not found"); 3761 return (jint) Result::NOT_INITIALIZED; 3762 } 3763 DemuxFilterSettings filterSettings = getFilterConfiguration(env, type, subtype, settings); 3764 Result res = filterClient->configure(filterSettings); 3765 3766 if (res != Result::SUCCESS) { 3767 return (jint) res; 3768 } 3769 3770 if (static_cast<DemuxFilterMainType>(type) == DemuxFilterMainType::IP) { 3771 res = configureIpFilterContextId(env, filterClient, settings); 3772 if (res != Result::SUCCESS) { 3773 return (jint) res; 3774 } 3775 } 3776 3777 AvStreamType streamType; 3778 if (isAvFilterSettings(filterSettings) && getAvStreamType(env, settings, streamType)) { 3779 res = filterClient->configureAvStreamType(streamType); 3780 } 3781 return (jint) res; 3782 } 3783 3784 static jint android_media_tv_Tuner_get_filter_id(JNIEnv* env, jobject filter) { 3785 sp<FilterClient> filterClient = getFilterClient(env, filter); 3786 if (filterClient == NULL) { 3787 ALOGD("Failed to get filter ID: filter client not found"); 3788 return (int) Result::NOT_INITIALIZED; 3789 } 3790 uint32_t id; 3791 Result res = filterClient->getId(id); 3792 if (res != Result::SUCCESS) { 3793 return (jint) Constant::INVALID_FILTER_ID; 3794 } 3795 return (jint) id; 3796 } 3797 3798 static jlong android_media_tv_Tuner_get_filter_64bit_id(JNIEnv* env, jobject filter) { 3799 sp<FilterClient> filterClient = getFilterClient(env, filter); 3800 if (filterClient == NULL) { 3801 ALOGD("Failed to get filter ID 64 bit: filter client not found"); 3802 return (int) Result::NOT_INITIALIZED; 3803 } 3804 uint64_t id; 3805 Result res = filterClient->getId64Bit(id); 3806 return (res == Result::SUCCESS) ? 3807 static_cast<jlong>(id) : static_cast<jlong>( 3808 ::android::hardware::tv::tuner::V1_1::Constant64Bit::INVALID_FILTER_ID_64BIT); 3809 } 3810 3811 static jint android_media_tv_Tuner_configure_monitor_event( 3812 JNIEnv* env, jobject filter, int monitorEventType) { 3813 sp<FilterClient> filterClient = getFilterClient(env, filter); 3814 if (filterClient == NULL) { 3815 ALOGD("Failed to configure scrambling event: filter client not found"); 3816 return (int) Result::NOT_INITIALIZED; 3817 } 3818 Result res = filterClient->configureMonitorEvent(monitorEventType); 3819 return (jint) res; 3820 } 3821 3822 static jint android_media_tv_Tuner_set_filter_data_source( 3823 JNIEnv* env, jobject filter, jobject srcFilter) { 3824 sp<FilterClient> filterClient = getFilterClient(env, filter); 3825 if (filterClient == NULL) { 3826 ALOGD("Failed to set filter data source: filter client not found"); 3827 return (int) Result::NOT_INITIALIZED; 3828 } 3829 Result res; 3830 if (srcFilter == NULL) { 3831 res = filterClient->setDataSource(NULL); 3832 } else { 3833 sp<FilterClient> srcClient = getFilterClient(env, srcFilter); 3834 if (srcClient == NULL) { 3835 ALOGD("Failed to set filter data source: src filter not found"); 3836 return (jint) Result::INVALID_ARGUMENT; 3837 } 3838 res = filterClient->setDataSource(srcClient); 3839 } 3840 return (jint) res; 3841 } 3842 3843 static jint android_media_tv_Tuner_start_filter(JNIEnv *env, jobject filter) { 3844 sp<FilterClient> filterClient = getFilterClient(env, filter); 3845 if (filterClient == NULL) { 3846 ALOGD("Failed to start filter: filter client not found"); 3847 return (int) Result::NOT_INITIALIZED; 3848 } 3849 return (jint) filterClient->start(); 3850 } 3851 3852 static jint android_media_tv_Tuner_stop_filter(JNIEnv *env, jobject filter) { 3853 sp<FilterClient> filterClient = getFilterClient(env, filter); 3854 if (filterClient == NULL) { 3855 ALOGD("Failed to stop filter: filter client not found"); 3856 return (int) Result::NOT_INITIALIZED; 3857 } 3858 return (jint) filterClient->stop(); 3859 } 3860 3861 static jint android_media_tv_Tuner_flush_filter(JNIEnv *env, jobject filter) { 3862 sp<FilterClient> filterClient = getFilterClient(env, filter); 3863 if (filterClient == NULL) { 3864 ALOGD("Failed to flush filter: filter client not found"); 3865 return (int) Result::NOT_INITIALIZED; 3866 } 3867 return (jint) filterClient->flush(); 3868 } 3869 3870 static jint android_media_tv_Tuner_read_filter_fmq( 3871 JNIEnv *env, jobject filter, jbyteArray buffer, jlong offset, jlong size) { 3872 sp<FilterClient> filterClient = getFilterClient(env, filter); 3873 if (filterClient == NULL) { 3874 jniThrowException(env, "java/lang/IllegalStateException", 3875 "Failed to read filter FMQ: filter client not found"); 3876 return -1; 3877 } 3878 3879 jboolean isCopy; 3880 jbyte *dst = env->GetByteArrayElements(buffer, &isCopy); 3881 ALOGD("copyData, isCopy=%d", isCopy); 3882 if (dst == nullptr) { 3883 jniThrowRuntimeException(env, "Failed to GetByteArrayElements"); 3884 return -1; 3885 } 3886 int realReadSize = filterClient->read(reinterpret_cast<int8_t*>(dst) + offset, size); 3887 env->ReleaseByteArrayElements(buffer, dst, 0); 3888 return (jint) realReadSize; 3889 } 3890 3891 static jint android_media_tv_Tuner_close_filter(JNIEnv *env, jobject filter) { 3892 sp<FilterClient> filterClient = getFilterClient(env, filter); 3893 if (filterClient == NULL) { 3894 jniThrowException(env, "java/lang/IllegalStateException", 3895 "Failed to close filter: filter client not found"); 3896 return 0; 3897 } 3898 3899 return (jint) filterClient->close(); 3900 } 3901 3902 static sp<TimeFilterClient> getTimeFilterClient(JNIEnv *env, jobject filter) { 3903 return (TimeFilterClient *)env->GetLongField(filter, gFields.timeFilterContext); 3904 } 3905 3906 static int android_media_tv_Tuner_time_filter_set_timestamp( 3907 JNIEnv *env, jobject filter, jlong timestamp) { 3908 sp<TimeFilterClient> timeFilterClient = getTimeFilterClient(env, filter); 3909 if (timeFilterClient == NULL) { 3910 ALOGD("Failed set timestamp: time filter client not found"); 3911 return (int) Result::INVALID_STATE; 3912 } 3913 Result r = timeFilterClient->setTimeStamp(static_cast<uint64_t>(timestamp)); 3914 return (int) r; 3915 } 3916 3917 static int android_media_tv_Tuner_time_filter_clear_timestamp(JNIEnv *env, jobject filter) { 3918 sp<TimeFilterClient> timeFilterClient = getTimeFilterClient(env, filter); 3919 if (timeFilterClient == NULL) { 3920 ALOGD("Failed clear timestamp: time filter client not found"); 3921 return (int) Result::INVALID_STATE; 3922 } 3923 Result r = timeFilterClient->clearTimeStamp(); 3924 return (int) r; 3925 } 3926 3927 static jobject android_media_tv_Tuner_time_filter_get_timestamp(JNIEnv *env, jobject filter) { 3928 sp<TimeFilterClient> timeFilterClient = getTimeFilterClient(env, filter); 3929 if (timeFilterClient == NULL) { 3930 ALOGD("Failed get timestamp: time filter client not found"); 3931 return NULL; 3932 } 3933 uint64_t timestamp = timeFilterClient->getTimeStamp(); 3934 if (timestamp == (long)Constant64Bit::INVALID_PRESENTATION_TIME_STAMP) { 3935 return NULL; 3936 } 3937 3938 jclass longClazz = env->FindClass("java/lang/Long"); 3939 jmethodID longInit = env->GetMethodID(longClazz, "<init>", "(J)V"); 3940 3941 jobject longObj = env->NewObject(longClazz, longInit, static_cast<jlong>(timestamp)); 3942 return longObj; 3943 } 3944 3945 static jobject android_media_tv_Tuner_time_filter_get_source_time(JNIEnv *env, jobject filter) { 3946 sp<TimeFilterClient> timeFilterClient = getTimeFilterClient(env, filter); 3947 if (timeFilterClient == NULL) { 3948 ALOGD("Failed get source time: time filter client not found"); 3949 return NULL; 3950 } 3951 uint64_t timestamp = timeFilterClient->getSourceTime(); 3952 if (timestamp == (long)Constant64Bit::INVALID_PRESENTATION_TIME_STAMP) { 3953 return NULL; 3954 } 3955 3956 jclass longClazz = env->FindClass("java/lang/Long"); 3957 jmethodID longInit = env->GetMethodID(longClazz, "<init>", "(J)V"); 3958 3959 jobject longObj = env->NewObject(longClazz, longInit, static_cast<jlong>(timestamp)); 3960 return longObj; 3961 } 3962 3963 static int android_media_tv_Tuner_time_filter_close(JNIEnv *env, jobject filter) { 3964 sp<TimeFilterClient> timeFilterClient = getTimeFilterClient(env, filter); 3965 if (timeFilterClient == NULL) { 3966 ALOGD("Failed close time filter: time filter client not found"); 3967 return (int) Result::INVALID_STATE; 3968 } 3969 3970 Result r = timeFilterClient->close(); 3971 if (r == Result::SUCCESS) { 3972 timeFilterClient->decStrong(filter); 3973 env->SetLongField(filter, gFields.timeFilterContext, 0); 3974 } 3975 return (int) r; 3976 } 3977 3978 static jobject android_media_tv_Tuner_open_descrambler(JNIEnv *env, jobject thiz, jint) { 3979 sp<JTuner> tuner = getTuner(env, thiz); 3980 return tuner->openDescrambler(); 3981 } 3982 3983 static jint android_media_tv_Tuner_descrambler_add_pid( 3984 JNIEnv *env, jobject descrambler, jint pidType, jint pid, jobject filter) { 3985 sp<DescramblerClient> descramblerClient = getDescramblerClient(env, descrambler); 3986 if (descramblerClient == NULL) { 3987 return (jint) Result::NOT_INITIALIZED; 3988 } 3989 sp<FilterClient> filterClient = (filter == NULL) ? NULL : getFilterClient(env, filter); 3990 Result result = descramblerClient->addPid(getDemuxPid((int)pidType, (int)pid), filterClient); 3991 return (jint) result; 3992 } 3993 3994 static jint android_media_tv_Tuner_descrambler_remove_pid( 3995 JNIEnv *env, jobject descrambler, jint pidType, jint pid, jobject filter) { 3996 sp<DescramblerClient> descramblerClient = getDescramblerClient(env, descrambler); 3997 if (descramblerClient == NULL) { 3998 return (jint) Result::NOT_INITIALIZED; 3999 } 4000 sp<FilterClient> filterClient = (filter == NULL) ? NULL : getFilterClient(env, filter); 4001 Result result = descramblerClient->removePid(getDemuxPid((int)pidType, (int)pid), filterClient); 4002 return (jint) result; 4003 } 4004 4005 static jint android_media_tv_Tuner_descrambler_set_key_token( 4006 JNIEnv* env, jobject descrambler, jbyteArray keyToken) { 4007 sp<DescramblerClient> descramblerClient = getDescramblerClient(env, descrambler); 4008 if (descramblerClient == NULL) { 4009 return (jint) Result::NOT_INITIALIZED; 4010 } 4011 int size = env->GetArrayLength(keyToken); 4012 std::vector<uint8_t> v(size); 4013 env->GetByteArrayRegion(keyToken, 0, size, reinterpret_cast<jbyte*>(&v[0])); 4014 Result result = descramblerClient->setKeyToken(v); 4015 return (jint) result; 4016 } 4017 4018 static jint android_media_tv_Tuner_close_descrambler(JNIEnv* env, jobject descrambler) { 4019 sp<DescramblerClient> descramblerClient = getDescramblerClient(env, descrambler); 4020 if (descramblerClient == NULL) { 4021 return (jint) Result::NOT_INITIALIZED; 4022 } 4023 Result r = descramblerClient->close(); 4024 if (r == Result::SUCCESS) { 4025 descramblerClient->decStrong(descrambler); 4026 } 4027 return (jint) r; 4028 } 4029 4030 static jobject android_media_tv_Tuner_open_dvr_recorder( 4031 JNIEnv* env, jobject thiz, jlong bufferSize) { 4032 sp<JTuner> tuner = getTuner(env, thiz); 4033 return tuner->openDvr(DvrType::RECORD, bufferSize); 4034 } 4035 4036 static jobject android_media_tv_Tuner_open_dvr_playback( 4037 JNIEnv* env, jobject thiz, jlong bufferSize) { 4038 sp<JTuner> tuner = getTuner(env, thiz); 4039 return tuner->openDvr(DvrType::PLAYBACK, bufferSize); 4040 } 4041 4042 static jobject android_media_tv_Tuner_get_demux_caps(JNIEnv* env, jobject thiz) { 4043 sp<JTuner> tuner = getTuner(env, thiz); 4044 return tuner->getDemuxCaps(); 4045 } 4046 4047 static jint android_media_tv_Tuner_open_demux(JNIEnv* env, jobject thiz, jint handle) { 4048 sp<JTuner> tuner = getTuner(env, thiz); 4049 return (jint) tuner->openDemux(handle); 4050 } 4051 4052 static jint android_media_tv_Tuner_close_tuner(JNIEnv* env, jobject thiz) { 4053 sp<JTuner> tuner = getTuner(env, thiz); 4054 setTuner(env, thiz, NULL); 4055 return (jint) tuner->close(); 4056 } 4057 4058 static jint android_media_tv_Tuner_close_demux(JNIEnv* env, jobject thiz, jint /* handle */) { 4059 sp<JTuner> tuner = getTuner(env, thiz); 4060 return tuner->closeDemux(); 4061 } 4062 4063 static jint android_media_tv_Tuner_close_frontend(JNIEnv* env, jobject thiz, jint /* handle */) { 4064 sp<JTuner> tuner = getTuner(env, thiz); 4065 return tuner->closeFrontend(); 4066 } 4067 4068 static jint android_media_tv_Tuner_attach_filter(JNIEnv *env, jobject dvr, jobject filter) { 4069 sp<FilterClient> filterClient = getFilterClient(env, filter); 4070 if (filterClient == NULL) { 4071 return (jint) Result::INVALID_ARGUMENT; 4072 } 4073 sp<DvrClient> dvrClient = getDvrClient(env, dvr); 4074 if (dvrClient == NULL) { 4075 return (jint) Result::NOT_INITIALIZED; 4076 } 4077 Result result = dvrClient->attachFilter(filterClient); 4078 return (jint) result; 4079 } 4080 4081 static jint android_media_tv_Tuner_detach_filter(JNIEnv *env, jobject dvr, jobject filter) { 4082 sp<FilterClient> filterClient = getFilterClient(env, filter); 4083 if (filterClient == NULL) { 4084 return (jint) Result::INVALID_ARGUMENT; 4085 } 4086 sp<DvrClient> dvrClient = getDvrClient(env, dvr); 4087 if (dvrClient == NULL) { 4088 return (jint) Result::NOT_INITIALIZED; 4089 } 4090 Result result = dvrClient->detachFilter(filterClient); 4091 return (jint) result; 4092 } 4093 4094 static jint android_media_tv_Tuner_configure_dvr(JNIEnv *env, jobject dvr, jobject settings) { 4095 sp<DvrClient> dvrClient = getDvrClient(env, dvr); 4096 if (dvrClient == NULL) { 4097 ALOGD("Failed to configure dvr: dvr client not found"); 4098 return (int)Result::NOT_INITIALIZED; 4099 } 4100 bool isRecorder = 4101 env->IsInstanceOf(dvr, env->FindClass("android/media/tv/tuner/dvr/DvrRecorder")); 4102 Result result = dvrClient->configure(getDvrSettings(env, settings, isRecorder)); 4103 return (jint) result; 4104 } 4105 4106 static jint android_media_tv_Tuner_start_dvr(JNIEnv *env, jobject dvr) { 4107 sp<DvrClient> dvrClient = getDvrClient(env, dvr); 4108 if (dvrClient == NULL) { 4109 ALOGD("Failed to start dvr: dvr client not found"); 4110 return (jint) Result::NOT_INITIALIZED; 4111 } 4112 Result result = dvrClient->start(); 4113 return (jint) result; 4114 } 4115 4116 static jint android_media_tv_Tuner_stop_dvr(JNIEnv *env, jobject dvr) { 4117 sp<DvrClient> dvrClient = getDvrClient(env, dvr); 4118 if (dvrClient == NULL) { 4119 ALOGD("Failed to stop dvr: dvr client not found"); 4120 return (jint) Result::NOT_INITIALIZED; 4121 } 4122 Result result = dvrClient->stop(); 4123 return (jint) result; 4124 } 4125 4126 static jint android_media_tv_Tuner_flush_dvr(JNIEnv *env, jobject dvr) { 4127 sp<DvrClient> dvrClient = getDvrClient(env, dvr); 4128 if (dvrClient == NULL) { 4129 ALOGD("Failed to flush dvr: dvr client not found"); 4130 return (jint) Result::NOT_INITIALIZED; 4131 } 4132 Result result = dvrClient->flush(); 4133 return (jint) result; 4134 } 4135 4136 static jint android_media_tv_Tuner_close_dvr(JNIEnv* env, jobject dvr) { 4137 sp<DvrClient> dvrClient = getDvrClient(env, dvr); 4138 if (dvrClient == NULL) { 4139 ALOGD("Failed to close dvr: dvr client not found"); 4140 return (jint) Result::NOT_INITIALIZED; 4141 } 4142 return (jint) dvrClient->close(); 4143 } 4144 4145 static jint android_media_tv_Tuner_lnb_set_voltage(JNIEnv* env, jobject lnb, jint voltage) { 4146 sp<LnbClient> lnbClient = getLnbClient(env, lnb); 4147 Result r = lnbClient->setVoltage(static_cast<LnbVoltage>(voltage)); 4148 return (jint) r; 4149 } 4150 4151 static int android_media_tv_Tuner_lnb_set_tone(JNIEnv* env, jobject lnb, jint tone) { 4152 sp<LnbClient> lnbClient = getLnbClient(env, lnb); 4153 Result r = lnbClient->setTone(static_cast<LnbTone>(tone)); 4154 return (jint) r; 4155 } 4156 4157 static int android_media_tv_Tuner_lnb_set_position(JNIEnv* env, jobject lnb, jint position) { 4158 sp<LnbClient> lnbClient = getLnbClient(env, lnb); 4159 Result r = lnbClient->setSatellitePosition(static_cast<LnbPosition>(position)); 4160 return (jint) r; 4161 } 4162 4163 static int android_media_tv_Tuner_lnb_send_diseqc_msg(JNIEnv* env, jobject lnb, jbyteArray msg) { 4164 sp<LnbClient> lnbClient = getLnbClient(env, lnb); 4165 int size = env->GetArrayLength(msg); 4166 std::vector<uint8_t> v(size); 4167 env->GetByteArrayRegion(msg, 0, size, reinterpret_cast<jbyte*>(&v[0])); 4168 Result r = lnbClient->sendDiseqcMessage(v); 4169 return (jint) r; 4170 } 4171 4172 static int android_media_tv_Tuner_close_lnb(JNIEnv* env, jobject lnb) { 4173 sp<LnbClient> lnbClient = getLnbClient(env, lnb); 4174 Result r = lnbClient->close(); 4175 if (r == Result::SUCCESS) { 4176 lnbClient->decStrong(lnb); 4177 env->SetLongField(lnb, gFields.lnbContext, 0); 4178 } 4179 return (jint) r; 4180 } 4181 4182 static void android_media_tv_Tuner_dvr_set_fd(JNIEnv *env, jobject dvr, jint fd) { 4183 sp<DvrClient> dvrClient = getDvrClient(env, dvr); 4184 if (dvrClient == NULL) { 4185 ALOGD("Failed to set FD for dvr: dvr client not found"); 4186 return; 4187 } 4188 dvrClient->setFd((int)fd); 4189 ALOGD("set fd = %d", fd); 4190 } 4191 4192 static jlong android_media_tv_Tuner_read_dvr(JNIEnv *env, jobject dvr, jlong size) { 4193 sp<DvrClient> dvrClient = getDvrClient(env, dvr); 4194 if (dvrClient == NULL) { 4195 jniThrowException(env, "java/lang/IllegalStateException", 4196 "Failed to read dvr: dvr client not found"); 4197 return -1; 4198 } 4199 4200 return (jlong) dvrClient->readFromFile(size); 4201 } 4202 4203 static jlong android_media_tv_Tuner_read_dvr_from_array( 4204 JNIEnv* env, jobject dvr, jbyteArray buffer, jlong offset, jlong size) { 4205 sp<DvrClient> dvrClient = getDvrClient(env, dvr); 4206 if (dvrClient == NULL) { 4207 ALOGW("Failed to read dvr: dvr client not found"); 4208 return -1; 4209 } 4210 4211 jboolean isCopy; 4212 jbyte *src = env->GetByteArrayElements(buffer, &isCopy); 4213 if (src == nullptr) { 4214 ALOGD("Failed to GetByteArrayElements"); 4215 return -1; 4216 } 4217 long realSize = dvrClient->readFromBuffer(reinterpret_cast<signed char*>(src) + offset, size); 4218 env->ReleaseByteArrayElements(buffer, src, 0); 4219 return (jlong) realSize; 4220 4221 } 4222 4223 static jlong android_media_tv_Tuner_write_dvr(JNIEnv *env, jobject dvr, jlong size) { 4224 sp<DvrClient> dvrClient = getDvrClient(env, dvr); 4225 if (dvrClient == NULL) { 4226 jniThrowException(env, "java/lang/IllegalStateException", 4227 "Failed to write dvr: dvr client not found"); 4228 return -1; 4229 } 4230 4231 return (jlong) dvrClient->writeToFile(size); 4232 } 4233 4234 static jlong android_media_tv_Tuner_write_dvr_to_array( 4235 JNIEnv *env, jobject dvr, jbyteArray buffer, jlong offset, jlong size) { 4236 sp<DvrClient> dvrClient = getDvrClient(env, dvr); 4237 if (dvrClient == NULL) { 4238 ALOGW("Failed to read dvr: dvr client not found"); 4239 return -1; 4240 } 4241 4242 jboolean isCopy; 4243 jbyte *dst = env->GetByteArrayElements(buffer, &isCopy); 4244 ALOGD("copyData, isCopy=%d", isCopy); 4245 if (dst == nullptr) { 4246 jniThrowRuntimeException(env, "Failed to GetByteArrayElements"); 4247 return -1; 4248 } 4249 4250 long realSize = dvrClient->writeToBuffer(reinterpret_cast<signed char*>(dst) + offset, size); 4251 env->ReleaseByteArrayElements(buffer, dst, 0); 4252 return (jlong) realSize; 4253 } 4254 4255 static sp<MediaEvent> getMediaEventSp(JNIEnv *env, jobject mediaEventObj) { 4256 return (MediaEvent *)env->GetLongField(mediaEventObj, gFields.mediaEventContext); 4257 } 4258 4259 static jobject android_media_tv_Tuner_media_event_get_linear_block( 4260 JNIEnv* env, jobject mediaEventObj) { 4261 sp<MediaEvent> mediaEventSp = getMediaEventSp(env, mediaEventObj); 4262 if (mediaEventSp == NULL) { 4263 ALOGD("Failed get MediaEvent"); 4264 return NULL; 4265 } 4266 android::Mutex::Autolock autoLock(mediaEventSp->mLock); 4267 4268 return mediaEventSp->getLinearBlock(); 4269 } 4270 4271 static jobject android_media_tv_Tuner_media_event_get_audio_handle( 4272 JNIEnv* env, jobject mediaEventObj) { 4273 sp<MediaEvent> mediaEventSp = getMediaEventSp(env, mediaEventObj); 4274 if (mediaEventSp == NULL) { 4275 ALOGD("Failed get MediaEvent"); 4276 return NULL; 4277 } 4278 4279 android::Mutex::Autolock autoLock(mediaEventSp->mLock); 4280 uint64_t audioHandle = mediaEventSp->getAudioHandle(); 4281 jclass longClazz = env->FindClass("java/lang/Long"); 4282 jmethodID longInit = env->GetMethodID(longClazz, "<init>", "(J)V"); 4283 4284 jobject longObj = env->NewObject(longClazz, longInit, static_cast<jlong>(audioHandle)); 4285 return longObj; 4286 } 4287 4288 static void android_media_tv_Tuner_media_event_finalize(JNIEnv* env, jobject mediaEventObj) { 4289 sp<MediaEvent> mediaEventSp = getMediaEventSp(env, mediaEventObj); 4290 if (mediaEventSp == NULL) { 4291 ALOGD("Failed get MediaEvent"); 4292 return; 4293 } 4294 4295 android::Mutex::Autolock autoLock(mediaEventSp->mLock); 4296 mediaEventSp->mAvHandleRefCnt--; 4297 mediaEventSp->finalize(); 4298 4299 mediaEventSp->decStrong(mediaEventObj); 4300 } 4301 4302 static const JNINativeMethod gTunerMethods[] = { 4303 { "nativeInit", "()V", (void *)android_media_tv_Tuner_native_init }, 4304 { "nativeSetup", "()V", (void *)android_media_tv_Tuner_native_setup }, 4305 { "nativeGetTunerVersion", "()I", (void *)android_media_tv_Tuner_native_get_tuner_version }, 4306 { "nativeGetFrontendIds", "()Ljava/util/List;", 4307 (void *)android_media_tv_Tuner_get_frontend_ids }, 4308 { "nativeOpenFrontendByHandle", "(I)Landroid/media/tv/tuner/Tuner$Frontend;", 4309 (void *)android_media_tv_Tuner_open_frontend_by_handle }, 4310 { "nativeTune", "(ILandroid/media/tv/tuner/frontend/FrontendSettings;)I", 4311 (void *)android_media_tv_Tuner_tune }, 4312 { "nativeStopTune", "()I", (void *)android_media_tv_Tuner_stop_tune }, 4313 { "nativeScan", "(ILandroid/media/tv/tuner/frontend/FrontendSettings;I)I", 4314 (void *)android_media_tv_Tuner_scan }, 4315 { "nativeStopScan", "()I", (void *)android_media_tv_Tuner_stop_scan }, 4316 { "nativeSetLnb", "(Landroid/media/tv/tuner/Lnb;)I", (void *)android_media_tv_Tuner_set_lnb }, 4317 { "nativeSetLna", "(Z)I", (void *)android_media_tv_Tuner_set_lna }, 4318 { "nativeGetFrontendStatus", "([I)Landroid/media/tv/tuner/frontend/FrontendStatus;", 4319 (void *)android_media_tv_Tuner_get_frontend_status }, 4320 { "nativeGetAvSyncHwId", "(Landroid/media/tv/tuner/filter/Filter;)Ljava/lang/Integer;", 4321 (void *)android_media_tv_Tuner_get_av_sync_hw_id }, 4322 { "nativeGetAvSyncTime", "(I)Ljava/lang/Long;", 4323 (void *)android_media_tv_Tuner_get_av_sync_time }, 4324 { "nativeConnectCiCam", "(I)I", (void *)android_media_tv_Tuner_connect_cicam }, 4325 { "nativeLinkCiCam", "(I)I", 4326 (void *)android_media_tv_Tuner_link_cicam }, 4327 { "nativeUnlinkCiCam", "(I)I", 4328 (void *)android_media_tv_Tuner_unlink_cicam }, 4329 { "nativeDisconnectCiCam", "()I", (void *)android_media_tv_Tuner_disconnect_cicam }, 4330 { "nativeGetFrontendInfo", "(I)Landroid/media/tv/tuner/frontend/FrontendInfo;", 4331 (void *)android_media_tv_Tuner_get_frontend_info }, 4332 { "nativeOpenFilter", "(IIJ)Landroid/media/tv/tuner/filter/Filter;", 4333 (void *)android_media_tv_Tuner_open_filter }, 4334 { "nativeOpenTimeFilter", "()Landroid/media/tv/tuner/filter/TimeFilter;", 4335 (void *)android_media_tv_Tuner_open_time_filter }, 4336 { "nativeOpenLnbByHandle", "(I)Landroid/media/tv/tuner/Lnb;", 4337 (void *)android_media_tv_Tuner_open_lnb_by_handle }, 4338 { "nativeOpenLnbByName", "(Ljava/lang/String;)Landroid/media/tv/tuner/Lnb;", 4339 (void *)android_media_tv_Tuner_open_lnb_by_name }, 4340 { "nativeOpenDescramblerByHandle", "(I)Landroid/media/tv/tuner/Descrambler;", 4341 (void *)android_media_tv_Tuner_open_descrambler }, 4342 { "nativeOpenDvrRecorder", "(J)Landroid/media/tv/tuner/dvr/DvrRecorder;", 4343 (void *)android_media_tv_Tuner_open_dvr_recorder }, 4344 { "nativeOpenDvrPlayback", "(J)Landroid/media/tv/tuner/dvr/DvrPlayback;", 4345 (void *)android_media_tv_Tuner_open_dvr_playback }, 4346 { "nativeGetDemuxCapabilities", "()Landroid/media/tv/tuner/DemuxCapabilities;", 4347 (void *)android_media_tv_Tuner_get_demux_caps }, 4348 { "nativeOpenDemuxByhandle", "(I)I", (void *)android_media_tv_Tuner_open_demux }, 4349 { "nativeClose", "()I", (void *)android_media_tv_Tuner_close_tuner }, 4350 { "nativeCloseFrontend", "(I)I", (void *)android_media_tv_Tuner_close_frontend }, 4351 { "nativeCloseDemux", "(I)I", (void *)android_media_tv_Tuner_close_demux }, 4352 }; 4353 4354 static const JNINativeMethod gFilterMethods[] = { 4355 { "nativeConfigureFilter", "(IILandroid/media/tv/tuner/filter/FilterConfiguration;)I", 4356 (void *)android_media_tv_Tuner_configure_filter }, 4357 { "nativeGetId", "()I", (void *)android_media_tv_Tuner_get_filter_id }, 4358 { "nativeGetId64Bit", "()J", 4359 (void *)android_media_tv_Tuner_get_filter_64bit_id }, 4360 { "nativeConfigureMonitorEvent", "(I)I", 4361 (void *)android_media_tv_Tuner_configure_monitor_event }, 4362 { "nativeSetDataSource", "(Landroid/media/tv/tuner/filter/Filter;)I", 4363 (void *)android_media_tv_Tuner_set_filter_data_source }, 4364 { "nativeStartFilter", "()I", (void *)android_media_tv_Tuner_start_filter }, 4365 { "nativeStopFilter", "()I", (void *)android_media_tv_Tuner_stop_filter }, 4366 { "nativeFlushFilter", "()I", (void *)android_media_tv_Tuner_flush_filter }, 4367 { "nativeRead", "([BJJ)I", (void *)android_media_tv_Tuner_read_filter_fmq }, 4368 { "nativeClose", "()I", (void *)android_media_tv_Tuner_close_filter }, 4369 }; 4370 4371 static const JNINativeMethod gTimeFilterMethods[] = { 4372 { "nativeSetTimestamp", "(J)I", (void *)android_media_tv_Tuner_time_filter_set_timestamp }, 4373 { "nativeClearTimestamp", "()I", (void *)android_media_tv_Tuner_time_filter_clear_timestamp }, 4374 { "nativeGetTimestamp", "()Ljava/lang/Long;", 4375 (void *)android_media_tv_Tuner_time_filter_get_timestamp }, 4376 { "nativeGetSourceTime", "()Ljava/lang/Long;", 4377 (void *)android_media_tv_Tuner_time_filter_get_source_time }, 4378 { "nativeClose", "()I", (void *)android_media_tv_Tuner_time_filter_close }, 4379 }; 4380 4381 static const JNINativeMethod gDescramblerMethods[] = { 4382 { "nativeAddPid", "(IILandroid/media/tv/tuner/filter/Filter;)I", 4383 (void *)android_media_tv_Tuner_descrambler_add_pid }, 4384 { "nativeRemovePid", "(IILandroid/media/tv/tuner/filter/Filter;)I", 4385 (void *)android_media_tv_Tuner_descrambler_remove_pid }, 4386 { "nativeSetKeyToken", "([B)I", (void *)android_media_tv_Tuner_descrambler_set_key_token }, 4387 { "nativeClose", "()I", (void *)android_media_tv_Tuner_close_descrambler }, 4388 }; 4389 4390 static const JNINativeMethod gDvrRecorderMethods[] = { 4391 { "nativeAttachFilter", "(Landroid/media/tv/tuner/filter/Filter;)I", 4392 (void *)android_media_tv_Tuner_attach_filter }, 4393 { "nativeDetachFilter", "(Landroid/media/tv/tuner/filter/Filter;)I", 4394 (void *)android_media_tv_Tuner_detach_filter }, 4395 { "nativeConfigureDvr", "(Landroid/media/tv/tuner/dvr/DvrSettings;)I", 4396 (void *)android_media_tv_Tuner_configure_dvr }, 4397 { "nativeStartDvr", "()I", (void *)android_media_tv_Tuner_start_dvr }, 4398 { "nativeStopDvr", "()I", (void *)android_media_tv_Tuner_stop_dvr }, 4399 { "nativeFlushDvr", "()I", (void *)android_media_tv_Tuner_flush_dvr }, 4400 { "nativeClose", "()I", (void *)android_media_tv_Tuner_close_dvr }, 4401 { "nativeSetFileDescriptor", "(I)V", (void *)android_media_tv_Tuner_dvr_set_fd }, 4402 { "nativeWrite", "(J)J", (void *)android_media_tv_Tuner_write_dvr }, 4403 { "nativeWrite", "([BJJ)J", (void *)android_media_tv_Tuner_write_dvr_to_array }, 4404 }; 4405 4406 static const JNINativeMethod gDvrPlaybackMethods[] = { 4407 { "nativeAttachFilter", "(Landroid/media/tv/tuner/filter/Filter;)I", 4408 (void *)android_media_tv_Tuner_attach_filter }, 4409 { "nativeDetachFilter", "(Landroid/media/tv/tuner/filter/Filter;)I", 4410 (void *)android_media_tv_Tuner_detach_filter }, 4411 { "nativeConfigureDvr", "(Landroid/media/tv/tuner/dvr/DvrSettings;)I", 4412 (void *)android_media_tv_Tuner_configure_dvr }, 4413 { "nativeStartDvr", "()I", (void *)android_media_tv_Tuner_start_dvr }, 4414 { "nativeStopDvr", "()I", (void *)android_media_tv_Tuner_stop_dvr }, 4415 { "nativeFlushDvr", "()I", (void *)android_media_tv_Tuner_flush_dvr }, 4416 { "nativeClose", "()I", (void *)android_media_tv_Tuner_close_dvr }, 4417 { "nativeSetFileDescriptor", "(I)V", (void *)android_media_tv_Tuner_dvr_set_fd }, 4418 { "nativeRead", "(J)J", (void *)android_media_tv_Tuner_read_dvr }, 4419 { "nativeRead", "([BJJ)J", (void *)android_media_tv_Tuner_read_dvr_from_array }, 4420 }; 4421 4422 static const JNINativeMethod gLnbMethods[] = { 4423 { "nativeSetVoltage", "(I)I", (void *)android_media_tv_Tuner_lnb_set_voltage }, 4424 { "nativeSetTone", "(I)I", (void *)android_media_tv_Tuner_lnb_set_tone }, 4425 { "nativeSetSatellitePosition", "(I)I", (void *)android_media_tv_Tuner_lnb_set_position }, 4426 { "nativeSendDiseqcMessage", "([B)I", (void *)android_media_tv_Tuner_lnb_send_diseqc_msg }, 4427 { "nativeClose", "()I", (void *)android_media_tv_Tuner_close_lnb }, 4428 }; 4429 4430 static const JNINativeMethod gMediaEventMethods[] = { 4431 { "nativeGetLinearBlock", "()Landroid/media/MediaCodec$LinearBlock;", 4432 (void *)android_media_tv_Tuner_media_event_get_linear_block }, 4433 { "nativeGetAudioHandle", "()Ljava/lang/Long;", 4434 (void *)android_media_tv_Tuner_media_event_get_audio_handle }, 4435 { "nativeFinalize", "()V", 4436 (void *)android_media_tv_Tuner_media_event_finalize }, 4437 }; 4438 4439 static bool register_android_media_tv_Tuner(JNIEnv *env) { 4440 if (AndroidRuntime::registerNativeMethods( 4441 env, "android/media/tv/tuner/Tuner", gTunerMethods, NELEM(gTunerMethods)) != JNI_OK) { 4442 ALOGE("Failed to register tuner native methods"); 4443 return false; 4444 } 4445 if (AndroidRuntime::registerNativeMethods( 4446 env, "android/media/tv/tuner/filter/Filter", 4447 gFilterMethods, 4448 NELEM(gFilterMethods)) != JNI_OK) { 4449 ALOGE("Failed to register filter native methods"); 4450 return false; 4451 } 4452 if (AndroidRuntime::registerNativeMethods( 4453 env, "android/media/tv/tuner/filter/TimeFilter", 4454 gTimeFilterMethods, 4455 NELEM(gTimeFilterMethods)) != JNI_OK) { 4456 ALOGE("Failed to register time filter native methods"); 4457 return false; 4458 } 4459 if (AndroidRuntime::registerNativeMethods( 4460 env, "android/media/tv/tuner/Descrambler", 4461 gDescramblerMethods, 4462 NELEM(gDescramblerMethods)) != JNI_OK) { 4463 ALOGE("Failed to register descrambler native methods"); 4464 return false; 4465 } 4466 if (AndroidRuntime::registerNativeMethods( 4467 env, "android/media/tv/tuner/dvr/DvrRecorder", 4468 gDvrRecorderMethods, 4469 NELEM(gDvrRecorderMethods)) != JNI_OK) { 4470 ALOGE("Failed to register dvr recorder native methods"); 4471 return false; 4472 } 4473 if (AndroidRuntime::registerNativeMethods( 4474 env, "android/media/tv/tuner/dvr/DvrPlayback", 4475 gDvrPlaybackMethods, 4476 NELEM(gDvrPlaybackMethods)) != JNI_OK) { 4477 ALOGE("Failed to register dvr playback native methods"); 4478 return false; 4479 } 4480 if (AndroidRuntime::registerNativeMethods( 4481 env, "android/media/tv/tuner/Lnb", 4482 gLnbMethods, 4483 NELEM(gLnbMethods)) != JNI_OK) { 4484 ALOGE("Failed to register lnb native methods"); 4485 return false; 4486 } 4487 if (AndroidRuntime::registerNativeMethods( 4488 env, "android/media/tv/tuner/filter/MediaEvent", 4489 gMediaEventMethods, 4490 NELEM(gMediaEventMethods)) != JNI_OK) { 4491 ALOGE("Failed to register MediaEvent native methods"); 4492 return false; 4493 } 4494 return true; 4495 } 4496 4497 jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) 4498 { 4499 JNIEnv* env = NULL; 4500 jint result = -1; 4501 4502 if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { 4503 ALOGE("ERROR: GetEnv failed\n"); 4504 return result; 4505 } 4506 assert(env != NULL); 4507 4508 if (!register_android_media_tv_Tuner(env)) { 4509 ALOGE("ERROR: Tuner native registration failed\n"); 4510 return result; 4511 } 4512 return JNI_VERSION_1_4; 4513 } 4514