Home | History | Annotate | Download | only in jni
      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  */
     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  */
     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
     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  */
     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  */
    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  */
    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
    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
    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 }