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