1 /* 2 * Copyright (C) 2015 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 #ifndef _ACAMERA_MANAGER_H 18 #define _ACAMERA_MANAGER_H 19 20 #include <camera/NdkCameraManager.h> 21 22 #include <android-base/parseint.h> 23 #include <android/companion/virtualnative/IVirtualDeviceManagerNative.h> 24 #include <android/hardware/ICameraService.h> 25 #include <android/hardware/BnCameraServiceListener.h> 26 #include <camera/CameraMetadata.h> 27 #include <binder/IServiceManager.h> 28 #include <utils/StrongPointer.h> 29 #include <utils/Mutex.h> 30 31 #include <media/stagefright/foundation/ALooper.h> 32 #include <media/stagefright/foundation/AHandler.h> 33 #include <media/stagefright/foundation/AMessage.h> 34 35 #include <set> 36 #include <map> 37 38 namespace android { 39 namespace acam { 40 41 enum class DevicePolicy { 42 DEVICE_POLICY_DEFAULT = 43 ::android::companion::virtualnative::IVirtualDeviceManagerNative::DEVICE_POLICY_DEFAULT, 44 DEVICE_POLICY_CUSTOM = 45 ::android::companion::virtualnative::IVirtualDeviceManagerNative::DEVICE_POLICY_CUSTOM 46 }; 47 48 /** 49 * Device context within which are cameras accessed. 50 * 51 * When constructed, the device id is set to id of virtual device corresponding to 52 * caller's UID (or default device id if current app process is not running on virtual device). 53 * 54 * See getDeviceId() in Context.java for more context (no pun intented). 55 */ 56 struct DeviceContext { 57 DeviceContext(); 58 59 // Id of virtual device asociated with this context (or DEFAULT_DEVICE_ID = 0 in case 60 // caller UID is not running on virtual device). 61 int deviceId; 62 // Device policy corresponding to VirtualDeviceParams.POLICY_TYPE_CAMERA: 63 // 64 // Can be either: 65 // * (0) DEVICE_POLICY_DEFAULT - virtual devices have access to default device cameras. 66 // * (1) DEVICE_POLICY_CUSTOM - virtual devices do not have access to default device cameras 67 // and can only access virtual cameras owned by the same device. 68 DevicePolicy policy; 69 }; 70 71 /** 72 * Per-process singleton instance of CameraManger. Shared by all ACameraManager 73 * instances. Created when first ACameraManager is created and destroyed when 74 * all ACameraManager instances are deleted. 75 * 76 * TODO: maybe CameraManagerGlobal is better suited in libcameraclient? 77 */ 78 class CameraManagerGlobal final : public RefBase { 79 public: 80 static sp<CameraManagerGlobal> getInstance(); 81 sp<hardware::ICameraService> getCameraService(); 82 83 void registerAvailabilityCallback(const DeviceContext& context, 84 const ACameraManager_AvailabilityCallbacks* callback); 85 void unregisterAvailabilityCallback(const DeviceContext& context, 86 const ACameraManager_AvailabilityCallbacks* callback); 87 88 void registerExtendedAvailabilityCallback( 89 const DeviceContext& context, 90 const ACameraManager_ExtendedAvailabilityCallbacks* callback); 91 void unregisterExtendedAvailabilityCallback( 92 const DeviceContext& context, 93 const ACameraManager_ExtendedAvailabilityCallbacks* callback); 94 95 /** 96 * Return camera IDs that support camera2 97 */ 98 void getCameraIdList(const DeviceContext& deviceContext, std::vector<std::string>* cameraIds); 99 100 private: 101 sp<hardware::ICameraService> mCameraService; 102 const int kCameraServicePollDelay = 500000; // 0.5s 103 const char* kCameraServiceName = "media.camera"; 104 Mutex mLock; 105 106 template <class T> 107 void registerAvailCallback(const DeviceContext& deviceContext, const T* callback); 108 109 class DeathNotifier : public IBinder::DeathRecipient { 110 public: DeathNotifier(CameraManagerGlobal * cm)111 explicit DeathNotifier(CameraManagerGlobal* cm) : mCameraManager(cm) {} 112 protected: 113 // IBinder::DeathRecipient implementation 114 virtual void binderDied(const wp<IBinder>& who); 115 private: 116 const wp<CameraManagerGlobal> mCameraManager; 117 }; 118 sp<DeathNotifier> mDeathNotifier; 119 120 class CameraServiceListener final : public hardware::BnCameraServiceListener { 121 public: CameraServiceListener(CameraManagerGlobal * cm)122 explicit CameraServiceListener(CameraManagerGlobal* cm) : mCameraManager(cm) {} 123 virtual binder::Status onStatusChanged(int32_t status, const std::string& cameraId, 124 int32_t deviceId); 125 virtual binder::Status onPhysicalCameraStatusChanged(int32_t status, 126 const std::string& cameraId, const std::string& physicalCameraId, int32_t deviceId); 127 128 // Torch API not implemented yet onTorchStatusChanged(int32_t,const std::string &,int32_t)129 virtual binder::Status onTorchStatusChanged(int32_t, const std::string&, int32_t) { 130 return binder::Status::ok(); 131 } onTorchStrengthLevelChanged(const std::string &,int32_t,int32_t)132 virtual binder::Status onTorchStrengthLevelChanged(const std::string&, int32_t, int32_t) { 133 return binder::Status::ok(); 134 } 135 136 virtual binder::Status onCameraAccessPrioritiesChanged(); onCameraOpened(const std::string &,const std::string &,int32_t)137 virtual binder::Status onCameraOpened(const std::string&, const std::string&, int32_t) { 138 return binder::Status::ok(); 139 } onCameraClosed(const std::string &,int32_t)140 virtual binder::Status onCameraClosed(const std::string&, int32_t) { 141 return binder::Status::ok(); 142 } 143 144 private: 145 const wp<CameraManagerGlobal> mCameraManager; 146 }; 147 sp<CameraServiceListener> mCameraServiceListener; 148 149 // Wrapper of ACameraManager_AvailabilityCallbacks so we can store it in std::set 150 struct Callback { CallbackCallback151 explicit Callback(const DeviceContext& deviceContext, 152 const ACameraManager_AvailabilityCallbacks* callback) 153 : mDeviceContext(deviceContext), 154 mAvailable(callback->onCameraAvailable), 155 mUnavailable(callback->onCameraUnavailable), 156 mAccessPriorityChanged(nullptr), 157 mPhysicalCamAvailable(nullptr), 158 mPhysicalCamUnavailable(nullptr), 159 mContext(callback->context) {} 160 CallbackCallback161 explicit Callback(const DeviceContext& deviceContext, 162 const ACameraManager_ExtendedAvailabilityCallbacks* callback) 163 : mDeviceContext(deviceContext), 164 mAvailable(callback->availabilityCallbacks.onCameraAvailable), 165 mUnavailable(callback->availabilityCallbacks.onCameraUnavailable), 166 mAccessPriorityChanged(callback->onCameraAccessPrioritiesChanged), 167 mPhysicalCamAvailable(callback->onPhysicalCameraAvailable), 168 mPhysicalCamUnavailable(callback->onPhysicalCameraUnavailable), 169 mContext(callback->availabilityCallbacks.context) {} 170 171 bool operator == (const Callback& other) const { 172 return (mAvailable == other.mAvailable && mUnavailable == other.mUnavailable && 173 mAccessPriorityChanged == other.mAccessPriorityChanged && 174 mPhysicalCamAvailable == other.mPhysicalCamAvailable && 175 mPhysicalCamUnavailable == other.mPhysicalCamUnavailable && 176 mContext == other.mContext && 177 mDeviceContext.deviceId == other.mDeviceContext.deviceId && 178 mDeviceContext.policy == other.mDeviceContext.policy); 179 } 180 bool operator != (const Callback& other) const { 181 return !(*this == other); 182 } 183 bool operator < (const Callback& other) const { 184 #pragma GCC diagnostic push 185 #pragma GCC diagnostic ignored "-Wordered-compare-function-pointers" 186 if (*this == other) return false; 187 if (mDeviceContext.deviceId != other.mDeviceContext.deviceId) { 188 return mDeviceContext.deviceId < other.mDeviceContext.deviceId; 189 } 190 if (mContext != other.mContext) return mContext < other.mContext; 191 if (mPhysicalCamAvailable != other.mPhysicalCamAvailable) { 192 return mPhysicalCamAvailable < other.mPhysicalCamAvailable; 193 } 194 if (mPhysicalCamUnavailable != other.mPhysicalCamUnavailable) { 195 return mPhysicalCamUnavailable < other.mPhysicalCamUnavailable; 196 } 197 if (mAccessPriorityChanged != other.mAccessPriorityChanged) { 198 return mAccessPriorityChanged < other.mAccessPriorityChanged; 199 } 200 if (mAvailable != other.mAvailable) return mAvailable < other.mAvailable; 201 return mUnavailable < other.mUnavailable; 202 #pragma GCC diagnostic pop 203 } 204 bool operator > (const Callback& other) const { 205 return (*this != other && !(*this < other)); 206 } 207 DeviceContext mDeviceContext; 208 ACameraManager_AvailabilityCallback mAvailable; 209 ACameraManager_AvailabilityCallback mUnavailable; 210 ACameraManager_AccessPrioritiesChangedCallback mAccessPriorityChanged; 211 ACameraManager_PhysicalCameraAvailabilityCallback mPhysicalCamAvailable; 212 ACameraManager_PhysicalCameraAvailabilityCallback mPhysicalCamUnavailable; 213 void* mContext; 214 }; 215 216 android::Condition mCallbacksCond; 217 size_t mPendingCallbackCnt = 0; 218 void onCallbackCalled(); 219 void drainPendingCallbacksLocked(); 220 221 std::set<Callback> mCallbacks; 222 223 // definition of handler and message 224 enum { 225 kWhatSendSingleCallback, 226 kWhatSendSingleAccessCallback, 227 kWhatSendSinglePhysicalCameraCallback, 228 }; 229 static const char* kCameraIdKey; 230 static const char* kPhysicalCameraIdKey; 231 static const char* kCallbackFpKey; 232 static const char* kContextKey; 233 static const nsecs_t kCallbackDrainTimeout; 234 class CallbackHandler : public AHandler { 235 public: CallbackHandler(wp<CameraManagerGlobal> parent)236 CallbackHandler(wp<CameraManagerGlobal> parent) : mParent(parent) {} 237 void onMessageReceived(const sp<AMessage> &msg) override; 238 239 private: 240 wp<CameraManagerGlobal> mParent; 241 void notifyParent(); 242 void onMessageReceivedInternal(const sp<AMessage> &msg); 243 }; 244 sp<CallbackHandler> mHandler; 245 sp<ALooper> mCbLooper; // Looper thread where callbacks actually happen on 246 247 sp<hardware::ICameraService> getCameraServiceLocked(); 248 void onCameraAccessPrioritiesChanged(); 249 void onStatusChanged(int32_t status, int deviceId, const std::string& cameraId); 250 void onStatusChangedLocked(int32_t status, int deviceId, const std::string& cameraId); 251 void onStatusChanged(int32_t status, int deviceId, const std::string& cameraId, 252 const std::string& physicalCameraId); 253 void onStatusChangedLocked(int32_t status, int deviceId, const std::string& cameraId, 254 const std::string& physicalCameraId); 255 // Utils for status 256 static bool validStatus(int32_t status); 257 static bool isStatusAvailable(int32_t status); 258 bool supportsCamera2ApiLocked(const std::string &cameraId); 259 260 struct StatusAndHAL3Support { 261 private: 262 int32_t status = hardware::ICameraServiceListener::STATUS_NOT_PRESENT; 263 mutable std::mutex mLock; 264 std::set<std::string> unavailablePhysicalIds; 265 public: 266 const bool supportsHAL3 = false; StatusAndHAL3SupportStatusAndHAL3Support267 StatusAndHAL3Support(int32_t st, bool HAL3support): 268 status(st), supportsHAL3(HAL3support) { }; 269 StatusAndHAL3Support() = default; 270 271 bool addUnavailablePhysicalId(const std::string& physicalCameraId); 272 bool removeUnavailablePhysicalId(const std::string& physicalCameraId); 273 int32_t getStatus(); 274 void updateStatus(int32_t newStatus); 275 std::set<std::string> getUnavailablePhysicalIds(); 276 }; 277 278 struct DeviceStatusMapKey { 279 int deviceId; 280 std::string cameraId; 281 282 bool operator<(const DeviceStatusMapKey& other) const { 283 if (deviceId != other.deviceId) { 284 return deviceId < other.deviceId; 285 } 286 287 // The sort logic must match the logic in 288 // libcameraservice/common/CameraProviderManager.cpp::getAPI1CompatibleCameraDeviceIds 289 uint32_t cameraIdUint = 0, otherCameraIdUint = 0; 290 bool cameraIdIsUint = base::ParseUint(cameraId.c_str(), &cameraIdUint); 291 bool otherCameraIdIsUint = base::ParseUint(other.cameraId.c_str(), &otherCameraIdUint); 292 293 // Uint device IDs first 294 if (cameraIdIsUint && otherCameraIdIsUint) { 295 return cameraIdUint < otherCameraIdUint; 296 } else if (cameraIdIsUint) { 297 return true; 298 } else if (otherCameraIdIsUint) { 299 return false; 300 } 301 // Simple string compare if both id are not uint 302 return cameraIdIsUint < otherCameraIdIsUint; 303 } 304 }; 305 306 std::map<DeviceStatusMapKey, StatusAndHAL3Support> mDeviceStatusMap; 307 308 // For the singleton instance 309 static Mutex sLock; 310 static wp<CameraManagerGlobal> sInstance; CameraManagerGlobal()311 CameraManagerGlobal() {} 312 ~CameraManagerGlobal(); 313 }; 314 315 } // namespace acam; 316 } // namespace android; 317 318 /** 319 * ACameraManager opaque struct definition 320 * Leave outside of android namespace because it's NDK struct 321 */ 322 struct ACameraManager { ACameraManagerACameraManager323 ACameraManager() : mGlobalManager(android::acam::CameraManagerGlobal::getInstance()) {} 324 camera_status_t getCameraIdList(ACameraIdList** cameraIdList); 325 static void deleteCameraIdList(ACameraIdList* cameraIdList); 326 327 camera_status_t getCameraCharacteristics( 328 const char* cameraId, android::sp<ACameraMetadata>* characteristics); 329 camera_status_t openCamera(const char* cameraId, 330 ACameraDevice_StateCallbacks* callback, 331 /*out*/ACameraDevice** device); 332 void registerAvailabilityCallback(const ACameraManager_AvailabilityCallbacks* callback); 333 void unregisterAvailabilityCallback(const ACameraManager_AvailabilityCallbacks* callback); 334 void registerExtendedAvailabilityCallback( 335 const ACameraManager_ExtendedAvailabilityCallbacks* callback); 336 void unregisterExtendedAvailabilityCallback( 337 const ACameraManager_ExtendedAvailabilityCallbacks* callback); 338 339 private: 340 enum { 341 kCameraIdListNotInit = -1 342 }; 343 android::Mutex mLock; 344 android::sp<android::acam::CameraManagerGlobal> mGlobalManager; 345 const android::acam::DeviceContext mDeviceContext; 346 }; 347 348 #endif //_ACAMERA_MANAGER_H 349