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