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