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