1 /* 2 * Copyright (c) 2025-2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #include "hcamera_session_manager.h" 17 18 #include <cstddef> 19 #include <cstdint> 20 #include <mutex> 21 #include <sched.h> 22 23 #include "camera_dynamic_loader.h" 24 #include "camera_util.h" 25 #include "hcamera_device_manager.h" 26 #include "hcapture_session.h" 27 #include "parameters.h" 28 29 namespace OHOS { 30 namespace CameraStandard { 31 static const int32_t GROUP_SIZE_MIN_LIMIT = 1; // Default session min size is 1 32 static const int32_t GROUP_SIZE_MAX_LIMIT = 10; // Default session max size is 10 33 GetGroupSizeLimit(pid_t pid)34static size_t GetGroupSizeLimit(pid_t pid) 35 { 36 if (HCameraDeviceManager::GetInstance()->IsProcessHasConcurrentDevice(pid)) { 37 return GROUP_SIZE_MAX_LIMIT; 38 } 39 return GROUP_SIZE_MIN_LIMIT; 40 } 41 GetTotalSessionSize()42size_t HCameraSessionManager::GetTotalSessionSize() 43 { 44 std::lock_guard<std::mutex> lock(totalSessionMapMutex_); 45 size_t totalSize = 0; 46 for (auto& it : totalSessionMap_) { 47 totalSize += it.second.size(); 48 } 49 return totalSize; 50 } 51 GetGroupCount()52size_t HCameraSessionManager::GetGroupCount() 53 { 54 std::lock_guard<std::mutex> lock(totalSessionMapMutex_); 55 return totalSessionMap_.size(); 56 } 57 GetSessionSize(pid_t pid)58size_t HCameraSessionManager::GetSessionSize(pid_t pid) 59 { 60 std::lock_guard<std::mutex> lock(totalSessionMapMutex_); 61 auto it = totalSessionMap_.find(pid); 62 if (it != totalSessionMap_.end()) { 63 return it->second.size(); 64 } 65 return 0; 66 } GetTotalSession()67std::list<sptr<HCaptureSession>> HCameraSessionManager::GetTotalSession() 68 { 69 std::list<sptr<HCaptureSession>> totalList {}; 70 std::lock_guard<std::mutex> lock(totalSessionMapMutex_); 71 for (auto& mapIt : totalSessionMap_) { 72 for (auto& listIt : mapIt.second) { 73 totalList.emplace_back(listIt); 74 } 75 } 76 return totalList; 77 } 78 GetGroupSessions(pid_t pid)79std::list<sptr<HCaptureSession>> HCameraSessionManager::GetGroupSessions(pid_t pid) 80 { 81 std::list<sptr<HCaptureSession>> totalList {}; 82 std::lock_guard<std::mutex> lock(totalSessionMapMutex_); 83 auto mapIt = totalSessionMap_.find(pid); 84 if (mapIt == totalSessionMap_.end()) { 85 return totalList; 86 } 87 for (auto& listIt : mapIt->second) { 88 totalList.emplace_back(listIt); 89 } 90 return totalList; 91 } 92 GetGroupDefaultSession(pid_t pid)93sptr<HCaptureSession> HCameraSessionManager::GetGroupDefaultSession(pid_t pid) 94 { 95 std::lock_guard<std::mutex> lock(totalSessionMapMutex_); 96 auto mapIt = totalSessionMap_.find(pid); 97 if (mapIt == totalSessionMap_.end()) { 98 return nullptr; 99 } 100 auto& list = mapIt->second; 101 if (list.empty()) { 102 return nullptr; 103 } 104 return list.front(); 105 } 106 AddSession(sptr<HCaptureSession> session)107CamServiceError HCameraSessionManager::AddSession(sptr<HCaptureSession> session) 108 { 109 if (session == nullptr) { 110 return CAMERA_INVALID_ARG; 111 } 112 auto pid = session->GetPid(); 113 std::lock_guard<std::mutex> lock(totalSessionMapMutex_); 114 auto& list = totalSessionMap_[pid]; 115 list.emplace_back(session); 116 117 if (list.size() > GetGroupSizeLimit(pid)) { 118 return CAMERA_SESSION_MAX_INSTANCE_NUMBER_REACHED; 119 } 120 return CAMERA_OK; 121 } 122 RemoveSession(sptr<HCaptureSession> session)123void HCameraSessionManager::RemoveSession(sptr<HCaptureSession> session) 124 { 125 if (session == nullptr) { 126 return; 127 } 128 std::lock_guard<std::mutex> lock(totalSessionMapMutex_); 129 auto mapIt = totalSessionMap_.find(session->GetPid()); 130 if (mapIt == totalSessionMap_.end()) { 131 return; 132 } 133 auto& list = mapIt->second; 134 for (auto listIt = list.begin(); listIt != list.end(); listIt++) { 135 if (session == *listIt) { 136 list.erase(listIt); 137 break; 138 } 139 } 140 if (list.empty()) { 141 RemoveGroupNoLock(mapIt); 142 } 143 } 144 PreemptOverflowSessions(pid_t pid)145void HCameraSessionManager::PreemptOverflowSessions(pid_t pid) 146 { 147 size_t limitSize = GetGroupSizeLimit(pid); 148 std::vector<sptr<HCaptureSession>> overflowSessions = {}; 149 { 150 std::lock_guard<std::mutex> lock(totalSessionMapMutex_); 151 auto mapIt = totalSessionMap_.find(pid); 152 if (mapIt == totalSessionMap_.end()) { 153 return; 154 } 155 auto& list = mapIt->second; 156 size_t currentListSize = list.size(); 157 if (currentListSize <= limitSize) { 158 return; 159 } 160 size_t overflowSize = currentListSize - limitSize; 161 for (size_t i = 0; i < overflowSize; i++) { 162 auto previousSession = list.front(); 163 overflowSessions.emplace_back(previousSession); 164 list.pop_front(); 165 } 166 if (list.empty()) { 167 RemoveGroupNoLock(mapIt); 168 } 169 } 170 for (auto& session : overflowSessions) { 171 session->OnSessionPreempt(); 172 } 173 } 174 RemoveGroup(pid_t pid)175void HCameraSessionManager::RemoveGroup(pid_t pid) 176 { 177 std::lock_guard<std::mutex> lock(totalSessionMapMutex_); 178 auto mapIt = totalSessionMap_.find(pid); 179 if (mapIt == totalSessionMap_.end()) { 180 return; 181 } 182 RemoveGroupNoLock(mapIt); 183 } 184 RemoveGroupNoLock(std::unordered_map<pid_t,SessionGroup>::iterator mapIt)185void HCameraSessionManager::RemoveGroupNoLock(std::unordered_map<pid_t, SessionGroup>::iterator mapIt) 186 { 187 totalSessionMap_.erase(mapIt); 188 } 189 } // namespace CameraStandard 190 } // namespace OHOS 191