• 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 "remote_command_manager.h"
17 #include <thread>
18 #include "device_info_manager.h"
19 #include "sync_remote_native_token_command.h"
20 #include "remote_command_factory.h"
21 #include "token_sync_event_handler.h"
22 #include "token_sync_manager_service.h"
23 #include "accesstoken_kit.h"
24 #include "constant_common.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, "RemoteCommandManager"};
31 }
RemoteCommandManager()32 RemoteCommandManager::RemoteCommandManager() : executors_(), mutex_()
33 {
34     ACCESSTOKEN_LOG_DEBUG(LABEL, "RemoteCommandManager()");
35 }
36 
~RemoteCommandManager()37 RemoteCommandManager::~RemoteCommandManager()
38 {
39     ACCESSTOKEN_LOG_DEBUG(LABEL, "~RemoteCommandManager()");
40 }
41 
GetInstance()42 RemoteCommandManager &RemoteCommandManager::GetInstance()
43 {
44     static RemoteCommandManager instance;
45     return instance;
46 }
47 
Init()48 void RemoteCommandManager::Init()
49 {
50     ACCESSTOKEN_LOG_DEBUG(LABEL, "Init()");
51 }
52 
AddCommand(const std::string & udid,const std::shared_ptr<BaseRemoteCommand> & command)53 int RemoteCommandManager::AddCommand(const std::string &udid, const std::shared_ptr<BaseRemoteCommand>& command)
54 {
55     if (udid.empty() || command == nullptr) {
56         ACCESSTOKEN_LOG_WARN(LABEL, "invalid udid, or null command");
57         return Constant::FAILURE;
58     }
59     ACCESSTOKEN_LOG_INFO(LABEL, "add uniqueId");
60 
61     std::shared_ptr<RemoteCommandExecutor> executor = GetOrCreateRemoteCommandExecutor(udid);
62     if (executor == nullptr) {
63         ACCESSTOKEN_LOG_ERROR(LABEL, "cannot get or create remote command executor");
64         return Constant::FAILURE;
65     }
66 
67     int result = executor->AddCommand(command);
68     ACCESSTOKEN_LOG_INFO(LABEL, "add command result: %{public}d ", result);
69     return result;
70 }
71 
RemoveCommand(const std::string & udid)72 void RemoteCommandManager::RemoveCommand(const std::string &udid)
73 {
74     ACCESSTOKEN_LOG_INFO(LABEL, "remove command");
75     executors_.erase(udid);
76 }
77 
ExecuteCommand(const std::string & udid,const std::shared_ptr<BaseRemoteCommand> & command)78 int RemoteCommandManager::ExecuteCommand(const std::string &udid, const std::shared_ptr<BaseRemoteCommand>& command)
79 {
80     if (udid.empty() || command == nullptr) {
81         ACCESSTOKEN_LOG_WARN(LABEL, "invalid udid: %{public}s, or null command",
82             ConstantCommon::EncryptDevId(udid).c_str());
83         return Constant::FAILURE;
84     }
85     std::string uniqueId = command->remoteProtocol_.uniqueId;
86     ACCESSTOKEN_LOG_INFO(LABEL, "start with udid: %{public}s , uniqueId: %{public}s ",
87         ConstantCommon::EncryptDevId(udid).c_str(), uniqueId.c_str());
88 
89     std::shared_ptr<RemoteCommandExecutor> executor = GetOrCreateRemoteCommandExecutor(udid);
90     if (executor == nullptr) {
91         ACCESSTOKEN_LOG_ERROR(LABEL, "cannot get or create remote command executor");
92         return Constant::FAILURE;
93     }
94 
95     int result = executor->ProcessOneCommand(command);
96     ACCESSTOKEN_LOG_INFO(LABEL, "remoteCommandExecutor processOneCommand result:%{public}d ", result);
97     return result;
98 }
99 
ProcessDeviceCommandImmediately(const std::string & udid)100 int RemoteCommandManager::ProcessDeviceCommandImmediately(const std::string &udid)
101 {
102     if (udid.empty()) {
103         ACCESSTOKEN_LOG_WARN(LABEL, "invalid udid: %{public}s", ConstantCommon::EncryptDevId(udid).c_str());
104         return Constant::FAILURE;
105     }
106     ACCESSTOKEN_LOG_INFO(LABEL, "start with udid:%{public}s ", ConstantCommon::EncryptDevId(udid).c_str());
107     auto executorIt = executors_.find(udid);
108     if (executorIt == executors_.end()) {
109         ACCESSTOKEN_LOG_ERROR(LABEL, "no executor found, udid:%{public}s", ConstantCommon::EncryptDevId(udid).c_str());
110         return Constant::FAILURE;
111     }
112 
113     auto executor = executorIt->second;
114     if (executor == nullptr) {
115         ACCESSTOKEN_LOG_INFO(LABEL, "RemoteCommandExecutor is null for udid %{public}s ",
116             ConstantCommon::EncryptDevId(udid).c_str());
117         return Constant::FAILURE;
118     }
119 
120     int result = executor->ProcessBufferedCommands();
121     ACCESSTOKEN_LOG_INFO(LABEL, "processBufferedCommands result: %{public}d", result);
122     return result;
123 }
124 
Loop()125 int RemoteCommandManager::Loop()
126 {
127     ACCESSTOKEN_LOG_INFO(LABEL, "start");
128     for (auto it = executors_.begin(); it != executors_.end(); it++) {
129         ACCESSTOKEN_LOG_INFO(LABEL, "udid:%{public}s", ConstantCommon::EncryptDevId(it->first).c_str());
130         (*it).second->ProcessBufferedCommandsWithThread();
131     }
132     return Constant::SUCCESS;
133 }
134 
135 /**
136  * caller: service connection listener
137  */
Clear()138 void RemoteCommandManager::Clear()
139 {
140     ACCESSTOKEN_LOG_INFO(LABEL, "remove all remote command executors.");
141 
142     std::map<std::string, std::shared_ptr<RemoteCommandExecutor>> dummy;
143     executors_.swap(dummy);
144     executors_.clear();
145 }
146 
147 /**
148  * caller: device listener
149  */
NotifyDeviceOnline(const std::string & nodeId)150 int RemoteCommandManager::NotifyDeviceOnline(const std::string &nodeId)
151 {
152     if (!DataValidator::IsDeviceIdValid(nodeId)) {
153         ACCESSTOKEN_LOG_INFO(LABEL, "invalid nodeId: %{public}s", ConstantCommon::EncryptDevId(nodeId).c_str());
154         return Constant::FAILURE;
155     }
156     ACCESSTOKEN_LOG_INFO(LABEL, "operation start with nodeId:  %{public}s",
157         ConstantCommon::EncryptDevId(nodeId).c_str());
158 
159     auto executor = GetOrCreateRemoteCommandExecutor(nodeId);
160     std::unique_lock<std::mutex> lock(mutex_);
161     if (executor == nullptr) {
162         ACCESSTOKEN_LOG_ERROR(LABEL, "cannot get or create remote command executor");
163         return Constant::FAILURE;
164     }
165 
166     if (executor->GetChannel() == nullptr) {
167         auto channel = RemoteCommandExecutor::CreateChannel(nodeId);
168         if (channel == nullptr) {
169             ACCESSTOKEN_LOG_ERROR(LABEL, "create channel failed.");
170             return Constant::FAILURE;
171         }
172         executor->SetChannel(channel);
173     }
174 
175     lock.unlock();
176 
177     std::function<void()> delayed = ([=]() {
178         const std::shared_ptr<SyncRemoteNativeTokenCommand> syncRemoteNativeTokenCommand =
179             RemoteCommandFactory::GetInstance().NewSyncRemoteNativeTokenCommand(ConstantCommon::GetLocalDeviceId(),
180             nodeId);
181 
182         const int32_t resultCode = RemoteCommandManager::GetInstance().ExecuteCommand(
183             nodeId, syncRemoteNativeTokenCommand);
184         if (resultCode != Constant::SUCCESS) {
185             ACCESSTOKEN_LOG_INFO(LABEL,
186                 "%{public}s: RemoteExecutorManager executeCommand syncRemoteNativeTokenCommand failed, return %d",
187                 __func__, resultCode);
188             return;
189         }
190     });
191 
192     std::shared_ptr<TokenSyncEventHandler> handler =
193         DelayedSingleton<TokenSyncManagerService>::GetInstance()->GetSendEventHandler();
194     if (handler == nullptr) {
195         ACCESSTOKEN_LOG_ERROR(LABEL, "fail to get EventHandler");
196         return Constant::FAILURE;
197     }
198     handler->ProxyPostTask(delayed, "HandleDeviceOnline", Constant::DELAY_SYNC_TOKEN_MS);
199 
200     return Constant::SUCCESS;
201 }
202 
203 /**
204  * caller: device listener
205  */
NotifyDeviceOffline(const std::string & nodeId)206 int RemoteCommandManager::NotifyDeviceOffline(const std::string &nodeId)
207 {
208     if (!DataValidator::IsDeviceIdValid(nodeId)) {
209         ACCESSTOKEN_LOG_INFO(LABEL, "invalid nodeId: %{public}s", ConstantCommon::EncryptDevId(nodeId).c_str());
210         return Constant::FAILURE;
211     }
212     ACCESSTOKEN_LOG_INFO(LABEL, "operation start with nodeId:  %{public}s",
213         ConstantCommon::EncryptDevId(nodeId).c_str());
214 
215     auto channel = GetExecutorChannel(nodeId);
216     if (channel != nullptr) {
217         channel->Release();
218     }
219 
220     std::unique_lock<std::mutex> lock(mutex_);
221     RemoveCommand(nodeId);
222     lock.unlock();
223 
224     DeviceInfo devInfo;
225     bool result = DeviceInfoManager::GetInstance().GetDeviceInfo(nodeId, DeviceIdType::UNKNOWN, devInfo);
226     if (!result) {
227         ACCESSTOKEN_LOG_INFO(LABEL, "get remote networkId failed");
228         return Constant::FAILURE;
229     }
230     std::string uniqueDeviceId = devInfo.deviceId.uniqueDeviceId;
231     std::function<void()> delayed = ([=]() {
232         AccessTokenKit::DeleteRemoteDeviceTokens(uniqueDeviceId);
233     });
234 
235     std::shared_ptr<TokenSyncEventHandler> handler =
236         DelayedSingleton<TokenSyncManagerService>::GetInstance()->GetSendEventHandler();
237     if (handler == nullptr) {
238         ACCESSTOKEN_LOG_ERROR(LABEL, "fail to get EventHandler");
239         return Constant::FAILURE;
240     }
241     handler->ProxyPostTask(delayed, "HandleDeviceOffline");
242 
243     ACCESSTOKEN_LOG_INFO(LABEL, "complete");
244     return Constant::SUCCESS;
245 }
246 
GetOrCreateRemoteCommandExecutor(const std::string & nodeId)247 std::shared_ptr<RemoteCommandExecutor> RemoteCommandManager::GetOrCreateRemoteCommandExecutor(const std::string &nodeId)
248 {
249     ACCESSTOKEN_LOG_DEBUG(LABEL, "begin, nodeId %{public}s", ConstantCommon::EncryptDevId(nodeId).c_str());
250 
251     std::unique_lock<std::mutex> lock(mutex_);
252     auto executorIter = executors_.find(nodeId);
253     if (executorIter != executors_.end()) {
254         return executorIter->second;
255     }
256 
257     auto executor = std::make_shared<RemoteCommandExecutor>(nodeId);
258     if (executor == nullptr) {
259         ACCESSTOKEN_LOG_INFO(LABEL, "cannot create remote command executor, nodeId: %{public}s",
260             ConstantCommon::EncryptDevId(nodeId).c_str());
261         return nullptr;
262     }
263 
264     executors_.insert(std::pair<std::string, std::shared_ptr<RemoteCommandExecutor>>(nodeId, executor));
265     ACCESSTOKEN_LOG_DEBUG(LABEL, "executor added, nodeId: %{public}s", ConstantCommon::EncryptDevId(nodeId).c_str());
266     return executor;
267 }
268 
269 /**
270  * caller: session listener(onBytesReceived), device listener(offline)
271  */
GetExecutorChannel(const std::string & nodeId)272 std::shared_ptr<RpcChannel> RemoteCommandManager::GetExecutorChannel(const std::string &nodeId)
273 {
274     ACCESSTOKEN_LOG_DEBUG(LABEL, "convert udid start, nodeId:%{public}s", ConstantCommon::EncryptDevId(nodeId).c_str());
275     std::string udid = DeviceInfoManager::GetInstance().ConvertToUniqueDeviceIdOrFetch(nodeId);
276     if (!DataValidator::IsDeviceIdValid(udid)) {
277         ACCESSTOKEN_LOG_WARN(
278             LABEL, "converted udid is invalid, nodeId:%{public}s", ConstantCommon::EncryptDevId(nodeId).c_str());
279         return nullptr;
280     }
281     std::map<std::string, std::shared_ptr<RemoteCommandExecutor>>::iterator iter = executors_.find(udid);
282     if (iter == executors_.end()) {
283         ACCESSTOKEN_LOG_INFO(LABEL, "executor not found");
284         return nullptr;
285     }
286     std::shared_ptr<RemoteCommandExecutor> executor = iter->second;
287     if (executor == nullptr) {
288         ACCESSTOKEN_LOG_INFO(LABEL, "executor is null");
289         return nullptr;
290     }
291     return executor->GetChannel();
292 }
293 }  // namespace AccessToken
294 }  // namespace Security
295 }  // namespace OHOS
296