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