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(), ConstantCommon::EncryptDevId(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 return Constant::SUCCESS;
178 }
179
180 /**
181 * caller: device listener
182 */
NotifyDeviceOffline(const std::string & nodeId)183 int RemoteCommandManager::NotifyDeviceOffline(const std::string &nodeId)
184 {
185 if (!DataValidator::IsDeviceIdValid(nodeId)) {
186 ACCESSTOKEN_LOG_INFO(LABEL, "invalid nodeId: %{public}s", ConstantCommon::EncryptDevId(nodeId).c_str());
187 return Constant::FAILURE;
188 }
189 ACCESSTOKEN_LOG_INFO(LABEL, "operation start with nodeId: %{public}s",
190 ConstantCommon::EncryptDevId(nodeId).c_str());
191
192 auto channel = GetExecutorChannel(nodeId);
193 if (channel != nullptr) {
194 channel->Release();
195 }
196
197 std::unique_lock<std::mutex> lock(mutex_);
198 RemoveCommand(nodeId);
199 lock.unlock();
200
201 DeviceInfo devInfo;
202 bool result = DeviceInfoManager::GetInstance().GetDeviceInfo(nodeId, DeviceIdType::UNKNOWN, devInfo);
203 if (!result) {
204 ACCESSTOKEN_LOG_INFO(LABEL, "get remote networkId failed");
205 return Constant::FAILURE;
206 }
207 std::string uniqueDeviceId = devInfo.deviceId.uniqueDeviceId;
208 std::function<void()> delayed = ([=]() {
209 AccessTokenKit::DeleteRemoteDeviceTokens(uniqueDeviceId);
210 });
211
212 std::shared_ptr<TokenSyncEventHandler> handler =
213 DelayedSingleton<TokenSyncManagerService>::GetInstance()->GetSendEventHandler();
214 if (handler == nullptr) {
215 ACCESSTOKEN_LOG_ERROR(LABEL, "fail to get EventHandler");
216 return Constant::FAILURE;
217 }
218 handler->ProxyPostTask(delayed, "HandleDeviceOffline");
219
220 ACCESSTOKEN_LOG_INFO(LABEL, "complete");
221 return Constant::SUCCESS;
222 }
223
GetOrCreateRemoteCommandExecutor(const std::string & nodeId)224 std::shared_ptr<RemoteCommandExecutor> RemoteCommandManager::GetOrCreateRemoteCommandExecutor(const std::string &nodeId)
225 {
226 ACCESSTOKEN_LOG_DEBUG(LABEL, "begin, nodeId %{public}s", ConstantCommon::EncryptDevId(nodeId).c_str());
227
228 std::unique_lock<std::mutex> lock(mutex_);
229 auto executorIter = executors_.find(nodeId);
230 if (executorIter != executors_.end()) {
231 return executorIter->second;
232 }
233
234 auto executor = std::make_shared<RemoteCommandExecutor>(nodeId);
235 executors_.insert(std::pair<std::string, std::shared_ptr<RemoteCommandExecutor>>(nodeId, executor));
236 ACCESSTOKEN_LOG_DEBUG(LABEL, "executor added, nodeId: %{public}s", ConstantCommon::EncryptDevId(nodeId).c_str());
237 return executor;
238 }
239
240 /**
241 * caller: session listener(onBytesReceived), device listener(offline)
242 */
GetExecutorChannel(const std::string & nodeId)243 std::shared_ptr<RpcChannel> RemoteCommandManager::GetExecutorChannel(const std::string &nodeId)
244 {
245 ACCESSTOKEN_LOG_DEBUG(LABEL, "convert udid start, nodeId:%{public}s", ConstantCommon::EncryptDevId(nodeId).c_str());
246 std::string udid = DeviceInfoManager::GetInstance().ConvertToUniqueDeviceIdOrFetch(nodeId);
247 if (!DataValidator::IsDeviceIdValid(udid)) {
248 ACCESSTOKEN_LOG_WARN(
249 LABEL, "converted udid is invalid, nodeId:%{public}s", ConstantCommon::EncryptDevId(nodeId).c_str());
250 return nullptr;
251 }
252 std::map<std::string, std::shared_ptr<RemoteCommandExecutor>>::iterator iter = executors_.find(udid);
253 if (iter == executors_.end()) {
254 ACCESSTOKEN_LOG_INFO(LABEL, "executor not found");
255 return nullptr;
256 }
257 std::shared_ptr<RemoteCommandExecutor> executor = iter->second;
258 if (executor == nullptr) {
259 ACCESSTOKEN_LOG_INFO(LABEL, "executor is null");
260 return nullptr;
261 }
262 return executor->GetChannel();
263 }
264 } // namespace AccessToken
265 } // namespace Security
266 } // namespace OHOS
267