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 "account_subscriber.h"
17 #include "bundle_info.h"
18 #include "common_event_manager.h"
19 #include "want.h"
20 #include "media_log.h"
21
22 namespace OHOS {
23 namespace Media {
24 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_PLAYER, "AccountSubscriber"};
25 std::shared_ptr<AccountSubscriber> AccountSubscriber::instance_ = nullptr;
26
GetInstance()27 std::shared_ptr<AccountSubscriber> AccountSubscriber::GetInstance()
28 {
29 if (instance_ == nullptr) {
30 static std::mutex instanceMutex;
31 std::lock_guard<std::mutex> lock(instanceMutex);
32 if (instance_ == nullptr) {
33 EventFwk::MatchingSkills matchingSkills;
34 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_BACKGROUND);
35 EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills);
36 instance_ = std::make_shared<AccountSubscriber>(subscribeInfo);
37 }
38 }
39 return instance_;
40 }
41
AccountSubscriber(const EventFwk::CommonEventSubscribeInfo & subscribeInfo)42 AccountSubscriber::AccountSubscriber(const EventFwk::CommonEventSubscribeInfo &subscribeInfo)
43 : EventFwk::CommonEventSubscriber(subscribeInfo)
44 {
45 MEDIA_LOGI("create instance");
46 }
47
~AccountSubscriber()48 AccountSubscriber::~AccountSubscriber()
49 {
50 std::lock_guard<std::mutex> lock(userMutex_);
51 userMap_.clear();
52 MEDIA_LOGI("free instance");
53 }
54
DispatchEvent(int32_t userId,const std::string & action)55 void AccountSubscriber::DispatchEvent(int32_t userId, const std::string &action)
56 {
57 std::lock_guard<std::mutex> lock(userMutex_);
58 auto mapIt = userMap_.find(userId);
59 if (mapIt == userMap_.end()) {
60 return;
61 }
62 for (auto receiver : mapIt->second) {
63 if (receiver) {
64 receiver->OnCommonEventReceived(action);
65 }
66 }
67 }
68
OnReceiveEvent(const EventFwk::CommonEventData & eventData)69 void AccountSubscriber::OnReceiveEvent(const EventFwk::CommonEventData &eventData)
70 {
71 const AAFwk::Want& want = eventData.GetWant();
72 std::string action = want.GetAction();
73 int32_t userId = eventData.GetCode();
74 MEDIA_LOGI("receive action %{public}s, userId %{public}u", action.c_str(), userId);
75 if (action == EventFwk::CommonEventSupport::COMMON_EVENT_USER_BACKGROUND) {
76 // prevent dead lock caused by NewUnSubscribeCommonEvent and OnReceiveEvent run parallelly.
77 std::shared_ptr<AccountSubscriber> subscriber = shared_from_this();
78 std::thread([subscriber, userId, action]() -> void {
79 MEDIA_LOGI("dispatch event action %{public}s, userId %{public}d", action.c_str(), userId);
80 subscriber->DispatchEvent(userId, action);
81 }).detach();
82 }
83 }
84
RegisterCommonEventReceiver(int32_t userId,const std::shared_ptr<CommonEventReceiver> & receiver)85 void AccountSubscriber::RegisterCommonEventReceiver(int32_t userId,
86 const std::shared_ptr<CommonEventReceiver> &receiver)
87 {
88 MEDIA_LOGI("receiver is 0x%{public}06" PRIXPTR ", userId %{public}d", FAKE_POINTER(receiver.get()), userId);
89 if (userId < 0 || receiver == nullptr) {
90 return;
91 }
92 std::lock_guard<std::mutex> lock(userMutex_);
93 if (userMap_.empty()) {
94 EventFwk::CommonEventManager::NewSubscribeCommonEvent(instance_);
95 MEDIA_LOGI("first register receiver, SubscribeCommonEvent");
96 }
97 auto mapIt = userMap_.find(userId);
98 if (mapIt == userMap_.end()) {
99 std::vector<std::shared_ptr<CommonEventReceiver>> vct;
100 vct.push_back(receiver);
101 userMap_[userId] = vct;
102 return;
103 }
104 auto receiverIt = std::find(mapIt->second.begin(), mapIt->second.end(),
105 receiver);
106 if (receiverIt != mapIt->second.end()) {
107 MEDIA_LOGI("register fail, receiver already exists");
108 return;
109 }
110 mapIt->second.push_back(receiver);
111 }
112
UnregisterCommonEventReceiver(int32_t userId,const std::shared_ptr<CommonEventReceiver> & receiver)113 void AccountSubscriber::UnregisterCommonEventReceiver(int32_t userId,
114 const std::shared_ptr<CommonEventReceiver> &receiver)
115 {
116 MEDIA_LOGI("receiver is 0x%{public}06" PRIXPTR ", userId %{public}d", FAKE_POINTER(receiver.get()), userId);
117 if (userId < 0 || receiver == nullptr) {
118 return;
119 }
120 std::lock_guard<std::mutex> lock(userMutex_);
121 auto mapIt = userMap_.find(userId);
122 if (mapIt == userMap_.end()) {
123 MEDIA_LOGI("unregister fail, cannot find userId");
124 return;
125 }
126 auto receiverIt = std::find(mapIt->second.begin(), mapIt->second.end(),
127 receiver);
128 if (receiverIt == mapIt->second.end()) {
129 MEDIA_LOGI("unregister fail, cannot find receiver");
130 return;
131 }
132 mapIt->second.erase(receiverIt);
133 if (mapIt->second.empty()) {
134 userMap_.erase(mapIt);
135 MEDIA_LOGI("remove userId %{public}d, map size %{public}u", userId,
136 static_cast<uint32_t>(userMap_.size()));
137 }
138 if (userMap_.empty()) {
139 EventFwk::CommonEventManager::NewUnSubscribeCommonEvent(instance_);
140 MEDIA_LOGI("user map empty, UnSubscribeCommonEvent");
141 }
142 }
143 } // namespace Media
144 } // namespace OHOS