1 /*
2 **
3 ** Copyright (C) 2008, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 ** http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17
18 //#define LOG_NDEBUG 0
19 #define LOG_TAG "Camera"
20 #include <utils/Log.h>
21 #include <utils/threads.h>
22 #include <binder/IPCThreadState.h>
23 #include <binder/IServiceManager.h>
24 #include <binder/IMemory.h>
25
26 #include <camera/Camera.h>
27 #include <camera/ICameraRecordingProxyListener.h>
28 #include <camera/ICameraService.h>
29
30 #include <gui/ISurfaceTexture.h>
31 #include <gui/Surface.h>
32
33 namespace android {
34
35 // client singleton for camera service binder interface
36 Mutex Camera::mLock;
37 sp<ICameraService> Camera::mCameraService;
38 sp<Camera::DeathNotifier> Camera::mDeathNotifier;
39
40 // establish binder interface to camera service
getCameraService()41 const sp<ICameraService>& Camera::getCameraService()
42 {
43 Mutex::Autolock _l(mLock);
44 if (mCameraService.get() == 0) {
45 sp<IServiceManager> sm = defaultServiceManager();
46 sp<IBinder> binder;
47 do {
48 binder = sm->getService(String16("media.camera"));
49 if (binder != 0)
50 break;
51 ALOGW("CameraService not published, waiting...");
52 usleep(500000); // 0.5 s
53 } while(true);
54 if (mDeathNotifier == NULL) {
55 mDeathNotifier = new DeathNotifier();
56 }
57 binder->linkToDeath(mDeathNotifier);
58 mCameraService = interface_cast<ICameraService>(binder);
59 }
60 ALOGE_IF(mCameraService==0, "no CameraService!?");
61 return mCameraService;
62 }
63
64 // ---------------------------------------------------------------------------
65
Camera()66 Camera::Camera()
67 {
68 init();
69 }
70
71 // construct a camera client from an existing camera remote
create(const sp<ICamera> & camera)72 sp<Camera> Camera::create(const sp<ICamera>& camera)
73 {
74 ALOGV("create");
75 if (camera == 0) {
76 ALOGE("camera remote is a NULL pointer");
77 return 0;
78 }
79
80 sp<Camera> c = new Camera();
81 if (camera->connect(c) == NO_ERROR) {
82 c->mStatus = NO_ERROR;
83 c->mCamera = camera;
84 camera->asBinder()->linkToDeath(c);
85 return c;
86 }
87 return 0;
88 }
89
init()90 void Camera::init()
91 {
92 mStatus = UNKNOWN_ERROR;
93 }
94
~Camera()95 Camera::~Camera()
96 {
97 // We don't need to call disconnect() here because if the CameraService
98 // thinks we are the owner of the hardware, it will hold a (strong)
99 // reference to us, and we can't possibly be here. We also don't want to
100 // call disconnect() here if we are in the same process as mediaserver,
101 // because we may be invoked by CameraService::Client::connect() and will
102 // deadlock if we call any method of ICamera here.
103 }
104
getNumberOfCameras()105 int32_t Camera::getNumberOfCameras()
106 {
107 const sp<ICameraService>& cs = getCameraService();
108 if (cs == 0) return 0;
109 return cs->getNumberOfCameras();
110 }
111
getCameraInfo(int cameraId,struct CameraInfo * cameraInfo)112 status_t Camera::getCameraInfo(int cameraId,
113 struct CameraInfo* cameraInfo) {
114 const sp<ICameraService>& cs = getCameraService();
115 if (cs == 0) return UNKNOWN_ERROR;
116 return cs->getCameraInfo(cameraId, cameraInfo);
117 }
118
connect(int cameraId)119 sp<Camera> Camera::connect(int cameraId)
120 {
121 ALOGV("connect");
122 sp<Camera> c = new Camera();
123 const sp<ICameraService>& cs = getCameraService();
124 if (cs != 0) {
125 c->mCamera = cs->connect(c, cameraId);
126 }
127 if (c->mCamera != 0) {
128 c->mCamera->asBinder()->linkToDeath(c);
129 c->mStatus = NO_ERROR;
130 } else {
131 c.clear();
132 }
133 return c;
134 }
135
disconnect()136 void Camera::disconnect()
137 {
138 ALOGV("disconnect");
139 if (mCamera != 0) {
140 mCamera->disconnect();
141 mCamera->asBinder()->unlinkToDeath(this);
142 mCamera = 0;
143 }
144 }
145
reconnect()146 status_t Camera::reconnect()
147 {
148 ALOGV("reconnect");
149 sp <ICamera> c = mCamera;
150 if (c == 0) return NO_INIT;
151 return c->connect(this);
152 }
153
remote()154 sp<ICamera> Camera::remote()
155 {
156 return mCamera;
157 }
158
lock()159 status_t Camera::lock()
160 {
161 sp <ICamera> c = mCamera;
162 if (c == 0) return NO_INIT;
163 return c->lock();
164 }
165
unlock()166 status_t Camera::unlock()
167 {
168 sp <ICamera> c = mCamera;
169 if (c == 0) return NO_INIT;
170 return c->unlock();
171 }
172
173 // pass the buffered Surface to the camera service
setPreviewDisplay(const sp<Surface> & surface)174 status_t Camera::setPreviewDisplay(const sp<Surface>& surface)
175 {
176 ALOGV("setPreviewDisplay(%p)", surface.get());
177 sp <ICamera> c = mCamera;
178 if (c == 0) return NO_INIT;
179 if (surface != 0) {
180 return c->setPreviewDisplay(surface);
181 } else {
182 ALOGD("app passed NULL surface");
183 return c->setPreviewDisplay(0);
184 }
185 }
186
187 // pass the buffered ISurfaceTexture to the camera service
setPreviewTexture(const sp<ISurfaceTexture> & surfaceTexture)188 status_t Camera::setPreviewTexture(const sp<ISurfaceTexture>& surfaceTexture)
189 {
190 ALOGV("setPreviewTexture(%p)", surfaceTexture.get());
191 sp <ICamera> c = mCamera;
192 if (c == 0) return NO_INIT;
193 if (surfaceTexture != 0) {
194 return c->setPreviewTexture(surfaceTexture);
195 } else {
196 ALOGD("app passed NULL surface");
197 return c->setPreviewTexture(0);
198 }
199 }
200
201 // start preview mode
startPreview()202 status_t Camera::startPreview()
203 {
204 ALOGV("startPreview");
205 sp <ICamera> c = mCamera;
206 if (c == 0) return NO_INIT;
207 return c->startPreview();
208 }
209
storeMetaDataInBuffers(bool enabled)210 status_t Camera::storeMetaDataInBuffers(bool enabled)
211 {
212 ALOGV("storeMetaDataInBuffers: %s",
213 enabled? "true": "false");
214 sp <ICamera> c = mCamera;
215 if (c == 0) return NO_INIT;
216 return c->storeMetaDataInBuffers(enabled);
217 }
218
219 // start recording mode, must call setPreviewDisplay first
startRecording()220 status_t Camera::startRecording()
221 {
222 ALOGV("startRecording");
223 sp <ICamera> c = mCamera;
224 if (c == 0) return NO_INIT;
225 return c->startRecording();
226 }
227
228 // stop preview mode
stopPreview()229 void Camera::stopPreview()
230 {
231 ALOGV("stopPreview");
232 sp <ICamera> c = mCamera;
233 if (c == 0) return;
234 c->stopPreview();
235 }
236
237 // stop recording mode
stopRecording()238 void Camera::stopRecording()
239 {
240 ALOGV("stopRecording");
241 {
242 Mutex::Autolock _l(mLock);
243 mRecordingProxyListener.clear();
244 }
245 sp <ICamera> c = mCamera;
246 if (c == 0) return;
247 c->stopRecording();
248 }
249
250 // release a recording frame
releaseRecordingFrame(const sp<IMemory> & mem)251 void Camera::releaseRecordingFrame(const sp<IMemory>& mem)
252 {
253 ALOGV("releaseRecordingFrame");
254 sp <ICamera> c = mCamera;
255 if (c == 0) return;
256 c->releaseRecordingFrame(mem);
257 }
258
259 // get preview state
previewEnabled()260 bool Camera::previewEnabled()
261 {
262 ALOGV("previewEnabled");
263 sp <ICamera> c = mCamera;
264 if (c == 0) return false;
265 return c->previewEnabled();
266 }
267
268 // get recording state
recordingEnabled()269 bool Camera::recordingEnabled()
270 {
271 ALOGV("recordingEnabled");
272 sp <ICamera> c = mCamera;
273 if (c == 0) return false;
274 return c->recordingEnabled();
275 }
276
autoFocus()277 status_t Camera::autoFocus()
278 {
279 ALOGV("autoFocus");
280 sp <ICamera> c = mCamera;
281 if (c == 0) return NO_INIT;
282 return c->autoFocus();
283 }
284
cancelAutoFocus()285 status_t Camera::cancelAutoFocus()
286 {
287 ALOGV("cancelAutoFocus");
288 sp <ICamera> c = mCamera;
289 if (c == 0) return NO_INIT;
290 return c->cancelAutoFocus();
291 }
292
293 // take a picture
takePicture(int msgType)294 status_t Camera::takePicture(int msgType)
295 {
296 ALOGV("takePicture: 0x%x", msgType);
297 sp <ICamera> c = mCamera;
298 if (c == 0) return NO_INIT;
299 return c->takePicture(msgType);
300 }
301
302 // set preview/capture parameters - key/value pairs
setParameters(const String8 & params)303 status_t Camera::setParameters(const String8& params)
304 {
305 ALOGV("setParameters");
306 sp <ICamera> c = mCamera;
307 if (c == 0) return NO_INIT;
308 return c->setParameters(params);
309 }
310
311 // get preview/capture parameters - key/value pairs
getParameters() const312 String8 Camera::getParameters() const
313 {
314 ALOGV("getParameters");
315 String8 params;
316 sp <ICamera> c = mCamera;
317 if (c != 0) params = mCamera->getParameters();
318 return params;
319 }
320
321 // send command to camera driver
sendCommand(int32_t cmd,int32_t arg1,int32_t arg2)322 status_t Camera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
323 {
324 ALOGV("sendCommand");
325 sp <ICamera> c = mCamera;
326 if (c == 0) return NO_INIT;
327 return c->sendCommand(cmd, arg1, arg2);
328 }
329
setListener(const sp<CameraListener> & listener)330 void Camera::setListener(const sp<CameraListener>& listener)
331 {
332 Mutex::Autolock _l(mLock);
333 mListener = listener;
334 }
335
setRecordingProxyListener(const sp<ICameraRecordingProxyListener> & listener)336 void Camera::setRecordingProxyListener(const sp<ICameraRecordingProxyListener>& listener)
337 {
338 Mutex::Autolock _l(mLock);
339 mRecordingProxyListener = listener;
340 }
341
setPreviewCallbackFlags(int flag)342 void Camera::setPreviewCallbackFlags(int flag)
343 {
344 ALOGV("setPreviewCallbackFlags");
345 sp <ICamera> c = mCamera;
346 if (c == 0) return;
347 mCamera->setPreviewCallbackFlag(flag);
348 }
349
350 // callback from camera service
notifyCallback(int32_t msgType,int32_t ext1,int32_t ext2)351 void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
352 {
353 sp<CameraListener> listener;
354 {
355 Mutex::Autolock _l(mLock);
356 listener = mListener;
357 }
358 if (listener != NULL) {
359 listener->notify(msgType, ext1, ext2);
360 }
361 }
362
363 // callback from camera service when frame or image is ready
dataCallback(int32_t msgType,const sp<IMemory> & dataPtr,camera_frame_metadata_t * metadata)364 void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr,
365 camera_frame_metadata_t *metadata)
366 {
367 sp<CameraListener> listener;
368 {
369 Mutex::Autolock _l(mLock);
370 listener = mListener;
371 }
372 if (listener != NULL) {
373 listener->postData(msgType, dataPtr, metadata);
374 }
375 }
376
377 // callback from camera service when timestamped frame is ready
dataCallbackTimestamp(nsecs_t timestamp,int32_t msgType,const sp<IMemory> & dataPtr)378 void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)
379 {
380 // If recording proxy listener is registered, forward the frame and return.
381 // The other listener (mListener) is ignored because the receiver needs to
382 // call releaseRecordingFrame.
383 sp<ICameraRecordingProxyListener> proxylistener;
384 {
385 Mutex::Autolock _l(mLock);
386 proxylistener = mRecordingProxyListener;
387 }
388 if (proxylistener != NULL) {
389 proxylistener->dataCallbackTimestamp(timestamp, msgType, dataPtr);
390 return;
391 }
392
393 sp<CameraListener> listener;
394 {
395 Mutex::Autolock _l(mLock);
396 listener = mListener;
397 }
398 if (listener != NULL) {
399 listener->postDataTimestamp(timestamp, msgType, dataPtr);
400 } else {
401 ALOGW("No listener was set. Drop a recording frame.");
402 releaseRecordingFrame(dataPtr);
403 }
404 }
405
binderDied(const wp<IBinder> & who)406 void Camera::binderDied(const wp<IBinder>& who) {
407 ALOGW("ICamera died");
408 notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0);
409 }
410
binderDied(const wp<IBinder> & who)411 void Camera::DeathNotifier::binderDied(const wp<IBinder>& who) {
412 ALOGV("binderDied");
413 Mutex::Autolock _l(Camera::mLock);
414 Camera::mCameraService.clear();
415 ALOGW("Camera server died!");
416 }
417
getRecordingProxy()418 sp<ICameraRecordingProxy> Camera::getRecordingProxy() {
419 ALOGV("getProxy");
420 return new RecordingProxy(this);
421 }
422
startRecording(const sp<ICameraRecordingProxyListener> & listener)423 status_t Camera::RecordingProxy::startRecording(const sp<ICameraRecordingProxyListener>& listener)
424 {
425 ALOGV("RecordingProxy::startRecording");
426 mCamera->setRecordingProxyListener(listener);
427 mCamera->reconnect();
428 return mCamera->startRecording();
429 }
430
stopRecording()431 void Camera::RecordingProxy::stopRecording()
432 {
433 ALOGV("RecordingProxy::stopRecording");
434 mCamera->stopRecording();
435 }
436
releaseRecordingFrame(const sp<IMemory> & mem)437 void Camera::RecordingProxy::releaseRecordingFrame(const sp<IMemory>& mem)
438 {
439 ALOGV("RecordingProxy::releaseRecordingFrame");
440 mCamera->releaseRecordingFrame(mem);
441 }
442
RecordingProxy(const sp<Camera> & camera)443 Camera::RecordingProxy::RecordingProxy(const sp<Camera>& camera)
444 {
445 mCamera = camera;
446 }
447
448 }; // namespace android
449