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/Camera.h>
28#include <camera/ICameraRecordingProxyListener.h>
29#include <camera/ICameraService.h>
30#include <camera/ICamera.h>
31
32#include <gui/IGraphicBufferProducer.h>
33#include <gui/Surface.h>
34
35namespace android {
36
37Camera::Camera(int cameraId)
38    : CameraBase(cameraId)
39{
40}
41
42CameraTraits<Camera>::TCamConnectService CameraTraits<Camera>::fnConnectService =
43        &ICameraService::connect;
44
45// construct a camera client from an existing camera remote
46sp<Camera> Camera::create(const sp<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        camera->asBinder()->linkToDeath(c);
59        return c;
60    }
61    return 0;
62}
63
64Camera::~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
74sp<Camera> Camera::connect(int cameraId, const String16& clientPackageName,
75        int clientUid)
76{
77    return CameraBaseT::connect(cameraId, clientPackageName, clientUid);
78}
79
80status_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<ICameraClient> cl = c;
88    status_t status = NO_ERROR;
89    const sp<ICameraService>& cs = CameraBaseT::getCameraService();
90
91    if (cs != 0) {
92        status = cs.get()->connectLegacy(cl, cameraId, halVersion, clientPackageName,
93                                        clientUid, /*out*/c->mCamera);
94    }
95    if (status == OK && c->mCamera != 0) {
96        c->mCamera->asBinder()->linkToDeath(c);
97        c->mStatus = NO_ERROR;
98        camera = c;
99    } else {
100        ALOGW("An error occurred while connecting to camera: %d", cameraId);
101        c.clear();
102    }
103    return status;
104}
105
106status_t Camera::reconnect()
107{
108    ALOGV("reconnect");
109    sp <ICamera> c = mCamera;
110    if (c == 0) return NO_INIT;
111    return c->connect(this);
112}
113
114status_t Camera::lock()
115{
116    sp <ICamera> c = mCamera;
117    if (c == 0) return NO_INIT;
118    return c->lock();
119}
120
121status_t Camera::unlock()
122{
123    sp <ICamera> c = mCamera;
124    if (c == 0) return NO_INIT;
125    return c->unlock();
126}
127
128// pass the buffered IGraphicBufferProducer to the camera service
129status_t Camera::setPreviewTarget(const sp<IGraphicBufferProducer>& bufferProducer)
130{
131    ALOGV("setPreviewTarget(%p)", bufferProducer.get());
132    sp <ICamera> c = mCamera;
133    if (c == 0) return NO_INIT;
134    ALOGD_IF(bufferProducer == 0, "app passed NULL surface");
135    return c->setPreviewTarget(bufferProducer);
136}
137
138// start preview mode
139status_t Camera::startPreview()
140{
141    ALOGV("startPreview");
142    sp <ICamera> c = mCamera;
143    if (c == 0) return NO_INIT;
144    return c->startPreview();
145}
146
147status_t Camera::storeMetaDataInBuffers(bool enabled)
148{
149    ALOGV("storeMetaDataInBuffers: %s",
150            enabled? "true": "false");
151    sp <ICamera> c = mCamera;
152    if (c == 0) return NO_INIT;
153    return c->storeMetaDataInBuffers(enabled);
154}
155
156// start recording mode, must call setPreviewTarget first
157status_t Camera::startRecording()
158{
159    ALOGV("startRecording");
160    sp <ICamera> c = mCamera;
161    if (c == 0) return NO_INIT;
162    return c->startRecording();
163}
164
165// stop preview mode
166void Camera::stopPreview()
167{
168    ALOGV("stopPreview");
169    sp <ICamera> c = mCamera;
170    if (c == 0) return;
171    c->stopPreview();
172}
173
174// stop recording mode
175void Camera::stopRecording()
176{
177    ALOGV("stopRecording");
178    {
179        Mutex::Autolock _l(mLock);
180        mRecordingProxyListener.clear();
181    }
182    sp <ICamera> c = mCamera;
183    if (c == 0) return;
184    c->stopRecording();
185}
186
187// release a recording frame
188void Camera::releaseRecordingFrame(const sp<IMemory>& mem)
189{
190    ALOGV("releaseRecordingFrame");
191    sp <ICamera> c = mCamera;
192    if (c == 0) return;
193    c->releaseRecordingFrame(mem);
194}
195
196// get preview state
197bool Camera::previewEnabled()
198{
199    ALOGV("previewEnabled");
200    sp <ICamera> c = mCamera;
201    if (c == 0) return false;
202    return c->previewEnabled();
203}
204
205// get recording state
206bool Camera::recordingEnabled()
207{
208    ALOGV("recordingEnabled");
209    sp <ICamera> c = mCamera;
210    if (c == 0) return false;
211    return c->recordingEnabled();
212}
213
214status_t Camera::autoFocus()
215{
216    ALOGV("autoFocus");
217    sp <ICamera> c = mCamera;
218    if (c == 0) return NO_INIT;
219    return c->autoFocus();
220}
221
222status_t Camera::cancelAutoFocus()
223{
224    ALOGV("cancelAutoFocus");
225    sp <ICamera> c = mCamera;
226    if (c == 0) return NO_INIT;
227    return c->cancelAutoFocus();
228}
229
230// take a picture
231status_t Camera::takePicture(int msgType)
232{
233    ALOGV("takePicture: 0x%x", msgType);
234    sp <ICamera> c = mCamera;
235    if (c == 0) return NO_INIT;
236    return c->takePicture(msgType);
237}
238
239// set preview/capture parameters - key/value pairs
240status_t Camera::setParameters(const String8& params)
241{
242    ALOGV("setParameters");
243    sp <ICamera> c = mCamera;
244    if (c == 0) return NO_INIT;
245    return c->setParameters(params);
246}
247
248// get preview/capture parameters - key/value pairs
249String8 Camera::getParameters() const
250{
251    ALOGV("getParameters");
252    String8 params;
253    sp <ICamera> c = mCamera;
254    if (c != 0) params = mCamera->getParameters();
255    return params;
256}
257
258// send command to camera driver
259status_t Camera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
260{
261    ALOGV("sendCommand");
262    sp <ICamera> c = mCamera;
263    if (c == 0) return NO_INIT;
264    return c->sendCommand(cmd, arg1, arg2);
265}
266
267void Camera::setListener(const sp<CameraListener>& listener)
268{
269    Mutex::Autolock _l(mLock);
270    mListener = listener;
271}
272
273void Camera::setRecordingProxyListener(const sp<ICameraRecordingProxyListener>& listener)
274{
275    Mutex::Autolock _l(mLock);
276    mRecordingProxyListener = listener;
277}
278
279void Camera::setPreviewCallbackFlags(int flag)
280{
281    ALOGV("setPreviewCallbackFlags");
282    sp <ICamera> c = mCamera;
283    if (c == 0) return;
284    mCamera->setPreviewCallbackFlag(flag);
285}
286
287status_t Camera::setPreviewCallbackTarget(
288        const sp<IGraphicBufferProducer>& callbackProducer)
289{
290    sp <ICamera> c = mCamera;
291    if (c == 0) return NO_INIT;
292    return c->setPreviewCallbackTarget(callbackProducer);
293}
294
295// callback from camera service
296void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
297{
298    return CameraBaseT::notifyCallback(msgType, ext1, ext2);
299}
300
301// callback from camera service when frame or image is ready
302void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr,
303                          camera_frame_metadata_t *metadata)
304{
305    sp<CameraListener> listener;
306    {
307        Mutex::Autolock _l(mLock);
308        listener = mListener;
309    }
310    if (listener != NULL) {
311        listener->postData(msgType, dataPtr, metadata);
312    }
313}
314
315// callback from camera service when timestamped frame is ready
316void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)
317{
318    // If recording proxy listener is registered, forward the frame and return.
319    // The other listener (mListener) is ignored because the receiver needs to
320    // call releaseRecordingFrame.
321    sp<ICameraRecordingProxyListener> proxylistener;
322    {
323        Mutex::Autolock _l(mLock);
324        proxylistener = mRecordingProxyListener;
325    }
326    if (proxylistener != NULL) {
327        proxylistener->dataCallbackTimestamp(timestamp, msgType, dataPtr);
328        return;
329    }
330
331    sp<CameraListener> listener;
332    {
333        Mutex::Autolock _l(mLock);
334        listener = mListener;
335    }
336
337    if (listener != NULL) {
338        listener->postDataTimestamp(timestamp, msgType, dataPtr);
339    } else {
340        ALOGW("No listener was set. Drop a recording frame.");
341        releaseRecordingFrame(dataPtr);
342    }
343}
344
345sp<ICameraRecordingProxy> Camera::getRecordingProxy() {
346    ALOGV("getProxy");
347    return new RecordingProxy(this);
348}
349
350status_t Camera::RecordingProxy::startRecording(const sp<ICameraRecordingProxyListener>& listener)
351{
352    ALOGV("RecordingProxy::startRecording");
353    mCamera->setRecordingProxyListener(listener);
354    mCamera->reconnect();
355    return mCamera->startRecording();
356}
357
358void Camera::RecordingProxy::stopRecording()
359{
360    ALOGV("RecordingProxy::stopRecording");
361    mCamera->stopRecording();
362}
363
364void Camera::RecordingProxy::releaseRecordingFrame(const sp<IMemory>& mem)
365{
366    ALOGV("RecordingProxy::releaseRecordingFrame");
367    mCamera->releaseRecordingFrame(mem);
368}
369
370Camera::RecordingProxy::RecordingProxy(const sp<Camera>& camera)
371{
372    mCamera = camera;
373}
374
375}; // namespace android
376