blob: 2fbddd55c613a68e792761e696d5d6d082a4b516 [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>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022#include <utils/threads.h>
Mathias Agopian000479f2010-02-09 17:46:37 -080023
24#include <binder/IServiceManager.h>
Mathias Agopian07952722009-05-19 19:08:10 -070025#include <binder/IMemory.h>
Mathias Agopian000479f2010-02-09 17:46:37 -080026
27#include <camera/Camera.h>
28#include <camera/ICameraService.h>
29
30#include <surfaceflinger/Surface.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031
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
James Dong325ac472009-04-27 12:01:59 -070070// construct a camera client from an existing camera remote
James Dong2adc2db2009-04-23 14:07:23 -070071sp<Camera> Camera::create(const sp<ICamera>& camera)
72{
James Dong325ac472009-04-27 12:01:59 -070073 LOGV("create");
74 if (camera == 0) {
75 LOGE("camera remote is a NULL pointer");
76 return 0;
77 }
78
James Dong2adc2db2009-04-23 14:07:23 -070079 sp<Camera> c = new Camera();
James Dong2adc2db2009-04-23 14:07:23 -070080 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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088void Camera::init()
89{
90 mStatus = UNKNOWN_ERROR;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091}
92
93Camera::~Camera()
94{
Chih-Chung Chang553447b2010-05-13 15:14:24 +080095 // We don't need to call disconnect() here because if the CameraService
96 // thinks we are the owner of the hardware, it will hold a (strong)
97 // reference to us, and we can't possibly be here. We also don't want to
98 // call disconnect() here if we are in the same process as mediaserver,
99 // because we may be invoked by CameraService::Client::connect() and will
100 // deadlock if we call any method of ICamera here.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101}
102
Chih-Chung Change25cc652010-05-06 16:36:58 +0800103int32_t Camera::getNumberOfCameras()
104{
105 const sp<ICameraService>& cs = getCameraService();
106 if (cs == 0) return 0;
107 return cs->getNumberOfCameras();
108}
109
110sp<Camera> Camera::connect(int cameraId)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111{
112 LOGV("connect");
113 sp<Camera> c = new Camera();
114 const sp<ICameraService>& cs = getCameraService();
115 if (cs != 0) {
Chih-Chung Change25cc652010-05-06 16:36:58 +0800116 c->mCamera = cs->connect(c, cameraId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800117 }
118 if (c->mCamera != 0) {
119 c->mCamera->asBinder()->linkToDeath(c);
120 c->mStatus = NO_ERROR;
121 } else {
122 c.clear();
123 }
124 return c;
125}
126
127void Camera::disconnect()
128{
129 LOGV("disconnect");
130 if (mCamera != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800131 mCamera->disconnect();
Chih-Chung Changcfea8fd2010-03-24 16:38:02 -0700132 mCamera->asBinder()->unlinkToDeath(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800133 mCamera = 0;
134 }
135}
136
137status_t Camera::reconnect()
138{
139 LOGV("reconnect");
140 sp <ICamera> c = mCamera;
141 if (c == 0) return NO_INIT;
142 return c->connect(this);
143}
144
145sp<ICamera> Camera::remote()
146{
147 return mCamera;
148}
149
150status_t Camera::lock()
151{
152 sp <ICamera> c = mCamera;
153 if (c == 0) return NO_INIT;
154 return c->lock();
155}
156
157status_t Camera::unlock()
158{
159 sp <ICamera> c = mCamera;
160 if (c == 0) return NO_INIT;
161 return c->unlock();
162}
163
164// pass the buffered ISurface to the camera service
165status_t Camera::setPreviewDisplay(const sp<Surface>& surface)
166{
167 LOGV("setPreviewDisplay");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800168 sp <ICamera> c = mCamera;
169 if (c == 0) return NO_INIT;
Wu-cheng Lib8a10fe2009-06-23 23:37:36 +0800170 if (surface != 0) {
171 return c->setPreviewDisplay(surface->getISurface());
172 } else {
173 LOGD("app passed NULL surface");
174 return c->setPreviewDisplay(0);
175 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800176}
177
178status_t Camera::setPreviewDisplay(const sp<ISurface>& surface)
179{
180 LOGV("setPreviewDisplay");
181 if (surface == 0) {
Wu-cheng Lib8a10fe2009-06-23 23:37:36 +0800182 LOGD("app passed NULL surface");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800183 }
184 sp <ICamera> c = mCamera;
185 if (c == 0) return NO_INIT;
186 return c->setPreviewDisplay(surface);
187}
188
189
Wu-cheng Lib8a10fe2009-06-23 23:37:36 +0800190// start preview mode
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800191status_t Camera::startPreview()
192{
193 LOGV("startPreview");
194 sp <ICamera> c = mCamera;
195 if (c == 0) return NO_INIT;
196 return c->startPreview();
197}
198
199// start recording mode, must call setPreviewDisplay first
200status_t Camera::startRecording()
201{
202 LOGV("startRecording");
203 sp <ICamera> c = mCamera;
204 if (c == 0) return NO_INIT;
205 return c->startRecording();
206}
207
208// stop preview mode
209void Camera::stopPreview()
210{
211 LOGV("stopPreview");
212 sp <ICamera> c = mCamera;
213 if (c == 0) return;
214 c->stopPreview();
215}
216
217// stop recording mode
218void Camera::stopRecording()
219{
220 LOGV("stopRecording");
221 sp <ICamera> c = mCamera;
222 if (c == 0) return;
223 c->stopRecording();
224}
225
226// release a recording frame
227void Camera::releaseRecordingFrame(const sp<IMemory>& mem)
228{
229 LOGV("releaseRecordingFrame");
230 sp <ICamera> c = mCamera;
231 if (c == 0) return;
232 c->releaseRecordingFrame(mem);
233}
234
235// get preview state
236bool Camera::previewEnabled()
237{
238 LOGV("previewEnabled");
239 sp <ICamera> c = mCamera;
240 if (c == 0) return false;
241 return c->previewEnabled();
242}
243
244// get recording state
245bool Camera::recordingEnabled()
246{
247 LOGV("recordingEnabled");
248 sp <ICamera> c = mCamera;
249 if (c == 0) return false;
250 return c->recordingEnabled();
251}
252
253status_t Camera::autoFocus()
254{
255 LOGV("autoFocus");
256 sp <ICamera> c = mCamera;
257 if (c == 0) return NO_INIT;
258 return c->autoFocus();
259}
260
Chih-Chung Chang244f8c22009-09-15 14:51:56 +0800261status_t Camera::cancelAutoFocus()
262{
263 LOGV("cancelAutoFocus");
264 sp <ICamera> c = mCamera;
265 if (c == 0) return NO_INIT;
266 return c->cancelAutoFocus();
267}
268
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800269// take a picture
270status_t Camera::takePicture()
271{
272 LOGV("takePicture");
273 sp <ICamera> c = mCamera;
274 if (c == 0) return NO_INIT;
275 return c->takePicture();
276}
277
278// set preview/capture parameters - key/value pairs
279status_t Camera::setParameters(const String8& params)
280{
281 LOGV("setParameters");
282 sp <ICamera> c = mCamera;
283 if (c == 0) return NO_INIT;
284 return c->setParameters(params);
285}
286
287// get preview/capture parameters - key/value pairs
288String8 Camera::getParameters() const
289{
290 LOGV("getParameters");
291 String8 params;
292 sp <ICamera> c = mCamera;
293 if (c != 0) params = mCamera->getParameters();
294 return params;
295}
296
Wu-cheng Li36f68b82009-09-28 16:14:58 -0700297// send command to camera driver
298status_t Camera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
299{
Wu-cheng Lica9d9dc2010-02-10 13:01:48 +0800300 LOGV("sendCommand");
Wu-cheng Li36f68b82009-09-28 16:14:58 -0700301 sp <ICamera> c = mCamera;
302 if (c == 0) return NO_INIT;
303 return c->sendCommand(cmd, arg1, arg2);
304}
305
Dave Sparks5e271152009-06-23 17:30:11 -0700306void Camera::setListener(const sp<CameraListener>& listener)
307{
308 Mutex::Autolock _l(mLock);
309 mListener = listener;
310}
311
312void Camera::setPreviewCallbackFlags(int flag)
313{
314 LOGV("setPreviewCallbackFlags");
315 sp <ICamera> c = mCamera;
316 if (c == 0) return;
317 mCamera->setPreviewCallbackFlag(flag);
318}
319
Dave Sparks2a04aef2009-05-07 12:25:25 -0700320// callback from camera service
321void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
322{
Dave Sparks5e271152009-06-23 17:30:11 -0700323 sp<CameraListener> listener;
324 {
325 Mutex::Autolock _l(mLock);
326 listener = mListener;
327 }
328 if (listener != NULL) {
329 listener->notify(msgType, ext1, ext2);
330 }
Dave Sparks2a04aef2009-05-07 12:25:25 -0700331}
332
Dave Sparksd6289b12009-05-07 19:27:32 -0700333// callback from camera service when frame or image is ready
334void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr)
Dave Sparks2a04aef2009-05-07 12:25:25 -0700335{
Dave Sparks5e271152009-06-23 17:30:11 -0700336 sp<CameraListener> listener;
337 {
338 Mutex::Autolock _l(mLock);
339 listener = mListener;
340 }
341 if (listener != NULL) {
342 listener->postData(msgType, dataPtr);
343 }
Dave Sparks2a04aef2009-05-07 12:25:25 -0700344}
345
Dave Sparks59c1a932009-07-08 15:56:53 -0700346// callback from camera service when timestamped frame is ready
347void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)
348{
349 sp<CameraListener> listener;
350 {
351 Mutex::Autolock _l(mLock);
352 listener = mListener;
353 }
354 if (listener != NULL) {
355 listener->postDataTimestamp(timestamp, msgType, dataPtr);
356 }
357}
358
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800359void Camera::binderDied(const wp<IBinder>& who) {
360 LOGW("ICamera died");
James Donga1b653d2009-07-02 10:04:20 -0700361 notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800362}
363
364void Camera::DeathNotifier::binderDied(const wp<IBinder>& who) {
365 LOGV("binderDied");
366 Mutex::Autolock _l(Camera::mLock);
367 Camera::mCameraService.clear();
368 LOGW("Camera server died!");
369}
370
371}; // namespace android
372