• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 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 #include "tunertvinput_jni.h"
18 #include <map>
19 
20 #include "DvbManager.h"
21 #define LOG_TAG "tunertvinput_jni"
22 #include "logging.h"
23 
24 //-------------------------------------------------------------------------------
25 // JNI native method implementation
26 //-------------------------------------------------------------------------------
27 
28 #define TS_PACKET_SIZE 188
29 #define TS_PAYLOAD_SIZE (TS_PACKET_SIZE * 7) // Fit Ethernet MTU (1500)
30 #define READ_TIMEOUT_MS 100
31 
32 static int sTotalBytesFetched = 0;
33 static std::map<jlong, DvbManager *> sDvbManagers;
34 
35 /*
36  * Class:     com_android_tv_tuner_TunerHal
37  * Method:    nativeFinalize
38  * Signature: (J)V
39  */
Java_com_android_tv_tuner_TunerHal_nativeFinalize(JNIEnv *,jobject,jlong deviceId)40 JNIEXPORT void JNICALL Java_com_android_tv_tuner_TunerHal_nativeFinalize(
41     JNIEnv *, jobject, jlong deviceId) {
42   std::map<jlong, DvbManager *>::iterator it = sDvbManagers.find(deviceId);
43   if (it != sDvbManagers.end()) {
44     delete it->second;
45     sDvbManagers.erase(it);
46   }
47 }
48 
49 /*
50  * Class:     com_android_tv_tuner_TunerHal
51  * Method:    nativeTune
52  * Signature: (JILjava/lang/String;)Z
53  */
Java_com_android_tv_tuner_TunerHal_nativeTune(JNIEnv * env,jobject thiz,jlong deviceId,jint frequency,jstring modulation,jint timeout_ms)54 JNIEXPORT jboolean JNICALL Java_com_android_tv_tuner_TunerHal_nativeTune(
55     JNIEnv *env, jobject thiz, jlong deviceId, jint frequency,
56     jstring modulation, jint timeout_ms) {
57   std::map<jlong, DvbManager *>::iterator it = sDvbManagers.find(deviceId);
58   DvbManager *dvbManager;
59   if (it == sDvbManagers.end()) {
60     dvbManager = new DvbManager(env, thiz);
61     sDvbManagers.insert(std::pair<jlong, DvbManager *>(deviceId, dvbManager));
62   } else {
63     dvbManager = it->second;
64   }
65   int res = dvbManager->tune(env, thiz, frequency,
66                              env->GetStringUTFChars(modulation, 0), timeout_ms);
67   return (res == 0);
68 }
69 
70 /*
71  * Class:     com_android_tv_tuner_TunerHal
72  * Method:    nativeCloseAllPidFilters
73  * Signature: (J)V
74  */
75 JNIEXPORT void JNICALL
Java_com_android_tv_tuner_TunerHal_nativeCloseAllPidFilters(JNIEnv *,jobject,jlong deviceId)76 Java_com_android_tv_tuner_TunerHal_nativeCloseAllPidFilters(JNIEnv *, jobject,
77                                                             jlong deviceId) {
78   std::map<jlong, DvbManager *>::iterator it = sDvbManagers.find(deviceId);
79   if (it != sDvbManagers.end()) {
80     it->second->closeAllDvbPidFilter();
81   }
82 }
83 
84 /*
85  * Class:     com_android_tv_tuner_TunerHal
86  * Method:    nativeStopTune
87  * Signature: (J)V
88  */
Java_com_android_tv_tuner_TunerHal_nativeStopTune(JNIEnv *,jobject,jlong deviceId)89 JNIEXPORT void JNICALL Java_com_android_tv_tuner_TunerHal_nativeStopTune(
90     JNIEnv *, jobject, jlong deviceId) {
91   std::map<jlong, DvbManager *>::iterator it = sDvbManagers.find(deviceId);
92   if (it != sDvbManagers.end()) {
93     it->second->stopTune();
94   }
95 }
96 
97 /*
98  * Class:     com_android_tv_tuner_TunerHal
99  * Method:    nativeAddPidFilter
100  * Signature: (JII)V
101  */
Java_com_android_tv_tuner_TunerHal_nativeAddPidFilter(JNIEnv * env,jobject thiz,jlong deviceId,jint pid,jint filterType)102 JNIEXPORT void JNICALL Java_com_android_tv_tuner_TunerHal_nativeAddPidFilter(
103     JNIEnv *env, jobject thiz, jlong deviceId, jint pid, jint filterType) {
104   std::map<jlong, DvbManager *>::iterator it = sDvbManagers.find(deviceId);
105   if (it != sDvbManagers.end()) {
106     it->second->startTsPidFilter(env, thiz, pid, filterType);
107   }
108 }
109 
110 /*
111  * Class:     com_android_tv_tuner_TunerHal
112  * Method:    nativeWriteInBuffer
113  * Signature: (J[BI)I
114  */
Java_com_android_tv_tuner_TunerHal_nativeWriteInBuffer(JNIEnv * env,jobject thiz,jlong deviceId,jbyteArray javaBuffer,jint javaBufferSize)115 JNIEXPORT jint JNICALL Java_com_android_tv_tuner_TunerHal_nativeWriteInBuffer(
116     JNIEnv *env, jobject thiz, jlong deviceId, jbyteArray javaBuffer,
117     jint javaBufferSize) {
118   uint8_t tsBuffer[TS_PAYLOAD_SIZE];
119   std::map<jlong, DvbManager *>::iterator it = sDvbManagers.find(deviceId);
120   if (it == sDvbManagers.end()) {
121     return -1;
122   }
123   DvbManager *dvbManager = it->second;
124 
125   // Always read multiple of TS_PACKET_SIZE
126   javaBufferSize = (javaBufferSize / TS_PACKET_SIZE) * TS_PACKET_SIZE;
127   int readBufferSize =
128       (javaBufferSize < TS_PAYLOAD_SIZE) ? javaBufferSize : TS_PAYLOAD_SIZE;
129 
130   int dataSize = dvbManager->readTsStream(env, thiz, tsBuffer, readBufferSize,
131                                           READ_TIMEOUT_MS);
132   if (dataSize == 0) {
133     ALOGD("No data to read DVR");
134     return 0;
135   } else if (dataSize < 0) {
136     return -1;
137   }
138 
139   sTotalBytesFetched += dataSize;
140 
141   env->SetByteArrayRegion(javaBuffer, 0, dataSize, (jbyte *)tsBuffer);
142   return dataSize;
143 }
144 
145 /*
146  * Class:     com_android_tv_tuner_TunerHal
147  * Method:    nativeSetHasPendingTune
148  * Signature: (JZ)V
149  */
150 JNIEXPORT void JNICALL
Java_com_android_tv_tuner_TunerHal_nativeSetHasPendingTune(JNIEnv *,jobject,jlong deviceId,jboolean hasPendingTune)151 Java_com_android_tv_tuner_TunerHal_nativeSetHasPendingTune(
152     JNIEnv *, jobject, jlong deviceId, jboolean hasPendingTune) {
153   std::map<jlong, DvbManager *>::iterator it = sDvbManagers.find(deviceId);
154   if (it != sDvbManagers.end()) {
155     it->second->setHasPendingTune(hasPendingTune);
156   }
157 }
158 
159 /*
160  * Class:     com_android_tv_tuner_TunerHal
161  * Method:    nativeGetDeliverySystemType
162  * Signature: (J)I
163  */
164 JNIEXPORT int JNICALL
Java_com_android_tv_tuner_TunerHal_nativeGetDeliverySystemType(JNIEnv * env,jobject thiz,jlong deviceId)165 Java_com_android_tv_tuner_TunerHal_nativeGetDeliverySystemType(JNIEnv *env,
166                                                                jobject thiz,
167                                                                jlong deviceId) {
168   std::map<jlong, DvbManager *>::iterator it = sDvbManagers.find(deviceId);
169   if (it != sDvbManagers.end()) {
170     return it->second->getDeliverySystemType(env, thiz);
171   } else {
172     DvbManager *dvbManager = new DvbManager(env, thiz);
173     sDvbManagers.insert(std::pair<jlong, DvbManager *>(deviceId, dvbManager));
174     return dvbManager->getDeliverySystemType(env, thiz);
175   }
176 }