1/*
2 * Copyright (C) 2016 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 <string.h>
18#include <cutils/log.h>
19#include <hardware/hardware.h>
20#include <hardware/vehicle_camera.h>
21#include <jni.h>
22#include <JNIHelp.h>
23#include <system/window.h>
24
25namespace android {
26
27/*
28 * Class:     com_android_car_CarCameraService
29 * Method:    nativeOpen
30 * Signature: ()J
31 */
32static jlong com_android_car_CarCameraService_nativeOpen
33  (JNIEnv *env, jobject obj)
34{
35    vehicle_camera_module_t *module = NULL;
36
37    hw_get_module(VEHICLE_CAMERA_HARDWARE_MODULE_ID, (const hw_module_t**)&module);
38
39    if (module == NULL) {
40        ALOGE("JNI Camera:  nativeOpen failed!");
41    }
42    return (jlong)module;
43}
44
45/*
46 * Class:     com_android_car_CarCameraService
47 * Method:    nativeClose
48 * Signature: (J)V
49 */
50static void com_android_car_CarCameraService_nativeClose
51  (JNIEnv *env, jobject, jlong dev)
52{
53    vehicle_camera_device_t *device = (vehicle_camera_device_t*)dev;
54
55    if (device != NULL) {
56        device->common.close((struct hw_device_t*)device);
57    }
58}
59
60/*
61 * Class:     com_android_car_CarCameraService
62 * Method:    nativeGetSupportedCameras
63 * Signature: (J)[I
64 */
65static jintArray com_android_car_CarCameraService_nativeGetSupportedCameras
66  (JNIEnv *env, jobject, jlong mod)
67{
68    int i;
69    vehicle_camera_module_t *module = (vehicle_camera_module_t*)mod;
70    const uint32_t *camera_list;
71    uint32_t numCameras;
72    jintArray outArray = NULL;
73
74    camera_list = module->get_camera_device_list(&numCameras);
75
76    if ((numCameras > 0) && (camera_list != NULL)) {
77        outArray = env->NewIntArray(numCameras);
78    }
79
80    if (outArray == NULL) {
81        return NULL;
82    }
83    // Copy camera list to output array
84    env->SetIntArrayRegion(outArray, 0, numCameras, (jint*)camera_list);
85    return outArray;
86}
87
88/*
89 * Class:     com_android_car_CarCameraService
90 * Method:    nativeGetDevice
91 * Signature: (JI)J
92 */
93static jlong com_android_car_CarCameraService_nativeGetDevice
94  (JNIEnv *env, jobject, jlong mod, jint cameraType)
95{
96    const char *cameraTypeString[] = {
97        VEHICLE_CAMERA_RVC_DEVICE,
98    };
99    vehicle_camera_module_t *module = (vehicle_camera_module_t*)mod;
100    hw_device_t *device = NULL;
101
102    if (module != NULL) {
103        module->common.methods->open((hw_module_t*)module, cameraTypeString[cameraType], &device);
104    }
105
106    if (device == NULL) {
107        ALOGE("JNI Camera:  nativeGetDevice failed!");
108    }
109    return (jlong)device;
110}
111
112
113/*
114 * Class:     com_android_car_CarCameraService
115 * Method:    nativeGetCapabilities
116 * Signature: (J)I
117 */
118static jint com_android_car_CarCameraService_nativeGetCapabilities
119  (JNIEnv *env, jobject, jlong dev)
120{
121    vehicle_camera_cap_t cap;
122    jint capabilities = 0;
123    vehicle_camera_device_t *device = (vehicle_camera_device_t*)dev;
124    if (device != NULL) {
125        // Fetch the capabilities
126        int errCode = device->get_capabilities(device, &cap);
127
128        if (errCode == 0) {
129            capabilities = cap.capabilites_flags;
130        } else {
131            ALOGE("JNI Camera:  nativeGetCapabilites errCode = %d", errCode);
132        }
133    } else {
134        ALOGE("JNI Camera:  nativeGetCapabilities!");
135    }
136
137    return capabilities;
138}
139
140/*
141 * Class:     com_android_car_CarCameraService
142 * Method:    nativeGetCameraCrop
143 * Signature: (J)Landroid/graphics/Rect;
144 */
145static jobject com_android_car_CarCameraService_nativeGetCameraCrop
146  (JNIEnv *env, jobject, jlong dev)
147{
148    vehicle_camera_device_t *device = (vehicle_camera_device_t*)dev;
149    jobject retObj = NULL;
150
151    if (device != NULL) {
152        // Get the crop values
153        android_native_rect_t rect;
154        device->get_camera_crop(device, &rect);
155
156        // Get the class
157        jclass cls = env->FindClass("android/graphics/Rect");
158        jmethodID midInit = env->GetMethodID(cls, "<init>", "(IIII)V");
159
160        // Instantiate a new java CarRect objected with the current values
161        retObj = env->NewObject(cls, midInit, rect.left, rect.top, rect.right, rect.bottom);
162    }
163
164    return retObj;
165}
166
167/*
168 * Class:     com_android_car_CarCameraService
169 * Method:    nativeSetCameraCrop
170 * Signature: (JLandroid/graphics/Rect;)V
171 */
172static void com_android_car_CarCameraService_nativeSetCameraCrop
173  (JNIEnv *env, jobject, jlong dev, jobject jrect)
174{
175    vehicle_camera_device_t *device = (vehicle_camera_device_t*)dev;
176    if (device != NULL) {
177        android_native_rect_t rect;
178
179        jclass   cls       = env->GetObjectClass(jrect);
180        jfieldID fidLeft   = env->GetFieldID(cls, "left",   "I");
181        jfieldID fidTop    = env->GetFieldID(cls, "top",    "I");
182        jfieldID fidRight  = env->GetFieldID(cls, "right",  "I");
183        jfieldID fidBottom = env->GetFieldID(cls, "bottom", "I");
184
185        rect.left   = (uint32_t)env->GetIntField(jrect, fidLeft);
186        rect.top    = (uint32_t)env->GetIntField(jrect, fidTop);
187        rect.right  = (uint32_t)env->GetIntField(jrect, fidRight);
188        rect.bottom = (uint32_t)env->GetIntField(jrect, fidBottom);
189
190        device->set_camera_crop(device, &rect);
191    }
192}
193
194/*
195 * Class:     com_android_car_CarCameraService
196 * Method:    nativeGetCameraPosition
197 * Signature: (J)Landroid/graphics/Rect;
198 */
199static jobject com_android_car_CarCameraService_nativeGetCameraPosition
200  (JNIEnv *env, jobject, jlong dev)
201{
202    vehicle_camera_device_t *device = (vehicle_camera_device_t*)dev;
203    jobject retObj = NULL;
204
205    if (device != NULL) {
206        // Get the position values
207        android_native_rect_t rect;
208        device->get_camera_position(device, &rect);
209
210        // Get the class
211        jclass cls = env->FindClass("android/graphics/Rect");
212        jmethodID midInit = env->GetMethodID(cls, "<init>", "(IIII)V");
213
214        // Instantiate a new java CarRect objected with the current values
215        retObj = env->NewObject(cls, midInit, rect.left, rect.top, rect.right, rect.bottom);
216    }
217
218    return retObj;
219}
220
221
222/*
223 * Class:     com_android_car_CarCameraService
224 * Method:    nativeSetCameraPosition
225 * Signature: (JLandroid/graphics/Rect;)V
226 */
227static void com_android_car_CarCameraService_nativeSetCameraPosition
228  (JNIEnv *env, jobject, jlong dev, jobject jrect)
229{
230    vehicle_camera_device_t *device = (vehicle_camera_device_t*)dev;
231    if (device != NULL) {
232        android_native_rect_t rect;
233
234        jclass   cls       = env->GetObjectClass(jrect);
235        jfieldID fidLeft   = env->GetFieldID(cls, "left",   "I");
236        jfieldID fidTop    = env->GetFieldID(cls, "top",    "I");
237        jfieldID fidRight  = env->GetFieldID(cls, "right",  "I");
238        jfieldID fidBottom = env->GetFieldID(cls, "bottom", "I");
239
240        rect.left   = (uint32_t)env->GetIntField(jrect, fidLeft);
241        rect.top    = (uint32_t)env->GetIntField(jrect, fidTop);
242        rect.right  = (uint32_t)env->GetIntField(jrect, fidRight);
243        rect.bottom = (uint32_t)env->GetIntField(jrect, fidBottom);
244
245        device->set_camera_position(device, &rect);
246    }
247}
248
249/*
250 * Class:     com_android_car_CarCameraService
251 * Method:    nativeGetCameraState
252 * Signature: (J)Landroid/car/hardware/camera/CarCameraState;
253 */
254static jobject com_android_car_CarCameraService_nativeGetCameraState
255  (JNIEnv *env, jobject, jlong dev)
256{
257    vehicle_camera_device_t *device = (vehicle_camera_device_t*)dev;
258    jobject retObj = NULL;
259
260    if (device != NULL) {
261        vehicle_camera_state_t state;
262        device->get_camera_state(device, &state);
263
264        // Get the class
265        jclass cls = env->FindClass("android/car/hardware/camera/CarCameraState");
266        jmethodID midInit = env->GetMethodID(cls, "<init>", "(ZZ)V");
267
268        // Instantiate a new java CarRect objected with the current values
269        retObj = env->NewObject(cls, midInit, state.overlay_on, state.camera_on);
270    }
271
272    return retObj;
273}
274
275
276/*
277 * Class:     com_android_car_CarCameraService
278 * Method:    nativeSetCameraState
279 * Signature: (JLandroid/car/hardware/camera/CarCameraState;)V
280 */
281static void com_android_car_CarCameraService_nativeSetCameraState
282  (JNIEnv *env, jobject, jlong dev, jobject jstate)
283{
284    vehicle_camera_device_t *device = (vehicle_camera_device_t*)dev;
285    if (device != NULL) {
286        vehicle_camera_state_t state;
287
288        jclass cls = env->GetObjectClass(jstate);
289        jmethodID midCamera  = env->GetMethodID(cls, "getCameraIsOn",  "()Z");
290        jmethodID midOverlay = env->GetMethodID(cls, "getOverlayIsOn", "()Z");
291
292        state.overlay_on = (uint32_t)env->CallBooleanMethod(jstate, midOverlay);
293        state.camera_on  = (uint32_t)env->CallBooleanMethod(jstate, midCamera);
294
295        device->set_camera_state(device, &state);
296    }
297}
298
299static JNINativeMethod gMethods[] = {
300    { "nativeOpen", "()J", (void*)com_android_car_CarCameraService_nativeOpen },
301    { "nativeClose", "(J)V", (void*)com_android_car_CarCameraService_nativeClose },
302    { "nativeGetSupportedCameras", "(J)[I", (void*)com_android_car_CarCameraService_nativeGetSupportedCameras },
303    { "nativeGetDevice", "(JI)J", (void*)com_android_car_CarCameraService_nativeGetDevice },
304    { "nativeGetCapabilities", "(J)I", (void*)com_android_car_CarCameraService_nativeGetCapabilities },
305    { "nativeGetCameraCrop", "(J)Landroid/graphics/Rect;", (void*)com_android_car_CarCameraService_nativeGetCameraCrop },
306    { "nativeSetCameraCrop", "(JLandroid/graphics/Rect;)V", (void*)com_android_car_CarCameraService_nativeSetCameraCrop },
307    { "nativeGetCameraPosition", "(J)Landroid/graphics/Rect;", (void*)com_android_car_CarCameraService_nativeGetCameraPosition },
308    { "nativeSetCameraPosition", "(JLandroid/graphics/Rect;)V", (void*)com_android_car_CarCameraService_nativeSetCameraPosition },
309    { "nativeGetCameraState", "(J)Landroid/car/hardware/camera/CarCameraState;", (void*)com_android_car_CarCameraService_nativeGetCameraState },
310    { "nativeSetCameraState", "(JLandroid/car/hardware/camera/CarCameraState;)V", (void*)com_android_car_CarCameraService_nativeSetCameraState },
311};
312
313int register_com_android_car_CarCameraService(JNIEnv *env) {
314    return jniRegisterNativeMethods(env, "com/android/car/CarCameraService",
315            gMethods, NELEM(gMethods));
316}
317
318} // namespace android
319
320
321