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 #include "extern_api.h" 17 #include "ipc_transactors_impl.h" 18 19 namespace OHOS::uitest { 20 using namespace std; 21 using namespace OHOS::EventFwk; 22 static constexpr string_view ACTION_CALL = "uitest.api.transaction.call_"; 23 static constexpr string_view ACTION_REPLY = "uitest.api.transaction.reply_"; 24 25 class CommonEventForwarder : public CommonEventSubscriber { 26 public: CommonEventForwarder(const CommonEventSubscribeInfo & info,function<void (const CommonEventData &)> processor)27 explicit CommonEventForwarder(const CommonEventSubscribeInfo &info, function<void(const CommonEventData &)> 28 processor) : CommonEventSubscriber(info), processor_(move(processor)) {} 29 ~CommonEventForwarder()30 virtual ~CommonEventForwarder() {} 31 OnReceiveEvent(const CommonEventData & data)32 void OnReceiveEvent(const CommonEventData &data) override 33 { 34 if (processor_ != nullptr) { 35 processor_(data); 36 } 37 } 38 39 private: 40 const function<void(const CommonEventData &)> processor_; 41 }; 42 TransactionTransceiverImpl(string_view token,bool asServer)43 TransactionTransceiverImpl::TransactionTransceiverImpl(string_view token, bool asServer) 44 : asServer_(asServer), token_(token) {} 45 Initialize()46 bool TransactionTransceiverImpl::Initialize() 47 { 48 const auto event = string(asServer_ ? ACTION_CALL : ACTION_REPLY) + token_; 49 MatchingSkills matchingSkills; 50 matchingSkills.AddEvent(event); 51 CommonEventSubscribeInfo info(matchingSkills); 52 subscriber_ = make_shared<CommonEventForwarder>(info, [this](const CommonEventData &event) { 53 auto &want = event.GetWant(); 54 auto message = TransactionMessage {}; 55 message.id_ = want.GetLongParam("id", -1); 56 message.type_ = static_cast<TransactionType>(want.GetIntParam("type", TransactionType::INVALID)); 57 message.apiId_ = want.GetStringParam("apiId"); 58 message.callerParcel_ = want.GetStringParam("callerParcel"); 59 message.paramsParcel_ = want.GetStringParam("paramsParcel"); 60 message.resultParcel_ = want.GetStringParam("resultParcel"); 61 this->OnReceiveMessage(message); 62 }); 63 if (subscriber_ == nullptr) { 64 return false; 65 } 66 return CommonEventManager::SubscribeCommonEvent(subscriber_); 67 } 68 Finalize()69 void TransactionTransceiverImpl::Finalize() 70 { 71 MessageTransceiver::Finalize(); 72 73 if (subscriber_ != nullptr) { 74 CommonEventManager::UnSubscribeCommonEvent(this->subscriber_); 75 } 76 } 77 DoEmitMessage(const TransactionMessage & message)78 void TransactionTransceiverImpl::DoEmitMessage(const TransactionMessage &message) 79 { 80 Want want; 81 want.SetAction(string(asServer_ ? ACTION_REPLY : ACTION_CALL) + token_); 82 CommonEventData event; 83 want.SetParam("id", (long) (message.id_)); 84 want.SetParam("type", message.type_); 85 want.SetParam("apiId", message.apiId_); 86 want.SetParam("callerParcel", message.callerParcel_); 87 want.SetParam("paramsParcel", message.paramsParcel_); 88 want.SetParam("resultParcel", message.resultParcel_); 89 event.SetWant(want); 90 CommonEventManager::PublishCommonEvent(event); 91 } 92 TransactionServerImpl(string_view token)93 TransactionServerImpl::TransactionServerImpl(string_view token) : token_(token) {}; 94 ~TransactionServerImpl()95 TransactionServerImpl::~TransactionServerImpl() {}; 96 Initialize()97 bool TransactionServerImpl::Initialize() 98 { 99 if (!Transactor::Initialize()) { 100 return false; 101 } 102 // schedule connection-checking on initialization 103 transceiver_->ScheduleCheckConnection(false); 104 return true; 105 } 106 CreateTransceiver()107 unique_ptr<MessageTransceiver> TransactionServerImpl::CreateTransceiver() 108 { 109 return make_unique<TransactionTransceiverImpl>(token_, true); 110 } 111 TransactionClientImpl(string_view token)112 TransactionClientImpl::TransactionClientImpl(string_view token) : token_(token) {}; 113 ~TransactionClientImpl()114 TransactionClientImpl::~TransactionClientImpl() {}; 115 116 static constexpr uint64_t WAIT_CONNECTION_TIMEOUT_MS = 1000; 117 Initialize()118 bool TransactionClientImpl::Initialize() 119 { 120 if (!Transactor::Initialize()) { 121 return false; 122 } 123 // schedule connection-checking with auto-handshaking, and wait-for first interaction established 124 transceiver_->ScheduleCheckConnection(true); 125 LOG_I("Start checking CS-interaction"); 126 if (!transceiver_->EnsureConnectionAlive(WAIT_CONNECTION_TIMEOUT_MS)) { 127 LOG_E("Wait CS-interaction timed out in %{public}llu ms", WAIT_CONNECTION_TIMEOUT_MS); 128 return false; 129 } 130 LOG_I("Check CS-interaction succeed"); 131 return true; 132 } 133 CreateTransceiver()134 unique_ptr<MessageTransceiver> TransactionClientImpl::CreateTransceiver() 135 { 136 return make_unique<TransactionTransceiverImpl>(token_, false); 137 } 138 139 static unique_ptr<TransactionClientImpl> sClient = nullptr; 140 static atomic<bool> sSetupCalled = false; 141 142 /**Exported transaction-client initialization callback function.*/ SetupTransactionEnv(string_view token)143 bool SetupTransactionEnv(string_view token) 144 { 145 if (!sSetupCalled.load()) { 146 if (sClient == nullptr) { 147 sClient = make_unique<TransactionClientImpl>(token); 148 } 149 if (!sClient->Initialize()) { 150 LOG_E("SetupTransactionEnv failed"); 151 } 152 sSetupCalled.store(true); 153 } 154 return true; 155 } 156 157 /**Exported transaction client api-calling function.*/ TransactionClientFunc(string_view apiId,string_view caller,string_view params)158 string TransactionClientFunc(string_view apiId, string_view caller, string_view params) 159 { 160 DCHECK(sClient != nullptr && sSetupCalled.load()); 161 return sClient->InvokeApi(apiId, caller, params); 162 } 163 164 /**Exported transaction-client dispose callback function.*/ DisposeTransactionEnv()165 void DisposeTransactionEnv() 166 { 167 if (sSetupCalled.load() && sClient != nullptr) { 168 sClient->Finalize(); 169 sSetupCalled.store(false); 170 } 171 } 172 }