• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2024 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_callback_proxys.h"
19 #include "accesstoken_id_manager.h"
20 #include "accesstoken_info_manager.h"
21 #include "accesstoken_common_log.h"
22 #include "access_token_error.h"
23 #ifdef RESOURCESCHEDULE_FFRT_ENABLE
24 #include "ffrt.h"
25 #endif
26 #include "hap_token_info.h"
27 #include "hap_token_info_inner.h"
28 #include "libraryloader.h"
29 #include "token_sync_kit_loader.h"
30 
31 namespace OHOS {
32 namespace Security {
33 namespace AccessToken {
34 namespace {
35 std::recursive_mutex g_instanceMutex;
36 }
37 
38 #ifdef RESOURCESCHEDULE_FFRT_ENABLE
TokenModifyNotifier()39 TokenModifyNotifier::TokenModifyNotifier() : hasInited_(false), curTaskNum_(0) {}
40 #else
TokenModifyNotifier()41 TokenModifyNotifier::TokenModifyNotifier() : hasInited_(false), notifyTokenWorker_("TokenModify") {}
42 #endif
43 
~TokenModifyNotifier()44 TokenModifyNotifier::~TokenModifyNotifier()
45 {
46     if (!hasInited_) {
47         return;
48     }
49 #ifndef RESOURCESCHEDULE_FFRT_ENABLE
50     this->notifyTokenWorker_.Stop();
51 #endif
52     this->hasInited_ = false;
53 }
54 
AddHapTokenObservation(AccessTokenID tokenID)55 void TokenModifyNotifier::AddHapTokenObservation(AccessTokenID tokenID)
56 {
57     if (AccessTokenIDManager::GetInstance().GetTokenIdType(tokenID) != TOKEN_HAP) {
58         LOGI(ATM_DOMAIN, ATM_TAG, "Observation token is not hap token");
59         return;
60     }
61     Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->Notifylock_);
62     if (observationSet_.count(tokenID) <= 0) {
63         observationSet_.insert(tokenID);
64     }
65 }
66 
NotifyTokenDelete(AccessTokenID tokenID)67 void TokenModifyNotifier::NotifyTokenDelete(AccessTokenID tokenID)
68 {
69     Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->Notifylock_);
70     if (observationSet_.count(tokenID) <= 0) {
71         LOGD(ATM_DOMAIN, ATM_TAG, "Hap token is not observed");
72         return;
73     }
74     observationSet_.erase(tokenID);
75     deleteTokenList_.emplace_back(tokenID);
76     NotifyTokenChangedIfNeed();
77 }
78 
NotifyTokenModify(AccessTokenID tokenID)79 void TokenModifyNotifier::NotifyTokenModify(AccessTokenID tokenID)
80 {
81     Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->Notifylock_);
82     if (observationSet_.count(tokenID) <= 0) {
83         LOGD(ATM_DOMAIN, ATM_TAG, "Hap token is not observed");
84         return;
85     }
86     modifiedTokenList_.emplace_back(tokenID);
87     NotifyTokenChangedIfNeed();
88 }
89 
GetInstance()90 TokenModifyNotifier& TokenModifyNotifier::GetInstance()
91 {
92     static TokenModifyNotifier* instance = nullptr;
93     if (instance == nullptr) {
94         std::lock_guard<std::recursive_mutex> lock(g_instanceMutex);
95         if (instance == nullptr) {
96             TokenModifyNotifier* tmp = new TokenModifyNotifier();
97             instance = std::move(tmp);
98         }
99     }
100 
101     if (!instance->hasInited_) {
102         Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(instance->initLock_);
103         if (!instance->hasInited_) {
104 #ifndef RESOURCESCHEDULE_FFRT_ENABLE
105             instance->notifyTokenWorker_.Start(1);
106 #endif
107             instance->hasInited_ = true;
108         }
109     }
110 
111     return *instance;
112 }
113 
NotifyTokenSyncTask()114 void TokenModifyNotifier::NotifyTokenSyncTask()
115 {
116     LOGI(ATM_DOMAIN, ATM_TAG, "Called!");
117 
118     Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->Notifylock_);
119     LibraryLoader loader(TOKEN_SYNC_LIBPATH);
120     TokenSyncKitInterface* tokenSyncKit = loader.GetObject<TokenSyncKitInterface>();
121     if (tokenSyncKit == nullptr) {
122         LOGE(ATM_DOMAIN, ATM_TAG, "Dlopen libtokensync_sdk failed.");
123         return;
124     }
125     for (AccessTokenID deleteToken : deleteTokenList_) {
126         int ret = TOKEN_SYNC_SUCCESS;
127         if (tokenSyncCallbackObject_ != nullptr) {
128             ret = tokenSyncCallbackObject_->DeleteRemoteHapTokenInfo(deleteToken);
129         }
130         ret = tokenSyncKit->DeleteRemoteHapTokenInfo(deleteToken);
131         if (ret != TOKEN_SYNC_SUCCESS) {
132             LOGE(ATM_DOMAIN, ATM_TAG, "Fail to delete remote haptoken info, ret is %{public}d", ret);
133         }
134     }
135 
136     for (AccessTokenID modifyToken : modifiedTokenList_) {
137         HapTokenInfoForSync hapSync;
138         int ret = AccessTokenInfoManager::GetInstance().GetHapTokenSync(modifyToken, hapSync);
139         if (ret != RET_SUCCESS) {
140             LOGE(ATM_DOMAIN, ATM_TAG, "The hap token 0x%{public}x need to sync is not found!", modifyToken);
141             continue;
142         }
143         if (tokenSyncCallbackObject_ != nullptr) {
144             ret = tokenSyncCallbackObject_->UpdateRemoteHapTokenInfo(hapSync);
145         }
146         ret = tokenSyncKit->UpdateRemoteHapTokenInfo(hapSync);
147         if (ret != TOKEN_SYNC_SUCCESS) {
148             LOGE(ATM_DOMAIN, ATM_TAG, "Fail to update remote haptoken info, ret is %{public}d", ret);
149         }
150     }
151     deleteTokenList_.clear();
152     modifiedTokenList_.clear();
153 
154     LOGI(ATM_DOMAIN, ATM_TAG, "Over!");
155 }
156 
GetRemoteHapTokenInfo(const std::string & deviceID,AccessTokenID tokenID)157 int32_t TokenModifyNotifier::GetRemoteHapTokenInfo(const std::string& deviceID, AccessTokenID tokenID)
158 {
159     if (tokenSyncCallbackObject_ != nullptr) {
160         Utils::UniqueReadGuard<Utils::RWLock> infoGuard(this->Notifylock_);
161         int32_t ret = tokenSyncCallbackObject_->GetRemoteHapTokenInfo(deviceID, tokenID);
162         if (ret != TOKEN_SYNC_OPENSOURCE_DEVICE) {
163             return ret;
164         }
165     }
166 
167     LibraryLoader loader(TOKEN_SYNC_LIBPATH);
168     TokenSyncKitInterface* tokenSyncKit = loader.GetObject<TokenSyncKitInterface>();
169     if (tokenSyncKit == nullptr) {
170         LOGE(ATM_DOMAIN, ATM_TAG, "Dlopen libtokensync_sdk failed.");
171         return ERR_LOAD_SO_FAILED;
172     }
173     return tokenSyncKit->GetRemoteHapTokenInfo(deviceID, tokenID);
174 }
175 
RegisterTokenSyncCallback(const sptr<IRemoteObject> & callback)176 int32_t TokenModifyNotifier::RegisterTokenSyncCallback(const sptr<IRemoteObject>& callback)
177 {
178     Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->Notifylock_);
179     tokenSyncCallbackObject_ = new TokenSyncCallbackProxy(callback);
180     tokenSyncCallbackDeathRecipient_ = sptr<TokenSyncCallbackDeathRecipient>::MakeSptr();
181     callback->AddDeathRecipient(tokenSyncCallbackDeathRecipient_);
182     LOGI(ATM_DOMAIN, ATM_TAG, "Register token sync callback successful.");
183     return ERR_OK;
184 }
185 
UnRegisterTokenSyncCallback()186 int32_t TokenModifyNotifier::UnRegisterTokenSyncCallback()
187 {
188     Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->Notifylock_);
189     if (tokenSyncCallbackObject_ != nullptr && tokenSyncCallbackDeathRecipient_ != nullptr) {
190         tokenSyncCallbackObject_->AsObject()->RemoveDeathRecipient(tokenSyncCallbackDeathRecipient_);
191     }
192     tokenSyncCallbackObject_ = nullptr;
193     tokenSyncCallbackDeathRecipient_ = nullptr;
194     LOGI(ATM_DOMAIN, ATM_TAG, "Unregister token sync callback successful.");
195     return ERR_OK;
196 }
197 
198 #ifdef RESOURCESCHEDULE_FFRT_ENABLE
GetCurTaskNum()199 int32_t TokenModifyNotifier::GetCurTaskNum()
200 {
201     return curTaskNum_.load();
202 }
203 
AddCurTaskNum()204 void TokenModifyNotifier::AddCurTaskNum()
205 {
206     LOGI(ATM_DOMAIN, ATM_TAG, "Add task!");
207     curTaskNum_++;
208 }
209 
ReduceCurTaskNum()210 void TokenModifyNotifier::ReduceCurTaskNum()
211 {
212     LOGI(ATM_DOMAIN, ATM_TAG, "Reduce task!");
213     curTaskNum_--;
214 }
215 #endif
216 
NotifyTokenChangedIfNeed()217 void TokenModifyNotifier::NotifyTokenChangedIfNeed()
218 {
219 #ifdef RESOURCESCHEDULE_FFRT_ENABLE
220     if (GetCurTaskNum() > 1) {
221         LOGI(ATM_DOMAIN, ATM_TAG, "Has notify task! taskNum is %{public}d.", GetCurTaskNum());
222         return;
223     }
224 
225     std::string taskName = "TokenModify";
226     auto tokenModify = []() {
227         TokenModifyNotifier::GetInstance().NotifyTokenSyncTask();
228         TokenModifyNotifier::GetInstance().ReduceCurTaskNum();
229     };
230     ffrt::submit(tokenModify, {}, {}, ffrt::task_attr().qos(ffrt::qos_default).name(taskName.c_str()));
231     AddCurTaskNum();
232 #else
233     if (notifyTokenWorker_.GetCurTaskNum() > 1) {
234         LOGI(ATM_DOMAIN, ATM_TAG, " has notify task! taskNum is %{public}zu.", notifyTokenWorker_.GetCurTaskNum());
235         return;
236     }
237 
238     notifyTokenWorker_.AddTask([]() {
239         TokenModifyNotifier::GetInstance().NotifyTokenSyncTask();
240     });
241 #endif
242 }
243 } // namespace AccessToken
244 } // namespace Security
245 } // namespace OHOS
246