blob: 975594f39e11440ef37c48e3c7910c7f23aca585 [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>
22#include <utils/IServiceManager.h>
23#include <utils/threads.h>
24#include <utils/IMemory.h>
25#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
245// take a picture
246status_t Camera::takePicture()
247{
248 LOGV("takePicture");
249 sp <ICamera> c = mCamera;
250 if (c == 0) return NO_INIT;
251 return c->takePicture();
252}
253
254// set preview/capture parameters - key/value pairs
255status_t Camera::setParameters(const String8& params)
256{
257 LOGV("setParameters");
258 sp <ICamera> c = mCamera;
259 if (c == 0) return NO_INIT;
260 return c->setParameters(params);
261}
262
263// get preview/capture parameters - key/value pairs
264String8 Camera::getParameters() const
265{
266 LOGV("getParameters");
267 String8 params;
268 sp <ICamera> c = mCamera;
269 if (c != 0) params = mCamera->getParameters();
270 return params;
271}
272
Dave Sparks5e271152009-06-23 17:30:11 -0700273void Camera::setListener(const sp<CameraListener>& listener)
274{
275 Mutex::Autolock _l(mLock);
276 mListener = listener;
277}
278
279void Camera::setPreviewCallbackFlags(int flag)
280{
281 LOGV("setPreviewCallbackFlags");
282 sp <ICamera> c = mCamera;
283 if (c == 0) return;
284 mCamera->setPreviewCallbackFlag(flag);
285}
286
Dave Sparks2a04aef2009-05-07 12:25:25 -0700287// callback from camera service
288void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
289{
Dave Sparks5e271152009-06-23 17:30:11 -0700290 sp<CameraListener> listener;
291 {
292 Mutex::Autolock _l(mLock);
293 listener = mListener;
294 }
295 if (listener != NULL) {
296 listener->notify(msgType, ext1, ext2);
297 }
Dave Sparks2a04aef2009-05-07 12:25:25 -0700298}
299
Dave Sparksd6289b12009-05-07 19:27:32 -0700300// callback from camera service when frame or image is ready
301void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr)
Dave Sparks2a04aef2009-05-07 12:25:25 -0700302{
Dave Sparks5e271152009-06-23 17:30:11 -0700303 sp<CameraListener> listener;
304 {
305 Mutex::Autolock _l(mLock);
306 listener = mListener;
307 }
308 if (listener != NULL) {
309 listener->postData(msgType, dataPtr);
310 }
Dave Sparks2a04aef2009-05-07 12:25:25 -0700311}
312
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800313void Camera::binderDied(const wp<IBinder>& who) {
314 LOGW("ICamera died");
James Donga1b653d2009-07-02 10:04:20 -0700315 notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800316}
317
318void Camera::DeathNotifier::binderDied(const wp<IBinder>& who) {
319 LOGV("binderDied");
320 Mutex::Autolock _l(Camera::mLock);
321 Camera::mCameraService.clear();
322 LOGW("Camera server died!");
323}
324
325}; // namespace android
326