1 /*
2 * Copyright (c) 2021-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 "os_account_subscribe_manager.h"
17 #include <pthread.h>
18 #include <thread>
19 #include "account_log_wrapper.h"
20 #include "os_account_subscribe_death_recipient.h"
21
22 namespace OHOS {
23 namespace AccountSA {
24 namespace {
25 const char THREAD_OS_ACCOUNT_EVENT[] = "osAccountEvent";
26 }
27
OsAccountSubscribeManager()28 OsAccountSubscribeManager::OsAccountSubscribeManager()
29 : subscribeDeathRecipient_(sptr<IRemoteObject::DeathRecipient>(
30 new (std::nothrow) OsAccountSubscribeDeathRecipient()))
31 {}
32
GetInstance()33 OsAccountSubscribeManager &OsAccountSubscribeManager::GetInstance()
34 {
35 static OsAccountSubscribeManager *instance = new (std::nothrow) OsAccountSubscribeManager();
36 return *instance;
37 }
38
SubscribeOsAccount(const std::shared_ptr<OsAccountSubscribeInfo> & subscribeInfoPtr,const sptr<IRemoteObject> & eventListener)39 ErrCode OsAccountSubscribeManager::SubscribeOsAccount(
40 const std::shared_ptr<OsAccountSubscribeInfo> &subscribeInfoPtr, const sptr<IRemoteObject> &eventListener)
41 {
42 if (subscribeInfoPtr == nullptr) {
43 ACCOUNT_LOGE("subscribeInfoPtr is nullptr");
44 return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
45 }
46
47 if (eventListener == nullptr) {
48 ACCOUNT_LOGE("eventListener is nullptr");
49 return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
50 }
51 auto subscribeRecordPtr = std::make_shared<OsSubscribeRecord>(subscribeInfoPtr, eventListener);
52 if (subscribeRecordPtr == nullptr) {
53 ACCOUNT_LOGE("subscribeRecordPtr is nullptr");
54 return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
55 }
56 if (subscribeDeathRecipient_ != nullptr) {
57 eventListener->AddDeathRecipient(subscribeDeathRecipient_);
58 }
59 subscribeRecordPtr->subscribeInfoPtr_ = subscribeInfoPtr;
60 subscribeRecordPtr->eventListener_ = eventListener;
61 return InsertSubscribeRecord(subscribeRecordPtr);
62 }
63
UnsubscribeOsAccount(const sptr<IRemoteObject> & eventListener)64 ErrCode OsAccountSubscribeManager::UnsubscribeOsAccount(const sptr<IRemoteObject> &eventListener)
65 {
66 if (eventListener == nullptr) {
67 ACCOUNT_LOGE("eventListener is nullptr");
68 return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
69 }
70
71 if (subscribeDeathRecipient_ != nullptr) {
72 eventListener->RemoveDeathRecipient(subscribeDeathRecipient_);
73 }
74
75 return RemoveSubscribeRecord(eventListener);
76 }
77
InsertSubscribeRecord(const OsSubscribeRecordPtr & subscribeRecordPtr)78 ErrCode OsAccountSubscribeManager::InsertSubscribeRecord(const OsSubscribeRecordPtr &subscribeRecordPtr)
79 {
80 if (subscribeRecordPtr == nullptr) {
81 ACCOUNT_LOGE("subscribeRecordPtr is nullptr");
82 return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
83 }
84
85 std::lock_guard<std::mutex> lock(subscribeRecordMutex_);
86
87 subscribeRecords_.emplace_back(subscribeRecordPtr);
88
89 return ERR_OK;
90 }
91
RemoveSubscribeRecord(const sptr<IRemoteObject> & eventListener)92 ErrCode OsAccountSubscribeManager::RemoveSubscribeRecord(const sptr<IRemoteObject> &eventListener)
93 {
94 if (eventListener == nullptr) {
95 ACCOUNT_LOGE("eventListener is nullptr");
96 return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
97 }
98
99 std::lock_guard<std::mutex> lock(subscribeRecordMutex_);
100
101 for (auto it = subscribeRecords_.begin(); it != subscribeRecords_.end(); ++it) {
102 if (eventListener == (*it)->eventListener_) {
103 (*it)->eventListener_ = nullptr;
104 subscribeRecords_.erase(it);
105 break;
106 }
107 }
108
109 return ERR_OK;
110 }
111
GetSubscribeRecordInfo(const sptr<IRemoteObject> & eventListener)112 const std::shared_ptr<OsAccountSubscribeInfo> OsAccountSubscribeManager::GetSubscribeRecordInfo(
113 const sptr<IRemoteObject> &eventListener)
114 {
115 if (eventListener == nullptr) {
116 ACCOUNT_LOGE("eventListener is nullptr");
117 return nullptr;
118 }
119
120 std::lock_guard<std::mutex> lock(subscribeRecordMutex_);
121
122 for (auto it = subscribeRecords_.begin(); it != subscribeRecords_.end(); ++it) {
123 if (eventListener == (*it)->eventListener_) {
124 return (*it)->subscribeInfoPtr_;
125 }
126 }
127
128 return nullptr;
129 }
130
OnAccountsChanged(const sptr<IOsAccountEvent> & eventProxy,const int id)131 bool OsAccountSubscribeManager::OnAccountsChanged(const sptr<IOsAccountEvent> &eventProxy, const int id)
132 {
133 if (eventProxy == nullptr) {
134 ACCOUNT_LOGE("Account event proxy is nullptr");
135 return false;
136 }
137 eventProxy->OnAccountsChanged(id);
138 return true;
139 }
140
OnAccountsSwitch(const sptr<IOsAccountEvent> & eventProxy,const int newId,const int oldId)141 bool OsAccountSubscribeManager::OnAccountsSwitch(const sptr<IOsAccountEvent> &eventProxy, const int newId,
142 const int oldId)
143 {
144 if (eventProxy == nullptr) {
145 ACCOUNT_LOGE("Account event proxy is nullptr");
146 return false;
147 }
148 eventProxy->OnAccountsSwitch(newId, oldId);
149 return true;
150 }
151
Publish(const int id,OS_ACCOUNT_SUBSCRIBE_TYPE subscribeType)152 ErrCode OsAccountSubscribeManager::Publish(const int id, OS_ACCOUNT_SUBSCRIBE_TYPE subscribeType)
153 {
154 if (subscribeType == SWITCHING || subscribeType == SWITCHED) {
155 ACCOUNT_LOGE("Switch event need two ids.");
156 return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
157 }
158
159 std::lock_guard<std::mutex> lock(subscribeRecordMutex_);
160 uint32_t sendCnt = 0;
161 for (auto it = subscribeRecords_.begin(); it != subscribeRecords_.end(); ++it) {
162 if ((*it)->subscribeInfoPtr_ == nullptr) {
163 ACCOUNT_LOGE("subscribeInfoPtr_ is null, id %{public}d.", id);
164 continue;
165 }
166 OS_ACCOUNT_SUBSCRIBE_TYPE osAccountSubscribeType;
167 (*it)->subscribeInfoPtr_->GetOsAccountSubscribeType(osAccountSubscribeType);
168 if (osAccountSubscribeType == subscribeType) {
169 sptr<IOsAccountEvent> eventProxy = iface_cast<IOsAccountEvent>((*it)->eventListener_);
170 if (eventProxy == nullptr) {
171 ACCOUNT_LOGE("Get eventProxy failed");
172 break;
173 }
174 auto task = [this, eventProxy, id] { this->OnAccountsChanged(eventProxy, id); };
175 std::thread taskThread(task);
176 pthread_setname_np(taskThread.native_handle(), THREAD_OS_ACCOUNT_EVENT);
177 taskThread.detach();
178 ++sendCnt;
179 }
180 }
181
182 ACCOUNT_LOGI("Publish OsAccountEvent %{public}d succeed! id %{public}d, sendCnt %{public}u.",
183 subscribeType, id, sendCnt);
184 return ERR_OK;
185 }
186
Publish(const int newId,const int oldId,OS_ACCOUNT_SUBSCRIBE_TYPE subscribeType)187 ErrCode OsAccountSubscribeManager::Publish(const int newId, const int oldId, OS_ACCOUNT_SUBSCRIBE_TYPE subscribeType)
188 {
189 if (subscribeType != SWITCHING && subscribeType != SWITCHED) {
190 ACCOUNT_LOGE("Only switch event need two ids.");
191 return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
192 }
193
194 std::lock_guard<std::mutex> lock(subscribeRecordMutex_);
195 uint32_t sendCnt = 0;
196 for (auto it = subscribeRecords_.begin(); it != subscribeRecords_.end(); ++it) {
197 if ((*it)->subscribeInfoPtr_ == nullptr) {
198 ACCOUNT_LOGE("SubscribeInfoPtr_ is null.");
199 continue;
200 }
201 OS_ACCOUNT_SUBSCRIBE_TYPE osAccountSubscribeType;
202 (*it)->subscribeInfoPtr_->GetOsAccountSubscribeType(osAccountSubscribeType);
203 if (osAccountSubscribeType == subscribeType) {
204 sptr<IOsAccountEvent> eventProxy = iface_cast<IOsAccountEvent>((*it)->eventListener_);
205 if (eventProxy == nullptr) {
206 ACCOUNT_LOGE("Get eventProxy failed");
207 break;
208 }
209 auto task = [this, eventProxy, newId, oldId] { this->OnAccountsSwitch(eventProxy, newId, oldId); };
210 std::thread taskThread(task);
211 pthread_setname_np(taskThread.native_handle(), THREAD_OS_ACCOUNT_EVENT);
212 taskThread.detach();
213 ++sendCnt;
214 }
215 }
216
217 ACCOUNT_LOGI("Publish %{public}d successful, newId=%{public}d, oldId=%{public}d, sendCnt=%{public}u.",
218 subscribeType, newId, oldId, sendCnt);
219 return ERR_OK;
220 }
221 } // namespace AccountSA
222 } // namespace OHOS
223