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