1 /*
2 * Copyright (c) 2021-2025 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 "app_account_event_listener.h"
17
18 #include "account_log_wrapper.h"
19 #include "app_account.h"
20
21 namespace OHOS {
22 namespace AccountSA {
AppAccountEventListener()23 AppAccountEventListener::AppAccountEventListener()
24 {}
25
~AppAccountEventListener()26 AppAccountEventListener::~AppAccountEventListener()
27 {}
28
OnAccountsChanged(const std::vector<AppAccountInfo> & accounts,const std::string & owner)29 ErrCode AppAccountEventListener::OnAccountsChanged(const std::vector<AppAccountInfo> &accounts,
30 const std::string &owner)
31 {
32 if (accounts.size() > Constants::MAX_ALLOWED_ARRAY_SIZE_INPUT) {
33 ACCOUNT_LOGE("ReadAppAccountList failed, please check accounts size");
34 return ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
35 }
36 std::string ownerKey;
37 if (accounts.empty()) {
38 ACCOUNT_LOGI("accounts is empty");
39 ownerKey = owner;
40 } else {
41 AppAccountInfo info = accounts[0];
42 info.GetOwner(ownerKey);
43 }
44
45 std::lock_guard<std::mutex> lock(appAccountsMutex_);
46 auto it = owner2Subscribers_.find(ownerKey);
47 if (it == owner2Subscribers_.end()) {
48 ACCOUNT_LOGI("appAccountSubscriber is nullptr");
49 return ERR_OK;
50 }
51
52 for (const auto &appAccountSubscriber : it->second) {
53 appAccountSubscriber->OnAccountsChanged(accounts);
54 }
55 return ERR_OK;
56 }
57
SubscribeAppAccount(const std::shared_ptr<AppAccountSubscriber> & subscriber,bool & needNotifyService)58 ErrCode AppAccountEventListener::SubscribeAppAccount(
59 const std::shared_ptr<AppAccountSubscriber> &subscriber, bool &needNotifyService)
60 {
61 AppAccountSubscribeInfo subscribeInfo;
62 subscriber->GetSubscribeInfo(subscribeInfo);
63 std::vector<std::string> owners;
64 subscribeInfo.GetOwners(owners);
65 if (owners.size() == 0) {
66 return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
67 }
68 std::sort(owners.begin(), owners.end());
69 owners.erase(std::unique(owners.begin(), owners.end()), owners.end());
70 subscribeInfo.SetOwners(owners);
71 for (auto owner : owners) {
72 if (owner.size() > Constants::OWNER_MAX_SIZE) {
73 ACCOUNT_LOGE("owner is out of range, owner.size() = %{public}zu", owner.size());
74 return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
75 }
76 }
77
78 std::lock_guard<std::mutex> lock(appAccountsMutex_);
79 auto subIt = std::find(appAccountSubscriberList_.begin(), appAccountSubscriberList_.end(), subscriber);
80 if (subIt != appAccountSubscriberList_.end()) {
81 ACCOUNT_LOGI("subscriber already has app account event listener");
82 return ERR_APPACCOUNT_SUBSCRIBER_ALREADY_REGISTERED;
83 }
84
85 if (appAccountSubscriberList_.size() == Constants::APP_ACCOUNT_SUBSCRIBER_MAX_SIZE) {
86 ACCOUNT_LOGE("the maximum number of subscribers has been reached");
87 return ERR_APPACCOUNT_KIT_SUBSCRIBE;
88 }
89 appAccountSubscriberList_.emplace_back(subscriber);
90
91 for (auto &owner : owners) {
92 auto it = owner2Subscribers_.find(owner);
93 if (it == owner2Subscribers_.end()) {
94 needNotifyService = true;
95 owner2Subscribers_[owner] = {subscriber};
96 } else {
97 owner2Subscribers_[owner].emplace_back(subscriber);
98 }
99 }
100 ACCOUNT_LOGI("APP client subscribe, owner size=%{public}zu, subscriber size=%{public}zu.",
101 owner2Subscribers_.size(), appAccountSubscriberList_.size());
102 return ERR_OK;
103 }
104
UnsubscribeAppAccount(const std::shared_ptr<AppAccountSubscriber> & subscriber,bool & needNotifyService,std::vector<std::string> & deleteOwners)105 ErrCode AppAccountEventListener::UnsubscribeAppAccount(const std::shared_ptr<AppAccountSubscriber> &subscriber,
106 bool &needNotifyService, std::vector<std::string> &deleteOwners)
107 {
108 std::lock_guard<std::mutex> lock(appAccountsMutex_);
109 auto subIt = std::find(appAccountSubscriberList_.begin(), appAccountSubscriberList_.end(), subscriber);
110 if (subIt == appAccountSubscriberList_.end()) {
111 ACCOUNT_LOGE("no specified subscriber has been registered");
112 return ERR_APPACCOUNT_KIT_NO_SPECIFIED_SUBSCRIBER_HAS_BEEN_REGISTERED;
113 }
114 appAccountSubscriberList_.erase(subIt);
115
116 deleteOwners.clear();
117 for (auto &owner : owner2Subscribers_) {
118 auto it = std::find(owner.second.begin(), owner.second.end(), subscriber);
119 if (it == owner.second.end()) {
120 continue;
121 }
122
123 owner.second.erase(it);
124 if (owner.second.empty()) {
125 needNotifyService = true;
126 deleteOwners.emplace_back(owner.first);
127 }
128 }
129
130 for (std::string &owner : deleteOwners) {
131 owner2Subscribers_.erase(owner);
132 }
133 ACCOUNT_LOGI("APP client unsubscribe, owner size=%{public}zu, subscriber size=%{public}zu.",
134 owner2Subscribers_.size(), appAccountSubscriberList_.size());
135 return ERR_OK;
136 }
137
GetRestoreData(AppAccountSubscribeInfo & subscribeInfo)138 bool AppAccountEventListener::GetRestoreData(AppAccountSubscribeInfo &subscribeInfo)
139 {
140 std::lock_guard<std::mutex> lock(appAccountsMutex_);
141 if (appAccountSubscriberList_.empty()) {
142 return false;
143 }
144 std::vector<std::string> owners;
145 std::transform(owner2Subscribers_.begin(), owner2Subscribers_.end(), std::back_inserter(owners),
146 [](const auto &pair) { return pair.first; });
147
148 subscribeInfo.SetOwners(owners);
149 return true;
150 }
151
GetInstance()152 AppAccountEventListener *AppAccountEventListener::GetInstance()
153 {
154 static sptr<AppAccountEventListener> instance = new (std::nothrow) AppAccountEventListener();
155 return instance.GetRefPtr();
156 }
157 } // namespace AccountSA
158 } // namespace OHOS
159