• 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 <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