1 /*
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 <binder/IServiceManager.h>
23 #include <utils/threads.h>
24 #include <binder/IMemory.h>
25 #include <ui/Surface.h>
26 #include <ui/Camera.h>
27 #include <ui/ICameraService.h>
28
29 namespace android {
30
31 // client singleton for camera service binder interface
32 Mutex Camera::mLock;
33 sp<ICameraService> Camera::mCameraService;
34 sp<Camera::DeathNotifier> Camera::mDeathNotifier;
35
36 // establish binder interface to camera service
getCameraService()37 const 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
Camera()62 Camera::Camera()
63 {
64 init();
65 }
66
67 // construct a camera client from an existing camera remote
create(const sp<ICamera> & camera)68 sp<Camera> Camera::create(const sp<ICamera>& camera)
69 {
70 LOGV("create");
71 if (camera == 0) {
72 LOGE("camera remote is a NULL pointer");
73 return 0;
74 }
75
76 sp<Camera> c = new Camera();
77 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
init()85 void Camera::init()
86 {
87 mStatus = UNKNOWN_ERROR;
88 }
89
~Camera()90 Camera::~Camera()
91 {
92 disconnect();
93 }
94
connect()95 sp<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
disconnect()112 void Camera::disconnect()
113 {
114 LOGV("disconnect");
115 if (mCamera != 0) {
116 mCamera->disconnect();
117 mCamera = 0;
118 }
119 }
120
reconnect()121 status_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
remote()129 sp<ICamera> Camera::remote()
130 {
131 return mCamera;
132 }
133
lock()134 status_t Camera::lock()
135 {
136 sp <ICamera> c = mCamera;
137 if (c == 0) return NO_INIT;
138 return c->lock();
139 }
140
unlock()141 status_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
setPreviewDisplay(const sp<Surface> & surface)149 status_t Camera::setPreviewDisplay(const sp<Surface>& surface)
150 {
151 LOGV("setPreviewDisplay");
152 sp <ICamera> c = mCamera;
153 if (c == 0) return NO_INIT;
154 if (surface != 0) {
155 return c->setPreviewDisplay(surface->getISurface());
156 } else {
157 LOGD("app passed NULL surface");
158 return c->setPreviewDisplay(0);
159 }
160 }
161
setPreviewDisplay(const sp<ISurface> & surface)162 status_t Camera::setPreviewDisplay(const sp<ISurface>& surface)
163 {
164 LOGV("setPreviewDisplay");
165 if (surface == 0) {
166 LOGD("app passed NULL surface");
167 }
168 sp <ICamera> c = mCamera;
169 if (c == 0) return NO_INIT;
170 return c->setPreviewDisplay(surface);
171 }
172
173
174 // start preview mode
startPreview()175 status_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
startRecording()184 status_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
stopPreview()193 void 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
stopRecording()202 void 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
releaseRecordingFrame(const sp<IMemory> & mem)211 void 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
previewEnabled()220 bool 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
recordingEnabled()229 bool Camera::recordingEnabled()
230 {
231 LOGV("recordingEnabled");
232 sp <ICamera> c = mCamera;
233 if (c == 0) return false;
234 return c->recordingEnabled();
235 }
236
autoFocus()237 status_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
cancelAutoFocus()245 status_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
253 // take a picture
takePicture()254 status_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
setParameters(const String8 & params)263 status_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
getParameters() const272 String8 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
281 // send command to camera driver
sendCommand(int32_t cmd,int32_t arg1,int32_t arg2)282 status_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
setListener(const sp<CameraListener> & listener)290 void Camera::setListener(const sp<CameraListener>& listener)
291 {
292 Mutex::Autolock _l(mLock);
293 mListener = listener;
294 }
295
setPreviewCallbackFlags(int flag)296 void Camera::setPreviewCallbackFlags(int flag)
297 {
298 LOGV("setPreviewCallbackFlags");
299 sp <ICamera> c = mCamera;
300 if (c == 0) return;
301 mCamera->setPreviewCallbackFlag(flag);
302 }
303
304 // callback from camera service
notifyCallback(int32_t msgType,int32_t ext1,int32_t ext2)305 void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
306 {
307 sp<CameraListener> listener;
308 {
309 Mutex::Autolock _l(mLock);
310 listener = mListener;
311 }
312 if (listener != NULL) {
313 listener->notify(msgType, ext1, ext2);
314 }
315 }
316
317 // callback from camera service when frame or image is ready
dataCallback(int32_t msgType,const sp<IMemory> & dataPtr)318 void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr)
319 {
320 sp<CameraListener> listener;
321 {
322 Mutex::Autolock _l(mLock);
323 listener = mListener;
324 }
325 if (listener != NULL) {
326 listener->postData(msgType, dataPtr);
327 }
328 }
329
330 // callback from camera service when timestamped frame is ready
dataCallbackTimestamp(nsecs_t timestamp,int32_t msgType,const sp<IMemory> & dataPtr)331 void 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
binderDied(const wp<IBinder> & who)343 void Camera::binderDied(const wp<IBinder>& who) {
344 LOGW("ICamera died");
345 notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0);
346 }
347
binderDied(const wp<IBinder> & who)348 void 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
357