Camera2ClientBase.cpp revision 66281c3a5d7eea486ddc6ad30088ba92956fd4fd
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 <utils/Log.h> 22#include <utils/Trace.h> 23 24#include <cutils/properties.h> 25#include <gui/Surface.h> 26#include <gui/Surface.h> 27 28#include "common/Camera2ClientBase.h" 29 30#include "api2/CameraDeviceClient.h" 31 32#include "CameraDeviceFactory.h" 33 34namespace android { 35using namespace camera2; 36 37static int getCallingPid() { 38 return IPCThreadState::self()->getCallingPid(); 39} 40 41// Interface used by CameraService 42 43template <typename TClientBase> 44Camera2ClientBase<TClientBase>::Camera2ClientBase( 45 const sp<CameraService>& cameraService, 46 const sp<TCamCallbacks>& remoteCallback, 47 const String16& clientPackageName, 48 int cameraId, 49 int cameraFacing, 50 int clientPid, 51 uid_t clientUid, 52 int servicePid): 53 TClientBase(cameraService, remoteCallback, clientPackageName, 54 cameraId, cameraFacing, clientPid, clientUid, servicePid), 55 mSharedCameraCallbacks(remoteCallback) 56{ 57 ALOGI("Camera %d: Opened", cameraId); 58 59 mDevice = CameraDeviceFactory::createDevice(cameraId); 60 LOG_ALWAYS_FATAL_IF(mDevice == 0, "Device should never be NULL here."); 61} 62 63template <typename TClientBase> 64status_t Camera2ClientBase<TClientBase>::checkPid(const char* checkLocation) 65 const { 66 67 int callingPid = getCallingPid(); 68 if (callingPid == TClientBase::mClientPid) return NO_ERROR; 69 70 ALOGE("%s: attempt to use a locked camera from a different process" 71 " (old pid %d, new pid %d)", checkLocation, TClientBase::mClientPid, callingPid); 72 return PERMISSION_DENIED; 73} 74 75template <typename TClientBase> 76status_t Camera2ClientBase<TClientBase>::initialize(camera_module_t *module) { 77 ATRACE_CALL(); 78 ALOGV("%s: Initializing client for camera %d", __FUNCTION__, 79 TClientBase::mCameraId); 80 status_t res; 81 82 // Verify ops permissions 83 res = TClientBase::startCameraOps(); 84 if (res != OK) { 85 return res; 86 } 87 88 if (mDevice == NULL) { 89 ALOGE("%s: Camera %d: No device connected", 90 __FUNCTION__, TClientBase::mCameraId); 91 return NO_INIT; 92 } 93 94 res = mDevice->initialize(module); 95 if (res != OK) { 96 ALOGE("%s: Camera %d: unable to initialize device: %s (%d)", 97 __FUNCTION__, TClientBase::mCameraId, strerror(-res), res); 98 return res; 99 } 100 101 res = mDevice->setNotifyCallback(this); 102 103 return OK; 104} 105 106template <typename TClientBase> 107Camera2ClientBase<TClientBase>::~Camera2ClientBase() { 108 ATRACE_CALL(); 109 110 TClientBase::mDestructionStarted = true; 111 112 TClientBase::finishCameraOps(); 113 114 disconnect(); 115 116 ALOGI("Closed Camera %d", TClientBase::mCameraId); 117} 118 119template <typename TClientBase> 120status_t Camera2ClientBase<TClientBase>::dump(int fd, 121 const Vector<String16>& args) { 122 String8 result; 123 result.appendFormat("Camera2ClientBase[%d] (%p) PID: %d, dump:\n", 124 TClientBase::mCameraId, 125 TClientBase::getRemoteCallback()->asBinder().get(), 126 TClientBase::mClientPid); 127 result.append(" State: "); 128 129 write(fd, result.string(), result.size()); 130 // TODO: print dynamic/request section from most recent requests 131 132 return dumpDevice(fd, args); 133} 134 135template <typename TClientBase> 136status_t Camera2ClientBase<TClientBase>::dumpDevice( 137 int fd, 138 const Vector<String16>& args) { 139 String8 result; 140 141 result = " Device dump:\n"; 142 write(fd, result.string(), result.size()); 143 144 if (!mDevice.get()) { 145 result = " *** Device is detached\n"; 146 write(fd, result.string(), result.size()); 147 return NO_ERROR; 148 } 149 150 status_t res = mDevice->dump(fd, args); 151 if (res != OK) { 152 result = String8::format(" Error dumping device: %s (%d)", 153 strerror(-res), res); 154 write(fd, result.string(), result.size()); 155 } 156 157 return NO_ERROR; 158} 159 160// ICameraClient2BaseUser interface 161 162 163template <typename TClientBase> 164void Camera2ClientBase<TClientBase>::disconnect() { 165 ATRACE_CALL(); 166 Mutex::Autolock icl(mBinderSerializationLock); 167 168 // Allow both client and the media server to disconnect at all times 169 int callingPid = getCallingPid(); 170 if (callingPid != TClientBase::mClientPid && 171 callingPid != TClientBase::mServicePid) return; 172 173 ALOGV("Camera %d: Shutting down", TClientBase::mCameraId); 174 175 detachDevice(); 176 177 CameraService::BasicClient::disconnect(); 178 179 ALOGV("Camera %d: Shut down complete complete", TClientBase::mCameraId); 180} 181 182template <typename TClientBase> 183void Camera2ClientBase<TClientBase>::detachDevice() { 184 if (mDevice == 0) return; 185 mDevice->disconnect(); 186 187 mDevice.clear(); 188 189 ALOGV("Camera %d: Detach complete", TClientBase::mCameraId); 190} 191 192template <typename TClientBase> 193status_t Camera2ClientBase<TClientBase>::connect( 194 const sp<TCamCallbacks>& client) { 195 ATRACE_CALL(); 196 ALOGV("%s: E", __FUNCTION__); 197 Mutex::Autolock icl(mBinderSerializationLock); 198 199 if (TClientBase::mClientPid != 0 && 200 getCallingPid() != TClientBase::mClientPid) { 201 202 ALOGE("%s: Camera %d: Connection attempt from pid %d; " 203 "current locked to pid %d", 204 __FUNCTION__, 205 TClientBase::mCameraId, 206 getCallingPid(), 207 TClientBase::mClientPid); 208 return BAD_VALUE; 209 } 210 211 TClientBase::mClientPid = getCallingPid(); 212 213 TClientBase::mRemoteCallback = client; 214 mSharedCameraCallbacks = client; 215 216 return OK; 217} 218 219/** Device-related methods */ 220 221template <typename TClientBase> 222void Camera2ClientBase<TClientBase>::notifyError(int errorCode, int arg1, 223 int arg2) { 224 ALOGE("Error condition %d reported by HAL, arguments %d, %d", errorCode, 225 arg1, arg2); 226} 227 228template <typename TClientBase> 229void Camera2ClientBase<TClientBase>::notifyShutter(int frameNumber, 230 nsecs_t timestamp) { 231 (void)frameNumber; 232 (void)timestamp; 233 234 ALOGV("%s: Shutter notification for frame %d at time %lld", __FUNCTION__, 235 frameNumber, timestamp); 236} 237 238template <typename TClientBase> 239void Camera2ClientBase<TClientBase>::notifyAutoFocus(uint8_t newState, 240 int triggerId) { 241 (void)newState; 242 (void)triggerId; 243 244 ALOGV("%s: Autofocus state now %d, last trigger %d", 245 __FUNCTION__, newState, triggerId); 246 247 typename SharedCameraCallbacks::Lock l(mSharedCameraCallbacks); 248 if (l.mRemoteCallback != 0) { 249 l.mRemoteCallback->notifyCallback(CAMERA_MSG_FOCUS_MOVE, 1, 0); 250 } 251 if (l.mRemoteCallback != 0) { 252 l.mRemoteCallback->notifyCallback(CAMERA_MSG_FOCUS, 1, 0); 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