blob: 5e4832c575eb743f9451e7e9d392c708a8213305 [file] [log] [blame]
Igor Murashkin44cfcf02013-03-01 16:22:28 -08001/*
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 <utils/Log.h>
22#include <utils/Trace.h>
23
24#include <cutils/properties.h>
25#include <gui/Surface.h>
26#include <gui/Surface.h>
27#include "camera2/Parameters.h"
28#include "Camera2ClientBase.h"
29#include "camera2/ProFrameProcessor.h"
30
Igor Murashkine7ee7632013-06-11 18:10:18 -070031#include "photography/CameraDeviceClient.h"
32
Igor Murashkin44cfcf02013-03-01 16:22:28 -080033#include "Camera2Device.h"
34
35namespace android {
36using namespace camera2;
37
38static int getCallingPid() {
39 return IPCThreadState::self()->getCallingPid();
40}
41
42// Interface used by CameraService
43
44template <typename TClientBase>
45Camera2ClientBase<TClientBase>::Camera2ClientBase(
46 const sp<CameraService>& cameraService,
47 const sp<TCamCallbacks>& remoteCallback,
48 const String16& clientPackageName,
49 int cameraId,
50 int cameraFacing,
51 int clientPid,
52 uid_t clientUid,
53 int servicePid):
54 TClientBase(cameraService, remoteCallback, clientPackageName,
55 cameraId, cameraFacing, clientPid, clientUid, servicePid),
56 mSharedCameraCallbacks(remoteCallback)
57{
58 ALOGI("Camera %d: Opened", cameraId);
59 mDevice = new Camera2Device(cameraId);
60}
61
62template <typename TClientBase>
63status_t Camera2ClientBase<TClientBase>::checkPid(const char* checkLocation)
64 const {
65
66 int callingPid = getCallingPid();
67 if (callingPid == TClientBase::mClientPid) return NO_ERROR;
68
69 ALOGE("%s: attempt to use a locked camera from a different process"
70 " (old pid %d, new pid %d)", checkLocation, TClientBase::mClientPid, callingPid);
71 return PERMISSION_DENIED;
72}
73
74template <typename TClientBase>
75status_t Camera2ClientBase<TClientBase>::initialize(camera_module_t *module) {
76 ATRACE_CALL();
77 ALOGV("%s: Initializing client for camera %d", __FUNCTION__,
78 TClientBase::mCameraId);
79 status_t res;
80
Igor Murashkine6800ce2013-03-04 17:25:57 -080081 // Verify ops permissions
82 res = TClientBase::startCameraOps();
83 if (res != OK) {
84 return res;
85 }
86
87 if (mDevice == NULL) {
88 ALOGE("%s: Camera %d: No device connected",
89 __FUNCTION__, TClientBase::mCameraId);
90 return NO_INIT;
91 }
92
Igor Murashkin44cfcf02013-03-01 16:22:28 -080093 res = mDevice->initialize(module);
94 if (res != OK) {
95 ALOGE("%s: Camera %d: unable to initialize device: %s (%d)",
96 __FUNCTION__, TClientBase::mCameraId, strerror(-res), res);
97 return NO_INIT;
98 }
99
100 res = mDevice->setNotifyCallback(this);
101
102 return OK;
103}
104
105template <typename TClientBase>
106Camera2ClientBase<TClientBase>::~Camera2ClientBase() {
107 ATRACE_CALL();
108
109 TClientBase::mDestructionStarted = true;
110
Igor Murashkine6800ce2013-03-04 17:25:57 -0800111 TClientBase::finishCameraOps();
112
Igor Murashkin44cfcf02013-03-01 16:22:28 -0800113 disconnect();
114
115 ALOGI("Closed Camera %d", TClientBase::mCameraId);
116}
117
118template <typename TClientBase>
119status_t Camera2ClientBase<TClientBase>::dump(int fd,
120 const Vector<String16>& args) {
121 String8 result;
122 result.appendFormat("Camera2ClientBase[%d] (%p) PID: %d, dump:\n",
123 TClientBase::mCameraId,
124 TClientBase::getRemoteCallback()->asBinder().get(),
125 TClientBase::mClientPid);
126 result.append(" State: ");
127
128 write(fd, result.string(), result.size());
129 // TODO: print dynamic/request section from most recent requests
130
131 return dumpDevice(fd, args);
132}
133
134template <typename TClientBase>
135status_t Camera2ClientBase<TClientBase>::dumpDevice(
136 int fd,
137 const Vector<String16>& args) {
138 String8 result;
139
140 result = " Device dump:\n";
141 write(fd, result.string(), result.size());
142
143 if (!mDevice.get()) {
144 result = " *** Device is detached\n";
145 write(fd, result.string(), result.size());
146 return NO_ERROR;
147 }
148
149 status_t res = mDevice->dump(fd, args);
150 if (res != OK) {
151 result = String8::format(" Error dumping device: %s (%d)",
152 strerror(-res), res);
153 write(fd, result.string(), result.size());
154 }
155
156 return NO_ERROR;
157}
158
159// ICameraClient2BaseUser interface
160
161
162template <typename TClientBase>
163void Camera2ClientBase<TClientBase>::disconnect() {
164 ATRACE_CALL();
165 Mutex::Autolock icl(mBinderSerializationLock);
166
167 // Allow both client and the media server to disconnect at all times
168 int callingPid = getCallingPid();
169 if (callingPid != TClientBase::mClientPid &&
170 callingPid != TClientBase::mServicePid) return;
171
172 ALOGV("Camera %d: Shutting down", TClientBase::mCameraId);
173
174 detachDevice();
175
Igor Murashkine6800ce2013-03-04 17:25:57 -0800176 CameraService::BasicClient::disconnect();
Igor Murashkin44cfcf02013-03-01 16:22:28 -0800177
178 ALOGV("Camera %d: Shut down complete complete", TClientBase::mCameraId);
179}
180
181template <typename TClientBase>
182void Camera2ClientBase<TClientBase>::detachDevice() {
183 if (mDevice == 0) return;
184 mDevice->disconnect();
185
186 mDevice.clear();
187
188 ALOGV("Camera %d: Detach complete", TClientBase::mCameraId);
189}
190
191template <typename TClientBase>
192status_t Camera2ClientBase<TClientBase>::connect(
193 const sp<TCamCallbacks>& client) {
194 ATRACE_CALL();
195 ALOGV("%s: E", __FUNCTION__);
196 Mutex::Autolock icl(mBinderSerializationLock);
197
198 if (TClientBase::mClientPid != 0 &&
199 getCallingPid() != TClientBase::mClientPid) {
200
201 ALOGE("%s: Camera %d: Connection attempt from pid %d; "
202 "current locked to pid %d",
203 __FUNCTION__,
204 TClientBase::mCameraId,
205 getCallingPid(),
206 TClientBase::mClientPid);
207 return BAD_VALUE;
208 }
209
210 TClientBase::mClientPid = getCallingPid();
211
212 TClientBase::mRemoteCallback = client;
213 mSharedCameraCallbacks = client;
214
215 return OK;
216}
217
218/** Device-related methods */
219
220template <typename TClientBase>
221void Camera2ClientBase<TClientBase>::notifyError(int errorCode, int arg1,
222 int arg2) {
223 ALOGE("Error condition %d reported by HAL, arguments %d, %d", errorCode,
224 arg1, arg2);
225}
226
227template <typename TClientBase>
228void Camera2ClientBase<TClientBase>::notifyShutter(int frameNumber,
229 nsecs_t timestamp) {
230 (void)frameNumber;
231 (void)timestamp;
232
233 ALOGV("%s: Shutter notification for frame %d at time %lld", __FUNCTION__,
234 frameNumber, timestamp);
235}
236
237template <typename TClientBase>
238void Camera2ClientBase<TClientBase>::notifyAutoFocus(uint8_t newState,
239 int triggerId) {
240 (void)newState;
241 (void)triggerId;
242
243 ALOGV("%s: Autofocus state now %d, last trigger %d",
244 __FUNCTION__, newState, triggerId);
245
246 typename SharedCameraCallbacks::Lock l(mSharedCameraCallbacks);
247 if (l.mRemoteCallback != 0) {
248 l.mRemoteCallback->notifyCallback(CAMERA_MSG_FOCUS_MOVE, 1, 0);
249 }
250 if (l.mRemoteCallback != 0) {
251 l.mRemoteCallback->notifyCallback(CAMERA_MSG_FOCUS, 1, 0);
252 }
253}
254
255template <typename TClientBase>
256void Camera2ClientBase<TClientBase>::notifyAutoExposure(uint8_t newState,
257 int triggerId) {
258 (void)newState;
259 (void)triggerId;
260
261 ALOGV("%s: Autoexposure state now %d, last trigger %d",
262 __FUNCTION__, newState, triggerId);
263}
264
265template <typename TClientBase>
266void Camera2ClientBase<TClientBase>::notifyAutoWhitebalance(uint8_t newState,
267 int triggerId) {
268 (void)newState;
269 (void)triggerId;
270
271 ALOGV("%s: Auto-whitebalance state now %d, last trigger %d",
272 __FUNCTION__, newState, triggerId);
273}
274
275template <typename TClientBase>
276int Camera2ClientBase<TClientBase>::getCameraId() const {
277 return TClientBase::mCameraId;
278}
279
280template <typename TClientBase>
281const sp<CameraDeviceBase>& Camera2ClientBase<TClientBase>::getCameraDevice() {
282 return mDevice;
283}
284
285template <typename TClientBase>
286const sp<CameraService>& Camera2ClientBase<TClientBase>::getCameraService() {
287 return TClientBase::mCameraService;
288}
289
290template <typename TClientBase>
291Camera2ClientBase<TClientBase>::SharedCameraCallbacks::Lock::Lock(
292 SharedCameraCallbacks &client) :
293
294 mRemoteCallback(client.mRemoteCallback),
295 mSharedClient(client) {
296
297 mSharedClient.mRemoteCallbackLock.lock();
298}
299
300template <typename TClientBase>
301Camera2ClientBase<TClientBase>::SharedCameraCallbacks::Lock::~Lock() {
302 mSharedClient.mRemoteCallbackLock.unlock();
303}
304
305template <typename TClientBase>
306Camera2ClientBase<TClientBase>::SharedCameraCallbacks::SharedCameraCallbacks(
307 const sp<TCamCallbacks>&client) :
308
309 mRemoteCallback(client) {
310}
311
312template <typename TClientBase>
313typename Camera2ClientBase<TClientBase>::SharedCameraCallbacks&
314Camera2ClientBase<TClientBase>::SharedCameraCallbacks::operator=(
315 const sp<TCamCallbacks>&client) {
316
317 Mutex::Autolock l(mRemoteCallbackLock);
318 mRemoteCallback = client;
319 return *this;
320}
321
322template <typename TClientBase>
323void Camera2ClientBase<TClientBase>::SharedCameraCallbacks::clear() {
324 Mutex::Autolock l(mRemoteCallbackLock);
325 mRemoteCallback.clear();
326}
327
328template class Camera2ClientBase<CameraService::ProClient>;
329template class Camera2ClientBase<CameraService::Client>;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700330template class Camera2ClientBase<CameraDeviceClientBase>;
Igor Murashkin44cfcf02013-03-01 16:22:28 -0800331
332} // namespace android