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