* Copyright (c) 2023-2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "method_data.h"
#include "bridge_binary_codec.h"
#include "bridge_json_codec.h"
#include "bridge_manager.h"
#include "error_code.h"
#include "log.h"
#include "method_data_converter.h"
#include "napi/native_api.h"
#include "napi_utils.h"
#include "plugins/bridge/interfaces/kits/napi/bridge_module/include/method_id.h"
#include "plugins/interfaces/native/inner_api/plugin_utils_inner.h"
#include "plugins/interfaces/native/inner_api/plugin_utils_napi.h"
#include "plugins/interfaces/native/plugin_utils.h"
namespace OHOS::Plugin::Bridge {
static constexpr const char* JS_REGISTER_METHOD_NAME = "name";
static constexpr const char* JS_REGISTER_METHOD_FUNCTION = "method";
MethodData::MethodData(napi_env env, const CodecType& type) : env_(env), codecType_(type)
{
}
std::shared_ptr<MethodData> MethodData::CreateMethodData(napi_env env, const CodecType& type)
{
return std::make_shared<MethodData>(env, type);
}
MethodData::~MethodData()
{
asyncEvent_ = nullptr;
}
const std::string& MethodData::GetBridgeName(void) const
{
return bridgeName_;
}
void MethodData::SetBridgeName(const std::string& bridgeName)
{
bridgeName_ = bridgeName;
}
void MethodData::SetMethodName(const std::string& methodName)
{
methodName_ = methodName;
}
const std::string& MethodData::GetMethodName(void) const
{
return methodName_;
}
void MethodData::SetMethodParamName(const std::string& paramName)
{
jsonParameter_ = paramName;
}
const std::string& MethodData::GetMethodParamName(void) const
{
return jsonParameter_;
}
void MethodData::SetMethodParamNameBinary(std::unique_ptr<std::vector<uint8_t>> paramName)
{
binaryParameter_ = std::move(paramName);
}
const std::vector<uint8_t>& MethodData::GetMethodParamNameBinary(void) const
{
return *binaryParameter_;
}
void MethodData::SetIsMessageEvent(bool isMessageEvent)
{
isMessageEvent_ = isMessageEvent;
}
bool MethodData::IsMessageEvent(void) const
{
return isMessageEvent_;
}
void MethodData::SetStartTime(int64_t startTime)
{
startTime_ = startTime;
}
int64_t MethodData::GetStartTime(void) const
{
return startTime_;
}
int64_t MethodData::GetSystemTime(void)
{
auto curNow = std::chrono::system_clock::now();
std::chrono::milliseconds milliSec =
std::chrono::duration_cast<std::chrono::milliseconds>(curNow.time_since_epoch());
return milliSec.count();
}
NAPIAsyncEvent* MethodData::GetAsyncEvent(void) const
{
return asyncEvent_;
}
bool MethodData::GetName(napi_value arg)
{
if (PluginUtilsNApi::GetValueType(env_, arg) == napi_string) {
methodName_ = PluginUtilsNApi::GetStringFromValueUtf8(env_, arg);
return !methodName_.empty();
}
return false;
}
bool MethodData::GetMessageData(napi_value arg)
{
ScopedHandleScope scope(env_);
if (codecType_ == CodecType::JSON_CODEC) {
NapiRawValue rawValue { .env = env_, .value = arg };
auto encoded = BridgeJsonCodec::GetInstance().Encode(rawValue);
SetMethodParamName(encoded->value);
} else if (codecType_ == CodecType::BINARY_CODEC) {
const auto& codecableValue = MethodDataConverter::ConvertToCodecableValue(env_, arg);
auto encoded = BridgeBinaryCodec::GetInstance().Encode(codecableValue);
if (!encoded || encoded->size() == 0) {
LOGE("GetMessageData: binary codec failed.");
return false;
}
SetMethodParamNameBinary(std::move(encoded));
}
return true;
}
napi_value MethodData::GetMessageResponse(const std::string& data)
{
DecodeValue decodeValue { .env = env_, .value = data };
auto decoded = BridgeJsonCodec::GetInstance().Decode(decodeValue);
return decoded->value;
}
bool MethodData::GetParamsByRecord(size_t argc, napi_value* arg)
{
ScopedHandleScope scope(env_);
if (codecType_ == CodecType::JSON_CODEC) {
NapiRawValue rawValue { .env = env_, .argc = static_cast<int>(argc), .argValue = arg };
auto encoded = BridgeJsonCodec::GetInstance().Encode(rawValue);
SetMethodParamName(encoded->value);
return true;
} else if (codecType_ == CodecType::BINARY_CODEC) {
const auto& codecableValue = MethodDataConverter::ConvertToCodecableValue(env_, argc, arg);
auto encoded = BridgeBinaryCodec::GetInstance().Encode(codecableValue);
if (!encoded || encoded->size() == 0) {
LOGE("GetParamsByRecord: binary codec failed.");
return false;
}
SetMethodParamNameBinary(std::move(encoded));
return true;
}
LOGE("GetParamsByRecord: codec type is error.");
return false;
}
bool MethodData::CreateEvent(napi_value arg, bool needListenEvent)
{
if (asyncEvent_ == nullptr) {
asyncEvent_ = new (std::nothrow) NAPIAsyncEvent(env_);
}
if (asyncEvent_ == nullptr) {
LOGE("CreateEvent: The asyncEvent_ is null.");
return false;
}
if (needListenEvent) {
if (isMessageEvent_) {
InitEventSuccessForMessage();
InitEventErrorForMessage();
} else {
InitEventSuccessForMethod();
InitEventErrorForMethod();
}
}
return true;
}
bool MethodData::GetCallback(napi_value arg, bool needListenEvent)
{
if (PluginUtilsNApi::GetValueType(env_, arg) != napi_function) {
LOGE("GetCallback: The napi_value is not napi_function.");
return false;
}
if (!CreateEvent(arg, needListenEvent)) {
LOGE("GetCallback: Failed to create an event.");
return false;
}
bool ret = asyncEvent_->CreateCallback(arg);
if (!ret) {
LOGE("GetCallback: Failed to create the JS callback event.");
ReleaseEvent();
}
return ret;
}
napi_value MethodData::GetPromise(bool needListenEvent)
{
bool ret = CreateEvent(nullptr, needListenEvent);
if (!ret) {
LOGE("GetPromise: Failed to create an event.");
return nullptr;
}
napi_value result = asyncEvent_->CreatePromise();
if (result == nullptr) {
LOGE("GetPromise: Failed to create the JS promise event.");
ReleaseEvent();
}
return result;
}
bool MethodData::IsCallback(void) const
{
if (asyncEvent_) {
return asyncEvent_->IsCallback();
}
return false;
}
void MethodData::InitEventSuccessForMethod(void)
{
if (asyncEvent_ == nullptr) {
LOGE("InitEventSuccessForMethod: asyncEvent_ is null.");
return;
}
auto executor = taskExecutor_;
auto codecType = codecType_;
auto event = [executor, codecType](napi_env env, const std::string& bridgeName,
const std::string& methodName, napi_value resultValue) {
MethodResult result;
result.SetErrorCode(0);
result.SetMethodName(methodName);
if (codecType == CodecType::JSON_CODEC) {
result.ParseJSMethodResult(env, resultValue);
auto task = [platformResult = result.GetResult(), bridgeName, methodName]() {
Ace::Platform::BridgeManager::JSSendMethodResult(bridgeName, methodName, platformResult);
};
if (!executor) {
LOGE("InitEventSuccessForMethod(JSON): taskExecutor_ is null.");
} else {
executor->RunTaskOnBridgeThread(task);
}
} else if (codecType == CodecType::BINARY_CODEC) {
result.ParseJSMethodResultBinary(env, resultValue);
auto task = [resultHold = result.GetResultBinary(), bridgeName, methodName]() {
std::unique_ptr<std::vector<uint8_t>> resultData { resultHold };
Ace::Platform::BridgeManager::JSSendMethodResultBinary(
bridgeName, methodName, 0, "", std::move(resultData));
};
if (!executor) {
LOGE("InitEventSuccessForMethod(Binary): taskExecutor_ is null.");
} else {
executor->RunTaskOnBridgeThread(task);
}
}
};
asyncEvent_->SetAsyncEventSuccess(event);
}
void MethodData::InitEventErrorForMethod(void)
{
if (asyncEvent_ == nullptr) {
LOGE("InitEventErrorForMethod: asyncEvent_ is null.");
return;
}
auto executor = taskExecutor_;
auto codecType = codecType_;
auto event = [executor, codecType](
napi_env env, const std::string& bridgeName, const std::string& methodName, int errorCode) {
MethodResult result;
result.SetErrorCode(errorCode);
result.SetMethodName(methodName);
if (codecType == CodecType::JSON_CODEC) {
result.ParseJSMethodResult(env, nullptr);
auto task = [platformResult = result.GetResult(), bridgeName, methodName]() {
Ace::Platform::BridgeManager::JSSendMethodResult(bridgeName, methodName, platformResult);
};
if (!executor) {
LOGE("InitEventErrorForMethod(JSON): taskExecutor_ is null.");
} else {
executor->RunTaskOnBridgeThread(task);
}
} else if (codecType == CodecType::BINARY_CODEC) {
auto task = [errorCode = result.GetErrorCode(), errorMessage = result.GetErrorMessage(),
bridgeName, methodName]() {
Ace::Platform::BridgeManager::JSSendMethodResultBinary(
bridgeName, methodName, errorCode, errorMessage, nullptr);
};
if (!executor) {
LOGE("InitEventErrorForMethod(Binary): taskExecutor_ is null.");
} else {
executor->RunTaskOnBridgeThread(task);
}
}
};
asyncEvent_->SetAsyncEventError(event);
}
void MethodData::InitEventSuccessForMessage(void)
{
if (asyncEvent_ == nullptr) {
LOGE("InitEventSuccessForMessage: asyncEvent_ is null.");
return;
}
auto executor = taskExecutor_;
auto event = [executor](napi_env env, const std::string& bridgeName, const std::string& methodName,
napi_value resultValue) {
NapiRawValue rawValue { .env = env, .value = resultValue };
auto encoded = BridgeJsonCodec::GetInstance().Encode(rawValue);
auto task = [data = encoded->value, bridgeName]() {
Ace::Platform::BridgeManager::JSSendMessageResponse(bridgeName, data);
};
if (!executor) {
LOGE("InitEventSuccessForMessage: taskExecutor_ is null.");
} else {
executor->RunTaskOnBridgeThread(task);
}
};
asyncEvent_->SetAsyncEventSuccess(event);
}
void MethodData::InitEventErrorForMessage(void)
{
if (asyncEvent_ == nullptr) {
LOGE("InitEventErrorForMessage: asyncEvent_ is null.");
return;
}
auto executor = taskExecutor_;
auto event = [executor](napi_env env, const std::string& bridgeName, const std::string& methodName, int errorCode) {
auto data = BridgeJsonCodec::ParseNullParams("{}");
auto task = [data, bridgeName]() {
Ace::Platform::BridgeManager::JSSendMessageResponse(bridgeName, data);
};
if (!executor) {
LOGE("InitEventErrorForMessage: taskExecutor_ is null.");
} else {
executor->RunTaskOnBridgeThread(task);
}
};
asyncEvent_->SetAsyncEventError(event);
}
void MethodData::ReleaseEvent(void)
{
if (asyncEvent_) {
delete asyncEvent_;
asyncEvent_ = nullptr;
}
}
bool MethodData::GetJSRegisterMethodObject(napi_value object)
{
ScopedHandleScope scope(env_);
if (!PluginUtilsNApi::HasNamedProperty(env_, object, JS_REGISTER_METHOD_NAME) ||
!PluginUtilsNApi::HasNamedProperty(env_, object, JS_REGISTER_METHOD_FUNCTION)) {
LOGE("GetJSRegisterMethodObject: Parameter error.");
return false;
}
napi_value jsMethodName = PluginUtilsNApi::GetNamedProperty(env_, object, JS_REGISTER_METHOD_NAME);
napi_value jsMethodFun = PluginUtilsNApi::GetNamedProperty(env_, object, JS_REGISTER_METHOD_FUNCTION);
if (jsMethodName == nullptr || jsMethodFun == nullptr) {
LOGE("GetJSRegisterMethodObject: Analytic parameter error.");
return false;
}
methodName_ = PluginUtilsNApi::GetStringFromValueUtf8(env_, jsMethodName);
if (methodName_.empty()) {
LOGE("GetJSRegisterMethodObject: methodName_ is empty.");
return false;
}
if (!CreateEvent(jsMethodFun, true)) {
LOGE("GetJSRegisterMethodObject: Failed to create an event.");
return false;
}
bool ret = asyncEvent_->CreateCallback(jsMethodFun);
if (!ret) {
LOGE("GetJSRegisterMethodObject: Failed to create the JS callback.");
ReleaseEvent();
}
return ret;
}
bool MethodData::GetJSRegisterMethodObjectCallBack(const std::string& arg, napi_value object)
{
methodName_ = arg;
if (methodName_.empty()) {
LOGE("Bridge GetJSRegisterMethodObjectCallBack: methodName_ is empty.");
return false;
}
if (!CreateEvent(object, true)) {
LOGE("Bridge GetJSRegisterMethodObjectCallBack: Failed to create an event.");
return false;
}
bool ret = asyncEvent_->CreateCallback(object);
if (!ret) {
LOGE("Bridge GetJSRegisterMethodObjectCallBack: Failed to create the JS callback.");
ReleaseEvent();
}
return ret;
}
bool MethodData::SendMethodResult(const std::string& data, bool removeMethod)
{
ScopedHandleScope scope(env_);
if (asyncEvent_ == nullptr) {
LOGE("SendMethodResult: asyncEvent_ is null.");
return false;
}
MethodResult resultValue;
resultValue.ParsePlatformMethodResult(env_, data);
asyncEvent_->SetErrorCode(resultValue.GetErrorCode());
asyncEvent_->SetRefErrorData(resultValue.GetErrorResult());
asyncEvent_->SetRefData(resultValue.GetOkResult());
asyncEvent_->SetBridgeName(bridgeName_);
AsyncWorkComplete jsCallback = nullptr;
if (removeMethod) {
jsCallback = [](napi_env env, napi_status status, void* data) {
auto deleter = [](NAPIAsyncEvent* event) { delete event; };
std::unique_ptr<NAPIAsyncEvent, decltype(deleter)> event(static_cast<NAPIAsyncEvent*>(data), deleter);
event->AsyncWorkCallback();
};
} else {
jsCallback = [](napi_env env, napi_status status, void* data) {
NAPIAsyncEvent* event = static_cast<NAPIAsyncEvent*>(data);
event->AsyncWorkCallback();
};
}
std::string methodName = MethodID::FetchMethodName(methodName_);
return asyncEvent_->CreateAsyncWork(
methodName, [](napi_env env, void* data) {}, jsCallback);
}
bool MethodData::SendMethodResultBinary(int errorCode, const std::string& errorMessage,
std::unique_ptr<Ace::Platform::BufferMapping> data, bool removeMethod)
{
ScopedHandleScope scope(env_);
if (asyncEvent_ == nullptr) {
LOGE("SendMethodResultBinary: asyncEvent_ is null.");
return false;
}
MethodResult resultValue;
resultValue.ParsePlatformMethodResultBinary(env_, errorCode, errorMessage, std::move(data));
asyncEvent_->SetErrorCode(resultValue.GetErrorCode());
asyncEvent_->SetRefErrorData(resultValue.GetErrorResult());
asyncEvent_->SetRefData(resultValue.GetOkResult());
asyncEvent_->SetBridgeName(bridgeName_);
AsyncWorkComplete jsCallback = nullptr;
if (removeMethod) {
jsCallback = [](napi_env env, napi_status status, void* data) {
auto deleter = [](NAPIAsyncEvent* event) { delete event; };
std::unique_ptr<NAPIAsyncEvent, decltype(deleter)> event(static_cast<NAPIAsyncEvent*>(data), deleter);
event->AsyncWorkCallback();
};
} else {
jsCallback = [](napi_env env, napi_status status, void* data) {
NAPIAsyncEvent* event = static_cast<NAPIAsyncEvent*>(data);
event->AsyncWorkCallback();
};
}
std::string methodName = MethodID::FetchMethodName(methodName_);
return asyncEvent_->CreateAsyncWork(
methodName, [](napi_env env, void* data) {}, jsCallback);
}
bool MethodData::SendMessageResponse(const std::string& data, bool removeMethod)
{
ScopedHandleScope scope(env_);
if (asyncEvent_ == nullptr) {
LOGE("SendMessageResponse: asyncEvent_ is null.");
return false;
}
DecodeValue decodeValue { .env = env_, .value = data };
auto decoded = BridgeJsonCodec::GetInstance().Decode(decodeValue);
MethodResult resultValue;
resultValue.SetOkResult(decoded->value);
resultValue.SetErrorCode(decoded->errorCode);
resultValue.CreateErrorObject(env_);
asyncEvent_->SetErrorCode(decoded->errorCode);
asyncEvent_->SetRefErrorData(resultValue.GetErrorResult());
asyncEvent_->SetRefData(resultValue.GetOkResult());
asyncEvent_->SetBridgeName(bridgeName_);
AsyncWorkComplete jsCallback = nullptr;
if (removeMethod) {
jsCallback = [](napi_env env, napi_status status, void* data) {
auto deleter = [](NAPIAsyncEvent* event) { delete event; };
std::unique_ptr<NAPIAsyncEvent, decltype(deleter)> event(static_cast<NAPIAsyncEvent*>(data), deleter);
event->AsyncWorkCallback();
};
} else {
jsCallback = [](napi_env env, napi_status status, void* data) {
NAPIAsyncEvent* event = static_cast<NAPIAsyncEvent*>(data);
event->AsyncWorkCallback();
};
}
return asyncEvent_->CreateAsyncWork(
methodName_, [](napi_env env, void* data) {}, jsCallback);
}
void MethodData::PlatformCallMethod(const std::string& parameter)
{
ScopedHandleScope scope(env_);
if (asyncEvent_ == nullptr) {
LOGE("PlatformCallMethod: asyncEvent_ is null.");
MethodResult result;
result.SetErrorCode(static_cast<int>(ErrorCode::BRIDGE_METHOD_UNIMPL));
result.SetMethodName(methodName_);
result.ParseJSMethodResult(env_, nullptr);
auto task = [platformResult = result.GetResult(), bridgeName = bridgeName_, methodName = methodName_]() {
Ace::Platform::BridgeManager::JSSendMethodResult(bridgeName, methodName, platformResult);
};
if (!taskExecutor_) {
LOGE("PlatformCallMethod(error path): taskExecutor_ is null.");
} else {
taskExecutor_->RunTaskOnBridgeThread(task);
}
return;
}
if (asyncEvent_ == nullptr) {
LOGE("PlatformCallMethod(Posted Task): asyncEvent_ became null.");
return;
}
asyncEvent_->SetMethodParameter(parameter);
asyncEvent_->SetBridgeName(bridgeName_);
AsyncWorkComplete jsCallback = [](napi_env env, napi_status status, void* data) {
NAPIAsyncEvent* event = static_cast<NAPIAsyncEvent*>(data);
event->AsyncWorkCallMethod();
};
bool ret = asyncEvent_->CreateAsyncWork(methodName_, [](napi_env env, void* data) {}, jsCallback);
if (!ret) {
LOGE("PlatformCallMethod: CreateAsyncWork failed for method %{public}s", methodName_.c_str());
}
}
void MethodData::PlatformCallMethodBinary(std::unique_ptr<Ace::Platform::BufferMapping> data)
{
if (asyncEvent_ == nullptr) {
LOGE("PlatformCallMethod: asyncEvent_ is null.");
MethodResult result;
result.SetErrorCode(static_cast<int>(ErrorCode::BRIDGE_METHOD_UNIMPL));
result.SetMethodName(methodName_);
auto task = [errorCode = result.GetErrorCode(), errorMessage = result.GetErrorMessage(),
bridgeName = bridgeName_, methodName = methodName_]() {
Ace::Platform::BridgeManager::JSSendMethodResultBinary(
bridgeName, methodName, errorCode, errorMessage, nullptr);
};
if (!taskExecutor_) {
LOGE("PlatformCallMethodBinary failed taskExecutor_ is null.");
} else {
taskExecutor_->RunTaskOnBridgeThread(task);
}
return;
}
asyncEvent_->SetBridgeName(bridgeName_);
size_t bufferSize = data->GetSize();
uint8_t* buffer = data->Release();
asyncEvent_->SetMethodParameter(buffer, bufferSize);
AsyncWorkComplete jsCallback = [](napi_env env, napi_status status, void* data) {
size_t argc = PluginUtilsNApi::MAX_ARG_NUM;
napi_value argv[PluginUtilsNApi::MAX_ARG_NUM] = { nullptr };
NAPIAsyncEvent* event = static_cast<NAPIAsyncEvent*>(data);
auto dataBuffer = event->GetMethodParameter();
Ace::Platform::BufferMapping mapping(std::get<uint8_t*>(dataBuffer), std::get<size_t>(dataBuffer));
auto decoded = BridgeBinaryCodec::GetInstance().DecodeBuffer(mapping.GetMapping(), mapping.GetSize());
MethodDataConverter::ConvertToNapiValues(env, *decoded, argc, argv);
event->AsyncWorkCallMethod(argc, argv);
};
asyncEvent_->CreateAsyncWork(
methodName_, [](napi_env env, void* data) {}, jsCallback);
}
void MethodData::PlatformSendMessage(const std::string& data)
{
ScopedHandleScope scope(env_);
if (asyncEvent_ == nullptr) {
LOGE("PlatformSendMessage: asyncEvent_ is null.");
return;
}
DecodeValue decodeValue { .env = env_, .value = data };
auto decoded = BridgeJsonCodec::GetInstance().Decode(decodeValue);
MethodResult resultValue;
resultValue.SetErrorCode(decoded->errorCode);
resultValue.CreateErrorObject(env_);
asyncEvent_->SetErrorCode(resultValue.GetErrorCode());
asyncEvent_->SetRefErrorData(resultValue.GetErrorResult());
asyncEvent_->SetRefData(decoded->value);
asyncEvent_->SetBridgeName(bridgeName_);
asyncEvent_->AsyncWorkMessage();
}
void MethodData::PlatformSendMessageBinary(std::unique_ptr<Ace::Platform::BufferMapping> data)
{
ScopedHandleScope scope(env_);
if (asyncEvent_ == nullptr) {
LOGE("PlatformSendMessageBinary: asyncEvent_ is null.");
return;
}
auto decoded = BridgeBinaryCodec::GetInstance().DecodeBuffer(data->GetMapping(), data->GetSize());
napi_value binaryResult = MethodDataConverter::ConvertToNapiValue(env_, *decoded);
asyncEvent_->SetRefData(binaryResult);
asyncEvent_->SetBridgeName(bridgeName_);
asyncEvent_->AsyncWorkMessage();
}
void MethodData::SendAsyncCallback(int errorCode, napi_value okArg)
{
ScopedHandleScope scope(env_);
if (asyncEvent_ == nullptr) {
LOGE("SendAsyncCallback: asyncEvent_ is null.");
return;
}
MethodResult resultValue;
resultValue.SetErrorCode(errorCode);
resultValue.CreateErrorObject(env_);
asyncEvent_->SetErrorCode(resultValue.GetErrorCode());
asyncEvent_->SetRefErrorData(resultValue.GetErrorResult());
asyncEvent_->SetRefData(okArg);
asyncEvent_->SetBridgeName(bridgeName_);
AsyncWorkComplete jsCallback = nullptr;
jsCallback = [](napi_env env, napi_status status, void* data) {
auto deleter = [](NAPIAsyncEvent* event) { delete event; };
std::unique_ptr<NAPIAsyncEvent, decltype(deleter)> event(static_cast<NAPIAsyncEvent*>(data), deleter);
event->AsyncWorkCallback();
};
bool ret = asyncEvent_->CreateAsyncWork(
methodName_, [](napi_env env, void* data) {}, jsCallback);
if (!ret) {
LOGE("SendAsyncCallback: Failed to call the JS callback.");
ReleaseEvent();
}
}
void MethodData::UpdateMethodName(void)
{
if (!methodName_.empty()) {
methodName_ = MethodID::MakeMethodNameID(methodName_);
}
}
MethodResult MethodData::PlatformCallMethodSync(const std::string& parameter)
{
ScopedHandleScope scope(env_);
LOGD("MethodData::PlatformCallMethodSync called for method '%{public}s'", methodName_.c_str());
MethodResult result;
result.SetMethodName(methodName_);
if (asyncEvent_ == nullptr || !asyncEvent_->IsCallback()) {
LOGE("PlatformCallMethodSync: No callback registered for method '%{public}s'", methodName_.c_str());
result.SetErrorCode(static_cast<int>(ErrorCode::BRIDGE_METHOD_UNIMPL));
result.CreateMethodResultForError();
return result;
}
napi_value methodResultValue = asyncEvent_->AsyncWorkCallMethodSync(parameter);
if (methodResultValue != nullptr) {
result.ParseJSMethodResult(env_, methodResultValue);
LOGD("PlatformCallMethodSync: Successfully called method '%{public}s'", methodName_.c_str());
} else {
LOGE("PlatformCallMethodSync: JavaScript method returned null for method '%{public}s'", methodName_.c_str());
result.SetErrorCode(static_cast<int>(ErrorCode::BRIDGE_METHOD_UNIMPL));
result.CreateMethodResultForError();
}
return result;
}
MethodResult MethodData::PlatformCallMethodSyncBinary(std::unique_ptr<Ace::Platform::BufferMapping> parameter)
{
ScopedHandleScope scope(env_);
LOGD("MethodData::PlatformCallMethodSyncBinary called for method '%{public}s'", methodName_.c_str());
MethodResult result;
result.SetMethodName(methodName_);
if (codecType_ != CodecType::BINARY_CODEC) {
LOGE("PlatformCallMethodSyncBinary: codec type not binary");
result.SetErrorCode(static_cast<int>(ErrorCode::BRIDGE_CODEC_TYPE_MISMATCH));
result.CreateMethodResultForError();
return result;
}
if (asyncEvent_ == nullptr || !asyncEvent_->IsCallback()) {
LOGE("PlatformCallMethodSyncBinary: No callback registered for method '%{public}s'", methodName_.c_str());
result.SetErrorCode(static_cast<int>(ErrorCode::BRIDGE_METHOD_UNIMPL));
result.CreateMethodResultForError();
return result;
}
uint8_t* dataPtr = nullptr;
size_t dataSize = 0;
if (parameter) {
dataPtr = const_cast<uint8_t*>(parameter->GetMapping());
dataSize = parameter->GetSize();
}
napi_value methodResultValue = asyncEvent_->AsyncWorkCallMethodSyncBinary(dataPtr, dataSize);
if (methodResultValue != nullptr) {
result.ParseJSMethodResultBinary(env_, methodResultValue);
} else {
LOGE("PlatformCallMethodSyncBinary: JS returned null");
result.SetErrorCode(static_cast<int>(ErrorCode::BRIDGE_METHOD_UNIMPL));
result.CreateMethodResultForError();
}
return result;
}
}