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 "device3/Camera3Device.h"
35 #include "utils/CameraThreadState.h"
36 
37 namespace android {
38 using namespace camera2;
39 
40 // Interface used by CameraService
41 
42 template <typename TClientBase>
Camera2ClientBase(const sp<CameraService> & cameraService,const sp<TCamCallbacks> & remoteCallback,const String16 & clientPackageName,const String8 & cameraId,int api1CameraId,int cameraFacing,int clientPid,uid_t clientUid,int servicePid)43 Camera2ClientBase<TClientBase>::Camera2ClientBase(
44         const sp<CameraService>& cameraService,
45         const sp<TCamCallbacks>& remoteCallback,
46         const String16& clientPackageName,
47         const String8& cameraId,
48         int api1CameraId,
49         int cameraFacing,
50         int clientPid,
51         uid_t clientUid,
52         int servicePid):
53         TClientBase(cameraService, remoteCallback, clientPackageName,
54                 cameraId, api1CameraId, cameraFacing, clientPid, clientUid, servicePid),
55         mSharedCameraCallbacks(remoteCallback),
56         mDeviceVersion(cameraService->getDeviceVersion(TClientBase::mCameraIdStr)),
57         mDevice(new Camera3Device(cameraId)),
58         mDeviceActive(false), mApi1CameraId(api1CameraId)
59 {
60     ALOGI("Camera %s: Opened. Client: %s (PID %d, UID %d)", cameraId.string(),
61             String8(clientPackageName).string(), clientPid, clientUid);
62 
63     mInitialClientPid = clientPid;
64     LOG_ALWAYS_FATAL_IF(mDevice == 0, "Device should never be NULL here.");
65 }
66 
67 template <typename TClientBase>
checkPid(const char * checkLocation) const68 status_t Camera2ClientBase<TClientBase>::checkPid(const char* checkLocation)
69         const {
70 
71     int callingPid = CameraThreadState::getCallingPid();
72     if (callingPid == TClientBase::mClientPid) return NO_ERROR;
73 
74     ALOGE("%s: attempt to use a locked camera from a different process"
75             " (old pid %d, new pid %d)", checkLocation, TClientBase::mClientPid, callingPid);
76     return PERMISSION_DENIED;
77 }
78 
79 template <typename TClientBase>
initialize(sp<CameraProviderManager> manager,const String8 & monitorTags)80 status_t Camera2ClientBase<TClientBase>::initialize(sp<CameraProviderManager> manager,
81         const String8& monitorTags) {
82     return initializeImpl(manager, monitorTags);
83 }
84 
85 template <typename TClientBase>
86 template <typename TProviderPtr>
initializeImpl(TProviderPtr providerPtr,const String8 & monitorTags)87 status_t Camera2ClientBase<TClientBase>::initializeImpl(TProviderPtr providerPtr,
88         const String8& monitorTags) {
89     ATRACE_CALL();
90     ALOGV("%s: Initializing client for camera %s", __FUNCTION__,
91           TClientBase::mCameraIdStr.string());
92     status_t res;
93 
94     // Verify ops permissions
95     res = TClientBase::startCameraOps();
96     if (res != OK) {
97         return res;
98     }
99 
100     if (mDevice == NULL) {
101         ALOGE("%s: Camera %s: No device connected",
102                 __FUNCTION__, TClientBase::mCameraIdStr.string());
103         return NO_INIT;
104     }
105 
106     res = mDevice->initialize(providerPtr, monitorTags);
107     if (res != OK) {
108         ALOGE("%s: Camera %s: unable to initialize device: %s (%d)",
109                 __FUNCTION__, TClientBase::mCameraIdStr.string(), strerror(-res), res);
110         return res;
111     }
112 
113     wp<CameraDeviceBase::NotificationListener> weakThis(this);
114     res = mDevice->setNotifyCallback(weakThis);
115 
116     return OK;
117 }
118 
119 template <typename TClientBase>
~Camera2ClientBase()120 Camera2ClientBase<TClientBase>::~Camera2ClientBase() {
121     ATRACE_CALL();
122 
123     TClientBase::mDestructionStarted = true;
124 
125     disconnect();
126 
127     ALOGI("Closed Camera %s. Client was: %s (PID %d, UID %u)",
128             TClientBase::mCameraIdStr.string(),
129             String8(TClientBase::mClientPackageName).string(),
130             mInitialClientPid, TClientBase::mClientUid);
131 }
132 
133 template <typename TClientBase>
dumpClient(int fd,const Vector<String16> & args)134 status_t Camera2ClientBase<TClientBase>::dumpClient(int fd,
135                                               const Vector<String16>& args) {
136     String8 result;
137     result.appendFormat("Camera2ClientBase[%s] (%p) PID: %d, dump:\n",
138             TClientBase::mCameraIdStr.string(),
139             (TClientBase::getRemoteCallback() != NULL ?
140                     IInterface::asBinder(TClientBase::getRemoteCallback()).get() : NULL),
141             TClientBase::mClientPid);
142     result.append("  State: ");
143 
144     write(fd, result.string(), result.size());
145     // TODO: print dynamic/request section from most recent requests
146 
147     return dumpDevice(fd, args);
148 }
149 
150 template <typename TClientBase>
dumpDevice(int fd,const Vector<String16> & args)151 status_t Camera2ClientBase<TClientBase>::dumpDevice(
152                                                 int fd,
153                                                 const Vector<String16>& args) {
154     String8 result;
155 
156     result = "  Device dump:\n";
157     write(fd, result.string(), result.size());
158 
159     sp<CameraDeviceBase> device = mDevice;
160     if (!device.get()) {
161         result = "  *** Device is detached\n";
162         write(fd, result.string(), result.size());
163         return NO_ERROR;
164     }
165 
166     status_t res = device->dump(fd, args);
167     if (res != OK) {
168         result = String8::format("   Error dumping device: %s (%d)",
169                 strerror(-res), res);
170         write(fd, result.string(), result.size());
171     }
172 
173     return NO_ERROR;
174 }
175 
176 // ICameraClient2BaseUser interface
177 
178 
179 template <typename TClientBase>
disconnect()180 binder::Status Camera2ClientBase<TClientBase>::disconnect() {
181     ATRACE_CALL();
182     Mutex::Autolock icl(mBinderSerializationLock);
183 
184     binder::Status res = binder::Status::ok();
185     // Allow both client and the media server to disconnect at all times
186     int callingPid = CameraThreadState::getCallingPid();
187     if (callingPid != TClientBase::mClientPid &&
188         callingPid != TClientBase::mServicePid) return res;
189 
190     ALOGV("Camera %s: Shutting down", TClientBase::mCameraIdStr.string());
191 
192     detachDevice();
193 
194     CameraService::BasicClient::disconnect();
195 
196     ALOGV("Camera %s: Shut down complete complete", TClientBase::mCameraIdStr.string());
197 
198     return res;
199 }
200 
201 template <typename TClientBase>
detachDevice()202 void Camera2ClientBase<TClientBase>::detachDevice() {
203     if (mDevice == 0) return;
204     mDevice->disconnect();
205 
206     ALOGV("Camera %s: Detach complete", TClientBase::mCameraIdStr.string());
207 }
208 
209 template <typename TClientBase>
connect(const sp<TCamCallbacks> & client)210 status_t Camera2ClientBase<TClientBase>::connect(
211         const sp<TCamCallbacks>& client) {
212     ATRACE_CALL();
213     ALOGV("%s: E", __FUNCTION__);
214     Mutex::Autolock icl(mBinderSerializationLock);
215 
216     if (TClientBase::mClientPid != 0 &&
217         CameraThreadState::getCallingPid() != TClientBase::mClientPid) {
218 
219         ALOGE("%s: Camera %s: Connection attempt from pid %d; "
220                 "current locked to pid %d",
221                 __FUNCTION__,
222                 TClientBase::mCameraIdStr.string(),
223                 CameraThreadState::getCallingPid(),
224                 TClientBase::mClientPid);
225         return BAD_VALUE;
226     }
227 
228     TClientBase::mClientPid = CameraThreadState::getCallingPid();
229 
230     TClientBase::mRemoteCallback = client;
231     mSharedCameraCallbacks = client;
232 
233     return OK;
234 }
235 
236 /** Device-related methods */
237 
238 template <typename TClientBase>
notifyError(int32_t errorCode,const CaptureResultExtras & resultExtras)239 void Camera2ClientBase<TClientBase>::notifyError(
240         int32_t errorCode,
241         const CaptureResultExtras& resultExtras) {
242     ALOGE("Error condition %d reported by HAL, requestId %" PRId32, errorCode,
243           resultExtras.requestId);
244 }
245 
246 template <typename TClientBase>
notifyIdle()247 void Camera2ClientBase<TClientBase>::notifyIdle() {
248     if (mDeviceActive) {
249         getCameraService()->updateProxyDeviceState(
250             hardware::ICameraServiceProxy::CAMERA_STATE_IDLE, TClientBase::mCameraIdStr,
251             TClientBase::mCameraFacing, TClientBase::mClientPackageName,
252             ((mApi1CameraId < 0) ? hardware::ICameraServiceProxy::CAMERA_API_LEVEL_2 :
253              hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1));
254     }
255     mDeviceActive = false;
256 
257     ALOGV("Camera device is now idle");
258 }
259 
260 template <typename TClientBase>
notifyShutter(const CaptureResultExtras & resultExtras,nsecs_t timestamp)261 void Camera2ClientBase<TClientBase>::notifyShutter(const CaptureResultExtras& resultExtras,
262                                                    nsecs_t timestamp) {
263     (void)resultExtras;
264     (void)timestamp;
265 
266     if (!mDeviceActive) {
267         getCameraService()->updateProxyDeviceState(
268             hardware::ICameraServiceProxy::CAMERA_STATE_ACTIVE, TClientBase::mCameraIdStr,
269             TClientBase::mCameraFacing, TClientBase::mClientPackageName,
270             ((mApi1CameraId < 0) ? hardware::ICameraServiceProxy::CAMERA_API_LEVEL_2 :
271              hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1));
272     }
273     mDeviceActive = true;
274 
275     ALOGV("%s: Shutter notification for request id %" PRId32 " at time %" PRId64,
276             __FUNCTION__, resultExtras.requestId, timestamp);
277 }
278 
279 template <typename TClientBase>
notifyAutoFocus(uint8_t newState,int triggerId)280 void Camera2ClientBase<TClientBase>::notifyAutoFocus(uint8_t newState,
281                                                      int triggerId) {
282     (void)newState;
283     (void)triggerId;
284 
285     ALOGV("%s: Autofocus state now %d, last trigger %d",
286           __FUNCTION__, newState, triggerId);
287 
288 }
289 
290 template <typename TClientBase>
notifyAutoExposure(uint8_t newState,int triggerId)291 void Camera2ClientBase<TClientBase>::notifyAutoExposure(uint8_t newState,
292                                                         int triggerId) {
293     (void)newState;
294     (void)triggerId;
295 
296     ALOGV("%s: Autoexposure state now %d, last trigger %d",
297             __FUNCTION__, newState, triggerId);
298 }
299 
300 template <typename TClientBase>
notifyAutoWhitebalance(uint8_t newState,int triggerId)301 void Camera2ClientBase<TClientBase>::notifyAutoWhitebalance(uint8_t newState,
302                                                             int triggerId) {
303     (void)newState;
304     (void)triggerId;
305 
306     ALOGV("%s: Auto-whitebalance state now %d, last trigger %d",
307             __FUNCTION__, newState, triggerId);
308 }
309 
310 template <typename TClientBase>
notifyPrepared(int streamId)311 void Camera2ClientBase<TClientBase>::notifyPrepared(int streamId) {
312     (void)streamId;
313 
314     ALOGV("%s: Stream %d now prepared",
315             __FUNCTION__, streamId);
316 }
317 
318 template <typename TClientBase>
notifyRequestQueueEmpty()319 void Camera2ClientBase<TClientBase>::notifyRequestQueueEmpty() {
320 
321     ALOGV("%s: Request queue now empty", __FUNCTION__);
322 }
323 
324 template <typename TClientBase>
notifyRepeatingRequestError(long lastFrameNumber)325 void Camera2ClientBase<TClientBase>::notifyRepeatingRequestError(long lastFrameNumber) {
326     (void)lastFrameNumber;
327 
328     ALOGV("%s: Repeating request was stopped. Last frame number is %ld",
329             __FUNCTION__, lastFrameNumber);
330 }
331 
332 template <typename TClientBase>
getCameraId() const333 int Camera2ClientBase<TClientBase>::getCameraId() const {
334     return mApi1CameraId;
335 }
336 
337 template <typename TClientBase>
getCameraDeviceVersion() const338 int Camera2ClientBase<TClientBase>::getCameraDeviceVersion() const {
339     return mDeviceVersion;
340 }
341 
342 template <typename TClientBase>
getCameraDevice()343 const sp<CameraDeviceBase>& Camera2ClientBase<TClientBase>::getCameraDevice() {
344     return mDevice;
345 }
346 
347 template <typename TClientBase>
getCameraService()348 const sp<CameraService>& Camera2ClientBase<TClientBase>::getCameraService() {
349     return TClientBase::sCameraService;
350 }
351 
352 template <typename TClientBase>
Lock(SharedCameraCallbacks & client)353 Camera2ClientBase<TClientBase>::SharedCameraCallbacks::Lock::Lock(
354         SharedCameraCallbacks &client) :
355 
356         mRemoteCallback(client.mRemoteCallback),
357         mSharedClient(client) {
358 
359     mSharedClient.mRemoteCallbackLock.lock();
360 }
361 
362 template <typename TClientBase>
~Lock()363 Camera2ClientBase<TClientBase>::SharedCameraCallbacks::Lock::~Lock() {
364     mSharedClient.mRemoteCallbackLock.unlock();
365 }
366 
367 template <typename TClientBase>
SharedCameraCallbacks(const sp<TCamCallbacks> & client)368 Camera2ClientBase<TClientBase>::SharedCameraCallbacks::SharedCameraCallbacks(
369         const sp<TCamCallbacks>&client) :
370 
371         mRemoteCallback(client) {
372 }
373 
374 template <typename TClientBase>
375 typename Camera2ClientBase<TClientBase>::SharedCameraCallbacks&
operator =(const sp<TCamCallbacks> & client)376 Camera2ClientBase<TClientBase>::SharedCameraCallbacks::operator=(
377         const sp<TCamCallbacks>&client) {
378 
379     Mutex::Autolock l(mRemoteCallbackLock);
380     mRemoteCallback = client;
381     return *this;
382 }
383 
384 template <typename TClientBase>
clear()385 void Camera2ClientBase<TClientBase>::SharedCameraCallbacks::clear() {
386     Mutex::Autolock l(mRemoteCallbackLock);
387     mRemoteCallback.clear();
388 }
389 
390 template class Camera2ClientBase<CameraService::Client>;
391 template class Camera2ClientBase<CameraDeviceClientBase>;
392 
393 } // namespace android
394