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