1 /* 2 * Copyright (C) 2023 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 #pragma once 18 19 #include "ConfigManager.h" 20 #include "EvsCameraBase.h" 21 #include "EvsGlDisplay.h" 22 23 #include <aidl/android/frameworks/automotive/display/ICarDisplayProxy.h> 24 #include <aidl/android/hardware/automotive/evs/BnEvsEnumerator.h> 25 #include <aidl/android/hardware/automotive/evs/CameraDesc.h> 26 #include <aidl/android/hardware/automotive/evs/DeviceStatusType.h> 27 #include <aidl/android/hardware/automotive/evs/IEvsCamera.h> 28 #include <aidl/android/hardware/automotive/evs/IEvsEnumeratorStatusCallback.h> 29 #include <aidl/android/hardware/automotive/evs/Stream.h> 30 #include <android-base/thread_annotations.h> 31 #include <utils/Thread.h> 32 33 #include <atomic> 34 #include <mutex> 35 #include <optional> 36 #include <thread> 37 #include <unordered_map> 38 39 namespace aidl::android::hardware::automotive::evs::implementation { 40 41 class EvsEnumerator final : public ::aidl::android::hardware::automotive::evs::BnEvsEnumerator { 42 public: 43 // Methods from ::aidl::android::hardware::automotive::evs::IEvsEnumerator 44 ndk::ScopedAStatus isHardware(bool* flag) override; 45 ndk::ScopedAStatus openCamera(const std::string& cameraId, const evs::Stream& streamConfig, 46 std::shared_ptr<evs::IEvsCamera>* obj) override; 47 ndk::ScopedAStatus closeCamera(const std::shared_ptr<evs::IEvsCamera>& obj) override; 48 ndk::ScopedAStatus getCameraList(std::vector<evs::CameraDesc>* _aidl_return) override; 49 ndk::ScopedAStatus getStreamList(const evs::CameraDesc& desc, 50 std::vector<evs::Stream>* _aidl_return) override; 51 ndk::ScopedAStatus openDisplay(int32_t displayId, 52 std::shared_ptr<evs::IEvsDisplay>* obj) override; 53 ndk::ScopedAStatus closeDisplay(const std::shared_ptr<evs::IEvsDisplay>& obj) override; 54 ndk::ScopedAStatus getDisplayIdList(std::vector<uint8_t>* list) override; 55 ndk::ScopedAStatus getDisplayState(evs::DisplayState* state) override; 56 ndk::ScopedAStatus getDisplayStateById(int32_t displayId, evs::DisplayState* state) override; 57 ndk::ScopedAStatus registerStatusCallback( 58 const std::shared_ptr<evs::IEvsEnumeratorStatusCallback>& callback) override; 59 ndk::ScopedAStatus openUltrasonicsArray( 60 const std::string& id, std::shared_ptr<evs::IEvsUltrasonicsArray>* obj) override; 61 ndk::ScopedAStatus closeUltrasonicsArray( 62 const std::shared_ptr<evs::IEvsUltrasonicsArray>& obj) override; 63 ndk::ScopedAStatus getUltrasonicsArrayList( 64 std::vector<evs::UltrasonicsArrayDesc>* list) override; 65 66 // Implementation details 67 EvsEnumerator(const std::shared_ptr< 68 ::aidl::android::frameworks::automotive::display::ICarDisplayProxy>& 69 proxyService); 70 71 void notifyDeviceStatusChange(const std::string_view& deviceName, evs::DeviceStatusType type); 72 73 private: 74 struct CameraRecord { 75 evs::CameraDesc desc; 76 std::weak_ptr<EvsCameraBase> activeInstance; 77 CameraRecordCameraRecord78 CameraRecord(const char* cameraId) : desc() { desc.id = cameraId; } 79 }; 80 81 class ActiveDisplays { 82 public: 83 struct DisplayInfo { 84 int32_t id{-1}; 85 std::weak_ptr<EvsGlDisplay> displayWeak; 86 uintptr_t internalDisplayRawAddr; 87 }; 88 89 std::optional<DisplayInfo> popDisplay(int32_t id); 90 91 std::optional<DisplayInfo> popDisplay(const std::shared_ptr<IEvsDisplay>& display); 92 93 std::unordered_map<int32_t, DisplayInfo> getAllDisplays(); 94 95 bool tryInsert(int32_t id, const std::shared_ptr<EvsGlDisplay>& display); 96 97 private: 98 std::mutex mMutex; 99 std::unordered_map<int32_t, DisplayInfo> mIdToDisplay GUARDED_BY(mMutex); 100 std::unordered_map<uintptr_t, int32_t> mDisplayToId GUARDED_BY(mMutex); 101 }; 102 103 bool checkPermission(); 104 void closeCamera_impl(const std::shared_ptr<evs::IEvsCamera>& pCamera, 105 const std::string& cameraId); 106 ndk::ScopedAStatus getDisplayStateImpl(std::optional<int32_t> displayId, 107 evs::DisplayState* state); 108 109 static bool qualifyCaptureDevice(const char* deviceName); 110 static CameraRecord* findCameraById(const std::string& cameraId); 111 static void enumerateCameras(); 112 static bool addCaptureDevice(const std::string& deviceName); 113 static bool removeCaptureDevice(const std::string& deviceName); 114 // Enumerate available displays and return an id of the internal display 115 static uint64_t enumerateDisplays(); 116 117 static ActiveDisplays& mutableActiveDisplays(); 118 119 // NOTE: All members values are static so that all clients operate on the same state 120 // That is to say, this is effectively a singleton despite the fact that HIDL 121 // constructs a new instance for each client. 122 // Because our server has a single thread in the thread pool, these values are 123 // never accessed concurrently despite potentially having multiple instance objects 124 // using them. 125 static std::unordered_map<std::string, CameraRecord> sCameraList; 126 // Object destructs if client dies. 127 static std::mutex sLock; // Mutex on shared camera device list. 128 static std::condition_variable sCameraSignal; // Signal on camera device addition. 129 static std::unique_ptr<ConfigManager> sConfigManager; // ConfigManager 130 static std::shared_ptr<::aidl::android::frameworks::automotive::display::ICarDisplayProxy> 131 sDisplayProxy; 132 static std::unordered_map<uint8_t, uint64_t> sDisplayPortList; 133 134 uint64_t mInternalDisplayId; 135 std::shared_ptr<evs::IEvsEnumeratorStatusCallback> mCallback; 136 }; 137 138 } // namespace aidl::android::hardware::automotive::evs::implementation 139