• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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