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 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 69template <typename TClientBase> 70status_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 81template <typename TClientBase> 82status_t Camera2ClientBase<TClientBase>::initialize(sp<CameraProviderManager> manager) { 83 return initializeImpl(manager); 84} 85 86template <typename TClientBase> 87template <typename TProviderPtr> 88status_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 119template <typename TClientBase> 120Camera2ClientBase<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 133template <typename TClientBase> 134status_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 150template <typename TClientBase> 151status_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 178template <typename TClientBase> 179binder::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 200template <typename TClientBase> 201void 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 210template <typename TClientBase> 211status_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 239template <typename TClientBase> 240void 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 247template <typename TClientBase> 248void 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 258template <typename TClientBase> 259void 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 274template <typename TClientBase> 275void 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 285template <typename TClientBase> 286void 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 295template <typename TClientBase> 296void 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 305template <typename TClientBase> 306void Camera2ClientBase<TClientBase>::notifyPrepared(int streamId) { 307 (void)streamId; 308 309 ALOGV("%s: Stream %d now prepared", 310 __FUNCTION__, streamId); 311} 312 313template <typename TClientBase> 314void Camera2ClientBase<TClientBase>::notifyRequestQueueEmpty() { 315 316 ALOGV("%s: Request queue now empty", __FUNCTION__); 317} 318 319template <typename TClientBase> 320void 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 327template <typename TClientBase> 328int Camera2ClientBase<TClientBase>::getCameraId() const { 329 return std::stoi(TClientBase::mCameraIdStr.string()); 330} 331 332template <typename TClientBase> 333int Camera2ClientBase<TClientBase>::getCameraDeviceVersion() const { 334 return mDeviceVersion; 335} 336 337template <typename TClientBase> 338const sp<CameraDeviceBase>& Camera2ClientBase<TClientBase>::getCameraDevice() { 339 return mDevice; 340} 341 342template <typename TClientBase> 343const sp<CameraService>& Camera2ClientBase<TClientBase>::getCameraService() { 344 return TClientBase::sCameraService; 345} 346 347template <typename TClientBase> 348Camera2ClientBase<TClientBase>::SharedCameraCallbacks::Lock::Lock( 349 SharedCameraCallbacks &client) : 350 351 mRemoteCallback(client.mRemoteCallback), 352 mSharedClient(client) { 353 354 mSharedClient.mRemoteCallbackLock.lock(); 355} 356 357template <typename TClientBase> 358Camera2ClientBase<TClientBase>::SharedCameraCallbacks::Lock::~Lock() { 359 mSharedClient.mRemoteCallbackLock.unlock(); 360} 361 362template <typename TClientBase> 363Camera2ClientBase<TClientBase>::SharedCameraCallbacks::SharedCameraCallbacks( 364 const sp<TCamCallbacks>&client) : 365 366 mRemoteCallback(client) { 367} 368 369template <typename TClientBase> 370typename Camera2ClientBase<TClientBase>::SharedCameraCallbacks& 371Camera2ClientBase<TClientBase>::SharedCameraCallbacks::operator=( 372 const sp<TCamCallbacks>&client) { 373 374 Mutex::Autolock l(mRemoteCallbackLock); 375 mRemoteCallback = client; 376 return *this; 377} 378 379template <typename TClientBase> 380void Camera2ClientBase<TClientBase>::SharedCameraCallbacks::clear() { 381 Mutex::Autolock l(mRemoteCallbackLock); 382 mRemoteCallback.clear(); 383} 384 385template class Camera2ClientBase<CameraService::Client>; 386template class Camera2ClientBase<CameraDeviceClientBase>; 387 388} // namespace android 389