1 /*
2 * Copyright (C) 2013 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 "ProCamera2Client"
18 #define ATRACE_TAG ATRACE_TAG_CAMERA
19 //#define LOG_NDEBUG 0
20
21 #include <utils/Log.h>
22 #include <utils/Trace.h>
23
24 #include <cutils/properties.h>
25 #include <gui/Surface.h>
26 #include <gui/Surface.h>
27 #include "camera2/Parameters.h"
28 #include "ProCamera2Client.h"
29 #include "camera2/ProFrameProcessor.h"
30 #include "CameraDeviceBase.h"
31
32 namespace android {
33 using namespace camera2;
34
35 // Interface used by CameraService
36
ProCamera2Client(const sp<CameraService> & cameraService,const sp<IProCameraCallbacks> & remoteCallback,const String16 & clientPackageName,int cameraId,int cameraFacing,int clientPid,uid_t clientUid,int servicePid)37 ProCamera2Client::ProCamera2Client(const sp<CameraService>& cameraService,
38 const sp<IProCameraCallbacks>& remoteCallback,
39 const String16& clientPackageName,
40 int cameraId,
41 int cameraFacing,
42 int clientPid,
43 uid_t clientUid,
44 int servicePid) :
45 Camera2ClientBase(cameraService, remoteCallback, clientPackageName,
46 cameraId, cameraFacing, clientPid, clientUid, servicePid)
47 {
48 ATRACE_CALL();
49 ALOGI("ProCamera %d: Opened", cameraId);
50
51 mExclusiveLock = false;
52 }
53
initialize(camera_module_t * module)54 status_t ProCamera2Client::initialize(camera_module_t *module)
55 {
56 ATRACE_CALL();
57 status_t res;
58
59 res = Camera2ClientBase::initialize(module);
60 if (res != OK) {
61 return res;
62 }
63
64 String8 threadName;
65 mFrameProcessor = new ProFrameProcessor(mDevice);
66 threadName = String8::format("PC2-%d-FrameProc", mCameraId);
67 mFrameProcessor->run(threadName.string());
68
69 mFrameProcessor->registerListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
70 FRAME_PROCESSOR_LISTENER_MAX_ID,
71 /*listener*/this);
72
73 return OK;
74 }
75
~ProCamera2Client()76 ProCamera2Client::~ProCamera2Client() {
77 }
78
exclusiveTryLock()79 status_t ProCamera2Client::exclusiveTryLock() {
80 ATRACE_CALL();
81 ALOGV("%s", __FUNCTION__);
82
83 Mutex::Autolock icl(mBinderSerializationLock);
84 SharedCameraCallbacks::Lock l(mSharedCameraCallbacks);
85
86 if (!mDevice.get()) return PERMISSION_DENIED;
87
88 if (!mExclusiveLock) {
89 mExclusiveLock = true;
90
91 if (mRemoteCallback != NULL) {
92 mRemoteCallback->onLockStatusChanged(
93 IProCameraCallbacks::LOCK_ACQUIRED);
94 }
95
96 ALOGV("%s: exclusive lock acquired", __FUNCTION__);
97
98 return OK;
99 }
100
101 // TODO: have a PERMISSION_DENIED case for when someone else owns the lock
102
103 // don't allow recursive locking
104 ALOGW("%s: exclusive lock already exists - recursive locking is not"
105 "allowed", __FUNCTION__);
106
107 return ALREADY_EXISTS;
108 }
109
exclusiveLock()110 status_t ProCamera2Client::exclusiveLock() {
111 ATRACE_CALL();
112 ALOGV("%s", __FUNCTION__);
113
114 Mutex::Autolock icl(mBinderSerializationLock);
115 SharedCameraCallbacks::Lock l(mSharedCameraCallbacks);
116
117 if (!mDevice.get()) return PERMISSION_DENIED;
118
119 /**
120 * TODO: this should asynchronously 'wait' until the lock becomes available
121 * if another client already has an exclusive lock.
122 *
123 * once we have proper sharing support this will need to do
124 * more than just return immediately
125 */
126 if (!mExclusiveLock) {
127 mExclusiveLock = true;
128
129 if (mRemoteCallback != NULL) {
130 mRemoteCallback->onLockStatusChanged(IProCameraCallbacks::LOCK_ACQUIRED);
131 }
132
133 ALOGV("%s: exclusive lock acquired", __FUNCTION__);
134
135 return OK;
136 }
137
138 // don't allow recursive locking
139 ALOGW("%s: exclusive lock already exists - recursive locking is not allowed"
140 , __FUNCTION__);
141 return ALREADY_EXISTS;
142 }
143
exclusiveUnlock()144 status_t ProCamera2Client::exclusiveUnlock() {
145 ATRACE_CALL();
146 ALOGV("%s", __FUNCTION__);
147
148 Mutex::Autolock icl(mBinderSerializationLock);
149 SharedCameraCallbacks::Lock l(mSharedCameraCallbacks);
150
151 // don't allow unlocking if we have no lock
152 if (!mExclusiveLock) {
153 ALOGW("%s: cannot unlock, no lock was held in the first place",
154 __FUNCTION__);
155 return BAD_VALUE;
156 }
157
158 mExclusiveLock = false;
159 if (mRemoteCallback != NULL ) {
160 mRemoteCallback->onLockStatusChanged(
161 IProCameraCallbacks::LOCK_RELEASED);
162 }
163 ALOGV("%s: exclusive lock released", __FUNCTION__);
164
165 return OK;
166 }
167
hasExclusiveLock()168 bool ProCamera2Client::hasExclusiveLock() {
169 Mutex::Autolock icl(mBinderSerializationLock);
170 return mExclusiveLock;
171 }
172
onExclusiveLockStolen()173 void ProCamera2Client::onExclusiveLockStolen() {
174 ALOGV("%s: ProClient lost exclusivity (id %d)",
175 __FUNCTION__, mCameraId);
176
177 Mutex::Autolock icl(mBinderSerializationLock);
178 SharedCameraCallbacks::Lock l(mSharedCameraCallbacks);
179
180 if (mExclusiveLock && mRemoteCallback.get() != NULL) {
181 mRemoteCallback->onLockStatusChanged(
182 IProCameraCallbacks::LOCK_STOLEN);
183 }
184
185 mExclusiveLock = false;
186
187 //TODO: we should not need to detach the device, merely reset it.
188 detachDevice();
189 }
190
submitRequest(camera_metadata_t * request,bool streaming)191 status_t ProCamera2Client::submitRequest(camera_metadata_t* request,
192 bool streaming) {
193 ATRACE_CALL();
194 ALOGV("%s", __FUNCTION__);
195
196 Mutex::Autolock icl(mBinderSerializationLock);
197
198 if (!mDevice.get()) return DEAD_OBJECT;
199
200 if (!mExclusiveLock) {
201 return PERMISSION_DENIED;
202 }
203
204 CameraMetadata metadata(request);
205
206 if (!enforceRequestPermissions(metadata)) {
207 return PERMISSION_DENIED;
208 }
209
210 if (streaming) {
211 return mDevice->setStreamingRequest(metadata);
212 } else {
213 return mDevice->capture(metadata);
214 }
215
216 // unreachable. thx gcc for a useless warning
217 return OK;
218 }
219
cancelRequest(int requestId)220 status_t ProCamera2Client::cancelRequest(int requestId) {
221 ATRACE_CALL();
222 ALOGV("%s", __FUNCTION__);
223
224 Mutex::Autolock icl(mBinderSerializationLock);
225
226 if (!mDevice.get()) return DEAD_OBJECT;
227
228 if (!mExclusiveLock) {
229 return PERMISSION_DENIED;
230 }
231
232 // TODO: implement
233 ALOGE("%s: not fully implemented yet", __FUNCTION__);
234 return INVALID_OPERATION;
235 }
236
deleteStream(int streamId)237 status_t ProCamera2Client::deleteStream(int streamId) {
238 ATRACE_CALL();
239 ALOGV("%s (streamId = 0x%x)", __FUNCTION__, streamId);
240
241 status_t res;
242 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
243
244 Mutex::Autolock icl(mBinderSerializationLock);
245
246 if (!mDevice.get()) return DEAD_OBJECT;
247 mDevice->clearStreamingRequest();
248
249 status_t code;
250 if ((code = mDevice->waitUntilDrained()) != OK) {
251 ALOGE("%s: waitUntilDrained failed with code 0x%x", __FUNCTION__, code);
252 }
253
254 return mDevice->deleteStream(streamId);
255 }
256
createStream(int width,int height,int format,const sp<IGraphicBufferProducer> & bufferProducer,int * streamId)257 status_t ProCamera2Client::createStream(int width, int height, int format,
258 const sp<IGraphicBufferProducer>& bufferProducer,
259 /*out*/
260 int* streamId)
261 {
262 if (streamId) {
263 *streamId = -1;
264 }
265
266 ATRACE_CALL();
267 ALOGV("%s (w = %d, h = %d, f = 0x%x)", __FUNCTION__, width, height, format);
268
269 status_t res;
270 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
271
272 Mutex::Autolock icl(mBinderSerializationLock);
273
274 if (!mDevice.get()) return DEAD_OBJECT;
275
276 sp<IBinder> binder;
277 sp<ANativeWindow> window;
278 if (bufferProducer != 0) {
279 binder = bufferProducer->asBinder();
280 window = new Surface(bufferProducer);
281 }
282
283 return mDevice->createStream(window, width, height, format, /*size*/1,
284 streamId);
285 }
286
287 // Create a request object from a template.
288 // -- Caller owns the newly allocated metadata
createDefaultRequest(int templateId,camera_metadata ** request)289 status_t ProCamera2Client::createDefaultRequest(int templateId,
290 /*out*/
291 camera_metadata** request)
292 {
293 ATRACE_CALL();
294 ALOGV("%s (templateId = 0x%x)", __FUNCTION__, templateId);
295
296 if (request) {
297 *request = NULL;
298 }
299
300 status_t res;
301 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
302
303 Mutex::Autolock icl(mBinderSerializationLock);
304
305 if (!mDevice.get()) return DEAD_OBJECT;
306
307 CameraMetadata metadata;
308 if ( (res = mDevice->createDefaultRequest(templateId, &metadata) ) == OK) {
309 *request = metadata.release();
310 }
311
312 return res;
313 }
314
getCameraInfo(int cameraId,camera_metadata ** info)315 status_t ProCamera2Client::getCameraInfo(int cameraId,
316 /*out*/
317 camera_metadata** info)
318 {
319 if (cameraId != mCameraId) {
320 return INVALID_OPERATION;
321 }
322
323 Mutex::Autolock icl(mBinderSerializationLock);
324
325 if (!mDevice.get()) return DEAD_OBJECT;
326
327 CameraMetadata deviceInfo = mDevice->info();
328 *info = deviceInfo.release();
329
330 return OK;
331 }
332
dump(int fd,const Vector<String16> & args)333 status_t ProCamera2Client::dump(int fd, const Vector<String16>& args) {
334 String8 result;
335 result.appendFormat("ProCamera2Client[%d] (%p) PID: %d, dump:\n",
336 mCameraId,
337 getRemoteCallback()->asBinder().get(),
338 mClientPid);
339 result.append(" State: ");
340
341 // TODO: print dynamic/request section from most recent requests
342 mFrameProcessor->dump(fd, args);
343
344 return dumpDevice(fd, args);
345 }
346
347 // IProCameraUser interface
348
detachDevice()349 void ProCamera2Client::detachDevice() {
350 if (mDevice == 0) return;
351
352 ALOGV("Camera %d: Stopping processors", mCameraId);
353
354 mFrameProcessor->removeListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
355 FRAME_PROCESSOR_LISTENER_MAX_ID,
356 /*listener*/this);
357 mFrameProcessor->requestExit();
358 ALOGV("Camera %d: Waiting for threads", mCameraId);
359 mFrameProcessor->join();
360 ALOGV("Camera %d: Disconnecting device", mCameraId);
361
362 // WORKAROUND: HAL refuses to disconnect while there's streams in flight
363 {
364 mDevice->clearStreamingRequest();
365
366 status_t code;
367 if ((code = mDevice->waitUntilDrained()) != OK) {
368 ALOGE("%s: waitUntilDrained failed with code 0x%x", __FUNCTION__,
369 code);
370 }
371 }
372
373 Camera2ClientBase::detachDevice();
374 }
375
376 /** Device-related methods */
onFrameAvailable(int32_t frameId,const CameraMetadata & frame)377 void ProCamera2Client::onFrameAvailable(int32_t frameId,
378 const CameraMetadata& frame) {
379 ATRACE_CALL();
380 ALOGV("%s", __FUNCTION__);
381
382 Mutex::Autolock icl(mBinderSerializationLock);
383 SharedCameraCallbacks::Lock l(mSharedCameraCallbacks);
384
385 if (mRemoteCallback != NULL) {
386 CameraMetadata tmp(frame);
387 camera_metadata_t* meta = tmp.release();
388 ALOGV("%s: meta = %p ", __FUNCTION__, meta);
389 mRemoteCallback->onResultReceived(frameId, meta);
390 tmp.acquire(meta);
391 }
392
393 }
394
enforceRequestPermissions(CameraMetadata & metadata)395 bool ProCamera2Client::enforceRequestPermissions(CameraMetadata& metadata) {
396
397 const int pid = IPCThreadState::self()->getCallingPid();
398 const int selfPid = getpid();
399 camera_metadata_entry_t entry;
400
401 /**
402 * Mixin default important security values
403 * - android.led.transmit = defaulted ON
404 */
405 CameraMetadata staticInfo = mDevice->info();
406 entry = staticInfo.find(ANDROID_LED_AVAILABLE_LEDS);
407 for(size_t i = 0; i < entry.count; ++i) {
408 uint8_t led = entry.data.u8[i];
409
410 switch(led) {
411 case ANDROID_LED_AVAILABLE_LEDS_TRANSMIT: {
412 uint8_t transmitDefault = ANDROID_LED_TRANSMIT_ON;
413 if (!metadata.exists(ANDROID_LED_TRANSMIT)) {
414 metadata.update(ANDROID_LED_TRANSMIT,
415 &transmitDefault, 1);
416 }
417 break;
418 }
419 }
420 }
421
422 // We can do anything!
423 if (pid == selfPid) {
424 return true;
425 }
426
427 /**
428 * Permission check special fields in the request
429 * - android.led.transmit = android.permission.CAMERA_DISABLE_TRANSMIT
430 */
431 entry = metadata.find(ANDROID_LED_TRANSMIT);
432 if (entry.count > 0 && entry.data.u8[0] != ANDROID_LED_TRANSMIT_ON) {
433 String16 permissionString =
434 String16("android.permission.CAMERA_DISABLE_TRANSMIT_LED");
435 if (!checkCallingPermission(permissionString)) {
436 const int uid = IPCThreadState::self()->getCallingUid();
437 ALOGE("Permission Denial: "
438 "can't disable transmit LED pid=%d, uid=%d", pid, uid);
439 return false;
440 }
441 }
442
443 return true;
444 }
445
446 } // namespace android
447