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 char* kCameraServiceName = "media.camera"; 103 Mutex mLock; 104 105 template <class T> 106 void registerAvailCallback(const DeviceContext& deviceContext, const T* callback); 107 108 bool setupVendorTags(sp<hardware::ICameraService> &cameraService); 109 110 class DeathNotifier : public IBinder::DeathRecipient { 111 public: DeathNotifier(CameraManagerGlobal * cm)112 explicit DeathNotifier(CameraManagerGlobal* cm) : mCameraManager(cm) {} 113 protected: 114 // IBinder::DeathRecipient implementation 115 virtual void binderDied(const wp<IBinder>& who); 116 private: 117 const wp<CameraManagerGlobal> mCameraManager; 118 }; 119 sp<DeathNotifier> mDeathNotifier; 120 121 class CameraServiceListener final : public hardware::BnCameraServiceListener { 122 public: CameraServiceListener(CameraManagerGlobal * cm)123 explicit CameraServiceListener(CameraManagerGlobal* cm) : mCameraManager(cm) {} 124 virtual binder::Status onStatusChanged(int32_t status, const std::string& cameraId, 125 int32_t deviceId); 126 virtual binder::Status onPhysicalCameraStatusChanged(int32_t status, 127 const std::string& cameraId, const std::string& physicalCameraId, int32_t deviceId); 128 129 // Torch API not implemented yet onTorchStatusChanged(int32_t,const std::string &,int32_t)130 virtual binder::Status onTorchStatusChanged(int32_t, const std::string&, int32_t) { 131 return binder::Status::ok(); 132 } onTorchStrengthLevelChanged(const std::string &,int32_t,int32_t)133 virtual binder::Status onTorchStrengthLevelChanged(const std::string&, int32_t, int32_t) { 134 return binder::Status::ok(); 135 } 136 137 virtual binder::Status onCameraAccessPrioritiesChanged(); onCameraOpened(const std::string &,const std::string &,int32_t)138 virtual binder::Status onCameraOpened(const std::string&, const std::string&, int32_t) { 139 return binder::Status::ok(); 140 } onCameraOpenedInSharedMode(const std::string &,const std::string &,int32_t,bool)141 virtual binder::Status onCameraOpenedInSharedMode(const std::string&, const std::string&, 142 int32_t, bool) { 143 return binder::Status::ok(); 144 } onCameraClosed(const std::string &,int32_t)145 virtual binder::Status onCameraClosed(const std::string&, int32_t) { 146 return binder::Status::ok(); 147 } 148 149 private: 150 const wp<CameraManagerGlobal> mCameraManager; 151 }; 152 sp<CameraServiceListener> mCameraServiceListener; 153 154 // Wrapper of ACameraManager_AvailabilityCallbacks so we can store it in std::set 155 struct Callback { CallbackCallback156 explicit Callback(const DeviceContext& deviceContext, 157 const ACameraManager_AvailabilityCallbacks* callback) 158 : mDeviceContext(deviceContext), 159 mAvailable(callback->onCameraAvailable), 160 mUnavailable(callback->onCameraUnavailable), 161 mAccessPriorityChanged(nullptr), 162 mPhysicalCamAvailable(nullptr), 163 mPhysicalCamUnavailable(nullptr), 164 mContext(callback->context) {} 165 CallbackCallback166 explicit Callback(const DeviceContext& deviceContext, 167 const ACameraManager_ExtendedAvailabilityCallbacks* callback) 168 : mDeviceContext(deviceContext), 169 mAvailable(callback->availabilityCallbacks.onCameraAvailable), 170 mUnavailable(callback->availabilityCallbacks.onCameraUnavailable), 171 mAccessPriorityChanged(callback->onCameraAccessPrioritiesChanged), 172 mPhysicalCamAvailable(callback->onPhysicalCameraAvailable), 173 mPhysicalCamUnavailable(callback->onPhysicalCameraUnavailable), 174 mContext(callback->availabilityCallbacks.context) {} 175 176 bool operator == (const Callback& other) const { 177 return (mAvailable == other.mAvailable && mUnavailable == other.mUnavailable && 178 mAccessPriorityChanged == other.mAccessPriorityChanged && 179 mPhysicalCamAvailable == other.mPhysicalCamAvailable && 180 mPhysicalCamUnavailable == other.mPhysicalCamUnavailable && 181 mContext == other.mContext && 182 mDeviceContext.deviceId == other.mDeviceContext.deviceId && 183 mDeviceContext.policy == other.mDeviceContext.policy); 184 } 185 bool operator != (const Callback& other) const { 186 return !(*this == other); 187 } 188 bool operator < (const Callback& other) const { 189 #pragma GCC diagnostic push 190 #pragma GCC diagnostic ignored "-Wordered-compare-function-pointers" 191 if (*this == other) return false; 192 if (mDeviceContext.deviceId != other.mDeviceContext.deviceId) { 193 return mDeviceContext.deviceId < other.mDeviceContext.deviceId; 194 } 195 if (mContext != other.mContext) return mContext < other.mContext; 196 if (mPhysicalCamAvailable != other.mPhysicalCamAvailable) { 197 return mPhysicalCamAvailable < other.mPhysicalCamAvailable; 198 } 199 if (mPhysicalCamUnavailable != other.mPhysicalCamUnavailable) { 200 return mPhysicalCamUnavailable < other.mPhysicalCamUnavailable; 201 } 202 if (mAccessPriorityChanged != other.mAccessPriorityChanged) { 203 return mAccessPriorityChanged < other.mAccessPriorityChanged; 204 } 205 if (mAvailable != other.mAvailable) return mAvailable < other.mAvailable; 206 return mUnavailable < other.mUnavailable; 207 #pragma GCC diagnostic pop 208 } 209 bool operator > (const Callback& other) const { 210 return (*this != other && !(*this < other)); 211 } 212 DeviceContext mDeviceContext; 213 ACameraManager_AvailabilityCallback mAvailable; 214 ACameraManager_AvailabilityCallback mUnavailable; 215 ACameraManager_AccessPrioritiesChangedCallback mAccessPriorityChanged; 216 ACameraManager_PhysicalCameraAvailabilityCallback mPhysicalCamAvailable; 217 ACameraManager_PhysicalCameraAvailabilityCallback mPhysicalCamUnavailable; 218 void* mContext; 219 }; 220 221 android::Condition mCallbacksCond; 222 size_t mPendingCallbackCnt = 0; 223 void onCallbackCalled(); 224 void drainPendingCallbacksLocked(); 225 226 std::set<Callback> mCallbacks; 227 228 // definition of handler and message 229 enum { 230 kWhatSendSingleCallback, 231 kWhatSendSingleAccessCallback, 232 kWhatSendSinglePhysicalCameraCallback, 233 }; 234 static const char* kCameraIdKey; 235 static const char* kPhysicalCameraIdKey; 236 static const char* kCallbackFpKey; 237 static const char* kContextKey; 238 static const nsecs_t kCallbackDrainTimeout; 239 class CallbackHandler : public AHandler { 240 public: CallbackHandler(wp<CameraManagerGlobal> parent)241 CallbackHandler(wp<CameraManagerGlobal> parent) : mParent(parent) {} 242 void onMessageReceived(const sp<AMessage> &msg) override; 243 244 private: 245 wp<CameraManagerGlobal> mParent; 246 void notifyParent(); 247 void onMessageReceivedInternal(const sp<AMessage> &msg); 248 }; 249 sp<CallbackHandler> mHandler; 250 sp<ALooper> mCbLooper; // Looper thread where callbacks actually happen on 251 252 sp<hardware::ICameraService> getCameraServiceLocked(); 253 void onCameraAccessPrioritiesChanged(); 254 void onStatusChanged(int32_t status, int deviceId, const std::string& cameraId); 255 void onStatusChangedLocked(int32_t status, int deviceId, const std::string& cameraId); 256 void onStatusChanged(int32_t status, int deviceId, const std::string& cameraId, 257 const std::string& physicalCameraId); 258 void onStatusChangedLocked(int32_t status, int deviceId, const std::string& cameraId, 259 const std::string& physicalCameraId); 260 // Utils for status 261 static bool validStatus(int32_t status); 262 static bool isStatusAvailable(int32_t status); 263 bool supportsCamera2ApiLocked(const std::string &cameraId); 264 265 struct StatusAndHAL3Support { 266 private: 267 int32_t status = hardware::ICameraServiceListener::STATUS_NOT_PRESENT; 268 mutable std::mutex mLock; 269 std::set<std::string> unavailablePhysicalIds; 270 public: 271 const bool supportsHAL3 = false; StatusAndHAL3SupportStatusAndHAL3Support272 StatusAndHAL3Support(int32_t st, bool HAL3support): 273 status(st), supportsHAL3(HAL3support) { }; 274 StatusAndHAL3Support() = default; 275 276 bool addUnavailablePhysicalId(const std::string& physicalCameraId); 277 bool removeUnavailablePhysicalId(const std::string& physicalCameraId); 278 int32_t getStatus(); 279 void updateStatus(int32_t newStatus); 280 std::set<std::string> getUnavailablePhysicalIds(); 281 }; 282 283 struct DeviceStatusMapKey { 284 int deviceId; 285 std::string cameraId; 286 287 bool operator<(const DeviceStatusMapKey& other) const { 288 if (deviceId != other.deviceId) { 289 return deviceId < other.deviceId; 290 } 291 292 // The sort logic must match the logic in 293 // libcameraservice/common/CameraProviderManager.cpp::getAPI1CompatibleCameraDeviceIds 294 uint32_t cameraIdUint = 0, otherCameraIdUint = 0; 295 bool cameraIdIsUint = base::ParseUint(cameraId.c_str(), &cameraIdUint); 296 bool otherCameraIdIsUint = base::ParseUint(other.cameraId.c_str(), &otherCameraIdUint); 297 298 // Uint device IDs first 299 if (cameraIdIsUint && otherCameraIdIsUint) { 300 return cameraIdUint < otherCameraIdUint; 301 } else if (cameraIdIsUint) { 302 return true; 303 } else if (otherCameraIdIsUint) { 304 return false; 305 } 306 // Simple string compare if both id are not uint 307 return cameraIdIsUint < otherCameraIdIsUint; 308 } 309 }; 310 311 std::map<DeviceStatusMapKey, StatusAndHAL3Support> mDeviceStatusMap; 312 313 // For the singleton instance 314 static Mutex sLock; 315 static wp<CameraManagerGlobal> sInstance; CameraManagerGlobal()316 CameraManagerGlobal() {} 317 ~CameraManagerGlobal(); 318 }; 319 320 } // namespace acam; 321 } // namespace android; 322 323 /** 324 * ACameraManager opaque struct definition 325 * Leave outside of android namespace because it's NDK struct 326 */ 327 struct ACameraManager { ACameraManagerACameraManager328 ACameraManager() : mGlobalManager(android::acam::CameraManagerGlobal::getInstance()) {} 329 camera_status_t getCameraIdList(ACameraIdList** cameraIdList); 330 static void deleteCameraIdList(ACameraIdList* cameraIdList); 331 332 camera_status_t getCameraCharacteristics( 333 const char* cameraId, android::sp<ACameraMetadata>* characteristics); 334 camera_status_t openCamera(const char* cameraId, bool sharedMode, 335 ACameraDevice_StateCallbacks* callback, 336 /*out*/ACameraDevice** device, /*out*/bool* primaryClient); 337 void registerAvailabilityCallback(const ACameraManager_AvailabilityCallbacks* callback); 338 void unregisterAvailabilityCallback(const ACameraManager_AvailabilityCallbacks* callback); 339 void registerExtendedAvailabilityCallback( 340 const ACameraManager_ExtendedAvailabilityCallbacks* callback); 341 void unregisterExtendedAvailabilityCallback( 342 const ACameraManager_ExtendedAvailabilityCallbacks* callback); 343 camera_status_t isCameraDeviceSharingSupported( 344 const char* cameraId, bool* isSharingSupported); 345 private: 346 enum { 347 kCameraIdListNotInit = -1 348 }; 349 android::Mutex mLock; 350 android::sp<android::acam::CameraManagerGlobal> mGlobalManager; 351 const android::acam::DeviceContext mDeviceContext; 352 }; 353 354 #endif //_ACAMERA_MANAGER_H 355