blob: 8587e0e755549e2aebefa7ecda35f19a14a69257 [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>
Ruben Brunk5698d442014-06-18 10:39:40 -070026#include <camera/CameraUtils.h>
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070027
28#include "common/CameraDeviceBase.h"
29#include "api2/CameraDeviceClient.h"
30
31
Igor Murashkine7ee7632013-06-11 18:10:18 -070032
33namespace android {
34using namespace camera2;
35
36CameraDeviceClientBase::CameraDeviceClientBase(
37 const sp<CameraService>& cameraService,
38 const sp<ICameraDeviceCallbacks>& remoteCallback,
39 const String16& clientPackageName,
40 int cameraId,
41 int cameraFacing,
42 int clientPid,
43 uid_t clientUid,
44 int servicePid) :
Eino-Ville Talvalae992e752014-11-07 16:17:48 -080045 BasicClient(cameraService,
Marco Nelissenf8880202014-11-14 07:58:25 -080046 IInterface::asBinder(remoteCallback),
Eino-Ville Talvalae992e752014-11-07 16:17:48 -080047 clientPackageName,
48 cameraId,
49 cameraFacing,
50 clientPid,
51 clientUid,
52 servicePid),
Igor Murashkine7ee7632013-06-11 18:10:18 -070053 mRemoteCallback(remoteCallback) {
54}
Igor Murashkine7ee7632013-06-11 18:10:18 -070055
56// Interface used by CameraService
57
58CameraDeviceClient::CameraDeviceClient(const sp<CameraService>& cameraService,
59 const sp<ICameraDeviceCallbacks>& remoteCallback,
60 const String16& clientPackageName,
61 int cameraId,
62 int cameraFacing,
63 int clientPid,
64 uid_t clientUid,
65 int servicePid) :
66 Camera2ClientBase(cameraService, remoteCallback, clientPackageName,
67 cameraId, cameraFacing, clientPid, clientUid, servicePid),
68 mRequestIdCounter(0) {
69
70 ATRACE_CALL();
71 ALOGI("CameraDeviceClient %d: Opened", cameraId);
72}
73
Yin-Chia Yehe074a932015-01-30 10:29:02 -080074status_t CameraDeviceClient::initialize(CameraModule *module)
Igor Murashkine7ee7632013-06-11 18:10:18 -070075{
76 ATRACE_CALL();
77 status_t res;
78
79 res = Camera2ClientBase::initialize(module);
80 if (res != OK) {
81 return res;
82 }
83
84 String8 threadName;
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070085 mFrameProcessor = new FrameProcessorBase(mDevice);
Igor Murashkine7ee7632013-06-11 18:10:18 -070086 threadName = String8::format("CDU-%d-FrameProc", mCameraId);
87 mFrameProcessor->run(threadName.string());
88
89 mFrameProcessor->registerListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
90 FRAME_PROCESSOR_LISTENER_MAX_ID,
Eino-Ville Talvala184dfe42013-11-07 15:13:16 -080091 /*listener*/this,
Zhijun He25a0aef2014-06-25 11:40:02 -070092 /*sendPartials*/true);
Igor Murashkine7ee7632013-06-11 18:10:18 -070093
94 return OK;
95}
96
97CameraDeviceClient::~CameraDeviceClient() {
98}
99
100status_t CameraDeviceClient::submitRequest(sp<CaptureRequest> request,
Jianing Weicb0652e2014-03-12 18:29:36 -0700101 bool streaming,
102 /*out*/
103 int64_t* lastFrameNumber) {
104 List<sp<CaptureRequest> > requestList;
105 requestList.push_back(request);
106 return submitRequestList(requestList, streaming, lastFrameNumber);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700107}
108
Jianing Wei90e59c92014-03-12 18:29:36 -0700109status_t CameraDeviceClient::submitRequestList(List<sp<CaptureRequest> > requests,
Jianing Weicb0652e2014-03-12 18:29:36 -0700110 bool streaming, int64_t* lastFrameNumber) {
Jianing Wei90e59c92014-03-12 18:29:36 -0700111 ATRACE_CALL();
Mark Salyzyn50468412014-06-18 16:33:43 -0700112 ALOGV("%s-start of function. Request list size %zu", __FUNCTION__, requests.size());
Jianing Wei90e59c92014-03-12 18:29:36 -0700113
114 status_t res;
115 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
116
117 Mutex::Autolock icl(mBinderSerializationLock);
118
119 if (!mDevice.get()) return DEAD_OBJECT;
120
121 if (requests.empty()) {
122 ALOGE("%s: Camera %d: Sent null request. Rejecting request.",
123 __FUNCTION__, mCameraId);
124 return BAD_VALUE;
125 }
126
127 List<const CameraMetadata> metadataRequestList;
128 int32_t requestId = mRequestIdCounter;
129 uint32_t loopCounter = 0;
130
131 for (List<sp<CaptureRequest> >::iterator it = requests.begin(); it != requests.end(); ++it) {
132 sp<CaptureRequest> request = *it;
133 if (request == 0) {
134 ALOGE("%s: Camera %d: Sent null request.",
135 __FUNCTION__, mCameraId);
136 return BAD_VALUE;
137 }
138
139 CameraMetadata metadata(request->mMetadata);
140 if (metadata.isEmpty()) {
141 ALOGE("%s: Camera %d: Sent empty metadata packet. Rejecting request.",
142 __FUNCTION__, mCameraId);
143 return BAD_VALUE;
144 } else if (request->mSurfaceList.isEmpty()) {
145 ALOGE("%s: Camera %d: Requests must have at least one surface target. "
146 "Rejecting request.", __FUNCTION__, mCameraId);
147 return BAD_VALUE;
148 }
149
150 if (!enforceRequestPermissions(metadata)) {
151 // Callee logs
152 return PERMISSION_DENIED;
153 }
154
155 /**
156 * Write in the output stream IDs which we calculate from
157 * the capture request's list of surface targets
158 */
159 Vector<int32_t> outputStreamIds;
160 outputStreamIds.setCapacity(request->mSurfaceList.size());
Jianing Weicb0652e2014-03-12 18:29:36 -0700161 for (size_t i = 0; i < request->mSurfaceList.size(); ++i) {
162 sp<Surface> surface = request->mSurfaceList[i];
Jianing Wei90e59c92014-03-12 18:29:36 -0700163 if (surface == 0) continue;
164
165 sp<IGraphicBufferProducer> gbp = surface->getIGraphicBufferProducer();
Marco Nelissenf8880202014-11-14 07:58:25 -0800166 int idx = mStreamMap.indexOfKey(IInterface::asBinder(gbp));
Jianing Wei90e59c92014-03-12 18:29:36 -0700167
168 // Trying to submit request with surface that wasn't created
169 if (idx == NAME_NOT_FOUND) {
170 ALOGE("%s: Camera %d: Tried to submit a request with a surface that"
171 " we have not called createStream on",
172 __FUNCTION__, mCameraId);
173 return BAD_VALUE;
174 }
175
176 int streamId = mStreamMap.valueAt(idx);
177 outputStreamIds.push_back(streamId);
178 ALOGV("%s: Camera %d: Appending output stream %d to request",
179 __FUNCTION__, mCameraId, streamId);
180 }
181
182 metadata.update(ANDROID_REQUEST_OUTPUT_STREAMS, &outputStreamIds[0],
183 outputStreamIds.size());
184
185 metadata.update(ANDROID_REQUEST_ID, &requestId, /*size*/1);
186 loopCounter++; // loopCounter starts from 1
Mark Salyzyn50468412014-06-18 16:33:43 -0700187 ALOGV("%s: Camera %d: Creating request with ID %d (%d of %zu)",
Jianing Wei90e59c92014-03-12 18:29:36 -0700188 __FUNCTION__, mCameraId, requestId, loopCounter, requests.size());
189
190 metadataRequestList.push_back(metadata);
191 }
192 mRequestIdCounter++;
193
194 if (streaming) {
Jianing Weicb0652e2014-03-12 18:29:36 -0700195 res = mDevice->setStreamingRequestList(metadataRequestList, lastFrameNumber);
Jianing Wei90e59c92014-03-12 18:29:36 -0700196 if (res != OK) {
197 ALOGE("%s: Camera %d: Got error %d after trying to set streaming "
198 "request", __FUNCTION__, mCameraId, res);
199 } else {
200 mStreamingRequestList.push_back(requestId);
201 }
202 } else {
Jianing Weicb0652e2014-03-12 18:29:36 -0700203 res = mDevice->captureList(metadataRequestList, lastFrameNumber);
Jianing Wei90e59c92014-03-12 18:29:36 -0700204 if (res != OK) {
205 ALOGE("%s: Camera %d: Got error %d after trying to set capture",
206 __FUNCTION__, mCameraId, res);
207 }
Jianing Weicb0652e2014-03-12 18:29:36 -0700208 ALOGV("%s: requestId = %d ", __FUNCTION__, requestId);
Jianing Wei90e59c92014-03-12 18:29:36 -0700209 }
210
211 ALOGV("%s: Camera %d: End of function", __FUNCTION__, mCameraId);
212 if (res == OK) {
213 return requestId;
214 }
215
216 return res;
217}
218
Jianing Weicb0652e2014-03-12 18:29:36 -0700219status_t CameraDeviceClient::cancelRequest(int requestId, int64_t* lastFrameNumber) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700220 ATRACE_CALL();
221 ALOGV("%s, requestId = %d", __FUNCTION__, requestId);
222
223 status_t res;
224
225 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
226
227 Mutex::Autolock icl(mBinderSerializationLock);
228
229 if (!mDevice.get()) return DEAD_OBJECT;
230
231 Vector<int>::iterator it, end;
232 for (it = mStreamingRequestList.begin(), end = mStreamingRequestList.end();
233 it != end; ++it) {
234 if (*it == requestId) {
235 break;
236 }
237 }
238
239 if (it == end) {
240 ALOGE("%s: Camera%d: Did not find request id %d in list of streaming "
241 "requests", __FUNCTION__, mCameraId, requestId);
242 return BAD_VALUE;
243 }
244
Jianing Weicb0652e2014-03-12 18:29:36 -0700245 res = mDevice->clearStreamingRequest(lastFrameNumber);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700246
247 if (res == OK) {
248 ALOGV("%s: Camera %d: Successfully cleared streaming request",
249 __FUNCTION__, mCameraId);
250 mStreamingRequestList.erase(it);
251 }
252
253 return res;
254}
255
Ruben Brunkb2119af2014-05-09 19:57:56 -0700256status_t CameraDeviceClient::beginConfigure() {
257 // TODO: Implement this.
258 ALOGE("%s: Not implemented yet.", __FUNCTION__);
259 return OK;
260}
261
262status_t CameraDeviceClient::endConfigure() {
Igor Murashkine2d167e2014-08-19 16:19:59 -0700263 ALOGV("%s: ending configure (%zu streams)",
264 __FUNCTION__, mStreamMap.size());
265
266 status_t res;
267 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
268
269 Mutex::Autolock icl(mBinderSerializationLock);
270
271 if (!mDevice.get()) return DEAD_OBJECT;
272
273 return mDevice->configureStreams();
Ruben Brunkb2119af2014-05-09 19:57:56 -0700274}
275
Igor Murashkine7ee7632013-06-11 18:10:18 -0700276status_t CameraDeviceClient::deleteStream(int streamId) {
277 ATRACE_CALL();
278 ALOGV("%s (streamId = 0x%x)", __FUNCTION__, streamId);
279
280 status_t res;
281 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
282
283 Mutex::Autolock icl(mBinderSerializationLock);
284
285 if (!mDevice.get()) return DEAD_OBJECT;
286
287 // Guard against trying to delete non-created streams
288 ssize_t index = NAME_NOT_FOUND;
289 for (size_t i = 0; i < mStreamMap.size(); ++i) {
290 if (streamId == mStreamMap.valueAt(i)) {
291 index = i;
292 break;
293 }
294 }
295
296 if (index == NAME_NOT_FOUND) {
297 ALOGW("%s: Camera %d: Invalid stream ID (%d) specified, no stream "
298 "created yet", __FUNCTION__, mCameraId, streamId);
299 return BAD_VALUE;
300 }
301
302 // Also returns BAD_VALUE if stream ID was not valid
303 res = mDevice->deleteStream(streamId);
304
305 if (res == BAD_VALUE) {
306 ALOGE("%s: Camera %d: Unexpected BAD_VALUE when deleting stream, but we"
307 " already checked and the stream ID (%d) should be valid.",
308 __FUNCTION__, mCameraId, streamId);
309 } else if (res == OK) {
310 mStreamMap.removeItemsAt(index);
311
Igor Murashkine7ee7632013-06-11 18:10:18 -0700312 }
313
314 return res;
315}
316
Yin-Chia Yehb97babb2015-03-12 13:42:44 -0700317status_t CameraDeviceClient::createStream(const OutputConfiguration &outputConfiguration)
Igor Murashkine7ee7632013-06-11 18:10:18 -0700318{
319 ATRACE_CALL();
Igor Murashkine7ee7632013-06-11 18:10:18 -0700320
321 status_t res;
322 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
323
324 Mutex::Autolock icl(mBinderSerializationLock);
325
Yin-Chia Yehb97babb2015-03-12 13:42:44 -0700326
327 sp<IGraphicBufferProducer> bufferProducer = outputConfiguration.getGraphicBufferProducer();
Yin-Chia Yeh89f14da2014-06-10 16:05:44 -0700328 if (bufferProducer == NULL) {
329 ALOGE("%s: bufferProducer must not be null", __FUNCTION__);
330 return BAD_VALUE;
331 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700332 if (!mDevice.get()) return DEAD_OBJECT;
333
334 // Don't create multiple streams for the same target surface
335 {
Marco Nelissenf8880202014-11-14 07:58:25 -0800336 ssize_t index = mStreamMap.indexOfKey(IInterface::asBinder(bufferProducer));
Igor Murashkine7ee7632013-06-11 18:10:18 -0700337 if (index != NAME_NOT_FOUND) {
338 ALOGW("%s: Camera %d: Buffer producer already has a stream for it "
Colin Crosse5729fa2014-03-21 15:04:25 -0700339 "(ID %zd)",
Igor Murashkine7ee7632013-06-11 18:10:18 -0700340 __FUNCTION__, mCameraId, index);
341 return ALREADY_EXISTS;
342 }
343 }
344
Eino-Ville Talvala1da3b602013-09-26 15:28:55 -0700345 // HACK b/10949105
346 // Query consumer usage bits to set async operation mode for
347 // GLConsumer using controlledByApp parameter.
348 bool useAsync = false;
349 int32_t consumerUsage;
350 if ((res = bufferProducer->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS,
351 &consumerUsage)) != OK) {
352 ALOGE("%s: Camera %d: Failed to query consumer usage", __FUNCTION__,
353 mCameraId);
354 return res;
355 }
356 if (consumerUsage & GraphicBuffer::USAGE_HW_TEXTURE) {
357 ALOGW("%s: Camera %d: Forcing asynchronous mode for stream",
358 __FUNCTION__, mCameraId);
359 useAsync = true;
360 }
361
Ruben Brunkbba75572014-11-20 17:29:50 -0800362 int32_t disallowedFlags = GraphicBuffer::USAGE_HW_VIDEO_ENCODER |
363 GRALLOC_USAGE_RENDERSCRIPT;
364 int32_t allowedFlags = GraphicBuffer::USAGE_SW_READ_MASK |
365 GraphicBuffer::USAGE_HW_TEXTURE |
366 GraphicBuffer::USAGE_HW_COMPOSER;
367 bool flexibleConsumer = (consumerUsage & disallowedFlags) == 0 &&
368 (consumerUsage & allowedFlags) != 0;
369
Marco Nelissenf8880202014-11-14 07:58:25 -0800370 sp<IBinder> binder = IInterface::asBinder(bufferProducer);
Eino-Ville Talvalae992e752014-11-07 16:17:48 -0800371 sp<ANativeWindow> anw = new Surface(bufferProducer, useAsync);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700372
Eino-Ville Talvala3d82c0d2015-02-23 15:19:19 -0800373 int width, height, format;
374 android_dataspace dataSpace;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700375
376 if ((res = anw->query(anw.get(), NATIVE_WINDOW_WIDTH, &width)) != OK) {
377 ALOGE("%s: Camera %d: Failed to query Surface width", __FUNCTION__,
378 mCameraId);
379 return res;
380 }
381 if ((res = anw->query(anw.get(), NATIVE_WINDOW_HEIGHT, &height)) != OK) {
382 ALOGE("%s: Camera %d: Failed to query Surface height", __FUNCTION__,
383 mCameraId);
384 return res;
385 }
386 if ((res = anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &format)) != OK) {
387 ALOGE("%s: Camera %d: Failed to query Surface format", __FUNCTION__,
388 mCameraId);
389 return res;
390 }
Eino-Ville Talvala3d82c0d2015-02-23 15:19:19 -0800391 if ((res = anw->query(anw.get(), NATIVE_WINDOW_DEFAULT_DATASPACE,
392 reinterpret_cast<int*>(&dataSpace))) != OK) {
393 ALOGE("%s: Camera %d: Failed to query Surface dataSpace", __FUNCTION__,
394 mCameraId);
395 return res;
396 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700397
398 // FIXME: remove this override since the default format should be
399 // IMPLEMENTATION_DEFINED. b/9487482
Igor Murashkin15811012013-07-29 12:25:59 -0700400 if (format >= HAL_PIXEL_FORMAT_RGBA_8888 &&
401 format <= HAL_PIXEL_FORMAT_BGRA_8888) {
Ruben Brunkbba75572014-11-20 17:29:50 -0800402 ALOGW("%s: Camera %d: Overriding format %#x to IMPLEMENTATION_DEFINED",
Igor Murashkine7ee7632013-06-11 18:10:18 -0700403 __FUNCTION__, mCameraId, format);
404 format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
405 }
406
Ruben Brunkbba75572014-11-20 17:29:50 -0800407 // Round dimensions to the nearest dimensions available for this format
408 if (flexibleConsumer && !CameraDeviceClient::roundBufferDimensionNearest(width, height,
Eino-Ville Talvala3d82c0d2015-02-23 15:19:19 -0800409 format, dataSpace, mDevice->info(), /*out*/&width, /*out*/&height)) {
Ruben Brunkbba75572014-11-20 17:29:50 -0800410 ALOGE("%s: No stream configurations with the format %#x defined, failed to create stream.",
411 __FUNCTION__, format);
412 return BAD_VALUE;
413 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700414
415 int streamId = -1;
Eino-Ville Talvala3d82c0d2015-02-23 15:19:19 -0800416 res = mDevice->createStream(anw, width, height, format, dataSpace,
Yin-Chia Yehb97babb2015-03-12 13:42:44 -0700417 static_cast<camera3_stream_rotation_t>
418 (outputConfiguration.getRotation()),
419 &streamId);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700420
421 if (res == OK) {
Eino-Ville Talvalae992e752014-11-07 16:17:48 -0800422 mStreamMap.add(binder, streamId);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700423
424 ALOGV("%s: Camera %d: Successfully created a new stream ID %d",
425 __FUNCTION__, mCameraId, streamId);
Igor Murashkinf8b2a6f2013-09-17 17:03:28 -0700426
427 /**
428 * Set the stream transform flags to automatically
429 * rotate the camera stream for preview use cases.
430 */
431 int32_t transform = 0;
432 res = getRotationTransformLocked(&transform);
433
434 if (res != OK) {
435 // Error logged by getRotationTransformLocked.
436 return res;
437 }
438
439 res = mDevice->setStreamTransform(streamId, transform);
440 if (res != OK) {
441 ALOGE("%s: Failed to set stream transform (stream id %d)",
442 __FUNCTION__, streamId);
443 return res;
444 }
445
Igor Murashkine7ee7632013-06-11 18:10:18 -0700446 return streamId;
447 }
448
449 return res;
450}
451
Ruben Brunkbba75572014-11-20 17:29:50 -0800452
453bool CameraDeviceClient::roundBufferDimensionNearest(int32_t width, int32_t height,
Eino-Ville Talvala3d82c0d2015-02-23 15:19:19 -0800454 int32_t format, android_dataspace dataSpace, const CameraMetadata& info,
Ruben Brunkbba75572014-11-20 17:29:50 -0800455 /*out*/int32_t* outWidth, /*out*/int32_t* outHeight) {
456
457 camera_metadata_ro_entry streamConfigs =
Eino-Ville Talvala3d82c0d2015-02-23 15:19:19 -0800458 (dataSpace == HAL_DATASPACE_DEPTH) ?
459 info.find(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS) :
Ruben Brunkbba75572014-11-20 17:29:50 -0800460 info.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
461
462 int32_t bestWidth = -1;
463 int32_t bestHeight = -1;
464
465 // Iterate through listed stream configurations and find the one with the smallest euclidean
466 // distance from the given dimensions for the given format.
467 for (size_t i = 0; i < streamConfigs.count; i += 4) {
468 int32_t fmt = streamConfigs.data.i32[i];
469 int32_t w = streamConfigs.data.i32[i + 1];
470 int32_t h = streamConfigs.data.i32[i + 2];
471
472 // Ignore input/output type for now
473 if (fmt == format) {
474 if (w == width && h == height) {
475 bestWidth = width;
476 bestHeight = height;
477 break;
478 } else if (w <= ROUNDING_WIDTH_CAP && (bestWidth == -1 ||
479 CameraDeviceClient::euclidDistSquare(w, h, width, height) <
480 CameraDeviceClient::euclidDistSquare(bestWidth, bestHeight, width, height))) {
481 bestWidth = w;
482 bestHeight = h;
483 }
484 }
485 }
486
487 if (bestWidth == -1) {
488 // Return false if no configurations for this format were listed
489 return false;
490 }
491
492 // Set the outputs to the closet width/height
493 if (outWidth != NULL) {
494 *outWidth = bestWidth;
495 }
496 if (outHeight != NULL) {
497 *outHeight = bestHeight;
498 }
499
500 // Return true if at least one configuration for this format was listed
501 return true;
502}
503
504int64_t CameraDeviceClient::euclidDistSquare(int32_t x0, int32_t y0, int32_t x1, int32_t y1) {
505 int64_t d0 = x0 - x1;
506 int64_t d1 = y0 - y1;
507 return d0 * d0 + d1 * d1;
508}
509
Igor Murashkine7ee7632013-06-11 18:10:18 -0700510// Create a request object from a template.
511status_t CameraDeviceClient::createDefaultRequest(int templateId,
512 /*out*/
513 CameraMetadata* request)
514{
515 ATRACE_CALL();
516 ALOGV("%s (templateId = 0x%x)", __FUNCTION__, templateId);
517
518 status_t res;
519 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
520
521 Mutex::Autolock icl(mBinderSerializationLock);
522
523 if (!mDevice.get()) return DEAD_OBJECT;
524
525 CameraMetadata metadata;
526 if ( (res = mDevice->createDefaultRequest(templateId, &metadata) ) == OK &&
527 request != NULL) {
528
529 request->swap(metadata);
530 }
531
532 return res;
533}
534
Igor Murashkin099b4572013-07-12 17:52:16 -0700535status_t CameraDeviceClient::getCameraInfo(/*out*/CameraMetadata* info)
Igor Murashkine7ee7632013-06-11 18:10:18 -0700536{
537 ATRACE_CALL();
538 ALOGV("%s", __FUNCTION__);
539
540 status_t res = OK;
541
Igor Murashkine7ee7632013-06-11 18:10:18 -0700542 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
543
544 Mutex::Autolock icl(mBinderSerializationLock);
545
546 if (!mDevice.get()) return DEAD_OBJECT;
547
Igor Murashkin099b4572013-07-12 17:52:16 -0700548 if (info != NULL) {
549 *info = mDevice->info(); // static camera metadata
550 // TODO: merge with device-specific camera metadata
551 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700552
553 return res;
554}
555
Zhijun He2ab500c2013-07-23 08:02:53 -0700556status_t CameraDeviceClient::waitUntilIdle()
557{
558 ATRACE_CALL();
559 ALOGV("%s", __FUNCTION__);
560
561 status_t res = OK;
562 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
563
564 Mutex::Autolock icl(mBinderSerializationLock);
565
566 if (!mDevice.get()) return DEAD_OBJECT;
567
568 // FIXME: Also need check repeating burst.
569 if (!mStreamingRequestList.isEmpty()) {
570 ALOGE("%s: Camera %d: Try to waitUntilIdle when there are active streaming requests",
571 __FUNCTION__, mCameraId);
572 return INVALID_OPERATION;
573 }
574 res = mDevice->waitUntilDrained();
575 ALOGV("%s Done", __FUNCTION__);
576
577 return res;
578}
579
Jianing Weicb0652e2014-03-12 18:29:36 -0700580status_t CameraDeviceClient::flush(int64_t* lastFrameNumber) {
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700581 ATRACE_CALL();
582 ALOGV("%s", __FUNCTION__);
583
584 status_t res = OK;
585 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
586
587 Mutex::Autolock icl(mBinderSerializationLock);
588
589 if (!mDevice.get()) return DEAD_OBJECT;
590
Jianing Wei3c76fa32014-04-21 11:34:34 -0700591 mStreamingRequestList.clear();
Jianing Weicb0652e2014-03-12 18:29:36 -0700592 return mDevice->flush(lastFrameNumber);
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700593}
594
Igor Murashkine7ee7632013-06-11 18:10:18 -0700595status_t CameraDeviceClient::dump(int fd, const Vector<String16>& args) {
596 String8 result;
Eino-Ville Talvala67489d22014-09-18 15:52:02 -0700597 result.appendFormat("CameraDeviceClient[%d] (%p) dump:\n",
Igor Murashkine7ee7632013-06-11 18:10:18 -0700598 mCameraId,
Eino-Ville Talvalae992e752014-11-07 16:17:48 -0800599 (getRemoteCallback() != NULL ?
Marco Nelissenf8880202014-11-14 07:58:25 -0800600 IInterface::asBinder(getRemoteCallback()).get() : NULL) );
Ruben Brunkcc776712015-02-17 20:18:47 -0800601 result.appendFormat(" Current client UID %u\n", mClientUid);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700602
Eino-Ville Talvala67489d22014-09-18 15:52:02 -0700603 result.append(" State:\n");
604 result.appendFormat(" Request ID counter: %d\n", mRequestIdCounter);
605 if (!mStreamMap.isEmpty()) {
606 result.append(" Current stream IDs:\n");
607 for (size_t i = 0; i < mStreamMap.size(); i++) {
608 result.appendFormat(" Stream %d\n", mStreamMap.valueAt(i));
609 }
610 } else {
611 result.append(" No streams configured.\n");
612 }
613 write(fd, result.string(), result.size());
Igor Murashkine7ee7632013-06-11 18:10:18 -0700614 // TODO: print dynamic/request section from most recent requests
615 mFrameProcessor->dump(fd, args);
616
617 return dumpDevice(fd, args);
618}
619
Jianing Weicb0652e2014-03-12 18:29:36 -0700620void CameraDeviceClient::notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
621 const CaptureResultExtras& resultExtras) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700622 // Thread safe. Don't bother locking.
623 sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
624
625 if (remoteCb != 0) {
Jianing Weicb0652e2014-03-12 18:29:36 -0700626 remoteCb->onDeviceError(errorCode, resultExtras);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700627 }
628}
629
630void CameraDeviceClient::notifyIdle() {
631 // Thread safe. Don't bother locking.
632 sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
633
634 if (remoteCb != 0) {
635 remoteCb->onDeviceIdle();
636 }
637}
638
Jianing Weicb0652e2014-03-12 18:29:36 -0700639void CameraDeviceClient::notifyShutter(const CaptureResultExtras& resultExtras,
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700640 nsecs_t timestamp) {
641 // Thread safe. Don't bother locking.
642 sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
643 if (remoteCb != 0) {
Jianing Weicb0652e2014-03-12 18:29:36 -0700644 remoteCb->onCaptureStarted(resultExtras, timestamp);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700645 }
646}
647
Igor Murashkine7ee7632013-06-11 18:10:18 -0700648void CameraDeviceClient::detachDevice() {
649 if (mDevice == 0) return;
650
651 ALOGV("Camera %d: Stopping processors", mCameraId);
652
653 mFrameProcessor->removeListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
654 FRAME_PROCESSOR_LISTENER_MAX_ID,
655 /*listener*/this);
656 mFrameProcessor->requestExit();
657 ALOGV("Camera %d: Waiting for threads", mCameraId);
658 mFrameProcessor->join();
659 ALOGV("Camera %d: Disconnecting device", mCameraId);
660
661 // WORKAROUND: HAL refuses to disconnect while there's streams in flight
662 {
663 mDevice->clearStreamingRequest();
664
665 status_t code;
666 if ((code = mDevice->waitUntilDrained()) != OK) {
667 ALOGE("%s: waitUntilDrained failed with code 0x%x", __FUNCTION__,
668 code);
669 }
670 }
671
672 Camera2ClientBase::detachDevice();
673}
674
675/** Device-related methods */
Jianing Weicb0652e2014-03-12 18:29:36 -0700676void CameraDeviceClient::onResultAvailable(const CaptureResult& result) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700677 ATRACE_CALL();
678 ALOGV("%s", __FUNCTION__);
679
Igor Murashkin4fb55c12013-08-29 17:43:01 -0700680 // Thread-safe. No lock necessary.
681 sp<ICameraDeviceCallbacks> remoteCb = mRemoteCallback;
682 if (remoteCb != NULL) {
Jianing Weicb0652e2014-03-12 18:29:36 -0700683 remoteCb->onResultReceived(result.mMetadata, result.mResultExtras);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700684 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700685}
686
687// TODO: move to Camera2ClientBase
688bool CameraDeviceClient::enforceRequestPermissions(CameraMetadata& metadata) {
689
690 const int pid = IPCThreadState::self()->getCallingPid();
691 const int selfPid = getpid();
692 camera_metadata_entry_t entry;
693
694 /**
695 * Mixin default important security values
696 * - android.led.transmit = defaulted ON
697 */
698 CameraMetadata staticInfo = mDevice->info();
699 entry = staticInfo.find(ANDROID_LED_AVAILABLE_LEDS);
700 for(size_t i = 0; i < entry.count; ++i) {
701 uint8_t led = entry.data.u8[i];
702
703 switch(led) {
704 case ANDROID_LED_AVAILABLE_LEDS_TRANSMIT: {
705 uint8_t transmitDefault = ANDROID_LED_TRANSMIT_ON;
706 if (!metadata.exists(ANDROID_LED_TRANSMIT)) {
707 metadata.update(ANDROID_LED_TRANSMIT,
708 &transmitDefault, 1);
709 }
710 break;
711 }
712 }
713 }
714
715 // We can do anything!
716 if (pid == selfPid) {
717 return true;
718 }
719
720 /**
721 * Permission check special fields in the request
722 * - android.led.transmit = android.permission.CAMERA_DISABLE_TRANSMIT
723 */
724 entry = metadata.find(ANDROID_LED_TRANSMIT);
725 if (entry.count > 0 && entry.data.u8[0] != ANDROID_LED_TRANSMIT_ON) {
726 String16 permissionString =
727 String16("android.permission.CAMERA_DISABLE_TRANSMIT_LED");
728 if (!checkCallingPermission(permissionString)) {
729 const int uid = IPCThreadState::self()->getCallingUid();
730 ALOGE("Permission Denial: "
731 "can't disable transmit LED pid=%d, uid=%d", pid, uid);
732 return false;
733 }
734 }
735
736 return true;
737}
738
Igor Murashkinf8b2a6f2013-09-17 17:03:28 -0700739status_t CameraDeviceClient::getRotationTransformLocked(int32_t* transform) {
740 ALOGV("%s: begin", __FUNCTION__);
741
Igor Murashkinf8b2a6f2013-09-17 17:03:28 -0700742 const CameraMetadata& staticInfo = mDevice->info();
Ruben Brunk5698d442014-06-18 10:39:40 -0700743 return CameraUtils::getRotationTransform(staticInfo, transform);
Igor Murashkinf8b2a6f2013-09-17 17:03:28 -0700744}
745
Igor Murashkine7ee7632013-06-11 18:10:18 -0700746} // namespace android