blob: 0037399752189971b973fbc53d2fb6a5c3baf30d [file] [log] [blame]
Mathias Agopian3cf61352010-02-09 17:46:37 -08001/*
2**
3** Copyright (C) 2008, The Android Open Source Project
4** Copyright (C) 2008 HTC Inc.
5**
6** Licensed under the Apache License, Version 2.0 (the "License");
7** you may not use this file except in compliance with the License.
8** You may obtain a copy of the License at
9**
10** http://www.apache.org/licenses/LICENSE-2.0
11**
12** Unless required by applicable law or agreed to in writing, software
13** distributed under the License is distributed on an "AS IS" BASIS,
14** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15** See the License for the specific language governing permissions and
16** limitations under the License.
17*/
18
19//#define LOG_NDEBUG 0
20#define LOG_TAG "Camera"
21#include <utils/Log.h>
22#include <utils/threads.h>
23
24#include <binder/IServiceManager.h>
25#include <binder/IMemory.h>
26
27#include <camera/Camera.h>
28#include <camera/ICameraService.h>
29
30#include <surfaceflinger/Surface.h>
31
32namespace android {
33
34// client singleton for camera service binder interface
35Mutex Camera::mLock;
36sp<ICameraService> Camera::mCameraService;
37sp<Camera::DeathNotifier> Camera::mDeathNotifier;
38
39// establish binder interface to camera service
40const 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
65Camera::Camera()
66{
67 init();
68}
69
70// construct a camera client from an existing camera remote
71sp<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 }
85 return c;
86}
87
88void Camera::init()
89{
90 mStatus = UNKNOWN_ERROR;
91}
92
93Camera::~Camera()
94{
Chih-Chung Changd06618e2010-05-13 15:14:24 +080095 // We don't need to call disconnect() here because if the CameraService
96 // thinks we are the owner of the hardware, it will hold a (strong)
97 // reference to us, and we can't possibly be here. We also don't want to
98 // call disconnect() here if we are in the same process as mediaserver,
99 // because we may be invoked by CameraService::Client::connect() and will
100 // deadlock if we call any method of ICamera here.
Mathias Agopian3cf61352010-02-09 17:46:37 -0800101}
102
Chih-Chung Chang35a055b2010-05-06 16:36:58 +0800103int32_t Camera::getNumberOfCameras()
104{
105 const sp<ICameraService>& cs = getCameraService();
106 if (cs == 0) return 0;
107 return cs->getNumberOfCameras();
108}
109
Chih-Chung Changddbdb352010-06-10 13:32:16 +0800110status_t Camera::getCameraInfo(int cameraId,
111 struct CameraInfo* cameraInfo) {
112 const sp<ICameraService>& cs = getCameraService();
113 if (cs == 0) return UNKNOWN_ERROR;
114 return cs->getCameraInfo(cameraId, cameraInfo);
115}
116
Chih-Chung Chang35a055b2010-05-06 16:36:58 +0800117sp<Camera> Camera::connect(int cameraId)
Mathias Agopian3cf61352010-02-09 17:46:37 -0800118{
119 LOGV("connect");
120 sp<Camera> c = new Camera();
121 const sp<ICameraService>& cs = getCameraService();
122 if (cs != 0) {
Chih-Chung Chang35a055b2010-05-06 16:36:58 +0800123 c->mCamera = cs->connect(c, cameraId);
Mathias Agopian3cf61352010-02-09 17:46:37 -0800124 }
125 if (c->mCamera != 0) {
126 c->mCamera->asBinder()->linkToDeath(c);
127 c->mStatus = NO_ERROR;
128 } else {
129 c.clear();
130 }
131 return c;
132}
133
134void Camera::disconnect()
135{
136 LOGV("disconnect");
137 if (mCamera != 0) {
138 mCamera->disconnect();
Chih-Chung Changf8ed70a2010-03-24 16:38:02 -0700139 mCamera->asBinder()->unlinkToDeath(this);
Mathias Agopian3cf61352010-02-09 17:46:37 -0800140 mCamera = 0;
141 }
142}
143
144status_t Camera::reconnect()
145{
146 LOGV("reconnect");
147 sp <ICamera> c = mCamera;
148 if (c == 0) return NO_INIT;
149 return c->connect(this);
150}
151
152sp<ICamera> Camera::remote()
153{
154 return mCamera;
155}
156
157status_t Camera::lock()
158{
159 sp <ICamera> c = mCamera;
160 if (c == 0) return NO_INIT;
161 return c->lock();
162}
163
164status_t Camera::unlock()
165{
166 sp <ICamera> c = mCamera;
167 if (c == 0) return NO_INIT;
168 return c->unlock();
169}
170
171// pass the buffered ISurface to the camera service
172status_t Camera::setPreviewDisplay(const sp<Surface>& surface)
173{
174 LOGV("setPreviewDisplay");
175 sp <ICamera> c = mCamera;
176 if (c == 0) return NO_INIT;
177 if (surface != 0) {
178 return c->setPreviewDisplay(surface->getISurface());
179 } else {
180 LOGD("app passed NULL surface");
181 return c->setPreviewDisplay(0);
182 }
183}
184
185status_t Camera::setPreviewDisplay(const sp<ISurface>& surface)
186{
187 LOGV("setPreviewDisplay");
188 if (surface == 0) {
189 LOGD("app passed NULL surface");
190 }
191 sp <ICamera> c = mCamera;
192 if (c == 0) return NO_INIT;
193 return c->setPreviewDisplay(surface);
194}
195
196
197// start preview mode
198status_t Camera::startPreview()
199{
200 LOGV("startPreview");
201 sp <ICamera> c = mCamera;
202 if (c == 0) return NO_INIT;
203 return c->startPreview();
204}
205
206// start recording mode, must call setPreviewDisplay first
207status_t Camera::startRecording()
208{
209 LOGV("startRecording");
210 sp <ICamera> c = mCamera;
211 if (c == 0) return NO_INIT;
212 return c->startRecording();
213}
214
215// stop preview mode
216void Camera::stopPreview()
217{
218 LOGV("stopPreview");
219 sp <ICamera> c = mCamera;
220 if (c == 0) return;
221 c->stopPreview();
222}
223
224// stop recording mode
225void Camera::stopRecording()
226{
227 LOGV("stopRecording");
228 sp <ICamera> c = mCamera;
229 if (c == 0) return;
230 c->stopRecording();
231}
232
233// release a recording frame
234void Camera::releaseRecordingFrame(const sp<IMemory>& mem)
235{
236 LOGV("releaseRecordingFrame");
237 sp <ICamera> c = mCamera;
238 if (c == 0) return;
239 c->releaseRecordingFrame(mem);
240}
241
242// get preview state
243bool Camera::previewEnabled()
244{
245 LOGV("previewEnabled");
246 sp <ICamera> c = mCamera;
247 if (c == 0) return false;
248 return c->previewEnabled();
249}
250
251// get recording state
252bool Camera::recordingEnabled()
253{
254 LOGV("recordingEnabled");
255 sp <ICamera> c = mCamera;
256 if (c == 0) return false;
257 return c->recordingEnabled();
258}
259
260status_t Camera::autoFocus()
261{
262 LOGV("autoFocus");
263 sp <ICamera> c = mCamera;
264 if (c == 0) return NO_INIT;
265 return c->autoFocus();
266}
267
268status_t Camera::cancelAutoFocus()
269{
270 LOGV("cancelAutoFocus");
271 sp <ICamera> c = mCamera;
272 if (c == 0) return NO_INIT;
273 return c->cancelAutoFocus();
274}
275
276// take a picture
277status_t Camera::takePicture()
278{
279 LOGV("takePicture");
280 sp <ICamera> c = mCamera;
281 if (c == 0) return NO_INIT;
282 return c->takePicture();
283}
284
285// set preview/capture parameters - key/value pairs
286status_t Camera::setParameters(const String8& params)
287{
288 LOGV("setParameters");
289 sp <ICamera> c = mCamera;
290 if (c == 0) return NO_INIT;
291 return c->setParameters(params);
292}
293
294// get preview/capture parameters - key/value pairs
295String8 Camera::getParameters() const
296{
297 LOGV("getParameters");
298 String8 params;
299 sp <ICamera> c = mCamera;
300 if (c != 0) params = mCamera->getParameters();
301 return params;
302}
303
304// send command to camera driver
305status_t Camera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
306{
307 LOGV("sendCommand");
308 sp <ICamera> c = mCamera;
309 if (c == 0) return NO_INIT;
310 return c->sendCommand(cmd, arg1, arg2);
311}
312
313void Camera::setListener(const sp<CameraListener>& listener)
314{
315 Mutex::Autolock _l(mLock);
316 mListener = listener;
317}
318
319void Camera::setPreviewCallbackFlags(int flag)
320{
321 LOGV("setPreviewCallbackFlags");
322 sp <ICamera> c = mCamera;
323 if (c == 0) return;
324 mCamera->setPreviewCallbackFlag(flag);
325}
326
327// callback from camera service
328void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
329{
330 sp<CameraListener> listener;
331 {
332 Mutex::Autolock _l(mLock);
333 listener = mListener;
334 }
335 if (listener != NULL) {
336 listener->notify(msgType, ext1, ext2);
337 }
338}
339
340// callback from camera service when frame or image is ready
341void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr)
342{
343 sp<CameraListener> listener;
344 {
345 Mutex::Autolock _l(mLock);
346 listener = mListener;
347 }
348 if (listener != NULL) {
349 listener->postData(msgType, dataPtr);
350 }
351}
352
353// callback from camera service when timestamped frame is ready
354void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)
355{
356 sp<CameraListener> listener;
357 {
358 Mutex::Autolock _l(mLock);
359 listener = mListener;
360 }
361 if (listener != NULL) {
362 listener->postDataTimestamp(timestamp, msgType, dataPtr);
363 }
364}
365
366void Camera::binderDied(const wp<IBinder>& who) {
367 LOGW("ICamera died");
368 notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0);
369}
370
371void Camera::DeathNotifier::binderDied(const wp<IBinder>& who) {
372 LOGV("binderDied");
373 Mutex::Autolock _l(Camera::mLock);
374 Camera::mCameraService.clear();
375 LOGW("Camera server died!");
376}
377
378}; // namespace android
379