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
20namespace OHOS::AVSession {
21AVSessionUsersManager& AVSessionUsersManager::GetInstance()
22{
23    static AVSessionUsersManager usersManager;
24    return usersManager;
25}
26
27void 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
47void 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
80SessionStack& AVSessionUsersManager::GetContainer()
81{
82    return GetContainerFromUser(curUserId_);
83}
84
85SessionStack& 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
105SessionStack& AVSessionUsersManager::GetContainerFromAll()
106{
107    if (sessionStackForAll_ == nullptr) {
108        sessionStackForAll_ = std::make_shared<SessionStack>();
109    }
110    return *sessionStackForAll_;
111}
112
113std::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
128int32_t AVSessionUsersManager::GetCurrentUserId()
129{
130    std::lock_guard lockGuard(userLock_);
131    return curUserId_;
132}
133
134std::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
147int32_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
160sptr<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
175sptr<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
189std::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
205void 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
219void 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
226void 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
237std::map<pid_t, sptr<ISessionListener>>& AVSessionUsersManager::GetSessionListener()
238{
239    return GetSessionListenerForCurUser();
240}
241
242std::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
256std::map<pid_t, sptr<ISessionListener>>& AVSessionUsersManager::GetSessionListenerForAllUsers()
257{
258    return sessionListenersMap_;
259}
260
261void 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
268void AVSessionUsersManager::SetTopSession(sptr<AVSessionItem> session)
269{
270    SetTopSession(session, curUserId_);
271}
272
273void AVSessionUsersManager::SetTopSession(sptr<AVSessionItem> session, int32_t userId)
274{
275    std::lock_guard lockGuard(userLock_);
276    topSessionsMapByUserId_[userId] = session;
277}
278
279sptr<AVSessionItem> AVSessionUsersManager::GetTopSession()
280{
281    return GetTopSession(curUserId_);
282}
283
284sptr<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
294void 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