Camera2ClientBase.cpp revision f67e23ef637d0b53a0d4bebb68c654234df3da94
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 "CameraDeviceFactory.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 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{ 60 ALOGI("Camera %d: Opened", cameraId); 61 62 mDevice = CameraDeviceFactory::createDevice(cameraId); 63 LOG_ALWAYS_FATAL_IF(mDevice == 0, "Device should never be NULL here."); 64} 65 66template <typename TClientBase> 67status_t Camera2ClientBase<TClientBase>::checkPid(const char* checkLocation) 68 const { 69 70 int callingPid = getCallingPid(); 71 if (callingPid == TClientBase::mClientPid) return NO_ERROR; 72 73 ALOGE("%s: attempt to use a locked camera from a different process" 74 " (old pid %d, new pid %d)", checkLocation, TClientBase::mClientPid, callingPid); 75 return PERMISSION_DENIED; 76} 77 78template <typename TClientBase> 79status_t Camera2ClientBase<TClientBase>::initialize(camera_module_t *module) { 80 ATRACE_CALL(); 81 ALOGV("%s: Initializing client for camera %d", __FUNCTION__, 82 TClientBase::mCameraId); 83 status_t res; 84 85 // Verify ops permissions 86 res = TClientBase::startCameraOps(); 87 if (res != OK) { 88 return res; 89 } 90 91 if (mDevice == NULL) { 92 ALOGE("%s: Camera %d: No device connected", 93 __FUNCTION__, TClientBase::mCameraId); 94 return NO_INIT; 95 } 96 97 res = mDevice->initialize(module); 98 if (res != OK) { 99 ALOGE("%s: Camera %d: unable to initialize device: %s (%d)", 100 __FUNCTION__, TClientBase::mCameraId, strerror(-res), res); 101 return res; 102 } 103 104 res = mDevice->setNotifyCallback(this); 105 106 return OK; 107} 108 109template <typename TClientBase> 110Camera2ClientBase<TClientBase>::~Camera2ClientBase() { 111 ATRACE_CALL(); 112 113 TClientBase::mDestructionStarted = true; 114 115 disconnect(); 116 117 ALOGI("Closed Camera %d", TClientBase::mCameraId); 118} 119 120template <typename TClientBase> 121status_t Camera2ClientBase<TClientBase>::dump(int fd, 122 const Vector<String16>& args) { 123 String8 result; 124 result.appendFormat("Camera2ClientBase[%d] (%p) PID: %d, dump:\n", 125 TClientBase::mCameraId, 126 TClientBase::getRemoteCallback()->asBinder().get(), 127 TClientBase::mClientPid); 128 result.append(" State: "); 129 130 write(fd, result.string(), result.size()); 131 // TODO: print dynamic/request section from most recent requests 132 133 return dumpDevice(fd, args); 134} 135 136template <typename TClientBase> 137status_t Camera2ClientBase<TClientBase>::dumpDevice( 138 int fd, 139 const Vector<String16>& args) { 140 String8 result; 141 142 result = " Device dump:\n"; 143 write(fd, result.string(), result.size()); 144 145 if (!mDevice.get()) { 146 result = " *** Device is detached\n"; 147 write(fd, result.string(), result.size()); 148 return NO_ERROR; 149 } 150 151 status_t res = mDevice->dump(fd, args); 152 if (res != OK) { 153 result = String8::format(" Error dumping device: %s (%d)", 154 strerror(-res), res); 155 write(fd, result.string(), result.size()); 156 } 157 158 return NO_ERROR; 159} 160 161// ICameraClient2BaseUser interface 162 163 164template <typename TClientBase> 165void Camera2ClientBase<TClientBase>::disconnect() { 166 ATRACE_CALL(); 167 Mutex::Autolock icl(mBinderSerializationLock); 168 169 // Allow both client and the media server to disconnect at all times 170 int callingPid = getCallingPid(); 171 if (callingPid != TClientBase::mClientPid && 172 callingPid != TClientBase::mServicePid) return; 173 174 ALOGV("Camera %d: Shutting down", TClientBase::mCameraId); 175 176 detachDevice(); 177 178 CameraService::BasicClient::disconnect(); 179 180 ALOGV("Camera %d: Shut down complete complete", TClientBase::mCameraId); 181} 182 183template <typename TClientBase> 184void Camera2ClientBase<TClientBase>::detachDevice() { 185 if (mDevice == 0) return; 186 mDevice->disconnect(); 187 188 mDevice.clear(); 189 190 ALOGV("Camera %d: Detach complete", TClientBase::mCameraId); 191} 192 193template <typename TClientBase> 194status_t Camera2ClientBase<TClientBase>::connect( 195 const sp<TCamCallbacks>& client) { 196 ATRACE_CALL(); 197 ALOGV("%s: E", __FUNCTION__); 198 Mutex::Autolock icl(mBinderSerializationLock); 199 200 if (TClientBase::mClientPid != 0 && 201 getCallingPid() != TClientBase::mClientPid) { 202 203 ALOGE("%s: Camera %d: Connection attempt from pid %d; " 204 "current locked to pid %d", 205 __FUNCTION__, 206 TClientBase::mCameraId, 207 getCallingPid(), 208 TClientBase::mClientPid); 209 return BAD_VALUE; 210 } 211 212 TClientBase::mClientPid = getCallingPid(); 213 214 TClientBase::mRemoteCallback = client; 215 mSharedCameraCallbacks = client; 216 217 return OK; 218} 219 220/** Device-related methods */ 221 222template <typename TClientBase> 223void Camera2ClientBase<TClientBase>::notifyError( 224 ICameraDeviceCallbacks::CameraErrorCode errorCode, 225 const CaptureResultExtras& resultExtras) { 226 ALOGE("Error condition %d reported by HAL, requestId %" PRId32, errorCode, 227 resultExtras.requestId); 228} 229 230template <typename TClientBase> 231void Camera2ClientBase<TClientBase>::notifyIdle() { 232 ALOGV("Camera device is now idle"); 233} 234 235template <typename TClientBase> 236void Camera2ClientBase<TClientBase>::notifyShutter(const CaptureResultExtras& resultExtras, 237 nsecs_t timestamp) { 238 (void)resultExtras; 239 (void)timestamp; 240 241 ALOGV("%s: Shutter notification for request id %" PRId32 " at time %" PRId64, 242 __FUNCTION__, resultExtras.requestId, timestamp); 243} 244 245template <typename TClientBase> 246void Camera2ClientBase<TClientBase>::notifyAutoFocus(uint8_t newState, 247 int triggerId) { 248 (void)newState; 249 (void)triggerId; 250 251 ALOGV("%s: Autofocus state now %d, last trigger %d", 252 __FUNCTION__, newState, triggerId); 253 254} 255 256template <typename TClientBase> 257void Camera2ClientBase<TClientBase>::notifyAutoExposure(uint8_t newState, 258 int triggerId) { 259 (void)newState; 260 (void)triggerId; 261 262 ALOGV("%s: Autoexposure state now %d, last trigger %d", 263 __FUNCTION__, newState, triggerId); 264} 265 266template <typename TClientBase> 267void Camera2ClientBase<TClientBase>::notifyAutoWhitebalance(uint8_t newState, 268 int triggerId) { 269 (void)newState; 270 (void)triggerId; 271 272 ALOGV("%s: Auto-whitebalance state now %d, last trigger %d", 273 __FUNCTION__, newState, triggerId); 274} 275 276template <typename TClientBase> 277int Camera2ClientBase<TClientBase>::getCameraId() const { 278 return TClientBase::mCameraId; 279} 280 281template <typename TClientBase> 282int Camera2ClientBase<TClientBase>::getCameraDeviceVersion() const { 283 return mDeviceVersion; 284} 285 286template <typename TClientBase> 287const sp<CameraDeviceBase>& Camera2ClientBase<TClientBase>::getCameraDevice() { 288 return mDevice; 289} 290 291template <typename TClientBase> 292const sp<CameraService>& Camera2ClientBase<TClientBase>::getCameraService() { 293 return TClientBase::mCameraService; 294} 295 296template <typename TClientBase> 297Camera2ClientBase<TClientBase>::SharedCameraCallbacks::Lock::Lock( 298 SharedCameraCallbacks &client) : 299 300 mRemoteCallback(client.mRemoteCallback), 301 mSharedClient(client) { 302 303 mSharedClient.mRemoteCallbackLock.lock(); 304} 305 306template <typename TClientBase> 307Camera2ClientBase<TClientBase>::SharedCameraCallbacks::Lock::~Lock() { 308 mSharedClient.mRemoteCallbackLock.unlock(); 309} 310 311template <typename TClientBase> 312Camera2ClientBase<TClientBase>::SharedCameraCallbacks::SharedCameraCallbacks( 313 const sp<TCamCallbacks>&client) : 314 315 mRemoteCallback(client) { 316} 317 318template <typename TClientBase> 319typename Camera2ClientBase<TClientBase>::SharedCameraCallbacks& 320Camera2ClientBase<TClientBase>::SharedCameraCallbacks::operator=( 321 const sp<TCamCallbacks>&client) { 322 323 Mutex::Autolock l(mRemoteCallbackLock); 324 mRemoteCallback = client; 325 return *this; 326} 327 328template <typename TClientBase> 329void Camera2ClientBase<TClientBase>::SharedCameraCallbacks::clear() { 330 Mutex::Autolock l(mRemoteCallbackLock); 331 mRemoteCallback.clear(); 332} 333 334template class Camera2ClientBase<CameraService::ProClient>; 335template class Camera2ClientBase<CameraService::Client>; 336template class Camera2ClientBase<CameraDeviceClientBase>; 337 338} // namespace android 339