1 /*
2 * Copyright (c) 2022 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 "token_modify_notifier.h"
17
18 #include "accesstoken_id_manager.h"
19 #include "accesstoken_info_manager.h"
20 #include "accesstoken_log.h"
21 #include "hap_token_info.h"
22 #include "hap_token_info_inner.h"
23 #include "token_sync_kit.h"
24
25 namespace OHOS {
26 namespace Security {
27 namespace AccessToken {
28 namespace {
29 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "TokenModifyNotifier"};
30 }
31
TokenModifyNotifier()32 TokenModifyNotifier::TokenModifyNotifier() : hasInited_(false), notifyTokenWorker_("TokenModify") {}
33
~TokenModifyNotifier()34 TokenModifyNotifier::~TokenModifyNotifier() {}
35
AddHapTokenObservation(AccessTokenID tokenID)36 void TokenModifyNotifier::AddHapTokenObservation(AccessTokenID tokenID)
37 {
38 if (AccessTokenIDManager::GetInstance().GetTokenIdType(tokenID) != TOKEN_HAP) {
39 ACCESSTOKEN_LOG_INFO(LABEL, "Observation token is not hap token");
40 return;
41 }
42 Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->Notifylock_);
43 if (observationSet_.count(tokenID) <= 0) {
44 observationSet_.insert(tokenID);
45 }
46 }
47
NotifyTokenDelete(AccessTokenID tokenID)48 void TokenModifyNotifier::NotifyTokenDelete(AccessTokenID tokenID)
49 {
50 Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->Notifylock_);
51 if (observationSet_.count(tokenID) <= 0) {
52 ACCESSTOKEN_LOG_DEBUG(LABEL, "hap token is not observed");
53 return;
54 }
55 observationSet_.erase(tokenID);
56 deleteTokenList_.emplace_back(tokenID);
57 NotifyTokenChangedIfNeed();
58 }
59
NotifyTokenModify(AccessTokenID tokenID)60 void TokenModifyNotifier::NotifyTokenModify(AccessTokenID tokenID)
61 {
62 Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->Notifylock_);
63 if (observationSet_.count(tokenID) <= 0) {
64 ACCESSTOKEN_LOG_DEBUG(LABEL, "hap token is not observed");
65 return;
66 }
67 modifiedTokenList_.emplace_back(tokenID);
68 NotifyTokenChangedIfNeed();
69 }
70
GetInstance()71 TokenModifyNotifier& TokenModifyNotifier::GetInstance()
72 {
73 static TokenModifyNotifier instance;
74
75 if (!instance.hasInited_) {
76 Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(instance.initLock_);
77 if (!instance.hasInited_) {
78 instance.notifyTokenWorker_.Start(1);
79 instance.hasInited_ = true;
80 }
81 }
82
83 return instance;
84 }
85
NotifyTokenSyncTask()86 void TokenModifyNotifier::NotifyTokenSyncTask()
87 {
88 Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->Notifylock_);
89 for (AccessTokenID deleteToken : deleteTokenList_) {
90 TokenSyncKit::DeleteRemoteHapTokenInfo(deleteToken);
91 }
92
93 for (AccessTokenID modifyToken : modifiedTokenList_) {
94 HapTokenInfoForSync hapSync;
95 int ret = AccessTokenInfoManager::GetInstance().GetHapTokenSync(modifyToken, hapSync);
96 if (ret != RET_SUCCESS) {
97 ACCESSTOKEN_LOG_ERROR(LABEL, "the hap token 0x%{public}x need to sync is not found!", modifyToken);
98 continue;
99 }
100 TokenSyncKit::UpdateRemoteHapTokenInfo(hapSync);
101 }
102 deleteTokenList_.clear();
103 modifiedTokenList_.clear();
104 }
NotifyTokenChangedIfNeed()105 void TokenModifyNotifier::NotifyTokenChangedIfNeed()
106 {
107 if (notifyTokenWorker_.GetCurTaskNum() > 1) {
108 ACCESSTOKEN_LOG_INFO(LABEL, " has notify task!");
109 return;
110 }
111
112 notifyTokenWorker_.AddTask([]() {
113 TokenModifyNotifier::GetInstance().NotifyTokenSyncTask();
114 });
115 }
116 } // namespace AccessToken
117 } // namespace Security
118 } // namespace OHOS
119