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