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