blob: 09a36f18a1b7044598950ab7d77a61991fb4a663 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -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>
Mathias Agopian07952722009-05-19 19:08:10 -070022#include <binder/IServiceManager.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023#include <utils/threads.h>
Mathias Agopian07952722009-05-19 19:08:10 -070024#include <binder/IMemory.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025#include <ui/Surface.h>
26#include <ui/Camera.h>
27#include <ui/ICameraService.h>
28
29namespace android {
30
31// client singleton for camera service binder interface
32Mutex Camera::mLock;
33sp<ICameraService> Camera::mCameraService;
34sp<Camera::DeathNotifier> Camera::mDeathNotifier;
35
36// establish binder interface to camera service
37const sp<ICameraService>& Camera::getCameraService()
38{
39 Mutex::Autolock _l(mLock);
40 if (mCameraService.get() == 0) {
41 sp<IServiceManager> sm = defaultServiceManager();
42 sp<IBinder> binder;
43 do {
44 binder = sm->getService(String16("media.camera"));
45 if (binder != 0)
46 break;
47 LOGW("CameraService not published, waiting...");
48 usleep(500000); // 0.5 s
49 } while(true);
50 if (mDeathNotifier == NULL) {
51 mDeathNotifier = new DeathNotifier();
52 }
53 binder->linkToDeath(mDeathNotifier);
54 mCameraService = interface_cast<ICameraService>(binder);
55 }
56 LOGE_IF(mCameraService==0, "no CameraService!?");
57 return mCameraService;
58}
59
60// ---------------------------------------------------------------------------
61
62Camera::Camera()
63{
64 init();
65}
66
James Dong325ac472009-04-27 12:01:59 -070067// construct a camera client from an existing camera remote
James Dong2adc2db2009-04-23 14:07:23 -070068sp<Camera> Camera::create(const sp<ICamera>& camera)
69{
James Dong325ac472009-04-27 12:01:59 -070070 LOGV("create");
71 if (camera == 0) {
72 LOGE("camera remote is a NULL pointer");
73 return 0;
74 }
75
James Dong2adc2db2009-04-23 14:07:23 -070076 sp<Camera> c = new Camera();
James Dong2adc2db2009-04-23 14:07:23 -070077 if (camera->connect(c) == NO_ERROR) {
78 c->mStatus = NO_ERROR;
79 c->mCamera = camera;
80 camera->asBinder()->linkToDeath(c);
81 }
82 return c;
83}
84
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080085void Camera::init()
86{
87 mStatus = UNKNOWN_ERROR;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088}
89
90Camera::~Camera()
91{
92 disconnect();
93}
94
95sp<Camera> Camera::connect()
96{
97 LOGV("connect");
98 sp<Camera> c = new Camera();
99 const sp<ICameraService>& cs = getCameraService();
100 if (cs != 0) {
101 c->mCamera = cs->connect(c);
102 }
103 if (c->mCamera != 0) {
104 c->mCamera->asBinder()->linkToDeath(c);
105 c->mStatus = NO_ERROR;
106 } else {
107 c.clear();
108 }
109 return c;
110}
111
112void Camera::disconnect()
113{
114 LOGV("disconnect");
115 if (mCamera != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116 mCamera->disconnect();
117 mCamera = 0;
118 }
119}
120
121status_t Camera::reconnect()
122{
123 LOGV("reconnect");
124 sp <ICamera> c = mCamera;
125 if (c == 0) return NO_INIT;
126 return c->connect(this);
127}
128
129sp<ICamera> Camera::remote()
130{
131 return mCamera;
132}
133
134status_t Camera::lock()
135{
136 sp <ICamera> c = mCamera;
137 if (c == 0) return NO_INIT;
138 return c->lock();
139}
140
141status_t Camera::unlock()
142{
143 sp <ICamera> c = mCamera;
144 if (c == 0) return NO_INIT;
145 return c->unlock();
146}
147
148// pass the buffered ISurface to the camera service
149status_t Camera::setPreviewDisplay(const sp<Surface>& surface)
150{
151 LOGV("setPreviewDisplay");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152 sp <ICamera> c = mCamera;
153 if (c == 0) return NO_INIT;
Wu-cheng Lib8a10fe2009-06-23 23:37:36 +0800154 if (surface != 0) {
155 return c->setPreviewDisplay(surface->getISurface());
156 } else {
157 LOGD("app passed NULL surface");
158 return c->setPreviewDisplay(0);
159 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160}
161
162status_t Camera::setPreviewDisplay(const sp<ISurface>& surface)
163{
164 LOGV("setPreviewDisplay");
165 if (surface == 0) {
Wu-cheng Lib8a10fe2009-06-23 23:37:36 +0800166 LOGD("app passed NULL surface");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800167 }
168 sp <ICamera> c = mCamera;
169 if (c == 0) return NO_INIT;
170 return c->setPreviewDisplay(surface);
171}
172
173
Wu-cheng Lib8a10fe2009-06-23 23:37:36 +0800174// start preview mode
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800175status_t Camera::startPreview()
176{
177 LOGV("startPreview");
178 sp <ICamera> c = mCamera;
179 if (c == 0) return NO_INIT;
180 return c->startPreview();
181}
182
183// start recording mode, must call setPreviewDisplay first
184status_t Camera::startRecording()
185{
186 LOGV("startRecording");
187 sp <ICamera> c = mCamera;
188 if (c == 0) return NO_INIT;
189 return c->startRecording();
190}
191
192// stop preview mode
193void Camera::stopPreview()
194{
195 LOGV("stopPreview");
196 sp <ICamera> c = mCamera;
197 if (c == 0) return;
198 c->stopPreview();
199}
200
201// stop recording mode
202void Camera::stopRecording()
203{
204 LOGV("stopRecording");
205 sp <ICamera> c = mCamera;
206 if (c == 0) return;
207 c->stopRecording();
208}
209
210// release a recording frame
211void Camera::releaseRecordingFrame(const sp<IMemory>& mem)
212{
213 LOGV("releaseRecordingFrame");
214 sp <ICamera> c = mCamera;
215 if (c == 0) return;
216 c->releaseRecordingFrame(mem);
217}
218
219// get preview state
220bool Camera::previewEnabled()
221{
222 LOGV("previewEnabled");
223 sp <ICamera> c = mCamera;
224 if (c == 0) return false;
225 return c->previewEnabled();
226}
227
228// get recording state
229bool Camera::recordingEnabled()
230{
231 LOGV("recordingEnabled");
232 sp <ICamera> c = mCamera;
233 if (c == 0) return false;
234 return c->recordingEnabled();
235}
236
237status_t Camera::autoFocus()
238{
239 LOGV("autoFocus");
240 sp <ICamera> c = mCamera;
241 if (c == 0) return NO_INIT;
242 return c->autoFocus();
243}
244
Chih-Chung Chang244f8c22009-09-15 14:51:56 +0800245status_t Camera::cancelAutoFocus()
246{
247 LOGV("cancelAutoFocus");
248 sp <ICamera> c = mCamera;
249 if (c == 0) return NO_INIT;
250 return c->cancelAutoFocus();
251}
252
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800253// take a picture
254status_t Camera::takePicture()
255{
256 LOGV("takePicture");
257 sp <ICamera> c = mCamera;
258 if (c == 0) return NO_INIT;
259 return c->takePicture();
260}
261
262// set preview/capture parameters - key/value pairs
263status_t Camera::setParameters(const String8& params)
264{
265 LOGV("setParameters");
266 sp <ICamera> c = mCamera;
267 if (c == 0) return NO_INIT;
268 return c->setParameters(params);
269}
270
271// get preview/capture parameters - key/value pairs
272String8 Camera::getParameters() const
273{
274 LOGV("getParameters");
275 String8 params;
276 sp <ICamera> c = mCamera;
277 if (c != 0) params = mCamera->getParameters();
278 return params;
279}
280
Wu-cheng Li36f68b82009-09-28 16:14:58 -0700281// send command to camera driver
282status_t Camera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
283{
284 LOGD("sendCommand");
285 sp <ICamera> c = mCamera;
286 if (c == 0) return NO_INIT;
287 return c->sendCommand(cmd, arg1, arg2);
288}
289
Dave Sparks5e271152009-06-23 17:30:11 -0700290void Camera::setListener(const sp<CameraListener>& listener)
291{
292 Mutex::Autolock _l(mLock);
293 mListener = listener;
294}
295
296void Camera::setPreviewCallbackFlags(int flag)
297{
298 LOGV("setPreviewCallbackFlags");
299 sp <ICamera> c = mCamera;
300 if (c == 0) return;
301 mCamera->setPreviewCallbackFlag(flag);
302}
303
Dave Sparks2a04aef2009-05-07 12:25:25 -0700304// callback from camera service
305void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
306{
Dave Sparks5e271152009-06-23 17:30:11 -0700307 sp<CameraListener> listener;
308 {
309 Mutex::Autolock _l(mLock);
310 listener = mListener;
311 }
312 if (listener != NULL) {
313 listener->notify(msgType, ext1, ext2);
314 }
Dave Sparks2a04aef2009-05-07 12:25:25 -0700315}
316
Dave Sparksd6289b12009-05-07 19:27:32 -0700317// callback from camera service when frame or image is ready
318void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr)
Dave Sparks2a04aef2009-05-07 12:25:25 -0700319{
Dave Sparks5e271152009-06-23 17:30:11 -0700320 sp<CameraListener> listener;
321 {
322 Mutex::Autolock _l(mLock);
323 listener = mListener;
324 }
325 if (listener != NULL) {
326 listener->postData(msgType, dataPtr);
327 }
Dave Sparks2a04aef2009-05-07 12:25:25 -0700328}
329
Dave Sparks59c1a932009-07-08 15:56:53 -0700330// callback from camera service when timestamped frame is ready
331void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)
332{
333 sp<CameraListener> listener;
334 {
335 Mutex::Autolock _l(mLock);
336 listener = mListener;
337 }
338 if (listener != NULL) {
339 listener->postDataTimestamp(timestamp, msgType, dataPtr);
340 }
341}
342
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800343void Camera::binderDied(const wp<IBinder>& who) {
344 LOGW("ICamera died");
James Donga1b653d2009-07-02 10:04:20 -0700345 notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800346}
347
348void Camera::DeathNotifier::binderDied(const wp<IBinder>& who) {
349 LOGV("binderDied");
350 Mutex::Autolock _l(Camera::mLock);
351 Camera::mCameraService.clear();
352 LOGW("Camera server died!");
353}
354
355}; // namespace android
356