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