1 /* 2 * Copyright (C) 2018 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 <CameraMetadata.h> 21 #include <aidl/android/frameworks/cameraservice/common/Status.h> 22 #include <aidl/android/frameworks/cameraservice/common/VendorTag.h> 23 #include <aidl/android/frameworks/cameraservice/common/VendorTagSection.h> 24 #include <aidl/android/frameworks/cameraservice/service/BnCameraServiceListener.h> 25 #include <aidl/android/frameworks/cameraservice/service/CameraDeviceStatus.h> 26 #include <aidl/android/frameworks/cameraservice/service/CameraStatusAndId.h> 27 #include <aidl/android/frameworks/cameraservice/service/ICameraService.h> 28 #include <android-base/parseint.h> 29 #include <camera/NdkCameraManager.h> 30 #include <map> 31 #include <media/stagefright/foundation/AHandler.h> 32 #include <media/stagefright/foundation/ALooper.h> 33 #include <media/stagefright/foundation/AMessage.h> 34 #include <set> 35 #include <utility> 36 #include <utils/Mutex.h> 37 #include <utils/StrongPointer.h> 38 39 namespace android { 40 namespace acam { 41 42 using ::aidl::android::frameworks::cameraservice::common::Status; 43 using ::aidl::android::frameworks::cameraservice::common::VendorTag; 44 using ::aidl::android::frameworks::cameraservice::common::VendorTagSection; 45 using ::aidl::android::frameworks::cameraservice::service::BnCameraServiceListener; 46 using ::aidl::android::frameworks::cameraservice::service::CameraDeviceStatus; 47 using ::aidl::android::frameworks::cameraservice::service::CameraStatusAndId; 48 using ::aidl::android::frameworks::cameraservice::service::ICameraService; 49 50 /** 51 * Per-process singleton instance of CameraManger. Shared by all ACameraManager 52 * instances. Created when first ACameraManager is created and destroyed when 53 * all ACameraManager instances are deleted. 54 * 55 * TODO: maybe CameraManagerGlobal is better suited in libcameraclient? 56 */ 57 class CameraManagerGlobal final: public std::enable_shared_from_this<CameraManagerGlobal> { 58 public: 59 static std::shared_ptr<CameraManagerGlobal> getInstance(); 60 static void binderDeathCallback(void* cookie); 61 CameraManagerGlobal()62 CameraManagerGlobal() {}; 63 ~CameraManagerGlobal(); 64 65 std::shared_ptr<ICameraService> getCameraService(); 66 67 void registerAvailabilityCallback(const ACameraManager_AvailabilityCallbacks *callback); 68 void unregisterAvailabilityCallback(const ACameraManager_AvailabilityCallbacks *callback); 69 70 void registerExtendedAvailabilityCallback( 71 const ACameraManager_ExtendedAvailabilityCallbacks* callback); 72 void unregisterExtendedAvailabilityCallback( 73 const ACameraManager_ExtendedAvailabilityCallbacks* callback); 74 75 /** 76 * Return camera IDs that support camera2 77 */ 78 void getCameraIdList(std::vector<std::string> *cameraIds); 79 80 private: 81 std::shared_ptr<ICameraService> mCameraService; 82 const int kCameraServicePollDelay = 500000; // 0.5s 83 Mutex mLock; 84 ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient; 85 86 class CameraServiceListener final : public BnCameraServiceListener { 87 public: CameraServiceListener(std::weak_ptr<CameraManagerGlobal> cm)88 explicit CameraServiceListener(std::weak_ptr<CameraManagerGlobal> cm) : 89 mCameraManager(std::move(cm)) {} 90 ndk::ScopedAStatus onPhysicalCameraStatusChanged( 91 CameraDeviceStatus in_status, const std::string& in_cameraId, 92 const std::string& in_physicalCameraId) override; 93 ndk::ScopedAStatus onStatusChanged(CameraDeviceStatus in_status, 94 const std::string& in_cameraId) override; 95 96 private: 97 const std::weak_ptr<CameraManagerGlobal> mCameraManager; 98 }; 99 std::shared_ptr<CameraServiceListener> mCameraServiceListener; 100 101 // Wrapper of ACameraManager_AvailabilityCallbacks so we can store it in std::set 102 struct Callback { CallbackCallback103 explicit Callback(const ACameraManager_AvailabilityCallbacks *callback) : 104 mAvailable(callback->onCameraAvailable), 105 mUnavailable(callback->onCameraUnavailable), 106 mAccessPriorityChanged(nullptr), 107 mPhysicalCamAvailable(nullptr), 108 mPhysicalCamUnavailable(nullptr), 109 mContext(callback->context) {} 110 CallbackCallback111 explicit Callback(const ACameraManager_ExtendedAvailabilityCallbacks *callback) : 112 mAvailable(callback->availabilityCallbacks.onCameraAvailable), 113 mUnavailable(callback->availabilityCallbacks.onCameraUnavailable), 114 mAccessPriorityChanged(callback->onCameraAccessPrioritiesChanged), 115 mPhysicalCamAvailable(callback->onPhysicalCameraAvailable), 116 mPhysicalCamUnavailable(callback->onPhysicalCameraUnavailable), 117 mContext(callback->availabilityCallbacks.context) {} 118 119 bool operator == (const Callback& other) const { 120 return (mAvailable == other.mAvailable && 121 mUnavailable == other.mUnavailable && 122 mAccessPriorityChanged == other.mAccessPriorityChanged && 123 mPhysicalCamAvailable == other.mPhysicalCamAvailable && 124 mPhysicalCamUnavailable == other.mPhysicalCamUnavailable && 125 mContext == other.mContext); 126 } 127 bool operator != (const Callback& other) const { 128 return !(*this == other); 129 } 130 bool operator < (const Callback& other) const { 131 #pragma GCC diagnostic push 132 #pragma GCC diagnostic ignored "-Wordered-compare-function-pointers" 133 if (*this == other) return false; 134 if (mContext != other.mContext) return mContext < other.mContext; 135 if (mAvailable != other.mAvailable) return mAvailable < other.mAvailable; 136 if (mAccessPriorityChanged != other.mAccessPriorityChanged) 137 return mAccessPriorityChanged < other.mAccessPriorityChanged; 138 if (mPhysicalCamAvailable != other.mPhysicalCamAvailable) 139 return mPhysicalCamAvailable < other.mPhysicalCamAvailable; 140 if (mPhysicalCamUnavailable != other.mPhysicalCamUnavailable) 141 return mPhysicalCamUnavailable < other.mPhysicalCamUnavailable; 142 return mUnavailable < other.mUnavailable; 143 #pragma GCC diagnostic pop 144 } 145 bool operator > (const Callback& other) const { 146 return (*this != other && !(*this < other)); 147 } 148 ACameraManager_AvailabilityCallback mAvailable; 149 ACameraManager_AvailabilityCallback mUnavailable; 150 ACameraManager_AccessPrioritiesChangedCallback mAccessPriorityChanged; 151 ACameraManager_PhysicalCameraAvailabilityCallback mPhysicalCamAvailable; 152 ACameraManager_PhysicalCameraAvailabilityCallback mPhysicalCamUnavailable; 153 void* mContext; 154 }; 155 156 android::Condition mCallbacksCond; 157 size_t mPendingCallbackCnt = 0; 158 void onCallbackCalled(); 159 void drainPendingCallbacksLocked(); 160 161 std::set<Callback> mCallbacks; 162 163 // definition of handler and message 164 enum { 165 kWhatSendSingleCallback, 166 kWhatSendSinglePhysicalCameraCallback, 167 }; 168 static const char* kCameraIdKey; 169 static const char* kPhysicalCameraIdKey; 170 static const char* kCallbackFpKey; 171 static const char* kContextKey; 172 static const nsecs_t kCallbackDrainTimeout; 173 class CallbackHandler : public AHandler { 174 public: CallbackHandler(std::weak_ptr<CameraManagerGlobal> parent)175 CallbackHandler(std::weak_ptr<CameraManagerGlobal> parent) : mParent(std::move(parent)) {} 176 void onMessageReceived(const sp<AMessage> &msg) override; 177 private: 178 std::weak_ptr<CameraManagerGlobal> mParent; 179 void notifyParent(); 180 void onMessageReceivedInternal(const sp<AMessage> &msg); 181 }; 182 sp<CallbackHandler> mHandler; 183 sp<ALooper> mCbLooper; // Looper thread where callbacks actually happen on 184 185 void onStatusChanged(const CameraDeviceStatus &status, const std::string &cameraId); 186 void onStatusChangedLocked(const CameraDeviceStatus &status, const std::string &cameraId); 187 void onStatusChanged(const CameraDeviceStatus &status, const std::string &cameraId, 188 const std::string &physicalCameraId); 189 void onStatusChangedLocked(const CameraDeviceStatus &status, const std::string &cameraId, 190 const std::string &physicalCameraId); 191 bool setupVendorTags(); 192 193 // Utils for status 194 static bool validStatus(CameraDeviceStatus status); 195 static bool isStatusAvailable(CameraDeviceStatus status); 196 197 // The sort logic must match the logic in 198 // libcameraservice/common/CameraProviderManager.cpp::getAPI1CompatibleCameraDeviceIds 199 struct CameraIdComparator { operatorCameraIdComparator200 bool operator()(const std::string& a, const std::string& b) const { 201 uint32_t aUint = 0, bUint = 0; 202 bool aIsUint = base::ParseUint(a.c_str(), &aUint); 203 bool bIsUint = base::ParseUint(b.c_str(), &bUint); 204 205 // Uint device IDs first 206 if (aIsUint && bIsUint) { 207 return aUint < bUint; 208 } else if (aIsUint) { 209 return true; 210 } else if (bIsUint) { 211 return false; 212 } 213 // Simple string compare if both id are not uint 214 return a < b; 215 } 216 }; 217 218 struct CameraStatus { 219 private: 220 CameraDeviceStatus status = CameraDeviceStatus::STATUS_NOT_PRESENT; 221 mutable std::mutex mLock; 222 std::set<std::string> unavailablePhysicalIds; 223 public: CameraStatusCameraStatus224 CameraStatus(CameraDeviceStatus st): status(st) { }; 225 CameraStatus() = default; 226 227 bool addUnavailablePhysicalId(const std::string& physicalCameraId); 228 bool removeUnavailablePhysicalId(const std::string& physicalCameraId); 229 CameraDeviceStatus getStatus(); 230 void updateStatus(CameraDeviceStatus newStatus); 231 std::set<std::string> getUnavailablePhysicalIds(); 232 }; 233 234 template <class T> 235 void registerAvailCallback(const T *callback); 236 237 // Map camera_id -> status 238 std::map<std::string, CameraStatus, CameraIdComparator> mDeviceStatusMap; 239 240 // For the singleton instance 241 static Mutex sLock; 242 // Static instance is stored in a weak pointer, so will only exist if there is at least one 243 // active consumer of CameraManagerGlobal 244 static std::weak_ptr<CameraManagerGlobal> sInstance; 245 }; 246 247 } // namespace acam; 248 } // namespace android; 249 250 /** 251 * ACameraManager opaque struct definition 252 * Leave outside of android namespace because it's NDK struct 253 */ 254 struct ACameraManager { ACameraManagerACameraManager255 ACameraManager() : 256 mGlobalManager(android::acam::CameraManagerGlobal::getInstance()) {} 257 ~ACameraManager(); 258 camera_status_t getCameraIdList(ACameraIdList** cameraIdList); 259 static void deleteCameraIdList(ACameraIdList* cameraIdList); 260 261 camera_status_t getCameraCharacteristics( 262 const char* cameraId, android::sp<ACameraMetadata>* characteristics); 263 264 camera_status_t openCamera(const char* cameraId, 265 ACameraDevice_StateCallbacks* callback, 266 /*out*/ACameraDevice** device); 267 camera_status_t getTagFromName(const char *cameraId, const char *name, uint32_t *tag); 268 void registerAvailabilityCallback(const ACameraManager_AvailabilityCallbacks* callback); 269 void unregisterAvailabilityCallback(const ACameraManager_AvailabilityCallbacks* callback); 270 void registerExtendedAvailabilityCallback( 271 const ACameraManager_ExtendedAvailabilityCallbacks* callback); 272 void unregisterExtendedAvailabilityCallback( 273 const ACameraManager_ExtendedAvailabilityCallbacks* callback); 274 275 private: 276 enum { 277 kCameraIdListNotInit = -1 278 }; 279 android::Mutex mLock; 280 std::shared_ptr<android::acam::CameraManagerGlobal> mGlobalManager; 281 }; 282 283 #endif //_ACAMERA_MANAGER_H 284