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