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