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