1 /*
2 * Copyright 2014 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_TAG "TvInputHal"
18
19 //#define LOG_NDEBUG 0
20
21 #include "tvinput/JTvInputHal.h"
22
23 gBundleClassInfoType gBundleClassInfo;
24 gTvInputHalClassInfoType gTvInputHalClassInfo;
25 gTvStreamConfigClassInfoType gTvStreamConfigClassInfo;
26 gTvStreamConfigBuilderClassInfoType gTvStreamConfigBuilderClassInfo;
27 gTvInputHardwareInfoBuilderClassInfoType gTvInputHardwareInfoBuilderClassInfo;
28
29 namespace android {
30
nativeOpen(JNIEnv * env,jobject thiz,jobject messageQueueObj)31 static jlong nativeOpen(JNIEnv* env, jobject thiz, jobject messageQueueObj) {
32 sp<MessageQueue> messageQueue =
33 android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
34 return (jlong)JTvInputHal::createInstance(env, thiz, messageQueue->getLooper());
35 }
36
nativeAddOrUpdateStream(JNIEnv * env,jclass clazz,jlong ptr,jint deviceId,jint streamId,jobject jsurface)37 static int nativeAddOrUpdateStream(JNIEnv* env, jclass clazz,
38 jlong ptr, jint deviceId, jint streamId, jobject jsurface) {
39 JTvInputHal* tvInputHal = (JTvInputHal*)ptr;
40 if (!jsurface) {
41 return BAD_VALUE;
42 }
43 sp<Surface> surface(android_view_Surface_getSurface(env, jsurface));
44 if (!Surface::isValid(surface)) {
45 return BAD_VALUE;
46 }
47 return tvInputHal->addOrUpdateStream(deviceId, streamId, surface);
48 }
49
nativeRemoveStream(JNIEnv * env,jclass clazz,jlong ptr,jint deviceId,jint streamId)50 static int nativeRemoveStream(JNIEnv* env, jclass clazz,
51 jlong ptr, jint deviceId, jint streamId) {
52 JTvInputHal* tvInputHal = (JTvInputHal*)ptr;
53 return tvInputHal->removeStream(deviceId, streamId);
54 }
55
nativeGetStreamConfigs(JNIEnv * env,jclass clazz,jlong ptr,jint deviceId,jint generation)56 static jobjectArray nativeGetStreamConfigs(JNIEnv* env, jclass clazz,
57 jlong ptr, jint deviceId, jint generation) {
58 JTvInputHal* tvInputHal = (JTvInputHal*)ptr;
59 const std::vector<AidlTvStreamConfig> configs = tvInputHal->getStreamConfigs(deviceId);
60
61 jobjectArray result = env->NewObjectArray(configs.size(), gTvStreamConfigClassInfo.clazz, NULL);
62 for (size_t i = 0; i < configs.size(); ++i) {
63 jobject builder = env->NewObject(
64 gTvStreamConfigBuilderClassInfo.clazz,
65 gTvStreamConfigBuilderClassInfo.constructor);
66 env->CallObjectMethod(
67 builder, gTvStreamConfigBuilderClassInfo.streamId, configs[i].streamId);
68 env->CallObjectMethod(
69 builder, gTvStreamConfigBuilderClassInfo.type,
70 TV_STREAM_TYPE_INDEPENDENT_VIDEO_SOURCE);
71 env->CallObjectMethod(
72 builder, gTvStreamConfigBuilderClassInfo.maxWidth, configs[i].maxVideoWidth);
73 env->CallObjectMethod(
74 builder, gTvStreamConfigBuilderClassInfo.maxHeight, configs[i].maxVideoHeight);
75 env->CallObjectMethod(
76 builder, gTvStreamConfigBuilderClassInfo.generation, generation);
77
78 jobject config = env->CallObjectMethod(builder, gTvStreamConfigBuilderClassInfo.build);
79
80 env->SetObjectArrayElement(result, i, config);
81
82 env->DeleteLocalRef(config);
83 env->DeleteLocalRef(builder);
84 }
85 return result;
86 }
87
nativeSetTvMessageEnabled(JNIEnv * env,jclass clazz,jlong ptr,jint deviceId,jint streamId,jint type,jboolean enabled)88 static int nativeSetTvMessageEnabled(JNIEnv* env, jclass clazz, jlong ptr, jint deviceId,
89 jint streamId, jint type, jboolean enabled) {
90 JTvInputHal* tvInputHal = (JTvInputHal*)ptr;
91 return tvInputHal->setTvMessageEnabled(deviceId, streamId, type, enabled);
92 }
93
nativeClose(JNIEnv * env,jclass clazz,jlong ptr)94 static void nativeClose(JNIEnv* env, jclass clazz, jlong ptr) {
95 JTvInputHal* tvInputHal = (JTvInputHal*)ptr;
96 delete tvInputHal;
97 }
98
99 static const JNINativeMethod gTvInputHalMethods[] = {
100 /* name, signature, funcPtr */
101 {"nativeOpen", "(Landroid/os/MessageQueue;)J", (void*)nativeOpen},
102 {"nativeAddOrUpdateStream", "(JIILandroid/view/Surface;)I", (void*)nativeAddOrUpdateStream},
103 {"nativeRemoveStream", "(JII)I", (void*)nativeRemoveStream},
104 {"nativeGetStreamConfigs", "(JII)[Landroid/media/tv/TvStreamConfig;",
105 (void*)nativeGetStreamConfigs},
106 {"nativeSetTvMessageEnabled", "(JIIIZ)I", (void*)nativeSetTvMessageEnabled},
107 {"nativeClose", "(J)V", (void*)nativeClose},
108 };
109
110 #define FIND_CLASS(var, className) \
111 var = env->FindClass(className); \
112 LOG_FATAL_IF(! (var), "Unable to find class " className)
113
114 #define GET_METHOD_ID(var, clazz, methodName, fieldDescriptor) \
115 var = env->GetMethodID(clazz, methodName, fieldDescriptor); \
116 LOG_FATAL_IF(! (var), "Unable to find method" methodName)
117
register_android_server_tv_TvInputHal(JNIEnv * env)118 int register_android_server_tv_TvInputHal(JNIEnv* env) {
119 int res = jniRegisterNativeMethods(env, "com/android/server/tv/TvInputHal",
120 gTvInputHalMethods, NELEM(gTvInputHalMethods));
121 LOG_FATAL_IF(res < 0, "Unable to register native methods.");
122 (void)res; // Don't complain about unused variable in the LOG_NDEBUG case
123
124 jclass clazz;
125 FIND_CLASS(clazz, "com/android/server/tv/TvInputHal");
126
127 GET_METHOD_ID(
128 gTvInputHalClassInfo.deviceAvailable, clazz,
129 "deviceAvailableFromNative", "(Landroid/media/tv/TvInputHardwareInfo;)V");
130 GET_METHOD_ID(
131 gTvInputHalClassInfo.deviceUnavailable, clazz, "deviceUnavailableFromNative", "(I)V");
132 GET_METHOD_ID(gTvInputHalClassInfo.streamConfigsChanged, clazz,
133 "streamConfigsChangedFromNative", "(II)V");
134 GET_METHOD_ID(
135 gTvInputHalClassInfo.firstFrameCaptured, clazz,
136 "firstFrameCapturedFromNative", "(II)V");
137 GET_METHOD_ID(gTvInputHalClassInfo.tvMessageReceived, clazz, "tvMessageReceivedFromNative",
138 "(IILandroid/os/Bundle;)V");
139
140 FIND_CLASS(gTvStreamConfigClassInfo.clazz, "android/media/tv/TvStreamConfig");
141 gTvStreamConfigClassInfo.clazz = jclass(env->NewGlobalRef(gTvStreamConfigClassInfo.clazz));
142
143 FIND_CLASS(gBundleClassInfo.clazz, "android/os/Bundle");
144 gBundleClassInfo.clazz = jclass(env->NewGlobalRef(gBundleClassInfo.clazz));
145 GET_METHOD_ID(gBundleClassInfo.constructor, gBundleClassInfo.clazz, "<init>", "()V");
146 GET_METHOD_ID(gBundleClassInfo.putByteArray, gBundleClassInfo.clazz, "putByteArray",
147 "(Ljava/lang/String;[B)V");
148 GET_METHOD_ID(gBundleClassInfo.putString, gBundleClassInfo.clazz, "putString",
149 "(Ljava/lang/String;Ljava/lang/String;)V");
150 GET_METHOD_ID(gBundleClassInfo.putInt, gBundleClassInfo.clazz, "putInt",
151 "(Ljava/lang/String;I)V");
152
153 FIND_CLASS(gTvStreamConfigBuilderClassInfo.clazz, "android/media/tv/TvStreamConfig$Builder");
154 gTvStreamConfigBuilderClassInfo.clazz =
155 jclass(env->NewGlobalRef(gTvStreamConfigBuilderClassInfo.clazz));
156
157 GET_METHOD_ID(
158 gTvStreamConfigBuilderClassInfo.constructor,
159 gTvStreamConfigBuilderClassInfo.clazz,
160 "<init>", "()V");
161 GET_METHOD_ID(
162 gTvStreamConfigBuilderClassInfo.streamId,
163 gTvStreamConfigBuilderClassInfo.clazz,
164 "streamId", "(I)Landroid/media/tv/TvStreamConfig$Builder;");
165 GET_METHOD_ID(
166 gTvStreamConfigBuilderClassInfo.type,
167 gTvStreamConfigBuilderClassInfo.clazz,
168 "type", "(I)Landroid/media/tv/TvStreamConfig$Builder;");
169 GET_METHOD_ID(
170 gTvStreamConfigBuilderClassInfo.maxWidth,
171 gTvStreamConfigBuilderClassInfo.clazz,
172 "maxWidth", "(I)Landroid/media/tv/TvStreamConfig$Builder;");
173 GET_METHOD_ID(
174 gTvStreamConfigBuilderClassInfo.maxHeight,
175 gTvStreamConfigBuilderClassInfo.clazz,
176 "maxHeight", "(I)Landroid/media/tv/TvStreamConfig$Builder;");
177 GET_METHOD_ID(
178 gTvStreamConfigBuilderClassInfo.generation,
179 gTvStreamConfigBuilderClassInfo.clazz,
180 "generation", "(I)Landroid/media/tv/TvStreamConfig$Builder;");
181 GET_METHOD_ID(
182 gTvStreamConfigBuilderClassInfo.build,
183 gTvStreamConfigBuilderClassInfo.clazz,
184 "build", "()Landroid/media/tv/TvStreamConfig;");
185
186 FIND_CLASS(gTvInputHardwareInfoBuilderClassInfo.clazz,
187 "android/media/tv/TvInputHardwareInfo$Builder");
188 gTvInputHardwareInfoBuilderClassInfo.clazz =
189 jclass(env->NewGlobalRef(gTvInputHardwareInfoBuilderClassInfo.clazz));
190
191 GET_METHOD_ID(
192 gTvInputHardwareInfoBuilderClassInfo.constructor,
193 gTvInputHardwareInfoBuilderClassInfo.clazz,
194 "<init>", "()V");
195 GET_METHOD_ID(
196 gTvInputHardwareInfoBuilderClassInfo.deviceId,
197 gTvInputHardwareInfoBuilderClassInfo.clazz,
198 "deviceId", "(I)Landroid/media/tv/TvInputHardwareInfo$Builder;");
199 GET_METHOD_ID(
200 gTvInputHardwareInfoBuilderClassInfo.type,
201 gTvInputHardwareInfoBuilderClassInfo.clazz,
202 "type", "(I)Landroid/media/tv/TvInputHardwareInfo$Builder;");
203 GET_METHOD_ID(
204 gTvInputHardwareInfoBuilderClassInfo.hdmiPortId,
205 gTvInputHardwareInfoBuilderClassInfo.clazz,
206 "hdmiPortId", "(I)Landroid/media/tv/TvInputHardwareInfo$Builder;");
207 GET_METHOD_ID(
208 gTvInputHardwareInfoBuilderClassInfo.cableConnectionStatus,
209 gTvInputHardwareInfoBuilderClassInfo.clazz,
210 "cableConnectionStatus", "(I)Landroid/media/tv/TvInputHardwareInfo$Builder;");
211 GET_METHOD_ID(
212 gTvInputHardwareInfoBuilderClassInfo.audioType,
213 gTvInputHardwareInfoBuilderClassInfo.clazz,
214 "audioType", "(I)Landroid/media/tv/TvInputHardwareInfo$Builder;");
215 GET_METHOD_ID(
216 gTvInputHardwareInfoBuilderClassInfo.audioAddress,
217 gTvInputHardwareInfoBuilderClassInfo.clazz,
218 "audioAddress", "(Ljava/lang/String;)Landroid/media/tv/TvInputHardwareInfo$Builder;");
219 GET_METHOD_ID(
220 gTvInputHardwareInfoBuilderClassInfo.build,
221 gTvInputHardwareInfoBuilderClassInfo.clazz,
222 "build", "()Landroid/media/tv/TvInputHardwareInfo;");
223
224 return 0;
225 }
226
227 } /* namespace android */
228