1 /*
2 * Copyright (c) 2024 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 "avsession_users_manager.h"
17 #include "account_manager_adapter.h"
18 #include "avsession_utils.h"
19
20 namespace OHOS::AVSession {
GetInstance()21 AVSessionUsersManager& AVSessionUsersManager::GetInstance()
22 {
23 static AVSessionUsersManager usersManager;
24 return usersManager;
25 }
26
Init()27 void AVSessionUsersManager::Init()
28 {
29 std::lock_guard lockGuard(userLock_);
30 AccountManagerAdapter::GetInstance().Init();
31 AccountManagerAdapter::GetInstance().AddAccountEventsListener([this] (const std::string &type, const int &userId) {
32 SLOGI("get event for %{public}d with type %{public}s, curUser: %{public}d", userId, type.c_str(), curUserId_);
33 if (type == AccountManagerAdapter::accountEventSwitched) {
34 curUserId_ = userId;
35 auto it = std::find(aliveUsers_.begin(), aliveUsers_.end(), curUserId_);
36 if (it == aliveUsers_.end()) {
37 aliveUsers_.push_back(curUserId_);
38 }
39 } else if (type == AccountManagerAdapter::accountEventRemoved) {
40 HandleUserRemoved(userId);
41 }
42 });
43 curUserId_ = AccountManagerAdapter::GetInstance().GetCurrentAccountUserId();
44 aliveUsers_.push_back(curUserId_);
45 }
46
HandleUserRemoved(int32_t userId)47 void AVSessionUsersManager::HandleUserRemoved(int32_t userId)
48 {
49 std::lock_guard lockGuard(userLock_);
50 SLOGI("HandleUserRemoved for user %{public}d", userId);
51 auto iterForStack = sessionStackMapByUserId_.find(userId);
52 if (iterForStack != sessionStackMapByUserId_.end()) {
53 std::shared_ptr<SessionStack> stackPtr = iterForStack->second;
54 CHECK_AND_RETURN_LOG(stackPtr != nullptr, "HandleUserRemoved with nullptr stack error");
55 std::vector<sptr<AVSessionItem>> allSession = stackPtr->GetAllSessions();
56 for (auto& sessionItem : allSession) {
57 CHECK_AND_RETURN_LOG(sessionItem != nullptr, "HandleUserRemoved session null");
58 std::string sessionId = sessionItem->GetSessionId();
59 stackPtr->RemoveSession(sessionId);
60 GetContainerFromAll().RemoveSession(sessionId);
61 }
62 sessionStackMapByUserId_.erase(iterForStack);
63 }
64 auto iterForFrontList = frontSessionListMapByUserId_.find(userId);
65 if (iterForFrontList != frontSessionListMapByUserId_.end()) {
66 frontSessionListMapByUserId_.erase(iterForFrontList);
67 }
68 auto iter = keyEventListMapByUserId_.find(userId);
69 if (iter != keyEventListMapByUserId_.end()) {
70 keyEventListMapByUserId_.erase(iter);
71 }
72 auto iterForListenerMap = sessionListenersMapByUserId_.find(userId);
73 if (iterForListenerMap != sessionListenersMapByUserId_.end()) {
74 sessionListenersMapByUserId_.erase(iterForListenerMap);
75 }
76 auto iterForTop = topSessionsMapByUserId_.find(userId);
77 if (iterForTop != topSessionsMapByUserId_.end()) {
78 topSessionsMapByUserId_.erase(iterForTop);
79 }
80 aliveUsers_.remove_if([userId](int32_t element) { return element == userId; });
81 }
82
83
GetContainer()84 SessionStack& AVSessionUsersManager::GetContainer()
85 {
86 return GetContainerFromUser(curUserId_);
87 }
88
GetContainerFromUser(int32_t userId)89 SessionStack& AVSessionUsersManager::GetContainerFromUser(int32_t userId)
90 {
91 std::lock_guard lockGuard(userLock_);
92 std::shared_ptr<SessionStack> stackPtr = nullptr;
93 auto iter = sessionStackMapByUserId_.find(userId);
94 if (iter != sessionStackMapByUserId_.end()) {
95 stackPtr = iter->second;
96 } else {
97 SLOGI("create new stack for user %{public}d", userId);
98 stackPtr = std::make_shared<SessionStack>();
99 sessionStackMapByUserId_[userId] = stackPtr;
100 }
101 if (stackPtr == nullptr) {
102 SLOGE("error finding sessionStack ptr null, return default!");
103 static SessionStack sessionStack;
104 return sessionStack;
105 }
106 return *stackPtr;
107 }
108
GetContainerFromAll()109 SessionStack& AVSessionUsersManager::GetContainerFromAll()
110 {
111 if (sessionStackForAll_ == nullptr) {
112 sessionStackForAll_ = std::make_shared<SessionStack>();
113 }
114 return *sessionStackForAll_;
115 }
116
GetCurSessionListForFront(int32_t userId)117 std::shared_ptr<std::list<sptr<AVSessionItem>>> AVSessionUsersManager::GetCurSessionListForFront(int32_t userId)
118 {
119 std::lock_guard lockGuard(userLock_);
120 if (userId <= 0) {
121 userId = curUserId_;
122 }
123 std::shared_ptr<std::list<sptr<AVSessionItem>>> sessionListForFront = nullptr;
124 auto iterForFrontList = frontSessionListMapByUserId_.find(userId);
125 if (iterForFrontList != frontSessionListMapByUserId_.end()) {
126 sessionListForFront = iterForFrontList->second;
127 } else {
128 SLOGI("GetCurSessionListForFront without targetUser: %{public}d, create new", userId);
129 sessionListForFront = std::make_shared<std::list<sptr<AVSessionItem>>>();
130 frontSessionListMapByUserId_[userId] = sessionListForFront;
131 }
132 return sessionListForFront;
133 }
134
GetCurSessionListForKeyEvent(int32_t userId)135 std::shared_ptr<std::list<sptr<AVSessionItem>>> AVSessionUsersManager::GetCurSessionListForKeyEvent(int32_t userId)
136 {
137 std::lock_guard lockGuard(userLock_);
138 if (userId <= 0) {
139 userId = curUserId_;
140 }
141 std::shared_ptr<std::list<sptr<AVSessionItem>>> keyEventSessionList = nullptr;
142 auto it = keyEventListMapByUserId_.find(userId);
143 if (it != keyEventListMapByUserId_.end()) {
144 keyEventSessionList = it->second;
145 } else {
146 SLOGI("GetCurSessionListForKeyEvent without targetUser: %{public}d, create new", userId);
147 keyEventSessionList = std::make_shared<std::list<sptr<AVSessionItem>>>();
148 keyEventListMapByUserId_[userId] = keyEventSessionList;
149 }
150 return keyEventSessionList;
151 }
152
GetCurrentUserId()153 int32_t AVSessionUsersManager::GetCurrentUserId()
154 {
155 std::lock_guard lockGuard(userLock_);
156 return curUserId_;
157 }
158
GetDirForCurrentUser(int32_t userId)159 std::string AVSessionUsersManager::GetDirForCurrentUser(int32_t userId)
160 {
161 std::lock_guard lockGuard(userLock_);
162 if (curUserId_ < 0) {
163 return AVSESSION_FILE_PUBLIC_DIR;
164 } else if (userId <= 0) {
165 return AVSESSION_FILE_DIR_HEAD + std::to_string(curUserId_) + AVSESSION_FILE_DIR_TAIL;
166 } else {
167 SLOGI("GetDirForCurrentUser with specific userId:%{public}d", userId);
168 return AVSESSION_FILE_DIR_HEAD + std::to_string(userId) + AVSESSION_FILE_DIR_TAIL;
169 }
170 }
171
AddSessionForCurrentUser(pid_t pid,const std::string & abilityName,sptr<AVSessionItem> & item)172 int32_t AVSessionUsersManager::AddSessionForCurrentUser(pid_t pid,
173 const std::string& abilityName, sptr<AVSessionItem>& item)
174 {
175 std::lock_guard lockGuard(userLock_);
176 SLOGI("add session for user %{public}d", curUserId_);
177 int32_t ret = AVSESSION_ERROR;
178 ret = GetContainerFromAll().AddSession(pid, abilityName, item);
179 CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, ret, "error when add session for all");
180 ret = GetContainerFromUser(curUserId_).AddSession(pid, abilityName, item);
181 CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, ret, "error when add session for user");
182 return ret;
183 }
184
RemoveSessionForAllUser(pid_t pid,const std::string & abilityName)185 sptr<AVSessionItem> AVSessionUsersManager::RemoveSessionForAllUser(pid_t pid, const std::string& abilityName)
186 {
187 std::lock_guard lockGuard(userLock_);
188 sptr<AVSessionItem> result;
189 SLOGI("remove session for pid %{public}d,abilityName %{public}s", static_cast<int>(pid), abilityName.c_str());
190 result = GetContainerFromAll().RemoveSession(pid, abilityName);
191 CHECK_AND_RETURN_RET_LOG(result != nullptr, result, "remove session from all get nullptr");
192 std::string sessionId = result->GetSessionId();
193 int32_t userId = result->GetUserId();
194 GetContainerFromUser(userId).RemoveSession(pid, abilityName);
195 std::string fileName = AVSessionUtils::GetCachePathName(userId) + sessionId + AVSessionUtils::GetFileSuffix();
196 AVSessionUtils::DeleteFile(fileName);
197 return result;
198 }
199
RemoveSessionForAllUser(const std::string & sessionId)200 sptr<AVSessionItem> AVSessionUsersManager::RemoveSessionForAllUser(const std::string& sessionId)
201 {
202 std::lock_guard lockGuard(userLock_);
203 sptr<AVSessionItem> result;
204 SLOGI("remove session for sessionId %{public}s", AVSessionUtils::GetAnonySessionId(sessionId).c_str());
205 result = GetContainerFromAll().RemoveSession(sessionId);
206 CHECK_AND_RETURN_RET_LOG(result != nullptr, result, "remove session from all get nullptr");
207 int32_t userId = result->GetUserId();
208 GetContainerFromUser(userId).RemoveSession(sessionId);
209 std::string fileName = AVSessionUtils::GetCachePathName(userId) + sessionId + AVSessionUtils::GetFileSuffix();
210 AVSessionUtils::DeleteFile(fileName);
211 return result;
212 }
213
RemoveSessionForAllUser(pid_t pid)214 std::vector<sptr<AVSessionItem>> AVSessionUsersManager::RemoveSessionForAllUser(pid_t pid)
215 {
216 std::lock_guard lockGuard(userLock_);
217 SLOGI("remove session for only pid %{public}d", static_cast<int>(pid));
218 std::vector<sptr<AVSessionItem>> result;
219 result = GetContainerFromAll().GetSessionsByPid(pid);
220 for (auto& sessionItem : result) {
221 CHECK_AND_RETURN_RET_LOG(sessionItem != nullptr, result, "RemoveSessionForAllUser session null");
222 std::string sessionId = sessionItem->GetSessionId();
223 int32_t userId = sessionItem->GetUserId();
224 GetContainerFromUser(userId).RemoveSession(sessionId);
225 GetContainerFromAll().RemoveSession(sessionId);
226 }
227 return result;
228 }
229
AddSessionListener(pid_t pid,const sptr<ISessionListener> & listener)230 void AVSessionUsersManager::AddSessionListener(pid_t pid, const sptr<ISessionListener>& listener)
231 {
232 std::lock_guard lockGuard(userLock_);
233 SLOGI("add sessionListener for pid %{public}d, curUser %{public}d", static_cast<int>(pid), curUserId_);
234 auto iterForListenerMap = sessionListenersMapByUserId_.find(curUserId_);
235 if (iterForListenerMap != sessionListenersMapByUserId_.end()) {
236 (iterForListenerMap->second)[pid] = listener;
237 } else {
238 std::map<pid_t, sptr<ISessionListener>> listenerMap;
239 listenerMap[pid] = listener;
240 sessionListenersMapByUserId_[curUserId_] = listenerMap;
241 }
242 }
243
AddSessionListenerForAllUsers(pid_t pid,const sptr<ISessionListener> & listener)244 void AVSessionUsersManager::AddSessionListenerForAllUsers(pid_t pid, const sptr<ISessionListener>& listener)
245 {
246 std::lock_guard lockGuard(userLock_);
247 SLOGI("add sessionListener for pid %{public}d, for all users", static_cast<int>(pid));
248 sessionListenersMap_[pid] = listener;
249 }
250
RemoveSessionListener(pid_t pid)251 void AVSessionUsersManager::RemoveSessionListener(pid_t pid)
252 {
253 std::lock_guard lockGuard(userLock_);
254 for (auto& listenersMapByUserIdPair : sessionListenersMapByUserId_) {
255 int32_t userId = listenersMapByUserIdPair.first;
256 auto iterForListenersMapByUserId = (listenersMapByUserIdPair.second).find(pid);
257 if (iterForListenersMapByUserId != (listenersMapByUserIdPair.second).end()) {
258 SLOGI("remove sessionListener for pid:%{public}d, targetUser:%{public}d", static_cast<int>(pid), userId);
259 (listenersMapByUserIdPair.second).erase(iterForListenersMapByUserId);
260 }
261 }
262 sessionListenersMap_.erase(pid);
263 SLOGI("remove sessionListener for pid %{public}d, curUser %{public}d", static_cast<int>(pid), curUserId_);
264 }
265
GetSessionListener(int32_t userId)266 std::map<pid_t, sptr<ISessionListener>>& AVSessionUsersManager::GetSessionListener(int32_t userId)
267 {
268 std::lock_guard lockGuard(userLock_);
269 userId = userId <= 0 ? curUserId_ : userId;
270 auto iterForListenerMap = sessionListenersMapByUserId_.find(userId);
271 if (iterForListenerMap != sessionListenersMapByUserId_.end()) {
272 return iterForListenerMap->second;
273 } else {
274 std::map<pid_t, sptr<ISessionListener>> listenerMap;
275 sessionListenersMapByUserId_[userId] = listenerMap;
276 SLOGI("get sessionListenerMap null, create new for user %{public}d", userId);
277 return sessionListenersMapByUserId_[userId];
278 }
279 }
280
GetSessionListenerForAllUsers()281 std::map<pid_t, sptr<ISessionListener>>& AVSessionUsersManager::GetSessionListenerForAllUsers()
282 {
283 return sessionListenersMap_;
284 }
285
NotifyAccountsEvent(const std::string & type,const int & userId)286 void AVSessionUsersManager::NotifyAccountsEvent(const std::string &type, const int &userId)
287 {
288 std::lock_guard lockGuard(userLock_);
289 // lock for AccountEventsListener callback
290 AccountManagerAdapter::GetInstance().HandleAccountsEvent(type, userId);
291 }
292
SetTopSession(sptr<AVSessionItem> session)293 void AVSessionUsersManager::SetTopSession(sptr<AVSessionItem> session)
294 {
295 SetTopSession(session, curUserId_);
296 }
297
SetTopSession(sptr<AVSessionItem> session,int32_t userId)298 void AVSessionUsersManager::SetTopSession(sptr<AVSessionItem> session, int32_t userId)
299 {
300 std::lock_guard lockGuard(userLock_);
301 topSessionsMapByUserId_[userId] = session;
302 }
303
GetTopSession()304 sptr<AVSessionItem> AVSessionUsersManager::GetTopSession()
305 {
306 return GetTopSession(curUserId_);
307 }
308
GetTopSession(int32_t userId)309 sptr<AVSessionItem> AVSessionUsersManager::GetTopSession(int32_t userId)
310 {
311 std::lock_guard lockGuard(userLock_);
312 auto iterForTop = topSessionsMapByUserId_.find(userId);
313 if (iterForTop != topSessionsMapByUserId_.end()) {
314 return iterForTop->second;
315 }
316 return nullptr;
317 }
318
ClearCache()319 void AVSessionUsersManager::ClearCache()
320 {
321 std::lock_guard lockGuard(userLock_);
322 for (const auto& userId : aliveUsers_) {
323 std::string cachePath(AVSessionUtils::GetCachePathName(userId));
324 AVSessionUtils::DeleteCacheFiles(cachePath);
325 }
326 }
327 }
328