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 <sstream> 17 #include "extern_api.h" 18 19 namespace OHOS::uitest { 20 using namespace std; 21 using namespace nlohmann; 22 23 /**Get the readable name of the error enum value.*/ GetErrorName(ErrCode code)24 string GetErrorName(ErrCode code) 25 { 26 static const std::map<ErrCode, std::string> names = { 27 {NO_ERROR, "NO_ERROR"}, 28 {INTERNAL_ERROR, "INTERNAL_ERROR"}, 29 {WIDGET_LOST, "WIDGET_LOST"}, 30 {USAGE_ERROR, "USAGE_ERROR"} 31 }; 32 const auto find = names.find(code); 33 return (find == names.end()) ? "UNKNOWN" : find->second; 34 } 35 36 /**Constructor function to register all the ExternAPI creators and functions.*/ ApiRegistration()37 static void __attribute__((constructor)) ApiRegistration() 38 { 39 RegisterExternApIs(); 40 } 41 Get()42 ExternApiServer &ExternApiServer::Get() 43 { 44 static ExternApiServer singleton; 45 return singleton; 46 } 47 AddHandler(ApiRequstHandler handler)48 void ExternApiServer::AddHandler(ApiRequstHandler handler) 49 { 50 if (handler == nullptr) { 51 return; 52 } 53 handlers_.emplace_back(handler); 54 } 55 RemoveHandler(ApiRequstHandler handler)56 void ExternApiServer::RemoveHandler(ApiRequstHandler handler) 57 { 58 auto newEnd = remove_if(handlers_.begin(), handlers_.end(), [handler](ApiRequstHandler hdl) { 59 return hdl == handler; 60 }); 61 handlers_.erase(newEnd, handlers_.end()); 62 } 63 Call(string_view apiId,json & caller,const json & in,json & out,ApiCallErr & err) const64 void ExternApiServer::Call(string_view apiId, json &caller, const json &in, json &out, ApiCallErr &err) const 65 { 66 string api(apiId); 67 for (auto handler:handlers_) { 68 try { 69 if (handler(apiId, caller, in, out, err)) { 70 return; 71 } 72 } catch (exception &ex) { 73 // catch possible json-parsing error 74 err = ApiCallErr(INTERNAL_ERROR, "Exception raised when handling '" + api + "':" + ex.what()); 75 return; 76 } 77 } 78 err = ApiCallErr(INTERNAL_ERROR, "No handler found for extern-api: " + api); 79 } 80 ApiTransact(string_view funcStr,string_view callerStr,string_view paramsStr)81 string ApiTransact(string_view funcStr, string_view callerStr, string_view paramsStr) 82 { 83 LOG_D("Begin to invoke api: %{public}s, params=%{public}s", funcStr.data(), paramsStr.data()); 84 auto error = ApiCallErr(NO_ERROR); 85 auto out = json::array(); 86 json returnData; 87 try { 88 auto caller = json::parse(callerStr); 89 auto in = json::parse(paramsStr); 90 ExternApiServer::Get().Call(funcStr, caller, in, out, error); 91 returnData[KEY_UPDATED_CALLER] = caller; 92 returnData[KEY_RESULT_VALUES] = out; 93 } catch (exception &ex) { 94 error = ApiCallErr(INTERNAL_ERROR, string("Convert transaction parameters failed: ") + ex.what()); 95 } 96 97 if (error.code_ != NO_ERROR) { 98 // deliver exception 99 LOG_W("Transact on api '%{public}s' failed, caller='%{public}s', params='%{public}s', error='%{public}s'", 100 funcStr.data(), callerStr.data(), paramsStr.data(), error.message_.c_str()); 101 json exceptionInfo; 102 exceptionInfo[KEY_CODE] = GetErrorName(error.code_); 103 exceptionInfo[KEY_MESSAGE] = error.message_; 104 returnData[KEY_EXCEPTION] = exceptionInfo; 105 } 106 return returnData.dump(); 107 } 108 } 109 110