blob: bf1692dcdf00759a3ddbcd2c5a01016ad77cd055 [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),
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -070068 mInputStream(),
Igor Murashkine7ee7632013-06-11 18:10:18 -070069 mRequestIdCounter(0) {
70
71 ATRACE_CALL();
72 ALOGI("CameraDeviceClient %d: Opened", cameraId);
73}
74
Yin-Chia Yehe074a932015-01-30 10:29:02 -080075status_t CameraDeviceClient::initialize(CameraModule *module)
Igor Murashkine7ee7632013-06-11 18:10:18 -070076{
77 ATRACE_CALL();
78 status_t res;
79
80 res = Camera2ClientBase::initialize(module);
81 if (res != OK) {
82 return res;
83 }
84
85 String8 threadName;
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070086 mFrameProcessor = new FrameProcessorBase(mDevice);
Igor Murashkine7ee7632013-06-11 18:10:18 -070087 threadName = String8::format("CDU-%d-FrameProc", mCameraId);
88 mFrameProcessor->run(threadName.string());
89
90 mFrameProcessor->registerListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
91 FRAME_PROCESSOR_LISTENER_MAX_ID,
Eino-Ville Talvala184dfe42013-11-07 15:13:16 -080092 /*listener*/this,
Zhijun He25a0aef2014-06-25 11:40:02 -070093 /*sendPartials*/true);
Igor Murashkine7ee7632013-06-11 18:10:18 -070094
95 return OK;
96}
97
98CameraDeviceClient::~CameraDeviceClient() {
99}
100
101status_t CameraDeviceClient::submitRequest(sp<CaptureRequest> request,
Jianing Weicb0652e2014-03-12 18:29:36 -0700102 bool streaming,
103 /*out*/
104 int64_t* lastFrameNumber) {
105 List<sp<CaptureRequest> > requestList;
106 requestList.push_back(request);
107 return submitRequestList(requestList, streaming, lastFrameNumber);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700108}
109
Jianing Wei90e59c92014-03-12 18:29:36 -0700110status_t CameraDeviceClient::submitRequestList(List<sp<CaptureRequest> > requests,
Jianing Weicb0652e2014-03-12 18:29:36 -0700111 bool streaming, int64_t* lastFrameNumber) {
Jianing Wei90e59c92014-03-12 18:29:36 -0700112 ATRACE_CALL();
Mark Salyzyn50468412014-06-18 16:33:43 -0700113 ALOGV("%s-start of function. Request list size %zu", __FUNCTION__, requests.size());
Jianing Wei90e59c92014-03-12 18:29:36 -0700114
115 status_t res;
116 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
117
118 Mutex::Autolock icl(mBinderSerializationLock);
119
120 if (!mDevice.get()) return DEAD_OBJECT;
121
122 if (requests.empty()) {
123 ALOGE("%s: Camera %d: Sent null request. Rejecting request.",
124 __FUNCTION__, mCameraId);
125 return BAD_VALUE;
126 }
127
128 List<const CameraMetadata> metadataRequestList;
129 int32_t requestId = mRequestIdCounter;
130 uint32_t loopCounter = 0;
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700131 bool isReprocess = false;
Jianing Wei90e59c92014-03-12 18:29:36 -0700132
133 for (List<sp<CaptureRequest> >::iterator it = requests.begin(); it != requests.end(); ++it) {
134 sp<CaptureRequest> request = *it;
135 if (request == 0) {
136 ALOGE("%s: Camera %d: Sent null request.",
137 __FUNCTION__, mCameraId);
138 return BAD_VALUE;
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700139 } else if (it == requests.begin()) {
140 isReprocess = request->mIsReprocess;
141 if (isReprocess && !mInputStream.configured) {
142 ALOGE("%s: Camera %d: no input stream is configured.");
143 return BAD_VALUE;
144 } else if (isReprocess && streaming) {
145 ALOGE("%s: Camera %d: streaming reprocess requests not supported.");
146 return BAD_VALUE;
147 }
148 } else if (isReprocess != request->mIsReprocess) {
149 ALOGE("%s: Camera %d: Sent regular and reprocess requests.");
150 return BAD_VALUE;
Jianing Wei90e59c92014-03-12 18:29:36 -0700151 }
152
153 CameraMetadata metadata(request->mMetadata);
154 if (metadata.isEmpty()) {
155 ALOGE("%s: Camera %d: Sent empty metadata packet. Rejecting request.",
156 __FUNCTION__, mCameraId);
157 return BAD_VALUE;
158 } else if (request->mSurfaceList.isEmpty()) {
159 ALOGE("%s: Camera %d: Requests must have at least one surface target. "
160 "Rejecting request.", __FUNCTION__, mCameraId);
161 return BAD_VALUE;
162 }
163
164 if (!enforceRequestPermissions(metadata)) {
165 // Callee logs
166 return PERMISSION_DENIED;
167 }
168
169 /**
170 * Write in the output stream IDs which we calculate from
171 * the capture request's list of surface targets
172 */
173 Vector<int32_t> outputStreamIds;
174 outputStreamIds.setCapacity(request->mSurfaceList.size());
Jianing Weicb0652e2014-03-12 18:29:36 -0700175 for (size_t i = 0; i < request->mSurfaceList.size(); ++i) {
176 sp<Surface> surface = request->mSurfaceList[i];
Jianing Wei90e59c92014-03-12 18:29:36 -0700177 if (surface == 0) continue;
178
179 sp<IGraphicBufferProducer> gbp = surface->getIGraphicBufferProducer();
Marco Nelissenf8880202014-11-14 07:58:25 -0800180 int idx = mStreamMap.indexOfKey(IInterface::asBinder(gbp));
Jianing Wei90e59c92014-03-12 18:29:36 -0700181
182 // Trying to submit request with surface that wasn't created
183 if (idx == NAME_NOT_FOUND) {
184 ALOGE("%s: Camera %d: Tried to submit a request with a surface that"
185 " we have not called createStream on",
186 __FUNCTION__, mCameraId);
187 return BAD_VALUE;
188 }
189
190 int streamId = mStreamMap.valueAt(idx);
191 outputStreamIds.push_back(streamId);
192 ALOGV("%s: Camera %d: Appending output stream %d to request",
193 __FUNCTION__, mCameraId, streamId);
194 }
195
196 metadata.update(ANDROID_REQUEST_OUTPUT_STREAMS, &outputStreamIds[0],
197 outputStreamIds.size());
198
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700199 if (isReprocess) {
200 metadata.update(ANDROID_REQUEST_INPUT_STREAMS, &mInputStream.id, 1);
201 }
202
Jianing Wei90e59c92014-03-12 18:29:36 -0700203 metadata.update(ANDROID_REQUEST_ID, &requestId, /*size*/1);
204 loopCounter++; // loopCounter starts from 1
Mark Salyzyn50468412014-06-18 16:33:43 -0700205 ALOGV("%s: Camera %d: Creating request with ID %d (%d of %zu)",
Jianing Wei90e59c92014-03-12 18:29:36 -0700206 __FUNCTION__, mCameraId, requestId, loopCounter, requests.size());
207
208 metadataRequestList.push_back(metadata);
209 }
210 mRequestIdCounter++;
211
212 if (streaming) {
Jianing Weicb0652e2014-03-12 18:29:36 -0700213 res = mDevice->setStreamingRequestList(metadataRequestList, lastFrameNumber);
Jianing Wei90e59c92014-03-12 18:29:36 -0700214 if (res != OK) {
215 ALOGE("%s: Camera %d: Got error %d after trying to set streaming "
216 "request", __FUNCTION__, mCameraId, res);
217 } else {
218 mStreamingRequestList.push_back(requestId);
219 }
220 } else {
Jianing Weicb0652e2014-03-12 18:29:36 -0700221 res = mDevice->captureList(metadataRequestList, lastFrameNumber);
Jianing Wei90e59c92014-03-12 18:29:36 -0700222 if (res != OK) {
223 ALOGE("%s: Camera %d: Got error %d after trying to set capture",
224 __FUNCTION__, mCameraId, res);
225 }
Jianing Weicb0652e2014-03-12 18:29:36 -0700226 ALOGV("%s: requestId = %d ", __FUNCTION__, requestId);
Jianing Wei90e59c92014-03-12 18:29:36 -0700227 }
228
229 ALOGV("%s: Camera %d: End of function", __FUNCTION__, mCameraId);
230 if (res == OK) {
231 return requestId;
232 }
233
234 return res;
235}
236
Jianing Weicb0652e2014-03-12 18:29:36 -0700237status_t CameraDeviceClient::cancelRequest(int requestId, int64_t* lastFrameNumber) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700238 ATRACE_CALL();
239 ALOGV("%s, requestId = %d", __FUNCTION__, requestId);
240
241 status_t res;
242
243 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
244
245 Mutex::Autolock icl(mBinderSerializationLock);
246
247 if (!mDevice.get()) return DEAD_OBJECT;
248
249 Vector<int>::iterator it, end;
250 for (it = mStreamingRequestList.begin(), end = mStreamingRequestList.end();
251 it != end; ++it) {
252 if (*it == requestId) {
253 break;
254 }
255 }
256
257 if (it == end) {
258 ALOGE("%s: Camera%d: Did not find request id %d in list of streaming "
259 "requests", __FUNCTION__, mCameraId, requestId);
260 return BAD_VALUE;
261 }
262
Jianing Weicb0652e2014-03-12 18:29:36 -0700263 res = mDevice->clearStreamingRequest(lastFrameNumber);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700264
265 if (res == OK) {
266 ALOGV("%s: Camera %d: Successfully cleared streaming request",
267 __FUNCTION__, mCameraId);
268 mStreamingRequestList.erase(it);
269 }
270
271 return res;
272}
273
Ruben Brunkb2119af2014-05-09 19:57:56 -0700274status_t CameraDeviceClient::beginConfigure() {
275 // TODO: Implement this.
276 ALOGE("%s: Not implemented yet.", __FUNCTION__);
277 return OK;
278}
279
280status_t CameraDeviceClient::endConfigure() {
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700281 ALOGV("%s: ending configure (%d input stream, %zu output streams)",
282 __FUNCTION__, mInputStream.configured ? 1 : 0, mStreamMap.size());
Igor Murashkine2d167e2014-08-19 16:19:59 -0700283
284 status_t res;
285 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
286
287 Mutex::Autolock icl(mBinderSerializationLock);
288
289 if (!mDevice.get()) return DEAD_OBJECT;
290
291 return mDevice->configureStreams();
Ruben Brunkb2119af2014-05-09 19:57:56 -0700292}
293
Igor Murashkine7ee7632013-06-11 18:10:18 -0700294status_t CameraDeviceClient::deleteStream(int streamId) {
295 ATRACE_CALL();
296 ALOGV("%s (streamId = 0x%x)", __FUNCTION__, streamId);
297
298 status_t res;
299 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
300
301 Mutex::Autolock icl(mBinderSerializationLock);
302
303 if (!mDevice.get()) return DEAD_OBJECT;
304
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700305 bool isInput = false;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700306 ssize_t index = NAME_NOT_FOUND;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700307
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700308 if (mInputStream.configured && mInputStream.id == streamId) {
309 isInput = true;
310 } else {
311 // Guard against trying to delete non-created streams
312 for (size_t i = 0; i < mStreamMap.size(); ++i) {
313 if (streamId == mStreamMap.valueAt(i)) {
314 index = i;
315 break;
316 }
317 }
318
319 if (index == NAME_NOT_FOUND) {
320 ALOGW("%s: Camera %d: Invalid stream ID (%d) specified, no stream "
321 "created yet", __FUNCTION__, mCameraId, streamId);
322 return BAD_VALUE;
323 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700324 }
325
326 // Also returns BAD_VALUE if stream ID was not valid
327 res = mDevice->deleteStream(streamId);
328
329 if (res == BAD_VALUE) {
330 ALOGE("%s: Camera %d: Unexpected BAD_VALUE when deleting stream, but we"
331 " already checked and the stream ID (%d) should be valid.",
332 __FUNCTION__, mCameraId, streamId);
333 } else if (res == OK) {
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700334 if (isInput) {
335 mInputStream.configured = false;
336 } else {
337 mStreamMap.removeItemsAt(index);
338 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700339 }
340
341 return res;
342}
343
Yin-Chia Yehb97babb2015-03-12 13:42:44 -0700344status_t CameraDeviceClient::createStream(const OutputConfiguration &outputConfiguration)
Igor Murashkine7ee7632013-06-11 18:10:18 -0700345{
346 ATRACE_CALL();
Igor Murashkine7ee7632013-06-11 18:10:18 -0700347
348 status_t res;
349 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
350
351 Mutex::Autolock icl(mBinderSerializationLock);
352
Yin-Chia Yehb97babb2015-03-12 13:42:44 -0700353
354 sp<IGraphicBufferProducer> bufferProducer = outputConfiguration.getGraphicBufferProducer();
Yin-Chia Yeh89f14da2014-06-10 16:05:44 -0700355 if (bufferProducer == NULL) {
356 ALOGE("%s: bufferProducer must not be null", __FUNCTION__);
357 return BAD_VALUE;
358 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700359 if (!mDevice.get()) return DEAD_OBJECT;
360
361 // Don't create multiple streams for the same target surface
362 {
Marco Nelissenf8880202014-11-14 07:58:25 -0800363 ssize_t index = mStreamMap.indexOfKey(IInterface::asBinder(bufferProducer));
Igor Murashkine7ee7632013-06-11 18:10:18 -0700364 if (index != NAME_NOT_FOUND) {
365 ALOGW("%s: Camera %d: Buffer producer already has a stream for it "
Colin Crosse5729fa2014-03-21 15:04:25 -0700366 "(ID %zd)",
Igor Murashkine7ee7632013-06-11 18:10:18 -0700367 __FUNCTION__, mCameraId, index);
368 return ALREADY_EXISTS;
369 }
370 }
371
Eino-Ville Talvala1da3b602013-09-26 15:28:55 -0700372 // HACK b/10949105
373 // Query consumer usage bits to set async operation mode for
374 // GLConsumer using controlledByApp parameter.
375 bool useAsync = false;
376 int32_t consumerUsage;
377 if ((res = bufferProducer->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS,
378 &consumerUsage)) != OK) {
379 ALOGE("%s: Camera %d: Failed to query consumer usage", __FUNCTION__,
380 mCameraId);
381 return res;
382 }
383 if (consumerUsage & GraphicBuffer::USAGE_HW_TEXTURE) {
384 ALOGW("%s: Camera %d: Forcing asynchronous mode for stream",
385 __FUNCTION__, mCameraId);
386 useAsync = true;
387 }
388
Ruben Brunkbba75572014-11-20 17:29:50 -0800389 int32_t disallowedFlags = GraphicBuffer::USAGE_HW_VIDEO_ENCODER |
390 GRALLOC_USAGE_RENDERSCRIPT;
391 int32_t allowedFlags = GraphicBuffer::USAGE_SW_READ_MASK |
392 GraphicBuffer::USAGE_HW_TEXTURE |
393 GraphicBuffer::USAGE_HW_COMPOSER;
394 bool flexibleConsumer = (consumerUsage & disallowedFlags) == 0 &&
395 (consumerUsage & allowedFlags) != 0;
396
Marco Nelissenf8880202014-11-14 07:58:25 -0800397 sp<IBinder> binder = IInterface::asBinder(bufferProducer);
Eino-Ville Talvalae992e752014-11-07 16:17:48 -0800398 sp<ANativeWindow> anw = new Surface(bufferProducer, useAsync);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700399
Eino-Ville Talvala3d82c0d2015-02-23 15:19:19 -0800400 int width, height, format;
401 android_dataspace dataSpace;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700402
403 if ((res = anw->query(anw.get(), NATIVE_WINDOW_WIDTH, &width)) != OK) {
404 ALOGE("%s: Camera %d: Failed to query Surface width", __FUNCTION__,
405 mCameraId);
406 return res;
407 }
408 if ((res = anw->query(anw.get(), NATIVE_WINDOW_HEIGHT, &height)) != OK) {
409 ALOGE("%s: Camera %d: Failed to query Surface height", __FUNCTION__,
410 mCameraId);
411 return res;
412 }
413 if ((res = anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &format)) != OK) {
414 ALOGE("%s: Camera %d: Failed to query Surface format", __FUNCTION__,
415 mCameraId);
416 return res;
417 }
Eino-Ville Talvala3d82c0d2015-02-23 15:19:19 -0800418 if ((res = anw->query(anw.get(), NATIVE_WINDOW_DEFAULT_DATASPACE,
419 reinterpret_cast<int*>(&dataSpace))) != OK) {
420 ALOGE("%s: Camera %d: Failed to query Surface dataSpace", __FUNCTION__,
421 mCameraId);
422 return res;
423 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700424
425 // FIXME: remove this override since the default format should be
426 // IMPLEMENTATION_DEFINED. b/9487482
Igor Murashkin15811012013-07-29 12:25:59 -0700427 if (format >= HAL_PIXEL_FORMAT_RGBA_8888 &&
428 format <= HAL_PIXEL_FORMAT_BGRA_8888) {
Ruben Brunkbba75572014-11-20 17:29:50 -0800429 ALOGW("%s: Camera %d: Overriding format %#x to IMPLEMENTATION_DEFINED",
Igor Murashkine7ee7632013-06-11 18:10:18 -0700430 __FUNCTION__, mCameraId, format);
431 format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
432 }
433
Ruben Brunkbba75572014-11-20 17:29:50 -0800434 // Round dimensions to the nearest dimensions available for this format
435 if (flexibleConsumer && !CameraDeviceClient::roundBufferDimensionNearest(width, height,
Eino-Ville Talvala3d82c0d2015-02-23 15:19:19 -0800436 format, dataSpace, mDevice->info(), /*out*/&width, /*out*/&height)) {
Ruben Brunkbba75572014-11-20 17:29:50 -0800437 ALOGE("%s: No stream configurations with the format %#x defined, failed to create stream.",
438 __FUNCTION__, format);
439 return BAD_VALUE;
440 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700441
442 int streamId = -1;
Eino-Ville Talvala3d82c0d2015-02-23 15:19:19 -0800443 res = mDevice->createStream(anw, width, height, format, dataSpace,
Yin-Chia Yehb97babb2015-03-12 13:42:44 -0700444 static_cast<camera3_stream_rotation_t>
445 (outputConfiguration.getRotation()),
446 &streamId);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700447
448 if (res == OK) {
Eino-Ville Talvalae992e752014-11-07 16:17:48 -0800449 mStreamMap.add(binder, streamId);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700450
451 ALOGV("%s: Camera %d: Successfully created a new stream ID %d",
452 __FUNCTION__, mCameraId, streamId);
Igor Murashkinf8b2a6f2013-09-17 17:03:28 -0700453
454 /**
455 * Set the stream transform flags to automatically
456 * rotate the camera stream for preview use cases.
457 */
458 int32_t transform = 0;
459 res = getRotationTransformLocked(&transform);
460
461 if (res != OK) {
462 // Error logged by getRotationTransformLocked.
463 return res;
464 }
465
466 res = mDevice->setStreamTransform(streamId, transform);
467 if (res != OK) {
468 ALOGE("%s: Failed to set stream transform (stream id %d)",
469 __FUNCTION__, streamId);
470 return res;
471 }
472
Igor Murashkine7ee7632013-06-11 18:10:18 -0700473 return streamId;
474 }
475
476 return res;
477}
478
Ruben Brunkbba75572014-11-20 17:29:50 -0800479
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700480status_t CameraDeviceClient::createInputStream(int width, int height,
481 int format) {
482
483 ATRACE_CALL();
484 ALOGV("%s (w = %d, h = %d, f = 0x%x)", __FUNCTION__, width, height, format);
485
486 status_t res;
487 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
488
489 Mutex::Autolock icl(mBinderSerializationLock);
490 if (!mDevice.get()) return DEAD_OBJECT;
491
492 if (mInputStream.configured) {
493 ALOGE("%s: Camera %d: Already has an input stream "
494 " configuration. (ID %zd)", __FUNCTION__, mCameraId,
495 mInputStream.id);
496 return ALREADY_EXISTS;
497 }
498
499 int streamId = -1;
500 res = mDevice->createInputStream(width, height, format, &streamId);
501 if (res == OK) {
502 mInputStream.configured = true;
503 mInputStream.width = width;
504 mInputStream.height = height;
505 mInputStream.format = format;
506 mInputStream.id = streamId;
507
508 ALOGV("%s: Camera %d: Successfully created a new input stream ID %d",
509 __FUNCTION__, mCameraId, streamId);
510
511 return streamId;
512 }
513
514 return res;
515}
516
517status_t CameraDeviceClient::getInputBufferProducer(
518 /*out*/sp<IGraphicBufferProducer> *producer) {
519 status_t res;
520 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
521
522 if (producer == NULL) {
523 return BAD_VALUE;
524 }
525
526 Mutex::Autolock icl(mBinderSerializationLock);
527 if (!mDevice.get()) return DEAD_OBJECT;
528
529 return mDevice->getInputBufferProducer(producer);
530}
531
Ruben Brunkbba75572014-11-20 17:29:50 -0800532bool CameraDeviceClient::roundBufferDimensionNearest(int32_t width, int32_t height,
Eino-Ville Talvala3d82c0d2015-02-23 15:19:19 -0800533 int32_t format, android_dataspace dataSpace, const CameraMetadata& info,
Ruben Brunkbba75572014-11-20 17:29:50 -0800534 /*out*/int32_t* outWidth, /*out*/int32_t* outHeight) {
535
536 camera_metadata_ro_entry streamConfigs =
Eino-Ville Talvala3d82c0d2015-02-23 15:19:19 -0800537 (dataSpace == HAL_DATASPACE_DEPTH) ?
538 info.find(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS) :
Ruben Brunkbba75572014-11-20 17:29:50 -0800539 info.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
540
541 int32_t bestWidth = -1;
542 int32_t bestHeight = -1;
543
544 // Iterate through listed stream configurations and find the one with the smallest euclidean
545 // distance from the given dimensions for the given format.
546 for (size_t i = 0; i < streamConfigs.count; i += 4) {
547 int32_t fmt = streamConfigs.data.i32[i];
548 int32_t w = streamConfigs.data.i32[i + 1];
549 int32_t h = streamConfigs.data.i32[i + 2];
550
551 // Ignore input/output type for now
552 if (fmt == format) {
553 if (w == width && h == height) {
554 bestWidth = width;
555 bestHeight = height;
556 break;
557 } else if (w <= ROUNDING_WIDTH_CAP && (bestWidth == -1 ||
558 CameraDeviceClient::euclidDistSquare(w, h, width, height) <
559 CameraDeviceClient::euclidDistSquare(bestWidth, bestHeight, width, height))) {
560 bestWidth = w;
561 bestHeight = h;
562 }
563 }
564 }
565
566 if (bestWidth == -1) {
567 // Return false if no configurations for this format were listed
568 return false;
569 }
570
571 // Set the outputs to the closet width/height
572 if (outWidth != NULL) {
573 *outWidth = bestWidth;
574 }
575 if (outHeight != NULL) {
576 *outHeight = bestHeight;
577 }
578
579 // Return true if at least one configuration for this format was listed
580 return true;
581}
582
583int64_t CameraDeviceClient::euclidDistSquare(int32_t x0, int32_t y0, int32_t x1, int32_t y1) {
584 int64_t d0 = x0 - x1;
585 int64_t d1 = y0 - y1;
586 return d0 * d0 + d1 * d1;
587}
588
Igor Murashkine7ee7632013-06-11 18:10:18 -0700589// Create a request object from a template.
590status_t CameraDeviceClient::createDefaultRequest(int templateId,
591 /*out*/
592 CameraMetadata* request)
593{
594 ATRACE_CALL();
595 ALOGV("%s (templateId = 0x%x)", __FUNCTION__, templateId);
596
597 status_t res;
598 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
599
600 Mutex::Autolock icl(mBinderSerializationLock);
601
602 if (!mDevice.get()) return DEAD_OBJECT;
603
604 CameraMetadata metadata;
605 if ( (res = mDevice->createDefaultRequest(templateId, &metadata) ) == OK &&
606 request != NULL) {
607
608 request->swap(metadata);
609 }
610
611 return res;
612}
613
Igor Murashkin099b4572013-07-12 17:52:16 -0700614status_t CameraDeviceClient::getCameraInfo(/*out*/CameraMetadata* info)
Igor Murashkine7ee7632013-06-11 18:10:18 -0700615{
616 ATRACE_CALL();
617 ALOGV("%s", __FUNCTION__);
618
619 status_t res = OK;
620
Igor Murashkine7ee7632013-06-11 18:10:18 -0700621 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
622
623 Mutex::Autolock icl(mBinderSerializationLock);
624
625 if (!mDevice.get()) return DEAD_OBJECT;
626
Igor Murashkin099b4572013-07-12 17:52:16 -0700627 if (info != NULL) {
628 *info = mDevice->info(); // static camera metadata
629 // TODO: merge with device-specific camera metadata
630 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700631
632 return res;
633}
634
Zhijun He2ab500c2013-07-23 08:02:53 -0700635status_t CameraDeviceClient::waitUntilIdle()
636{
637 ATRACE_CALL();
638 ALOGV("%s", __FUNCTION__);
639
640 status_t res = OK;
641 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
642
643 Mutex::Autolock icl(mBinderSerializationLock);
644
645 if (!mDevice.get()) return DEAD_OBJECT;
646
647 // FIXME: Also need check repeating burst.
648 if (!mStreamingRequestList.isEmpty()) {
649 ALOGE("%s: Camera %d: Try to waitUntilIdle when there are active streaming requests",
650 __FUNCTION__, mCameraId);
651 return INVALID_OPERATION;
652 }
653 res = mDevice->waitUntilDrained();
654 ALOGV("%s Done", __FUNCTION__);
655
656 return res;
657}
658
Jianing Weicb0652e2014-03-12 18:29:36 -0700659status_t CameraDeviceClient::flush(int64_t* lastFrameNumber) {
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700660 ATRACE_CALL();
661 ALOGV("%s", __FUNCTION__);
662
663 status_t res = OK;
664 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
665
666 Mutex::Autolock icl(mBinderSerializationLock);
667
668 if (!mDevice.get()) return DEAD_OBJECT;
669
Jianing Wei3c76fa32014-04-21 11:34:34 -0700670 mStreamingRequestList.clear();
Jianing Weicb0652e2014-03-12 18:29:36 -0700671 return mDevice->flush(lastFrameNumber);
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700672}
673
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700674status_t CameraDeviceClient::prepare(int streamId) {
675 ATRACE_CALL();
676 ALOGV("%s", __FUNCTION__);
677
678 status_t res = OK;
679 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
680
681 Mutex::Autolock icl(mBinderSerializationLock);
682
683 // Guard against trying to prepare non-created streams
684 ssize_t index = NAME_NOT_FOUND;
685 for (size_t i = 0; i < mStreamMap.size(); ++i) {
686 if (streamId == mStreamMap.valueAt(i)) {
687 index = i;
688 break;
689 }
690 }
691
692 if (index == NAME_NOT_FOUND) {
693 ALOGW("%s: Camera %d: Invalid stream ID (%d) specified, no stream "
694 "created yet", __FUNCTION__, mCameraId, streamId);
695 return BAD_VALUE;
696 }
697
698 // Also returns BAD_VALUE if stream ID was not valid
699 res = mDevice->prepare(streamId);
700
701 if (res == BAD_VALUE) {
702 ALOGE("%s: Camera %d: Unexpected BAD_VALUE when preparing stream, but we"
703 " already checked and the stream ID (%d) should be valid.",
704 __FUNCTION__, mCameraId, streamId);
705 }
706
707 return res;
708}
709
Igor Murashkine7ee7632013-06-11 18:10:18 -0700710status_t CameraDeviceClient::dump(int fd, const Vector<String16>& args) {
711 String8 result;
Eino-Ville Talvala67489d22014-09-18 15:52:02 -0700712 result.appendFormat("CameraDeviceClient[%d] (%p) dump:\n",
Igor Murashkine7ee7632013-06-11 18:10:18 -0700713 mCameraId,
Eino-Ville Talvalae992e752014-11-07 16:17:48 -0800714 (getRemoteCallback() != NULL ?
Marco Nelissenf8880202014-11-14 07:58:25 -0800715 IInterface::asBinder(getRemoteCallback()).get() : NULL) );
Ruben Brunkcc776712015-02-17 20:18:47 -0800716 result.appendFormat(" Current client UID %u\n", mClientUid);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700717
Eino-Ville Talvala67489d22014-09-18 15:52:02 -0700718 result.append(" State:\n");
719 result.appendFormat(" Request ID counter: %d\n", mRequestIdCounter);
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700720 if (mInputStream.configured) {
721 result.appendFormat(" Current input stream ID: %d\n",
722 mInputStream.id);
723 } else {
724 result.append(" No input stream configured.\n");
725 }
Eino-Ville Talvala67489d22014-09-18 15:52:02 -0700726 if (!mStreamMap.isEmpty()) {
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700727 result.append(" Current output stream IDs:\n");
Eino-Ville Talvala67489d22014-09-18 15:52:02 -0700728 for (size_t i = 0; i < mStreamMap.size(); i++) {
729 result.appendFormat(" Stream %d\n", mStreamMap.valueAt(i));
730 }
731 } else {
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700732 result.append(" No output streams configured.\n");
Eino-Ville Talvala67489d22014-09-18 15:52:02 -0700733 }
734 write(fd, result.string(), result.size());
Igor Murashkine7ee7632013-06-11 18:10:18 -0700735 // TODO: print dynamic/request section from most recent requests
736 mFrameProcessor->dump(fd, args);
737
738 return dumpDevice(fd, args);
739}
740
Jianing Weicb0652e2014-03-12 18:29:36 -0700741void CameraDeviceClient::notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
742 const CaptureResultExtras& resultExtras) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700743 // Thread safe. Don't bother locking.
744 sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
745
746 if (remoteCb != 0) {
Jianing Weicb0652e2014-03-12 18:29:36 -0700747 remoteCb->onDeviceError(errorCode, resultExtras);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700748 }
749}
750
751void CameraDeviceClient::notifyIdle() {
752 // Thread safe. Don't bother locking.
753 sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
754
755 if (remoteCb != 0) {
756 remoteCb->onDeviceIdle();
757 }
758}
759
Jianing Weicb0652e2014-03-12 18:29:36 -0700760void CameraDeviceClient::notifyShutter(const CaptureResultExtras& resultExtras,
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700761 nsecs_t timestamp) {
762 // Thread safe. Don't bother locking.
763 sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
764 if (remoteCb != 0) {
Jianing Weicb0652e2014-03-12 18:29:36 -0700765 remoteCb->onCaptureStarted(resultExtras, timestamp);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700766 }
767}
768
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700769void CameraDeviceClient::notifyPrepared(int streamId) {
770 // Thread safe. Don't bother locking.
771 sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
772 if (remoteCb != 0) {
773 remoteCb->onPrepared(streamId);
774 }
775}
776
Igor Murashkine7ee7632013-06-11 18:10:18 -0700777void CameraDeviceClient::detachDevice() {
778 if (mDevice == 0) return;
779
780 ALOGV("Camera %d: Stopping processors", mCameraId);
781
782 mFrameProcessor->removeListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
783 FRAME_PROCESSOR_LISTENER_MAX_ID,
784 /*listener*/this);
785 mFrameProcessor->requestExit();
786 ALOGV("Camera %d: Waiting for threads", mCameraId);
787 mFrameProcessor->join();
788 ALOGV("Camera %d: Disconnecting device", mCameraId);
789
790 // WORKAROUND: HAL refuses to disconnect while there's streams in flight
791 {
792 mDevice->clearStreamingRequest();
793
794 status_t code;
795 if ((code = mDevice->waitUntilDrained()) != OK) {
796 ALOGE("%s: waitUntilDrained failed with code 0x%x", __FUNCTION__,
797 code);
798 }
799 }
800
801 Camera2ClientBase::detachDevice();
802}
803
804/** Device-related methods */
Jianing Weicb0652e2014-03-12 18:29:36 -0700805void CameraDeviceClient::onResultAvailable(const CaptureResult& result) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700806 ATRACE_CALL();
807 ALOGV("%s", __FUNCTION__);
808
Igor Murashkin4fb55c12013-08-29 17:43:01 -0700809 // Thread-safe. No lock necessary.
810 sp<ICameraDeviceCallbacks> remoteCb = mRemoteCallback;
811 if (remoteCb != NULL) {
Jianing Weicb0652e2014-03-12 18:29:36 -0700812 remoteCb->onResultReceived(result.mMetadata, result.mResultExtras);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700813 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700814}
815
816// TODO: move to Camera2ClientBase
817bool CameraDeviceClient::enforceRequestPermissions(CameraMetadata& metadata) {
818
819 const int pid = IPCThreadState::self()->getCallingPid();
820 const int selfPid = getpid();
821 camera_metadata_entry_t entry;
822
823 /**
824 * Mixin default important security values
825 * - android.led.transmit = defaulted ON
826 */
827 CameraMetadata staticInfo = mDevice->info();
828 entry = staticInfo.find(ANDROID_LED_AVAILABLE_LEDS);
829 for(size_t i = 0; i < entry.count; ++i) {
830 uint8_t led = entry.data.u8[i];
831
832 switch(led) {
833 case ANDROID_LED_AVAILABLE_LEDS_TRANSMIT: {
834 uint8_t transmitDefault = ANDROID_LED_TRANSMIT_ON;
835 if (!metadata.exists(ANDROID_LED_TRANSMIT)) {
836 metadata.update(ANDROID_LED_TRANSMIT,
837 &transmitDefault, 1);
838 }
839 break;
840 }
841 }
842 }
843
844 // We can do anything!
845 if (pid == selfPid) {
846 return true;
847 }
848
849 /**
850 * Permission check special fields in the request
851 * - android.led.transmit = android.permission.CAMERA_DISABLE_TRANSMIT
852 */
853 entry = metadata.find(ANDROID_LED_TRANSMIT);
854 if (entry.count > 0 && entry.data.u8[0] != ANDROID_LED_TRANSMIT_ON) {
855 String16 permissionString =
856 String16("android.permission.CAMERA_DISABLE_TRANSMIT_LED");
857 if (!checkCallingPermission(permissionString)) {
858 const int uid = IPCThreadState::self()->getCallingUid();
859 ALOGE("Permission Denial: "
860 "can't disable transmit LED pid=%d, uid=%d", pid, uid);
861 return false;
862 }
863 }
864
865 return true;
866}
867
Igor Murashkinf8b2a6f2013-09-17 17:03:28 -0700868status_t CameraDeviceClient::getRotationTransformLocked(int32_t* transform) {
869 ALOGV("%s: begin", __FUNCTION__);
870
Igor Murashkinf8b2a6f2013-09-17 17:03:28 -0700871 const CameraMetadata& staticInfo = mDevice->info();
Ruben Brunk5698d442014-06-18 10:39:40 -0700872 return CameraUtils::getRotationTransform(staticInfo, transform);
Igor Murashkinf8b2a6f2013-09-17 17:03:28 -0700873}
874
Igor Murashkine7ee7632013-06-11 18:10:18 -0700875} // namespace android