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