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