mirror of
https://gitee.com/openharmony/applications_app_samples
synced 2024-11-27 18:50:42 +00:00
Description:可变帧率提供分级管控NDK接口
Feature or Bugfix:Feature Signed-off-by: xuweinan <xuweinan5@huawei.com>
This commit is contained in:
parent
85d864e660
commit
472539db0f
5
OAT.xml
5
OAT.xml
@ -661,6 +661,11 @@ Note:If the text contains special characters, please escape them according to th
|
||||
<filteritem type="filepath" name="code/BasicFeature/DeviceManagement/Sensor/Capi/entry/src/main/resources/base/media/compass.png" desc="Provided by code/BasicFeature/DeviceManagement/Sensor"/>
|
||||
<filteritem type="filepath" name=" code/BasicFeature/DeviceManagement/Vibrator/CustomHaptic/entry/src/main/resources/base/media/select.png" desc="Provided by code/BasicFeature/DeviceManagement/Vibrator"/>
|
||||
<filteritem type="filepath" name="code/BasicFeature/Graphics/DisplaySync/screenshots/device/animator.jpg" desc="Provided by code/BasicFeature/Graphics/DisplaySync"/>
|
||||
<filteritem type="filepath" name="code/BasicFeature/Graphics/DisplaySoloist/screenshots/device/displaySoloist.jpg" desc="Provided by code/BasicFeature/Graphics/DisplaySoloist"/>
|
||||
<filteritem type="filepath" name="code/BasicFeature/Graphics/DisplaySoloist/entry/src/ohosTest/resources/base/media/icon.png" desc="Provided by code/BasicFeature/Graphics/DisplaySoloist"/>
|
||||
<filteritem type="filepath" name="code/BasicFeature/Graphics/DisplaySoloist/entry/src/main/resources/base/media/startIcon.png" desc="Provided by code/BasicFeature/Graphics/DisplaySoloist"/>
|
||||
<filteritem type="filepath" name="code/BasicFeature/Graphics/DisplaySoloist/AppScope/resources/base/media/app_icon.png" desc="Provided by code/BasicFeature/Graphics/DisplaySoloist"/>
|
||||
<filteritem type="filepath" name="code/BasicFeature/Graphics/DisplaySoloist/entry/src/main/resources/base/media/icon.png" desc="Provided by code/BasicFeature/Graphics/DisplaySoloist"/>
|
||||
<filteritem type="filepath" name="code/Solutions/Social/GrapeSquare/feature/authorizedControl/src/main/resources/base/media/photo120.jpg" desc="Provided by code/Solutions/Social/GrapeSquare"/>
|
||||
<filteritem type="filepath" name="code/BasicFeature/WindowManagement/WindowManage/screenshots/devices/getPropertiesOfSystemBar.jpg" desc="Provided by code/BasicFeature/WindowManagement/WindowManage"/>
|
||||
<filteritem type="filepath" name="code/BasicFeature/WindowManagement/WindowManage/screenshots/devices/mainWindow.jpg" desc="Provided by code/BasicFeature/WindowManagement/WindowManage"/>
|
||||
|
11
code/BasicFeature/Graphics/DisplaySoloist/.gitignore
vendored
Normal file
11
code/BasicFeature/Graphics/DisplaySoloist/.gitignore
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
/node_modules
|
||||
/oh_modules
|
||||
/local.properties
|
||||
/.idea
|
||||
**/build
|
||||
/.hvigor
|
||||
.cxx
|
||||
/.clangd
|
||||
/.clang-format
|
||||
/.clang-tidy
|
||||
**/.test
|
25
code/BasicFeature/Graphics/DisplaySoloist/AppScope/app.json5
Normal file
25
code/BasicFeature/Graphics/DisplaySoloist/AppScope/app.json5
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
{
|
||||
"app": {
|
||||
"bundleName": "com.samples.DisplaySoloist",
|
||||
"vendor": "example",
|
||||
"versionCode": 1000000,
|
||||
"versionName": "1.0.0",
|
||||
"icon": "$media:app_icon",
|
||||
"label": "$string:app_name"
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
{
|
||||
"string": [
|
||||
{
|
||||
"name": "app_name",
|
||||
"value": "DisplaySoloist"
|
||||
}
|
||||
]
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
82
code/BasicFeature/Graphics/DisplaySoloist/README_zh.md
Normal file
82
code/BasicFeature/Graphics/DisplaySoloist/README_zh.md
Normal file
@ -0,0 +1,82 @@
|
||||
# DisplaySoloist分级管控
|
||||
|
||||
### 介绍
|
||||
|
||||
本示例通过DisplaySoloist分级管控功能,使用UI以外的线程对XComponent的绘制内容设置开发者所期望的帧率。
|
||||
### 效果预览
|
||||
|
||||
| XComponent |
|
||||
|---------------------------------------------------------------|
|
||||
| <img src="./screenshots/device/displaySoloist.jpg" width="100%"/> |
|
||||
|
||||
使用说明
|
||||
|
||||
1.进入XComponent页面,依次点击“**Start**”,三个方块分别按照30Hz、60Hz、120Hz移动;点击“**Stop**”动画停止;
|
||||
|
||||
### 工程目录
|
||||
```
|
||||
├──entry/src/main
|
||||
│ ├──cpp // C++代码区
|
||||
│ │ ├──CMakeLists.txt // CMake配置文件
|
||||
│ │ ├──hello.cpp // Napi模块注册
|
||||
│ │ ├──common
|
||||
│ │ │ └──log_common.h // 日志封装定义文件
|
||||
│ │ ├──plugin // 生命周期管理模块
|
||||
│ │ │ ├──plugin_manager.cpp
|
||||
│ │ │ └──plugin_manager.h
|
||||
│ │ ├──samples // samples渲染模块
|
||||
│ │ │ ├──sample_xcomponent.cpp
|
||||
│ │ │ └──sample_xcomponent.h
|
||||
│ ├──ets // ets代码区
|
||||
│ │ ├──entryability
|
||||
│ │ │ ├──EntryAbility.ts // 程序入口类
|
||||
| | | └──EntryAbility.ets
|
||||
| | ├──interface
|
||||
│ │ │ └──XComponentContext.ts // XComponentContext
|
||||
│ │ ├──pages // 页面文件
|
||||
│ │ | └──Index.ets // XComponent页面
|
||||
│ │ ├──utils // 工具类
|
||||
| ├──resources // 资源文件目录
|
||||
```
|
||||
|
||||
### 具体实现
|
||||
|
||||
* XComponent:通过在IDE中的Native c++ 工程,在c++代码中定义对外接口为register、unregister以及destroy,并调用NativeDisplaySoloist分级管控接口,可在页面上使用drawing根据设定的期望帧率来绘制。
|
||||
|
||||
| 接口名 | 描述 |
|
||||
| -------- | -------- |
|
||||
| OH_DisplaySoloist_Create| 创建一个OH_DisplaySoloist实例 |
|
||||
| OH_DisplaySoloist_Destroy | 销毁一个OH_DisplaySoloist实例 |
|
||||
| OH_DisplaySoloist_Start | 设置每帧回调函数,每次vsync信号到来时启动每帧回调 |
|
||||
| OH_DisplaySoloist_Stop | 停止请求下一次vsync信号,并停止调用回调函数callback |
|
||||
| OH_DisplaySoloist_SetExpectedFrameRateRange | 设置期望帧率范围 |
|
||||
|
||||
|
||||
### 相关权限
|
||||
|
||||
不涉及
|
||||
|
||||
### 依赖
|
||||
|
||||
不涉及
|
||||
|
||||
### 约束与限制
|
||||
|
||||
1.本示例仅支持在标准系统上运行,支持设备:RK3568。
|
||||
|
||||
2.本示例为Stage模型,已适配API version 12版本SDK,SDK版本号(API Version 12 5.0.0.26),镜像版本号(5.0.0.26)。
|
||||
|
||||
3.本示例需要使用DevEco Studio 版本号(4.1.3.500)及以上版本才可编译运行。
|
||||
|
||||
|
||||
### 下载
|
||||
|
||||
如需单独下载本工程,执行如下命令:
|
||||
```
|
||||
git init
|
||||
git config core.sparsecheckout true
|
||||
echo code/SystemFeature/Graphics/DisplaySoloist/ > .git/info/sparse-checkout
|
||||
git remote add origin https://gitee.com/openharmony/applications_app_samples.git
|
||||
git pull origin master
|
||||
|
||||
```
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
{
|
||||
"app": {
|
||||
"signingConfigs": [],
|
||||
"products": [
|
||||
{
|
||||
"compileSdkVersion": 12,
|
||||
"compatibleSdkVersion": 12,
|
||||
"name": "default",
|
||||
"signingConfig": "default",
|
||||
}
|
||||
]
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "entry",
|
||||
"srcPath": "./entry",
|
||||
"targets": [
|
||||
{
|
||||
"name": "default",
|
||||
"applyToProducts": [
|
||||
"default"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
6
code/BasicFeature/Graphics/DisplaySoloist/entry/.gitignore
vendored
Normal file
6
code/BasicFeature/Graphics/DisplaySoloist/entry/.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
/node_modules
|
||||
/oh_modules
|
||||
/.preview
|
||||
/build
|
||||
/.cxx
|
||||
/.test
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
{
|
||||
"apiType": "stageMode",
|
||||
"buildOption": {
|
||||
"externalNativeOptions": {
|
||||
"path": "./src/main/cpp/CMakeLists.txt",
|
||||
"arguments": "",
|
||||
"cppFlags": "",
|
||||
"abiFilters": ["arm64-v8a", "armeabi-v7a", "x86_64"]
|
||||
}
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"name": "default",
|
||||
"runtimeOS": "OpenHarmony"
|
||||
},
|
||||
{
|
||||
"name": "ohosTest",
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export { hapTasks } from '@ohos/hvigor-ohos-plugin';
|
@ -0,0 +1,12 @@
|
||||
{
|
||||
"license": "",
|
||||
"devDependencies": {},
|
||||
"author": "",
|
||||
"name": "entry",
|
||||
"description": "Please describe the basic information.",
|
||||
"main": "",
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"libentry.so": "file:./src/main/cpp/types/libentry"
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
# the minimum version of CMake.
|
||||
cmake_minimum_required(VERSION 3.4.1)
|
||||
project(drawing_test)
|
||||
|
||||
set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
include_directories(${NATIVERENDER_ROOT_PATH}
|
||||
${NATIVERENDER_ROOT_PATH}/include)
|
||||
|
||||
add_library(entry SHARED
|
||||
hello.cpp
|
||||
samples/sample_xcomponent.cpp
|
||||
plugin/plugin_manager.cpp
|
||||
)
|
||||
find_library(
|
||||
# Sets the name of the path variable.
|
||||
hilog-lib
|
||||
# Specifies the name of the NDK library that
|
||||
# you want CMake to locate.
|
||||
hilog_ndk.z
|
||||
)
|
||||
target_link_libraries(entry PUBLIC ${hilog-lib})
|
||||
target_link_libraries(entry PUBLIC libace_napi.z.so libnative_drawing.so libnative_window.so libace_ndk.z.so libnative_display_soloist.so)
|
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef LOG_COMMON_H
|
||||
#define LOG_COMMON_H
|
||||
#include <hilog/log.h>
|
||||
#define LOG_PRINT_DOMAIN 0xFF00
|
||||
#define APP_LOG_DOMAIN 0x0001
|
||||
constexpr const char *APP_LOG_TAG = "DisplaySoloistSample";
|
||||
#define SAMPLE_LOGI(...) ((void)OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, APP_LOG_TAG, __VA_ARGS__))
|
||||
#define SAMPLE_LOGD(...) ((void)OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_DOMAIN, APP_LOG_TAG, __VA_ARGS__))
|
||||
#define SAMPLE_LOGW(...) ((void)OH_LOG_Print(LOG_APP, LOG_WARN, LOG_DOMAIN, APP_LOG_TAG, __VA_ARGS__))
|
||||
#define SAMPLE_LOGE(...) ((void)OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, APP_LOG_TAG, __VA_ARGS__))
|
||||
|
||||
#endif // LOG_COMMON_H
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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 <hilog/log.h>
|
||||
#include "napi/native_api.h"
|
||||
#include "common/log_common.h"
|
||||
#include "plugin/plugin_manager.h"
|
||||
|
||||
EXTERN_C_START
|
||||
static napi_value Init(napi_env env, napi_value exports)
|
||||
{
|
||||
SAMPLE_LOGI("napi init");
|
||||
PluginManager::GetInstance()->Export(env, exports);
|
||||
return exports;
|
||||
}
|
||||
EXTERN_C_END
|
||||
|
||||
static napi_module demoModule = {
|
||||
.nm_version = 1,
|
||||
.nm_flags = 0,
|
||||
.nm_filename = nullptr,
|
||||
.nm_register_func = Init,
|
||||
.nm_modname = "entry",
|
||||
.nm_priv = ((void *)0),
|
||||
.reserved = {0},
|
||||
};
|
||||
|
||||
extern "C" __attribute__((constructor)) void RegisterEntryModule(void)
|
||||
{
|
||||
napi_module_register(&demoModule);
|
||||
}
|
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* 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 <ace/xcomponent/native_interface_xcomponent.h>
|
||||
#include <cstdint>
|
||||
#include <hilog/log.h>
|
||||
#include <string>
|
||||
#include "common/log_common.h"
|
||||
#include "plugin_manager.h"
|
||||
|
||||
PluginManager *PluginManager::GetInstance()
|
||||
{
|
||||
static PluginManager pluginManager;
|
||||
return &pluginManager;
|
||||
}
|
||||
|
||||
PluginManager::~PluginManager()
|
||||
{
|
||||
SAMPLE_LOGI("~PluginManager");
|
||||
for (auto iter = nativeXComponentMap_.begin(); iter != nativeXComponentMap_.end(); ++iter) {
|
||||
if (iter->second != nullptr) {
|
||||
delete iter->second;
|
||||
iter->second = nullptr;
|
||||
}
|
||||
}
|
||||
nativeXComponentMap_.clear();
|
||||
|
||||
for (auto iter = pluginRenderMap_.begin(); iter != pluginRenderMap_.end(); ++iter) {
|
||||
if (iter->second != nullptr) {
|
||||
delete iter->second;
|
||||
iter->second = nullptr;
|
||||
}
|
||||
}
|
||||
pluginRenderMap_.clear();
|
||||
}
|
||||
|
||||
void PluginManager::Export(napi_env env, napi_value exports)
|
||||
{
|
||||
nativeXComponentMap_.clear();
|
||||
pluginRenderMap_.clear();
|
||||
if ((env == nullptr) || (exports == nullptr)) {
|
||||
SAMPLE_LOGE("Export: env or exports is null");
|
||||
return;
|
||||
}
|
||||
|
||||
napi_value exportInstance = nullptr;
|
||||
if (napi_get_named_property(env, exports, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance) != napi_ok) {
|
||||
SAMPLE_LOGE("Export: napi_get_named_property fail");
|
||||
return;
|
||||
}
|
||||
|
||||
OH_NativeXComponent *nativeXComponent = nullptr;
|
||||
if (napi_unwrap(env, exportInstance, reinterpret_cast<void **>(&nativeXComponent)) != napi_ok) {
|
||||
SAMPLE_LOGE("Export: napi_unwrap fail");
|
||||
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) {
|
||||
SAMPLE_LOGE("Export: OH_NativeXComponent_GetXComponentId fail");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string id(idStr);
|
||||
auto context = PluginManager::GetInstance();
|
||||
if ((context != nullptr) && (nativeXComponent != nullptr)) {
|
||||
context->SetNativeXComponent(id, nativeXComponent);
|
||||
auto render = context->GetRender(id);
|
||||
if (render != nullptr) {
|
||||
render->RegisterCallback(nativeXComponent);
|
||||
render->Export(env, exports);
|
||||
} else {
|
||||
SAMPLE_LOGE("render is nullptr");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PluginManager::SetNativeXComponent(std::string &id, OH_NativeXComponent *nativeXComponent)
|
||||
{
|
||||
SAMPLE_LOGI("set native xComponent, ID = %{public}s.", id.c_str());
|
||||
if (nativeXComponent == nullptr) {
|
||||
SAMPLE_LOGE("xcomponent null");
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
SampleXComponent *PluginManager::GetRender(std::string &id)
|
||||
{
|
||||
if (pluginRenderMap_.find(id) == pluginRenderMap_.end()) {
|
||||
SampleXComponent *instance = SampleXComponent::GetInstance(id);
|
||||
pluginRenderMap_[id] = instance;
|
||||
return instance;
|
||||
}
|
||||
return pluginRenderMap_[id];
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef PLUGIN_MANAGER_H
|
||||
#define PLUGIN_MANAGER_H
|
||||
|
||||
#include <ace/xcomponent/native_interface_xcomponent.h>
|
||||
#include <js_native_api.h>
|
||||
#include <js_native_api_types.h>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include "samples/sample_xcomponent.h"
|
||||
|
||||
class PluginManager {
|
||||
public:
|
||||
~PluginManager();
|
||||
|
||||
static PluginManager *GetInstance();
|
||||
|
||||
void SetNativeXComponent(std::string &id, OH_NativeXComponent *nativeXComponent);
|
||||
SampleXComponent *GetRender(std::string &id);
|
||||
void Export(napi_env env, napi_value exports);
|
||||
private:
|
||||
|
||||
std::unordered_map<std::string, OH_NativeXComponent *> nativeXComponentMap_;
|
||||
std::unordered_map<std::string, SampleXComponent *> pluginRenderMap_;
|
||||
};
|
||||
#endif // PLUGIN_MANAGER_H
|
@ -0,0 +1,498 @@
|
||||
/*
|
||||
* 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 <bits/alltypes.h>
|
||||
#include <native_drawing/drawing_text_typography.h>
|
||||
#include <native_display_soloist/native_display_soloist.h>
|
||||
#include <unistd.h>
|
||||
#include "common/log_common.h"
|
||||
#include "sample_xcomponent.h"
|
||||
|
||||
static std::unordered_map<std::string, OH_DisplaySoloist *> g_displaySync;
|
||||
|
||||
static void OnSurfaceCreatedCB(OH_NativeXComponent *component, void *window)
|
||||
{
|
||||
SAMPLE_LOGI("OnSurfaceCreatedCB");
|
||||
if ((component == nullptr) || (window == nullptr)) {
|
||||
SAMPLE_LOGE("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) {
|
||||
SAMPLE_LOGE("OnSurfaceCreatedCB: Unable to get XComponent id");
|
||||
return;
|
||||
}
|
||||
std::string id(idStr);
|
||||
auto render = SampleXComponent::GetInstance(id);
|
||||
OHNativeWindow *nativeWindow = static_cast<OHNativeWindow *>(window);
|
||||
render->SetNativeWindow(nativeWindow);
|
||||
|
||||
uint64_t width;
|
||||
uint64_t height;
|
||||
int32_t xSize = OH_NativeXComponent_GetXComponentSize(component, window, &width, &height);
|
||||
if ((xSize == OH_NATIVEXCOMPONENT_RESULT_SUCCESS) && (render != nullptr)) {
|
||||
render->SetHeight(height);
|
||||
render->SetWidth(width);
|
||||
SAMPLE_LOGI("xComponent width = %{public}llu, height = %{public}llu", width, height);
|
||||
}
|
||||
}
|
||||
|
||||
static void OnSurfaceDestroyedCB(OH_NativeXComponent *component, void *window)
|
||||
{
|
||||
SAMPLE_LOGI("OnSurfaceDestroyedCB");
|
||||
if ((component == nullptr) || (window == nullptr)) {
|
||||
SAMPLE_LOGE("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) {
|
||||
SAMPLE_LOGE("OnSurfaceDestroyedCB: Unable to get XComponent id");
|
||||
return;
|
||||
}
|
||||
std::string id(idStr);
|
||||
SampleXComponent::Release(id);
|
||||
}
|
||||
|
||||
|
||||
static void TestCallback(long long timestamp, long long targetTimestamp, void *data)
|
||||
{
|
||||
SAMPLE_LOGI("test callback timestamp = %{public}llu, ", timestamp);
|
||||
OH_NativeXComponent *component = nullptr;
|
||||
component = static_cast<OH_NativeXComponent *>(data);
|
||||
if (component == nullptr) {
|
||||
SAMPLE_LOGE("TestCallback: component 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) {
|
||||
SAMPLE_LOGE("TestCallback: Unable to get XComponent id");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string id(idStr);
|
||||
auto render = SampleXComponent::GetInstance(id);
|
||||
OHNativeWindow *nativeWindow = render->GetNativeWindow();
|
||||
uint64_t width;
|
||||
uint64_t height;
|
||||
|
||||
int32_t xSize = OH_NativeXComponent_GetXComponentSize(component, nativeWindow, &width, &height);
|
||||
if ((xSize == OH_NATIVEXCOMPONENT_RESULT_SUCCESS) && (render != nullptr)) {
|
||||
render->Prepare();
|
||||
render->Create();
|
||||
// 每帧移动8像素
|
||||
render->ConstructPath(8, 8, render->defaultOffsetY);
|
||||
render->SetPenAndBrush();
|
||||
render->DrawPath();
|
||||
render->DisPlay();
|
||||
render->Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
static std::unordered_map<std::string, SampleXComponent *> g_instance;
|
||||
|
||||
void SampleXComponent::SetWidth(uint64_t width) { width_ = width; }
|
||||
|
||||
void SampleXComponent::SetHeight(uint64_t height) { height_ = height; }
|
||||
|
||||
void SampleXComponent::SetNativeWindow(OHNativeWindow *nativeWindow) { nativeWindow_ = nativeWindow; }
|
||||
|
||||
OHNativeWindow *SampleXComponent::GetNativeWindow() { return nativeWindow_; }
|
||||
|
||||
void SampleXComponent::Prepare()
|
||||
{
|
||||
if (nativeWindow_ == nullptr) {
|
||||
SAMPLE_LOGE("nativeWindow_ is nullptr");
|
||||
return;
|
||||
}
|
||||
// 这里的nativeWindow是从上一步骤中的回调函数中获得的
|
||||
// 通过 OH_NativeWindow_NativeWindowRequestBuffer 获取 OHNativeWindowBuffer 实例
|
||||
int ret = OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow_, &buffer_, &fenceFd_);
|
||||
SAMPLE_LOGI("request buffer ret = %{public}d", ret);
|
||||
// 通过 OH_NativeWindow_GetBufferHandleFromNative 获取 buffer 的 handle
|
||||
bufferHandle_ = OH_NativeWindow_GetBufferHandleFromNative(buffer_);
|
||||
// 使用系统mmap接口拿到bufferHandle的内存虚拟地址
|
||||
mappedAddr_ = static_cast<uint32_t *>(
|
||||
mmap(bufferHandle_->virAddr, bufferHandle_->size, PROT_READ | PROT_WRITE, MAP_SHARED, bufferHandle_->fd, 0));
|
||||
if (mappedAddr_ == MAP_FAILED) {
|
||||
SAMPLE_LOGE("mmap failed");
|
||||
}
|
||||
}
|
||||
|
||||
void SampleXComponent::DisPlay()
|
||||
{
|
||||
// 画完后获取像素地址,地址指向的内存包含画布画的像素数据
|
||||
void *bitmapAddr = OH_Drawing_BitmapGetPixels(cBitmap_);
|
||||
uint32_t *value = static_cast<uint32_t *>(bitmapAddr);
|
||||
|
||||
uint32_t *pixel = static_cast<uint32_t *>(mappedAddr_); // 使用mmap获取到的地址来访问内存
|
||||
if (pixel == nullptr) {
|
||||
SAMPLE_LOGE("pixel is null");
|
||||
return;
|
||||
}
|
||||
if (value == nullptr) {
|
||||
SAMPLE_LOGE("value is null");
|
||||
return;
|
||||
}
|
||||
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) {
|
||||
SAMPLE_LOGE("munmap failed!");
|
||||
}
|
||||
}
|
||||
|
||||
void SampleXComponent::Create()
|
||||
{
|
||||
uint32_t width = static_cast<uint32_t>(bufferHandle_->stride / 4);
|
||||
// 创建一个bitmap对象
|
||||
cBitmap_ = OH_Drawing_BitmapCreate();
|
||||
// 定义bitmap的像素格式
|
||||
OH_Drawing_BitmapFormat cFormat{COLOR_FORMAT_RGBA_8888, ALPHA_FORMAT_OPAQUE};
|
||||
// 构造对应格式的bitmap
|
||||
OH_Drawing_BitmapBuild(cBitmap_, width, height_, &cFormat);
|
||||
|
||||
// 创建一个canvas对象
|
||||
cCanvas_ = OH_Drawing_CanvasCreate();
|
||||
// 将画布与bitmap绑定,画布画的内容会输出到绑定的bitmap内存中
|
||||
OH_Drawing_CanvasBind(cCanvas_, cBitmap_);
|
||||
// 使用白色清除画布内容
|
||||
OH_Drawing_CanvasClear(cCanvas_, OH_Drawing_ColorSetArgb(0xFF, 0xFF, 0xFF, 0xFF));
|
||||
}
|
||||
|
||||
void SampleXComponent::ConstructPath(int x, int y, int offsetY)
|
||||
{
|
||||
// 初始的矩形A点纵坐标为100.0
|
||||
aY = 100.0 + offsetY;
|
||||
// 初始的矩形C点纵坐标为200.0
|
||||
cY = 200.0 + offsetY;
|
||||
|
||||
if (desc) {
|
||||
aX -= x * 1.0;
|
||||
bX -= x * 1.0;
|
||||
} else {
|
||||
aX += x * 1.0;
|
||||
bX += x * 1.0;
|
||||
}
|
||||
|
||||
if (bX >= width_) {
|
||||
desc = true;
|
||||
}
|
||||
|
||||
if (aX <= 0) {
|
||||
desc = false;
|
||||
}
|
||||
|
||||
float bY = aY;
|
||||
float cX = bX;
|
||||
float dX = aX;
|
||||
float dY = cY;
|
||||
|
||||
// 创建一个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);
|
||||
|
||||
// 闭合形状,path绘制完毕
|
||||
OH_Drawing_PathClose(cPath_);
|
||||
}
|
||||
|
||||
void SampleXComponent::SetPenAndBrush()
|
||||
{
|
||||
constexpr float penWidth = 10.0f; // pen width 10
|
||||
// 创建一个画笔Pen对象,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_, penWidth);
|
||||
OH_Drawing_PenSetJoin(cPen_, LINE_ROUND_JOIN);
|
||||
// 将Pen画笔设置到canvas中
|
||||
OH_Drawing_CanvasAttachPen(cCanvas_, cPen_);
|
||||
|
||||
// 创建一个画刷Brush对象,Brush对象用于形状的填充
|
||||
cBrush_ = OH_Drawing_BrushCreate();
|
||||
OH_Drawing_BrushSetColor(cBrush_, OH_Drawing_ColorSetArgb(0xFF, 0x00, 0xFF, 0x00));
|
||||
|
||||
// 将Brush画刷设置到canvas中
|
||||
OH_Drawing_CanvasAttachBrush(cCanvas_, cBrush_);
|
||||
}
|
||||
|
||||
void SampleXComponent::DrawPath()
|
||||
{
|
||||
// 在画布上画path的形状,矩形的边框样式为pen设置,颜色填充为Brush设置
|
||||
OH_Drawing_CanvasDrawPath(cCanvas_, cPath_);
|
||||
}
|
||||
|
||||
void ExecuteDisplaySoloist(std::string id, DisplaySoloist_ExpectedRateRange range, bool useExclusiveThread,
|
||||
OH_NativeXComponent *nativeXComponent)
|
||||
{
|
||||
OH_DisplaySoloist *nativeDisplaySoloist = nullptr;
|
||||
if (g_displaySync.find(id) == g_displaySync.end()) {
|
||||
g_displaySync[id] = OH_DisplaySoloist_Create(useExclusiveThread);
|
||||
}
|
||||
nativeDisplaySoloist = g_displaySync[id];
|
||||
OH_DisplaySoloist_SetExpectedFrameRateRange(nativeDisplaySoloist, &range);
|
||||
OH_DisplaySoloist_Start(nativeDisplaySoloist, TestCallback, nativeXComponent);
|
||||
}
|
||||
|
||||
napi_value SampleXComponent::NapiRegister(napi_env env, napi_callback_info info)
|
||||
{
|
||||
SAMPLE_LOGI("NapiRegister");
|
||||
if ((env == nullptr) || (info == nullptr)) {
|
||||
SAMPLE_LOGE("NapiRegister: env or info is null");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
napi_value thisArg;
|
||||
if (napi_get_cb_info(env, info, nullptr, nullptr, &thisArg, nullptr) != napi_ok) {
|
||||
SAMPLE_LOGE("NapiRegister: napi_get_cb_info fail");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
napi_value exportInstance;
|
||||
if (napi_get_named_property(env, thisArg, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance) != napi_ok) {
|
||||
SAMPLE_LOGE("NapiRegister: napi_get_named_property fail");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
OH_NativeXComponent *nativeXComponent = nullptr;
|
||||
if (napi_unwrap(env, exportInstance, reinterpret_cast<void **>(&nativeXComponent)) != napi_ok) {
|
||||
SAMPLE_LOGE("NapiRegister: 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_GetXComponentId(nativeXComponent, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
|
||||
SAMPLE_LOGE("NapiRegister: Unable to get XComponent id");
|
||||
return nullptr;
|
||||
}
|
||||
SAMPLE_LOGI("RegisterID = %{public}s", idStr);
|
||||
std::string id(idStr);
|
||||
SampleXComponent *render = SampleXComponent().GetInstance(id);
|
||||
if (render != nullptr) {
|
||||
DisplaySoloist_ExpectedRateRange range;
|
||||
bool useExclusiveThread = false;
|
||||
if (id == "xcomponentId30") {
|
||||
// 第一个按照期望30HZ的帧率来移动
|
||||
range = {30, 120, 30};
|
||||
}
|
||||
|
||||
if (id == "xcomponentId60") {
|
||||
// 第二个按照期望60HZ的帧率来移动
|
||||
range = {30, 120, 60};
|
||||
useExclusiveThread = true;
|
||||
}
|
||||
|
||||
if (id == "xcomponentId120") {
|
||||
// 第三个按照期望120HZ的帧率来移动
|
||||
range = {30, 120, 120};
|
||||
}
|
||||
ExecuteDisplaySoloist(id, range, useExclusiveThread, nativeXComponent);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
napi_value SampleXComponent::NapiUnregister(napi_env env, napi_callback_info info)
|
||||
{
|
||||
SAMPLE_LOGI("NapiUnregister");
|
||||
if ((env == nullptr) || (info == nullptr)) {
|
||||
SAMPLE_LOGE("NapiUnregister: env or info is null");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
napi_value thisArg;
|
||||
if (napi_get_cb_info(env, info, nullptr, nullptr, &thisArg, nullptr) != napi_ok) {
|
||||
SAMPLE_LOGE("NapiUnregister: napi_get_cb_info fail");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
napi_value exportInstance;
|
||||
if (napi_get_named_property(env, thisArg, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance) != napi_ok) {
|
||||
SAMPLE_LOGE("NapiUnregister: napi_get_named_property fail");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
OH_NativeXComponent *nativeXComponent = nullptr;
|
||||
if (napi_unwrap(env, exportInstance, reinterpret_cast<void **>(&nativeXComponent)) != napi_ok) {
|
||||
SAMPLE_LOGE("NapiUnregister: 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_GetXComponentId(nativeXComponent, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
|
||||
SAMPLE_LOGE("NapiUnregister: Unable to get XComponent id");
|
||||
return nullptr;
|
||||
}
|
||||
SAMPLE_LOGI("ID = %{public}s", idStr);
|
||||
std::string id(idStr);
|
||||
SampleXComponent *render = SampleXComponent().GetInstance(id);
|
||||
if (render != nullptr) {
|
||||
OH_DisplaySoloist_Stop(g_displaySync[id]);
|
||||
SAMPLE_LOGI("NapiUnregister executed");
|
||||
} else {
|
||||
SAMPLE_LOGE("render is nullptr");
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
napi_value SampleXComponent::NapiDestroy(napi_env env, napi_callback_info info)
|
||||
{
|
||||
SAMPLE_LOGI("NapiUnregister");
|
||||
if ((env == nullptr) || (info == nullptr)) {
|
||||
SAMPLE_LOGE("NapiDestroy: env or info is null");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
napi_value thisArg;
|
||||
if (napi_get_cb_info(env, info, nullptr, nullptr, &thisArg, nullptr) != napi_ok) {
|
||||
SAMPLE_LOGE("NapiDestroy: napi_get_cb_info fail");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
napi_value exportInstance;
|
||||
if (napi_get_named_property(env, thisArg, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance) != napi_ok) {
|
||||
SAMPLE_LOGE("NapiDestroy: napi_get_named_property fail");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
OH_NativeXComponent *nativeXComponent = nullptr;
|
||||
if (napi_unwrap(env, exportInstance, reinterpret_cast<void **>(&nativeXComponent)) != napi_ok) {
|
||||
SAMPLE_LOGE("NapiDestroy: 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_GetXComponentId(nativeXComponent, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
|
||||
SAMPLE_LOGE("NapiDestroy: Unable to get XComponent id");
|
||||
return nullptr;
|
||||
}
|
||||
SAMPLE_LOGI("ID = %{public}s", idStr);
|
||||
std::string id(idStr);
|
||||
SampleXComponent *render = SampleXComponent().GetInstance(id);
|
||||
if (render != nullptr) {
|
||||
OH_DisplaySoloist_Destroy(g_displaySync[id]);
|
||||
g_displaySync.erase(id);
|
||||
SAMPLE_LOGI("NapiUnregister executed");
|
||||
} else {
|
||||
SAMPLE_LOGE("render is nullptr");
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SampleXComponent::~SampleXComponent()
|
||||
{
|
||||
// 销毁创建的对象
|
||||
OH_Drawing_BrushDestroy(cBrush_);
|
||||
cBrush_ = nullptr;
|
||||
OH_Drawing_PenDestroy(cPen_);
|
||||
cPen_ = nullptr;
|
||||
OH_Drawing_PathDestroy(cPath_);
|
||||
cPath_ = nullptr;
|
||||
// 销毁canvas对象
|
||||
OH_Drawing_CanvasDestroy(cCanvas_);
|
||||
cCanvas_ = nullptr;
|
||||
// 销毁bitmap对象
|
||||
OH_Drawing_BitmapDestroy(cBitmap_);
|
||||
cBitmap_ = nullptr;
|
||||
|
||||
buffer_ = nullptr;
|
||||
bufferHandle_ = nullptr;
|
||||
nativeWindow_ = nullptr;
|
||||
mappedAddr_ = nullptr;
|
||||
}
|
||||
|
||||
void SampleXComponent::Destroy()
|
||||
{
|
||||
// 销毁创建的对象
|
||||
OH_Drawing_BrushDestroy(cBrush_);
|
||||
cBrush_ = nullptr;
|
||||
OH_Drawing_PenDestroy(cPen_);
|
||||
cPen_ = nullptr;
|
||||
OH_Drawing_PathDestroy(cPath_);
|
||||
cPath_ = nullptr;
|
||||
// 销毁canvas对象
|
||||
OH_Drawing_CanvasDestroy(cCanvas_);
|
||||
cCanvas_ = nullptr;
|
||||
// 销毁bitmap对象
|
||||
OH_Drawing_BitmapDestroy(cBitmap_);
|
||||
cBitmap_ = nullptr;
|
||||
}
|
||||
|
||||
void SampleXComponent::Release(std::string &id)
|
||||
{
|
||||
SampleXComponent *render = SampleXComponent::GetInstance(id);
|
||||
if (render != nullptr) {
|
||||
delete render;
|
||||
render = nullptr;
|
||||
g_instance.erase(g_instance.find(id));
|
||||
}
|
||||
}
|
||||
|
||||
void SampleXComponent::Export(napi_env env, napi_value exports)
|
||||
{
|
||||
if ((env == nullptr) || (exports == nullptr)) {
|
||||
SAMPLE_LOGE("Export: env or exports is null");
|
||||
return;
|
||||
}
|
||||
napi_property_descriptor desc[] = {
|
||||
{"register", nullptr, SampleXComponent::NapiRegister, nullptr, nullptr, nullptr, napi_default, nullptr},
|
||||
{"unregister", nullptr, SampleXComponent::NapiUnregister, nullptr, nullptr, nullptr, napi_default, nullptr},
|
||||
{"destroy", nullptr, SampleXComponent::NapiDestroy, nullptr, nullptr, nullptr, napi_default, nullptr}};
|
||||
|
||||
napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
|
||||
if (napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc) != napi_ok) {
|
||||
SAMPLE_LOGE("Export: napi_define_properties failed");
|
||||
}
|
||||
}
|
||||
|
||||
void SampleXComponent::RegisterCallback(OH_NativeXComponent *nativeXComponent)
|
||||
{
|
||||
SAMPLE_LOGI("register callback");
|
||||
renderCallback_.OnSurfaceCreated = OnSurfaceCreatedCB;
|
||||
renderCallback_.OnSurfaceDestroyed = OnSurfaceDestroyedCB;
|
||||
// Callback must be initialized
|
||||
renderCallback_.DispatchTouchEvent = nullptr;
|
||||
renderCallback_.OnSurfaceChanged = nullptr;
|
||||
OH_NativeXComponent_RegisterCallback(nativeXComponent, &renderCallback_);
|
||||
}
|
||||
|
||||
SampleXComponent *SampleXComponent::GetInstance(std::string &id)
|
||||
{
|
||||
if (g_instance.find(id) == g_instance.end()) {
|
||||
SampleXComponent *render = new SampleXComponent(id);
|
||||
g_instance[id] = render;
|
||||
return render;
|
||||
} else {
|
||||
return g_instance[id];
|
||||
}
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef SAMPLE_XCOMPONENT_H
|
||||
#define SAMPLE_XCOMPONENT_H
|
||||
#include <ace/xcomponent/native_interface_xcomponent.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <bits/alltypes.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 <cstdint>
|
||||
#include <map>
|
||||
#include <sys/mman.h>
|
||||
#include <string>
|
||||
#include "napi/native_api.h"
|
||||
|
||||
class SampleXComponent {
|
||||
public:
|
||||
SampleXComponent() = default;
|
||||
~SampleXComponent();
|
||||
explicit SampleXComponent(std::string id) : id_(id) {}
|
||||
static napi_value NapiRegister(napi_env env, napi_callback_info info);
|
||||
static napi_value NapiUnregister(napi_env env, napi_callback_info info);
|
||||
static napi_value NapiDestroy(napi_env env, napi_callback_info info);
|
||||
static void Release(std::string &id);
|
||||
void DrawPath();
|
||||
void SetWidth(uint64_t width);
|
||||
void SetHeight(uint64_t height);
|
||||
void SetNativeWindow(OHNativeWindow *nativeWindow);
|
||||
OHNativeWindow* GetNativeWindow();
|
||||
|
||||
void Prepare();
|
||||
void Create();
|
||||
void DisPlay();
|
||||
void ConstructPath(int x, int y, int offsetY);
|
||||
void SetPenAndBrush();
|
||||
void Export(napi_env env, napi_value exports);
|
||||
void RegisterCallback(OH_NativeXComponent *nativeXComponent);
|
||||
void Destroy();
|
||||
static SampleXComponent *GetInstance(std::string &id);
|
||||
std::string id_;
|
||||
int defaultOffsetY = 100;
|
||||
private:
|
||||
OH_NativeXComponent_Callback renderCallback_;
|
||||
|
||||
uint64_t width_ = 0;
|
||||
uint64_t height_ = 0;
|
||||
|
||||
float aX = 0.0;
|
||||
float aY = 0.0;
|
||||
float bX = 80.0;
|
||||
float cY = 0.0;
|
||||
bool desc = false;
|
||||
|
||||
OH_Drawing_Bitmap *cBitmap_ = nullptr;
|
||||
OH_Drawing_Canvas *cCanvas_ = nullptr;
|
||||
|
||||
OH_Drawing_Path *cPath_ = nullptr;
|
||||
OH_Drawing_Brush *cBrush_ = nullptr;
|
||||
OH_Drawing_Pen *cPen_ = nullptr;
|
||||
OHNativeWindow *nativeWindow_ = nullptr;
|
||||
uint32_t *mappedAddr_ = nullptr;
|
||||
BufferHandle *bufferHandle_ = nullptr;
|
||||
struct NativeWindowBuffer *buffer_ = nullptr;
|
||||
int fenceFd_ = 0;
|
||||
};
|
||||
|
||||
#endif
|
16
code/BasicFeature/Graphics/DisplaySoloist/entry/src/main/cpp/types/libentry/index.d.ts
vendored
Normal file
16
code/BasicFeature/Graphics/DisplaySoloist/entry/src/main/cpp/types/libentry/index.d.ts
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export const add: (a: number, b: number) => number;
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "libentry.so",
|
||||
"types": "./index.d.ts",
|
||||
"version": "",
|
||||
"description": "Please describe the basic information."
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
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');
|
||||
}
|
||||
};
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import UIAbility from '@ohos.app.ability.UIAbility';
|
||||
import hilog from '@ohos.hilog';
|
||||
import window from '@ohos.window';
|
||||
import { BusinessError } from '@ohos.base';
|
||||
|
||||
export default class EntryAbility extends UIAbility {
|
||||
onCreate(want, launchParam) {
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
|
||||
}
|
||||
|
||||
onDestroy() {
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
|
||||
}
|
||||
|
||||
onWindowStageCreate(windowStage: window.WindowStage) {
|
||||
// Main window is created, set main page for this ability
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
|
||||
|
||||
windowStage.loadContent('pages/XComponentDisplaySync', (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() {
|
||||
// Main window is destroyed, release UI related resources
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
|
||||
}
|
||||
|
||||
onForeground() {
|
||||
// Ability has brought to foreground
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
|
||||
}
|
||||
|
||||
onBackground() {
|
||||
// Ability has back to background
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
|
||||
}
|
||||
};
|
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export default interface XComponentContext {
|
||||
register(): void;
|
||||
|
||||
unregister(): void;
|
||||
|
||||
destroy():void;
|
||||
};
|
@ -0,0 +1,147 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import XComponentContext from '../interface/XComponentContext';
|
||||
import Logger from '../utils/Logger';
|
||||
|
||||
const TAG = '[XComponentDisplaySoloist]';
|
||||
const START = 'Start';
|
||||
const STOP = 'Stop';
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct Index {
|
||||
@State status1: string = START;
|
||||
@State isOn1: boolean = false;
|
||||
@State status2: string = START;
|
||||
@State isOn2: boolean = false;
|
||||
@State status3: string = START;
|
||||
@State isOn3: boolean = false;
|
||||
private xComponentContext1: XComponentContext | undefined = undefined;
|
||||
private xComponentContext2: XComponentContext | undefined = undefined;
|
||||
private xComponentContext3: XComponentContext | undefined = undefined;
|
||||
|
||||
aboutToDisappear(): void {
|
||||
// 离开当前页面时解除注册的回调,销毁申请的DisplaySoloist
|
||||
Logger.info(TAG, 'aboutToDisappear');
|
||||
if (this.xComponentContext1) {
|
||||
this.xComponentContext1.unregister();
|
||||
this.xComponentContext1.destroy();
|
||||
}
|
||||
if (this.xComponentContext2) {
|
||||
this.xComponentContext2.unregister();
|
||||
this.xComponentContext2.destroy();
|
||||
}
|
||||
if (this.xComponentContext3) {
|
||||
this.xComponentContext3.unregister();
|
||||
this.xComponentContext3.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
Execute(component: XComponentContext, flg: boolean): string {
|
||||
if (flg) {
|
||||
// 注册回调函数并开启每帧回调
|
||||
component.register();
|
||||
return STOP;
|
||||
} else {
|
||||
// 解注册回调函数并停止启每帧回调
|
||||
component.unregister();
|
||||
return START;
|
||||
}
|
||||
}
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
Row() {
|
||||
Text('30hz')
|
||||
.fontWeight(FontWeight.Bold)
|
||||
.fontSize(12)
|
||||
.fontColor(Color.Red)
|
||||
.textAlign(TextAlign.End)
|
||||
.width(40)
|
||||
.height(30)
|
||||
|
||||
Button(this.status1)
|
||||
.id('Start30')
|
||||
.controlSize(ControlSize.SMALL)
|
||||
.onClick((): void => {
|
||||
if (this.xComponentContext1) {
|
||||
// 每次点击切换按钮上的显示Start/Stop
|
||||
this.isOn1 = !(this.isOn1);
|
||||
this.status1 = this.Execute(this.xComponentContext1, this.isOn1);
|
||||
}
|
||||
}).margin(4)
|
||||
|
||||
XComponent({ id: 'xcomponentId30', type: 'surface', libraryname: 'entry' })
|
||||
.onLoad((xComponentContext) => {
|
||||
this.xComponentContext1 = xComponentContext as XComponentContext;
|
||||
}).width('640px')
|
||||
}.height('30%')
|
||||
.backgroundColor(Color.White);
|
||||
|
||||
Row() {
|
||||
Text('60hz')
|
||||
.fontWeight(FontWeight.Bold)
|
||||
.fontSize(12)
|
||||
.fontColor(Color.Red)
|
||||
.textAlign(TextAlign.End)
|
||||
.width(40)
|
||||
.height(30)
|
||||
|
||||
Button(this.status2)
|
||||
.id('Start60')
|
||||
.controlSize(ControlSize.SMALL)
|
||||
.onClick((): void => {
|
||||
if (this.xComponentContext2) {
|
||||
this.isOn2 = !(this.isOn2);
|
||||
this.status2 = this.Execute(this.xComponentContext2, this.isOn2);
|
||||
}
|
||||
}).margin(4)
|
||||
|
||||
XComponent({ id: 'xcomponentId60', type: 'surface', libraryname: 'entry' })
|
||||
.onLoad((xComponentContext) => {
|
||||
this.xComponentContext2 = xComponentContext as XComponentContext;
|
||||
}).width('640px')
|
||||
}.height('30%')
|
||||
.backgroundColor(Color.White);
|
||||
|
||||
Row() {
|
||||
Text('120hz')
|
||||
.fontWeight(FontWeight.Bold)
|
||||
.fontSize(12)
|
||||
.fontColor(Color.Red)
|
||||
.textAlign(TextAlign.End)
|
||||
.width(40)
|
||||
.height(30)
|
||||
|
||||
Button(this.status3)
|
||||
.id('Start120')
|
||||
.controlSize(ControlSize.SMALL)
|
||||
.onClick((): void => {
|
||||
if (this.xComponentContext3) {
|
||||
this.isOn3 = !(this.isOn3);
|
||||
this.status3 = this.Execute(this.xComponentContext3, this.isOn3);
|
||||
}
|
||||
}).margin(4)
|
||||
|
||||
XComponent({ id: 'xcomponentId120', type: 'surface', libraryname: 'entry' })
|
||||
.onLoad((xComponentContext) => {
|
||||
this.xComponentContext3 = xComponentContext as XComponentContext;
|
||||
}).width('640px')
|
||||
}.height('30%')
|
||||
.backgroundColor(Color.White);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
import hilog from '@ohos.hilog';
|
||||
|
||||
class Logger {
|
||||
private domain: number;
|
||||
private prefix: string;
|
||||
private format: string = '%{public}s, %{public}s';
|
||||
|
||||
constructor(prefix: string) {
|
||||
this.prefix = prefix;
|
||||
this.domain = 0xFF00;
|
||||
}
|
||||
|
||||
debug(...args: string[]) {
|
||||
hilog.debug(this.domain, this.prefix, this.format, args);
|
||||
}
|
||||
|
||||
info(...args: string[]) {
|
||||
hilog.info(this.domain, this.prefix, this.format, args);
|
||||
}
|
||||
|
||||
warn(...args: string[]) {
|
||||
hilog.warn(this.domain, this.prefix, this.format, args);
|
||||
}
|
||||
|
||||
error(...args: string[]) {
|
||||
hilog.error(this.domain, this.prefix, this.format, args);
|
||||
}
|
||||
}
|
||||
|
||||
export default new Logger('[Sample_DisplaySync]');
|
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
{
|
||||
"module": {
|
||||
"name": "entry",
|
||||
"type": "entry",
|
||||
"description": "$string:module_desc",
|
||||
"mainElement": "EntryAbility",
|
||||
"deviceTypes": [
|
||||
"default",
|
||||
"tablet"
|
||||
],
|
||||
"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"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
{
|
||||
"color": [
|
||||
{
|
||||
"name": "start_window_background",
|
||||
"value": "#FFFFFF"
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
{
|
||||
"string": [
|
||||
{
|
||||
"name": "module_desc",
|
||||
"value": "module description"
|
||||
},
|
||||
{
|
||||
"name": "EntryAbility_desc",
|
||||
"value": "description"
|
||||
},
|
||||
{
|
||||
"name": "EntryAbility_label",
|
||||
"value": "DisplaySoloist"
|
||||
}
|
||||
]
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
@ -0,0 +1,5 @@
|
||||
{
|
||||
"src": [
|
||||
"pages/Index"
|
||||
]
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
{
|
||||
"string": [
|
||||
{
|
||||
"name": "module_desc",
|
||||
"value": "module description"
|
||||
},
|
||||
{
|
||||
"name": "EntryAbility_desc",
|
||||
"value": "description"
|
||||
},
|
||||
{
|
||||
"name": "EntryAbility_label",
|
||||
"value": "DisplaySoloist"
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
{
|
||||
"string": [
|
||||
{
|
||||
"name": "module_desc",
|
||||
"value": "模块描述"
|
||||
},
|
||||
{
|
||||
"name": "EntryAbility_desc",
|
||||
"value": "description"
|
||||
},
|
||||
{
|
||||
"name": "EntryAbility_label",
|
||||
"value": "DisplaySoloist"
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import { describe, it, beforeAll, expect } from '@ohos/hypium';
|
||||
import { Driver, ON } from '@ohos.UiTest';
|
||||
import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry';
|
||||
import Logger from '../utils/Logger';
|
||||
|
||||
const TAG = '[Sample_DisplaySoloist]';
|
||||
const DELAYMS1S = 1000;
|
||||
|
||||
export default function abilityTest() {
|
||||
describe('ActsAbilityTest', () => {
|
||||
beforeAll(async (done: Function) => {
|
||||
Logger.info(TAG, 'beforeAll begin');
|
||||
let abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
|
||||
try {
|
||||
await abilityDelegator.startAbility({
|
||||
bundleName: 'com.samples.DisplaySoloist',
|
||||
abilityName: 'EntryAbility'
|
||||
});
|
||||
} catch (err) {
|
||||
Logger.info(TAG, `beforeAll exception = ${JSON.stringify(err)}`);
|
||||
}
|
||||
|
||||
Logger.info(TAG, 'beforeAll end');
|
||||
done();
|
||||
});
|
||||
|
||||
/**
|
||||
* @tc.number:SUB_GRAPHIC_2D_HGM_DISPLAYSOLOIST_0100
|
||||
* @tc.name:DisplaySoloist_001
|
||||
* @tc.desc:DisplaySoloist
|
||||
* @tc.size:MediumTest
|
||||
* @tc.type:Function
|
||||
* @tc.level:Level 1
|
||||
*/
|
||||
it('DisplaySoloist_001', 0, async (done: Function) => {
|
||||
try {
|
||||
Logger.info(TAG, 'DisplaySoloist_001 begin');
|
||||
|
||||
let driver = Driver.create();
|
||||
await driver.assertComponentExist(ON.id('Start30'));
|
||||
let Start30Button = await driver.findComponent(ON.id('Start30'));
|
||||
await Start30Button.click();
|
||||
|
||||
await driver.assertComponentExist(ON.id('Start60'));
|
||||
let start60Button = await driver.findComponent(ON.id('Start60'));
|
||||
await start60Button.click();
|
||||
|
||||
await driver.assertComponentExist(ON.id('Start120'));
|
||||
let Start120Button = await driver.findComponent(ON.id('Start120'));
|
||||
await Start120Button.click();
|
||||
|
||||
await driver.assertComponentExist(ON.id('Start30'));
|
||||
let Stop30Button = await driver.findComponent(ON.id('Start30'));
|
||||
await Stop30Button.click();
|
||||
|
||||
await driver.assertComponentExist(ON.id('Start60'));
|
||||
let Stop60Button = await driver.findComponent(ON.id('Start60'));
|
||||
await Stop60Button.click();
|
||||
|
||||
await driver.assertComponentExist(ON.id('Start120'));
|
||||
let Stop120Button = await driver.findComponent(ON.id('Start120'));
|
||||
await Stop120Button.click();
|
||||
await driver.delayMs(DELAYMS1S);
|
||||
|
||||
Logger.info(TAG, 'DisplaySoloist_001 end');
|
||||
done();
|
||||
} catch (error) {
|
||||
Logger.info(TAG, `DisplaySoloist_001 exception = ${JSON.stringify(error)}`);
|
||||
expect().assertFail();
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import abilityTest from './Ability.test';
|
||||
|
||||
export default function testsuite() {
|
||||
abilityTest();
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
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');
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct Index {
|
||||
@State message: string = 'Hello World';
|
||||
|
||||
build() {
|
||||
Row() {
|
||||
Column() {
|
||||
Text(this.message)
|
||||
.fontSize(50)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
}
|
||||
.width('100%')
|
||||
}
|
||||
.height('100%')
|
||||
}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
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');
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import hilog from '@ohos.hilog';
|
||||
|
||||
class Logger {
|
||||
private domain: number = 0xF811;
|
||||
private prefix: string = '';
|
||||
private format: string = '%{public}s, %{public}s';
|
||||
|
||||
constructor(prefix: string) {
|
||||
this.prefix = prefix;
|
||||
this.domain = 0xF811;
|
||||
}
|
||||
|
||||
debug(...args: string[]): void {
|
||||
hilog.debug(this.domain, this.prefix, this.format, args);
|
||||
}
|
||||
|
||||
info(...args: string[]): void {
|
||||
hilog.info(this.domain, this.prefix, this.format, args);
|
||||
}
|
||||
|
||||
warn(...args: string[]): void {
|
||||
hilog.warn(this.domain, this.prefix, this.format, args);
|
||||
}
|
||||
|
||||
error(...args: string[]): void {
|
||||
hilog.error(this.domain, this.prefix, this.format, args);
|
||||
}
|
||||
}
|
||||
|
||||
export default new Logger('[Sample_DisplaySync]');
|
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
{
|
||||
"module": {
|
||||
"name": "entry_test",
|
||||
"type": "feature",
|
||||
"description": "$string:module_test_desc",
|
||||
"mainElement": "TestAbility",
|
||||
"deviceTypes": [
|
||||
"default",
|
||||
"tablet"
|
||||
],
|
||||
"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"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
{
|
||||
"color": [
|
||||
{
|
||||
"name": "start_window_background",
|
||||
"value": "#FFFFFF"
|
||||
}
|
||||
]
|
||||
}
|
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 6.6 KiB |
@ -0,0 +1,5 @@
|
||||
{
|
||||
"src": [
|
||||
"testability/pages/Index"
|
||||
]
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"hvigorVersion": "4.0.2",
|
||||
"dependencies": {
|
||||
"@ohos/hvigor-ohos-plugin": "4.0.2"
|
||||
}
|
||||
}
|
File diff suppressed because one or more lines are too long
15
code/BasicFeature/Graphics/DisplaySoloist/hvigorfile.ts
Normal file
15
code/BasicFeature/Graphics/DisplaySoloist/hvigorfile.ts
Normal file
@ -0,0 +1,15 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
export { appTasks } from '@ohos/hvigor-ohos-plugin';
|
48
code/BasicFeature/Graphics/DisplaySoloist/hvigorw
Normal file
48
code/BasicFeature/Graphics/DisplaySoloist/hvigorw
Normal file
@ -0,0 +1,48 @@
|
||||
#!/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
|
||||
warn() {
|
||||
echo ""
|
||||
echo -e "\033[1;33m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m"
|
||||
}
|
||||
|
||||
error() {
|
||||
echo ""
|
||||
echo -e "\033[1;31m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m"
|
||||
}
|
||||
|
||||
fail() {
|
||||
error "$@"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Determine node to start hvigor wrapper script
|
||||
if [ -n "${NODE_HOME}" ];then
|
||||
EXECUTABLE_NODE="${NODE_HOME}/bin/node"
|
||||
if [ ! -x "$EXECUTABLE_NODE" ];then
|
||||
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"
|
||||
fi
|
||||
else
|
||||
EXECUTABLE_NODE="node"
|
||||
which ${EXECUTABLE_NODE} > /dev/null 2>&1 || fail "ERROR: NODE_HOME is not set and not 'node' command found in your path"
|
||||
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
|
||||
|
||||
# start hvigor-wrapper script
|
||||
exec "${EXECUTABLE_NODE}" \
|
||||
"${HVIGOR_WRAPPER_SCRIPT}" "$@"
|
64
code/BasicFeature/Graphics/DisplaySoloist/hvigorw.bat
Normal file
64
code/BasicFeature/Graphics/DisplaySoloist/hvigorw.bat
Normal file
@ -0,0 +1,64 @@
|
||||
@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
|
||||
|
||||
goto start
|
||||
|
||||
:start
|
||||
@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%" "%WRAPPER_MODULE_PATH%" %*
|
||||
|
||||
if "%ERRORLEVEL%" == "0" goto hvigorwEnd
|
||||
|
||||
:fail
|
||||
exit /b 1
|
||||
|
||||
:hvigorwEnd
|
||||
if "%OS%" == "Windows_NT" endlocal
|
||||
|
||||
:end
|
12
code/BasicFeature/Graphics/DisplaySoloist/oh-package.json5
Normal file
12
code/BasicFeature/Graphics/DisplaySoloist/oh-package.json5
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"license": "",
|
||||
"devDependencies": {
|
||||
"@ohos/hypium": "1.0.6"
|
||||
},
|
||||
"author": "",
|
||||
"name": "drawing",
|
||||
"description": "Please describe the basic information.",
|
||||
"main": "",
|
||||
"version": "1.0.0",
|
||||
"dependencies": {}
|
||||
}
|
13
code/BasicFeature/Graphics/DisplaySoloist/ohosTest.md
Normal file
13
code/BasicFeature/Graphics/DisplaySoloist/ohosTest.md
Normal file
@ -0,0 +1,13 @@
|
||||
# DisplaySoloist测试用例归档
|
||||
|
||||
## 用例表
|
||||
|
||||
| 测试功能 | 预置条件 | 输入 | 预期输出 | 是否自动 | 测试结果 |
|
||||
|---------|--------------|----------------|-----------------------|------|------|
|
||||
| 拉起应用 | 设备正常运行 | | 成功拉起应用 | 是 | Pass |
|
||||
| 按钮点击 | 位于主页 | 点击30hz右侧Start | 方块按照30hz频率移动,同时按钮显示为Stop | 是 | Pass |
|
||||
| 按钮点击 | 位于主页 | 点击30hz右侧Stop | 方块停止移动,同时按钮显示为Start | 是 | Pass |
|
||||
| 按钮点击 | 位于主页 | 点击60hz右侧Start | 方块按照60hz频率移动,同时按钮显示为Stop | 是 | Pass | 是 | Pass |
|
||||
| 按钮点击 | 位于主页 | 点击60hz右侧Stop | 方块停止移动,同时按钮显示为Start | 是 | Pass | 是 | Pass |
|
||||
| 按钮点击 | 位于主页 | 点击120hz右侧Start | 方块按照120hz频率移动,同时按钮显示为Stop | 是 | Pass | 是 | Pass |
|
||||
| 按钮点击 | 位于主页 | 点击120hz右侧Stop | 方块停止移动,同时按钮显示为Start | 是 | Pass | 是 | Pass |
|
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
Loading…
Reference in New Issue
Block a user