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