* Copyright (c) 2024 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 <cstdint>
#include <hilog/log.h>
#include <js_native_api.h>
#include <js_native_api_types.h>
#include <string>
#include "PluginManager.h"
#include "PluginRender.h"
#undef LOG_TAG
#define LOG_TAG "PluginRender"
namespace NativeXComponentSample {
namespace {
constexpr uint32_t LOG_PRINT_DOMAIN = 0xFF00;
void OnSurfaceCreatedCB(OH_NativeXComponent *component, void *window) {
if (component == nullptr || window == nullptr) {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, LOG_TAG, "OnSurfaceCreatedCB component or window is null");
return;
}
char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'};
uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
if (OH_NativeXComponent_GetXComponentId(component, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, LOG_TAG, "OnSurfaceCreatedCB unable to get XComponent id");
return;
}
std::string id(idStr);
uint64_t width;
uint64_t height;
int32_t xSize = OH_NativeXComponent_GetXComponentSize(component, window, &width, &height);
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, LOG_TAG, "OnSurfaceCreatedCB id: %{public}s", id.c_str());
if ((xSize == OH_NATIVEXCOMPONENT_RESULT_SUCCESS) && (id == "srcPlayer")) {
auto context = PluginManager::GetInstance();
context->renderWindow = (OHNativeWindow *)window;
OH_NativeWindow_NativeWindowHandleOpt(context->renderWindow, SET_BUFFER_GEOMETRY, width, height);
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, LOG_TAG, "OnSurfaceCreatedCB create windowOut: w:%{public}ld h:%{public}ld", width, height);
}
if ((xSize == OH_NATIVEXCOMPONENT_RESULT_SUCCESS) && (id == "dstPlayer")) {
auto context = PluginManager::GetInstance();
context->windowOut = (OHNativeWindow *)window;
OH_NativeWindow_NativeWindowHandleOpt(context->windowOut, SET_BUFFER_GEOMETRY, width, height);
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, LOG_TAG, "OnSurfaceCreatedCB create windowOut: w:%{public}ld h:%{public}ld", width, height);
}
}
void OnSurfaceChangedCB(OH_NativeXComponent *component, void *window) {
if (component == nullptr || window == nullptr) {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, LOG_TAG, "OnSurfaceChangedCB component or window is null");
return;
}
char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'};
uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
if (OH_NativeXComponent_GetXComponentId(component, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, LOG_TAG, "OnSurfaceChangedCB unable to get XComponent id");
return;
}
std::string id(idStr);
auto render = PluginRender::GetInstance(id);
if (render != nullptr) {
render->OnSurfaceChanged(component, window);
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, LOG_TAG, "OnSurfaceChangedCB");
}
}
void OnSurfaceDestroyedCB(OH_NativeXComponent *component, void *window) {
if (component == nullptr || window == nullptr) {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, LOG_TAG, "OnSurfaceDestroyedCB component or window is null");
return;
}
char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'};
uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
if (OH_NativeXComponent_GetXComponentId(component, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, LOG_TAG, "OnSurfaceDestroyedCB unable to get XComponent id");
return;
}
std::string id(idStr);
PluginRender::Release(id);
}
void DispatchTouchEventCB(OH_NativeXComponent *component, void *window) {
if (component == nullptr || window == nullptr) {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, LOG_TAG, "DispatchTouchEventCB component or window is null");
return;
}
char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'};
uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
if (OH_NativeXComponent_GetXComponentId(component, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, LOG_TAG, "DispatchTouchEventCB unable to get XComponent id");
return;
}
std::string id(idStr);
PluginRender *render = PluginRender::GetInstance(id);
if (render != nullptr) {
render->OnTouchEvent(component, window);
}
}
}
std::unordered_map<std::string, PluginRender *> PluginRender::instance_;
int32_t PluginRender::hasDraw_ = 0;
int32_t PluginRender::hasChangeColor_ = 0;
PluginRender::PluginRender(std::string &id) {
this->id_ = id;
}
PluginRender *PluginRender::GetInstance(std::string &id) {
if (instance_.find(id) == instance_.end()) {
PluginRender *instance = new PluginRender(id);
instance_[id] = instance;
return instance;
} else {
return instance_[id];
}
}
void PluginRender::Release(std::string &id) {
PluginRender *render = PluginRender::GetInstance(id);
if (render != nullptr) {
delete render;
render = nullptr;
instance_.erase(instance_.find(id));
}
}
void PluginRender::Export(napi_env env, napi_value exports) {
if (env == nullptr || exports == nullptr) {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, LOG_TAG, "Export env or exports is null");
return;
}
napi_property_descriptor desc[] = {};
if (napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc) != napi_ok) {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, LOG_TAG, "Export napi_define_properties failed");
}
}
void PluginRender::OnSurfaceChanged(OH_NativeXComponent *component, void *window) {
char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'};
uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
if (OH_NativeXComponent_GetXComponentId(component, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, LOG_TAG, "OnSurfaceChanged unable to get XComponent id");
return;
}
std::string id(idStr);
PluginRender *render = PluginRender::GetInstance(id);
double offsetX;
double offsetY;
OH_NativeXComponent_GetXComponentOffset(component, window, &offsetX, &offsetY);
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, LOG_TAG, "OnSurfaceChanged offsetX:%{public}lf, "
"offsetY:%{public}lf", offsetX, offsetY);
}
void PluginRender::OnTouchEvent(OH_NativeXComponent *component, void *window) {
char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'};
uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
if (OH_NativeXComponent_GetXComponentId(component, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, LOG_TAG, "OnTouchEvent unable to get XComponent id");
return;
}
OH_NativeXComponent_TouchEvent touchEvent;
OH_NativeXComponent_GetTouchEvent(component, window, &touchEvent);
float tiltX = 0.0f;
float tiltY = 0.0f;
OH_NativeXComponent_TouchPointToolType toolType = OH_NativeXComponent_TouchPointToolType::OH_NATIVEXCOMPONENT_TOOL_TYPE_UNKNOWN;
OH_NativeXComponent_GetTouchPointToolType(component, 0, &toolType);
OH_NativeXComponent_GetTouchPointTiltX(component, 0, &tiltX);
OH_NativeXComponent_GetTouchPointTiltY(component, 0, &tiltY);
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, LOG_TAG, "OnTouchEvent toolType:%{public}d, "
"tiltX:%{public}lf, tiltY:%{public}lf", toolType, tiltX, tiltY);
}
void PluginRender::RegisterCallback(OH_NativeXComponent *nativeXComponent) {
renderCallback_.OnSurfaceCreated = OnSurfaceCreatedCB;
renderCallback_.OnSurfaceChanged = OnSurfaceChangedCB;
renderCallback_.OnSurfaceDestroyed = OnSurfaceDestroyedCB;
renderCallback_.DispatchTouchEvent = DispatchTouchEventCB;
OH_NativeXComponent_RegisterCallback(nativeXComponent, &renderCallback_);
}
}