• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "os_account_constraint_subscriber_manager.h"
17 
18 #include "account_error_no.h"
19 #include "account_log_wrapper.h"
20 #include "os_account_constants.h"
21 #include <pthread.h>
22 #include <thread>
23 
24 namespace OHOS {
25 namespace AccountSA {
26 namespace {
27 const char THREAD_OS_ACCOUNT_CONSTRAINT_EVENT[] = "OsAccountConstraintEvent";
28 
ConvertToAccountErrCode(ErrCode idlErrCode)29 ErrCode ConvertToAccountErrCode(ErrCode idlErrCode)
30 {
31     if (idlErrCode == ERR_INVALID_VALUE) {
32         return ERR_ACCOUNT_COMMON_WRITE_DESCRIPTOR_ERROR;
33     }
34     if (idlErrCode == ERR_INVALID_DATA) {
35         return ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR;
36     }
37     return idlErrCode;
38 }
39 }
GetInstance()40 OsAccountConstraintSubscriberManager* OsAccountConstraintSubscriberManager::GetInstance()
41 {
42     static sptr<OsAccountConstraintSubscriberManager> instance =
43         new (std::nothrow) OsAccountConstraintSubscriberManager();
44     return instance.GetRefPtr();
45 }
46 
OsAccountConstraintSubscriberManager()47 OsAccountConstraintSubscriberManager::OsAccountConstraintSubscriberManager() {}
48 
OnConstraintChanged(int32_t localId,const std::set<std::string> & constraints,bool enable)49 ErrCode OsAccountConstraintSubscriberManager::OnConstraintChanged(
50     int32_t localId, const std::set<std::string> &constraints, bool enable)
51 {
52     std::lock_guard<std::mutex> lock(mutex_);
53     for (auto const &constraint : constraints) {
54         for (auto const &subscriber: constraint2SubscriberMap_[constraint]) {
55             OsAccountConstraintStateData data{localId, constraint, enable};
56             auto task = [subscriber, data]() mutable {
57                 subscriber->OnConstraintChanged(data);
58             };
59             std::thread taskThread(task);
60             pthread_setname_np(taskThread.native_handle(), THREAD_OS_ACCOUNT_CONSTRAINT_EVENT);
61             taskThread.detach();
62         }
63     }
64     return ERR_OK;
65 }
66 
InsertSubscriberRecord(const std::shared_ptr<OsAccountConstraintSubscriber> & subscriber)67 void OsAccountConstraintSubscriberManager::InsertSubscriberRecord(
68     const std::shared_ptr<OsAccountConstraintSubscriber> &subscriber)
69 {
70     std::set<std::string> constraintSet;
71     subscriber->GetConstraintSet(constraintSet);
72     subscriberSet_.emplace(subscriber);
73     for (auto const &constraint : constraintSet) {
74         constraint2SubscriberMap_[constraint].emplace(subscriber);
75         constraintSet_.emplace(constraint);
76     }
77 }
78 
HasSubscribed(const std::shared_ptr<OsAccountConstraintSubscriber> & subscriber)79 bool OsAccountConstraintSubscriberManager::HasSubscribed(
80     const std::shared_ptr<OsAccountConstraintSubscriber> &subscriber)
81 {
82     return subscriberSet_.find(subscriber) != subscriberSet_.end();
83 }
84 
RemoveSubscriberRecord(const std::shared_ptr<OsAccountConstraintSubscriber> & subscriber)85 void OsAccountConstraintSubscriberManager::RemoveSubscriberRecord(
86     const std::shared_ptr<OsAccountConstraintSubscriber> &subscriber)
87 {
88     std::set<std::string> constraintSet;
89     subscriber->GetConstraintSet(constraintSet);
90     subscriberSet_.erase(subscriber);
91     for (auto const &item :  constraintSet) {
92         constraint2SubscriberMap_[item].erase(subscriber);
93         if (constraint2SubscriberMap_[item].empty()) {
94             constraint2SubscriberMap_.erase(item);
95             constraintSet_.erase(item);
96         }
97     }
98 }
99 
SubscribeOsAccountConstraints(const std::shared_ptr<OsAccountConstraintSubscriber> & subscriber,sptr<IOsAccount> & proxy)100 ErrCode OsAccountConstraintSubscriberManager::SubscribeOsAccountConstraints(
101     const std::shared_ptr<OsAccountConstraintSubscriber> &subscriber, sptr<IOsAccount> &proxy)
102 {
103     if (subscriber == nullptr) {
104         ACCOUNT_LOGE("Subscriber is nullptr.");
105         return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
106     }
107     std::set<std::string> constraintSet;
108     subscriber->GetConstraintSet(constraintSet);
109     if (constraintSet.empty()) {
110         ACCOUNT_LOGE("Empty constraints.");
111         return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
112     }
113     if (constraintSet.size() > Constants::CONSTRAINT_MAX_SIZE) {
114         ACCOUNT_LOGE("Constraints size=%{public}zu is too large.", constraintSet.size());
115         return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
116     }
117     std::lock_guard<std::mutex> lock(mutex_);
118     if (proxy == nullptr) {
119         ACCOUNT_LOGE("Proxy is nullptr.");
120         return ERR_ACCOUNT_COMMON_GET_PROXY;
121     }
122     if (HasSubscribed(subscriber)) {
123         ACCOUNT_LOGE("Already subscribed.");
124         return ERR_ACCOUNT_COMMON_ACCOUNT_AREADY_SUBSCRIBE_ERROR;
125     }
126     constraintSet.insert(constraintSet_.begin(), constraintSet_.end());
127     if (constraintSet.size() == constraintSet_.size()) {
128         ACCOUNT_LOGI("No need to sync data service.");
129         InsertSubscriberRecord(subscriber);
130         return ERR_OK;
131     }
132     OsAccountConstraintSubscribeInfo subscribeInfo(constraintSet);
133     ErrCode errCode = proxy->SubscribeOsAccountConstraints(subscribeInfo, GetInstance()->AsObject());
134     errCode = ConvertToAccountErrCode(errCode);
135     if (errCode != ERR_OK) {
136         ACCOUNT_LOGE("SubscribeOsAccountConstraints fail, errcode:%{public}d", errCode);
137         return errCode;
138     }
139     InsertSubscriberRecord(subscriber);
140     return ERR_OK;
141 }
142 
UnsubscribeOsAccountConstraints(const std::shared_ptr<OsAccountConstraintSubscriber> & subscriber,sptr<IOsAccount> & proxy)143 ErrCode OsAccountConstraintSubscriberManager::UnsubscribeOsAccountConstraints(
144     const std::shared_ptr<OsAccountConstraintSubscriber> &subscriber, sptr<IOsAccount> &proxy)
145 {
146     if (subscriber == nullptr) {
147         ACCOUNT_LOGE("Subscriber is nullptr.");
148         return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
149     }
150     std::set<std::string> constraintSet;
151     subscriber->GetConstraintSet(constraintSet);
152     std::lock_guard<std::mutex> lock(mutex_);
153     if (proxy == nullptr) {
154         ACCOUNT_LOGE("Proxy is nullptr.");
155         return ERR_ACCOUNT_COMMON_GET_PROXY;
156     }
157     if (!HasSubscribed(subscriber)) {
158         ACCOUNT_LOGE("Not subscribed.");
159         return ERR_ACCOUNT_COMMON_ACCOUNT_SUBSCRIBE_NOT_FOUND_ERROR;
160     }
161     std::set<std::string> syncData;
162     for (auto const &constraint : constraintSet) {
163         if (constraint2SubscriberMap_[constraint].size() == 1) {
164             syncData.emplace(constraint);
165         }
166     }
167     if (syncData.empty()) {
168         ACCOUNT_LOGI("No need to sync data service.");
169         RemoveSubscriberRecord(subscriber);
170         return ERR_OK;
171     }
172     OsAccountConstraintSubscribeInfo info(syncData);
173     ErrCode errCode =  proxy->UnsubscribeOsAccountConstraints(info, GetInstance()->AsObject());
174     errCode = ConvertToAccountErrCode(errCode);
175     if (errCode != ERR_OK) {
176         ACCOUNT_LOGE("UnsubscribeOsAccountConstraints fail, errcode:%{public}d", errCode);
177         return errCode;
178     }
179     RemoveSubscriberRecord(subscriber);
180     return ERR_OK;
181 }
182 
RestoreConstraintSubscriberRecords(sptr<IOsAccount> & proxy)183 void OsAccountConstraintSubscriberManager::RestoreConstraintSubscriberRecords(sptr<IOsAccount> &proxy)
184 {
185     std::lock_guard<std::mutex> lock(mutex_);
186     if (proxy == nullptr) {
187         ACCOUNT_LOGE("Proxy is nullptr.");
188         return;
189     }
190     if (constraintSet_.empty()) {
191         ACCOUNT_LOGD("RestoreConstraintSubscriberRecords empty.");
192         return;
193     }
194     OsAccountConstraintSubscribeInfo subscribeInfo(constraintSet_);
195     ErrCode errCode = proxy->SubscribeOsAccountConstraints(subscribeInfo, GetInstance()->AsObject());
196     errCode = ConvertToAccountErrCode(errCode);
197     if (errCode != ERR_OK) {
198         ACCOUNT_LOGE("RestoreConstraintSubscriberRecords failed, errCode=%{public}d.", errCode);
199         return;
200     }
201     ACCOUNT_LOGI("RestoreConstraintSubscriberRecords success.");
202 }
203 }  // namespace AccountSA
204 }  // namespace OHOS