Camera2ClientBase.cpp revision cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4
1/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "Camera2ClientBase"
18#define ATRACE_TAG ATRACE_TAG_CAMERA
19//#define LOG_NDEBUG 0
20
21#include <inttypes.h>
22
23#include <utils/Log.h>
24#include <utils/Trace.h>
25
26#include <cutils/properties.h>
27#include <gui/Surface.h>
28#include <gui/Surface.h>
29
30#include "common/Camera2ClientBase.h"
31
32#include "api2/CameraDeviceClient.h"
33
34#include "CameraDeviceFactory.h"
35
36namespace android {
37using namespace camera2;
38
39static int getCallingPid() {
40    return IPCThreadState::self()->getCallingPid();
41}
42
43// Interface used by CameraService
44
45template <typename TClientBase>
46Camera2ClientBase<TClientBase>::Camera2ClientBase(
47        const sp<CameraService>& cameraService,
48        const sp<TCamCallbacks>& remoteCallback,
49        const String16& clientPackageName,
50        int cameraId,
51        int cameraFacing,
52        int clientPid,
53        uid_t clientUid,
54        int servicePid):
55        TClientBase(cameraService, remoteCallback, clientPackageName,
56                cameraId, cameraFacing, clientPid, clientUid, servicePid),
57        mSharedCameraCallbacks(remoteCallback),
58        mDeviceVersion(cameraService->getDeviceVersion(cameraId))
59{
60    ALOGI("Camera %d: Opened", cameraId);
61
62    mDevice = CameraDeviceFactory::createDevice(cameraId);
63    LOG_ALWAYS_FATAL_IF(mDevice == 0, "Device should never be NULL here.");
64}
65
66template <typename TClientBase>
67status_t Camera2ClientBase<TClientBase>::checkPid(const char* checkLocation)
68        const {
69
70    int callingPid = getCallingPid();
71    if (callingPid == TClientBase::mClientPid) return NO_ERROR;
72
73    ALOGE("%s: attempt to use a locked camera from a different process"
74            " (old pid %d, new pid %d)", checkLocation, TClientBase::mClientPid, callingPid);
75    return PERMISSION_DENIED;
76}
77
78template <typename TClientBase>
79status_t Camera2ClientBase<TClientBase>::initialize(camera_module_t *module) {
80    ATRACE_CALL();
81    ALOGV("%s: Initializing client for camera %d", __FUNCTION__,
82          TClientBase::mCameraId);
83    status_t res;
84
85    // Verify ops permissions
86    res = TClientBase::startCameraOps();
87    if (res != OK) {
88        return res;
89    }
90
91    if (mDevice == NULL) {
92        ALOGE("%s: Camera %d: No device connected",
93                __FUNCTION__, TClientBase::mCameraId);
94        return NO_INIT;
95    }
96
97    res = mDevice->initialize(module);
98    if (res != OK) {
99        ALOGE("%s: Camera %d: unable to initialize device: %s (%d)",
100                __FUNCTION__, TClientBase::mCameraId, strerror(-res), res);
101        return res;
102    }
103
104    res = mDevice->setNotifyCallback(this);
105
106    return OK;
107}
108
109template <typename TClientBase>
110Camera2ClientBase<TClientBase>::~Camera2ClientBase() {
111    ATRACE_CALL();
112
113    TClientBase::mDestructionStarted = true;
114
115    TClientBase::finishCameraOps();
116
117    disconnect();
118
119    ALOGI("Closed Camera %d", TClientBase::mCameraId);
120}
121
122template <typename TClientBase>
123status_t Camera2ClientBase<TClientBase>::dump(int fd,
124                                              const Vector<String16>& args) {
125    String8 result;
126    result.appendFormat("Camera2ClientBase[%d] (%p) PID: %d, dump:\n",
127            TClientBase::mCameraId,
128            TClientBase::getRemoteCallback()->asBinder().get(),
129            TClientBase::mClientPid);
130    result.append("  State: ");
131
132    write(fd, result.string(), result.size());
133    // TODO: print dynamic/request section from most recent requests
134
135    return dumpDevice(fd, args);
136}
137
138template <typename TClientBase>
139status_t Camera2ClientBase<TClientBase>::dumpDevice(
140                                                int fd,
141                                                const Vector<String16>& args) {
142    String8 result;
143
144    result = "  Device dump:\n";
145    write(fd, result.string(), result.size());
146
147    if (!mDevice.get()) {
148        result = "  *** Device is detached\n";
149        write(fd, result.string(), result.size());
150        return NO_ERROR;
151    }
152
153    status_t res = mDevice->dump(fd, args);
154    if (res != OK) {
155        result = String8::format("   Error dumping device: %s (%d)",
156                strerror(-res), res);
157        write(fd, result.string(), result.size());
158    }
159
160    return NO_ERROR;
161}
162
163// ICameraClient2BaseUser interface
164
165
166template <typename TClientBase>
167void Camera2ClientBase<TClientBase>::disconnect() {
168    ATRACE_CALL();
169    Mutex::Autolock icl(mBinderSerializationLock);
170
171    // Allow both client and the media server to disconnect at all times
172    int callingPid = getCallingPid();
173    if (callingPid != TClientBase::mClientPid &&
174        callingPid != TClientBase::mServicePid) return;
175
176    ALOGV("Camera %d: Shutting down", TClientBase::mCameraId);
177
178    detachDevice();
179
180    CameraService::BasicClient::disconnect();
181
182    ALOGV("Camera %d: Shut down complete complete", TClientBase::mCameraId);
183}
184
185template <typename TClientBase>
186void Camera2ClientBase<TClientBase>::detachDevice() {
187    if (mDevice == 0) return;
188    mDevice->disconnect();
189
190    mDevice.clear();
191
192    ALOGV("Camera %d: Detach complete", TClientBase::mCameraId);
193}
194
195template <typename TClientBase>
196status_t Camera2ClientBase<TClientBase>::connect(
197        const sp<TCamCallbacks>& client) {
198    ATRACE_CALL();
199    ALOGV("%s: E", __FUNCTION__);
200    Mutex::Autolock icl(mBinderSerializationLock);
201
202    if (TClientBase::mClientPid != 0 &&
203        getCallingPid() != TClientBase::mClientPid) {
204
205        ALOGE("%s: Camera %d: Connection attempt from pid %d; "
206                "current locked to pid %d",
207                __FUNCTION__,
208                TClientBase::mCameraId,
209                getCallingPid(),
210                TClientBase::mClientPid);
211        return BAD_VALUE;
212    }
213
214    TClientBase::mClientPid = getCallingPid();
215
216    TClientBase::mRemoteCallback = client;
217    mSharedCameraCallbacks = client;
218
219    return OK;
220}
221
222/** Device-related methods */
223
224template <typename TClientBase>
225void Camera2ClientBase<TClientBase>::notifyError(
226        ICameraDeviceCallbacks::CameraErrorCode errorCode,
227        const CaptureResultExtras& resultExtras) {
228    ALOGE("Error condition %d reported by HAL, requestId %" PRId32, errorCode,
229          resultExtras.requestId);
230}
231
232template <typename TClientBase>
233void Camera2ClientBase<TClientBase>::notifyIdle() {
234    ALOGV("Camera device is now idle");
235}
236
237template <typename TClientBase>
238void Camera2ClientBase<TClientBase>::notifyShutter(const CaptureResultExtras& resultExtras,
239                                                   nsecs_t timestamp) {
240    (void)resultExtras;
241    (void)timestamp;
242
243    ALOGV("%s: Shutter notification for request id %" PRId32 " at time %" PRId64,
244            __FUNCTION__, resultExtras.requestId, timestamp);
245}
246
247template <typename TClientBase>
248void Camera2ClientBase<TClientBase>::notifyAutoFocus(uint8_t newState,
249                                                     int triggerId) {
250    (void)newState;
251    (void)triggerId;
252
253    ALOGV("%s: Autofocus state now %d, last trigger %d",
254          __FUNCTION__, newState, triggerId);
255
256}
257
258template <typename TClientBase>
259void Camera2ClientBase<TClientBase>::notifyAutoExposure(uint8_t newState,
260                                                        int triggerId) {
261    (void)newState;
262    (void)triggerId;
263
264    ALOGV("%s: Autoexposure state now %d, last trigger %d",
265            __FUNCTION__, newState, triggerId);
266}
267
268template <typename TClientBase>
269void Camera2ClientBase<TClientBase>::notifyAutoWhitebalance(uint8_t newState,
270                                                            int triggerId) {
271    (void)newState;
272    (void)triggerId;
273
274    ALOGV("%s: Auto-whitebalance state now %d, last trigger %d",
275            __FUNCTION__, newState, triggerId);
276}
277
278template <typename TClientBase>
279int Camera2ClientBase<TClientBase>::getCameraId() const {
280    return TClientBase::mCameraId;
281}
282
283template <typename TClientBase>
284int Camera2ClientBase<TClientBase>::getCameraDeviceVersion() const {
285    return mDeviceVersion;
286}
287
288template <typename TClientBase>
289const sp<CameraDeviceBase>& Camera2ClientBase<TClientBase>::getCameraDevice() {
290    return mDevice;
291}
292
293template <typename TClientBase>
294const sp<CameraService>& Camera2ClientBase<TClientBase>::getCameraService() {
295    return TClientBase::mCameraService;
296}
297
298template <typename TClientBase>
299Camera2ClientBase<TClientBase>::SharedCameraCallbacks::Lock::Lock(
300        SharedCameraCallbacks &client) :
301
302        mRemoteCallback(client.mRemoteCallback),
303        mSharedClient(client) {
304
305    mSharedClient.mRemoteCallbackLock.lock();
306}
307
308template <typename TClientBase>
309Camera2ClientBase<TClientBase>::SharedCameraCallbacks::Lock::~Lock() {
310    mSharedClient.mRemoteCallbackLock.unlock();
311}
312
313template <typename TClientBase>
314Camera2ClientBase<TClientBase>::SharedCameraCallbacks::SharedCameraCallbacks(
315        const sp<TCamCallbacks>&client) :
316
317        mRemoteCallback(client) {
318}
319
320template <typename TClientBase>
321typename Camera2ClientBase<TClientBase>::SharedCameraCallbacks&
322Camera2ClientBase<TClientBase>::SharedCameraCallbacks::operator=(
323        const sp<TCamCallbacks>&client) {
324
325    Mutex::Autolock l(mRemoteCallbackLock);
326    mRemoteCallback = client;
327    return *this;
328}
329
330template <typename TClientBase>
331void Camera2ClientBase<TClientBase>::SharedCameraCallbacks::clear() {
332    Mutex::Autolock l(mRemoteCallbackLock);
333    mRemoteCallback.clear();
334}
335
336template class Camera2ClientBase<CameraService::ProClient>;
337template class Camera2ClientBase<CameraService::Client>;
338template class Camera2ClientBase<CameraDeviceClientBase>;
339
340} // namespace android
341