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 36 namespace android { 37 using namespace camera2; 38 39 static int getCallingPid() { 40 return IPCThreadState::self()->getCallingPid(); 41 } 42 43 // Interface used by CameraService 44 45 template <typename TClientBase> 46 Camera2ClientBase<TClientBase>::Camera2ClientBase( 47 const sp<CameraService>& cameraService, 48 const sp<TCamCallbacks>& remoteCallback, 49 const String16& clientPackageName, 50 const String8& 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(TClientBase::mCameraIdStr)), 59 mDeviceActive(false) 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 mDevice = new Camera3Device(cameraId); 66 LOG_ALWAYS_FATAL_IF(mDevice == 0, "Device should never be NULL here."); 67 } 68 69 template <typename TClientBase> 70 status_t Camera2ClientBase<TClientBase>::checkPid(const char* checkLocation) 71 const { 72 73 int callingPid = getCallingPid(); 74 if (callingPid == TClientBase::mClientPid) return NO_ERROR; 75 76 ALOGE("%s: attempt to use a locked camera from a different process" 77 " (old pid %d, new pid %d)", checkLocation, TClientBase::mClientPid, callingPid); 78 return PERMISSION_DENIED; 79 } 80 81 template <typename TClientBase> 82 status_t Camera2ClientBase<TClientBase>::initialize(sp<CameraProviderManager> manager) { 83 return initializeImpl(manager); 84 } 85 86 template <typename TClientBase> 87 template <typename TProviderPtr> 88 status_t Camera2ClientBase<TClientBase>::initializeImpl(TProviderPtr providerPtr) { 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); 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> 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> 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> 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 if (!mDevice.get()) { 160 result = " *** Device is detached\n"; 161 write(fd, result.string(), result.size()); 162 return NO_ERROR; 163 } 164 165 status_t res = mDevice->dump(fd, args); 166 if (res != OK) { 167 result = String8::format(" Error dumping device: %s (%d)", 168 strerror(-res), res); 169 write(fd, result.string(), result.size()); 170 } 171 172 return NO_ERROR; 173 } 174 175 // ICameraClient2BaseUser interface 176 177 178 template <typename TClientBase> 179 binder::Status Camera2ClientBase<TClientBase>::disconnect() { 180 ATRACE_CALL(); 181 Mutex::Autolock icl(mBinderSerializationLock); 182 183 binder::Status res = binder::Status::ok(); 184 // Allow both client and the media server to disconnect at all times 185 int callingPid = getCallingPid(); 186 if (callingPid != TClientBase::mClientPid && 187 callingPid != TClientBase::mServicePid) return res; 188 189 ALOGV("Camera %s: Shutting down", TClientBase::mCameraIdStr.string()); 190 191 detachDevice(); 192 193 CameraService::BasicClient::disconnect(); 194 195 ALOGV("Camera %s: Shut down complete complete", TClientBase::mCameraIdStr.string()); 196 197 return res; 198 } 199 200 template <typename TClientBase> 201 void Camera2ClientBase<TClientBase>::detachDevice() { 202 if (mDevice == 0) return; 203 mDevice->disconnect(); 204 205 mDevice.clear(); 206 207 ALOGV("Camera %s: Detach complete", TClientBase::mCameraIdStr.string()); 208 } 209 210 template <typename TClientBase> 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 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 getCallingPid(), 225 TClientBase::mClientPid); 226 return BAD_VALUE; 227 } 228 229 TClientBase::mClientPid = getCallingPid(); 230 231 TClientBase::mRemoteCallback = client; 232 mSharedCameraCallbacks = client; 233 234 return OK; 235 } 236 237 /** Device-related methods */ 238 239 template <typename TClientBase> 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> 248 void Camera2ClientBase<TClientBase>::notifyIdle() { 249 if (mDeviceActive) { 250 getCameraService()->updateProxyDeviceState( 251 ICameraServiceProxy::CAMERA_STATE_IDLE, TClientBase::mCameraIdStr); 252 } 253 mDeviceActive = false; 254 255 ALOGV("Camera device is now idle"); 256 } 257 258 template <typename TClientBase> 259 void Camera2ClientBase<TClientBase>::notifyShutter(const CaptureResultExtras& resultExtras, 260 nsecs_t timestamp) { 261 (void)resultExtras; 262 (void)timestamp; 263 264 if (!mDeviceActive) { 265 getCameraService()->updateProxyDeviceState( 266 ICameraServiceProxy::CAMERA_STATE_ACTIVE, TClientBase::mCameraIdStr); 267 } 268 mDeviceActive = true; 269 270 ALOGV("%s: Shutter notification for request id %" PRId32 " at time %" PRId64, 271 __FUNCTION__, resultExtras.requestId, timestamp); 272 } 273 274 template <typename TClientBase> 275 void Camera2ClientBase<TClientBase>::notifyAutoFocus(uint8_t newState, 276 int triggerId) { 277 (void)newState; 278 (void)triggerId; 279 280 ALOGV("%s: Autofocus state now %d, last trigger %d", 281 __FUNCTION__, newState, triggerId); 282 283 } 284 285 template <typename TClientBase> 286 void Camera2ClientBase<TClientBase>::notifyAutoExposure(uint8_t newState, 287 int triggerId) { 288 (void)newState; 289 (void)triggerId; 290 291 ALOGV("%s: Autoexposure state now %d, last trigger %d", 292 __FUNCTION__, newState, triggerId); 293 } 294 295 template <typename TClientBase> 296 void Camera2ClientBase<TClientBase>::notifyAutoWhitebalance(uint8_t newState, 297 int triggerId) { 298 (void)newState; 299 (void)triggerId; 300 301 ALOGV("%s: Auto-whitebalance state now %d, last trigger %d", 302 __FUNCTION__, newState, triggerId); 303 } 304 305 template <typename TClientBase> 306 void Camera2ClientBase<TClientBase>::notifyPrepared(int streamId) { 307 (void)streamId; 308 309 ALOGV("%s: Stream %d now prepared", 310 __FUNCTION__, streamId); 311 } 312 313 template <typename TClientBase> 314 void Camera2ClientBase<TClientBase>::notifyRequestQueueEmpty() { 315 316 ALOGV("%s: Request queue now empty", __FUNCTION__); 317 } 318 319 template <typename TClientBase> 320 void Camera2ClientBase<TClientBase>::notifyRepeatingRequestError(long lastFrameNumber) { 321 (void)lastFrameNumber; 322 323 ALOGV("%s: Repeating request was stopped. Last frame number is %ld", 324 __FUNCTION__, lastFrameNumber); 325 } 326 327 template <typename TClientBase> 328 int Camera2ClientBase<TClientBase>::getCameraId() const { 329 return std::stoi(TClientBase::mCameraIdStr.string()); 330 } 331 332 template <typename TClientBase> 333 int Camera2ClientBase<TClientBase>::getCameraDeviceVersion() const { 334 return mDeviceVersion; 335 } 336 337 template <typename TClientBase> 338 const sp<CameraDeviceBase>& Camera2ClientBase<TClientBase>::getCameraDevice() { 339 return mDevice; 340 } 341 342 template <typename TClientBase> 343 const sp<CameraService>& Camera2ClientBase<TClientBase>::getCameraService() { 344 return TClientBase::sCameraService; 345 } 346 347 template <typename TClientBase> 348 Camera2ClientBase<TClientBase>::SharedCameraCallbacks::Lock::Lock( 349 SharedCameraCallbacks &client) : 350 351 mRemoteCallback(client.mRemoteCallback), 352 mSharedClient(client) { 353 354 mSharedClient.mRemoteCallbackLock.lock(); 355 } 356 357 template <typename TClientBase> 358 Camera2ClientBase<TClientBase>::SharedCameraCallbacks::Lock::~Lock() { 359 mSharedClient.mRemoteCallbackLock.unlock(); 360 } 361 362 template <typename TClientBase> 363 Camera2ClientBase<TClientBase>::SharedCameraCallbacks::SharedCameraCallbacks( 364 const sp<TCamCallbacks>&client) : 365 366 mRemoteCallback(client) { 367 } 368 369 template <typename TClientBase> 370 typename Camera2ClientBase<TClientBase>::SharedCameraCallbacks& 371 Camera2ClientBase<TClientBase>::SharedCameraCallbacks::operator=( 372 const sp<TCamCallbacks>&client) { 373 374 Mutex::Autolock l(mRemoteCallbackLock); 375 mRemoteCallback = client; 376 return *this; 377 } 378 379 template <typename TClientBase> 380 void Camera2ClientBase<TClientBase>::SharedCameraCallbacks::clear() { 381 Mutex::Autolock l(mRemoteCallbackLock); 382 mRemoteCallback.clear(); 383 } 384 385 template class Camera2ClientBase<CameraService::Client>; 386 template class Camera2ClientBase<CameraDeviceClientBase>; 387 388 } // namespace android 389