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