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