blob: 3346b1f876ed6a63b8e6c31e2b5524575bf0d778 [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{
95 disconnect();
96}
97
Chih-Chung Chang35a055b2010-05-06 16:36:58 +080098int32_t Camera::getNumberOfCameras()
99{
100 const sp<ICameraService>& cs = getCameraService();
101 if (cs == 0) return 0;
102 return cs->getNumberOfCameras();
103}
104
105sp<Camera> Camera::connect(int cameraId)
Mathias Agopian3cf61352010-02-09 17:46:37 -0800106{
107 LOGV("connect");
108 sp<Camera> c = new Camera();
109 const sp<ICameraService>& cs = getCameraService();
110 if (cs != 0) {
Chih-Chung Chang35a055b2010-05-06 16:36:58 +0800111 c->mCamera = cs->connect(c, cameraId);
Mathias Agopian3cf61352010-02-09 17:46:37 -0800112 }
113 if (c->mCamera != 0) {
114 c->mCamera->asBinder()->linkToDeath(c);
115 c->mStatus = NO_ERROR;
116 } else {
117 c.clear();
118 }
119 return c;
120}
121
122void Camera::disconnect()
123{
124 LOGV("disconnect");
125 if (mCamera != 0) {
126 mCamera->disconnect();
Chih-Chung Changf8ed70a2010-03-24 16:38:02 -0700127 mCamera->asBinder()->unlinkToDeath(this);
Mathias Agopian3cf61352010-02-09 17:46:37 -0800128 mCamera = 0;
129 }
130}
131
132status_t Camera::reconnect()
133{
134 LOGV("reconnect");
135 sp <ICamera> c = mCamera;
136 if (c == 0) return NO_INIT;
137 return c->connect(this);
138}
139
140sp<ICamera> Camera::remote()
141{
142 return mCamera;
143}
144
145status_t Camera::lock()
146{
147 sp <ICamera> c = mCamera;
148 if (c == 0) return NO_INIT;
149 return c->lock();
150}
151
152status_t Camera::unlock()
153{
154 sp <ICamera> c = mCamera;
155 if (c == 0) return NO_INIT;
156 return c->unlock();
157}
158
159// pass the buffered ISurface to the camera service
160status_t Camera::setPreviewDisplay(const sp<Surface>& surface)
161{
162 LOGV("setPreviewDisplay");
163 sp <ICamera> c = mCamera;
164 if (c == 0) return NO_INIT;
165 if (surface != 0) {
166 return c->setPreviewDisplay(surface->getISurface());
167 } else {
168 LOGD("app passed NULL surface");
169 return c->setPreviewDisplay(0);
170 }
171}
172
173status_t Camera::setPreviewDisplay(const sp<ISurface>& surface)
174{
175 LOGV("setPreviewDisplay");
176 if (surface == 0) {
177 LOGD("app passed NULL surface");
178 }
179 sp <ICamera> c = mCamera;
180 if (c == 0) return NO_INIT;
181 return c->setPreviewDisplay(surface);
182}
183
184
185// start preview mode
186status_t Camera::startPreview()
187{
188 LOGV("startPreview");
189 sp <ICamera> c = mCamera;
190 if (c == 0) return NO_INIT;
191 return c->startPreview();
192}
193
194// start recording mode, must call setPreviewDisplay first
195status_t Camera::startRecording()
196{
197 LOGV("startRecording");
198 sp <ICamera> c = mCamera;
199 if (c == 0) return NO_INIT;
200 return c->startRecording();
201}
202
203// stop preview mode
204void Camera::stopPreview()
205{
206 LOGV("stopPreview");
207 sp <ICamera> c = mCamera;
208 if (c == 0) return;
209 c->stopPreview();
210}
211
212// stop recording mode
213void Camera::stopRecording()
214{
215 LOGV("stopRecording");
216 sp <ICamera> c = mCamera;
217 if (c == 0) return;
218 c->stopRecording();
219}
220
221// release a recording frame
222void Camera::releaseRecordingFrame(const sp<IMemory>& mem)
223{
224 LOGV("releaseRecordingFrame");
225 sp <ICamera> c = mCamera;
226 if (c == 0) return;
227 c->releaseRecordingFrame(mem);
228}
229
230// get preview state
231bool Camera::previewEnabled()
232{
233 LOGV("previewEnabled");
234 sp <ICamera> c = mCamera;
235 if (c == 0) return false;
236 return c->previewEnabled();
237}
238
239// get recording state
240bool Camera::recordingEnabled()
241{
242 LOGV("recordingEnabled");
243 sp <ICamera> c = mCamera;
244 if (c == 0) return false;
245 return c->recordingEnabled();
246}
247
248status_t Camera::autoFocus()
249{
250 LOGV("autoFocus");
251 sp <ICamera> c = mCamera;
252 if (c == 0) return NO_INIT;
253 return c->autoFocus();
254}
255
256status_t Camera::cancelAutoFocus()
257{
258 LOGV("cancelAutoFocus");
259 sp <ICamera> c = mCamera;
260 if (c == 0) return NO_INIT;
261 return c->cancelAutoFocus();
262}
263
264// take a picture
265status_t Camera::takePicture()
266{
267 LOGV("takePicture");
268 sp <ICamera> c = mCamera;
269 if (c == 0) return NO_INIT;
270 return c->takePicture();
271}
272
273// set preview/capture parameters - key/value pairs
274status_t Camera::setParameters(const String8& params)
275{
276 LOGV("setParameters");
277 sp <ICamera> c = mCamera;
278 if (c == 0) return NO_INIT;
279 return c->setParameters(params);
280}
281
282// get preview/capture parameters - key/value pairs
283String8 Camera::getParameters() const
284{
285 LOGV("getParameters");
286 String8 params;
287 sp <ICamera> c = mCamera;
288 if (c != 0) params = mCamera->getParameters();
289 return params;
290}
291
292// send command to camera driver
293status_t Camera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
294{
295 LOGV("sendCommand");
296 sp <ICamera> c = mCamera;
297 if (c == 0) return NO_INIT;
298 return c->sendCommand(cmd, arg1, arg2);
299}
300
301void Camera::setListener(const sp<CameraListener>& listener)
302{
303 Mutex::Autolock _l(mLock);
304 mListener = listener;
305}
306
307void Camera::setPreviewCallbackFlags(int flag)
308{
309 LOGV("setPreviewCallbackFlags");
310 sp <ICamera> c = mCamera;
311 if (c == 0) return;
312 mCamera->setPreviewCallbackFlag(flag);
313}
314
315// callback from camera service
316void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
317{
318 sp<CameraListener> listener;
319 {
320 Mutex::Autolock _l(mLock);
321 listener = mListener;
322 }
323 if (listener != NULL) {
324 listener->notify(msgType, ext1, ext2);
325 }
326}
327
328// callback from camera service when frame or image is ready
329void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr)
330{
331 sp<CameraListener> listener;
332 {
333 Mutex::Autolock _l(mLock);
334 listener = mListener;
335 }
336 if (listener != NULL) {
337 listener->postData(msgType, dataPtr);
338 }
339}
340
341// callback from camera service when timestamped frame is ready
342void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)
343{
344 sp<CameraListener> listener;
345 {
346 Mutex::Autolock _l(mLock);
347 listener = mListener;
348 }
349 if (listener != NULL) {
350 listener->postDataTimestamp(timestamp, msgType, dataPtr);
351 }
352}
353
354void Camera::binderDied(const wp<IBinder>& who) {
355 LOGW("ICamera died");
356 notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0);
357}
358
359void Camera::DeathNotifier::binderDied(const wp<IBinder>& who) {
360 LOGV("binderDied");
361 Mutex::Autolock _l(Camera::mLock);
362 Camera::mCameraService.clear();
363 LOGW("Camera server died!");
364}
365
366}; // namespace android
367