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