1886da342Sopenharmony_ci/* 2886da342Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 3886da342Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4886da342Sopenharmony_ci * you may not use this file except in compliance with the License. 5886da342Sopenharmony_ci * You may obtain a copy of the License at 6886da342Sopenharmony_ci * 7886da342Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8886da342Sopenharmony_ci * 9886da342Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10886da342Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11886da342Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12886da342Sopenharmony_ci * See the License for the specific language governing permissions and 13886da342Sopenharmony_ci * limitations under the License. 14886da342Sopenharmony_ci */ 15886da342Sopenharmony_ci 16886da342Sopenharmony_ci#include "uitest_ffi.h" 17886da342Sopenharmony_ci 18886da342Sopenharmony_ci#include <cstdlib> 19886da342Sopenharmony_ci#include <grp.h> 20886da342Sopenharmony_ci#include <pthread.h> 21886da342Sopenharmony_ci#include <pwd.h> 22886da342Sopenharmony_ci#include <sched.h> 23886da342Sopenharmony_ci#include <future> 24886da342Sopenharmony_ci#include <queue> 25886da342Sopenharmony_ci#include <set> 26886da342Sopenharmony_ci#include <string> 27886da342Sopenharmony_ci#include <sys/resource.h> 28886da342Sopenharmony_ci#include <sys/syscall.h> 29886da342Sopenharmony_ci#include <sys/types.h> 30886da342Sopenharmony_ci#include <unistd.h> 31886da342Sopenharmony_ci#include "json.hpp" 32886da342Sopenharmony_ci#include "fcntl.h" 33886da342Sopenharmony_ci#include "common_utilities_hpp.h" 34886da342Sopenharmony_ci#include "frontend_api_defines.h" 35886da342Sopenharmony_ci#include "ipc_transactor.h" 36886da342Sopenharmony_ci#include "ui_event_observer_impl.h" 37886da342Sopenharmony_ci#include "test_server_client.h" 38886da342Sopenharmony_ci 39886da342Sopenharmony_cinamespace OHOS::cjuitest { 40886da342Sopenharmony_ci using namespace nlohmann; 41886da342Sopenharmony_ci using namespace std; 42886da342Sopenharmony_ci using namespace OHOS::uitest; 43886da342Sopenharmony_ci 44886da342Sopenharmony_ci static constexpr size_t BACKEND_OBJ_GC_BATCH = 100; 45886da342Sopenharmony_ci /**For gc usage, records the backend objRefs about to delete. */ 46886da342Sopenharmony_ci static queue<string> g_backendObjsAboutToDelete; 47886da342Sopenharmony_ci static mutex g_gcQueueMutex; 48886da342Sopenharmony_ci /**IPC client. */ 49886da342Sopenharmony_ci static ApiTransactor g_apiTransactClient(false); 50886da342Sopenharmony_ci static future<void> g_establishConnectionFuture; 51886da342Sopenharmony_ci 52886da342Sopenharmony_ci char *MallocCString(const string &origin) 53886da342Sopenharmony_ci { 54886da342Sopenharmony_ci if (origin.empty()) { 55886da342Sopenharmony_ci return nullptr; 56886da342Sopenharmony_ci } 57886da342Sopenharmony_ci auto len = origin.length() + 1; 58886da342Sopenharmony_ci char *res = static_cast<char *>(malloc(sizeof(char) * len)); 59886da342Sopenharmony_ci if (res == nullptr) { 60886da342Sopenharmony_ci return nullptr; 61886da342Sopenharmony_ci } 62886da342Sopenharmony_ci return char_traits<char>::copy(res, origin.c_str(), len); 63886da342Sopenharmony_ci } 64886da342Sopenharmony_ci 65886da342Sopenharmony_ci /**Wait connection result sync if need.*/ 66886da342Sopenharmony_ci static void WaitForConnectionIfNeed() 67886da342Sopenharmony_ci { 68886da342Sopenharmony_ci if (g_establishConnectionFuture.valid()) { 69886da342Sopenharmony_ci LOG_I("Begin WaitForConnection"); 70886da342Sopenharmony_ci g_establishConnectionFuture.get(); 71886da342Sopenharmony_ci } 72886da342Sopenharmony_ci } 73886da342Sopenharmony_ci 74886da342Sopenharmony_ci static void SetPasteBoardData(string_view text) 75886da342Sopenharmony_ci { 76886da342Sopenharmony_ci OHOS::testserver::TestServerClient::GetInstance().SetPasteData(string(text)); 77886da342Sopenharmony_ci } 78886da342Sopenharmony_ci 79886da342Sopenharmony_ci void PreprocessTransaction(ApiCallInfo &callInfo, ApiCallErr &error) 80886da342Sopenharmony_ci { 81886da342Sopenharmony_ci auto ¶mList = callInfo.paramList_; 82886da342Sopenharmony_ci const auto &id = callInfo.apiId_; 83886da342Sopenharmony_ci if (id == "Component.inputText" && paramList.size() > 0) { 84886da342Sopenharmony_ci if (paramList.at(INDEX_ZERO).type() == nlohmann::detail::value_t::string) { 85886da342Sopenharmony_ci SetPasteBoardData(paramList.at(INDEX_ZERO).get<string>()); 86886da342Sopenharmony_ci } 87886da342Sopenharmony_ci } else if (id == "Driver.inputText" && paramList.size() > 1) { 88886da342Sopenharmony_ci if (paramList.at(INDEX_ONE).type() == nlohmann::detail::value_t::string) { 89886da342Sopenharmony_ci SetPasteBoardData(paramList.at(INDEX_ONE).get<string>()); 90886da342Sopenharmony_ci } 91886da342Sopenharmony_ci } else if (id == "Driver.screenCap" || id == "UiDriver.screenCap" || id == "Driver.screenCapture") { 92886da342Sopenharmony_ci if (paramList.size() < 1 || paramList.at(0).type() != nlohmann::detail::value_t::string) { 93886da342Sopenharmony_ci LOG_E("Missing file path argument"); 94886da342Sopenharmony_ci error = ApiCallErr{ERR_INVALID_INPUT, "Missing file path argument"}; 95886da342Sopenharmony_ci return; 96886da342Sopenharmony_ci } 97886da342Sopenharmony_ci auto path = paramList.at(INDEX_ZERO).get<string>(); 98886da342Sopenharmony_ci auto fd = open(path.c_str(), O_RDWR | O_CREAT, 0666); 99886da342Sopenharmony_ci if (fd == -1) { 100886da342Sopenharmony_ci LOG_E("Invalid file path: %{public}s", path.data()); 101886da342Sopenharmony_ci error = ApiCallErr{ERR_INVALID_INPUT, "Invalid file path:" + path}; 102886da342Sopenharmony_ci return; 103886da342Sopenharmony_ci } 104886da342Sopenharmony_ci paramList[INDEX_ZERO] = fd; 105886da342Sopenharmony_ci callInfo.fdParamIndex_ = INDEX_ZERO; 106886da342Sopenharmony_ci } else if (id == "UIEventObserver.once") { 107886da342Sopenharmony_ci LOG_I("preprocess callback"); 108886da342Sopenharmony_ci int64_t callbackId = paramList.at(1).get<int64_t>(); 109886da342Sopenharmony_ci UiEventObserverImpl::Get().PreprocessCallOnce(callInfo, callbackId, error); 110886da342Sopenharmony_ci } 111886da342Sopenharmony_ci } 112886da342Sopenharmony_ci 113886da342Sopenharmony_ci /**Call api with parameters out, wait for and return result value or throw raised exception.*/ 114886da342Sopenharmony_ci ApiReplyInfo CJTransact(ApiCallInfo callInfo) 115886da342Sopenharmony_ci { 116886da342Sopenharmony_ci WaitForConnectionIfNeed(); 117886da342Sopenharmony_ci LOG_D("TargetApi=%{public}s", callInfo.apiId_.data()); 118886da342Sopenharmony_ci auto reply = ApiReplyInfo(); 119886da342Sopenharmony_ci g_apiTransactClient.Transact(callInfo, reply); 120886da342Sopenharmony_ci LOG_I("return value: %{public}s", reply.resultValue_.dump().c_str()); 121886da342Sopenharmony_ci // notify backend objects deleting 122886da342Sopenharmony_ci if (g_backendObjsAboutToDelete.size() >= BACKEND_OBJ_GC_BATCH) { 123886da342Sopenharmony_ci auto gcCall = ApiCallInfo {.apiId_ = "BackendObjectsCleaner"}; 124886da342Sopenharmony_ci unique_lock<mutex> lock(g_gcQueueMutex); 125886da342Sopenharmony_ci for (size_t count = 0; count < BACKEND_OBJ_GC_BATCH; count++) { 126886da342Sopenharmony_ci gcCall.paramList_.emplace_back(g_backendObjsAboutToDelete.front()); 127886da342Sopenharmony_ci g_backendObjsAboutToDelete.pop(); 128886da342Sopenharmony_ci } 129886da342Sopenharmony_ci lock.unlock(); 130886da342Sopenharmony_ci auto gcReply = ApiReplyInfo(); 131886da342Sopenharmony_ci g_apiTransactClient.Transact(gcCall, gcReply); 132886da342Sopenharmony_ci } 133886da342Sopenharmony_ci return reply; 134886da342Sopenharmony_ci } 135886da342Sopenharmony_ci 136886da342Sopenharmony_ci int32_t GetUid() 137886da342Sopenharmony_ci { 138886da342Sopenharmony_ci auto processGetuid = static_cast<int32_t>(getuid()); 139886da342Sopenharmony_ci return processGetuid; 140886da342Sopenharmony_ci } 141886da342Sopenharmony_ci 142886da342Sopenharmony_ci int32_t GetPid() 143886da342Sopenharmony_ci { 144886da342Sopenharmony_ci auto proPid = static_cast<int32_t>(getpid()); 145886da342Sopenharmony_ci return proPid; 146886da342Sopenharmony_ci } 147886da342Sopenharmony_ci 148886da342Sopenharmony_ci int32_t GetTid() 149886da342Sopenharmony_ci { 150886da342Sopenharmony_ci auto proTid = static_cast<int32_t>(gettid()); 151886da342Sopenharmony_ci return proTid; 152886da342Sopenharmony_ci } 153886da342Sopenharmony_ci 154886da342Sopenharmony_ci extern "C" { 155886da342Sopenharmony_ci void CJ_InitConnection(char *token) 156886da342Sopenharmony_ci { 157886da342Sopenharmony_ci string realToken{token}; 158886da342Sopenharmony_ci LOG_I("connect token is %{public}s", token); 159886da342Sopenharmony_ci g_establishConnectionFuture = async(launch::async, [realToken]() { 160886da342Sopenharmony_ci auto &instance = UiEventObserverImpl::Get(); 161886da342Sopenharmony_ci using namespace std::placeholders; 162886da342Sopenharmony_ci auto callbackHandler = std::bind(&UiEventObserverImpl::HandleEventCallback, &instance, _1, _2); 163886da342Sopenharmony_ci auto result = g_apiTransactClient.InitAndConnectPeer(realToken, callbackHandler); 164886da342Sopenharmony_ci LOG_I("End setup transaction connection, result=%{public}d", result); 165886da342Sopenharmony_ci }); 166886da342Sopenharmony_ci } 167886da342Sopenharmony_ci 168886da342Sopenharmony_ci RetDataCString CJ_ApiCall(ApiCallParams params) 169886da342Sopenharmony_ci { 170886da342Sopenharmony_ci RetDataCString ret{.code = uitest::ErrCode::NO_ERROR, .data = nullptr}; 171886da342Sopenharmony_ci ApiCallInfo callInfo_; 172886da342Sopenharmony_ci LOG_D("apiId: %{public}s", params.apiId); 173886da342Sopenharmony_ci callInfo_.apiId_ = string{params.apiId}; 174886da342Sopenharmony_ci if (params.callerObjRef != nullptr) { 175886da342Sopenharmony_ci LOG_D("callerObjRef_: %{public}s", params.callerObjRef); 176886da342Sopenharmony_ci callInfo_.callerObjRef_ = string{params.callerObjRef}; 177886da342Sopenharmony_ci } 178886da342Sopenharmony_ci if (params.paramList == nullptr) { 179886da342Sopenharmony_ci LOG_D("paramList_: \"\""); 180886da342Sopenharmony_ci callInfo_.paramList_ = ""; 181886da342Sopenharmony_ci } else { 182886da342Sopenharmony_ci LOG_D("paramList_: %{public}s", params.paramList); 183886da342Sopenharmony_ci callInfo_.paramList_ = nlohmann::json::parse(string{params.paramList}); 184886da342Sopenharmony_ci } 185886da342Sopenharmony_ci ApiCallErr err{uitest::ErrCode::NO_ERROR}; 186886da342Sopenharmony_ci PreprocessTransaction(callInfo_, err); 187886da342Sopenharmony_ci if (err.code_ != uitest::ErrCode::NO_ERROR) { 188886da342Sopenharmony_ci ret.code = err.code_; 189886da342Sopenharmony_ci ret.data = MallocCString(err.message_); 190886da342Sopenharmony_ci return ret; 191886da342Sopenharmony_ci } 192886da342Sopenharmony_ci auto result = CJTransact(callInfo_); 193886da342Sopenharmony_ci if (callInfo_.fdParamIndex_ >= 0) { 194886da342Sopenharmony_ci auto fd = callInfo_.paramList_.at(INDEX_ZERO).get<int>(); 195886da342Sopenharmony_ci (void) close(fd); 196886da342Sopenharmony_ci } 197886da342Sopenharmony_ci if (result.exception_.code_ != uitest::ErrCode::NO_ERROR) { 198886da342Sopenharmony_ci ret.code = result.exception_.code_; 199886da342Sopenharmony_ci ret.data = MallocCString(result.exception_.message_); 200886da342Sopenharmony_ci return ret; 201886da342Sopenharmony_ci } 202886da342Sopenharmony_ci ret.data = MallocCString(result.resultValue_.dump()); 203886da342Sopenharmony_ci return ret; 204886da342Sopenharmony_ci } 205886da342Sopenharmony_ci 206886da342Sopenharmony_ci void CJ_UITestObjDelete(char *objref) 207886da342Sopenharmony_ci { 208886da342Sopenharmony_ci unique_lock<mutex> lock(g_gcQueueMutex); 209886da342Sopenharmony_ci g_backendObjsAboutToDelete.push(string(objref)); 210886da342Sopenharmony_ci } 211886da342Sopenharmony_ci 212886da342Sopenharmony_ci int32_t FfiOHOSProcessManagerGetUid() 213886da342Sopenharmony_ci { 214886da342Sopenharmony_ci auto result = GetUid(); 215886da342Sopenharmony_ci return result; 216886da342Sopenharmony_ci } 217886da342Sopenharmony_ci 218886da342Sopenharmony_ci int32_t FfiOHOSProcessManagerGetPid() 219886da342Sopenharmony_ci { 220886da342Sopenharmony_ci auto result = GetPid(); 221886da342Sopenharmony_ci return result; 222886da342Sopenharmony_ci } 223886da342Sopenharmony_ci 224886da342Sopenharmony_ci int32_t FfiOHOSProcessManagerGetTid() 225886da342Sopenharmony_ci { 226886da342Sopenharmony_ci auto result = GetTid(); 227886da342Sopenharmony_ci return result; 228886da342Sopenharmony_ci } 229886da342Sopenharmony_ci } 230886da342Sopenharmony_ci} // namespace OHOS::uitest 231