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_sync_manager_client.h"
17
18 #include "accesstoken_log.h"
19 #include "hap_token_info_for_sync_parcel.h"
20 #include "native_token_info_for_sync_parcel.h"
21 #include "iservice_registry.h"
22 #include "token_sync_death_recipient.h"
23 #include "token_sync_load_callback.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, "TokenSyncManagerClient"};
30 } // namespace
31
GetInstance()32 TokenSyncManagerClient& TokenSyncManagerClient::GetInstance()
33 {
34 static TokenSyncManagerClient instance;
35 return instance;
36 }
37
TokenSyncManagerClient()38 TokenSyncManagerClient::TokenSyncManagerClient()
39 {}
40
~TokenSyncManagerClient()41 TokenSyncManagerClient::~TokenSyncManagerClient()
42 {}
43
GetRemoteHapTokenInfo(const std::string & deviceID,AccessTokenID tokenID)44 int TokenSyncManagerClient::GetRemoteHapTokenInfo(const std::string& deviceID, AccessTokenID tokenID)
45 {
46 ACCESSTOKEN_LOG_DEBUG(LABEL, "called");
47 auto proxy = GetProxy();
48 if (proxy == nullptr) {
49 ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null");
50 return TOKEN_SYNC_IPC_ERROR;
51 }
52 return proxy->GetRemoteHapTokenInfo(deviceID, tokenID);
53 }
54
DeleteRemoteHapTokenInfo(AccessTokenID tokenID)55 int TokenSyncManagerClient::DeleteRemoteHapTokenInfo(AccessTokenID tokenID)
56 {
57 ACCESSTOKEN_LOG_DEBUG(LABEL, "called");
58 auto proxy = GetProxy();
59 if (proxy == nullptr) {
60 ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null");
61 return TOKEN_SYNC_IPC_ERROR;
62 }
63 return proxy->DeleteRemoteHapTokenInfo(tokenID);
64 }
65
UpdateRemoteHapTokenInfo(const HapTokenInfoForSync & tokenInfo)66 int TokenSyncManagerClient::UpdateRemoteHapTokenInfo(const HapTokenInfoForSync& tokenInfo)
67 {
68 ACCESSTOKEN_LOG_DEBUG(LABEL, "called");
69 auto proxy = GetProxy();
70 if (proxy == nullptr) {
71 ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null");
72 return TOKEN_SYNC_IPC_ERROR;
73 }
74 return proxy->UpdateRemoteHapTokenInfo(tokenInfo);
75 }
76
LoadTokenSync()77 void TokenSyncManagerClient::LoadTokenSync()
78 {
79 {
80 std::unique_lock<std::mutex> lock(tokenSyncMutex_);
81 ready_ = false;
82 }
83
84 auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
85 if (sam == nullptr) {
86 ACCESSTOKEN_LOG_ERROR(LABEL, "GetSystemAbilityManager return null");
87 return;
88 }
89
90 sptr<TokenSyncLoadCallback> ptrTokenSyncLoadCallback = new (std::nothrow) TokenSyncLoadCallback();
91 if (ptrTokenSyncLoadCallback == nullptr) {
92 ACCESSTOKEN_LOG_ERROR(LABEL, "new ptrTokenSyncLoadCallback fail.");
93 return;
94 }
95
96 int32_t result = sam->LoadSystemAbility(ITokenSyncManager::SA_ID_TOKENSYNC_MANAGER_SERVICE,
97 ptrTokenSyncLoadCallback);
98 if (result != ERR_OK) {
99 ACCESSTOKEN_LOG_ERROR(LABEL, "LoadSystemAbility %{public}d failed",
100 ITokenSyncManager::SA_ID_TOKENSYNC_MANAGER_SERVICE);
101 return;
102 }
103
104 {
105 std::unique_lock<std::mutex> lock(tokenSyncMutex_);
106 // wait_for release lock and block until time out(60s) or match the condition with notice
107 auto waitStatus = tokenSyncCon_.wait_for(lock, std::chrono::milliseconds(TOKEN_SYNC_LOAD_SA_TIMEOUT_MS),
108 [this]() { return ready_; });
109 if (!waitStatus) {
110 // time out or loadcallback fail
111 ACCESSTOKEN_LOG_WARN(LABEL, "tokensync load sa timeout");
112 return;
113 }
114 }
115
116 if (GetRemoteObject() == nullptr) {
117 ACCESSTOKEN_LOG_WARN(LABEL, "remote object is null");
118 return;
119 }
120 sptr<TokenSyncDeathRecipient> ptrTokenSyncDeathRecipient = new (std::nothrow) TokenSyncDeathRecipient();
121 if (ptrTokenSyncDeathRecipient == nullptr) {
122 ACCESSTOKEN_LOG_ERROR(LABEL, "new TokenSyncDeathRecipient fail.");
123 return;
124 }
125 // add death recipient to reset token_sync
126 GetRemoteObject()->AddDeathRecipient(ptrTokenSyncDeathRecipient);
127 }
128
FinishStartSASuccess(const sptr<IRemoteObject> & remoteObject)129 void TokenSyncManagerClient::FinishStartSASuccess(const sptr<IRemoteObject>& remoteObject)
130 {
131 ACCESSTOKEN_LOG_DEBUG(LABEL, "get tokensync sa success.");
132
133 SetRemoteObject(remoteObject);
134
135 // get lock which wait_for release and send a notice so that wait_for can out of block
136 {
137 std::unique_lock<std::mutex> lock(tokenSyncMutex_);
138 ready_ = true;
139 }
140
141 tokenSyncCon_.notify_one();
142 }
143
FinishStartSAFailed()144 void TokenSyncManagerClient::FinishStartSAFailed()
145 {
146 ACCESSTOKEN_LOG_DEBUG(LABEL, "get tokensync sa failed.");
147
148 SetRemoteObject(nullptr);
149
150 // get lock which wait_for release and send a notice
151 {
152 std::unique_lock<std::mutex> lock(tokenSyncMutex_);
153 ready_ = true;
154 }
155
156 tokenSyncCon_.notify_one();
157 }
158
SetRemoteObject(const sptr<IRemoteObject> & remoteObject)159 void TokenSyncManagerClient::SetRemoteObject(const sptr<IRemoteObject>& remoteObject)
160 {
161 std::unique_lock<std::mutex> lock(remoteMutex_);
162 remoteObject_ = remoteObject;
163 }
164
GetRemoteObject()165 sptr<IRemoteObject> TokenSyncManagerClient::GetRemoteObject()
166 {
167 std::unique_lock<std::mutex> lock(remoteMutex_);
168 return remoteObject_;
169 }
170
OnRemoteDiedHandle()171 void TokenSyncManagerClient::OnRemoteDiedHandle()
172 {
173 ACCESSTOKEN_LOG_DEBUG(LABEL, "Remote service died.");
174
175 SetRemoteObject(nullptr);
176
177 std::unique_lock<std::mutex> lock(tokenSyncMutex_);
178 ready_ = false;
179 }
180
GetProxy()181 sptr<ITokenSyncManager> TokenSyncManagerClient::GetProxy()
182 {
183 if (GetRemoteObject() == nullptr) {
184 LoadTokenSync();
185 }
186
187 auto proxy = iface_cast<ITokenSyncManager>(GetRemoteObject());
188 if (proxy == nullptr) {
189 ACCESSTOKEN_LOG_WARN(LABEL, "iface_cast get null");
190 return nullptr;
191 }
192 return proxy;
193 }
194 } // namespace AccessToken
195 } // namespace Security
196 } // namespace OHOS
197