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 iterForListenerMap = sessionListenersMapByUserId_.find(userId);
69     if (iterForListenerMap != sessionListenersMapByUserId_.end()) {
70         sessionListenersMapByUserId_.erase(iterForListenerMap);
71     }
72     auto iterForTop = topSessionsMapByUserId_.find(userId);
73     if (iterForTop != topSessionsMapByUserId_.end()) {
74         topSessionsMapByUserId_.erase(iterForTop);
75     }
76     aliveUsers_.remove_if([userId](int32_t element) { return element == userId; });
77 }
78 
79 
GetContainer()80 SessionStack& AVSessionUsersManager::GetContainer()
81 {
82     return GetContainerFromUser(curUserId_);
83 }
84 
GetContainerFromUser(int32_t userId)85 SessionStack& AVSessionUsersManager::GetContainerFromUser(int32_t userId)
86 {
87     std::lock_guard lockGuard(userLock_);
88     std::shared_ptr<SessionStack> stackPtr = nullptr;
89     auto iter = sessionStackMapByUserId_.find(userId);
90     if (iter != sessionStackMapByUserId_.end()) {
91         stackPtr = iter->second;
92     } else {
93         SLOGI("create new stack for user %{public}d", userId);
94         stackPtr = std::make_shared<SessionStack>();
95         sessionStackMapByUserId_[userId] = stackPtr;
96     }
97     if (stackPtr == nullptr) {
98         SLOGE("error finding sessionStack ptr null, return default!");
99         static SessionStack sessionStack;
100         return sessionStack;
101     }
102     return *stackPtr;
103 }
104 
GetContainerFromAll()105 SessionStack& AVSessionUsersManager::GetContainerFromAll()
106 {
107     if (sessionStackForAll_ == nullptr) {
108         sessionStackForAll_ = std::make_shared<SessionStack>();
109     }
110     return *sessionStackForAll_;
111 }
112 
GetCurSessionListForFront()113 std::shared_ptr<std::list<sptr<AVSessionItem>>> AVSessionUsersManager::GetCurSessionListForFront()
114 {
115     std::lock_guard lockGuard(userLock_);
116     std::shared_ptr<std::list<sptr<AVSessionItem>>> sessionListForFront = nullptr;
117     auto iterForFrontList = frontSessionListMapByUserId_.find(curUserId_);
118     if (iterForFrontList != frontSessionListMapByUserId_.end()) {
119         sessionListForFront = iterForFrontList->second;
120     } else {
121         SLOGI("GetCurSessionListForFront without curUser: %{public}d, create new", curUserId_);
122         sessionListForFront = std::make_shared<std::list<sptr<AVSessionItem>>>();
123         frontSessionListMapByUserId_[curUserId_] = sessionListForFront;
124     }
125     return sessionListForFront;
126 }
127 
GetCurrentUserId()128 int32_t AVSessionUsersManager::GetCurrentUserId()
129 {
130     std::lock_guard lockGuard(userLock_);
131     return curUserId_;
132 }
133 
GetDirForCurrentUser(int32_t userId)134 std::string AVSessionUsersManager::GetDirForCurrentUser(int32_t userId)
135 {
136     std::lock_guard lockGuard(userLock_);
137     if (curUserId_ < 0) {
138         return AVSESSION_FILE_PUBLIC_DIR;
139     } else if (userId <= 0) {
140         return AVSESSION_FILE_DIR_HEAD + std::to_string(curUserId_) + AVSESSION_FILE_DIR_TAIL;
141     } else {
142         SLOGI("GetDirForCurrentUser with specific userId:%{public}d", userId);
143         return AVSESSION_FILE_DIR_HEAD + std::to_string(userId) + AVSESSION_FILE_DIR_TAIL;
144     }
145 }
146 
AddSessionForCurrentUser(pid_t pid,const std::string & abilityName,sptr<AVSessionItem> & item)147 int32_t AVSessionUsersManager::AddSessionForCurrentUser(pid_t pid,
148     const std::string& abilityName, sptr<AVSessionItem>& item)
149 {
150     std::lock_guard lockGuard(userLock_);
151     SLOGI("add session for user %{public}d", curUserId_);
152     int32_t ret = AVSESSION_ERROR;
153     ret = GetContainerFromAll().AddSession(pid, abilityName, item);
154     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, ret, "error when add session for all");
155     ret = GetContainerFromUser(curUserId_).AddSession(pid, abilityName, item);
156     CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, ret, "error when add session for user");
157     return ret;
158 }
159 
RemoveSessionForAllUser(pid_t pid,const std::string & abilityName)160 sptr<AVSessionItem> AVSessionUsersManager::RemoveSessionForAllUser(pid_t pid, const std::string& abilityName)
161 {
162     std::lock_guard lockGuard(userLock_);
163     sptr<AVSessionItem> result;
164     SLOGI("remove session for pid %{public}d,abilityName %{public}s", static_cast<int>(pid), abilityName.c_str());
165     result = GetContainerFromAll().RemoveSession(pid, abilityName);
166     CHECK_AND_RETURN_RET_LOG(result != nullptr, result, "remove session from all get nullptr");
167     std::string sessionId = result->GetSessionId();
168     int32_t userId = result->GetUserId();
169     GetContainerFromUser(userId).RemoveSession(pid, abilityName);
170     std::string fileName = AVSessionUtils::GetCachePathName(userId) + sessionId + AVSessionUtils::GetFileSuffix();
171     AVSessionUtils::DeleteFile(fileName);
172     return result;
173 }
174 
RemoveSessionForAllUser(const std::string & sessionId)175 sptr<AVSessionItem> AVSessionUsersManager::RemoveSessionForAllUser(const std::string& sessionId)
176 {
177     std::lock_guard lockGuard(userLock_);
178     sptr<AVSessionItem> result;
179     SLOGI("remove session for sessionId %{public}s", AVSessionUtils::GetAnonySessionId(sessionId).c_str());
180     result = GetContainerFromAll().RemoveSession(sessionId);
181     CHECK_AND_RETURN_RET_LOG(result != nullptr, result, "remove session from all get nullptr");
182     int32_t userId = result->GetUserId();
183     GetContainerFromUser(userId).RemoveSession(sessionId);
184     std::string fileName = AVSessionUtils::GetCachePathName(userId) + sessionId + AVSessionUtils::GetFileSuffix();
185     AVSessionUtils::DeleteFile(fileName);
186     return result;
187 }
188 
RemoveSessionForAllUser(pid_t pid)189 std::vector<sptr<AVSessionItem>> AVSessionUsersManager::RemoveSessionForAllUser(pid_t pid)
190 {
191     std::lock_guard lockGuard(userLock_);
192     SLOGI("remove session for only pid %{public}d", static_cast<int>(pid));
193     std::vector<sptr<AVSessionItem>> result;
194     result = GetContainerFromAll().GetSessionsByPid(pid);
195     for (auto& sessionItem : result) {
196         CHECK_AND_RETURN_RET_LOG(sessionItem != nullptr, result, "RemoveSessionForAllUser session null");
197         std::string sessionId = sessionItem->GetSessionId();
198         int32_t userId = sessionItem->GetUserId();
199         GetContainerFromUser(userId).RemoveSession(sessionId);
200         GetContainerFromAll().RemoveSession(sessionId);
201     }
202     return result;
203 }
204 
AddSessionListener(pid_t pid,const sptr<ISessionListener> & listener)205 void AVSessionUsersManager::AddSessionListener(pid_t pid, const sptr<ISessionListener>& listener)
206 {
207     std::lock_guard lockGuard(userLock_);
208     SLOGI("add sessionListener for pid %{public}d, curUser %{public}d", static_cast<int>(pid), curUserId_);
209     auto iterForListenerMap = sessionListenersMapByUserId_.find(curUserId_);
210     if (iterForListenerMap != sessionListenersMapByUserId_.end()) {
211         (iterForListenerMap->second)[pid] = listener;
212     } else {
213         std::map<pid_t, sptr<ISessionListener>> listenerMap;
214         listenerMap[pid] = listener;
215         sessionListenersMapByUserId_[curUserId_] = listenerMap;
216     }
217 }
218 
AddSessionListenerForAllUsers(pid_t pid,const sptr<ISessionListener> & listener)219 void AVSessionUsersManager::AddSessionListenerForAllUsers(pid_t pid, const sptr<ISessionListener>& listener)
220 {
221     std::lock_guard lockGuard(userLock_);
222     SLOGI("add sessionListener for pid %{public}d, for all users", static_cast<int>(pid));
223     sessionListenersMap_[pid] = listener;
224 }
225 
RemoveSessionListener(pid_t pid)226 void AVSessionUsersManager::RemoveSessionListener(pid_t pid)
227 {
228     std::lock_guard lockGuard(userLock_);
229     SLOGI("remove sessionListener for pid %{public}d, curUser %{public}d", static_cast<int>(pid), curUserId_);
230     auto iterForListenerMap = sessionListenersMapByUserId_.find(curUserId_);
231     if (iterForListenerMap != sessionListenersMapByUserId_.end()) {
232         (iterForListenerMap->second).erase(pid);
233     }
234     sessionListenersMap_.erase(pid);
235 }
236 
GetSessionListener()237 std::map<pid_t, sptr<ISessionListener>>& AVSessionUsersManager::GetSessionListener()
238 {
239     return GetSessionListenerForCurUser();
240 }
241 
GetSessionListenerForCurUser()242 std::map<pid_t, sptr<ISessionListener>>& AVSessionUsersManager::GetSessionListenerForCurUser()
243 {
244     std::lock_guard lockGuard(userLock_);
245     auto iterForListenerMap = sessionListenersMapByUserId_.find(curUserId_);
246     if (iterForListenerMap != sessionListenersMapByUserId_.end()) {
247         return iterForListenerMap->second;
248     } else {
249         std::map<pid_t, sptr<ISessionListener>> listenerMap;
250         sessionListenersMapByUserId_[curUserId_] = listenerMap;
251         SLOGI("get session listener map with null, create new map and return for user %{public}d", curUserId_);
252         return sessionListenersMapByUserId_[curUserId_];
253     }
254 }
255 
GetSessionListenerForAllUsers()256 std::map<pid_t, sptr<ISessionListener>>& AVSessionUsersManager::GetSessionListenerForAllUsers()
257 {
258     return sessionListenersMap_;
259 }
260 
NotifyAccountsEvent(const std::string & type,const int & userId)261 void AVSessionUsersManager::NotifyAccountsEvent(const std::string &type, const int &userId)
262 {
263     std::lock_guard lockGuard(userLock_);
264     // lock for AccountEventsListener callback
265     AccountManagerAdapter::GetInstance().HandleAccountsEvent(type, userId);
266 }
267 
SetTopSession(sptr<AVSessionItem> session)268 void AVSessionUsersManager::SetTopSession(sptr<AVSessionItem> session)
269 {
270     SetTopSession(session, curUserId_);
271 }
272 
SetTopSession(sptr<AVSessionItem> session,int32_t userId)273 void AVSessionUsersManager::SetTopSession(sptr<AVSessionItem> session, int32_t userId)
274 {
275     std::lock_guard lockGuard(userLock_);
276     topSessionsMapByUserId_[userId] = session;
277 }
278 
GetTopSession()279 sptr<AVSessionItem> AVSessionUsersManager::GetTopSession()
280 {
281     return GetTopSession(curUserId_);
282 }
283 
GetTopSession(int32_t userId)284 sptr<AVSessionItem> AVSessionUsersManager::GetTopSession(int32_t userId)
285 {
286     std::lock_guard lockGuard(userLock_);
287     auto iterForTop = topSessionsMapByUserId_.find(userId);
288     if (iterForTop != topSessionsMapByUserId_.end()) {
289         return iterForTop->second;
290     }
291     return nullptr;
292 }
293 
ClearCache()294 void AVSessionUsersManager::ClearCache()
295 {
296     std::lock_guard lockGuard(userLock_);
297     for (const auto& userId : aliveUsers_) {
298         std::string cachePath(AVSessionUtils::GetCachePathName(userId));
299         AVSessionUtils::DeleteCacheFiles(cachePath);
300     }
301 }
302 }
303