• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 **
3 ** Copyright (C) 2008, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 **     http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17 
18 //#define LOG_NDEBUG 0
19 #define LOG_TAG "Camera"
20 #include <utils/Log.h>
21 #include <utils/threads.h>
22 #include <utils/String16.h>
23 #include <binder/IPCThreadState.h>
24 #include <binder/IServiceManager.h>
25 #include <binder/IMemory.h>
26 
27 #include <Camera.h>
28 #include <ICameraRecordingProxyListener.h>
29 #include <android/hardware/ICameraService.h>
30 #include <android/hardware/ICamera.h>
31 
32 #include <gui/IGraphicBufferProducer.h>
33 #include <gui/Surface.h>
34 
35 namespace android {
36 
Camera(int cameraId)37 Camera::Camera(int cameraId)
38     : CameraBase(cameraId)
39 {
40 }
41 
42 CameraTraits<Camera>::TCamConnectService CameraTraits<Camera>::fnConnectService =
43         &::android::hardware::ICameraService::connect;
44 
45 // construct a camera client from an existing camera remote
create(const sp<::android::hardware::ICamera> & camera)46 sp<Camera> Camera::create(const sp<::android::hardware::ICamera>& camera)
47 {
48      ALOGV("create");
49      if (camera == 0) {
50          ALOGE("camera remote is a NULL pointer");
51          return 0;
52      }
53 
54     sp<Camera> c = new Camera(-1);
55     if (camera->connect(c) == NO_ERROR) {
56         c->mStatus = NO_ERROR;
57         c->mCamera = camera;
58         IInterface::asBinder(camera)->linkToDeath(c);
59         return c;
60     }
61     return 0;
62 }
63 
~Camera()64 Camera::~Camera()
65 {
66     // We don't need to call disconnect() here because if the CameraService
67     // thinks we are the owner of the hardware, it will hold a (strong)
68     // reference to us, and we can't possibly be here. We also don't want to
69     // call disconnect() here if we are in the same process as mediaserver,
70     // because we may be invoked by CameraService::Client::connect() and will
71     // deadlock if we call any method of ICamera here.
72 }
73 
connect(int cameraId,const String16 & clientPackageName,int clientUid,int clientPid)74 sp<Camera> Camera::connect(int cameraId, const String16& clientPackageName,
75         int clientUid, int clientPid)
76 {
77     return CameraBaseT::connect(cameraId, clientPackageName, clientUid, clientPid);
78 }
79 
connectLegacy(int cameraId,int halVersion,const String16 & clientPackageName,int clientUid,sp<Camera> & camera)80 status_t Camera::connectLegacy(int cameraId, int halVersion,
81         const String16& clientPackageName,
82         int clientUid,
83         sp<Camera>& camera)
84 {
85     ALOGV("%s: connect legacy camera device", __FUNCTION__);
86     sp<Camera> c = new Camera(cameraId);
87     sp<::android::hardware::ICameraClient> cl = c;
88     status_t status = NO_ERROR;
89     const sp<::android::hardware::ICameraService>& cs = CameraBaseT::getCameraService();
90 
91     binder::Status ret;
92     if (cs != nullptr) {
93         ret = cs.get()->connectLegacy(cl, cameraId, halVersion, clientPackageName,
94                 clientUid, /*out*/&(c->mCamera));
95     }
96     if (ret.isOk() && c->mCamera != nullptr) {
97         IInterface::asBinder(c->mCamera)->linkToDeath(c);
98         c->mStatus = NO_ERROR;
99         camera = c;
100     } else {
101         switch(ret.serviceSpecificErrorCode()) {
102             case hardware::ICameraService::ERROR_DISCONNECTED:
103                 status = -ENODEV;
104                 break;
105             case hardware::ICameraService::ERROR_CAMERA_IN_USE:
106                 status = -EBUSY;
107                 break;
108             case hardware::ICameraService::ERROR_INVALID_OPERATION:
109                 status = -EINVAL;
110                 break;
111             case hardware::ICameraService::ERROR_MAX_CAMERAS_IN_USE:
112                 status = -EUSERS;
113                 break;
114             case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
115                 status = BAD_VALUE;
116                 break;
117             case hardware::ICameraService::ERROR_DEPRECATED_HAL:
118                 status = -EOPNOTSUPP;
119                 break;
120             case hardware::ICameraService::ERROR_DISABLED:
121                 status = -EACCES;
122                 break;
123             case hardware::ICameraService::ERROR_PERMISSION_DENIED:
124                 status = PERMISSION_DENIED;
125                 break;
126             default:
127                 status = -EINVAL;
128                 ALOGW("An error occurred while connecting to camera %d: %s", cameraId,
129                         (cs != nullptr) ? "Service not available" : ret.toString8().string());
130                 break;
131         }
132         c.clear();
133     }
134     return status;
135 }
136 
reconnect()137 status_t Camera::reconnect()
138 {
139     ALOGV("reconnect");
140     sp <::android::hardware::ICamera> c = mCamera;
141     if (c == 0) return NO_INIT;
142     return c->connect(this);
143 }
144 
lock()145 status_t Camera::lock()
146 {
147     sp <::android::hardware::ICamera> c = mCamera;
148     if (c == 0) return NO_INIT;
149     return c->lock();
150 }
151 
unlock()152 status_t Camera::unlock()
153 {
154     sp <::android::hardware::ICamera> c = mCamera;
155     if (c == 0) return NO_INIT;
156     return c->unlock();
157 }
158 
159 // pass the buffered IGraphicBufferProducer to the camera service
setPreviewTarget(const sp<IGraphicBufferProducer> & bufferProducer)160 status_t Camera::setPreviewTarget(const sp<IGraphicBufferProducer>& bufferProducer)
161 {
162     ALOGV("setPreviewTarget(%p)", bufferProducer.get());
163     sp <::android::hardware::ICamera> c = mCamera;
164     if (c == 0) return NO_INIT;
165     ALOGD_IF(bufferProducer == 0, "app passed NULL surface");
166     return c->setPreviewTarget(bufferProducer);
167 }
168 
setVideoTarget(const sp<IGraphicBufferProducer> & bufferProducer)169 status_t Camera::setVideoTarget(const sp<IGraphicBufferProducer>& bufferProducer)
170 {
171     ALOGV("setVideoTarget(%p)", bufferProducer.get());
172     sp <::android::hardware::ICamera> c = mCamera;
173     if (c == 0) return NO_INIT;
174     ALOGD_IF(bufferProducer == 0, "app passed NULL video surface");
175     return c->setVideoTarget(bufferProducer);
176 }
177 
178 // start preview mode
startPreview()179 status_t Camera::startPreview()
180 {
181     ALOGV("startPreview");
182     sp <::android::hardware::ICamera> c = mCamera;
183     if (c == 0) return NO_INIT;
184     return c->startPreview();
185 }
186 
setVideoBufferMode(int32_t videoBufferMode)187 status_t Camera::setVideoBufferMode(int32_t videoBufferMode)
188 {
189     ALOGV("setVideoBufferMode: %d", videoBufferMode);
190     sp <::android::hardware::ICamera> c = mCamera;
191     if (c == 0) return NO_INIT;
192     return c->setVideoBufferMode(videoBufferMode);
193 }
194 
195 // start recording mode, must call setPreviewTarget first
startRecording()196 status_t Camera::startRecording()
197 {
198     ALOGV("startRecording");
199     sp <::android::hardware::ICamera> c = mCamera;
200     if (c == 0) return NO_INIT;
201     return c->startRecording();
202 }
203 
204 // stop preview mode
stopPreview()205 void Camera::stopPreview()
206 {
207     ALOGV("stopPreview");
208     sp <::android::hardware::ICamera> c = mCamera;
209     if (c == 0) return;
210     c->stopPreview();
211 }
212 
213 // stop recording mode
stopRecording()214 void Camera::stopRecording()
215 {
216     ALOGV("stopRecording");
217     {
218         Mutex::Autolock _l(mLock);
219         mRecordingProxyListener.clear();
220     }
221     sp <::android::hardware::ICamera> c = mCamera;
222     if (c == 0) return;
223     c->stopRecording();
224 }
225 
226 // release a recording frame
releaseRecordingFrame(const sp<IMemory> & mem)227 void Camera::releaseRecordingFrame(const sp<IMemory>& mem)
228 {
229     ALOGV("releaseRecordingFrame");
230     sp <::android::hardware::ICamera> c = mCamera;
231     if (c == 0) return;
232     c->releaseRecordingFrame(mem);
233 }
234 
releaseRecordingFrameHandle(native_handle_t * handle)235 void Camera::releaseRecordingFrameHandle(native_handle_t* handle)
236 {
237     ALOGV("releaseRecordingFrameHandle");
238     sp <::android::hardware::ICamera> c = mCamera;
239     if (c == 0) return;
240     c->releaseRecordingFrameHandle(handle);
241 }
242 
releaseRecordingFrameHandleBatch(const std::vector<native_handle_t * > handles)243 void Camera::releaseRecordingFrameHandleBatch(
244         const std::vector<native_handle_t*> handles) {
245     ALOGV("releaseRecordingFrameHandleBatch");
246     sp <::android::hardware::ICamera> c = mCamera;
247     if (c == 0) return;
248     c->releaseRecordingFrameHandleBatch(handles);
249 }
250 
251 // get preview state
previewEnabled()252 bool Camera::previewEnabled()
253 {
254     ALOGV("previewEnabled");
255     sp <::android::hardware::ICamera> c = mCamera;
256     if (c == 0) return false;
257     return c->previewEnabled();
258 }
259 
260 // get recording state
recordingEnabled()261 bool Camera::recordingEnabled()
262 {
263     ALOGV("recordingEnabled");
264     sp <::android::hardware::ICamera> c = mCamera;
265     if (c == 0) return false;
266     return c->recordingEnabled();
267 }
268 
autoFocus()269 status_t Camera::autoFocus()
270 {
271     ALOGV("autoFocus");
272     sp <::android::hardware::ICamera> c = mCamera;
273     if (c == 0) return NO_INIT;
274     return c->autoFocus();
275 }
276 
cancelAutoFocus()277 status_t Camera::cancelAutoFocus()
278 {
279     ALOGV("cancelAutoFocus");
280     sp <::android::hardware::ICamera> c = mCamera;
281     if (c == 0) return NO_INIT;
282     return c->cancelAutoFocus();
283 }
284 
285 // take a picture
takePicture(int msgType)286 status_t Camera::takePicture(int msgType)
287 {
288     ALOGV("takePicture: 0x%x", msgType);
289     sp <::android::hardware::ICamera> c = mCamera;
290     if (c == 0) return NO_INIT;
291     return c->takePicture(msgType);
292 }
293 
294 // set preview/capture parameters - key/value pairs
setParameters(const String8 & params)295 status_t Camera::setParameters(const String8& params)
296 {
297     ALOGV("setParameters");
298     sp <::android::hardware::ICamera> c = mCamera;
299     if (c == 0) return NO_INIT;
300     return c->setParameters(params);
301 }
302 
303 // get preview/capture parameters - key/value pairs
getParameters() const304 String8 Camera::getParameters() const
305 {
306     ALOGV("getParameters");
307     String8 params;
308     sp <::android::hardware::ICamera> c = mCamera;
309     if (c != 0) params = mCamera->getParameters();
310     return params;
311 }
312 
313 // send command to camera driver
sendCommand(int32_t cmd,int32_t arg1,int32_t arg2)314 status_t Camera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
315 {
316     ALOGV("sendCommand");
317     sp <::android::hardware::ICamera> c = mCamera;
318     if (c == 0) return NO_INIT;
319     return c->sendCommand(cmd, arg1, arg2);
320 }
321 
setListener(const sp<CameraListener> & listener)322 void Camera::setListener(const sp<CameraListener>& listener)
323 {
324     Mutex::Autolock _l(mLock);
325     mListener = listener;
326 }
327 
setRecordingProxyListener(const sp<ICameraRecordingProxyListener> & listener)328 void Camera::setRecordingProxyListener(const sp<ICameraRecordingProxyListener>& listener)
329 {
330     Mutex::Autolock _l(mLock);
331     mRecordingProxyListener = listener;
332 }
333 
setPreviewCallbackFlags(int flag)334 void Camera::setPreviewCallbackFlags(int flag)
335 {
336     ALOGV("setPreviewCallbackFlags");
337     sp <::android::hardware::ICamera> c = mCamera;
338     if (c == 0) return;
339     mCamera->setPreviewCallbackFlag(flag);
340 }
341 
setPreviewCallbackTarget(const sp<IGraphicBufferProducer> & callbackProducer)342 status_t Camera::setPreviewCallbackTarget(
343         const sp<IGraphicBufferProducer>& callbackProducer)
344 {
345     sp <::android::hardware::ICamera> c = mCamera;
346     if (c == 0) return NO_INIT;
347     return c->setPreviewCallbackTarget(callbackProducer);
348 }
349 
350 // callback from camera service
notifyCallback(int32_t msgType,int32_t ext1,int32_t ext2)351 void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
352 {
353     return CameraBaseT::notifyCallback(msgType, ext1, ext2);
354 }
355 
356 // callback from camera service when frame or image is ready
dataCallback(int32_t msgType,const sp<IMemory> & dataPtr,camera_frame_metadata_t * metadata)357 void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr,
358                           camera_frame_metadata_t *metadata)
359 {
360     sp<CameraListener> listener;
361     {
362         Mutex::Autolock _l(mLock);
363         listener = mListener;
364     }
365     if (listener != NULL) {
366         listener->postData(msgType, dataPtr, metadata);
367     }
368 }
369 
370 // callback from camera service when timestamped frame is ready
dataCallbackTimestamp(nsecs_t timestamp,int32_t msgType,const sp<IMemory> & dataPtr)371 void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)
372 {
373     // If recording proxy listener is registered, forward the frame and return.
374     // The other listener (mListener) is ignored because the receiver needs to
375     // call releaseRecordingFrame.
376     sp<ICameraRecordingProxyListener> proxylistener;
377     {
378         Mutex::Autolock _l(mLock);
379         proxylistener = mRecordingProxyListener;
380     }
381     if (proxylistener != NULL) {
382         proxylistener->dataCallbackTimestamp(timestamp, msgType, dataPtr);
383         return;
384     }
385 
386     sp<CameraListener> listener;
387     {
388         Mutex::Autolock _l(mLock);
389         listener = mListener;
390     }
391 
392     if (listener != NULL) {
393         listener->postDataTimestamp(timestamp, msgType, dataPtr);
394     } else {
395         ALOGW("No listener was set. Drop a recording frame.");
396         releaseRecordingFrame(dataPtr);
397     }
398 }
399 
recordingFrameHandleCallbackTimestamp(nsecs_t timestamp,native_handle_t * handle)400 void Camera::recordingFrameHandleCallbackTimestamp(nsecs_t timestamp, native_handle_t* handle)
401 {
402     // If recording proxy listener is registered, forward the frame and return.
403     // The other listener (mListener) is ignored because the receiver needs to
404     // call releaseRecordingFrameHandle.
405     sp<ICameraRecordingProxyListener> proxylistener;
406     {
407         Mutex::Autolock _l(mLock);
408         proxylistener = mRecordingProxyListener;
409     }
410     if (proxylistener != NULL) {
411         proxylistener->recordingFrameHandleCallbackTimestamp(timestamp, handle);
412         return;
413     }
414 
415     sp<CameraListener> listener;
416     {
417         Mutex::Autolock _l(mLock);
418         listener = mListener;
419     }
420 
421     if (listener != NULL) {
422         listener->postRecordingFrameHandleTimestamp(timestamp, handle);
423     } else {
424         ALOGW("No listener was set. Drop a recording frame.");
425         releaseRecordingFrameHandle(handle);
426     }
427 }
428 
recordingFrameHandleCallbackTimestampBatch(const std::vector<nsecs_t> & timestamps,const std::vector<native_handle_t * > & handles)429 void Camera::recordingFrameHandleCallbackTimestampBatch(
430         const std::vector<nsecs_t>& timestamps,
431         const std::vector<native_handle_t*>& handles)
432 {
433     // If recording proxy listener is registered, forward the frame and return.
434     // The other listener (mListener) is ignored because the receiver needs to
435     // call releaseRecordingFrameHandle.
436     sp<ICameraRecordingProxyListener> proxylistener;
437     {
438         Mutex::Autolock _l(mLock);
439         proxylistener = mRecordingProxyListener;
440     }
441     if (proxylistener != NULL) {
442         proxylistener->recordingFrameHandleCallbackTimestampBatch(timestamps, handles);
443         return;
444     }
445 
446     sp<CameraListener> listener;
447     {
448         Mutex::Autolock _l(mLock);
449         listener = mListener;
450     }
451 
452     if (listener != NULL) {
453         listener->postRecordingFrameHandleTimestampBatch(timestamps, handles);
454     } else {
455         ALOGW("No listener was set. Drop a batch of recording frames.");
456         releaseRecordingFrameHandleBatch(handles);
457     }
458 }
459 
getRecordingProxy()460 sp<ICameraRecordingProxy> Camera::getRecordingProxy() {
461     ALOGV("getProxy");
462     return new RecordingProxy(this);
463 }
464 
startRecording(const sp<ICameraRecordingProxyListener> & listener)465 status_t Camera::RecordingProxy::startRecording(const sp<ICameraRecordingProxyListener>& listener)
466 {
467     ALOGV("RecordingProxy::startRecording");
468     mCamera->setRecordingProxyListener(listener);
469     mCamera->reconnect();
470     return mCamera->startRecording();
471 }
472 
stopRecording()473 void Camera::RecordingProxy::stopRecording()
474 {
475     ALOGV("RecordingProxy::stopRecording");
476     mCamera->stopRecording();
477 }
478 
releaseRecordingFrame(const sp<IMemory> & mem)479 void Camera::RecordingProxy::releaseRecordingFrame(const sp<IMemory>& mem)
480 {
481     ALOGV("RecordingProxy::releaseRecordingFrame");
482     mCamera->releaseRecordingFrame(mem);
483 }
484 
releaseRecordingFrameHandle(native_handle_t * handle)485 void Camera::RecordingProxy::releaseRecordingFrameHandle(native_handle_t* handle) {
486     ALOGV("RecordingProxy::releaseRecordingFrameHandle");
487     mCamera->releaseRecordingFrameHandle(handle);
488 }
489 
releaseRecordingFrameHandleBatch(const std::vector<native_handle_t * > & handles)490 void Camera::RecordingProxy::releaseRecordingFrameHandleBatch(
491         const std::vector<native_handle_t*>& handles) {
492     ALOGV("RecordingProxy::releaseRecordingFrameHandleBatch");
493     mCamera->releaseRecordingFrameHandleBatch(handles);
494 }
495 
RecordingProxy(const sp<Camera> & camera)496 Camera::RecordingProxy::RecordingProxy(const sp<Camera>& camera)
497 {
498     mCamera = camera;
499 }
500 
501 }; // namespace android
502