Camera2ClientBase.cpp revision e5729fac81c8a984e984fefc90afc64135817d4f
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(int errorCode, int arg1, 225 int arg2) { 226 ALOGE("Error condition %d reported by HAL, arguments %d, %d", errorCode, 227 arg1, arg2); 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(int requestId, 237 nsecs_t timestamp) { 238 (void)requestId; 239 (void)timestamp; 240 241 ALOGV("%s: Shutter notification for request id %d at time %" PRId64, 242 __FUNCTION__, 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> 282const sp<CameraDeviceBase>& Camera2ClientBase<TClientBase>::getCameraDevice() { 283 return mDevice; 284} 285 286template <typename TClientBase> 287const sp<CameraService>& Camera2ClientBase<TClientBase>::getCameraService() { 288 return TClientBase::mCameraService; 289} 290 291template <typename TClientBase> 292Camera2ClientBase<TClientBase>::SharedCameraCallbacks::Lock::Lock( 293 SharedCameraCallbacks &client) : 294 295 mRemoteCallback(client.mRemoteCallback), 296 mSharedClient(client) { 297 298 mSharedClient.mRemoteCallbackLock.lock(); 299} 300 301template <typename TClientBase> 302Camera2ClientBase<TClientBase>::SharedCameraCallbacks::Lock::~Lock() { 303 mSharedClient.mRemoteCallbackLock.unlock(); 304} 305 306template <typename TClientBase> 307Camera2ClientBase<TClientBase>::SharedCameraCallbacks::SharedCameraCallbacks( 308 const sp<TCamCallbacks>&client) : 309 310 mRemoteCallback(client) { 311} 312 313template <typename TClientBase> 314typename Camera2ClientBase<TClientBase>::SharedCameraCallbacks& 315Camera2ClientBase<TClientBase>::SharedCameraCallbacks::operator=( 316 const sp<TCamCallbacks>&client) { 317 318 Mutex::Autolock l(mRemoteCallbackLock); 319 mRemoteCallback = client; 320 return *this; 321} 322 323template <typename TClientBase> 324void Camera2ClientBase<TClientBase>::SharedCameraCallbacks::clear() { 325 Mutex::Autolock l(mRemoteCallbackLock); 326 mRemoteCallback.clear(); 327} 328 329template class Camera2ClientBase<CameraService::ProClient>; 330template class Camera2ClientBase<CameraService::Client>; 331template class Camera2ClientBase<CameraDeviceClientBase>; 332 333} // namespace android 334