Merge ~chrisccoulson/libhybris/+git/libhybris:oxide-camera into ~libhybris-maintainers/libhybris/+git/libhybris:master

Proposed by Chris Coulson
Status: Merged
Approved by: Simon Fels
Approved revision: f36585e4759204bf6cb9bce0afb50bf23299b5d1
Merged at revision: 8a63560457c550b3804db4afb64c6b87a10dde68
Proposed branch: ~chrisccoulson/libhybris/+git/libhybris:oxide-camera
Merge into: ~libhybris-maintainers/libhybris/+git/libhybris:master
Diff against target: 252 lines (+87/-17)
4 files modified
compat/camera/camera_compatibility_layer.cpp (+64/-17)
hybris/camera/camera.c (+8/-0)
hybris/include/hybris/camera/camera_compatibility_layer.h (+14/-0)
hybris/include/hybris/camera/camera_compatibility_layer_capabilities.h (+1/-0)
Reviewer Review Type Date Requested Status
Simon Fels Approve
Jim Hodapp (community) code Needs Fixing
Florian Boucault Pending
Review via email: mp+280070@code.launchpad.net

Description of the change

Various fixes to allow camera access to work in the web browser

To post a comment you must log in.
Revision history for this message
Jim Hodapp (jhodapp) wrote :

Looks good, a few inline comments.

review: Needs Fixing (code)
Revision history for this message
Simon Fels (morphis) wrote :

LGTM

review: Approve
Revision history for this message
Simon Fels (morphis) wrote :

Overriding Jims review here as his comments were addressed.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/compat/camera/camera_compatibility_layer.cpp b/compat/camera/camera_compatibility_layer.cpp
2index 3d8e5bc..a6bdeae 100644
3--- a/compat/camera/camera_compatibility_layer.cpp
4+++ b/compat/camera/camera_compatibility_layer.cpp
5@@ -45,6 +45,8 @@
6
7 #undef LOG_TAG
8 #define LOG_TAG "CameraCompatibilityLayer"
9+#include <utils/Debug.h>
10+#include <utils/Errors.h>
11 #include <utils/KeyedVector.h>
12 #include <utils/Log.h>
13 #include <utils/String16.h>
14@@ -55,6 +57,8 @@
15
16 #define REPORT_FUNCTION() ALOGV("%s \n", __PRETTY_FUNCTION__)
17
18+using android::CompileTimeAssert; // So COMPILE_TIME_ASSERT works
19+
20 // From android::GLConsumer::FrameAvailableListener
21 #if ANDROID_VERSION_MAJOR==5 && ANDROID_VERSION_MINOR>=1
22 void CameraControl::onFrameAvailable(const android::BufferItem& item)
23@@ -117,6 +121,9 @@ void CameraControl::postData(
24 if (listener->on_data_compressed_image_cb)
25 listener->on_data_compressed_image_cb(data->pointer(), data->size(), listener->context);
26 break;
27+ case CAMERA_MSG_PREVIEW_FRAME:
28+ if (listener->on_preview_frame_cb)
29+ listener->on_preview_frame_cb(data->pointer(), data->size(), listener->context);
30 default:
31 break;
32 }
33@@ -159,38 +166,59 @@ sp<GraphicBuffer> NativeBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
34 }
35 }
36
37-namespace
38+int android_camera_get_number_of_devices()
39 {
40-
41-android::sp<CameraControl> camera_control_instance;
42-
43+ REPORT_FUNCTION();
44+ return android::Camera::getNumberOfCameras();
45 }
46
47-int android_camera_get_number_of_devices()
48+int android_camera_get_device_info(int32_t camera_id, int* facing, int* orientation)
49 {
50 REPORT_FUNCTION();
51- return android::Camera::getNumberOfCameras();
52+
53+ if (!facing || !orientation)
54+ return android::BAD_VALUE;
55+
56+ COMPILE_TIME_ASSERT_FUNCTION_SCOPE(CAMERA_FACING_BACK == static_cast<int>(BACK_FACING_CAMERA_TYPE));
57+ COMPILE_TIME_ASSERT_FUNCTION_SCOPE(CAMERA_FACING_FRONT == static_cast<int>(FRONT_FACING_CAMERA_TYPE));
58+
59+ android::CameraInfo ci;
60+
61+ int rv = android::Camera::getCameraInfo(camera_id, &ci);
62+ if (rv != android::OK)
63+ return rv;
64+
65+ *facing = ci.facing;
66+ *orientation = ci.orientation;
67+
68+ return android::OK;
69 }
70
71 CameraControl* android_camera_connect_to(CameraType camera_type, CameraControlListener* listener)
72 {
73 REPORT_FUNCTION();
74
75- int32_t camera_id;
76- int32_t camera_count = camera_id = android::Camera::getNumberOfCameras();
77+ const int32_t camera_count = android::Camera::getNumberOfCameras();
78
79- for (camera_id = 0; camera_id < camera_count; camera_id++) {
80+ for (int32_t camera_id = 0; camera_id < camera_count; camera_id++) {
81 android::CameraInfo ci;
82 android::Camera::getCameraInfo(camera_id, &ci);
83
84- if (ci.facing == camera_type)
85- break;
86+ if (ci.facing != camera_type)
87+ continue;
88+
89+ return android_camera_connect_by_id(camera_id, listener);
90 }
91
92- if (camera_id == camera_count)
93+ return NULL;
94+}
95+
96+CameraControl* android_camera_connect_by_id(int32_t camera_id, struct CameraControlListener* listener)
97+{
98+ if (camera_id < 0 || camera_id >= android::Camera::getNumberOfCameras())
99 return NULL;
100
101- CameraControl* cc = new CameraControl();
102+ android::sp<CameraControl> cc = new CameraControl();
103 cc->listener = listener;
104 #if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR>=3 || ANDROID_VERSION_MAJOR==5
105 cc->camera = android::Camera::connect(camera_id, android::String16("hybris"), android::Camera::USE_CALLING_UID);
106@@ -203,14 +231,15 @@ CameraControl* android_camera_connect_to(CameraType camera_type, CameraControlLi
107
108 cc->camera_parameters = android::CameraParameters(cc->camera->getParameters());
109
110- camera_control_instance = cc;
111- cc->camera->setListener(camera_control_instance);
112+ // android::Camera holds a strong reference to the listener, keeping
113+ // |cc| alive
114+ cc->camera->setListener(cc);
115 cc->camera->lock();
116
117 // TODO: Move this to a more generic component
118 android::ProcessState::self()->startThreadPool();
119
120- return cc;
121+ return cc.get();
122 }
123
124 void android_camera_disconnect(CameraControl* control)
125@@ -241,7 +270,9 @@ int android_camera_unlock(CameraControl* control)
126
127 void android_camera_delete(CameraControl* control)
128 {
129- delete control;
130+ android::sp<android::Camera> camera = control->camera;
131+ control->camera.clear();
132+ camera.clear();
133 }
134
135 void android_camera_dump_parameters(CameraControl* control)
136@@ -814,6 +845,22 @@ void android_camera_take_snapshot(CameraControl* control)
137 control->camera->takePicture(CAMERA_MSG_SHUTTER | CAMERA_MSG_COMPRESSED_IMAGE);
138 }
139
140+int android_camera_set_preview_callback_mode(CameraControl* control, PreviewCallbackMode mode)
141+{
142+ REPORT_FUNCTION();
143+
144+ if (!control)
145+ return android::BAD_VALUE;
146+
147+ android::Mutex::Autolock al(control->guard);
148+
149+ control->camera->setPreviewCallbackFlags(
150+ mode == PREVIEW_CALLBACK_ENABLED ?
151+ CAMERA_FRAME_CALLBACK_FLAG_CAMCORDER : CAMERA_FRAME_CALLBACK_FLAG_NOOP);
152+
153+ return android::OK;
154+}
155+
156 void android_camera_set_preview_format(CameraControl* control, CameraPixelFormat pf)
157 {
158 REPORT_FUNCTION();
159diff --git a/hybris/camera/camera.c b/hybris/camera/camera.c
160index 41071a1..9f1c2d2 100644
161--- a/hybris/camera/camera.c
162+++ b/hybris/camera/camera.c
163@@ -31,8 +31,11 @@
164 HYBRIS_LIBRARY_INITIALIZE(camera, COMPAT_LIBRARY_PATH);
165
166 HYBRIS_IMPLEMENT_FUNCTION0(camera, int, android_camera_get_number_of_devices);
167+HYBRIS_IMPLEMENT_FUNCTION3(camera, int, android_camera_get_device_info, int32_t, int*, int*);
168 HYBRIS_IMPLEMENT_FUNCTION2(camera, struct CameraControl*, android_camera_connect_to,
169 CameraType, struct CameraControlListener*);
170+HYBRIS_IMPLEMENT_FUNCTION2(camera, struct CameraControl*, android_camera_connect_by_id,
171+ int32_t, struct CameraControlListener*);
172 HYBRIS_IMPLEMENT_VOID_FUNCTION1(camera, android_camera_disconnect,
173 struct CameraControl*);
174 HYBRIS_IMPLEMENT_FUNCTION1(camera, int, android_camera_lock, struct CameraControl*);
175@@ -52,6 +55,8 @@ HYBRIS_IMPLEMENT_VOID_FUNCTION2(camera, android_camera_set_scene_mode,
176 struct CameraControl*, SceneMode);
177 HYBRIS_IMPLEMENT_VOID_FUNCTION2(camera, android_camera_set_auto_focus_mode,
178 struct CameraControl*, AutoFocusMode);
179+HYBRIS_IMPLEMENT_VOID_FUNCTION2(camera, android_camera_set_preview_format,
180+ struct CameraControl*, CameraPixelFormat);
181 HYBRIS_IMPLEMENT_VOID_FUNCTION3(camera, android_camera_set_picture_size,
182 struct CameraControl*, int, int);
183 HYBRIS_IMPLEMENT_VOID_FUNCTION3(camera, android_camera_set_thumbnail_size,
184@@ -134,3 +139,6 @@ HYBRIS_IMPLEMENT_VOID_FUNCTION2(camera, android_camera_start_zoom, struct Camera
185 HYBRIS_IMPLEMENT_VOID_FUNCTION2(camera, android_camera_set_zoom, struct CameraControl*, int32_t);
186 HYBRIS_IMPLEMENT_VOID_FUNCTION1(camera, android_camera_stop_zoom, struct CameraControl*);
187 HYBRIS_IMPLEMENT_VOID_FUNCTION1(camera, android_camera_take_snapshot, struct CameraControl*);
188+
189+HYBRIS_IMPLEMENT_FUNCTION2(camera, int, android_camera_set_preview_callback_mode,
190+ struct CameraControl*, PreviewCallbackMode);
191diff --git a/hybris/include/hybris/camera/camera_compatibility_layer.h b/hybris/include/hybris/camera/camera_compatibility_layer.h
192index 72aabcf..90f12a0 100644
193--- a/hybris/include/hybris/camera/camera_compatibility_layer.h
194+++ b/hybris/include/hybris/camera/camera_compatibility_layer.h
195@@ -37,6 +37,12 @@ extern "C" {
196 FRONT_FACING_CAMERA_TYPE
197 } CameraType;
198
199+ typedef enum
200+ {
201+ PREVIEW_CALLBACK_DISABLED,
202+ PREVIEW_CALLBACK_ENABLED
203+ } PreviewCallbackMode;
204+
205 struct CameraControl;
206
207 typedef void (*on_msg_error)(void* context);
208@@ -47,6 +53,7 @@ extern "C" {
209 typedef void (*on_data_raw_image)(void* data, uint32_t data_size, void* context);
210 typedef void (*on_data_compressed_image)(void* data, uint32_t data_size, void* context);
211 typedef void (*on_preview_texture_needs_update)(void* context);
212+ typedef void (*on_preview_frame)(void* data, uint32_t data_size, void* context);
213
214 struct CameraControlListener
215 {
216@@ -73,10 +80,14 @@ extern "C" {
217 on_preview_texture_needs_update on_preview_texture_needs_update_cb;
218
219 void* context;
220+
221+ // Called when there is a new preview frame
222+ on_preview_frame on_preview_frame_cb;
223 };
224
225 // Initializes a connection to the camera, returns NULL on error.
226 struct CameraControl* android_camera_connect_to(CameraType camera_type, struct CameraControlListener* listener);
227+ struct CameraControl* android_camera_connect_by_id(int32_t camera_id, struct CameraControlListener* listener);
228
229 // Disconnects the camera and deletes the pointer
230 void android_camera_disconnect(struct CameraControl* control);
231@@ -135,6 +146,9 @@ extern "C" {
232 // completed. Ideally, this is done from the raw data callback.
233 void android_camera_take_snapshot(struct CameraControl* control);
234
235+ // Enable or disable the preview callback for clients that want software frames
236+ int android_camera_set_preview_callback_mode(struct CameraControl* control, PreviewCallbackMode mode);
237+
238 #ifdef __cplusplus
239 }
240 #endif
241diff --git a/hybris/include/hybris/camera/camera_compatibility_layer_capabilities.h b/hybris/include/hybris/camera/camera_compatibility_layer_capabilities.h
242index 66bbaa7..486f9fc 100644
243--- a/hybris/include/hybris/camera/camera_compatibility_layer_capabilities.h
244+++ b/hybris/include/hybris/camera/camera_compatibility_layer_capabilities.h
245@@ -105,6 +105,7 @@ extern "C" {
246
247 // Query camera parameters
248 int android_camera_get_number_of_devices();
249+ int android_camera_get_device_info(int32_t camera_id, int* facing, int* orientation);
250 void android_camera_enumerate_supported_preview_sizes(struct CameraControl* control, size_callback cb, void* ctx);
251 void android_camera_get_preview_fps_range(struct CameraControl* control, int* min, int* max);
252 void android_camera_get_preview_fps(struct CameraControl* control, int* fps);

Subscribers

People subscribed via source and target branches