feat: finish drawing
This commit is contained in:
commit
7f9ae9cb3b
11
.gitignore
vendored
Normal file
11
.gitignore
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
/node_modules
|
||||||
|
/oh_modules
|
||||||
|
/local.properties
|
||||||
|
/.idea
|
||||||
|
**/build
|
||||||
|
/.hvigor
|
||||||
|
.cxx
|
||||||
|
/.clangd
|
||||||
|
/.clang-format
|
||||||
|
/.clang-tidy
|
||||||
|
**/.test
|
10
AppScope/app.json5
Normal file
10
AppScope/app.json5
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"app": {
|
||||||
|
"bundleName": "com.example.harmony_demo_napi_drawing",
|
||||||
|
"vendor": "example",
|
||||||
|
"versionCode": 1000000,
|
||||||
|
"versionName": "1.0.0",
|
||||||
|
"icon": "$media:app_icon",
|
||||||
|
"label": "$string:app_name"
|
||||||
|
}
|
||||||
|
}
|
8
AppScope/resources/base/element/string.json
Normal file
8
AppScope/resources/base/element/string.json
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"string": [
|
||||||
|
{
|
||||||
|
"name": "app_name",
|
||||||
|
"value": "harmony_demo_napi_drawing"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
BIN
AppScope/resources/base/media/app_icon.png
Normal file
BIN
AppScope/resources/base/media/app_icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
62
build-profile.json5
Normal file
62
build-profile.json5
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
{
|
||||||
|
"app": {
|
||||||
|
"signingConfigs": [
|
||||||
|
{
|
||||||
|
"name": "default",
|
||||||
|
"type": "HarmonyOS",
|
||||||
|
"material": {
|
||||||
|
"certpath": "C:\\Users\\Administrator\\.ohos\\config\\auto_debug_harmony_demo_napi_drawing_com.example.harmony_demo_napi_drawing_70086000144137060.cer",
|
||||||
|
"storePassword": "0000001BE3753910899E0BBB6ECF202A75EEFB89D3A07523759EE64981C319C97D66402C494CE432BBF304",
|
||||||
|
"keyAlias": "debugKey",
|
||||||
|
"keyPassword": "0000001BAC241F099392989D533D4D4FF463DB473AD97FFE782F55EAD43F81EB506344AFD09877228BDBB3",
|
||||||
|
"profile": "C:\\Users\\Administrator\\.ohos\\config\\auto_debug_harmony_demo_napi_drawing_com.example.harmony_demo_napi_drawing_70086000144137060.p7b",
|
||||||
|
"signAlg": "SHA256withECDSA",
|
||||||
|
"storeFile": "C:\\Users\\Administrator\\.ohos\\config\\auto_debug_harmony_demo_napi_drawing_com.example.harmony_demo_napi_drawing_70086000144137060.p12"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"products": [
|
||||||
|
{
|
||||||
|
"name": "default",
|
||||||
|
"signingConfig": "default",
|
||||||
|
"compileSdkVersion": "4.1.0(11)",
|
||||||
|
"compatibleSdkVersion": "4.0.0(10)",
|
||||||
|
"runtimeOS": "HarmonyOS"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"buildModeSet": [
|
||||||
|
{
|
||||||
|
"name": "debug",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "release"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"modules": [
|
||||||
|
{
|
||||||
|
"name": "entry",
|
||||||
|
"srcPath": "./entry",
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"name": "default",
|
||||||
|
"applyToProducts": [
|
||||||
|
"default"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "drawing",
|
||||||
|
"srcPath": "./drawing",
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"name": "default",
|
||||||
|
"applyToProducts": [
|
||||||
|
"default"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
BIN
dependencies/fast-xml-parser-4.3.2.tgz
vendored
Normal file
BIN
dependencies/fast-xml-parser-4.3.2.tgz
vendored
Normal file
Binary file not shown.
BIN
dependencies/hvigor-3.1.0-s.tgz
vendored
Normal file
BIN
dependencies/hvigor-3.1.0-s.tgz
vendored
Normal file
Binary file not shown.
BIN
dependencies/hvigor-ohos-arkui-x-plugin-2.2.1-s.tgz
vendored
Normal file
BIN
dependencies/hvigor-ohos-arkui-x-plugin-2.2.1-s.tgz
vendored
Normal file
Binary file not shown.
BIN
dependencies/hvigor-ohos-plugin-3.1.0-s.tgz
vendored
Normal file
BIN
dependencies/hvigor-ohos-plugin-3.1.0-s.tgz
vendored
Normal file
Binary file not shown.
BIN
dependencies/rollup.tgz
vendored
Normal file
BIN
dependencies/rollup.tgz
vendored
Normal file
Binary file not shown.
6
drawing/.gitignore
vendored
Normal file
6
drawing/.gitignore
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
/node_modules
|
||||||
|
/oh_modules
|
||||||
|
/.preview
|
||||||
|
/build
|
||||||
|
/.cxx
|
||||||
|
/.test
|
3
drawing/Index.ets
Normal file
3
drawing/Index.ets
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
export { DrawingDemo } from './src/main/ets/pages/Index'
|
||||||
|
|
||||||
|
export { XComponentContext } from './src/main/ets/interface/XComponentContext'
|
33
drawing/build-profile.json5
Normal file
33
drawing/build-profile.json5
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
{
|
||||||
|
"apiType": "stageMode",
|
||||||
|
"buildOption": {
|
||||||
|
"externalNativeOptions": {
|
||||||
|
"path": "./src/main/cpp/CMakeLists.txt",
|
||||||
|
"arguments": "",
|
||||||
|
"cppFlags": ""
|
||||||
|
},
|
||||||
|
"arkOptions": {
|
||||||
|
// "apPath": "./modules.ap" /* Profile used for profile-guided optimization (PGO), a compiler optimization technique to improve app runtime performance. */
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"buildOptionSet": [
|
||||||
|
{
|
||||||
|
"name": "release",
|
||||||
|
"arkOptions": {
|
||||||
|
"obfuscation": {
|
||||||
|
"ruleOptions": {
|
||||||
|
"enable": true,
|
||||||
|
"files": [
|
||||||
|
"./obfuscation-rules.txt"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"name": "default"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
6
drawing/hvigorfile.ts
Normal file
6
drawing/hvigorfile.ts
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
import { hspTasks } from '@ohos/hvigor-ohos-plugin';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
system: hspTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
|
||||||
|
plugins:[] /* Custom plugin to extend the functionality of Hvigor. */
|
||||||
|
}
|
18
drawing/obfuscation-rules.txt
Normal file
18
drawing/obfuscation-rules.txt
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# Define project specific obfuscation rules here.
|
||||||
|
# You can include the obfuscation configuration files in the current module's build-profile.json5.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# https://gitee.com/openharmony/arkcompiler_ets_frontend/blob/master/arkguard/README.md
|
||||||
|
|
||||||
|
# Obfuscation options:
|
||||||
|
# -disable-obfuscation: disable all obfuscations
|
||||||
|
# -enable-property-obfuscation: obfuscate the property names
|
||||||
|
# -enable-toplevel-obfuscation: obfuscate the names in the global scope
|
||||||
|
# -compact: remove unnecessary blank spaces and all line feeds
|
||||||
|
# -remove-log: remove all console.* statements
|
||||||
|
# -print-namecache: print the name cache that contains the mapping from the old names to new names
|
||||||
|
# -apply-namecache: reuse the given cache file
|
||||||
|
|
||||||
|
# Keep options:
|
||||||
|
# -keep-property-name: specifies property names that you want to keep
|
||||||
|
# -keep-global-name: specifies names that you want to keep in the global scope
|
12
drawing/oh-package.json5
Normal file
12
drawing/oh-package.json5
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"name": "drawing",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Please describe the basic information.",
|
||||||
|
"main": "Index.ets",
|
||||||
|
"author": "",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"packageType": "InterfaceHar",
|
||||||
|
"dependencies": {
|
||||||
|
"libdrawing.so": "file:./src/main/cpp/types/libdrawing"
|
||||||
|
}
|
||||||
|
}
|
24
drawing/src/main/cpp/CMakeLists.txt
Normal file
24
drawing/src/main/cpp/CMakeLists.txt
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
# the minimum version of CMake.
|
||||||
|
cmake_minimum_required(VERSION 3.4.1)
|
||||||
|
project(harmony_demo_napi_drawing)
|
||||||
|
|
||||||
|
set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
|
||||||
|
include_directories(${NATIVERENDER_ROOT_PATH}
|
||||||
|
${NATIVERENDER_ROOT_PATH}/include
|
||||||
|
${NATIVERENDER_ROOT_PATH}/plugin)
|
||||||
|
|
||||||
|
add_library(drawing SHARED
|
||||||
|
napi_init.cpp
|
||||||
|
plugin/plugin_manager.cpp
|
||||||
|
plugin/plugin_render.cpp
|
||||||
|
plugin/sample_bitMap.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(drawing PUBLIC
|
||||||
|
libace_napi.z.so
|
||||||
|
libace_ndk.z.so
|
||||||
|
libnative_window.so
|
||||||
|
libnative_drawing.so
|
||||||
|
hilog_ndk.z.so
|
||||||
|
)
|
61
drawing/src/main/cpp/napi_init.cpp
Normal file
61
drawing/src/main/cpp/napi_init.cpp
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
#include "napi/native_api.h"
|
||||||
|
#include "plugin/plugin_manager.h"
|
||||||
|
#include "sample_bitMap.h"
|
||||||
|
#include <hilog/log.h>
|
||||||
|
|
||||||
|
static napi_value Add(napi_env env, napi_callback_info info) {
|
||||||
|
size_t requireArgc = 2;
|
||||||
|
size_t argc = 2;
|
||||||
|
napi_value args[2] = {nullptr};
|
||||||
|
|
||||||
|
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
|
||||||
|
|
||||||
|
napi_valuetype valuetype0;
|
||||||
|
napi_typeof(env, args[0], &valuetype0);
|
||||||
|
|
||||||
|
napi_valuetype valuetype1;
|
||||||
|
napi_typeof(env, args[1], &valuetype1);
|
||||||
|
|
||||||
|
double value0;
|
||||||
|
napi_get_value_double(env, args[0], &value0);
|
||||||
|
|
||||||
|
double value1;
|
||||||
|
napi_get_value_double(env, args[1], &value1);
|
||||||
|
|
||||||
|
napi_value sum;
|
||||||
|
napi_create_double(env, value0 + value1, &sum);
|
||||||
|
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXTERN_C_START
|
||||||
|
static napi_value Init(napi_env env, napi_value exports) {
|
||||||
|
napi_property_descriptor desc[] = {
|
||||||
|
{"add", nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr},
|
||||||
|
// {"getContext", nullptr, PluginManager::GetContext, nullptr, nullptr, nullptr, napi_default, nullptr},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc) != napi_ok) {
|
||||||
|
OH_LOG_ERROR(LOG_APP, "Init", "napi_define_properties failed");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
PluginManager::GetInstance()->Export(env, exports);
|
||||||
|
|
||||||
|
SampleBitMap::Export(env, exports);
|
||||||
|
|
||||||
|
return exports;
|
||||||
|
}
|
||||||
|
EXTERN_C_END
|
||||||
|
|
||||||
|
static napi_module drawing = {
|
||||||
|
.nm_version = 1,
|
||||||
|
.nm_flags = 0,
|
||||||
|
.nm_filename = nullptr,
|
||||||
|
.nm_register_func = Init,
|
||||||
|
.nm_modname = "drawing",
|
||||||
|
.nm_priv = ((void *)0),
|
||||||
|
.reserved = {0},
|
||||||
|
};
|
||||||
|
|
||||||
|
extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&drawing); }
|
88
drawing/src/main/cpp/plugin/plugin_manager.cpp
Normal file
88
drawing/src/main/cpp/plugin/plugin_manager.cpp
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
//
|
||||||
|
// Created on 2023/12/22.
|
||||||
|
//
|
||||||
|
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
|
||||||
|
// please include "napi/native_api.h".
|
||||||
|
|
||||||
|
#include "plugin_manager.h"
|
||||||
|
#include "plugin_render.h"
|
||||||
|
#include <hilog/log.h>
|
||||||
|
|
||||||
|
const auto TAG = "PluginManager";
|
||||||
|
|
||||||
|
PluginManager PluginManager::pluginManager_;
|
||||||
|
|
||||||
|
PluginManager::~PluginManager() { OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, TAG, "~PluginManager"); }
|
||||||
|
|
||||||
|
void PluginManager::Export(napi_env env, napi_value exports) {
|
||||||
|
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, TAG, "Export: begin");
|
||||||
|
|
||||||
|
if ((env == nullptr) || (exports == nullptr)) {
|
||||||
|
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, TAG, "Export: env or exports is null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
napi_value exportsInstance = nullptr;
|
||||||
|
if ((napi_get_named_property(env, exports, OH_NATIVE_XCOMPONENT_OBJ, &exportsInstance)) != napi_ok) {
|
||||||
|
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, TAG, "Export: napi_get_named_property failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
OH_NativeXComponent *nativeXComponent = nullptr;
|
||||||
|
if ((napi_unwrap(env, exportsInstance, reinterpret_cast<void **>(&nativeXComponent))) != napi_ok) {
|
||||||
|
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, TAG, "Export: napi_unwrap failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'};
|
||||||
|
uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
|
||||||
|
|
||||||
|
if (OH_NativeXComponent_GetXComponentId(nativeXComponent, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
|
||||||
|
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, TAG, "Export: OH_NativeXComponent_GetXComponentId fail");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string id(idStr);
|
||||||
|
|
||||||
|
auto context = PluginManager::GetInstance();
|
||||||
|
|
||||||
|
if (context != nullptr && nativeXComponent != nullptr) {
|
||||||
|
context->SetNativeXComponent(id, nativeXComponent);
|
||||||
|
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, TAG, "id is %s", id.c_str());
|
||||||
|
auto render = context->GetRender(id);
|
||||||
|
if (render != nullptr) {
|
||||||
|
render->RegisterCallback(nativeXComponent);
|
||||||
|
render->Export(env, exports);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, TAG, "Export: render is nullptr");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PluginManager::SetNativeXComponent(std::string &id, OH_NativeXComponent *nativeXComponent) {
|
||||||
|
if (nativeXComponent == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nativeXComponentMap_.find(id) == nativeXComponentMap_.end()) {
|
||||||
|
nativeXComponentMap_[id] = nativeXComponent;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nativeXComponentMap_[id] != nativeXComponent) {
|
||||||
|
OH_NativeXComponent *tmp = nativeXComponentMap_[id];
|
||||||
|
delete tmp;
|
||||||
|
tmp = nullptr;
|
||||||
|
nativeXComponentMap_[id] = nativeXComponent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PluginRender *PluginManager::GetRender(std::string &id) {
|
||||||
|
if (pluginRenderMap_.find(id) == pluginRenderMap_.end()) {
|
||||||
|
PluginRender *instance = PluginRender::GetInstance(id);
|
||||||
|
pluginRenderMap_[id] = instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pluginRenderMap_[id];
|
||||||
|
}
|
51
drawing/src/main/cpp/plugin/plugin_manager.h
Normal file
51
drawing/src/main/cpp/plugin/plugin_manager.h
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
//
|
||||||
|
// Created on 2023/12/22.
|
||||||
|
//
|
||||||
|
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
|
||||||
|
// please include "napi/native_api.h".
|
||||||
|
|
||||||
|
#ifndef HARMONY_DEMO_NAPI_DRAWING_PLUGIN_MANAGER_H
|
||||||
|
#define HARMONY_DEMO_NAPI_DRAWING_PLUGIN_MANAGER_H
|
||||||
|
|
||||||
|
#include <ace/xcomponent/native_interface_xcomponent.h>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include "napi/native_api.h"
|
||||||
|
#include "plugin_render.h"
|
||||||
|
#include <native_window/external_window.h>
|
||||||
|
#include <native_drawing/drawing_bitmap.h>
|
||||||
|
#include <native_drawing/drawing_color.h>
|
||||||
|
#include <native_drawing/drawing_canvas.h>
|
||||||
|
#include <native_drawing/drawing_pen.h>
|
||||||
|
#include <native_drawing/drawing_brush.h>
|
||||||
|
#include <native_drawing/drawing_path.h>
|
||||||
|
#include <cmath>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class PluginManager {
|
||||||
|
public:
|
||||||
|
~PluginManager();
|
||||||
|
|
||||||
|
static PluginManager *GetInstance() { return &PluginManager::pluginManager_; }
|
||||||
|
static napi_value GetContext(napi_env env, napi_callback_info info);
|
||||||
|
|
||||||
|
void SetNativeXComponent(std::string &id, OH_NativeXComponent *nativeXComponent);
|
||||||
|
PluginRender *GetRender(std::string &id);
|
||||||
|
void Export(napi_env env, napi_value exports);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static PluginManager pluginManager_;
|
||||||
|
|
||||||
|
OH_NativeXComponent_Callback mRenderCallback;
|
||||||
|
OH_NativeXComponent_MouseEvent_Callback mMouseCallback;
|
||||||
|
|
||||||
|
std::unordered_map<std::string, OH_NativeXComponent *> nativeXComponentMap_;
|
||||||
|
std::unordered_map<std::string, PluginRender *> pluginRenderMap_;
|
||||||
|
|
||||||
|
// void RegisterCallback(OH_NativeXComponent *nativeXComponent);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // HARMONY_DEMO_NAPI_DRAWING_PLUGIN_MANAGER_H
|
95
drawing/src/main/cpp/plugin/plugin_render.cpp
Normal file
95
drawing/src/main/cpp/plugin/plugin_render.cpp
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
//
|
||||||
|
// Created on 2023/12/25.
|
||||||
|
//
|
||||||
|
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
|
||||||
|
// please include "napi/native_api.h".
|
||||||
|
|
||||||
|
#include "plugin_render.h"
|
||||||
|
#include <ace/xcomponent/native_interface_xcomponent.h>
|
||||||
|
#include "napi/native_api.h"
|
||||||
|
#include <hilog/log.h>
|
||||||
|
#include <native_window/external_window.h>
|
||||||
|
#include <native_drawing/drawing_bitmap.h>
|
||||||
|
#include <native_drawing/drawing_color.h>
|
||||||
|
#include <native_drawing/drawing_canvas.h>
|
||||||
|
#include <native_drawing/drawing_pen.h>
|
||||||
|
#include <native_drawing/drawing_brush.h>
|
||||||
|
#include <native_drawing/drawing_path.h>
|
||||||
|
#include <cmath>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include "sample_bitMap.h"
|
||||||
|
|
||||||
|
const auto TAG = "PluginRender";
|
||||||
|
|
||||||
|
void OnSurfaceCreatedCB(OH_NativeXComponent *component, void *window) {
|
||||||
|
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, TAG, "OnSurfaceCreated");
|
||||||
|
// 可获取 OHNativeWindow 实例
|
||||||
|
OHNativeWindow *nativeWindow = static_cast<OHNativeWindow *>(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_DOMAIN, TAG, "OnSurfaceCreatedCB: Unable to get XComponent id");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string id(idStr);
|
||||||
|
|
||||||
|
auto render = SampleBitMap::GetInstance(id);
|
||||||
|
// auto render = new SampleBitMap();
|
||||||
|
|
||||||
|
render->SetNativeWindow(nativeWindow); // 设置OHNativeWindow实例
|
||||||
|
|
||||||
|
uint64_t width;
|
||||||
|
uint64_t height;
|
||||||
|
|
||||||
|
int32_t size_res = OH_NativeXComponent_GetXComponentSize(component, window, &width, &height);
|
||||||
|
|
||||||
|
// 设置画布宽高
|
||||||
|
if ((size_res == OH_NATIVEXCOMPONENT_RESULT_SUCCESS) && (render != nullptr)) {
|
||||||
|
render->SetHeight(height);
|
||||||
|
render->SetWidth(width);
|
||||||
|
|
||||||
|
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, TAG, "xComponent render width = %{public}d, height = %{public}d",
|
||||||
|
render->GetWidth(), render->GetHeight());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnSurfaceChangedCB(OH_NativeXComponent *component, void *window) {
|
||||||
|
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, TAG, "OnSurfaceChanged");
|
||||||
|
}
|
||||||
|
void OnSurfaceDestroyedCB(OH_NativeXComponent *component, void *window) {
|
||||||
|
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, TAG, "OnSurfaceDestroyed");
|
||||||
|
}
|
||||||
|
void DispatchTouchEventCB(OH_NativeXComponent *component, void *window) {
|
||||||
|
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, TAG, "DispatchTouchEvent");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::unordered_map<std::string, PluginRender *> PluginRender::instance_;
|
||||||
|
|
||||||
|
PluginRender::~PluginRender() {}
|
||||||
|
|
||||||
|
PluginRender *PluginRender::GetInstance(std::string &id) {
|
||||||
|
if (PluginRender::instance_.find(id) == PluginRender::instance_.end()) {
|
||||||
|
PluginRender render;
|
||||||
|
PluginRender::instance_[id] = &render;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PluginRender::instance_[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PluginRender::Export(napi_env env, napi_value value) {}
|
||||||
|
|
||||||
|
void PluginRender::RegisterCallback(OH_NativeXComponent *nativeXComponent) {
|
||||||
|
this->renderCallback_.DispatchTouchEvent = DispatchTouchEventCB;
|
||||||
|
this->renderCallback_.OnSurfaceChanged = OnSurfaceChangedCB;
|
||||||
|
this->renderCallback_.OnSurfaceCreated = OnSurfaceCreatedCB;
|
||||||
|
this->renderCallback_.OnSurfaceDestroyed = OnSurfaceDestroyedCB;
|
||||||
|
|
||||||
|
// 将 callback 注册给 NativeXComponent
|
||||||
|
OH_NativeXComponent_RegisterCallback(nativeXComponent, &this->renderCallback_);
|
||||||
|
}
|
42
drawing/src/main/cpp/plugin/plugin_render.h
Normal file
42
drawing/src/main/cpp/plugin/plugin_render.h
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
//
|
||||||
|
// Created on 2023/12/25.
|
||||||
|
//
|
||||||
|
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
|
||||||
|
// please include "napi/native_api.h".
|
||||||
|
|
||||||
|
#include <ace/xcomponent/native_interface_xcomponent.h>
|
||||||
|
#include "napi/native_api.h"
|
||||||
|
#include <native_window/external_window.h>
|
||||||
|
#include <native_drawing/drawing_bitmap.h>
|
||||||
|
#include <native_drawing/drawing_color.h>
|
||||||
|
#include <native_drawing/drawing_canvas.h>
|
||||||
|
#include <native_drawing/drawing_pen.h>
|
||||||
|
#include <native_drawing/drawing_brush.h>
|
||||||
|
#include <native_drawing/drawing_path.h>
|
||||||
|
#include <cmath>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#ifndef HARMONY_DEMO_NAPI_DRAWING_PLUGIN_RENDER_H
|
||||||
|
#define HARMONY_DEMO_NAPI_DRAWING_PLUGIN_RENDER_H
|
||||||
|
|
||||||
|
class PluginRender {
|
||||||
|
private:
|
||||||
|
~PluginRender();
|
||||||
|
|
||||||
|
OH_NativeXComponent_Callback renderCallback_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static std::unordered_map<std::string, PluginRender *> instance_;
|
||||||
|
|
||||||
|
static PluginRender *GetInstance(std::string &id);
|
||||||
|
|
||||||
|
void Export(napi_env env, napi_value);
|
||||||
|
// 注册监听XComponent组件的回调,包括生命周期函数,手势监听函数等。
|
||||||
|
void RegisterCallback(OH_NativeXComponent *nativeXComponent);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // HARMONY_DEMO_NAPI_DRAWING_PLUGIN_RENDER_H
|
246
drawing/src/main/cpp/plugin/sample_bitMap.cpp
Normal file
246
drawing/src/main/cpp/plugin/sample_bitMap.cpp
Normal file
|
@ -0,0 +1,246 @@
|
||||||
|
//
|
||||||
|
// Created on 2023/12/27.
|
||||||
|
//
|
||||||
|
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
|
||||||
|
// please include "napi/native_api.h".
|
||||||
|
|
||||||
|
#include "sample_bitMap.h"
|
||||||
|
#include <ace/xcomponent/native_interface_xcomponent.h>
|
||||||
|
#include <asm/setup.h>
|
||||||
|
#include <hilog/log.h>
|
||||||
|
#include <ace/xcomponent/native_interface_xcomponent.h>
|
||||||
|
#include <native_window/external_window.h>
|
||||||
|
#include <native_drawing/drawing_bitmap.h>
|
||||||
|
#include <native_drawing/drawing_color.h>
|
||||||
|
#include <native_drawing/drawing_canvas.h>
|
||||||
|
#include <native_drawing/drawing_pen.h>
|
||||||
|
#include <native_drawing/drawing_brush.h>
|
||||||
|
#include <native_drawing/drawing_path.h>
|
||||||
|
#include <cmath>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
const auto TAG = "SampleBitMap";
|
||||||
|
|
||||||
|
const unsigned int LOG_PRINT_DOMAIN = 0xFF00;
|
||||||
|
|
||||||
|
SampleBitMap::~SampleBitMap() {}
|
||||||
|
|
||||||
|
std::unordered_map<std::string, SampleBitMap *> SampleBitMap::instance_;
|
||||||
|
|
||||||
|
SampleBitMap *SampleBitMap::GetInstance(std::string &id) {
|
||||||
|
if (SampleBitMap::instance_.find(id) == SampleBitMap::instance_.end()) {
|
||||||
|
SampleBitMap::instance_[id] = new SampleBitMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
return SampleBitMap::instance_[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
napi_value SampleBitMap::NapiDrawPattern(napi_env env, napi_callback_info info) {
|
||||||
|
// 获取XComponentId 和 NativeWindows
|
||||||
|
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, TAG, "NapiDrawPattern");
|
||||||
|
if ((nullptr == env) || (nullptr == info)) {
|
||||||
|
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, TAG, "NapiDrawPattern: env or info is null");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
napi_value thisArg;
|
||||||
|
if (napi_ok != napi_get_cb_info(env, info, nullptr, nullptr, &thisArg, nullptr)) {
|
||||||
|
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, TAG, "NapiDrawPattern: napi_get_cb_info fail");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
napi_value exportInstance;
|
||||||
|
if (napi_ok != napi_get_named_property(env, thisArg, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance)) {
|
||||||
|
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, TAG, "NapiDrawPattern: napi_get_named_property fail");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
OH_NativeXComponent *nativeXComponent = nullptr;
|
||||||
|
if (napi_ok != napi_unwrap(env, exportInstance, reinterpret_cast<void **>(&nativeXComponent))) {
|
||||||
|
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, TAG, "NapiDrawPattern: napi_unwrap fail");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'};
|
||||||
|
uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
|
||||||
|
|
||||||
|
if (OH_NATIVEXCOMPONENT_RESULT_SUCCESS != OH_NativeXComponent_GetXComponentId(nativeXComponent, idStr, &idSize)) {
|
||||||
|
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, TAG, "NapiDrawPattern: Unable to get XComponent id");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string id(idStr); // XComponent id
|
||||||
|
|
||||||
|
// 根据XComponent Id 获取SampleBitMap对象绘制图形
|
||||||
|
auto bitMap = SampleBitMap::GetInstance(id);
|
||||||
|
bitMap->DrawPattern();
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SampleBitMap::DrawPattern() {
|
||||||
|
/**
|
||||||
|
* 1. 创建BitMap实例
|
||||||
|
*/
|
||||||
|
// 创建一个bitmap对象
|
||||||
|
OH_Drawing_Bitmap *cBitmap = OH_Drawing_BitmapCreate();
|
||||||
|
// 定义bitmap的像素格式
|
||||||
|
OH_Drawing_BitmapFormat cFormat{COLOR_FORMAT_RGBA_8888, ALPHA_FORMAT_OPAQUE};
|
||||||
|
// 构造对应格式的bitmap,width的值必须为 bufferHandle->stride / 4
|
||||||
|
|
||||||
|
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, TAG, "DrawingPattern: width=%{public}d, height=%{public}d",
|
||||||
|
width_, height_);
|
||||||
|
|
||||||
|
OH_Drawing_BitmapBuild(cBitmap, width_, height_, &cFormat);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 2. 创建画布实例
|
||||||
|
*/
|
||||||
|
// 创建一个canvas对象
|
||||||
|
OH_Drawing_Canvas *cCanvas = OH_Drawing_CanvasCreate();
|
||||||
|
// 将画布与bitmap绑定,画布画的内容会输出到绑定的bitmap内存中
|
||||||
|
OH_Drawing_CanvasBind(cCanvas, cBitmap);
|
||||||
|
// 使用白色清除画布内容
|
||||||
|
OH_Drawing_CanvasClear(cCanvas, OH_Drawing_ColorSetArgb(0xFF, 0xFF, 0xFF, 0xFF));
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 3. 构建Path形状
|
||||||
|
*/
|
||||||
|
int len = height_ / 4;
|
||||||
|
float aX = width_ / 2;
|
||||||
|
float aY = height_ / 4;
|
||||||
|
float dX = aX - len * std::sin(18.0f);
|
||||||
|
float dY = aY + len * std::cos(18.0f);
|
||||||
|
float cX = aX + len * std::sin(18.0f);
|
||||||
|
float cY = dY;
|
||||||
|
float bX = aX + (len / 2.0);
|
||||||
|
float bY = aY + std::sqrt((cX - dX) * (cX - dX) + (len / 2.0) * (len / 2.0));
|
||||||
|
float eX = aX - (len / 2.0);
|
||||||
|
float eY = bY;
|
||||||
|
|
||||||
|
// 创建一个path对象,然后使用接口连接成一个五角星形状
|
||||||
|
OH_Drawing_Path *cPath = OH_Drawing_PathCreate();
|
||||||
|
// 指定path的起始位置
|
||||||
|
OH_Drawing_PathMoveTo(cPath, aX, aY);
|
||||||
|
// 用直线连接到目标点
|
||||||
|
OH_Drawing_PathLineTo(cPath, bX, bY);
|
||||||
|
OH_Drawing_PathLineTo(cPath, cX, cY);
|
||||||
|
OH_Drawing_PathLineTo(cPath, dX, dY);
|
||||||
|
OH_Drawing_PathLineTo(cPath, eX, eY);
|
||||||
|
// 闭合形状,path绘制完毕
|
||||||
|
OH_Drawing_PathClose(cPath);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 4. 设置画笔和画刷样式
|
||||||
|
*/
|
||||||
|
// 创建一个画笔Pen对象,Pen对象用于形状的边框线绘制
|
||||||
|
OH_Drawing_Pen *cPen = OH_Drawing_PenCreate();
|
||||||
|
OH_Drawing_PenSetAntiAlias(cPen, true);
|
||||||
|
OH_Drawing_PenSetColor(cPen, OH_Drawing_ColorSetArgb(0xFF, 0xFF, 0x00, 0x00));
|
||||||
|
OH_Drawing_PenSetWidth(cPen, 10.0);
|
||||||
|
OH_Drawing_PenSetJoin(cPen, LINE_ROUND_JOIN);
|
||||||
|
// 将Pen画笔设置到canvas中
|
||||||
|
OH_Drawing_CanvasAttachPen(cCanvas, cPen);
|
||||||
|
|
||||||
|
// 创建一个画刷Brush对象,Brush对象用于形状的填充
|
||||||
|
OH_Drawing_Brush *cBrush = OH_Drawing_BrushCreate();
|
||||||
|
OH_Drawing_BrushSetColor(cBrush, OH_Drawing_ColorSetArgb(0xFF, 0x00, 0xFF, 0x00));
|
||||||
|
|
||||||
|
// 将Brush画刷设置到canvas中
|
||||||
|
OH_Drawing_CanvasAttachBrush(cCanvas, cBrush);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 5. 绘制Path形状
|
||||||
|
*/
|
||||||
|
// 在画布上画path的形状,五角星的边框样式为pen设置,颜色填充为Brush设置
|
||||||
|
OH_Drawing_CanvasDrawPath(cCanvas, cPath);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 6. 绘制内容送显
|
||||||
|
*/
|
||||||
|
this->Draw(cBitmap);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 7. 内存释放
|
||||||
|
*/
|
||||||
|
// 销毁创建的对象
|
||||||
|
OH_Drawing_BrushDestroy(cBrush);
|
||||||
|
cBrush = nullptr;
|
||||||
|
OH_Drawing_PenDestroy(cPen);
|
||||||
|
cPen = nullptr;
|
||||||
|
OH_Drawing_PathDestroy(cPath);
|
||||||
|
cPath = nullptr;
|
||||||
|
OH_Drawing_CanvasDestroy(cCanvas);
|
||||||
|
cCanvas = nullptr;
|
||||||
|
OH_Drawing_BitmapDestroy(cBitmap);
|
||||||
|
cBitmap = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SampleBitMap::Clear() {}
|
||||||
|
|
||||||
|
void SampleBitMap::Draw(OH_Drawing_Bitmap *cBitmap) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
OHNativeWindowBuffer *buffer_ = NULL;
|
||||||
|
// 通过 OH_NativeWindow_NativeWindowRequestBuffer 获取 OHNativeWindowBuffer 实例
|
||||||
|
int32_t ret = OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow_, &buffer_, &fenceFd_);
|
||||||
|
|
||||||
|
BufferHandle *bufferHandle_ = OH_NativeWindow_GetBufferHandleFromNative(buffer_);
|
||||||
|
|
||||||
|
uint32_t *mappedAddr_ = static_cast<uint32_t *>(
|
||||||
|
// 使用系统接口mmap将bufferHandle对应的共享内存映射到用户空间,可以通过映射出来的虚拟地址向bufferHandle中写入图像数据
|
||||||
|
// bufferHandle->virAddr是bufferHandle在共享内存中的起始地址,bufferHandle->size是bufferHandle在共享内存中的内存占用大小
|
||||||
|
mmap(bufferHandle_->virAddr, bufferHandle_->size, PROT_READ | PROT_WRITE, MAP_SHARED, bufferHandle_->fd, 0));
|
||||||
|
|
||||||
|
if (mappedAddr_ == MAP_FAILED) {
|
||||||
|
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, TAG, "mmap failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 画完后获取像素地址,地址指向的内存包含画布画的像素数据
|
||||||
|
void *bitmapAddr = OH_Drawing_BitmapGetPixels(cBitmap);
|
||||||
|
uint32_t *value = static_cast<uint32_t *>(bitmapAddr);
|
||||||
|
|
||||||
|
// 使用mmap获取到的地址来访问内存
|
||||||
|
uint32_t *pixel = static_cast<uint32_t *>(mappedAddr_);
|
||||||
|
for (uint32_t x = 0; x < width_; x++) {
|
||||||
|
for (uint32_t y = 0; y < height_; y++) {
|
||||||
|
*pixel++ = *value++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果Region中的Rect为nullptr,或者rectNumber为0,则认为OHNativeWindowBuffer全部有内容更改。
|
||||||
|
Region region{nullptr, 0};
|
||||||
|
// 通过OH_NativeWindow_NativeWindowFlushBuffer 提交给消费者使用,例如:显示在屏幕上。
|
||||||
|
OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow_, buffer_, fenceFd_, region);
|
||||||
|
|
||||||
|
// 去掉内存映射
|
||||||
|
int result = munmap(mappedAddr_, bufferHandle_->size);
|
||||||
|
if (result == -1) {
|
||||||
|
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, TAG, "munmap failed!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
napi_value SampleBitMap::NapiClear(napi_env env, napi_callback_info info) { return nullptr; }
|
||||||
|
|
||||||
|
void SampleBitMap::Export(napi_env env, napi_value exports) {
|
||||||
|
if ((env == nullptr) || (exports == nullptr)) {
|
||||||
|
// DRAWING_LOGE("Export: env or exports is null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
napi_property_descriptor desc[] = {
|
||||||
|
{"drawPattern", nullptr, SampleBitMap::NapiDrawPattern, nullptr, nullptr, nullptr, napi_default, nullptr},
|
||||||
|
// {"drawText", nullptr, SampleBitMap::NapiDrawText, nullptr, nullptr, nullptr, napi_default, nullptr},
|
||||||
|
{"clearPattern", nullptr, SampleBitMap::NapiClear, nullptr, nullptr, nullptr, napi_default, nullptr},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc) != napi_ok) {
|
||||||
|
// DRAWING_LOGE("Export: napi_define_properties failed");
|
||||||
|
}
|
||||||
|
}
|
52
drawing/src/main/cpp/plugin/sample_bitMap.h
Normal file
52
drawing/src/main/cpp/plugin/sample_bitMap.h
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
//
|
||||||
|
// Created on 2023/12/27.
|
||||||
|
//
|
||||||
|
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
|
||||||
|
// please include "napi/native_api.h".
|
||||||
|
|
||||||
|
#ifndef HARMONY_DEMO_NAPI_DRAWING_SAMPLE_BITMAP_H
|
||||||
|
#define HARMONY_DEMO_NAPI_DRAWING_SAMPLE_BITMAP_H
|
||||||
|
|
||||||
|
#include <bits/alltypes.h>
|
||||||
|
#include <hilog/log.h>
|
||||||
|
#include <native_drawing/drawing_types.h>
|
||||||
|
#include <native_window/external_window.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <string>
|
||||||
|
#include <js_native_api.h>
|
||||||
|
#include <js_native_api_types.h>
|
||||||
|
|
||||||
|
class SampleBitMap {
|
||||||
|
public:
|
||||||
|
~SampleBitMap();
|
||||||
|
|
||||||
|
static SampleBitMap *GetInstance(std::string &id);
|
||||||
|
|
||||||
|
void SetNativeWindow(OHNativeWindow *native_window) { this->nativeWindow_ = native_window; }
|
||||||
|
void SetHeight(int height) { this->height_ = height; }
|
||||||
|
void SetWidth(int width) { this->width_ = width; }
|
||||||
|
|
||||||
|
int GetHeight() const { return this->height_; }
|
||||||
|
int GetWidth() const { return this->width_; }
|
||||||
|
|
||||||
|
void Draw(OH_Drawing_Bitmap *cBitmap);
|
||||||
|
void DrawPattern();
|
||||||
|
void Clear();
|
||||||
|
|
||||||
|
static napi_value NapiDrawPattern(napi_env env, napi_callback_info info);
|
||||||
|
static napi_value NapiClear(napi_env env, napi_callback_info info);
|
||||||
|
static void Export(napi_env env, napi_value exports);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static std::unordered_map<std::string, SampleBitMap *> instance_;
|
||||||
|
|
||||||
|
OHNativeWindow *nativeWindow_;
|
||||||
|
|
||||||
|
int fenceFd_;
|
||||||
|
|
||||||
|
int height_ = 0;
|
||||||
|
int width_ = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // HARMONY_DEMO_NAPI_DRAWING_SAMPLE_BITMAP_H
|
3
drawing/src/main/cpp/types/libdrawing/index.d.ts
vendored
Normal file
3
drawing/src/main/cpp/types/libdrawing/index.d.ts
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
export const add: (a: number, b: number) => number;
|
||||||
|
|
||||||
|
export const drawPattern: () => void;
|
6
drawing/src/main/cpp/types/libdrawing/oh-package.json5
Normal file
6
drawing/src/main/cpp/types/libdrawing/oh-package.json5
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"name": "libdrawing.so",
|
||||||
|
"types": "./index.d.ts",
|
||||||
|
"version": "",
|
||||||
|
"description": "Please describe the basic information."
|
||||||
|
}
|
4
drawing/src/main/ets/interface/XComponentContext.ets
Normal file
4
drawing/src/main/ets/interface/XComponentContext.ets
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
export interface XComponentContext {
|
||||||
|
add: (a: number, b: number) => number;
|
||||||
|
drawPattern: () => void;
|
||||||
|
}
|
50
drawing/src/main/ets/pages/Index.ets
Normal file
50
drawing/src/main/ets/pages/Index.ets
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
import hilog from '@ohos.hilog';
|
||||||
|
import { XComponentContext } from '../interface/XComponentContext';
|
||||||
|
|
||||||
|
const TAG = 'DrawingDemo'
|
||||||
|
|
||||||
|
@Entry
|
||||||
|
@Component
|
||||||
|
export struct DrawingDemo {
|
||||||
|
private xComponentAttrs: XComponentAttrs = {
|
||||||
|
id: 'xcomponentId',
|
||||||
|
type: XComponentType.SURFACE,
|
||||||
|
libraryname: 'drawing'
|
||||||
|
}
|
||||||
|
@State xComponentContext: XComponentContext | undefined = undefined;
|
||||||
|
|
||||||
|
build() {
|
||||||
|
Column({ space: 10 }) {
|
||||||
|
Row() {
|
||||||
|
XComponent(this.xComponentAttrs)// .focusable(true)// 可响应键盘事件
|
||||||
|
.onLoad((xComponentContext: XComponentContext) => {
|
||||||
|
this.xComponentContext = xComponentContext
|
||||||
|
const res = xComponentContext.add(2, 3)
|
||||||
|
hilog.info(0xffff, TAG, `xComponentContext.add: 2 + 3 = ${res}`)
|
||||||
|
})
|
||||||
|
.onDestroy(() => {
|
||||||
|
console.log("onDestroy");
|
||||||
|
})
|
||||||
|
.width('100%')
|
||||||
|
.height('80%')
|
||||||
|
}
|
||||||
|
.width('100%')
|
||||||
|
.justifyContent(FlexAlign.Center)
|
||||||
|
|
||||||
|
Row() {
|
||||||
|
Button('绘制')
|
||||||
|
.onClick(() => {
|
||||||
|
this.xComponentContext?.drawPattern()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
.width('100%')
|
||||||
|
.justifyContent(FlexAlign.Center)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface XComponentAttrs {
|
||||||
|
id: string;
|
||||||
|
type: number;
|
||||||
|
libraryname: string;
|
||||||
|
}
|
3
drawing/src/main/ets/utils/Calc.ets
Normal file
3
drawing/src/main/ets/utils/Calc.ets
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
export function add(a:number, b:number) {
|
||||||
|
return a + b;
|
||||||
|
}
|
14
drawing/src/main/module.json5
Normal file
14
drawing/src/main/module.json5
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"module": {
|
||||||
|
"name": "drawing",
|
||||||
|
"type": "shared",
|
||||||
|
"description": "$string:shared_desc",
|
||||||
|
"deviceTypes": [
|
||||||
|
"phone",
|
||||||
|
"tablet",
|
||||||
|
"2in1"
|
||||||
|
],
|
||||||
|
"deliveryWithInstall": true,
|
||||||
|
"pages": "$profile:main_pages"
|
||||||
|
}
|
||||||
|
}
|
8
drawing/src/main/resources/base/element/color.json
Normal file
8
drawing/src/main/resources/base/element/color.json
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"color": [
|
||||||
|
{
|
||||||
|
"name": "white",
|
||||||
|
"value": "#FFFFFF"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
8
drawing/src/main/resources/base/element/string.json
Normal file
8
drawing/src/main/resources/base/element/string.json
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"string": [
|
||||||
|
{
|
||||||
|
"name": "shared_desc",
|
||||||
|
"value": "description"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
BIN
drawing/src/main/resources/base/media/icon.png
Normal file
BIN
drawing/src/main/resources/base/media/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.6 KiB |
BIN
drawing/src/main/resources/base/media/setting.jpeg
Normal file
BIN
drawing/src/main/resources/base/media/setting.jpeg
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
5
drawing/src/main/resources/base/profile/main_pages.json
Normal file
5
drawing/src/main/resources/base/profile/main_pages.json
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"src": [
|
||||||
|
"pages/Index"
|
||||||
|
]
|
||||||
|
}
|
5
drawing/src/test/List.test.ets
Normal file
5
drawing/src/test/List.test.ets
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import localUnitTest from './LocalUnit.test';
|
||||||
|
|
||||||
|
export default function testsuite() {
|
||||||
|
localUnitTest();
|
||||||
|
}
|
33
drawing/src/test/LocalUnit.test.ets
Normal file
33
drawing/src/test/LocalUnit.test.ets
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
|
||||||
|
|
||||||
|
export default function localUnitTest() {
|
||||||
|
describe('localUnitTest',() => {
|
||||||
|
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
|
||||||
|
beforeAll(() => {
|
||||||
|
// Presets an action, which is performed only once before all test cases of the test suite start.
|
||||||
|
// This API supports only one parameter: preset action function.
|
||||||
|
});
|
||||||
|
beforeEach(() => {
|
||||||
|
// Presets an action, which is performed before each unit test case starts.
|
||||||
|
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||||
|
// This API supports only one parameter: preset action function.
|
||||||
|
});
|
||||||
|
afterEach(() => {
|
||||||
|
// Presets a clear action, which is performed after each unit test case ends.
|
||||||
|
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||||
|
// This API supports only one parameter: clear action function.
|
||||||
|
});
|
||||||
|
afterAll(() => {
|
||||||
|
// Presets a clear action, which is performed after all test cases of the test suite end.
|
||||||
|
// This API supports only one parameter: clear action function.
|
||||||
|
});
|
||||||
|
it('assertContain', 0, () => {
|
||||||
|
// Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.
|
||||||
|
let a = 'abc';
|
||||||
|
let b = 'b';
|
||||||
|
// Defines a variety of assertion methods, which are used to declare expected boolean conditions.
|
||||||
|
expect(a).assertContain(b);
|
||||||
|
expect(a).assertEqual(a);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
6
entry/.gitignore
vendored
Normal file
6
entry/.gitignore
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
/node_modules
|
||||||
|
/oh_modules
|
||||||
|
/.preview
|
||||||
|
/build
|
||||||
|
/.cxx
|
||||||
|
/.test
|
31
entry/build-profile.json5
Normal file
31
entry/build-profile.json5
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
{
|
||||||
|
"apiType": "stageMode",
|
||||||
|
"buildOption": {
|
||||||
|
"arkOptions": {
|
||||||
|
// "apPath": "./modules.ap" /* Profile used for profile-guided optimization (PGO), a compiler optimization technique to improve app runtime performance. */
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"buildOptionSet": [
|
||||||
|
{
|
||||||
|
"name": "release",
|
||||||
|
"arkOptions": {
|
||||||
|
"obfuscation": {
|
||||||
|
"ruleOptions": {
|
||||||
|
"enable": true,
|
||||||
|
"files": [
|
||||||
|
"./obfuscation-rules.txt"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"name": "default"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ohosTest",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
6
entry/hvigorfile.ts
Normal file
6
entry/hvigorfile.ts
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
import { hapTasks } from '@ohos/hvigor-ohos-plugin';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
|
||||||
|
plugins:[] /* Custom plugin to extend the functionality of Hvigor. */
|
||||||
|
}
|
18
entry/obfuscation-rules.txt
Normal file
18
entry/obfuscation-rules.txt
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# Define project specific obfuscation rules here.
|
||||||
|
# You can include the obfuscation configuration files in the current module's build-profile.json5.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# https://gitee.com/openharmony/arkcompiler_ets_frontend/blob/master/arkguard/README.md
|
||||||
|
|
||||||
|
# Obfuscation options:
|
||||||
|
# -disable-obfuscation: disable all obfuscations
|
||||||
|
# -enable-property-obfuscation: obfuscate the property names
|
||||||
|
# -enable-toplevel-obfuscation: obfuscate the names in the global scope
|
||||||
|
# -compact: remove unnecessary blank spaces and all line feeds
|
||||||
|
# -remove-log: remove all console.* statements
|
||||||
|
# -print-namecache: print the name cache that contains the mapping from the old names to new names
|
||||||
|
# -apply-namecache: reuse the given cache file
|
||||||
|
|
||||||
|
# Keep options:
|
||||||
|
# -keep-property-name: specifies property names that you want to keep
|
||||||
|
# -keep-global-name: specifies names that you want to keep in the global scope
|
13
entry/oh-package.json5
Normal file
13
entry/oh-package.json5
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
{
|
||||||
|
"license": "",
|
||||||
|
"devDependencies": {},
|
||||||
|
"author": "",
|
||||||
|
"name": "entry",
|
||||||
|
"description": "Please describe the basic information.",
|
||||||
|
"main": "",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"dynamicDependencies": {},
|
||||||
|
"dependencies": {
|
||||||
|
"drawing": 'file:../drawing',
|
||||||
|
}
|
||||||
|
}
|
43
entry/src/main/ets/entryability/EntryAbility.ets
Normal file
43
entry/src/main/ets/entryability/EntryAbility.ets
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
import AbilityConstant from '@ohos.app.ability.AbilityConstant';
|
||||||
|
import hilog from '@ohos.hilog';
|
||||||
|
import UIAbility from '@ohos.app.ability.UIAbility';
|
||||||
|
import Want from '@ohos.app.ability.Want';
|
||||||
|
import window from '@ohos.window';
|
||||||
|
|
||||||
|
export default class EntryAbility extends UIAbility {
|
||||||
|
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
|
||||||
|
}
|
||||||
|
|
||||||
|
onDestroy(): void {
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
|
||||||
|
}
|
||||||
|
|
||||||
|
onWindowStageCreate(windowStage: window.WindowStage): void {
|
||||||
|
// Main window is created, set main page for this ability
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
|
||||||
|
|
||||||
|
windowStage.loadContent('pages/Index', (err, data) => {
|
||||||
|
if (err.code) {
|
||||||
|
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onWindowStageDestroy(): void {
|
||||||
|
// Main window is destroyed, release UI related resources
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
|
||||||
|
}
|
||||||
|
|
||||||
|
onForeground(): void {
|
||||||
|
// Ability has brought to foreground
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
|
||||||
|
}
|
||||||
|
|
||||||
|
onBackground(): void {
|
||||||
|
// Ability has back to background
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
|
||||||
|
}
|
||||||
|
};
|
22
entry/src/main/ets/pages/Index.ets
Normal file
22
entry/src/main/ets/pages/Index.ets
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
import hilog from '@ohos.hilog';
|
||||||
|
import testNapi from 'libentry.so';
|
||||||
|
import { DrawingDemo } from 'drawing'
|
||||||
|
|
||||||
|
|
||||||
|
const TAG = '[Sample_DrawingAPI]'
|
||||||
|
|
||||||
|
@Entry
|
||||||
|
@Component
|
||||||
|
struct Index {
|
||||||
|
build() {
|
||||||
|
Column() {
|
||||||
|
DrawingDemo()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface XComponentAttrs {
|
||||||
|
id: string;
|
||||||
|
type: number;
|
||||||
|
libraryname: string;
|
||||||
|
}
|
38
entry/src/main/module.json5
Normal file
38
entry/src/main/module.json5
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
"module": {
|
||||||
|
"name": "entry",
|
||||||
|
"type": "entry",
|
||||||
|
"description": "$string:module_desc",
|
||||||
|
"mainElement": "EntryAbility",
|
||||||
|
"deviceTypes": [
|
||||||
|
"phone",
|
||||||
|
"tablet",
|
||||||
|
"2in1"
|
||||||
|
],
|
||||||
|
"deliveryWithInstall": true,
|
||||||
|
"installationFree": false,
|
||||||
|
"pages": "$profile:main_pages",
|
||||||
|
"abilities": [
|
||||||
|
{
|
||||||
|
"name": "EntryAbility",
|
||||||
|
"srcEntry": "./ets/entryability/EntryAbility.ets",
|
||||||
|
"description": "$string:EntryAbility_desc",
|
||||||
|
"icon": "$media:icon",
|
||||||
|
"label": "$string:EntryAbility_label",
|
||||||
|
"startWindowIcon": "$media:startIcon",
|
||||||
|
"startWindowBackground": "$color:start_window_background",
|
||||||
|
"exported": true,
|
||||||
|
"skills": [
|
||||||
|
{
|
||||||
|
"entities": [
|
||||||
|
"entity.system.home"
|
||||||
|
],
|
||||||
|
"actions": [
|
||||||
|
"action.system.home"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
8
entry/src/main/resources/base/element/color.json
Normal file
8
entry/src/main/resources/base/element/color.json
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"color": [
|
||||||
|
{
|
||||||
|
"name": "start_window_background",
|
||||||
|
"value": "#FFFFFF"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
16
entry/src/main/resources/base/element/string.json
Normal file
16
entry/src/main/resources/base/element/string.json
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"string": [
|
||||||
|
{
|
||||||
|
"name": "module_desc",
|
||||||
|
"value": "module description"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "EntryAbility_desc",
|
||||||
|
"value": "description"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "EntryAbility_label",
|
||||||
|
"value": "harmony_demo_napi_drawing"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
BIN
entry/src/main/resources/base/media/icon.png
Normal file
BIN
entry/src/main/resources/base/media/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
BIN
entry/src/main/resources/base/media/startIcon.png
Normal file
BIN
entry/src/main/resources/base/media/startIcon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
5
entry/src/main/resources/base/profile/main_pages.json
Normal file
5
entry/src/main/resources/base/profile/main_pages.json
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"src": [
|
||||||
|
"pages/Index"
|
||||||
|
]
|
||||||
|
}
|
16
entry/src/main/resources/en_US/element/string.json
Normal file
16
entry/src/main/resources/en_US/element/string.json
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"string": [
|
||||||
|
{
|
||||||
|
"name": "module_desc",
|
||||||
|
"value": "module description"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "EntryAbility_desc",
|
||||||
|
"value": "description"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "EntryAbility_label",
|
||||||
|
"value": "label"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
16
entry/src/main/resources/zh_CN/element/string.json
Normal file
16
entry/src/main/resources/zh_CN/element/string.json
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"string": [
|
||||||
|
{
|
||||||
|
"name": "module_desc",
|
||||||
|
"value": "模块描述"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "EntryAbility_desc",
|
||||||
|
"value": "description"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "EntryAbility_label",
|
||||||
|
"value": "harmony_demo_napi_drawing"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
35
entry/src/ohosTest/ets/test/Ability.test.ets
Normal file
35
entry/src/ohosTest/ets/test/Ability.test.ets
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
import hilog from '@ohos.hilog';
|
||||||
|
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
|
||||||
|
|
||||||
|
export default function abilityTest() {
|
||||||
|
describe('ActsAbilityTest', () => {
|
||||||
|
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
|
||||||
|
beforeAll(() => {
|
||||||
|
// Presets an action, which is performed only once before all test cases of the test suite start.
|
||||||
|
// This API supports only one parameter: preset action function.
|
||||||
|
})
|
||||||
|
beforeEach(() => {
|
||||||
|
// Presets an action, which is performed before each unit test case starts.
|
||||||
|
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||||
|
// This API supports only one parameter: preset action function.
|
||||||
|
})
|
||||||
|
afterEach(() => {
|
||||||
|
// Presets a clear action, which is performed after each unit test case ends.
|
||||||
|
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||||
|
// This API supports only one parameter: clear action function.
|
||||||
|
})
|
||||||
|
afterAll(() => {
|
||||||
|
// Presets a clear action, which is performed after all test cases of the test suite end.
|
||||||
|
// This API supports only one parameter: clear action function.
|
||||||
|
})
|
||||||
|
it('assertContain', 0, () => {
|
||||||
|
// Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'it begin');
|
||||||
|
let a = 'abc';
|
||||||
|
let b = 'b';
|
||||||
|
// Defines a variety of assertion methods, which are used to declare expected boolean conditions.
|
||||||
|
expect(a).assertContain(b);
|
||||||
|
expect(a).assertEqual(a);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
5
entry/src/ohosTest/ets/test/List.test.ets
Normal file
5
entry/src/ohosTest/ets/test/List.test.ets
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import abilityTest from './Ability.test';
|
||||||
|
|
||||||
|
export default function testsuite() {
|
||||||
|
abilityTest();
|
||||||
|
}
|
50
entry/src/ohosTest/ets/testability/TestAbility.ets
Normal file
50
entry/src/ohosTest/ets/testability/TestAbility.ets
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
import UIAbility from '@ohos.app.ability.UIAbility';
|
||||||
|
import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry';
|
||||||
|
import hilog from '@ohos.hilog';
|
||||||
|
import { Hypium } from '@ohos/hypium';
|
||||||
|
import testsuite from '../test/List.test';
|
||||||
|
import window from '@ohos.window';
|
||||||
|
import Want from '@ohos.app.ability.Want';
|
||||||
|
import AbilityConstant from '@ohos.app.ability.AbilityConstant';
|
||||||
|
|
||||||
|
export default class TestAbility extends UIAbility {
|
||||||
|
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onCreate');
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'want param:' + JSON.stringify(want) ?? '');
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'launchParam:' + JSON.stringify(launchParam) ?? '');
|
||||||
|
let abilityDelegator: AbilityDelegatorRegistry.AbilityDelegator;
|
||||||
|
abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
|
||||||
|
let abilityDelegatorArguments: AbilityDelegatorRegistry.AbilityDelegatorArgs;
|
||||||
|
abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments();
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'start run testcase!!!');
|
||||||
|
Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite);
|
||||||
|
}
|
||||||
|
|
||||||
|
onDestroy() {
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onDestroy');
|
||||||
|
}
|
||||||
|
|
||||||
|
onWindowStageCreate(windowStage: window.WindowStage) {
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageCreate');
|
||||||
|
windowStage.loadContent('testability/pages/Index', (err, data) => {
|
||||||
|
if (err.code) {
|
||||||
|
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s',
|
||||||
|
JSON.stringify(data) ?? '');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onWindowStageDestroy() {
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageDestroy');
|
||||||
|
}
|
||||||
|
|
||||||
|
onForeground() {
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onForeground');
|
||||||
|
}
|
||||||
|
|
||||||
|
onBackground() {
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onBackground');
|
||||||
|
}
|
||||||
|
}
|
17
entry/src/ohosTest/ets/testability/pages/Index.ets
Normal file
17
entry/src/ohosTest/ets/testability/pages/Index.ets
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
@Entry
|
||||||
|
@Component
|
||||||
|
struct Index {
|
||||||
|
@State message: string = 'Hello World';
|
||||||
|
|
||||||
|
build() {
|
||||||
|
Row() {
|
||||||
|
Column() {
|
||||||
|
Text(this.message)
|
||||||
|
.fontSize(50)
|
||||||
|
.fontWeight(FontWeight.Bold)
|
||||||
|
}
|
||||||
|
.width('100%')
|
||||||
|
}
|
||||||
|
.height('100%')
|
||||||
|
}
|
||||||
|
}
|
47
entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ets
Normal file
47
entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ets
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
import hilog from '@ohos.hilog';
|
||||||
|
import TestRunner from '@ohos.application.testRunner';
|
||||||
|
import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry';
|
||||||
|
import Want from '@ohos.app.ability.Want';
|
||||||
|
|
||||||
|
let abilityDelegator: AbilityDelegatorRegistry.AbilityDelegator | undefined = undefined
|
||||||
|
let abilityDelegatorArguments: AbilityDelegatorRegistry.AbilityDelegatorArgs | undefined = undefined
|
||||||
|
|
||||||
|
async function onAbilityCreateCallback() {
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'onAbilityCreateCallback');
|
||||||
|
}
|
||||||
|
|
||||||
|
async function addAbilityMonitorCallback(err : Error) {
|
||||||
|
hilog.info(0x0000, 'testTag', 'addAbilityMonitorCallback : %{public}s', JSON.stringify(err) ?? '');
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class OpenHarmonyTestRunner implements TestRunner {
|
||||||
|
constructor() {
|
||||||
|
}
|
||||||
|
|
||||||
|
onPrepare() {
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner OnPrepare ');
|
||||||
|
}
|
||||||
|
|
||||||
|
async onRun() {
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun run');
|
||||||
|
abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments()
|
||||||
|
abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator()
|
||||||
|
const bundleName = abilityDelegatorArguments.bundleName;
|
||||||
|
const testAbilityName = 'TestAbility';
|
||||||
|
let lMonitor: AbilityDelegatorRegistry.AbilityMonitor = {
|
||||||
|
abilityName: testAbilityName,
|
||||||
|
onAbilityCreate: onAbilityCreateCallback,
|
||||||
|
};
|
||||||
|
abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback)
|
||||||
|
const want: Want = {
|
||||||
|
bundleName: bundleName,
|
||||||
|
abilityName: testAbilityName
|
||||||
|
};
|
||||||
|
abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
|
||||||
|
abilityDelegator.startAbility(want, (err, data) => {
|
||||||
|
hilog.info(0x0000, 'testTag', 'startAbility : err : %{public}s', JSON.stringify(err) ?? '');
|
||||||
|
hilog.info(0x0000, 'testTag', 'startAbility : data : %{public}s',JSON.stringify(data) ?? '');
|
||||||
|
})
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun end');
|
||||||
|
}
|
||||||
|
}
|
38
entry/src/ohosTest/module.json5
Normal file
38
entry/src/ohosTest/module.json5
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
"module": {
|
||||||
|
"name": "entry_test",
|
||||||
|
"type": "feature",
|
||||||
|
"description": "$string:module_test_desc",
|
||||||
|
"mainElement": "TestAbility",
|
||||||
|
"deviceTypes": [
|
||||||
|
"phone",
|
||||||
|
"tablet",
|
||||||
|
"2in1"
|
||||||
|
],
|
||||||
|
"deliveryWithInstall": true,
|
||||||
|
"installationFree": false,
|
||||||
|
"pages": "$profile:test_pages",
|
||||||
|
"abilities": [
|
||||||
|
{
|
||||||
|
"name": "TestAbility",
|
||||||
|
"srcEntry": "./ets/testability/TestAbility.ets",
|
||||||
|
"description": "$string:TestAbility_desc",
|
||||||
|
"icon": "$media:icon",
|
||||||
|
"label": "$string:TestAbility_label",
|
||||||
|
"exported": true,
|
||||||
|
"startWindowIcon": "$media:icon",
|
||||||
|
"startWindowBackground": "$color:start_window_background",
|
||||||
|
"skills": [
|
||||||
|
{
|
||||||
|
"actions": [
|
||||||
|
"action.system.home"
|
||||||
|
],
|
||||||
|
"entities": [
|
||||||
|
"entity.system.home"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
8
entry/src/ohosTest/resources/base/element/color.json
Normal file
8
entry/src/ohosTest/resources/base/element/color.json
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"color": [
|
||||||
|
{
|
||||||
|
"name": "start_window_background",
|
||||||
|
"value": "#FFFFFF"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
16
entry/src/ohosTest/resources/base/element/string.json
Normal file
16
entry/src/ohosTest/resources/base/element/string.json
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"string": [
|
||||||
|
{
|
||||||
|
"name": "module_test_desc",
|
||||||
|
"value": "test ability description"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "TestAbility_desc",
|
||||||
|
"value": "the test ability"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "TestAbility_label",
|
||||||
|
"value": "test label"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
BIN
entry/src/ohosTest/resources/base/media/icon.png
Normal file
BIN
entry/src/ohosTest/resources/base/media/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"src": [
|
||||||
|
"testability/pages/Index"
|
||||||
|
]
|
||||||
|
}
|
5
entry/src/test/List.test.ets
Normal file
5
entry/src/test/List.test.ets
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import localUnitTest from './LocalUnit.test';
|
||||||
|
|
||||||
|
export default function testsuite() {
|
||||||
|
localUnitTest();
|
||||||
|
}
|
33
entry/src/test/LocalUnit.test.ets
Normal file
33
entry/src/test/LocalUnit.test.ets
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
|
||||||
|
|
||||||
|
export default function localUnitTest() {
|
||||||
|
describe('localUnitTest',() => {
|
||||||
|
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
|
||||||
|
beforeAll(() => {
|
||||||
|
// Presets an action, which is performed only once before all test cases of the test suite start.
|
||||||
|
// This API supports only one parameter: preset action function.
|
||||||
|
});
|
||||||
|
beforeEach(() => {
|
||||||
|
// Presets an action, which is performed before each unit test case starts.
|
||||||
|
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||||
|
// This API supports only one parameter: preset action function.
|
||||||
|
});
|
||||||
|
afterEach(() => {
|
||||||
|
// Presets a clear action, which is performed after each unit test case ends.
|
||||||
|
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||||
|
// This API supports only one parameter: clear action function.
|
||||||
|
});
|
||||||
|
afterAll(() => {
|
||||||
|
// Presets a clear action, which is performed after all test cases of the test suite end.
|
||||||
|
// This API supports only one parameter: clear action function.
|
||||||
|
});
|
||||||
|
it('assertContain', 0, () => {
|
||||||
|
// Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.
|
||||||
|
let a = 'abc';
|
||||||
|
let b = 'b';
|
||||||
|
// Defines a variety of assertion methods, which are used to declare expected boolean conditions.
|
||||||
|
expect(a).assertContain(b);
|
||||||
|
expect(a).assertEqual(a);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
8
hvigor/hvigor-config.json5
Normal file
8
hvigor/hvigor-config.json5
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"hvigorVersion": "file:../dependencies/hvigor-3.1.0-s.tgz",
|
||||||
|
"dependencies": {
|
||||||
|
"@ohos/hvigor-ohos-plugin": "file:../dependencies/hvigor-ohos-plugin-3.1.0-s.tgz",
|
||||||
|
"rollup": "file:../dependencies/rollup.tgz",
|
||||||
|
"fast-xml-parser": "file:../dependencies/fast-xml-parser-4.3.2.tgz"
|
||||||
|
}
|
||||||
|
}
|
2
hvigor/hvigor-wrapper.js
Normal file
2
hvigor/hvigor-wrapper.js
Normal file
File diff suppressed because one or more lines are too long
6
hvigorfile.ts
Normal file
6
hvigorfile.ts
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
import { appTasks } from '@ohos/hvigor-ohos-plugin';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
|
||||||
|
plugins:[] /* Custom plugin to extend the functionality of Hvigor. */
|
||||||
|
}
|
54
hvigorw
Normal file
54
hvigorw
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
# Hvigor startup script, version 1.0.0
|
||||||
|
#
|
||||||
|
# Required ENV vars:
|
||||||
|
# ------------------
|
||||||
|
# NODE_HOME - location of a Node home dir
|
||||||
|
# or
|
||||||
|
# Add /usr/local/nodejs/bin to the PATH environment variable
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
HVIGOR_APP_HOME="`pwd -P`"
|
||||||
|
HVIGOR_WRAPPER_SCRIPT=${HVIGOR_APP_HOME}/hvigor/hvigor-wrapper.js
|
||||||
|
#NODE_OPTS="--max-old-space-size=4096"
|
||||||
|
|
||||||
|
fail() {
|
||||||
|
echo "$*"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
set_executable_node() {
|
||||||
|
EXECUTABLE_NODE="${NODE_HOME}/bin/node"
|
||||||
|
if [ -x "$EXECUTABLE_NODE" ]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
EXECUTABLE_NODE="${NODE_HOME}/node"
|
||||||
|
if [ -x "$EXECUTABLE_NODE" ]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
fail "ERROR: NODE_HOME is set to an invalid directory,check $NODE_HOME\n\nPlease set NODE_HOME in your environment to the location where your nodejs installed"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Determine node to start hvigor wrapper script
|
||||||
|
if [ -n "${NODE_HOME}" ]; then
|
||||||
|
set_executable_node
|
||||||
|
else
|
||||||
|
EXECUTABLE_NODE="node"
|
||||||
|
command -v ${EXECUTABLE_NODE} &> /dev/null || fail "ERROR: NODE_HOME not set and 'node' command not found"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check hvigor wrapper script
|
||||||
|
if [ ! -r "$HVIGOR_WRAPPER_SCRIPT" ]; then
|
||||||
|
fail "ERROR: Couldn't find hvigor/hvigor-wrapper.js in ${HVIGOR_APP_HOME}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${NODE_OPTS}" ]; then
|
||||||
|
NODE_OPTS="--"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# start hvigor-wrapper script
|
||||||
|
exec "${EXECUTABLE_NODE}" "${NODE_OPTS}" \
|
||||||
|
"${HVIGOR_WRAPPER_SCRIPT}" "$@"
|
67
hvigorw.bat
Normal file
67
hvigorw.bat
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
@if "%DEBUG%" == "" @echo off
|
||||||
|
@rem ##########################################################################
|
||||||
|
@rem
|
||||||
|
@rem Hvigor startup script for Windows
|
||||||
|
@rem
|
||||||
|
@rem ##########################################################################
|
||||||
|
|
||||||
|
@rem Set local scope for the variables with windows NT shell
|
||||||
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
|
set DIRNAME=%~dp0
|
||||||
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
|
set APP_BASE_NAME=%~n0
|
||||||
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||||
|
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||||
|
|
||||||
|
set WRAPPER_MODULE_PATH=%APP_HOME%\hvigor\hvigor-wrapper.js
|
||||||
|
set NODE_EXE=node.exe
|
||||||
|
@rem set NODE_OPTS="--max-old-space-size=4096"
|
||||||
|
|
||||||
|
goto start
|
||||||
|
|
||||||
|
:start
|
||||||
|
if not defined NODE_OPTS set NODE_OPTS="--"
|
||||||
|
|
||||||
|
@rem Find node.exe
|
||||||
|
if defined NODE_HOME goto findNodeFromNodeHome
|
||||||
|
|
||||||
|
%NODE_EXE% --version >NUL 2>&1
|
||||||
|
if "%ERRORLEVEL%" == "0" goto execute
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH.
|
||||||
|
echo.
|
||||||
|
echo Please set the NODE_HOME variable in your environment to match the
|
||||||
|
echo location of your NodeJs installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:findNodeFromNodeHome
|
||||||
|
set NODE_HOME=%NODE_HOME:"=%
|
||||||
|
set NODE_EXE_PATH=%NODE_HOME%/%NODE_EXE%
|
||||||
|
|
||||||
|
if exist "%NODE_EXE_PATH%" goto execute
|
||||||
|
echo.
|
||||||
|
echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH.
|
||||||
|
echo.
|
||||||
|
echo Please set the NODE_HOME variable in your environment to match the
|
||||||
|
echo location of your NodeJs installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:execute
|
||||||
|
@rem Execute hvigor
|
||||||
|
"%NODE_EXE%" "%NODE_OPTS%" "%WRAPPER_MODULE_PATH%" %*
|
||||||
|
|
||||||
|
if "%ERRORLEVEL%" == "0" goto hvigorwEnd
|
||||||
|
|
||||||
|
:fail
|
||||||
|
exit /b 1
|
||||||
|
|
||||||
|
:hvigorwEnd
|
||||||
|
if "%OS%" == "Windows_NT" endlocal
|
||||||
|
|
||||||
|
:end
|
13
oh-package-lock.json5
Normal file
13
oh-package-lock.json5
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
{
|
||||||
|
"lockfileVersion": 1,
|
||||||
|
"ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.",
|
||||||
|
"specifiers": {
|
||||||
|
"@ohos/hypium@1.0.11": "@ohos/hypium@1.0.11"
|
||||||
|
},
|
||||||
|
"packages": {
|
||||||
|
"@ohos/hypium@1.0.11": {
|
||||||
|
"resolved": "https://repo.harmonyos.com/ohpm/@ohos/hypium/-/hypium-1.0.11.tgz",
|
||||||
|
"integrity": "sha512-KawcLnv43C3QIYv1UbDnKCFX3MohtDxGuFvzlUxT/qf2DBilR56Ws6zrj90LdH6PjloJQwOPESuBQIHBACAK7w=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
13
oh-package.json5
Normal file
13
oh-package.json5
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
{
|
||||||
|
"license": "",
|
||||||
|
"devDependencies": {
|
||||||
|
"@ohos/hypium": "1.0.11"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"name": "harmony_demo_napi_drawing",
|
||||||
|
"description": "Please describe the basic information.",
|
||||||
|
"main": "",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"dynamicDependencies": {},
|
||||||
|
"dependencies": {}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user