summaryrefslogtreecommitdiff
path: root/tvapi/android/jni/cfbc_jni.cpp (plain)
blob: 7ec7d86ee647c561c4a720f2bbae157e2cda5d95
1#include <stdio.h>
2#include <stdlib.h>
3#include <unistd.h>
4#include <sys/types.h>
5#include <sys/stat.h>
6#include <fcntl.h>
7#include <assert.h>
8#include "jni.h"
9#include "JNIHelp.h"
10#include "android_runtime/AndroidRuntime.h"
11#include "tv/CFbcCommunication.h"
12
13#define TAG "joey_jni"
14#define JNI_DBG(a...) __android_log_print(ANDROID_LOG_INFO, TAG, a)
15#define MAX_CNT 128
16
17static JNIEnv *jni_local_env = NULL;
18static jclass jni_local_clz = NULL;
19static jobject jni_local_obj = NULL;
20static jmethodID jni_local_mid = NULL;
21static JavaVM *m_vm = NULL;
22static CFbcCommunication *g_cfbc_handle = NULL;
23
24JNIEnv *getJNIEnv(bool *needsDetach)
25{
26 JNIEnv *env = NULL;
27 jint result = -1;
28 if (m_vm->GetEnv((void **) &env, JNI_VERSION_1_4) != JNI_OK) {
29 __android_log_print(ANDROID_LOG_INFO, TAG, "ERROR: GetEnv failed\n");
30
31 int status = m_vm->AttachCurrentThread(&env, NULL);
32 if (status < 0) {
33 __android_log_print(ANDROID_LOG_INFO, TAG, "callback_handler: failed to attach current thread");
34 return NULL;
35 }
36
37 *needsDetach = true;
38 }
39
40 __android_log_print(ANDROID_LOG_INFO, TAG, "GetEnv Success");
41 return env;
42}
43
44void detachJNI()
45{
46 int result = m_vm->DetachCurrentThread();
47 if (result != JNI_OK) {
48 __android_log_print(ANDROID_LOG_INFO, TAG, "thread detach failed: %#x", result);
49 }
50}
51
52//this data buf is same as cmd buf
53void java_jni_callback(char *str, int cnt, int data_buf[])
54{
55 char temp_str[MAX_CNT];
56 int idx = 0;
57 if (str != NULL && cnt > 0) {
58 memset(temp_str, 0, sizeof(temp_str));
59 JNI_DBG("java jni string is:\n%s, cnt:%d.", str, cnt);
60 //strcpy(temp_str, "Call From C/C++!");
61 memcpy(temp_str, str, strlen(str) % MAX_CNT);
62
63 if (NULL != jni_local_obj) {
64 bool needsDetach = false;
65 jint j_cnt = data_buf[1];
66 jint j_data_buf[MAX_CNT];
67 for (idx = 0; idx < j_cnt; idx++) {
68 idx %= MAX_CNT;
69 j_data_buf[idx] = data_buf[idx];
70 JNI_DBG("java_jni_callback the %d data is:0x%x, %d.", idx, j_data_buf[idx], data_buf[idx]);
71 }
72
73 //jobject obj;
74 jni_local_env = getJNIEnv(&needsDetach);
75 //obj = (*jni_local_env)->NewGlobalRef(jni_local_env,jni_local_obj);
76 jni_local_clz = jni_local_env->GetObjectClass(jni_local_obj);
77 //this func name and parameters should be same as the callback defined in java code
78 jni_local_mid = jni_local_env->GetMethodID(jni_local_clz, "android_java_callback", "(Ljava/lang/String;[I)I");
79
80 jstring str1 = jni_local_env->NewStringUTF(temp_str);
81
82 jintArray cc_data_arr = jni_local_env->NewIntArray(j_cnt);
83 jni_local_env->SetIntArrayRegion(cc_data_arr, 0, cnt, j_data_buf);
84 //jint *temp_data = jni_local_env->GetIntArrayElements(cc_data_arr, NULL);
85
86 jint cnt = jni_local_env->CallIntMethod(jni_local_obj, jni_local_mid, str1, cc_data_arr);
87
88 //jni_local_env->ReleaseIntArrayElements(cc_data_arr, temp_data, 0);
89 //jni_local_env->ReleaseIntArrayElements(cc_cmd_arr, temp_cmd, 0);
90 JNI_DBG("%s %d be called.", __FUNCTION__, __LINE__);
91
92 if (needsDetach) {
93 detachJNI();
94 }
95 }
96 }
97}
98
99//here we needn't to match the java package name
100static jint jni_java_exec_cmd(JNIEnv *env, jobject obj, jintArray cmdArray)
101{
102 jint *arry = env->GetIntArrayElements(cmdArray, NULL);
103 jint length = env->GetArrayLength(cmdArray);
104
105 int cmd_cnt = arry[1], idx = 0;
106 int cmd_array[MAX_CNT];
107 memset(cmd_array, 0, sizeof(cmd_array));
108 for (idx = 0; idx < cmd_cnt; idx++)
109 cmd_array[idx] = arry[idx];
110
111 JNI_DBG("%s %s %d be called.", __FILE__, __FUNCTION__, __LINE__);
112
113 if (g_cfbc_handle == NULL) {
114 g_cfbc_handle = new CFbcCommunication();
115 g_cfbc_handle->run("cfbc_thread", 0, 0);
116 }
117
118 //g_cfbc_handle->handleCmd(COMM_DEV_CEC, cmd_array);
119 //c_exec_cmd(cmd_array);
120
121 if (NULL == jni_local_obj) {
122 jni_local_obj = env->NewGlobalRef(obj);
123 }
124
125#if 0
126 /* this is used to terminate the jni call if needed
127 ** and we should handle the pthread we create in c layer
128 */
129 if (cmd_array[0] == 0x1002) {
130 if (NULL != jni_local_obj)
131 env->DeleteGlobalRef(jni_local_obj);
132 }
133#endif
134 return 0;
135}
136
137//the name of 'exec_cmd' should be same as the native func in java code
138static JNINativeMethod gMethods[] = {
139 {"exec_cmd", "([I)I", (void *)jni_java_exec_cmd},
140};
141
142static int register_android_MyFunc(JNIEnv *env)
143{
144 JNI_DBG("%s %s %d be called.", __FILE__, __FUNCTION__, __LINE__);
145 //the name below should be same as the class name in which native method declared in Java layer
146 return android::AndroidRuntime::registerNativeMethods(env, "com/fbc/MyFunc", gMethods, NELEM(gMethods));
147}
148
149jint JNI_OnLoad(JavaVM *vm, void *reserved)
150{
151 JNIEnv *env = NULL;
152 JNI_DBG("%s %s %d be called.", __FILE__, __FUNCTION__, __LINE__);
153 //c_set_callback(&java_jni_callback);
154 if (vm->GetEnv((void **)&env, JNI_VERSION_1_4) != JNI_OK) {
155 JNI_DBG("Error GetEnv\n");
156 return -1;
157 }
158
159 assert(env != NULL);
160 if (register_android_MyFunc(env) < 0) {
161 JNI_DBG("register_android_test_hdi error.\n");
162 return -1;
163 }
164
165 m_vm = vm;
166 return JNI_VERSION_1_4;
167}
168