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