• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "access_token_error.h"
22 #include "hap_token_info.h"
23 #include "hap_token_info_inner.h"
24 #include "token_sync_kit.h"
25 
26 namespace OHOS {
27 namespace Security {
28 namespace AccessToken {
29 namespace {
30 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "TokenModifyNotifier"};
31 }
32 
33 #ifdef RESOURCESCHEDULE_FFRT_ENABLE
TokenModifyNotifier()34 TokenModifyNotifier::TokenModifyNotifier() : hasInited_(false), curTaskNum_(0) {}
35 #else
TokenModifyNotifier()36 TokenModifyNotifier::TokenModifyNotifier() : hasInited_(false), notifyTokenWorker_("TokenModify") {}
37 #endif
38 
~TokenModifyNotifier()39 TokenModifyNotifier::~TokenModifyNotifier()
40 {
41     if (!hasInited_) {
42         return;
43     }
44 #ifndef RESOURCESCHEDULE_FFRT_ENABLE
45     this->notifyTokenWorker_.Stop();
46 #endif
47     this->hasInited_ = false;
48 }
49 
AddHapTokenObservation(AccessTokenID tokenID)50 void TokenModifyNotifier::AddHapTokenObservation(AccessTokenID tokenID)
51 {
52     if (AccessTokenIDManager::GetInstance().GetTokenIdType(tokenID) != TOKEN_HAP) {
53         ACCESSTOKEN_LOG_INFO(LABEL, "Observation token is not hap token");
54         return;
55     }
56     Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->Notifylock_);
57     if (observationSet_.count(tokenID) <= 0) {
58         observationSet_.insert(tokenID);
59     }
60 }
61 
NotifyTokenDelete(AccessTokenID tokenID)62 void TokenModifyNotifier::NotifyTokenDelete(AccessTokenID tokenID)
63 {
64     Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->Notifylock_);
65     if (observationSet_.count(tokenID) <= 0) {
66         ACCESSTOKEN_LOG_DEBUG(LABEL, "hap token is not observed");
67         return;
68     }
69     observationSet_.erase(tokenID);
70     deleteTokenList_.emplace_back(tokenID);
71     NotifyTokenChangedIfNeed();
72 }
73 
NotifyTokenModify(AccessTokenID tokenID)74 void TokenModifyNotifier::NotifyTokenModify(AccessTokenID tokenID)
75 {
76     Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->Notifylock_);
77     if (observationSet_.count(tokenID) <= 0) {
78         ACCESSTOKEN_LOG_DEBUG(LABEL, "hap token is not observed");
79         return;
80     }
81     modifiedTokenList_.emplace_back(tokenID);
82     NotifyTokenChangedIfNeed();
83 }
84 
GetInstance()85 TokenModifyNotifier& TokenModifyNotifier::GetInstance()
86 {
87     static TokenModifyNotifier instance;
88 
89     if (!instance.hasInited_) {
90         Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(instance.initLock_);
91         if (!instance.hasInited_) {
92 #ifndef RESOURCESCHEDULE_FFRT_ENABLE
93             instance.notifyTokenWorker_.Start(1);
94 #endif
95             instance.hasInited_ = true;
96         }
97     }
98 
99     return instance;
100 }
101 
NotifyTokenSyncTask()102 void TokenModifyNotifier::NotifyTokenSyncTask()
103 {
104     ACCESSTOKEN_LOG_INFO(LABEL, "called!");
105 
106     Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->Notifylock_);
107     for (AccessTokenID deleteToken : deleteTokenList_) {
108         TokenSyncKit::DeleteRemoteHapTokenInfo(deleteToken);
109     }
110 
111     for (AccessTokenID modifyToken : modifiedTokenList_) {
112         HapTokenInfoForSync hapSync;
113         int ret = AccessTokenInfoManager::GetInstance().GetHapTokenSync(modifyToken, hapSync);
114         if (ret != RET_SUCCESS) {
115             ACCESSTOKEN_LOG_ERROR(LABEL, "the hap token 0x%{public}x need to sync is not found!", modifyToken);
116             continue;
117         }
118         TokenSyncKit::UpdateRemoteHapTokenInfo(hapSync);
119     }
120     deleteTokenList_.clear();
121     modifiedTokenList_.clear();
122 
123     ACCESSTOKEN_LOG_INFO(LABEL, "over!");
124 }
125 
126 #ifdef RESOURCESCHEDULE_FFRT_ENABLE
GetCurTaskNum()127 int32_t TokenModifyNotifier::GetCurTaskNum()
128 {
129     return curTaskNum_.load();
130 }
131 
AddCurTaskNum()132 void TokenModifyNotifier::AddCurTaskNum()
133 {
134     ACCESSTOKEN_LOG_INFO(LABEL, "Add task!");
135     curTaskNum_++;
136 }
137 
ReduceCurTaskNum()138 void TokenModifyNotifier::ReduceCurTaskNum()
139 {
140     ACCESSTOKEN_LOG_INFO(LABEL, "Reduce task!");
141     curTaskNum_--;
142 }
143 #endif
144 
NotifyTokenChangedIfNeed()145 void TokenModifyNotifier::NotifyTokenChangedIfNeed()
146 {
147 #ifdef RESOURCESCHEDULE_FFRT_ENABLE
148     if (GetCurTaskNum() > 1) {
149         ACCESSTOKEN_LOG_INFO(LABEL, "has notify task! taskNum is %{public}d.", GetCurTaskNum());
150         return;
151     }
152 
153     std::string taskName = "TokenModify";
154     auto tokenModify = []() {
155         TokenModifyNotifier::GetInstance().NotifyTokenSyncTask();
156         TokenModifyNotifier::GetInstance().ReduceCurTaskNum();
157     };
158     ffrt::submit(tokenModify, {}, {}, ffrt::task_attr().qos(ffrt::qos_default).name(taskName.c_str()));
159     AddCurTaskNum();
160 #else
161     if (notifyTokenWorker_.GetCurTaskNum() > 1) {
162         ACCESSTOKEN_LOG_INFO(LABEL, " has notify task! taskNum is %{public}zu.", notifyTokenWorker_.GetCurTaskNum());
163         return;
164     }
165 
166     notifyTokenWorker_.AddTask([]() {
167         TokenModifyNotifier::GetInstance().NotifyTokenSyncTask();
168     });
169 #endif
170 }
171 } // namespace AccessToken
172 } // namespace Security
173 } // namespace OHOS
174