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