blob: 1270751d25748ff6ee76016fb17960896da3becb [file] [log] [blame]
Igor Murashkin985fd302013-02-20 18:24:43 -08001/*
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 "ProCamera2Client"
18#define ATRACE_TAG ATRACE_TAG_CAMERA
19//#define LOG_NDEBUG 0
20
21#include <utils/Log.h>
22#include <utils/Trace.h>
23
24#include <cutils/properties.h>
25#include <gui/Surface.h>
26#include <gui/Surface.h>
27#include "camera2/Parameters.h"
28#include "ProCamera2Client.h"
Igor Murashkina91537e2013-02-21 12:02:29 -080029#include "camera2/ProFrameProcessor.h"
Igor Murashkince124da2013-03-04 14:53:08 -080030#include "CameraDeviceBase.h"
Igor Murashkin985fd302013-02-20 18:24:43 -080031
32namespace android {
33using namespace camera2;
34
Igor Murashkin985fd302013-02-20 18:24:43 -080035// Interface used by CameraService
36
37ProCamera2Client::ProCamera2Client(const sp<CameraService>& cameraService,
Igor Murashkin44cfcf02013-03-01 16:22:28 -080038 const sp<IProCameraCallbacks>& remoteCallback,
39 const String16& clientPackageName,
40 int cameraId,
41 int cameraFacing,
42 int clientPid,
43 uid_t clientUid,
44 int servicePid) :
45 Camera2ClientBase(cameraService, remoteCallback, clientPackageName,
46 cameraId, cameraFacing, clientPid, clientUid, servicePid)
Igor Murashkin985fd302013-02-20 18:24:43 -080047{
48 ATRACE_CALL();
49 ALOGI("ProCamera %d: Opened", cameraId);
50
Igor Murashkin985fd302013-02-20 18:24:43 -080051 mExclusiveLock = false;
52}
53
Igor Murashkin985fd302013-02-20 18:24:43 -080054status_t ProCamera2Client::initialize(camera_module_t *module)
55{
56 ATRACE_CALL();
Igor Murashkin985fd302013-02-20 18:24:43 -080057 status_t res;
58
Igor Murashkin44cfcf02013-03-01 16:22:28 -080059 res = Camera2ClientBase::initialize(module);
Igor Murashkin985fd302013-02-20 18:24:43 -080060 if (res != OK) {
Igor Murashkin44cfcf02013-03-01 16:22:28 -080061 return res;
Igor Murashkin985fd302013-02-20 18:24:43 -080062 }
63
Igor Murashkina91537e2013-02-21 12:02:29 -080064 String8 threadName;
Igor Murashkince124da2013-03-04 14:53:08 -080065 mFrameProcessor = new ProFrameProcessor(mDevice);
Igor Murashkin44cfcf02013-03-01 16:22:28 -080066 threadName = String8::format("PC2-%d-FrameProc", mCameraId);
Igor Murashkina91537e2013-02-21 12:02:29 -080067 mFrameProcessor->run(threadName.string());
68
69 mFrameProcessor->registerListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
70 FRAME_PROCESSOR_LISTENER_MAX_ID,
71 /*listener*/this);
72
Igor Murashkin985fd302013-02-20 18:24:43 -080073 return OK;
74}
75
76ProCamera2Client::~ProCamera2Client() {
Igor Murashkin985fd302013-02-20 18:24:43 -080077}
78
79status_t ProCamera2Client::exclusiveTryLock() {
80 ATRACE_CALL();
81 ALOGV("%s", __FUNCTION__);
82
Igor Murashkin44cfcf02013-03-01 16:22:28 -080083 Mutex::Autolock icl(mBinderSerializationLock);
Igor Murashkin985fd302013-02-20 18:24:43 -080084 SharedCameraCallbacks::Lock l(mSharedCameraCallbacks);
85
Igor Murashkinbfc99152013-02-27 12:55:20 -080086 if (!mDevice.get()) return PERMISSION_DENIED;
87
Igor Murashkin985fd302013-02-20 18:24:43 -080088 if (!mExclusiveLock) {
89 mExclusiveLock = true;
90
91 if (mRemoteCallback != NULL) {
92 mRemoteCallback->onLockStatusChanged(
93 IProCameraCallbacks::LOCK_ACQUIRED);
94 }
95
96 ALOGV("%s: exclusive lock acquired", __FUNCTION__);
97
98 return OK;
99 }
100
101 // TODO: have a PERMISSION_DENIED case for when someone else owns the lock
102
103 // don't allow recursive locking
104 ALOGW("%s: exclusive lock already exists - recursive locking is not"
105 "allowed", __FUNCTION__);
106
107 return ALREADY_EXISTS;
108}
109
110status_t ProCamera2Client::exclusiveLock() {
111 ATRACE_CALL();
112 ALOGV("%s", __FUNCTION__);
113
Igor Murashkin44cfcf02013-03-01 16:22:28 -0800114 Mutex::Autolock icl(mBinderSerializationLock);
Igor Murashkin985fd302013-02-20 18:24:43 -0800115 SharedCameraCallbacks::Lock l(mSharedCameraCallbacks);
116
Igor Murashkinbfc99152013-02-27 12:55:20 -0800117 if (!mDevice.get()) return PERMISSION_DENIED;
118
Igor Murashkin985fd302013-02-20 18:24:43 -0800119 /**
120 * TODO: this should asynchronously 'wait' until the lock becomes available
121 * if another client already has an exclusive lock.
122 *
123 * once we have proper sharing support this will need to do
124 * more than just return immediately
125 */
126 if (!mExclusiveLock) {
127 mExclusiveLock = true;
128
129 if (mRemoteCallback != NULL) {
130 mRemoteCallback->onLockStatusChanged(IProCameraCallbacks::LOCK_ACQUIRED);
131 }
132
133 ALOGV("%s: exclusive lock acquired", __FUNCTION__);
134
135 return OK;
136 }
137
138 // don't allow recursive locking
139 ALOGW("%s: exclusive lock already exists - recursive locking is not allowed"
140 , __FUNCTION__);
141 return ALREADY_EXISTS;
142}
143
144status_t ProCamera2Client::exclusiveUnlock() {
145 ATRACE_CALL();
146 ALOGV("%s", __FUNCTION__);
147
Igor Murashkin44cfcf02013-03-01 16:22:28 -0800148 Mutex::Autolock icl(mBinderSerializationLock);
Igor Murashkin985fd302013-02-20 18:24:43 -0800149 SharedCameraCallbacks::Lock l(mSharedCameraCallbacks);
150
151 // don't allow unlocking if we have no lock
152 if (!mExclusiveLock) {
153 ALOGW("%s: cannot unlock, no lock was held in the first place",
154 __FUNCTION__);
155 return BAD_VALUE;
156 }
157
158 mExclusiveLock = false;
159 if (mRemoteCallback != NULL ) {
160 mRemoteCallback->onLockStatusChanged(
161 IProCameraCallbacks::LOCK_RELEASED);
162 }
163 ALOGV("%s: exclusive lock released", __FUNCTION__);
164
165 return OK;
166}
167
168bool ProCamera2Client::hasExclusiveLock() {
Igor Murashkin44cfcf02013-03-01 16:22:28 -0800169 Mutex::Autolock icl(mBinderSerializationLock);
Igor Murashkin985fd302013-02-20 18:24:43 -0800170 return mExclusiveLock;
171}
172
Igor Murashkinbfc99152013-02-27 12:55:20 -0800173void ProCamera2Client::onExclusiveLockStolen() {
174 ALOGV("%s: ProClient lost exclusivity (id %d)",
175 __FUNCTION__, mCameraId);
176
Igor Murashkin44cfcf02013-03-01 16:22:28 -0800177 Mutex::Autolock icl(mBinderSerializationLock);
Igor Murashkinbfc99152013-02-27 12:55:20 -0800178 SharedCameraCallbacks::Lock l(mSharedCameraCallbacks);
179
180 if (mExclusiveLock && mRemoteCallback.get() != NULL) {
181 mRemoteCallback->onLockStatusChanged(
182 IProCameraCallbacks::LOCK_STOLEN);
183 }
184
185 mExclusiveLock = false;
186
187 //TODO: we should not need to detach the device, merely reset it.
188 detachDevice();
189}
190
Igor Murashkin985fd302013-02-20 18:24:43 -0800191status_t ProCamera2Client::submitRequest(camera_metadata_t* request,
192 bool streaming) {
193 ATRACE_CALL();
194 ALOGV("%s", __FUNCTION__);
195
Igor Murashkin44cfcf02013-03-01 16:22:28 -0800196 Mutex::Autolock icl(mBinderSerializationLock);
Igor Murashkinbfc99152013-02-27 12:55:20 -0800197
198 if (!mDevice.get()) return DEAD_OBJECT;
199
Igor Murashkin985fd302013-02-20 18:24:43 -0800200 if (!mExclusiveLock) {
201 return PERMISSION_DENIED;
202 }
203
Igor Murashkin3261fd32013-02-20 19:02:36 -0800204 CameraMetadata metadata(request);
205
206 if (streaming) {
207 return mDevice->setStreamingRequest(metadata);
208 } else {
209 return mDevice->capture(metadata);
210 }
211
212 // unreachable. thx gcc for a useless warning
Igor Murashkin985fd302013-02-20 18:24:43 -0800213 return OK;
214}
215
216status_t ProCamera2Client::cancelRequest(int requestId) {
217 ATRACE_CALL();
218 ALOGV("%s", __FUNCTION__);
219
Igor Murashkin44cfcf02013-03-01 16:22:28 -0800220 Mutex::Autolock icl(mBinderSerializationLock);
Igor Murashkinbfc99152013-02-27 12:55:20 -0800221
222 if (!mDevice.get()) return DEAD_OBJECT;
223
Igor Murashkin985fd302013-02-20 18:24:43 -0800224 if (!mExclusiveLock) {
225 return PERMISSION_DENIED;
226 }
227
Igor Murashkin44cfcf02013-03-01 16:22:28 -0800228 // TODO: implement
Igor Murashkin985fd302013-02-20 18:24:43 -0800229 ALOGE("%s: not fully implemented yet", __FUNCTION__);
Igor Murashkin3261fd32013-02-20 19:02:36 -0800230 return INVALID_OPERATION;
Igor Murashkin985fd302013-02-20 18:24:43 -0800231}
232
Igor Murashkin44cfcf02013-03-01 16:22:28 -0800233//TODO: Remove
Igor Murashkin985fd302013-02-20 18:24:43 -0800234status_t ProCamera2Client::requestStream(int streamId) {
235 ALOGE("%s: not implemented yet", __FUNCTION__);
236
237 return INVALID_OPERATION;
238}
239
240status_t ProCamera2Client::cancelStream(int streamId) {
Igor Murashkin3261fd32013-02-20 19:02:36 -0800241 ATRACE_CALL();
242 ALOGV("%s (streamId = 0x%x)", __FUNCTION__, streamId);
Igor Murashkin985fd302013-02-20 18:24:43 -0800243
Igor Murashkin3261fd32013-02-20 19:02:36 -0800244 status_t res;
245 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
246
Igor Murashkin44cfcf02013-03-01 16:22:28 -0800247 Mutex::Autolock icl(mBinderSerializationLock);
Igor Murashkin3261fd32013-02-20 19:02:36 -0800248
Igor Murashkinbfc99152013-02-27 12:55:20 -0800249 if (!mDevice.get()) return DEAD_OBJECT;
Igor Murashkin5835cc42013-02-20 19:29:53 -0800250 mDevice->clearStreamingRequest();
251
252 status_t code;
253 if ((code = mDevice->waitUntilDrained()) != OK) {
254 ALOGE("%s: waitUntilDrained failed with code 0x%x", __FUNCTION__, code);
255 }
256
Igor Murashkin3261fd32013-02-20 19:02:36 -0800257 return mDevice->deleteStream(streamId);
Igor Murashkin985fd302013-02-20 18:24:43 -0800258}
259
260status_t ProCamera2Client::createStream(int width, int height, int format,
Igor Murashkin76f8b432013-02-20 19:15:15 -0800261 const sp<IGraphicBufferProducer>& bufferProducer,
Igor Murashkin3261fd32013-02-20 19:02:36 -0800262 /*out*/
263 int* streamId)
264{
265 if (streamId) {
266 *streamId = -1;
267 }
Igor Murashkin985fd302013-02-20 18:24:43 -0800268
Igor Murashkin3261fd32013-02-20 19:02:36 -0800269 ATRACE_CALL();
270 ALOGV("%s (w = %d, h = %d, f = 0x%x)", __FUNCTION__, width, height, format);
271
272 status_t res;
273 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
274
Igor Murashkin44cfcf02013-03-01 16:22:28 -0800275 Mutex::Autolock icl(mBinderSerializationLock);
Igor Murashkin3261fd32013-02-20 19:02:36 -0800276
Igor Murashkinbfc99152013-02-27 12:55:20 -0800277 if (!mDevice.get()) return DEAD_OBJECT;
278
Igor Murashkin76f8b432013-02-20 19:15:15 -0800279 sp<IBinder> binder;
280 sp<ANativeWindow> window;
281 if (bufferProducer != 0) {
282 binder = bufferProducer->asBinder();
283 window = new Surface(bufferProducer);
284 }
285
286 return mDevice->createStream(window, width, height, format, /*size*/1,
287 streamId);
Igor Murashkin985fd302013-02-20 18:24:43 -0800288}
289
Igor Murashkin3261fd32013-02-20 19:02:36 -0800290// Create a request object from a template.
291// -- Caller owns the newly allocated metadata
Igor Murashkin985fd302013-02-20 18:24:43 -0800292status_t ProCamera2Client::createDefaultRequest(int templateId,
Igor Murashkin3261fd32013-02-20 19:02:36 -0800293 /*out*/
294 camera_metadata** request)
295{
296 ATRACE_CALL();
297 ALOGV("%s (templateId = 0x%x)", __FUNCTION__, templateId);
Igor Murashkin985fd302013-02-20 18:24:43 -0800298
Igor Murashkin3261fd32013-02-20 19:02:36 -0800299 if (request) {
300 *request = NULL;
301 }
302
303 status_t res;
304 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
305
Igor Murashkin44cfcf02013-03-01 16:22:28 -0800306 Mutex::Autolock icl(mBinderSerializationLock);
Igor Murashkin3261fd32013-02-20 19:02:36 -0800307
Igor Murashkinbfc99152013-02-27 12:55:20 -0800308 if (!mDevice.get()) return DEAD_OBJECT;
309
Igor Murashkin3261fd32013-02-20 19:02:36 -0800310 CameraMetadata metadata;
311 if ( (res = mDevice->createDefaultRequest(templateId, &metadata) ) == OK) {
312 *request = metadata.release();
313 }
314
315 return res;
Igor Murashkin985fd302013-02-20 18:24:43 -0800316}
317
Igor Murashkin7b33a742013-02-21 13:49:26 -0800318status_t ProCamera2Client::getCameraInfo(int cameraId,
319 /*out*/
320 camera_metadata** info)
321{
322 if (cameraId != mCameraId) {
323 return INVALID_OPERATION;
324 }
325
Igor Murashkin44cfcf02013-03-01 16:22:28 -0800326 Mutex::Autolock icl(mBinderSerializationLock);
Igor Murashkinbfc99152013-02-27 12:55:20 -0800327
328 if (!mDevice.get()) return DEAD_OBJECT;
329
Igor Murashkin7b33a742013-02-21 13:49:26 -0800330 CameraMetadata deviceInfo = mDevice->info();
331 *info = deviceInfo.release();
332
333 return OK;
334}
335
Igor Murashkin985fd302013-02-20 18:24:43 -0800336status_t ProCamera2Client::dump(int fd, const Vector<String16>& args) {
337 String8 result;
338 result.appendFormat("ProCamera2Client[%d] (%p) PID: %d, dump:\n",
339 mCameraId,
340 getRemoteCallback()->asBinder().get(),
341 mClientPid);
342 result.append(" State: ");
343
344 // TODO: print dynamic/request section from most recent requests
Igor Murashkina91537e2013-02-21 12:02:29 -0800345 mFrameProcessor->dump(fd, args);
Igor Murashkin985fd302013-02-20 18:24:43 -0800346
Igor Murashkin44cfcf02013-03-01 16:22:28 -0800347 return dumpDevice(fd, args);
Igor Murashkin985fd302013-02-20 18:24:43 -0800348}
349
350// IProCameraUser interface
351
Igor Murashkinbfc99152013-02-27 12:55:20 -0800352void ProCamera2Client::detachDevice() {
Igor Murashkin985fd302013-02-20 18:24:43 -0800353 if (mDevice == 0) return;
354
Igor Murashkinbfc99152013-02-27 12:55:20 -0800355 ALOGV("Camera %d: Stopping processors", mCameraId);
356
Igor Murashkina91537e2013-02-21 12:02:29 -0800357 mFrameProcessor->removeListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
358 FRAME_PROCESSOR_LISTENER_MAX_ID,
359 /*listener*/this);
360 mFrameProcessor->requestExit();
Igor Murashkin985fd302013-02-20 18:24:43 -0800361 ALOGV("Camera %d: Waiting for threads", mCameraId);
Igor Murashkina91537e2013-02-21 12:02:29 -0800362 mFrameProcessor->join();
Igor Murashkin985fd302013-02-20 18:24:43 -0800363 ALOGV("Camera %d: Disconnecting device", mCameraId);
364
Igor Murashkinbfc99152013-02-27 12:55:20 -0800365 // WORKAROUND: HAL refuses to disconnect while there's streams in flight
366 {
367 mDevice->clearStreamingRequest();
368
369 status_t code;
370 if ((code = mDevice->waitUntilDrained()) != OK) {
371 ALOGE("%s: waitUntilDrained failed with code 0x%x", __FUNCTION__,
372 code);
373 }
374 }
375
Igor Murashkin44cfcf02013-03-01 16:22:28 -0800376 Camera2ClientBase::detachDevice();
Igor Murashkin985fd302013-02-20 18:24:43 -0800377}
378
379/** Device-related methods */
Igor Murashkina91537e2013-02-21 12:02:29 -0800380void ProCamera2Client::onFrameAvailable(int32_t frameId,
381 const CameraMetadata& frame) {
382 ATRACE_CALL();
383 ALOGV("%s", __FUNCTION__);
384
Igor Murashkin44cfcf02013-03-01 16:22:28 -0800385 Mutex::Autolock icl(mBinderSerializationLock);
Igor Murashkina91537e2013-02-21 12:02:29 -0800386 SharedCameraCallbacks::Lock l(mSharedCameraCallbacks);
387
388 if (mRemoteCallback != NULL) {
389 CameraMetadata tmp(frame);
390 camera_metadata_t* meta = tmp.release();
391 ALOGV("%s: meta = %p ", __FUNCTION__, meta);
392 mRemoteCallback->onResultReceived(frameId, meta);
393 tmp.acquire(meta);
394 }
395
396}
397
Igor Murashkin985fd302013-02-20 18:24:43 -0800398} // namespace android