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 #ifndef REMOTE_COMMAND_EXECUTOR_H
17 #define REMOTE_COMMAND_EXECUTOR_H
18 
19 #include <deque>
20 #include <mutex>
21 
22 #include "accesstoken_log.h"
23 #include "base_remote_command.h"
24 #include "remote_command_factory.h"
25 #include "rpc_channel.h"
26 
27 namespace OHOS {
28 namespace Security {
29 namespace AccessToken {
30 class RemoteCommandExecutor final : public std::enable_shared_from_this<RemoteCommandExecutor>  {
31 public:
32     explicit RemoteCommandExecutor(const std::string &targetNodeId);
33     virtual ~RemoteCommandExecutor();
34 
GetChannel()35     const std::shared_ptr<RpcChannel>& GetChannel() const
36     {
37         return ptrChannel_;
38     }
SetChannel(const std::shared_ptr<RpcChannel> & ptrChannel)39     void SetChannel(const std::shared_ptr<RpcChannel>& ptrChannel)
40     {
41         ptrChannel_ = ptrChannel;
42     }
43 
44     /**
45      * @brief Factory method to create a rpc channel. we will only create SoftBusChannel by now.
46      *
47      * @param targetNodeId target device node id(udid)
48      * @return Returns <b>a shared_ptr</b> if the operation is successful, returns <b>nullptr</b> otherwise.
49      * @see SoftBusChannel
50      * @since 1.0
51      * @version 1.0
52      */
53     static const std::shared_ptr<RpcChannel> CreateChannel(const std::string &targetNodeId);
54 
55     /**
56      * @brief Process one command given.
57      *
58      * @param ptrCommand BaseRemoteCommand to execute.
59      * @return Returns <b>SUCCESS</b> if the operation is successful, returns <b>minus integer</b> otherwise.
60      * @see void
61      * @since 1.0
62      * @version 1.0
63      */
64     int ProcessOneCommand(const std::shared_ptr<BaseRemoteCommand>& ptrCommand);
65 
66     /**
67      * @brief Add one command into the buffer
68      *
69      * @param ptrCommand BaseRemoteCommand to execute.
70      * @return Returns <b>SUCCESS</b> if the operation is successful, returns <b>INVALID_COMMAND</b> otherwise.
71      * @see ProcessBufferedCommands
72      * @since 1.0
73      * @version 1.0
74      */
75     int AddCommand(const std::shared_ptr<BaseRemoteCommand>& ptrCommand);
76 
77     /**
78      * @brief Process all the command in the buffer
79      *
80      * @param standalone true if run in a new thread or event runner, otherwise false.
81      * @return Returns <b>SUCCESS</b> if the operation is successful, returns <b>FAILURE</b> otherwise.
82      * @see AddCommand ProcessOneCommand
83      * @since 1.0
84      * @version 1.0
85      */
86     int ProcessBufferedCommands(bool standalone = false);
87 
88     /**
89      * @brief Process all the command in the buffer within a new thread. in deconstruct, we need to join this thread if
90      * needed.
91      *
92      * @param ptrCommand BaseRemoteCommand to execute.
93      * @return void
94      * @see ProcessBufferedCommands
95      * @since 1.0
96      * @version 1.0
97      */
98     void ProcessBufferedCommandsWithThread();
99 
100 private:
101     /**
102      * @brief execute a command in a specific place.
103      * for remote command, transfor the command json string by channel to softbus, and wait for softbus to response a
104      * json string. while remote response a json string, construct a remote command and finish it.
105      * if command buffer is empty, close the rpc channel.
106      *
107      * @param ptrCommand BaseRemoteCommand to execute.
108      * @param isRemote where to run. true for remote, false for local.
109      * @return Returns <b>SUCCESS</b> if the operation is successful, returns <b>FAILURE</b> otherwise.
110      * @see ProcessBufferedCommands
111      * @since 1.0
112      * @version 1.0
113      */
114     int ExecuteRemoteCommand(const std::shared_ptr<BaseRemoteCommand>& ptrCommand, bool isRemote);
115 
116     /**
117      * @brief create a rpc channel if not exist.
118      *
119      * @param ptrCommand BaseRemoteCommand to execute.
120      * @param isRemote where to run. true for remote, false for local.
121      * @return void
122      * @see ProcessBufferedCommands
123      * @since 1.0
124      * @version 1.0
125      */
126     void CreateChannelIfNeeded();
127 
128     /**
129      * @brief finish a command
130      *
131      * @param ptrCommand BaseRemoteCommand to execute.
132      * @return Returns <b>SUCCESS</b> if the operation is successful, returns <b>FAILURE</b> otherwise.
133      * @see ProcessBufferedCommands
134      * @since 1.0
135      * @version 1.0
136      */
137     int ClientProcessResult(const std::shared_ptr<BaseRemoteCommand>& ptrCommand);
138 
139 private:
140     // target device node id(udid)
141     std::string targetNodeId_;
142 
143     // cached channel for buffered commands
144     std::shared_ptr<RpcChannel> ptrChannel_;
145 
146     // mutex to lock commands buffer for concurrent access.
147     std::recursive_mutex mutex_;
148 
149     // commands buffer
150     std::deque<std::shared_ptr<BaseRemoteCommand>> commands_;
151 
152     // consumer running flag, true if the consumer is RUNNING, false otherwise. @see ProcessBufferedCommands
153     bool running_;
154 };
155 }  // namespace AccessToken
156 }  // namespace Security
157 }  // namespace OHOS
158 #endif  // REMOTE_COMMAND_EXECUTOR_H
159