blob: a02381d77ebd51713a79e91f92401456ae8f6733 [file] [log] [blame]
Igor Murashkine7ee7632013-06-11 18:10:18 -07001/*
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 "CameraDeviceClient"
18#define ATRACE_TAG ATRACE_TAG_CAMERA
19// #define LOG_NDEBUG 0
20
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070021#include <cutils/properties.h>
Igor Murashkine7ee7632013-06-11 18:10:18 -070022#include <utils/Log.h>
23#include <utils/Trace.h>
Igor Murashkine7ee7632013-06-11 18:10:18 -070024#include <gui/Surface.h>
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070025#include <camera/camera2/CaptureRequest.h>
26
27#include "common/CameraDeviceBase.h"
28#include "api2/CameraDeviceClient.h"
29
30
Igor Murashkine7ee7632013-06-11 18:10:18 -070031
32namespace android {
33using namespace camera2;
34
35CameraDeviceClientBase::CameraDeviceClientBase(
36 const sp<CameraService>& cameraService,
37 const sp<ICameraDeviceCallbacks>& remoteCallback,
38 const String16& clientPackageName,
39 int cameraId,
40 int cameraFacing,
41 int clientPid,
42 uid_t clientUid,
43 int servicePid) :
44 BasicClient(cameraService, remoteCallback->asBinder(), clientPackageName,
45 cameraId, cameraFacing, clientPid, clientUid, servicePid),
46 mRemoteCallback(remoteCallback) {
47}
Igor Murashkine7ee7632013-06-11 18:10:18 -070048
49// Interface used by CameraService
50
51CameraDeviceClient::CameraDeviceClient(const sp<CameraService>& cameraService,
52 const sp<ICameraDeviceCallbacks>& remoteCallback,
53 const String16& clientPackageName,
54 int cameraId,
55 int cameraFacing,
56 int clientPid,
57 uid_t clientUid,
58 int servicePid) :
59 Camera2ClientBase(cameraService, remoteCallback, clientPackageName,
60 cameraId, cameraFacing, clientPid, clientUid, servicePid),
61 mRequestIdCounter(0) {
62
63 ATRACE_CALL();
64 ALOGI("CameraDeviceClient %d: Opened", cameraId);
65}
66
67status_t CameraDeviceClient::initialize(camera_module_t *module)
68{
69 ATRACE_CALL();
70 status_t res;
71
72 res = Camera2ClientBase::initialize(module);
73 if (res != OK) {
74 return res;
75 }
76
77 String8 threadName;
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070078 mFrameProcessor = new FrameProcessorBase(mDevice);
Igor Murashkine7ee7632013-06-11 18:10:18 -070079 threadName = String8::format("CDU-%d-FrameProc", mCameraId);
80 mFrameProcessor->run(threadName.string());
81
82 mFrameProcessor->registerListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
83 FRAME_PROCESSOR_LISTENER_MAX_ID,
Eino-Ville Talvala184dfe42013-11-07 15:13:16 -080084 /*listener*/this,
85 /*quirkSendPartials*/true);
Igor Murashkine7ee7632013-06-11 18:10:18 -070086
87 return OK;
88}
89
90CameraDeviceClient::~CameraDeviceClient() {
91}
92
93status_t CameraDeviceClient::submitRequest(sp<CaptureRequest> request,
94 bool streaming) {
95 ATRACE_CALL();
96 ALOGV("%s", __FUNCTION__);
97
98 status_t res;
99
100 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
101
102 Mutex::Autolock icl(mBinderSerializationLock);
103
104 if (!mDevice.get()) return DEAD_OBJECT;
105
106 if (request == 0) {
107 ALOGE("%s: Camera %d: Sent null request. Rejecting request.",
108 __FUNCTION__, mCameraId);
109 return BAD_VALUE;
110 }
111
112 CameraMetadata metadata(request->mMetadata);
113
114 if (metadata.isEmpty()) {
115 ALOGE("%s: Camera %d: Sent empty metadata packet. Rejecting request.",
116 __FUNCTION__, mCameraId);
117 return BAD_VALUE;
118 } else if (request->mSurfaceList.size() == 0) {
119 ALOGE("%s: Camera %d: Requests must have at least one surface target. "
120 "Rejecting request.", __FUNCTION__, mCameraId);
121 return BAD_VALUE;
122 }
123
124 if (!enforceRequestPermissions(metadata)) {
125 // Callee logs
126 return PERMISSION_DENIED;
127 }
128
129 /**
130 * Write in the output stream IDs which we calculate from
131 * the capture request's list of surface targets
132 */
Zhijun Hed1d64672013-09-06 15:00:01 -0700133 Vector<int32_t> outputStreamIds;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700134 outputStreamIds.setCapacity(request->mSurfaceList.size());
135 for (size_t i = 0; i < request->mSurfaceList.size(); ++i) {
136 sp<Surface> surface = request->mSurfaceList[i];
137
138 if (surface == 0) continue;
139
140 sp<IGraphicBufferProducer> gbp = surface->getIGraphicBufferProducer();
141 int idx = mStreamMap.indexOfKey(gbp->asBinder());
142
143 // Trying to submit request with surface that wasn't created
144 if (idx == NAME_NOT_FOUND) {
145 ALOGE("%s: Camera %d: Tried to submit a request with a surface that"
146 " we have not called createStream on",
147 __FUNCTION__, mCameraId);
148 return BAD_VALUE;
149 }
150
151 int streamId = mStreamMap.valueAt(idx);
152 outputStreamIds.push_back(streamId);
153 ALOGV("%s: Camera %d: Appending output stream %d to request",
154 __FUNCTION__, mCameraId, streamId);
155 }
156
157 metadata.update(ANDROID_REQUEST_OUTPUT_STREAMS, &outputStreamIds[0],
158 outputStreamIds.size());
159
Igor Murashkine7ee7632013-06-11 18:10:18 -0700160 int32_t requestId = mRequestIdCounter++;
161 metadata.update(ANDROID_REQUEST_ID, &requestId, /*size*/1);
Jianing Wei90e59c92014-03-12 18:29:36 -0700162 ALOGV("%s: Camera %d: Creating request with ID %d",
Igor Murashkine7ee7632013-06-11 18:10:18 -0700163 __FUNCTION__, mCameraId, requestId);
164
165 if (streaming) {
166 res = mDevice->setStreamingRequest(metadata);
167 if (res != OK) {
168 ALOGE("%s: Camera %d: Got error %d after trying to set streaming "
169 "request", __FUNCTION__, mCameraId, res);
170 } else {
Zhijun Hefe0799e2013-07-19 13:18:43 -0700171 mStreamingRequestList.push_back(requestId);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700172 }
173 } else {
174 res = mDevice->capture(metadata);
175 if (res != OK) {
176 ALOGE("%s: Camera %d: Got error %d after trying to set capture",
177 __FUNCTION__, mCameraId, res);
178 }
179 }
180
181 ALOGV("%s: Camera %d: End of function", __FUNCTION__, mCameraId);
182 if (res == OK) {
183 return requestId;
184 }
185
186 return res;
187}
188
Jianing Wei90e59c92014-03-12 18:29:36 -0700189status_t CameraDeviceClient::submitRequestList(List<sp<CaptureRequest> > requests,
190 bool streaming) {
191 ATRACE_CALL();
192 ALOGV("%s-start of function", __FUNCTION__);
193
194 status_t res;
195 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
196
197 Mutex::Autolock icl(mBinderSerializationLock);
198
199 if (!mDevice.get()) return DEAD_OBJECT;
200
201 if (requests.empty()) {
202 ALOGE("%s: Camera %d: Sent null request. Rejecting request.",
203 __FUNCTION__, mCameraId);
204 return BAD_VALUE;
205 }
206
207 List<const CameraMetadata> metadataRequestList;
208 int32_t requestId = mRequestIdCounter;
209 uint32_t loopCounter = 0;
210
211 for (List<sp<CaptureRequest> >::iterator it = requests.begin(); it != requests.end(); ++it) {
212 sp<CaptureRequest> request = *it;
213 if (request == 0) {
214 ALOGE("%s: Camera %d: Sent null request.",
215 __FUNCTION__, mCameraId);
216 return BAD_VALUE;
217 }
218
219 CameraMetadata metadata(request->mMetadata);
220 if (metadata.isEmpty()) {
221 ALOGE("%s: Camera %d: Sent empty metadata packet. Rejecting request.",
222 __FUNCTION__, mCameraId);
223 return BAD_VALUE;
224 } else if (request->mSurfaceList.isEmpty()) {
225 ALOGE("%s: Camera %d: Requests must have at least one surface target. "
226 "Rejecting request.", __FUNCTION__, mCameraId);
227 return BAD_VALUE;
228 }
229
230 if (!enforceRequestPermissions(metadata)) {
231 // Callee logs
232 return PERMISSION_DENIED;
233 }
234
235 /**
236 * Write in the output stream IDs which we calculate from
237 * the capture request's list of surface targets
238 */
239 Vector<int32_t> outputStreamIds;
240 outputStreamIds.setCapacity(request->mSurfaceList.size());
241 for (Vector<sp<Surface> >::iterator surfaceIt = 0;
242 surfaceIt != request->mSurfaceList.end(); ++surfaceIt) {
243 sp<Surface> surface = *surfaceIt;
244 if (surface == 0) continue;
245
246 sp<IGraphicBufferProducer> gbp = surface->getIGraphicBufferProducer();
247 int idx = mStreamMap.indexOfKey(gbp->asBinder());
248
249 // Trying to submit request with surface that wasn't created
250 if (idx == NAME_NOT_FOUND) {
251 ALOGE("%s: Camera %d: Tried to submit a request with a surface that"
252 " we have not called createStream on",
253 __FUNCTION__, mCameraId);
254 return BAD_VALUE;
255 }
256
257 int streamId = mStreamMap.valueAt(idx);
258 outputStreamIds.push_back(streamId);
259 ALOGV("%s: Camera %d: Appending output stream %d to request",
260 __FUNCTION__, mCameraId, streamId);
261 }
262
263 metadata.update(ANDROID_REQUEST_OUTPUT_STREAMS, &outputStreamIds[0],
264 outputStreamIds.size());
265
266 metadata.update(ANDROID_REQUEST_ID, &requestId, /*size*/1);
267 loopCounter++; // loopCounter starts from 1
268 ALOGV("%s: Camera %d: Creating request with ID %d (%d of %d)",
269 __FUNCTION__, mCameraId, requestId, loopCounter, requests.size());
270
271 metadataRequestList.push_back(metadata);
272 }
273 mRequestIdCounter++;
274
275 if (streaming) {
276 res = mDevice->setStreamingRequestList(metadataRequestList);
277 if (res != OK) {
278 ALOGE("%s: Camera %d: Got error %d after trying to set streaming "
279 "request", __FUNCTION__, mCameraId, res);
280 } else {
281 mStreamingRequestList.push_back(requestId);
282 }
283 } else {
284 res = mDevice->captureList(metadataRequestList);
285 if (res != OK) {
286 ALOGE("%s: Camera %d: Got error %d after trying to set capture",
287 __FUNCTION__, mCameraId, res);
288 }
289 }
290
291 ALOGV("%s: Camera %d: End of function", __FUNCTION__, mCameraId);
292 if (res == OK) {
293 return requestId;
294 }
295
296 return res;
297}
298
Igor Murashkine7ee7632013-06-11 18:10:18 -0700299status_t CameraDeviceClient::cancelRequest(int requestId) {
300 ATRACE_CALL();
301 ALOGV("%s, requestId = %d", __FUNCTION__, requestId);
302
303 status_t res;
304
305 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
306
307 Mutex::Autolock icl(mBinderSerializationLock);
308
309 if (!mDevice.get()) return DEAD_OBJECT;
310
311 Vector<int>::iterator it, end;
312 for (it = mStreamingRequestList.begin(), end = mStreamingRequestList.end();
313 it != end; ++it) {
314 if (*it == requestId) {
315 break;
316 }
317 }
318
319 if (it == end) {
320 ALOGE("%s: Camera%d: Did not find request id %d in list of streaming "
321 "requests", __FUNCTION__, mCameraId, requestId);
322 return BAD_VALUE;
323 }
324
325 res = mDevice->clearStreamingRequest();
326
327 if (res == OK) {
328 ALOGV("%s: Camera %d: Successfully cleared streaming request",
329 __FUNCTION__, mCameraId);
330 mStreamingRequestList.erase(it);
331 }
332
333 return res;
334}
335
336status_t CameraDeviceClient::deleteStream(int streamId) {
337 ATRACE_CALL();
338 ALOGV("%s (streamId = 0x%x)", __FUNCTION__, streamId);
339
340 status_t res;
341 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
342
343 Mutex::Autolock icl(mBinderSerializationLock);
344
345 if (!mDevice.get()) return DEAD_OBJECT;
346
347 // Guard against trying to delete non-created streams
348 ssize_t index = NAME_NOT_FOUND;
349 for (size_t i = 0; i < mStreamMap.size(); ++i) {
350 if (streamId == mStreamMap.valueAt(i)) {
351 index = i;
352 break;
353 }
354 }
355
356 if (index == NAME_NOT_FOUND) {
357 ALOGW("%s: Camera %d: Invalid stream ID (%d) specified, no stream "
358 "created yet", __FUNCTION__, mCameraId, streamId);
359 return BAD_VALUE;
360 }
361
362 // Also returns BAD_VALUE if stream ID was not valid
363 res = mDevice->deleteStream(streamId);
364
365 if (res == BAD_VALUE) {
366 ALOGE("%s: Camera %d: Unexpected BAD_VALUE when deleting stream, but we"
367 " already checked and the stream ID (%d) should be valid.",
368 __FUNCTION__, mCameraId, streamId);
369 } else if (res == OK) {
370 mStreamMap.removeItemsAt(index);
371
372 ALOGV("%s: Camera %d: Successfully deleted stream ID (%d)",
373 __FUNCTION__, mCameraId, streamId);
374 }
375
376 return res;
377}
378
379status_t CameraDeviceClient::createStream(int width, int height, int format,
380 const sp<IGraphicBufferProducer>& bufferProducer)
381{
382 ATRACE_CALL();
383 ALOGV("%s (w = %d, h = %d, f = 0x%x)", __FUNCTION__, width, height, format);
384
385 status_t res;
386 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
387
388 Mutex::Autolock icl(mBinderSerializationLock);
389
390 if (!mDevice.get()) return DEAD_OBJECT;
391
392 // Don't create multiple streams for the same target surface
393 {
394 ssize_t index = mStreamMap.indexOfKey(bufferProducer->asBinder());
395 if (index != NAME_NOT_FOUND) {
396 ALOGW("%s: Camera %d: Buffer producer already has a stream for it "
397 "(ID %d)",
398 __FUNCTION__, mCameraId, index);
399 return ALREADY_EXISTS;
400 }
401 }
402
Eino-Ville Talvala1da3b602013-09-26 15:28:55 -0700403 // HACK b/10949105
404 // Query consumer usage bits to set async operation mode for
405 // GLConsumer using controlledByApp parameter.
406 bool useAsync = false;
407 int32_t consumerUsage;
408 if ((res = bufferProducer->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS,
409 &consumerUsage)) != OK) {
410 ALOGE("%s: Camera %d: Failed to query consumer usage", __FUNCTION__,
411 mCameraId);
412 return res;
413 }
414 if (consumerUsage & GraphicBuffer::USAGE_HW_TEXTURE) {
415 ALOGW("%s: Camera %d: Forcing asynchronous mode for stream",
416 __FUNCTION__, mCameraId);
417 useAsync = true;
418 }
419
Igor Murashkine7ee7632013-06-11 18:10:18 -0700420 sp<IBinder> binder;
421 sp<ANativeWindow> anw;
422 if (bufferProducer != 0) {
423 binder = bufferProducer->asBinder();
Eino-Ville Talvala1da3b602013-09-26 15:28:55 -0700424 anw = new Surface(bufferProducer, useAsync);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700425 }
426
427 // TODO: remove w,h,f since we are ignoring them
428
429 if ((res = anw->query(anw.get(), NATIVE_WINDOW_WIDTH, &width)) != OK) {
430 ALOGE("%s: Camera %d: Failed to query Surface width", __FUNCTION__,
431 mCameraId);
432 return res;
433 }
434 if ((res = anw->query(anw.get(), NATIVE_WINDOW_HEIGHT, &height)) != OK) {
435 ALOGE("%s: Camera %d: Failed to query Surface height", __FUNCTION__,
436 mCameraId);
437 return res;
438 }
439 if ((res = anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &format)) != OK) {
440 ALOGE("%s: Camera %d: Failed to query Surface format", __FUNCTION__,
441 mCameraId);
442 return res;
443 }
444
445 // FIXME: remove this override since the default format should be
446 // IMPLEMENTATION_DEFINED. b/9487482
Igor Murashkin15811012013-07-29 12:25:59 -0700447 if (format >= HAL_PIXEL_FORMAT_RGBA_8888 &&
448 format <= HAL_PIXEL_FORMAT_BGRA_8888) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700449 ALOGW("%s: Camera %d: Overriding format 0x%x to IMPLEMENTATION_DEFINED",
450 __FUNCTION__, mCameraId, format);
451 format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
452 }
453
454 // TODO: add startConfigure/stopConfigure call to CameraDeviceBase
455 // this will make it so Camera3Device doesn't call configure_streams
456 // after each call, but only once we are done with all.
457
458 int streamId = -1;
Eino-Ville Talvalac7ba4a52013-07-01 09:23:55 -0700459 if (format == HAL_PIXEL_FORMAT_BLOB) {
460 // JPEG buffers need to be sized for maximum possible compressed size
461 CameraMetadata staticInfo = mDevice->info();
462 camera_metadata_entry_t entry = staticInfo.find(ANDROID_JPEG_MAX_SIZE);
463 if (entry.count == 0) {
464 ALOGE("%s: Camera %d: Can't find maximum JPEG size in "
465 "static metadata!", __FUNCTION__, mCameraId);
466 return INVALID_OPERATION;
467 }
468 int32_t maxJpegSize = entry.data.i32[0];
469 res = mDevice->createStream(anw, width, height, format, maxJpegSize,
470 &streamId);
471 } else {
472 // All other streams are a known size
473 res = mDevice->createStream(anw, width, height, format, /*size*/0,
474 &streamId);
475 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700476
477 if (res == OK) {
478 mStreamMap.add(bufferProducer->asBinder(), streamId);
479
480 ALOGV("%s: Camera %d: Successfully created a new stream ID %d",
481 __FUNCTION__, mCameraId, streamId);
Igor Murashkinf8b2a6f2013-09-17 17:03:28 -0700482
483 /**
484 * Set the stream transform flags to automatically
485 * rotate the camera stream for preview use cases.
486 */
487 int32_t transform = 0;
488 res = getRotationTransformLocked(&transform);
489
490 if (res != OK) {
491 // Error logged by getRotationTransformLocked.
492 return res;
493 }
494
495 res = mDevice->setStreamTransform(streamId, transform);
496 if (res != OK) {
497 ALOGE("%s: Failed to set stream transform (stream id %d)",
498 __FUNCTION__, streamId);
499 return res;
500 }
501
Igor Murashkine7ee7632013-06-11 18:10:18 -0700502 return streamId;
503 }
504
505 return res;
506}
507
508// Create a request object from a template.
509status_t CameraDeviceClient::createDefaultRequest(int templateId,
510 /*out*/
511 CameraMetadata* request)
512{
513 ATRACE_CALL();
514 ALOGV("%s (templateId = 0x%x)", __FUNCTION__, templateId);
515
516 status_t res;
517 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
518
519 Mutex::Autolock icl(mBinderSerializationLock);
520
521 if (!mDevice.get()) return DEAD_OBJECT;
522
523 CameraMetadata metadata;
524 if ( (res = mDevice->createDefaultRequest(templateId, &metadata) ) == OK &&
525 request != NULL) {
526
527 request->swap(metadata);
528 }
529
530 return res;
531}
532
Igor Murashkin099b4572013-07-12 17:52:16 -0700533status_t CameraDeviceClient::getCameraInfo(/*out*/CameraMetadata* info)
Igor Murashkine7ee7632013-06-11 18:10:18 -0700534{
535 ATRACE_CALL();
536 ALOGV("%s", __FUNCTION__);
537
538 status_t res = OK;
539
Igor Murashkine7ee7632013-06-11 18:10:18 -0700540 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
541
542 Mutex::Autolock icl(mBinderSerializationLock);
543
544 if (!mDevice.get()) return DEAD_OBJECT;
545
Igor Murashkin099b4572013-07-12 17:52:16 -0700546 if (info != NULL) {
547 *info = mDevice->info(); // static camera metadata
548 // TODO: merge with device-specific camera metadata
549 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700550
551 return res;
552}
553
Zhijun He2ab500c2013-07-23 08:02:53 -0700554status_t CameraDeviceClient::waitUntilIdle()
555{
556 ATRACE_CALL();
557 ALOGV("%s", __FUNCTION__);
558
559 status_t res = OK;
560 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
561
562 Mutex::Autolock icl(mBinderSerializationLock);
563
564 if (!mDevice.get()) return DEAD_OBJECT;
565
566 // FIXME: Also need check repeating burst.
567 if (!mStreamingRequestList.isEmpty()) {
568 ALOGE("%s: Camera %d: Try to waitUntilIdle when there are active streaming requests",
569 __FUNCTION__, mCameraId);
570 return INVALID_OPERATION;
571 }
572 res = mDevice->waitUntilDrained();
573 ALOGV("%s Done", __FUNCTION__);
574
575 return res;
576}
577
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700578status_t CameraDeviceClient::flush() {
579 ATRACE_CALL();
580 ALOGV("%s", __FUNCTION__);
581
582 status_t res = OK;
583 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
584
585 Mutex::Autolock icl(mBinderSerializationLock);
586
587 if (!mDevice.get()) return DEAD_OBJECT;
588
589 return mDevice->flush();
590}
591
Igor Murashkine7ee7632013-06-11 18:10:18 -0700592status_t CameraDeviceClient::dump(int fd, const Vector<String16>& args) {
593 String8 result;
594 result.appendFormat("CameraDeviceClient[%d] (%p) PID: %d, dump:\n",
595 mCameraId,
596 getRemoteCallback()->asBinder().get(),
597 mClientPid);
598 result.append(" State: ");
599
600 // TODO: print dynamic/request section from most recent requests
601 mFrameProcessor->dump(fd, args);
602
603 return dumpDevice(fd, args);
604}
605
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700606
607void CameraDeviceClient::notifyError() {
608 // Thread safe. Don't bother locking.
609 sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
610
611 if (remoteCb != 0) {
612 remoteCb->onDeviceError(ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE);
613 }
614}
615
616void CameraDeviceClient::notifyIdle() {
617 // Thread safe. Don't bother locking.
618 sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
619
620 if (remoteCb != 0) {
621 remoteCb->onDeviceIdle();
622 }
623}
624
625void CameraDeviceClient::notifyShutter(int requestId,
626 nsecs_t timestamp) {
627 // Thread safe. Don't bother locking.
628 sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
629 if (remoteCb != 0) {
630 remoteCb->onCaptureStarted(requestId, timestamp);
631 }
632}
633
Igor Murashkine7ee7632013-06-11 18:10:18 -0700634// TODO: refactor the code below this with IProCameraUser.
635// it's 100% copy-pasted, so lets not change it right now to make it easier.
636
637void CameraDeviceClient::detachDevice() {
638 if (mDevice == 0) return;
639
640 ALOGV("Camera %d: Stopping processors", mCameraId);
641
642 mFrameProcessor->removeListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
643 FRAME_PROCESSOR_LISTENER_MAX_ID,
644 /*listener*/this);
645 mFrameProcessor->requestExit();
646 ALOGV("Camera %d: Waiting for threads", mCameraId);
647 mFrameProcessor->join();
648 ALOGV("Camera %d: Disconnecting device", mCameraId);
649
650 // WORKAROUND: HAL refuses to disconnect while there's streams in flight
651 {
652 mDevice->clearStreamingRequest();
653
654 status_t code;
655 if ((code = mDevice->waitUntilDrained()) != OK) {
656 ALOGE("%s: waitUntilDrained failed with code 0x%x", __FUNCTION__,
657 code);
658 }
659 }
660
661 Camera2ClientBase::detachDevice();
662}
663
664/** Device-related methods */
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700665void CameraDeviceClient::onFrameAvailable(int32_t requestId,
666 const CameraMetadata& frame) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700667 ATRACE_CALL();
668 ALOGV("%s", __FUNCTION__);
669
Igor Murashkin4fb55c12013-08-29 17:43:01 -0700670 // Thread-safe. No lock necessary.
671 sp<ICameraDeviceCallbacks> remoteCb = mRemoteCallback;
672 if (remoteCb != NULL) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700673 ALOGV("%s: frame = %p ", __FUNCTION__, &frame);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700674 remoteCb->onResultReceived(requestId, frame);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700675 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700676}
677
678// TODO: move to Camera2ClientBase
679bool CameraDeviceClient::enforceRequestPermissions(CameraMetadata& metadata) {
680
681 const int pid = IPCThreadState::self()->getCallingPid();
682 const int selfPid = getpid();
683 camera_metadata_entry_t entry;
684
685 /**
686 * Mixin default important security values
687 * - android.led.transmit = defaulted ON
688 */
689 CameraMetadata staticInfo = mDevice->info();
690 entry = staticInfo.find(ANDROID_LED_AVAILABLE_LEDS);
691 for(size_t i = 0; i < entry.count; ++i) {
692 uint8_t led = entry.data.u8[i];
693
694 switch(led) {
695 case ANDROID_LED_AVAILABLE_LEDS_TRANSMIT: {
696 uint8_t transmitDefault = ANDROID_LED_TRANSMIT_ON;
697 if (!metadata.exists(ANDROID_LED_TRANSMIT)) {
698 metadata.update(ANDROID_LED_TRANSMIT,
699 &transmitDefault, 1);
700 }
701 break;
702 }
703 }
704 }
705
706 // We can do anything!
707 if (pid == selfPid) {
708 return true;
709 }
710
711 /**
712 * Permission check special fields in the request
713 * - android.led.transmit = android.permission.CAMERA_DISABLE_TRANSMIT
714 */
715 entry = metadata.find(ANDROID_LED_TRANSMIT);
716 if (entry.count > 0 && entry.data.u8[0] != ANDROID_LED_TRANSMIT_ON) {
717 String16 permissionString =
718 String16("android.permission.CAMERA_DISABLE_TRANSMIT_LED");
719 if (!checkCallingPermission(permissionString)) {
720 const int uid = IPCThreadState::self()->getCallingUid();
721 ALOGE("Permission Denial: "
722 "can't disable transmit LED pid=%d, uid=%d", pid, uid);
723 return false;
724 }
725 }
726
727 return true;
728}
729
Igor Murashkinf8b2a6f2013-09-17 17:03:28 -0700730status_t CameraDeviceClient::getRotationTransformLocked(int32_t* transform) {
731 ALOGV("%s: begin", __FUNCTION__);
732
733 if (transform == NULL) {
734 ALOGW("%s: null transform", __FUNCTION__);
735 return BAD_VALUE;
736 }
737
738 *transform = 0;
739
740 const CameraMetadata& staticInfo = mDevice->info();
741 camera_metadata_ro_entry_t entry = staticInfo.find(ANDROID_SENSOR_ORIENTATION);
742 if (entry.count == 0) {
743 ALOGE("%s: Camera %d: Can't find android.sensor.orientation in "
744 "static metadata!", __FUNCTION__, mCameraId);
745 return INVALID_OPERATION;
746 }
747
Zhijun Hef0b70262013-12-26 10:38:46 -0800748 camera_metadata_ro_entry_t entryFacing = staticInfo.find(ANDROID_LENS_FACING);
749 if (entry.count == 0) {
750 ALOGE("%s: Camera %d: Can't find android.lens.facing in "
751 "static metadata!", __FUNCTION__, mCameraId);
752 return INVALID_OPERATION;
753 }
754
Igor Murashkinf8b2a6f2013-09-17 17:03:28 -0700755 int32_t& flags = *transform;
756
Zhijun Hef0b70262013-12-26 10:38:46 -0800757 bool mirror = (entryFacing.data.u8[0] == ANDROID_LENS_FACING_FRONT);
Igor Murashkinf8b2a6f2013-09-17 17:03:28 -0700758 int orientation = entry.data.i32[0];
Zhijun Hef0b70262013-12-26 10:38:46 -0800759 if (!mirror) {
760 switch (orientation) {
761 case 0:
762 flags = 0;
763 break;
764 case 90:
765 flags = NATIVE_WINDOW_TRANSFORM_ROT_90;
766 break;
767 case 180:
768 flags = NATIVE_WINDOW_TRANSFORM_ROT_180;
769 break;
770 case 270:
771 flags = NATIVE_WINDOW_TRANSFORM_ROT_270;
772 break;
773 default:
774 ALOGE("%s: Invalid HAL android.sensor.orientation value: %d",
775 __FUNCTION__, orientation);
776 return INVALID_OPERATION;
777 }
778 } else {
779 switch (orientation) {
780 case 0:
781 flags = HAL_TRANSFORM_FLIP_H;
782 break;
783 case 90:
784 flags = HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
785 break;
786 case 180:
787 flags = HAL_TRANSFORM_FLIP_V;
788 break;
789 case 270:
790 flags = HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
791 break;
792 default:
793 ALOGE("%s: Invalid HAL android.sensor.orientation value: %d",
794 __FUNCTION__, orientation);
795 return INVALID_OPERATION;
796 }
797
Igor Murashkinf8b2a6f2013-09-17 17:03:28 -0700798 }
799
800 /**
801 * This magic flag makes surfaceflinger un-rotate the buffers
802 * to counter the extra global device UI rotation whenever the user
803 * physically rotates the device.
804 *
805 * By doing this, the camera buffer always ends up aligned
806 * with the physical camera for a "see through" effect.
807 *
808 * In essence, the buffer only gets rotated during preview use-cases.
809 * The user is still responsible to re-create streams of the proper
810 * aspect ratio, or the preview will end up looking non-uniformly
811 * stretched.
812 */
813 flags |= NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY;
814
815 ALOGV("%s: final transform = 0x%x", __FUNCTION__, flags);
816
817 return OK;
818}
819
Igor Murashkine7ee7632013-06-11 18:10:18 -0700820} // namespace android