• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)34 static 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()42 size_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()52 size_t HCameraSessionManager::GetGroupCount()
53 {
54     std::lock_guard<std::mutex> lock(totalSessionMapMutex_);
55     return totalSessionMap_.size();
56 }
57 
GetSessionSize(pid_t pid)58 size_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()67 std::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)79 std::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)93 sptr<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)107 CamServiceError 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)123 void 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)145 void 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)175 void 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)185 void HCameraSessionManager::RemoveGroupNoLock(std::unordered_map<pid_t, SessionGroup>::iterator mapIt)
186 {
187     totalSessionMap_.erase(mapIt);
188 }
189 } // namespace CameraStandard
190 } // namespace OHOS
191