• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 IPC_TRANSACTORS_H
17 #define IPC_TRANSACTORS_H
18 
19 #include <queue>
20 #include <future>
21 
22 namespace OHOS::uitest {
23     enum TransactionType : uint8_t {
24         INVALID, CALL, REPLY, HANDSHAKE, ACK, EXIT
25     };
26 
27     /**Represents the api invocation call/reply message.*/
28     struct TransactionMessage {
29         uint32_t id_;
30         TransactionType type_;
31         std::string apiId_;
32         std::string callerParcel_;
33         std::string paramsParcel_;
34         std::string resultParcel_;
35     };
36 
37     /**Api request/reply message transceiver.*/
38     class MessageTransceiver {
39     public:
40         enum PollStatus : uint8_t {
41             SUCCESS,
42             ABORT_WAIT_TIMEOUT,
43             ABORT_CONNECTION_DIED,
44             ABORT_REQUEST_EXIT
45         };
46 
47         virtual ~MessageTransceiver() = default;
48 
49         virtual bool Initialize() = 0;
50 
51         void OnReceiveMessage(const TransactionMessage &message);
52 
53         void EmitCall(std::string_view apiId, std::string_view caller, std::string_view params);
54 
55         void EmitReply(const TransactionMessage &request, std::string_view reply);
56 
57         void EmitHandshake();
58 
59         void EmitAck(const TransactionMessage &handshake);
60 
61         void EmitExit();
62 
63         void SetMessageFilter(std::function<bool(TransactionType)>);
64 
65         PollStatus PollCallReply(TransactionMessage &out, uint64_t timeoutMs);
66 
67         void ScheduleCheckConnection(bool emitHandshake);
68 
69         bool EnsureConnectionAlive(uint64_t timeoutMs);
70 
71         virtual void Finalize();
72 
73     protected:
74         virtual void DoEmitMessage(const TransactionMessage &message) = 0;
75 
76     private:
77         void EmitMessage(const TransactionMessage &message);
78 
79         static constexpr uint32_t FLAG_CONNECT_DIED = 1 << 0;
80         static constexpr uint32_t FLAG_REQUEST_EXIT = 1 << 1;
81         std::function<bool(TransactionType)> messageFilter_;
82         std::atomic<bool> autoHandshaking_ = false;
83         std::future<void> handshakeFuture_;
84         std::atomic<uint32_t> extraFlags_ = 0;
85         std::atomic<uint64_t> lastIncomingMessageMillis_ = 0;
86         std::atomic<uint64_t> lastOutgoingMessageMillis_ = 0;
87         std::condition_variable busyCond_;
88         std::mutex queueLock_;
89         std::queue<TransactionMessage> messageQueue_;
90     };
91 
92     /**Represents the notify-alive timeout between client and server (2s).*/
93     constexpr uint64_t WATCH_DOG_TIMEOUT_MS = 2000;
94 
95     /**Represents the api transaction participant(client/server).*/
96     class Transactor {
97     public:
98         virtual bool Initialize();
99 
100         virtual void Finalize();
101 
102     protected:
103         virtual std::unique_ptr<MessageTransceiver> CreateTransceiver() = 0;
104 
GetMessageFilter()105         virtual std::function<bool(TransactionType)> GetMessageFilter()
106         {
107             return nullptr;
108         }
109 
110         std::unique_ptr<MessageTransceiver> transceiver_;
111         static constexpr uint32_t EXIT_CODE_SUCCESS = 0;
112         static constexpr uint32_t EXIT_CODE_FAILURE = 1;
113         static constexpr uint32_t WAIT_TRANSACTION_MS = WATCH_DOG_TIMEOUT_MS / 100;
114     };
115 
116     /**Represents the api transaction server.*/
117     class TransactionServer : public Transactor {
118     public:
119         uint32_t RunLoop();
120 
121         void SetCallFunction(std::function<std::string(std::string_view, std::string_view, std::string_view)> func);
122 
123     private:
124         // use function pointer here to keep independent from 'core', which are not wanted by the client-side
125         std::function<std::string(std::string_view, std::string_view, std::string_view)> callFunc_;
126     };
127 
128     /**Represents the api transaction client.*/
129     class TransactionClient : public Transactor {
130     public:
131         std::string InvokeApi(std::string_view apiId, std::string_view caller, std::string_view params);
132 
133         /**Finalize both self side and server side.*/
134         void Finalize() override;
135 
136     private:
137         std::mutex stateMtx_;
138         std::string processingApi_;
139         bool connectionDied_ = false;
140     };
141 }
142 
143 #endif