blob: 3b83f63eb3dadf10937340c36a08c0fc7c3c1bfa [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;
131
132 for (List<sp<CaptureRequest> >::iterator it = requests.begin(); it != requests.end(); ++it) {
133 sp<CaptureRequest> request = *it;
134 if (request == 0) {
135 ALOGE("%s: Camera %d: Sent null request.",
136 __FUNCTION__, mCameraId);
137 return BAD_VALUE;
Chien-Yu Chened0412e2015-04-27 15:04:22 -0700138 } else if (request->mIsReprocess) {
139 if (!mInputStream.configured) {
140 ALOGE("%s: Camera %d: no input stream is configured.", __FUNCTION__, mCameraId);
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700141 return BAD_VALUE;
Chien-Yu Chened0412e2015-04-27 15:04:22 -0700142 } else if (streaming) {
143 ALOGE("%s: Camera %d: streaming reprocess requests not supported.", __FUNCTION__,
144 mCameraId);
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700145 return BAD_VALUE;
146 }
Jianing Wei90e59c92014-03-12 18:29:36 -0700147 }
148
149 CameraMetadata metadata(request->mMetadata);
150 if (metadata.isEmpty()) {
151 ALOGE("%s: Camera %d: Sent empty metadata packet. Rejecting request.",
152 __FUNCTION__, mCameraId);
153 return BAD_VALUE;
154 } else if (request->mSurfaceList.isEmpty()) {
155 ALOGE("%s: Camera %d: Requests must have at least one surface target. "
156 "Rejecting request.", __FUNCTION__, mCameraId);
157 return BAD_VALUE;
158 }
159
160 if (!enforceRequestPermissions(metadata)) {
161 // Callee logs
162 return PERMISSION_DENIED;
163 }
164
165 /**
166 * Write in the output stream IDs which we calculate from
167 * the capture request's list of surface targets
168 */
169 Vector<int32_t> outputStreamIds;
170 outputStreamIds.setCapacity(request->mSurfaceList.size());
Jianing Weicb0652e2014-03-12 18:29:36 -0700171 for (size_t i = 0; i < request->mSurfaceList.size(); ++i) {
172 sp<Surface> surface = request->mSurfaceList[i];
Jianing Wei90e59c92014-03-12 18:29:36 -0700173 if (surface == 0) continue;
174
175 sp<IGraphicBufferProducer> gbp = surface->getIGraphicBufferProducer();
Marco Nelissenf8880202014-11-14 07:58:25 -0800176 int idx = mStreamMap.indexOfKey(IInterface::asBinder(gbp));
Jianing Wei90e59c92014-03-12 18:29:36 -0700177
178 // Trying to submit request with surface that wasn't created
179 if (idx == NAME_NOT_FOUND) {
180 ALOGE("%s: Camera %d: Tried to submit a request with a surface that"
181 " we have not called createStream on",
182 __FUNCTION__, mCameraId);
183 return BAD_VALUE;
184 }
185
186 int streamId = mStreamMap.valueAt(idx);
187 outputStreamIds.push_back(streamId);
188 ALOGV("%s: Camera %d: Appending output stream %d to request",
189 __FUNCTION__, mCameraId, streamId);
190 }
191
192 metadata.update(ANDROID_REQUEST_OUTPUT_STREAMS, &outputStreamIds[0],
193 outputStreamIds.size());
194
Chien-Yu Chened0412e2015-04-27 15:04:22 -0700195 if (request->mIsReprocess) {
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700196 metadata.update(ANDROID_REQUEST_INPUT_STREAMS, &mInputStream.id, 1);
197 }
198
Jianing Wei90e59c92014-03-12 18:29:36 -0700199 metadata.update(ANDROID_REQUEST_ID, &requestId, /*size*/1);
200 loopCounter++; // loopCounter starts from 1
Mark Salyzyn50468412014-06-18 16:33:43 -0700201 ALOGV("%s: Camera %d: Creating request with ID %d (%d of %zu)",
Jianing Wei90e59c92014-03-12 18:29:36 -0700202 __FUNCTION__, mCameraId, requestId, loopCounter, requests.size());
203
204 metadataRequestList.push_back(metadata);
205 }
206 mRequestIdCounter++;
207
208 if (streaming) {
Jianing Weicb0652e2014-03-12 18:29:36 -0700209 res = mDevice->setStreamingRequestList(metadataRequestList, lastFrameNumber);
Jianing Wei90e59c92014-03-12 18:29:36 -0700210 if (res != OK) {
211 ALOGE("%s: Camera %d: Got error %d after trying to set streaming "
212 "request", __FUNCTION__, mCameraId, res);
213 } else {
214 mStreamingRequestList.push_back(requestId);
215 }
216 } else {
Jianing Weicb0652e2014-03-12 18:29:36 -0700217 res = mDevice->captureList(metadataRequestList, lastFrameNumber);
Jianing Wei90e59c92014-03-12 18:29:36 -0700218 if (res != OK) {
219 ALOGE("%s: Camera %d: Got error %d after trying to set capture",
220 __FUNCTION__, mCameraId, res);
221 }
Jianing Weicb0652e2014-03-12 18:29:36 -0700222 ALOGV("%s: requestId = %d ", __FUNCTION__, requestId);
Jianing Wei90e59c92014-03-12 18:29:36 -0700223 }
224
225 ALOGV("%s: Camera %d: End of function", __FUNCTION__, mCameraId);
226 if (res == OK) {
227 return requestId;
228 }
229
230 return res;
231}
232
Jianing Weicb0652e2014-03-12 18:29:36 -0700233status_t CameraDeviceClient::cancelRequest(int requestId, int64_t* lastFrameNumber) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700234 ATRACE_CALL();
235 ALOGV("%s, requestId = %d", __FUNCTION__, requestId);
236
237 status_t res;
238
239 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
240
241 Mutex::Autolock icl(mBinderSerializationLock);
242
243 if (!mDevice.get()) return DEAD_OBJECT;
244
245 Vector<int>::iterator it, end;
246 for (it = mStreamingRequestList.begin(), end = mStreamingRequestList.end();
247 it != end; ++it) {
248 if (*it == requestId) {
249 break;
250 }
251 }
252
253 if (it == end) {
254 ALOGE("%s: Camera%d: Did not find request id %d in list of streaming "
255 "requests", __FUNCTION__, mCameraId, requestId);
256 return BAD_VALUE;
257 }
258
Jianing Weicb0652e2014-03-12 18:29:36 -0700259 res = mDevice->clearStreamingRequest(lastFrameNumber);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700260
261 if (res == OK) {
262 ALOGV("%s: Camera %d: Successfully cleared streaming request",
263 __FUNCTION__, mCameraId);
264 mStreamingRequestList.erase(it);
265 }
266
267 return res;
268}
269
Ruben Brunkb2119af2014-05-09 19:57:56 -0700270status_t CameraDeviceClient::beginConfigure() {
271 // TODO: Implement this.
Zhijun He1fa89992015-06-01 15:44:31 -0700272 ALOGV("%s: Not implemented yet.", __FUNCTION__);
Ruben Brunkb2119af2014-05-09 19:57:56 -0700273 return OK;
274}
275
Zhijun He1fa89992015-06-01 15:44:31 -0700276status_t CameraDeviceClient::endConfigure(bool isConstrainedHighSpeed) {
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700277 ALOGV("%s: ending configure (%d input stream, %zu output streams)",
278 __FUNCTION__, mInputStream.configured ? 1 : 0, mStreamMap.size());
Igor Murashkine2d167e2014-08-19 16:19:59 -0700279
Zhijun He1fa89992015-06-01 15:44:31 -0700280 // Sanitize the high speed session against necessary capability bit.
281 if (isConstrainedHighSpeed) {
282 CameraMetadata staticInfo = mDevice->info();
283 camera_metadata_entry_t entry = staticInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
284 bool isConstrainedHighSpeedSupported = false;
285 for(size_t i = 0; i < entry.count; ++i) {
286 uint8_t capability = entry.data.u8[i];
287 if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO) {
288 isConstrainedHighSpeedSupported = true;
289 break;
290 }
291 }
292 if (!isConstrainedHighSpeedSupported) {
293 ALOGE("%s: Camera %d: Try to create a constrained high speed configuration on a device"
294 " that doesn't support it.",
295 __FUNCTION__, mCameraId);
296 return INVALID_OPERATION;
297 }
298 }
299
Igor Murashkine2d167e2014-08-19 16:19:59 -0700300 status_t res;
301 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
302
303 Mutex::Autolock icl(mBinderSerializationLock);
304
305 if (!mDevice.get()) return DEAD_OBJECT;
306
Zhijun He1fa89992015-06-01 15:44:31 -0700307 return mDevice->configureStreams(isConstrainedHighSpeed);
Ruben Brunkb2119af2014-05-09 19:57:56 -0700308}
309
Igor Murashkine7ee7632013-06-11 18:10:18 -0700310status_t CameraDeviceClient::deleteStream(int streamId) {
311 ATRACE_CALL();
312 ALOGV("%s (streamId = 0x%x)", __FUNCTION__, streamId);
313
314 status_t res;
315 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
316
317 Mutex::Autolock icl(mBinderSerializationLock);
318
319 if (!mDevice.get()) return DEAD_OBJECT;
320
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700321 bool isInput = false;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700322 ssize_t index = NAME_NOT_FOUND;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700323
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700324 if (mInputStream.configured && mInputStream.id == streamId) {
325 isInput = true;
326 } else {
327 // Guard against trying to delete non-created streams
328 for (size_t i = 0; i < mStreamMap.size(); ++i) {
329 if (streamId == mStreamMap.valueAt(i)) {
330 index = i;
331 break;
332 }
333 }
334
335 if (index == NAME_NOT_FOUND) {
336 ALOGW("%s: Camera %d: Invalid stream ID (%d) specified, no stream "
337 "created yet", __FUNCTION__, mCameraId, streamId);
338 return BAD_VALUE;
339 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700340 }
341
342 // Also returns BAD_VALUE if stream ID was not valid
343 res = mDevice->deleteStream(streamId);
344
345 if (res == BAD_VALUE) {
346 ALOGE("%s: Camera %d: Unexpected BAD_VALUE when deleting stream, but we"
347 " already checked and the stream ID (%d) should be valid.",
348 __FUNCTION__, mCameraId, streamId);
349 } else if (res == OK) {
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700350 if (isInput) {
351 mInputStream.configured = false;
352 } else {
353 mStreamMap.removeItemsAt(index);
354 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700355 }
356
357 return res;
358}
359
Yin-Chia Yehb97babb2015-03-12 13:42:44 -0700360status_t CameraDeviceClient::createStream(const OutputConfiguration &outputConfiguration)
Igor Murashkine7ee7632013-06-11 18:10:18 -0700361{
362 ATRACE_CALL();
Igor Murashkine7ee7632013-06-11 18:10:18 -0700363
364 status_t res;
365 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
366
367 Mutex::Autolock icl(mBinderSerializationLock);
368
Yin-Chia Yehb97babb2015-03-12 13:42:44 -0700369
370 sp<IGraphicBufferProducer> bufferProducer = outputConfiguration.getGraphicBufferProducer();
Yin-Chia Yeh89f14da2014-06-10 16:05:44 -0700371 if (bufferProducer == NULL) {
372 ALOGE("%s: bufferProducer must not be null", __FUNCTION__);
373 return BAD_VALUE;
374 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700375 if (!mDevice.get()) return DEAD_OBJECT;
376
377 // Don't create multiple streams for the same target surface
378 {
Marco Nelissenf8880202014-11-14 07:58:25 -0800379 ssize_t index = mStreamMap.indexOfKey(IInterface::asBinder(bufferProducer));
Igor Murashkine7ee7632013-06-11 18:10:18 -0700380 if (index != NAME_NOT_FOUND) {
381 ALOGW("%s: Camera %d: Buffer producer already has a stream for it "
Colin Crosse5729fa2014-03-21 15:04:25 -0700382 "(ID %zd)",
Igor Murashkine7ee7632013-06-11 18:10:18 -0700383 __FUNCTION__, mCameraId, index);
384 return ALREADY_EXISTS;
385 }
386 }
387
Eino-Ville Talvala1da3b602013-09-26 15:28:55 -0700388 // HACK b/10949105
389 // Query consumer usage bits to set async operation mode for
390 // GLConsumer using controlledByApp parameter.
391 bool useAsync = false;
392 int32_t consumerUsage;
393 if ((res = bufferProducer->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS,
394 &consumerUsage)) != OK) {
395 ALOGE("%s: Camera %d: Failed to query consumer usage", __FUNCTION__,
396 mCameraId);
397 return res;
398 }
399 if (consumerUsage & GraphicBuffer::USAGE_HW_TEXTURE) {
400 ALOGW("%s: Camera %d: Forcing asynchronous mode for stream",
401 __FUNCTION__, mCameraId);
402 useAsync = true;
403 }
404
Ruben Brunkbba75572014-11-20 17:29:50 -0800405 int32_t disallowedFlags = GraphicBuffer::USAGE_HW_VIDEO_ENCODER |
406 GRALLOC_USAGE_RENDERSCRIPT;
407 int32_t allowedFlags = GraphicBuffer::USAGE_SW_READ_MASK |
408 GraphicBuffer::USAGE_HW_TEXTURE |
409 GraphicBuffer::USAGE_HW_COMPOSER;
410 bool flexibleConsumer = (consumerUsage & disallowedFlags) == 0 &&
411 (consumerUsage & allowedFlags) != 0;
412
Marco Nelissenf8880202014-11-14 07:58:25 -0800413 sp<IBinder> binder = IInterface::asBinder(bufferProducer);
Eino-Ville Talvala727d1722015-06-09 13:44:19 -0700414 sp<Surface> surface = new Surface(bufferProducer, useAsync);
415 ANativeWindow *anw = surface.get();
Igor Murashkine7ee7632013-06-11 18:10:18 -0700416
Eino-Ville Talvala3d82c0d2015-02-23 15:19:19 -0800417 int width, height, format;
418 android_dataspace dataSpace;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700419
Eino-Ville Talvala727d1722015-06-09 13:44:19 -0700420 if ((res = anw->query(anw, NATIVE_WINDOW_WIDTH, &width)) != OK) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700421 ALOGE("%s: Camera %d: Failed to query Surface width", __FUNCTION__,
422 mCameraId);
423 return res;
424 }
Eino-Ville Talvala727d1722015-06-09 13:44:19 -0700425 if ((res = anw->query(anw, NATIVE_WINDOW_HEIGHT, &height)) != OK) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700426 ALOGE("%s: Camera %d: Failed to query Surface height", __FUNCTION__,
427 mCameraId);
428 return res;
429 }
Eino-Ville Talvala727d1722015-06-09 13:44:19 -0700430 if ((res = anw->query(anw, NATIVE_WINDOW_FORMAT, &format)) != OK) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700431 ALOGE("%s: Camera %d: Failed to query Surface format", __FUNCTION__,
432 mCameraId);
433 return res;
434 }
Eino-Ville Talvala727d1722015-06-09 13:44:19 -0700435 if ((res = anw->query(anw, NATIVE_WINDOW_DEFAULT_DATASPACE,
Eino-Ville Talvala3d82c0d2015-02-23 15:19:19 -0800436 reinterpret_cast<int*>(&dataSpace))) != OK) {
437 ALOGE("%s: Camera %d: Failed to query Surface dataSpace", __FUNCTION__,
438 mCameraId);
439 return res;
440 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700441
442 // FIXME: remove this override since the default format should be
443 // IMPLEMENTATION_DEFINED. b/9487482
Igor Murashkin15811012013-07-29 12:25:59 -0700444 if (format >= HAL_PIXEL_FORMAT_RGBA_8888 &&
445 format <= HAL_PIXEL_FORMAT_BGRA_8888) {
Ruben Brunkbba75572014-11-20 17:29:50 -0800446 ALOGW("%s: Camera %d: Overriding format %#x to IMPLEMENTATION_DEFINED",
Igor Murashkine7ee7632013-06-11 18:10:18 -0700447 __FUNCTION__, mCameraId, format);
448 format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
449 }
450
Ruben Brunkbba75572014-11-20 17:29:50 -0800451 // Round dimensions to the nearest dimensions available for this format
452 if (flexibleConsumer && !CameraDeviceClient::roundBufferDimensionNearest(width, height,
Eino-Ville Talvala3d82c0d2015-02-23 15:19:19 -0800453 format, dataSpace, mDevice->info(), /*out*/&width, /*out*/&height)) {
Ruben Brunkbba75572014-11-20 17:29:50 -0800454 ALOGE("%s: No stream configurations with the format %#x defined, failed to create stream.",
455 __FUNCTION__, format);
456 return BAD_VALUE;
457 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700458
459 int streamId = -1;
Eino-Ville Talvala727d1722015-06-09 13:44:19 -0700460 res = mDevice->createStream(surface, width, height, format, dataSpace,
Yin-Chia Yehb97babb2015-03-12 13:42:44 -0700461 static_cast<camera3_stream_rotation_t>
462 (outputConfiguration.getRotation()),
463 &streamId);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700464
465 if (res == OK) {
Eino-Ville Talvalae992e752014-11-07 16:17:48 -0800466 mStreamMap.add(binder, streamId);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700467
468 ALOGV("%s: Camera %d: Successfully created a new stream ID %d",
469 __FUNCTION__, mCameraId, streamId);
Igor Murashkinf8b2a6f2013-09-17 17:03:28 -0700470
471 /**
472 * Set the stream transform flags to automatically
473 * rotate the camera stream for preview use cases.
474 */
475 int32_t transform = 0;
476 res = getRotationTransformLocked(&transform);
477
478 if (res != OK) {
479 // Error logged by getRotationTransformLocked.
480 return res;
481 }
482
483 res = mDevice->setStreamTransform(streamId, transform);
484 if (res != OK) {
485 ALOGE("%s: Failed to set stream transform (stream id %d)",
486 __FUNCTION__, streamId);
487 return res;
488 }
489
Igor Murashkine7ee7632013-06-11 18:10:18 -0700490 return streamId;
491 }
492
493 return res;
494}
495
Ruben Brunkbba75572014-11-20 17:29:50 -0800496
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700497status_t CameraDeviceClient::createInputStream(int width, int height,
498 int format) {
499
500 ATRACE_CALL();
501 ALOGV("%s (w = %d, h = %d, f = 0x%x)", __FUNCTION__, width, height, format);
502
503 status_t res;
504 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
505
506 Mutex::Autolock icl(mBinderSerializationLock);
507 if (!mDevice.get()) return DEAD_OBJECT;
508
509 if (mInputStream.configured) {
510 ALOGE("%s: Camera %d: Already has an input stream "
511 " configuration. (ID %zd)", __FUNCTION__, mCameraId,
512 mInputStream.id);
513 return ALREADY_EXISTS;
514 }
515
516 int streamId = -1;
517 res = mDevice->createInputStream(width, height, format, &streamId);
518 if (res == OK) {
519 mInputStream.configured = true;
520 mInputStream.width = width;
521 mInputStream.height = height;
522 mInputStream.format = format;
523 mInputStream.id = streamId;
524
525 ALOGV("%s: Camera %d: Successfully created a new input stream ID %d",
526 __FUNCTION__, mCameraId, streamId);
527
528 return streamId;
529 }
530
531 return res;
532}
533
534status_t CameraDeviceClient::getInputBufferProducer(
535 /*out*/sp<IGraphicBufferProducer> *producer) {
536 status_t res;
537 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
538
539 if (producer == NULL) {
540 return BAD_VALUE;
541 }
542
543 Mutex::Autolock icl(mBinderSerializationLock);
544 if (!mDevice.get()) return DEAD_OBJECT;
545
546 return mDevice->getInputBufferProducer(producer);
547}
548
Ruben Brunkbba75572014-11-20 17:29:50 -0800549bool CameraDeviceClient::roundBufferDimensionNearest(int32_t width, int32_t height,
Eino-Ville Talvala3d82c0d2015-02-23 15:19:19 -0800550 int32_t format, android_dataspace dataSpace, const CameraMetadata& info,
Ruben Brunkbba75572014-11-20 17:29:50 -0800551 /*out*/int32_t* outWidth, /*out*/int32_t* outHeight) {
552
553 camera_metadata_ro_entry streamConfigs =
Eino-Ville Talvala3d82c0d2015-02-23 15:19:19 -0800554 (dataSpace == HAL_DATASPACE_DEPTH) ?
555 info.find(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS) :
Ruben Brunkbba75572014-11-20 17:29:50 -0800556 info.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
557
558 int32_t bestWidth = -1;
559 int32_t bestHeight = -1;
560
561 // Iterate through listed stream configurations and find the one with the smallest euclidean
562 // distance from the given dimensions for the given format.
563 for (size_t i = 0; i < streamConfigs.count; i += 4) {
564 int32_t fmt = streamConfigs.data.i32[i];
565 int32_t w = streamConfigs.data.i32[i + 1];
566 int32_t h = streamConfigs.data.i32[i + 2];
567
568 // Ignore input/output type for now
569 if (fmt == format) {
570 if (w == width && h == height) {
571 bestWidth = width;
572 bestHeight = height;
573 break;
574 } else if (w <= ROUNDING_WIDTH_CAP && (bestWidth == -1 ||
575 CameraDeviceClient::euclidDistSquare(w, h, width, height) <
576 CameraDeviceClient::euclidDistSquare(bestWidth, bestHeight, width, height))) {
577 bestWidth = w;
578 bestHeight = h;
579 }
580 }
581 }
582
583 if (bestWidth == -1) {
584 // Return false if no configurations for this format were listed
585 return false;
586 }
587
588 // Set the outputs to the closet width/height
589 if (outWidth != NULL) {
590 *outWidth = bestWidth;
591 }
592 if (outHeight != NULL) {
593 *outHeight = bestHeight;
594 }
595
596 // Return true if at least one configuration for this format was listed
597 return true;
598}
599
600int64_t CameraDeviceClient::euclidDistSquare(int32_t x0, int32_t y0, int32_t x1, int32_t y1) {
601 int64_t d0 = x0 - x1;
602 int64_t d1 = y0 - y1;
603 return d0 * d0 + d1 * d1;
604}
605
Igor Murashkine7ee7632013-06-11 18:10:18 -0700606// Create a request object from a template.
607status_t CameraDeviceClient::createDefaultRequest(int templateId,
608 /*out*/
609 CameraMetadata* request)
610{
611 ATRACE_CALL();
612 ALOGV("%s (templateId = 0x%x)", __FUNCTION__, templateId);
613
614 status_t res;
615 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
616
617 Mutex::Autolock icl(mBinderSerializationLock);
618
619 if (!mDevice.get()) return DEAD_OBJECT;
620
621 CameraMetadata metadata;
622 if ( (res = mDevice->createDefaultRequest(templateId, &metadata) ) == OK &&
623 request != NULL) {
624
625 request->swap(metadata);
626 }
627
628 return res;
629}
630
Igor Murashkin099b4572013-07-12 17:52:16 -0700631status_t CameraDeviceClient::getCameraInfo(/*out*/CameraMetadata* info)
Igor Murashkine7ee7632013-06-11 18:10:18 -0700632{
633 ATRACE_CALL();
634 ALOGV("%s", __FUNCTION__);
635
636 status_t res = OK;
637
Igor Murashkine7ee7632013-06-11 18:10:18 -0700638 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
639
640 Mutex::Autolock icl(mBinderSerializationLock);
641
642 if (!mDevice.get()) return DEAD_OBJECT;
643
Igor Murashkin099b4572013-07-12 17:52:16 -0700644 if (info != NULL) {
645 *info = mDevice->info(); // static camera metadata
646 // TODO: merge with device-specific camera metadata
647 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700648
649 return res;
650}
651
Zhijun He2ab500c2013-07-23 08:02:53 -0700652status_t CameraDeviceClient::waitUntilIdle()
653{
654 ATRACE_CALL();
655 ALOGV("%s", __FUNCTION__);
656
657 status_t res = OK;
658 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
659
660 Mutex::Autolock icl(mBinderSerializationLock);
661
662 if (!mDevice.get()) return DEAD_OBJECT;
663
664 // FIXME: Also need check repeating burst.
665 if (!mStreamingRequestList.isEmpty()) {
666 ALOGE("%s: Camera %d: Try to waitUntilIdle when there are active streaming requests",
667 __FUNCTION__, mCameraId);
668 return INVALID_OPERATION;
669 }
670 res = mDevice->waitUntilDrained();
671 ALOGV("%s Done", __FUNCTION__);
672
673 return res;
674}
675
Jianing Weicb0652e2014-03-12 18:29:36 -0700676status_t CameraDeviceClient::flush(int64_t* lastFrameNumber) {
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700677 ATRACE_CALL();
678 ALOGV("%s", __FUNCTION__);
679
680 status_t res = OK;
681 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
682
683 Mutex::Autolock icl(mBinderSerializationLock);
684
685 if (!mDevice.get()) return DEAD_OBJECT;
686
Jianing Wei3c76fa32014-04-21 11:34:34 -0700687 mStreamingRequestList.clear();
Jianing Weicb0652e2014-03-12 18:29:36 -0700688 return mDevice->flush(lastFrameNumber);
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700689}
690
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700691status_t CameraDeviceClient::prepare(int streamId) {
692 ATRACE_CALL();
693 ALOGV("%s", __FUNCTION__);
694
695 status_t res = OK;
696 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
697
698 Mutex::Autolock icl(mBinderSerializationLock);
699
700 // Guard against trying to prepare non-created streams
701 ssize_t index = NAME_NOT_FOUND;
702 for (size_t i = 0; i < mStreamMap.size(); ++i) {
703 if (streamId == mStreamMap.valueAt(i)) {
704 index = i;
705 break;
706 }
707 }
708
709 if (index == NAME_NOT_FOUND) {
710 ALOGW("%s: Camera %d: Invalid stream ID (%d) specified, no stream "
711 "created yet", __FUNCTION__, mCameraId, streamId);
712 return BAD_VALUE;
713 }
714
Eino-Ville Talvala261394e2015-05-13 14:28:38 -0700715 // Also returns BAD_VALUE if stream ID was not valid, or stream already
716 // has been used
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700717 res = mDevice->prepare(streamId);
718
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700719 return res;
720}
721
Igor Murashkine7ee7632013-06-11 18:10:18 -0700722status_t CameraDeviceClient::dump(int fd, const Vector<String16>& args) {
723 String8 result;
Eino-Ville Talvala67489d22014-09-18 15:52:02 -0700724 result.appendFormat("CameraDeviceClient[%d] (%p) dump:\n",
Igor Murashkine7ee7632013-06-11 18:10:18 -0700725 mCameraId,
Eino-Ville Talvalae992e752014-11-07 16:17:48 -0800726 (getRemoteCallback() != NULL ?
Marco Nelissenf8880202014-11-14 07:58:25 -0800727 IInterface::asBinder(getRemoteCallback()).get() : NULL) );
Ruben Brunkcc776712015-02-17 20:18:47 -0800728 result.appendFormat(" Current client UID %u\n", mClientUid);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700729
Eino-Ville Talvala67489d22014-09-18 15:52:02 -0700730 result.append(" State:\n");
731 result.appendFormat(" Request ID counter: %d\n", mRequestIdCounter);
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700732 if (mInputStream.configured) {
733 result.appendFormat(" Current input stream ID: %d\n",
734 mInputStream.id);
735 } else {
736 result.append(" No input stream configured.\n");
737 }
Eino-Ville Talvala67489d22014-09-18 15:52:02 -0700738 if (!mStreamMap.isEmpty()) {
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700739 result.append(" Current output stream IDs:\n");
Eino-Ville Talvala67489d22014-09-18 15:52:02 -0700740 for (size_t i = 0; i < mStreamMap.size(); i++) {
741 result.appendFormat(" Stream %d\n", mStreamMap.valueAt(i));
742 }
743 } else {
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700744 result.append(" No output streams configured.\n");
Eino-Ville Talvala67489d22014-09-18 15:52:02 -0700745 }
746 write(fd, result.string(), result.size());
Igor Murashkine7ee7632013-06-11 18:10:18 -0700747 // TODO: print dynamic/request section from most recent requests
748 mFrameProcessor->dump(fd, args);
749
750 return dumpDevice(fd, args);
751}
752
Jianing Weicb0652e2014-03-12 18:29:36 -0700753void CameraDeviceClient::notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
754 const CaptureResultExtras& resultExtras) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700755 // Thread safe. Don't bother locking.
756 sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
757
758 if (remoteCb != 0) {
Jianing Weicb0652e2014-03-12 18:29:36 -0700759 remoteCb->onDeviceError(errorCode, resultExtras);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700760 }
761}
762
763void CameraDeviceClient::notifyIdle() {
764 // Thread safe. Don't bother locking.
765 sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
766
767 if (remoteCb != 0) {
768 remoteCb->onDeviceIdle();
769 }
770}
771
Jianing Weicb0652e2014-03-12 18:29:36 -0700772void CameraDeviceClient::notifyShutter(const CaptureResultExtras& resultExtras,
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700773 nsecs_t timestamp) {
774 // Thread safe. Don't bother locking.
775 sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
776 if (remoteCb != 0) {
Jianing Weicb0652e2014-03-12 18:29:36 -0700777 remoteCb->onCaptureStarted(resultExtras, timestamp);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700778 }
779}
780
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700781void CameraDeviceClient::notifyPrepared(int streamId) {
782 // Thread safe. Don't bother locking.
783 sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
784 if (remoteCb != 0) {
785 remoteCb->onPrepared(streamId);
786 }
787}
788
Igor Murashkine7ee7632013-06-11 18:10:18 -0700789void CameraDeviceClient::detachDevice() {
790 if (mDevice == 0) return;
791
792 ALOGV("Camera %d: Stopping processors", mCameraId);
793
794 mFrameProcessor->removeListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
795 FRAME_PROCESSOR_LISTENER_MAX_ID,
796 /*listener*/this);
797 mFrameProcessor->requestExit();
798 ALOGV("Camera %d: Waiting for threads", mCameraId);
799 mFrameProcessor->join();
800 ALOGV("Camera %d: Disconnecting device", mCameraId);
801
802 // WORKAROUND: HAL refuses to disconnect while there's streams in flight
803 {
804 mDevice->clearStreamingRequest();
805
806 status_t code;
807 if ((code = mDevice->waitUntilDrained()) != OK) {
808 ALOGE("%s: waitUntilDrained failed with code 0x%x", __FUNCTION__,
809 code);
810 }
811 }
812
813 Camera2ClientBase::detachDevice();
814}
815
816/** Device-related methods */
Jianing Weicb0652e2014-03-12 18:29:36 -0700817void CameraDeviceClient::onResultAvailable(const CaptureResult& result) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700818 ATRACE_CALL();
819 ALOGV("%s", __FUNCTION__);
820
Igor Murashkin4fb55c12013-08-29 17:43:01 -0700821 // Thread-safe. No lock necessary.
822 sp<ICameraDeviceCallbacks> remoteCb = mRemoteCallback;
823 if (remoteCb != NULL) {
Jianing Weicb0652e2014-03-12 18:29:36 -0700824 remoteCb->onResultReceived(result.mMetadata, result.mResultExtras);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700825 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700826}
827
828// TODO: move to Camera2ClientBase
829bool CameraDeviceClient::enforceRequestPermissions(CameraMetadata& metadata) {
830
831 const int pid = IPCThreadState::self()->getCallingPid();
832 const int selfPid = getpid();
833 camera_metadata_entry_t entry;
834
835 /**
836 * Mixin default important security values
837 * - android.led.transmit = defaulted ON
838 */
839 CameraMetadata staticInfo = mDevice->info();
840 entry = staticInfo.find(ANDROID_LED_AVAILABLE_LEDS);
841 for(size_t i = 0; i < entry.count; ++i) {
842 uint8_t led = entry.data.u8[i];
843
844 switch(led) {
845 case ANDROID_LED_AVAILABLE_LEDS_TRANSMIT: {
846 uint8_t transmitDefault = ANDROID_LED_TRANSMIT_ON;
847 if (!metadata.exists(ANDROID_LED_TRANSMIT)) {
848 metadata.update(ANDROID_LED_TRANSMIT,
849 &transmitDefault, 1);
850 }
851 break;
852 }
853 }
854 }
855
856 // We can do anything!
857 if (pid == selfPid) {
858 return true;
859 }
860
861 /**
862 * Permission check special fields in the request
863 * - android.led.transmit = android.permission.CAMERA_DISABLE_TRANSMIT
864 */
865 entry = metadata.find(ANDROID_LED_TRANSMIT);
866 if (entry.count > 0 && entry.data.u8[0] != ANDROID_LED_TRANSMIT_ON) {
867 String16 permissionString =
868 String16("android.permission.CAMERA_DISABLE_TRANSMIT_LED");
869 if (!checkCallingPermission(permissionString)) {
870 const int uid = IPCThreadState::self()->getCallingUid();
871 ALOGE("Permission Denial: "
872 "can't disable transmit LED pid=%d, uid=%d", pid, uid);
873 return false;
874 }
875 }
876
877 return true;
878}
879
Igor Murashkinf8b2a6f2013-09-17 17:03:28 -0700880status_t CameraDeviceClient::getRotationTransformLocked(int32_t* transform) {
881 ALOGV("%s: begin", __FUNCTION__);
882
Igor Murashkinf8b2a6f2013-09-17 17:03:28 -0700883 const CameraMetadata& staticInfo = mDevice->info();
Ruben Brunk5698d442014-06-18 10:39:40 -0700884 return CameraUtils::getRotationTransform(staticInfo, transform);
Igor Murashkinf8b2a6f2013-09-17 17:03:28 -0700885}
886
Igor Murashkine7ee7632013-06-11 18:10:18 -0700887} // namespace android