Camera2ClientBase.cpp revision f67e23ef637d0b53a0d4bebb68c654234df3da94
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    disconnect();
116
117    ALOGI("Closed Camera %d", TClientBase::mCameraId);
118}
119
120template <typename TClientBase>
121status_t Camera2ClientBase<TClientBase>::dump(int fd,
122                                              const Vector<String16>& args) {
123    String8 result;
124    result.appendFormat("Camera2ClientBase[%d] (%p) PID: %d, dump:\n",
125            TClientBase::mCameraId,
126            TClientBase::getRemoteCallback()->asBinder().get(),
127            TClientBase::mClientPid);
128    result.append("  State: ");
129
130    write(fd, result.string(), result.size());
131    // TODO: print dynamic/request section from most recent requests
132
133    return dumpDevice(fd, args);
134}
135
136template <typename TClientBase>
137status_t Camera2ClientBase<TClientBase>::dumpDevice(
138                                                int fd,
139                                                const Vector<String16>& args) {
140    String8 result;
141
142    result = "  Device dump:\n";
143    write(fd, result.string(), result.size());
144
145    if (!mDevice.get()) {
146        result = "  *** Device is detached\n";
147        write(fd, result.string(), result.size());
148        return NO_ERROR;
149    }
150
151    status_t res = mDevice->dump(fd, args);
152    if (res != OK) {
153        result = String8::format("   Error dumping device: %s (%d)",
154                strerror(-res), res);
155        write(fd, result.string(), result.size());
156    }
157
158    return NO_ERROR;
159}
160
161// ICameraClient2BaseUser interface
162
163
164template <typename TClientBase>
165void Camera2ClientBase<TClientBase>::disconnect() {
166    ATRACE_CALL();
167    Mutex::Autolock icl(mBinderSerializationLock);
168
169    // Allow both client and the media server to disconnect at all times
170    int callingPid = getCallingPid();
171    if (callingPid != TClientBase::mClientPid &&
172        callingPid != TClientBase::mServicePid) return;
173
174    ALOGV("Camera %d: Shutting down", TClientBase::mCameraId);
175
176    detachDevice();
177
178    CameraService::BasicClient::disconnect();
179
180    ALOGV("Camera %d: Shut down complete complete", TClientBase::mCameraId);
181}
182
183template <typename TClientBase>
184void Camera2ClientBase<TClientBase>::detachDevice() {
185    if (mDevice == 0) return;
186    mDevice->disconnect();
187
188    mDevice.clear();
189
190    ALOGV("Camera %d: Detach complete", TClientBase::mCameraId);
191}
192
193template <typename TClientBase>
194status_t Camera2ClientBase<TClientBase>::connect(
195        const sp<TCamCallbacks>& client) {
196    ATRACE_CALL();
197    ALOGV("%s: E", __FUNCTION__);
198    Mutex::Autolock icl(mBinderSerializationLock);
199
200    if (TClientBase::mClientPid != 0 &&
201        getCallingPid() != TClientBase::mClientPid) {
202
203        ALOGE("%s: Camera %d: Connection attempt from pid %d; "
204                "current locked to pid %d",
205                __FUNCTION__,
206                TClientBase::mCameraId,
207                getCallingPid(),
208                TClientBase::mClientPid);
209        return BAD_VALUE;
210    }
211
212    TClientBase::mClientPid = getCallingPid();
213
214    TClientBase::mRemoteCallback = client;
215    mSharedCameraCallbacks = client;
216
217    return OK;
218}
219
220/** Device-related methods */
221
222template <typename TClientBase>
223void Camera2ClientBase<TClientBase>::notifyError(
224        ICameraDeviceCallbacks::CameraErrorCode errorCode,
225        const CaptureResultExtras& resultExtras) {
226    ALOGE("Error condition %d reported by HAL, requestId %" PRId32, errorCode,
227          resultExtras.requestId);
228}
229
230template <typename TClientBase>
231void Camera2ClientBase<TClientBase>::notifyIdle() {
232    ALOGV("Camera device is now idle");
233}
234
235template <typename TClientBase>
236void Camera2ClientBase<TClientBase>::notifyShutter(const CaptureResultExtras& resultExtras,
237                                                   nsecs_t timestamp) {
238    (void)resultExtras;
239    (void)timestamp;
240
241    ALOGV("%s: Shutter notification for request id %" PRId32 " at time %" PRId64,
242            __FUNCTION__, resultExtras.requestId, timestamp);
243}
244
245template <typename TClientBase>
246void Camera2ClientBase<TClientBase>::notifyAutoFocus(uint8_t newState,
247                                                     int triggerId) {
248    (void)newState;
249    (void)triggerId;
250
251    ALOGV("%s: Autofocus state now %d, last trigger %d",
252          __FUNCTION__, newState, triggerId);
253
254}
255
256template <typename TClientBase>
257void Camera2ClientBase<TClientBase>::notifyAutoExposure(uint8_t newState,
258                                                        int triggerId) {
259    (void)newState;
260    (void)triggerId;
261
262    ALOGV("%s: Autoexposure state now %d, last trigger %d",
263            __FUNCTION__, newState, triggerId);
264}
265
266template <typename TClientBase>
267void Camera2ClientBase<TClientBase>::notifyAutoWhitebalance(uint8_t newState,
268                                                            int triggerId) {
269    (void)newState;
270    (void)triggerId;
271
272    ALOGV("%s: Auto-whitebalance state now %d, last trigger %d",
273            __FUNCTION__, newState, triggerId);
274}
275
276template <typename TClientBase>
277int Camera2ClientBase<TClientBase>::getCameraId() const {
278    return TClientBase::mCameraId;
279}
280
281template <typename TClientBase>
282int Camera2ClientBase<TClientBase>::getCameraDeviceVersion() const {
283    return mDeviceVersion;
284}
285
286template <typename TClientBase>
287const sp<CameraDeviceBase>& Camera2ClientBase<TClientBase>::getCameraDevice() {
288    return mDevice;
289}
290
291template <typename TClientBase>
292const sp<CameraService>& Camera2ClientBase<TClientBase>::getCameraService() {
293    return TClientBase::mCameraService;
294}
295
296template <typename TClientBase>
297Camera2ClientBase<TClientBase>::SharedCameraCallbacks::Lock::Lock(
298        SharedCameraCallbacks &client) :
299
300        mRemoteCallback(client.mRemoteCallback),
301        mSharedClient(client) {
302
303    mSharedClient.mRemoteCallbackLock.lock();
304}
305
306template <typename TClientBase>
307Camera2ClientBase<TClientBase>::SharedCameraCallbacks::Lock::~Lock() {
308    mSharedClient.mRemoteCallbackLock.unlock();
309}
310
311template <typename TClientBase>
312Camera2ClientBase<TClientBase>::SharedCameraCallbacks::SharedCameraCallbacks(
313        const sp<TCamCallbacks>&client) :
314
315        mRemoteCallback(client) {
316}
317
318template <typename TClientBase>
319typename Camera2ClientBase<TClientBase>::SharedCameraCallbacks&
320Camera2ClientBase<TClientBase>::SharedCameraCallbacks::operator=(
321        const sp<TCamCallbacks>&client) {
322
323    Mutex::Autolock l(mRemoteCallbackLock);
324    mRemoteCallback = client;
325    return *this;
326}
327
328template <typename TClientBase>
329void Camera2ClientBase<TClientBase>::SharedCameraCallbacks::clear() {
330    Mutex::Autolock l(mRemoteCallbackLock);
331    mRemoteCallback.clear();
332}
333
334template class Camera2ClientBase<CameraService::ProClient>;
335template class Camera2ClientBase<CameraService::Client>;
336template class Camera2ClientBase<CameraDeviceClientBase>;
337
338} // namespace android
339