• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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_subscribe_manager.h"
17 #include <pthread.h>
18 #include <thread>
19 #include "account_log_wrapper.h"
20 #include "app_account_control_manager.h"
21 #include "app_account_data_storage.h"
22 #include "app_account_subscribe_death_recipient.h"
23 #include "iapp_account_event.h"
24 #include "ipc_skeleton.h"
25 #include "ohos_account_kits.h"
26 
27 namespace OHOS {
28 namespace AccountSA {
29 namespace {
30 const char THREAD_APP_ACCOUNT_EVENT[] = "appAccountEvent";
31 }
32 
AppAccountSubscribeManager()33 AppAccountSubscribeManager::AppAccountSubscribeManager()
34     : subscribeDeathRecipient_(sptr<IRemoteObject::DeathRecipient>(
35         new (std::nothrow) AppAccountSubscribeDeathRecipient()))
36 {}
37 
GetInstance()38 AppAccountSubscribeManager &AppAccountSubscribeManager::GetInstance()
39 {
40     static AppAccountSubscribeManager *instance = new (std::nothrow) AppAccountSubscribeManager();
41     return *instance;
42 }
43 
SubscribeAppAccount(const std::shared_ptr<AppAccountSubscribeInfo> & subscribeInfoPtr,const sptr<IRemoteObject> & eventListener,const uid_t & uid,const std::string & bundleName,const uint32_t & appIndex)44 ErrCode AppAccountSubscribeManager::SubscribeAppAccount(
45     const std::shared_ptr<AppAccountSubscribeInfo> &subscribeInfoPtr, const sptr<IRemoteObject> &eventListener,
46     const uid_t &uid, const std::string &bundleName, const uint32_t &appIndex)
47 {
48     if (subscribeInfoPtr == nullptr) {
49         ACCOUNT_LOGE("subscribeInfoPtr is nullptr");
50         return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
51     }
52 
53     if (eventListener == nullptr) {
54         ACCOUNT_LOGE("eventListener is nullptr");
55         return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
56     }
57 
58     std::vector<std::string> owners;
59     subscribeInfoPtr->GetOwners(owners);
60 
61     if (owners.size() == 0) {
62         ACCOUNT_LOGE("owners size is 0");
63         return ERR_APPACCOUNT_SERVICE_OWNERS_SIZE_IS_ZERO;
64     }
65 
66     ErrCode result = CheckAppAccess(subscribeInfoPtr, uid, bundleName, appIndex);
67     if (result != ERR_OK) {
68         ACCOUNT_LOGE("failed to check app access, result %{public}d.", result);
69         return result;
70     }
71 
72     auto subscribeRecordPtr = std::make_shared<AppAccountSubscribeRecord>();
73     if (subscribeRecordPtr == nullptr) {
74         ACCOUNT_LOGE("subscribeRecordPtr is nullptr");
75         return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
76     }
77 
78     subscribeRecordPtr->subscribeInfoPtr = subscribeInfoPtr;
79     subscribeRecordPtr->eventListener = eventListener;
80     subscribeRecordPtr->bundleName = bundleName;
81     subscribeRecordPtr->appIndex = appIndex;
82 
83     if (subscribeDeathRecipient_ != nullptr) {
84         eventListener->AddDeathRecipient(subscribeDeathRecipient_);
85     }
86 
87     return InsertSubscribeRecord(owners, subscribeRecordPtr);
88 }
89 
UnsubscribeAppAccount(const sptr<IRemoteObject> & eventListener)90 ErrCode AppAccountSubscribeManager::UnsubscribeAppAccount(const sptr<IRemoteObject> &eventListener)
91 {
92     if (eventListener == nullptr) {
93         ACCOUNT_LOGE("eventListener is nullptr");
94         return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
95     }
96 
97     if (subscribeDeathRecipient_ != nullptr) {
98         eventListener->RemoveDeathRecipient(subscribeDeathRecipient_);
99     }
100 
101     return RemoveSubscribeRecord(eventListener);
102 }
103 
GetSubscribeRecords(const std::string & owner)104 std::vector<AppAccountSubscribeRecordPtr> AppAccountSubscribeManager::GetSubscribeRecords(const std::string &owner)
105 {
106     auto records = std::vector<AppAccountSubscribeRecordPtr>();
107 
108     std::lock_guard<std::mutex> lock(mutex_);
109     if (ownerSubscribeRecords_.size() == 0) {
110         return records;
111     }
112 
113     auto subscribeRecordsPtr = ownerSubscribeRecords_.find(owner);
114     if (subscribeRecordsPtr == ownerSubscribeRecords_.end()) {
115         return records;
116     }
117 
118     auto subscribeRecords = subscribeRecordsPtr->second;
119     for (auto it = subscribeRecords.begin(); it != subscribeRecords.end(); it++) {
120         std::vector<std::string> owners;
121         ErrCode result = (*it)->subscribeInfoPtr->GetOwners(owners);
122         if (result != ERR_OK) {
123             ACCOUNT_LOGE("failed to get owners for subscribeInfoPtr, result %{public}d.", result);
124             return records;
125         }
126 
127         if (std::find(owners.begin(), owners.end(), owner) == owners.end()) {
128             ACCOUNT_LOGE("failed to find owner in owners");
129             return records;
130         }
131 
132         records.emplace_back(*it);
133     }
134 
135     return records;
136 }
137 
CheckAppAccess(const std::shared_ptr<AppAccountSubscribeInfo> & subscribeInfoPtr,const uid_t & uid,const std::string & bundleName,const uint32_t & appIndex)138 ErrCode AppAccountSubscribeManager::CheckAppAccess(const std::shared_ptr<AppAccountSubscribeInfo> &subscribeInfoPtr,
139     const uid_t &uid, const std::string &bundleName, const uint32_t &appIndex)
140 {
141     if (subscribeInfoPtr == nullptr) {
142         ACCOUNT_LOGE("subscribeInfoPtr is nullptr");
143         return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
144     }
145 
146     std::vector<std::string> owners;
147     subscribeInfoPtr->GetOwners(owners);
148     auto dataStoragePtr = AppAccountControlManager::GetInstance().GetDataStorage(uid);
149     if (dataStoragePtr == nullptr) {
150         ACCOUNT_LOGE("dataStoragePtr is nullptr");
151         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
152     }
153 
154     std::vector<std::string> accessibleAccounts;
155     ErrCode ret = dataStoragePtr->GetAccessibleAccountsFromDataStorage(bundleName, accessibleAccounts);
156     if (ret != ERR_OK) {
157         ACCOUNT_LOGE("failed to get accessible account from data storage, ret %{public}d.", ret);
158         return ret;
159     }
160     for (auto owner : owners) {
161         if (owner == bundleName) {
162             continue;
163         }
164         auto it = std::find_if(
165             accessibleAccounts.begin(),
166             accessibleAccounts.end(),
167             [owner](const std::string &account) {
168                 auto position = account.find(owner);
169                 if (position != 0) {
170                     return false;
171                 }
172 
173                 return true;
174             });
175         if (it == accessibleAccounts.end()) {
176             ACCOUNT_LOGE("failed to find accessible account");
177             return ERR_ACCOUNT_COMMON_PERMISSION_DENIED;
178         }
179     }
180 
181     return ERR_OK;
182 }
183 
InsertSubscribeRecord(const std::vector<std::string> & owners,const AppAccountSubscribeRecordPtr & subscribeRecordPtr)184 ErrCode AppAccountSubscribeManager::InsertSubscribeRecord(
185     const std::vector<std::string> &owners, const AppAccountSubscribeRecordPtr &subscribeRecordPtr)
186 {
187     if (owners.size() == 0) {
188         ACCOUNT_LOGE("owners size is 0");
189         return ERR_APPACCOUNT_SERVICE_OWNERS_SIZE_IS_ZERO;
190     }
191 
192     if (subscribeRecordPtr == nullptr) {
193         ACCOUNT_LOGE("subscribeRecordPtr is nullptr");
194         return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
195     }
196 
197     std::lock_guard<std::mutex> lock(subscribeRecordMutex_);
198 
199     for (auto owner : owners) {
200         auto item = ownerSubscribeRecords_.find(owner);
201         if (item != ownerSubscribeRecords_.end()) {
202             item->second.insert(subscribeRecordPtr);
203         } else {
204             std::multiset<AppAccountSubscribeRecordPtr> subscribeRecords;
205             subscribeRecords.insert(subscribeRecordPtr);
206             ownerSubscribeRecords_[owner] = subscribeRecords;
207         }
208     }
209 
210     subscribeRecords_.emplace_back(subscribeRecordPtr);
211 
212     return ERR_OK;
213 }
214 
RemoveSubscribeRecord(const sptr<IRemoteObject> & eventListener)215 ErrCode AppAccountSubscribeManager::RemoveSubscribeRecord(const sptr<IRemoteObject> &eventListener)
216 {
217     if (eventListener == nullptr) {
218         ACCOUNT_LOGE("eventListener is nullptr");
219         return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
220     }
221 
222     std::lock_guard<std::mutex> lock(subscribeRecordMutex_);
223 
224     std::vector<std::string> owners;
225     for (auto it = subscribeRecords_.begin(); it != subscribeRecords_.end(); ++it) {
226         if (eventListener == (*it)->eventListener) {
227             (*it)->eventListener = nullptr;
228             (*it)->subscribeInfoPtr->GetOwners(owners);
229             subscribeRecords_.erase(it);
230             break;
231         }
232     }
233 
234     for (auto owner : owners) {
235         for (auto it = ownerSubscribeRecords_[owner].begin(); it != ownerSubscribeRecords_[owner].end(); ++it) {
236             if ((eventListener == (*it)->eventListener) || ((*it)->eventListener == nullptr)) {
237                 (*it)->eventListener = nullptr;
238                 ownerSubscribeRecords_[owner].erase(it);
239                 break;
240             }
241         }
242 
243         if (ownerSubscribeRecords_[owner].size() == 0) {
244             ownerSubscribeRecords_.erase(owner);
245         }
246     }
247 
248     return ERR_OK;
249 }
250 
PublishAccount(AppAccountInfo & appAccountInfo,const uid_t & uid,const std::string & bundleName)251 bool AppAccountSubscribeManager::PublishAccount(
252     AppAccountInfo &appAccountInfo, const uid_t &uid, const std::string &bundleName)
253 {
254     std::string name;
255     appAccountInfo.GetName(name);
256     uint32_t appIndex = appAccountInfo.GetAppIndex();
257 
258     auto eventRecordPtr = std::make_shared<AppAccountEventRecord>();
259     if (eventRecordPtr == nullptr) {
260         ACCOUNT_LOGE("failed to create AppAccountEventRecord");
261         return false;
262     }
263     eventRecordPtr->info = std::make_shared<AppAccountInfo>(appAccountInfo);
264     eventRecordPtr->receivers = GetSubscribeRecords(bundleName);
265     eventRecordPtr->uid = uid;
266     eventRecordPtr->bundleName = bundleName;
267     eventRecordPtr->appIndex = appIndex;
268 
269     auto callback = std::bind(&AppAccountSubscribeManager::OnAccountsChanged, this, eventRecordPtr);
270 
271     std::thread taskThread(callback);
272     pthread_setname_np(taskThread.native_handle(), THREAD_APP_ACCOUNT_EVENT);
273     taskThread.detach();
274     return true;
275 }
276 
OnAccountsChanged(const std::shared_ptr<AppAccountEventRecord> & record)277 ErrCode AppAccountSubscribeManager::OnAccountsChanged(const std::shared_ptr<AppAccountEventRecord> &record)
278 {
279     auto uid = record->uid;
280     auto &controlManagerPtr = AppAccountControlManager::GetInstance();
281     auto dataStoragePtr = controlManagerPtr.GetDataStorage(uid);
282     if (dataStoragePtr == nullptr) {
283         ACCOUNT_LOGE("dataStoragePtr is nullptr");
284         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
285     }
286 
287     for (auto receiver : record->receivers) {
288         std::vector<AppAccountInfo> accessibleAccounts;
289         ErrCode result = controlManagerPtr.GetAllAccessibleAccountsFromDataStorage(
290             accessibleAccounts, receiver->bundleName, dataStoragePtr, record->appIndex);
291         if (result != ERR_OK) {
292             ACCOUNT_LOGE("failed to get all accessible accounts from data storage, result = %{public}d", result);
293             return result;
294         }
295 
296         std::vector<AppAccountInfo> appAccounts;
297         result = GetAccessibleAccountsBySubscribeInfo(receiver->subscribeInfoPtr, accessibleAccounts, appAccounts);
298         if (result != ERR_OK) {
299             ACCOUNT_LOGE("failed to get accessible accounts by subscribe info");
300             continue;
301         }
302 
303         auto appAccountEventProxy = iface_cast<IAppAccountEvent>(receiver->eventListener);
304         if (appAccountEventProxy == nullptr) {
305             ACCOUNT_LOGE("failed to get app account event proxy");
306             continue;
307         }
308 
309         appAccountEventProxy->OnAccountsChanged(appAccounts);
310     }
311 
312     return ERR_OK;
313 }
314 
GetAccessibleAccountsBySubscribeInfo(const std::shared_ptr<AppAccountSubscribeInfo> & subscribeInfoPtr,const std::vector<AppAccountInfo> & accessibleAccounts,std::vector<AppAccountInfo> & appAccounts)315 ErrCode AppAccountSubscribeManager::GetAccessibleAccountsBySubscribeInfo(
316     const std::shared_ptr<AppAccountSubscribeInfo> &subscribeInfoPtr,
317     const std::vector<AppAccountInfo> &accessibleAccounts, std::vector<AppAccountInfo> &appAccounts)
318 {
319     if (subscribeInfoPtr == nullptr) {
320         ACCOUNT_LOGE("subscribeInfoPtr is nullptr");
321         return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
322     }
323 
324     appAccounts.clear();
325 
326     std::vector<std::string> owners;
327     subscribeInfoPtr->GetOwners(owners);
328 
329     for (auto accessibleAccount : accessibleAccounts) {
330         std::string name;
331         accessibleAccount.GetName(name);
332 
333         std::string owner;
334         accessibleAccount.GetOwner(owner);
335 
336         if (std::find(owners.begin(), owners.end(), owner) != owners.end()) {
337             appAccounts.emplace_back(accessibleAccount);
338         }
339     }
340 
341     return ERR_OK;
342 }
343 }  // namespace AccountSA
344 }  // namespace OHOS
345