blob: de42cee0c380167284862287b3c16a76310efad3 [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
Jianing Weicb0652e2014-03-12 18:29:36 -070019//#define LOG_NDEBUG 0
Igor Murashkine7ee7632013-06-11 18:10:18 -070020
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,
Zhijun He25a0aef2014-06-25 11:40:02 -070085 /*sendPartials*/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,
Jianing Weicb0652e2014-03-12 18:29:36 -070094 bool streaming,
95 /*out*/
96 int64_t* lastFrameNumber) {
97 List<sp<CaptureRequest> > requestList;
98 requestList.push_back(request);
99 return submitRequestList(requestList, streaming, lastFrameNumber);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700100}
101
Jianing Wei90e59c92014-03-12 18:29:36 -0700102status_t CameraDeviceClient::submitRequestList(List<sp<CaptureRequest> > requests,
Jianing Weicb0652e2014-03-12 18:29:36 -0700103 bool streaming, int64_t* lastFrameNumber) {
Jianing Wei90e59c92014-03-12 18:29:36 -0700104 ATRACE_CALL();
Mark Salyzyn50468412014-06-18 16:33:43 -0700105 ALOGV("%s-start of function. Request list size %zu", __FUNCTION__, requests.size());
Jianing Wei90e59c92014-03-12 18:29:36 -0700106
107 status_t res;
108 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
109
110 Mutex::Autolock icl(mBinderSerializationLock);
111
112 if (!mDevice.get()) return DEAD_OBJECT;
113
114 if (requests.empty()) {
115 ALOGE("%s: Camera %d: Sent null request. Rejecting request.",
116 __FUNCTION__, mCameraId);
117 return BAD_VALUE;
118 }
119
120 List<const CameraMetadata> metadataRequestList;
121 int32_t requestId = mRequestIdCounter;
122 uint32_t loopCounter = 0;
123
124 for (List<sp<CaptureRequest> >::iterator it = requests.begin(); it != requests.end(); ++it) {
125 sp<CaptureRequest> request = *it;
126 if (request == 0) {
127 ALOGE("%s: Camera %d: Sent null request.",
128 __FUNCTION__, mCameraId);
129 return BAD_VALUE;
130 }
131
132 CameraMetadata metadata(request->mMetadata);
133 if (metadata.isEmpty()) {
134 ALOGE("%s: Camera %d: Sent empty metadata packet. Rejecting request.",
135 __FUNCTION__, mCameraId);
136 return BAD_VALUE;
137 } else if (request->mSurfaceList.isEmpty()) {
138 ALOGE("%s: Camera %d: Requests must have at least one surface target. "
139 "Rejecting request.", __FUNCTION__, mCameraId);
140 return BAD_VALUE;
141 }
142
143 if (!enforceRequestPermissions(metadata)) {
144 // Callee logs
145 return PERMISSION_DENIED;
146 }
147
148 /**
149 * Write in the output stream IDs which we calculate from
150 * the capture request's list of surface targets
151 */
152 Vector<int32_t> outputStreamIds;
153 outputStreamIds.setCapacity(request->mSurfaceList.size());
Jianing Weicb0652e2014-03-12 18:29:36 -0700154 for (size_t i = 0; i < request->mSurfaceList.size(); ++i) {
155 sp<Surface> surface = request->mSurfaceList[i];
Jianing Wei90e59c92014-03-12 18:29:36 -0700156 if (surface == 0) continue;
157
158 sp<IGraphicBufferProducer> gbp = surface->getIGraphicBufferProducer();
159 int idx = mStreamMap.indexOfKey(gbp->asBinder());
160
161 // Trying to submit request with surface that wasn't created
162 if (idx == NAME_NOT_FOUND) {
163 ALOGE("%s: Camera %d: Tried to submit a request with a surface that"
164 " we have not called createStream on",
165 __FUNCTION__, mCameraId);
166 return BAD_VALUE;
167 }
168
169 int streamId = mStreamMap.valueAt(idx);
170 outputStreamIds.push_back(streamId);
171 ALOGV("%s: Camera %d: Appending output stream %d to request",
172 __FUNCTION__, mCameraId, streamId);
173 }
174
175 metadata.update(ANDROID_REQUEST_OUTPUT_STREAMS, &outputStreamIds[0],
176 outputStreamIds.size());
177
178 metadata.update(ANDROID_REQUEST_ID, &requestId, /*size*/1);
179 loopCounter++; // loopCounter starts from 1
Mark Salyzyn50468412014-06-18 16:33:43 -0700180 ALOGV("%s: Camera %d: Creating request with ID %d (%d of %zu)",
Jianing Wei90e59c92014-03-12 18:29:36 -0700181 __FUNCTION__, mCameraId, requestId, loopCounter, requests.size());
182
183 metadataRequestList.push_back(metadata);
184 }
185 mRequestIdCounter++;
186
187 if (streaming) {
Jianing Weicb0652e2014-03-12 18:29:36 -0700188 res = mDevice->setStreamingRequestList(metadataRequestList, lastFrameNumber);
Jianing Wei90e59c92014-03-12 18:29:36 -0700189 if (res != OK) {
190 ALOGE("%s: Camera %d: Got error %d after trying to set streaming "
191 "request", __FUNCTION__, mCameraId, res);
192 } else {
193 mStreamingRequestList.push_back(requestId);
194 }
195 } else {
Jianing Weicb0652e2014-03-12 18:29:36 -0700196 res = mDevice->captureList(metadataRequestList, lastFrameNumber);
Jianing Wei90e59c92014-03-12 18:29:36 -0700197 if (res != OK) {
198 ALOGE("%s: Camera %d: Got error %d after trying to set capture",
199 __FUNCTION__, mCameraId, res);
200 }
Jianing Weicb0652e2014-03-12 18:29:36 -0700201 ALOGV("%s: requestId = %d ", __FUNCTION__, requestId);
Jianing Wei90e59c92014-03-12 18:29:36 -0700202 }
203
204 ALOGV("%s: Camera %d: End of function", __FUNCTION__, mCameraId);
205 if (res == OK) {
206 return requestId;
207 }
208
209 return res;
210}
211
Jianing Weicb0652e2014-03-12 18:29:36 -0700212status_t CameraDeviceClient::cancelRequest(int requestId, int64_t* lastFrameNumber) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700213 ATRACE_CALL();
214 ALOGV("%s, requestId = %d", __FUNCTION__, requestId);
215
216 status_t res;
217
218 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
219
220 Mutex::Autolock icl(mBinderSerializationLock);
221
222 if (!mDevice.get()) return DEAD_OBJECT;
223
224 Vector<int>::iterator it, end;
225 for (it = mStreamingRequestList.begin(), end = mStreamingRequestList.end();
226 it != end; ++it) {
227 if (*it == requestId) {
228 break;
229 }
230 }
231
232 if (it == end) {
233 ALOGE("%s: Camera%d: Did not find request id %d in list of streaming "
234 "requests", __FUNCTION__, mCameraId, requestId);
235 return BAD_VALUE;
236 }
237
Jianing Weicb0652e2014-03-12 18:29:36 -0700238 res = mDevice->clearStreamingRequest(lastFrameNumber);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700239
240 if (res == OK) {
241 ALOGV("%s: Camera %d: Successfully cleared streaming request",
242 __FUNCTION__, mCameraId);
243 mStreamingRequestList.erase(it);
244 }
245
246 return res;
247}
248
Ruben Brunkb2119af2014-05-09 19:57:56 -0700249status_t CameraDeviceClient::beginConfigure() {
250 // TODO: Implement this.
251 ALOGE("%s: Not implemented yet.", __FUNCTION__);
252 return OK;
253}
254
255status_t CameraDeviceClient::endConfigure() {
256 // TODO: Implement this.
257 ALOGE("%s: Not implemented yet.", __FUNCTION__);
258 return OK;
259}
260
Igor Murashkine7ee7632013-06-11 18:10:18 -0700261status_t CameraDeviceClient::deleteStream(int streamId) {
262 ATRACE_CALL();
263 ALOGV("%s (streamId = 0x%x)", __FUNCTION__, streamId);
264
265 status_t res;
266 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
267
268 Mutex::Autolock icl(mBinderSerializationLock);
269
270 if (!mDevice.get()) return DEAD_OBJECT;
271
272 // Guard against trying to delete non-created streams
273 ssize_t index = NAME_NOT_FOUND;
274 for (size_t i = 0; i < mStreamMap.size(); ++i) {
275 if (streamId == mStreamMap.valueAt(i)) {
276 index = i;
277 break;
278 }
279 }
280
281 if (index == NAME_NOT_FOUND) {
282 ALOGW("%s: Camera %d: Invalid stream ID (%d) specified, no stream "
283 "created yet", __FUNCTION__, mCameraId, streamId);
284 return BAD_VALUE;
285 }
286
287 // Also returns BAD_VALUE if stream ID was not valid
288 res = mDevice->deleteStream(streamId);
289
290 if (res == BAD_VALUE) {
291 ALOGE("%s: Camera %d: Unexpected BAD_VALUE when deleting stream, but we"
292 " already checked and the stream ID (%d) should be valid.",
293 __FUNCTION__, mCameraId, streamId);
294 } else if (res == OK) {
295 mStreamMap.removeItemsAt(index);
296
Igor Murashkine7ee7632013-06-11 18:10:18 -0700297 }
298
299 return res;
300}
301
302status_t CameraDeviceClient::createStream(int width, int height, int format,
303 const sp<IGraphicBufferProducer>& bufferProducer)
304{
305 ATRACE_CALL();
306 ALOGV("%s (w = %d, h = %d, f = 0x%x)", __FUNCTION__, width, height, format);
307
308 status_t res;
309 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
310
311 Mutex::Autolock icl(mBinderSerializationLock);
312
Yin-Chia Yeh89f14da2014-06-10 16:05:44 -0700313 if (bufferProducer == NULL) {
314 ALOGE("%s: bufferProducer must not be null", __FUNCTION__);
315 return BAD_VALUE;
316 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700317 if (!mDevice.get()) return DEAD_OBJECT;
318
319 // Don't create multiple streams for the same target surface
320 {
321 ssize_t index = mStreamMap.indexOfKey(bufferProducer->asBinder());
322 if (index != NAME_NOT_FOUND) {
323 ALOGW("%s: Camera %d: Buffer producer already has a stream for it "
Colin Crosse5729fa2014-03-21 15:04:25 -0700324 "(ID %zd)",
Igor Murashkine7ee7632013-06-11 18:10:18 -0700325 __FUNCTION__, mCameraId, index);
326 return ALREADY_EXISTS;
327 }
328 }
329
Eino-Ville Talvala1da3b602013-09-26 15:28:55 -0700330 // HACK b/10949105
331 // Query consumer usage bits to set async operation mode for
332 // GLConsumer using controlledByApp parameter.
333 bool useAsync = false;
334 int32_t consumerUsage;
335 if ((res = bufferProducer->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS,
336 &consumerUsage)) != OK) {
337 ALOGE("%s: Camera %d: Failed to query consumer usage", __FUNCTION__,
338 mCameraId);
339 return res;
340 }
341 if (consumerUsage & GraphicBuffer::USAGE_HW_TEXTURE) {
342 ALOGW("%s: Camera %d: Forcing asynchronous mode for stream",
343 __FUNCTION__, mCameraId);
344 useAsync = true;
345 }
346
Igor Murashkine7ee7632013-06-11 18:10:18 -0700347 sp<IBinder> binder;
348 sp<ANativeWindow> anw;
349 if (bufferProducer != 0) {
350 binder = bufferProducer->asBinder();
Eino-Ville Talvala1da3b602013-09-26 15:28:55 -0700351 anw = new Surface(bufferProducer, useAsync);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700352 }
353
354 // TODO: remove w,h,f since we are ignoring them
355
356 if ((res = anw->query(anw.get(), NATIVE_WINDOW_WIDTH, &width)) != OK) {
357 ALOGE("%s: Camera %d: Failed to query Surface width", __FUNCTION__,
358 mCameraId);
359 return res;
360 }
361 if ((res = anw->query(anw.get(), NATIVE_WINDOW_HEIGHT, &height)) != OK) {
362 ALOGE("%s: Camera %d: Failed to query Surface height", __FUNCTION__,
363 mCameraId);
364 return res;
365 }
366 if ((res = anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &format)) != OK) {
367 ALOGE("%s: Camera %d: Failed to query Surface format", __FUNCTION__,
368 mCameraId);
369 return res;
370 }
371
372 // FIXME: remove this override since the default format should be
373 // IMPLEMENTATION_DEFINED. b/9487482
Igor Murashkin15811012013-07-29 12:25:59 -0700374 if (format >= HAL_PIXEL_FORMAT_RGBA_8888 &&
375 format <= HAL_PIXEL_FORMAT_BGRA_8888) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700376 ALOGW("%s: Camera %d: Overriding format 0x%x to IMPLEMENTATION_DEFINED",
377 __FUNCTION__, mCameraId, format);
378 format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
379 }
380
381 // TODO: add startConfigure/stopConfigure call to CameraDeviceBase
382 // this will make it so Camera3Device doesn't call configure_streams
383 // after each call, but only once we are done with all.
384
385 int streamId = -1;
Eino-Ville Talvalac7ba4a52013-07-01 09:23:55 -0700386 if (format == HAL_PIXEL_FORMAT_BLOB) {
387 // JPEG buffers need to be sized for maximum possible compressed size
388 CameraMetadata staticInfo = mDevice->info();
389 camera_metadata_entry_t entry = staticInfo.find(ANDROID_JPEG_MAX_SIZE);
390 if (entry.count == 0) {
391 ALOGE("%s: Camera %d: Can't find maximum JPEG size in "
392 "static metadata!", __FUNCTION__, mCameraId);
393 return INVALID_OPERATION;
394 }
395 int32_t maxJpegSize = entry.data.i32[0];
396 res = mDevice->createStream(anw, width, height, format, maxJpegSize,
397 &streamId);
398 } else {
399 // All other streams are a known size
400 res = mDevice->createStream(anw, width, height, format, /*size*/0,
401 &streamId);
402 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700403
404 if (res == OK) {
405 mStreamMap.add(bufferProducer->asBinder(), streamId);
406
407 ALOGV("%s: Camera %d: Successfully created a new stream ID %d",
408 __FUNCTION__, mCameraId, streamId);
Igor Murashkinf8b2a6f2013-09-17 17:03:28 -0700409
410 /**
411 * Set the stream transform flags to automatically
412 * rotate the camera stream for preview use cases.
413 */
414 int32_t transform = 0;
415 res = getRotationTransformLocked(&transform);
416
417 if (res != OK) {
418 // Error logged by getRotationTransformLocked.
419 return res;
420 }
421
422 res = mDevice->setStreamTransform(streamId, transform);
423 if (res != OK) {
424 ALOGE("%s: Failed to set stream transform (stream id %d)",
425 __FUNCTION__, streamId);
426 return res;
427 }
428
Igor Murashkine7ee7632013-06-11 18:10:18 -0700429 return streamId;
430 }
431
432 return res;
433}
434
435// Create a request object from a template.
436status_t CameraDeviceClient::createDefaultRequest(int templateId,
437 /*out*/
438 CameraMetadata* request)
439{
440 ATRACE_CALL();
441 ALOGV("%s (templateId = 0x%x)", __FUNCTION__, templateId);
442
443 status_t res;
444 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
445
446 Mutex::Autolock icl(mBinderSerializationLock);
447
448 if (!mDevice.get()) return DEAD_OBJECT;
449
450 CameraMetadata metadata;
451 if ( (res = mDevice->createDefaultRequest(templateId, &metadata) ) == OK &&
452 request != NULL) {
453
454 request->swap(metadata);
455 }
456
457 return res;
458}
459
Igor Murashkin099b4572013-07-12 17:52:16 -0700460status_t CameraDeviceClient::getCameraInfo(/*out*/CameraMetadata* info)
Igor Murashkine7ee7632013-06-11 18:10:18 -0700461{
462 ATRACE_CALL();
463 ALOGV("%s", __FUNCTION__);
464
465 status_t res = OK;
466
Igor Murashkine7ee7632013-06-11 18:10:18 -0700467 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
468
469 Mutex::Autolock icl(mBinderSerializationLock);
470
471 if (!mDevice.get()) return DEAD_OBJECT;
472
Igor Murashkin099b4572013-07-12 17:52:16 -0700473 if (info != NULL) {
474 *info = mDevice->info(); // static camera metadata
475 // TODO: merge with device-specific camera metadata
476 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700477
478 return res;
479}
480
Zhijun He2ab500c2013-07-23 08:02:53 -0700481status_t CameraDeviceClient::waitUntilIdle()
482{
483 ATRACE_CALL();
484 ALOGV("%s", __FUNCTION__);
485
486 status_t res = OK;
487 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
488
489 Mutex::Autolock icl(mBinderSerializationLock);
490
491 if (!mDevice.get()) return DEAD_OBJECT;
492
493 // FIXME: Also need check repeating burst.
494 if (!mStreamingRequestList.isEmpty()) {
495 ALOGE("%s: Camera %d: Try to waitUntilIdle when there are active streaming requests",
496 __FUNCTION__, mCameraId);
497 return INVALID_OPERATION;
498 }
499 res = mDevice->waitUntilDrained();
500 ALOGV("%s Done", __FUNCTION__);
501
502 return res;
503}
504
Jianing Weicb0652e2014-03-12 18:29:36 -0700505status_t CameraDeviceClient::flush(int64_t* lastFrameNumber) {
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700506 ATRACE_CALL();
507 ALOGV("%s", __FUNCTION__);
508
509 status_t res = OK;
510 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
511
512 Mutex::Autolock icl(mBinderSerializationLock);
513
514 if (!mDevice.get()) return DEAD_OBJECT;
515
Jianing Wei3c76fa32014-04-21 11:34:34 -0700516 mStreamingRequestList.clear();
Jianing Weicb0652e2014-03-12 18:29:36 -0700517 return mDevice->flush(lastFrameNumber);
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700518}
519
Igor Murashkine7ee7632013-06-11 18:10:18 -0700520status_t CameraDeviceClient::dump(int fd, const Vector<String16>& args) {
521 String8 result;
522 result.appendFormat("CameraDeviceClient[%d] (%p) PID: %d, dump:\n",
523 mCameraId,
524 getRemoteCallback()->asBinder().get(),
525 mClientPid);
526 result.append(" State: ");
527
528 // TODO: print dynamic/request section from most recent requests
529 mFrameProcessor->dump(fd, args);
530
531 return dumpDevice(fd, args);
532}
533
Jianing Weicb0652e2014-03-12 18:29:36 -0700534void CameraDeviceClient::notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
535 const CaptureResultExtras& resultExtras) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700536 // Thread safe. Don't bother locking.
537 sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
538
539 if (remoteCb != 0) {
Jianing Weicb0652e2014-03-12 18:29:36 -0700540 remoteCb->onDeviceError(errorCode, resultExtras);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700541 }
542}
543
544void CameraDeviceClient::notifyIdle() {
545 // Thread safe. Don't bother locking.
546 sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
547
548 if (remoteCb != 0) {
549 remoteCb->onDeviceIdle();
550 }
551}
552
Jianing Weicb0652e2014-03-12 18:29:36 -0700553void CameraDeviceClient::notifyShutter(const CaptureResultExtras& resultExtras,
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700554 nsecs_t timestamp) {
555 // Thread safe. Don't bother locking.
556 sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
557 if (remoteCb != 0) {
Jianing Weicb0652e2014-03-12 18:29:36 -0700558 remoteCb->onCaptureStarted(resultExtras, timestamp);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700559 }
560}
561
Igor Murashkine7ee7632013-06-11 18:10:18 -0700562// TODO: refactor the code below this with IProCameraUser.
563// it's 100% copy-pasted, so lets not change it right now to make it easier.
564
565void CameraDeviceClient::detachDevice() {
566 if (mDevice == 0) return;
567
568 ALOGV("Camera %d: Stopping processors", mCameraId);
569
570 mFrameProcessor->removeListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
571 FRAME_PROCESSOR_LISTENER_MAX_ID,
572 /*listener*/this);
573 mFrameProcessor->requestExit();
574 ALOGV("Camera %d: Waiting for threads", mCameraId);
575 mFrameProcessor->join();
576 ALOGV("Camera %d: Disconnecting device", mCameraId);
577
578 // WORKAROUND: HAL refuses to disconnect while there's streams in flight
579 {
580 mDevice->clearStreamingRequest();
581
582 status_t code;
583 if ((code = mDevice->waitUntilDrained()) != OK) {
584 ALOGE("%s: waitUntilDrained failed with code 0x%x", __FUNCTION__,
585 code);
586 }
587 }
588
589 Camera2ClientBase::detachDevice();
590}
591
592/** Device-related methods */
Jianing Weicb0652e2014-03-12 18:29:36 -0700593void CameraDeviceClient::onResultAvailable(const CaptureResult& result) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700594 ATRACE_CALL();
595 ALOGV("%s", __FUNCTION__);
596
Igor Murashkin4fb55c12013-08-29 17:43:01 -0700597 // Thread-safe. No lock necessary.
598 sp<ICameraDeviceCallbacks> remoteCb = mRemoteCallback;
599 if (remoteCb != NULL) {
Jianing Weicb0652e2014-03-12 18:29:36 -0700600 remoteCb->onResultReceived(result.mMetadata, result.mResultExtras);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700601 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700602}
603
604// TODO: move to Camera2ClientBase
605bool CameraDeviceClient::enforceRequestPermissions(CameraMetadata& metadata) {
606
607 const int pid = IPCThreadState::self()->getCallingPid();
608 const int selfPid = getpid();
609 camera_metadata_entry_t entry;
610
611 /**
612 * Mixin default important security values
613 * - android.led.transmit = defaulted ON
614 */
615 CameraMetadata staticInfo = mDevice->info();
616 entry = staticInfo.find(ANDROID_LED_AVAILABLE_LEDS);
617 for(size_t i = 0; i < entry.count; ++i) {
618 uint8_t led = entry.data.u8[i];
619
620 switch(led) {
621 case ANDROID_LED_AVAILABLE_LEDS_TRANSMIT: {
622 uint8_t transmitDefault = ANDROID_LED_TRANSMIT_ON;
623 if (!metadata.exists(ANDROID_LED_TRANSMIT)) {
624 metadata.update(ANDROID_LED_TRANSMIT,
625 &transmitDefault, 1);
626 }
627 break;
628 }
629 }
630 }
631
632 // We can do anything!
633 if (pid == selfPid) {
634 return true;
635 }
636
637 /**
638 * Permission check special fields in the request
639 * - android.led.transmit = android.permission.CAMERA_DISABLE_TRANSMIT
640 */
641 entry = metadata.find(ANDROID_LED_TRANSMIT);
642 if (entry.count > 0 && entry.data.u8[0] != ANDROID_LED_TRANSMIT_ON) {
643 String16 permissionString =
644 String16("android.permission.CAMERA_DISABLE_TRANSMIT_LED");
645 if (!checkCallingPermission(permissionString)) {
646 const int uid = IPCThreadState::self()->getCallingUid();
647 ALOGE("Permission Denial: "
648 "can't disable transmit LED pid=%d, uid=%d", pid, uid);
649 return false;
650 }
651 }
652
653 return true;
654}
655
Igor Murashkinf8b2a6f2013-09-17 17:03:28 -0700656status_t CameraDeviceClient::getRotationTransformLocked(int32_t* transform) {
657 ALOGV("%s: begin", __FUNCTION__);
658
659 if (transform == NULL) {
660 ALOGW("%s: null transform", __FUNCTION__);
661 return BAD_VALUE;
662 }
663
664 *transform = 0;
665
666 const CameraMetadata& staticInfo = mDevice->info();
667 camera_metadata_ro_entry_t entry = staticInfo.find(ANDROID_SENSOR_ORIENTATION);
668 if (entry.count == 0) {
669 ALOGE("%s: Camera %d: Can't find android.sensor.orientation in "
670 "static metadata!", __FUNCTION__, mCameraId);
671 return INVALID_OPERATION;
672 }
673
Zhijun Hef0b70262013-12-26 10:38:46 -0800674 camera_metadata_ro_entry_t entryFacing = staticInfo.find(ANDROID_LENS_FACING);
675 if (entry.count == 0) {
676 ALOGE("%s: Camera %d: Can't find android.lens.facing in "
677 "static metadata!", __FUNCTION__, mCameraId);
678 return INVALID_OPERATION;
679 }
680
Igor Murashkinf8b2a6f2013-09-17 17:03:28 -0700681 int32_t& flags = *transform;
682
Zhijun Hef0b70262013-12-26 10:38:46 -0800683 bool mirror = (entryFacing.data.u8[0] == ANDROID_LENS_FACING_FRONT);
Igor Murashkinf8b2a6f2013-09-17 17:03:28 -0700684 int orientation = entry.data.i32[0];
Zhijun Hef0b70262013-12-26 10:38:46 -0800685 if (!mirror) {
686 switch (orientation) {
687 case 0:
688 flags = 0;
689 break;
690 case 90:
691 flags = NATIVE_WINDOW_TRANSFORM_ROT_90;
692 break;
693 case 180:
694 flags = NATIVE_WINDOW_TRANSFORM_ROT_180;
695 break;
696 case 270:
697 flags = NATIVE_WINDOW_TRANSFORM_ROT_270;
698 break;
699 default:
700 ALOGE("%s: Invalid HAL android.sensor.orientation value: %d",
701 __FUNCTION__, orientation);
702 return INVALID_OPERATION;
703 }
704 } else {
705 switch (orientation) {
706 case 0:
707 flags = HAL_TRANSFORM_FLIP_H;
708 break;
709 case 90:
710 flags = HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
711 break;
712 case 180:
713 flags = HAL_TRANSFORM_FLIP_V;
714 break;
715 case 270:
716 flags = HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
717 break;
718 default:
719 ALOGE("%s: Invalid HAL android.sensor.orientation value: %d",
720 __FUNCTION__, orientation);
721 return INVALID_OPERATION;
722 }
723
Igor Murashkinf8b2a6f2013-09-17 17:03:28 -0700724 }
725
726 /**
727 * This magic flag makes surfaceflinger un-rotate the buffers
728 * to counter the extra global device UI rotation whenever the user
729 * physically rotates the device.
730 *
731 * By doing this, the camera buffer always ends up aligned
732 * with the physical camera for a "see through" effect.
733 *
734 * In essence, the buffer only gets rotated during preview use-cases.
735 * The user is still responsible to re-create streams of the proper
736 * aspect ratio, or the preview will end up looking non-uniformly
737 * stretched.
738 */
739 flags |= NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY;
740
741 ALOGV("%s: final transform = 0x%x", __FUNCTION__, flags);
742
743 return OK;
744}
745
Igor Murashkine7ee7632013-06-11 18:10:18 -0700746} // namespace android