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 #ifndef _ANDROID_MEDIA_TV_TUNER_H_
18 #define _ANDROID_MEDIA_TV_TUNER_H_
19 
20 #include <android/hardware/tv/tuner/1.0/ITuner.h>
21 #include <C2BlockInternal.h>
22 #include <C2HandleIonInternal.h>
23 #include <C2ParamDef.h>
24 #include <fmq/MessageQueue.h>
25 #include <fstream>
26 #include <string>
27 #include <unordered_map>
28 #include <utils/Mutex.h>
29 #include <utils/RefBase.h>
30 
31 #include "jni.h"
32 
33 using ::android::hardware::EventFlag;
34 using ::android::hardware::MQDescriptorSync;
35 using ::android::hardware::MessageQueue;
36 using ::android::hardware::Return;
37 using ::android::hardware::hidl_handle;
38 using ::android::hardware::hidl_vec;
39 using ::android::hardware::kSynchronizedReadWrite;
40 using ::android::hardware::tv::tuner::V1_0::DemuxFilterEvent;
41 using ::android::hardware::tv::tuner::V1_0::DemuxFilterStatus;
42 using ::android::hardware::tv::tuner::V1_0::DemuxFilterType;
43 using ::android::hardware::tv::tuner::V1_0::DemuxPid;
44 using ::android::hardware::tv::tuner::V1_0::DvrType;
45 using ::android::hardware::tv::tuner::V1_0::FrontendEventType;
46 using ::android::hardware::tv::tuner::V1_0::FrontendId;
47 using ::android::hardware::tv::tuner::V1_0::FrontendInfo;
48 using ::android::hardware::tv::tuner::V1_0::FrontendScanMessage;
49 using ::android::hardware::tv::tuner::V1_0::FrontendScanMessageType;
50 using ::android::hardware::tv::tuner::V1_0::FrontendScanType;
51 using ::android::hardware::tv::tuner::V1_0::FrontendSettings;
52 using ::android::hardware::tv::tuner::V1_0::IDemux;
53 using ::android::hardware::tv::tuner::V1_0::IDescrambler;
54 using ::android::hardware::tv::tuner::V1_0::IDvr;
55 using ::android::hardware::tv::tuner::V1_0::IDvrCallback;
56 using ::android::hardware::tv::tuner::V1_0::IFilter;
57 using ::android::hardware::tv::tuner::V1_0::IFilterCallback;
58 using ::android::hardware::tv::tuner::V1_0::IFrontend;
59 using ::android::hardware::tv::tuner::V1_0::IFrontendCallback;
60 using ::android::hardware::tv::tuner::V1_0::ILnb;
61 using ::android::hardware::tv::tuner::V1_0::ILnbCallback;
62 using ::android::hardware::tv::tuner::V1_0::ITimeFilter;
63 using ::android::hardware::tv::tuner::V1_0::ITuner;
64 using ::android::hardware::tv::tuner::V1_0::LnbEventType;
65 using ::android::hardware::tv::tuner::V1_0::LnbId;
66 using ::android::hardware::tv::tuner::V1_0::PlaybackStatus;
67 using ::android::hardware::tv::tuner::V1_0::RecordStatus;
68 using ::android::hardware::tv::tuner::V1_0::Result;
69 
70 using MQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
71 
72 namespace android {
73 
74 struct LnbCallback : public ILnbCallback {
75     LnbCallback(jweak tunerObj, LnbId id);
76     virtual Return<void> onEvent(LnbEventType lnbEventType);
77     virtual Return<void> onDiseqcMessage(const hidl_vec<uint8_t>& diseqcMessage);
78     jweak mLnb;
79     LnbId mId;
80 };
81 
82 struct Lnb : public RefBase {
83     Lnb(sp<ILnb> sp, jobject obj);
84     ~Lnb();
85     sp<ILnb> getILnb();
86     sp<ILnb> mLnbSp;
87     jweak mLnbObj;
88 };
89 
90 struct DvrCallback : public IDvrCallback {
91     ~DvrCallback();
92     virtual Return<void> onRecordStatus(RecordStatus status);
93     virtual Return<void> onPlaybackStatus(PlaybackStatus status);
94 
95     void setDvr(const jobject dvr);
96 private:
97     jweak mDvr;
98 };
99 
100 struct Dvr : public RefBase {
101     Dvr(sp<IDvr> sp, jweak obj);
102     ~Dvr();
103     jint close();
104     MQ& getDvrMQ();
105     sp<IDvr> getIDvr();
106     sp<IDvr> mDvrSp;
107     jweak mDvrObj;
108     std::unique_ptr<MQ> mDvrMQ;
109     EventFlag* mDvrMQEventFlag;
110     std::string mFilePath;
111     int mFd;
112 };
113 
114 struct MediaEvent : public RefBase {
115     MediaEvent(sp<IFilter> iFilter, hidl_handle avHandle, uint64_t dataId,
116         uint64_t dataLength, jobject obj);
117     ~MediaEvent();
118     jobject getLinearBlock();
119     uint64_t getAudioHandle();
120     void finalize();
121 
122     sp<IFilter> mIFilter;
123     native_handle_t* mAvHandle;
124     uint64_t mDataId;
125     uint64_t mDataLength;
126     uint8_t* mBuffer;
127     android::Mutex mLock;
128     int mDataIdRefCnt;
129     int mAvHandleRefCnt;
130     jweak mMediaEventObj;
131     jweak mLinearBlockObj;
132     C2HandleIon* mIonHandle;
133     std::weak_ptr<C2Buffer> mC2Buffer;
134 };
135 
136 struct Filter : public RefBase {
137     Filter(sp<IFilter> sp, jobject obj);
138     ~Filter();
139     int close();
140     sp<IFilter> getIFilter();
141     sp<IFilter> mFilterSp;
142     std::unique_ptr<MQ> mFilterMQ;
143     EventFlag* mFilterMQEventFlag;
144     jweak mFilterObj;
145 };
146 
147 struct FilterCallback : public IFilterCallback {
148     ~FilterCallback();
149     virtual Return<void> onFilterEvent(const DemuxFilterEvent& filterEvent);
150     virtual Return<void> onFilterStatus(const DemuxFilterStatus status);
151 
152     void setFilter(const sp<Filter> filter);
153 private:
154     jweak mFilter;
155     sp<IFilter> mIFilter;
156     jobjectArray getSectionEvent(
157             jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events);
158     jobjectArray getMediaEvent(
159             jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events);
160     jobjectArray getPesEvent(
161             jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events);
162     jobjectArray getTsRecordEvent(
163             jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events);
164     jobjectArray getMmtpRecordEvent(
165             jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events);
166     jobjectArray getDownloadEvent(
167             jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events);
168     jobjectArray getIpPayloadEvent(
169             jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events);
170     jobjectArray getTemiEvent(
171             jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events);
172 };
173 
174 struct FrontendCallback : public IFrontendCallback {
175     FrontendCallback(jweak tunerObj, FrontendId id);
176 
177     virtual Return<void> onEvent(FrontendEventType frontendEventType);
178     virtual Return<void> onScanMessage(
179             FrontendScanMessageType type, const FrontendScanMessage& message);
180 
181     jweak mObject;
182     FrontendId mId;
183 };
184 
185 struct TimeFilter : public RefBase {
186     TimeFilter(sp<ITimeFilter> sp, jweak obj);
187     ~TimeFilter();
188     sp<ITimeFilter> getITimeFilter();
189     sp<ITimeFilter> mTimeFilterSp;
190     jweak mTimeFilterObj;
191 };
192 
193 struct JTuner : public RefBase {
194     JTuner(JNIEnv *env, jobject thiz);
195     sp<ITuner> getTunerService();
196     jobject getAvSyncHwId(sp<Filter> filter);
197     jobject getAvSyncTime(jint id);
198     int connectCiCam(jint id);
199     int disconnectCiCam();
200     jobject getFrontendIds();
201     jobject openFrontendById(int id);
202     jint closeFrontendById(int id);
203     jobject getFrontendInfo(int id);
204     int tune(const FrontendSettings& settings);
205     int stopTune();
206     int scan(const FrontendSettings& settings, FrontendScanType scanType);
207     int stopScan();
208     int setLnb(int id);
209     int setLna(bool enable);
210     jintArray getLnbIds();
211     jobject openLnbById(int id);
212     jobject openLnbByName(jstring name);
213     jobject openFilter(DemuxFilterType type, int bufferSize);
214     jobject openTimeFilter();
215     jobject openDescrambler();
216     jobject openDvr(DvrType type, jlong bufferSize);
217     jobject getDemuxCaps();
218     jobject getFrontendStatus(jintArray types);
219     Result openDemux();
220     jint close();
221     jint closeFrontend();
222     jint closeDemux();
223 
224 protected:
225     virtual ~JTuner();
226 
227 private:
228     jclass mClass;
229     jweak mObject;
230     static sp<ITuner> mTuner;
231     hidl_vec<FrontendId> mFeIds;
232     sp<IFrontend> mFe;
233     int mFeId;
234     hidl_vec<LnbId> mLnbIds;
235     sp<ILnb> mLnb;
236     sp<IDemux> mDemux;
237     uint32_t mDemuxId;
238     static jobject getAnalogFrontendCaps(JNIEnv *env, FrontendInfo::FrontendCapabilities& caps);
239     static jobject getAtsc3FrontendCaps(JNIEnv *env, FrontendInfo::FrontendCapabilities& caps);
240     static jobject getAtscFrontendCaps(JNIEnv *env, FrontendInfo::FrontendCapabilities& caps);
241     static jobject getDvbcFrontendCaps(JNIEnv *env, FrontendInfo::FrontendCapabilities& caps);
242     static jobject getDvbsFrontendCaps(JNIEnv *env, FrontendInfo::FrontendCapabilities& caps);
243     static jobject getDvbtFrontendCaps(JNIEnv *env, FrontendInfo::FrontendCapabilities& caps);
244     static jobject getIsdbs3FrontendCaps(JNIEnv *env, FrontendInfo::FrontendCapabilities& caps);
245     static jobject getIsdbsFrontendCaps(JNIEnv *env, FrontendInfo::FrontendCapabilities& caps);
246     static jobject getIsdbtFrontendCaps(JNIEnv *env, FrontendInfo::FrontendCapabilities& caps);
247 };
248 
249 class C2DataIdInfo : public C2Param {
250 public:
251     C2DataIdInfo(uint32_t index, uint64_t value);
252 private:
253     typedef C2GlobalParam<C2Info, C2Int64Value, 0> DummyInfo;
254     static const size_t kParamSize = sizeof(DummyInfo);
255 };
256 
257 }  // namespace android
258 
259 #endif  // _ANDROID_MEDIA_TV_TUNER_H_
260