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