mirror of
https://gitee.com/openharmony/graphic_graphic_2d
synced 2025-03-03 18:21:45 +00:00
split mode
Change-Id: Ibb867534ba877ada08c03698fd5a31d1f2e66c8c Signed-off-by: lizheng <lizheng2@huawei.com>
This commit is contained in:
parent
3e2a628d2b
commit
2d7cebeacd
5
BUILD.gn
5
BUILD.gn
@ -19,6 +19,7 @@ group("default") {
|
||||
public_deps = [
|
||||
":default.scss",
|
||||
":graphic.rc",
|
||||
"frameworks/animation_server:animation_server",
|
||||
"frameworks/bootanimation:bootanimation",
|
||||
"frameworks/bootanimation:bootanimation-480x960.raw",
|
||||
"frameworks/dumper:gdumper",
|
||||
@ -30,10 +31,6 @@ group("default") {
|
||||
"frameworks/wmservice:wmservice_test",
|
||||
"frameworks/wmtest:wmtest",
|
||||
]
|
||||
|
||||
if (ace_enable_gpu) {
|
||||
public_deps += [ "frameworks/animation_server:animation_server" ]
|
||||
}
|
||||
}
|
||||
|
||||
## Install graphic.rc to /system/etc/init/graphic.rc {{{
|
||||
|
12
default.scss
12
default.scss
@ -50,6 +50,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
#WINDOW_TYPE_SPLIT_LINE {
|
||||
z-index: 0;
|
||||
position: relative;
|
||||
horizon-align: middle;
|
||||
vertical-align: middle;
|
||||
width: 100.0%;
|
||||
height: 100.0%;
|
||||
}
|
||||
|
||||
#WINDOW_TYPE_STATUS_BAR {
|
||||
z-index: 10;
|
||||
position: static;
|
||||
@ -79,6 +88,9 @@
|
||||
|
||||
#WINDOW_TYPE_SYSTEM_UI {
|
||||
z-index: 31;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#WINDOW_TYPE_LAUNCHER {
|
||||
|
@ -12,6 +12,7 @@
|
||||
# limitations under the License.
|
||||
|
||||
import("//build/ohos.gni")
|
||||
import("//foundation/graphic/standard/graphic_config.gni")
|
||||
|
||||
## Build libanimation_service.so {{{
|
||||
config("libanimation_service_config") {
|
||||
@ -47,12 +48,14 @@ ohos_shared_library("libanimation_service") {
|
||||
public_configs = [ ":libanimation_service_public_config" ]
|
||||
|
||||
deps = [
|
||||
"//foundation/communication/ipc/interfaces/innerkits/ipc_core:ipc_core",
|
||||
"//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy",
|
||||
"//foundation/graphic/standard/utils:libgslogger",
|
||||
]
|
||||
|
||||
public_deps = [ "//utils/native/base:utils" ]
|
||||
public_deps = [
|
||||
"//foundation/communication/ipc/interfaces/innerkits/ipc_core:ipc_core",
|
||||
"//utils/native/base:utils",
|
||||
]
|
||||
|
||||
part_name = "graphic_standard"
|
||||
subsystem_name = "graphic"
|
||||
@ -84,11 +87,16 @@ ohos_executable("animation_server") {
|
||||
"server/src/animation_server.cpp",
|
||||
"server/src/animation_service_stub.cpp",
|
||||
"server/src/main.cpp",
|
||||
"server/src/rotation_animation.cpp",
|
||||
"server/src/shader.cpp",
|
||||
"server/src/texture.cpp",
|
||||
]
|
||||
|
||||
if (ace_enable_gpu) {
|
||||
sources += [
|
||||
"server/src/rotation_animation.cpp",
|
||||
"server/src/shader.cpp",
|
||||
"server/src/texture.cpp",
|
||||
]
|
||||
}
|
||||
|
||||
configs = [ ":animation_server_config" ]
|
||||
|
||||
deps = [
|
||||
@ -97,9 +105,11 @@ ohos_executable("animation_server") {
|
||||
"//foundation/graphic/standard:libvsync_client",
|
||||
"//foundation/graphic/standard:libwmclient",
|
||||
"//foundation/graphic/standard:libwmservice",
|
||||
"//foundation/graphic/standard/utils:cpudraw",
|
||||
"//foundation/graphic/standard/utils:graphic_bytrace",
|
||||
"//foundation/graphic/standard/utils:libgslogger",
|
||||
"//foundation/graphic/standard/utils:matrix",
|
||||
"//foundation/multimodalinput/input/frameworks/proxy:libmmi-client",
|
||||
]
|
||||
|
||||
part_name = "graphic_standard"
|
||||
|
@ -26,6 +26,8 @@ public:
|
||||
AnimationServiceProxy(const sptr<IRemoteObject>& impl);
|
||||
|
||||
GSError StartRotationAnimation(int32_t did, int32_t degree) override;
|
||||
GSError SplitModeCreateBackground() override;
|
||||
GSError SplitModeCreateMiddleLine() override;
|
||||
|
||||
private:
|
||||
static inline BrokerDelegator<AnimationServiceProxy> delegator_;
|
||||
|
@ -55,4 +55,56 @@ GSError AnimationServiceProxy::StartRotationAnimation(int32_t did, int32_t degre
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
GSError AnimationServiceProxy::SplitModeCreateBackground()
|
||||
{
|
||||
MessageParcel data;
|
||||
MessageParcel reply;
|
||||
MessageOption option;
|
||||
|
||||
auto retval = data.WriteInterfaceToken(GetDescriptor());
|
||||
if (!retval) {
|
||||
GSLOG2HI(ERROR) << "WriteInterfaceToken failed";
|
||||
return GSERROR_INVALID_ARGUMENTS;
|
||||
}
|
||||
|
||||
int32_t res = Remote()->SendRequest(SPLIT_MODE_CREATE_BACKGOUND, data, reply, option);
|
||||
if (res) {
|
||||
GSLOG2HI(ERROR) << "SendRequest failed, retval=" << res;
|
||||
return GSERROR_BINDER;
|
||||
}
|
||||
|
||||
GSError ret = static_cast<enum GSError>(reply.ReadInt32());
|
||||
if (ret != GSERROR_OK) {
|
||||
GSLOG2HI(ERROR) << "Call return failed: " << ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
GSError AnimationServiceProxy::SplitModeCreateMiddleLine()
|
||||
{
|
||||
MessageParcel data;
|
||||
MessageParcel reply;
|
||||
MessageOption option;
|
||||
|
||||
auto retval = data.WriteInterfaceToken(GetDescriptor());
|
||||
if (!retval) {
|
||||
GSLOG2HI(ERROR) << "WriteInterfaceToken failed";
|
||||
return GSERROR_INVALID_ARGUMENTS;
|
||||
}
|
||||
|
||||
int32_t res = Remote()->SendRequest(SPLIT_MODE_CREATE_MIDDLE_LINE, data, reply, option);
|
||||
if (res) {
|
||||
GSLOG2HI(ERROR) << "SendRequest failed, retval=" << res;
|
||||
return GSERROR_BINDER;
|
||||
}
|
||||
|
||||
GSError ret = static_cast<enum GSError>(reply.ReadInt32());
|
||||
if (ret != GSERROR_OK) {
|
||||
GSLOG2HI(ERROR) << "Call return failed: " << ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
} // namespace OHOS
|
||||
|
@ -24,9 +24,9 @@ namespace {
|
||||
DEFINE_HILOG_LABEL("IAnimationService");
|
||||
} // namespace
|
||||
|
||||
GSError IAnimationService::Init()
|
||||
GSError IAnimationService::Init(bool reinit)
|
||||
{
|
||||
if (animationService != nullptr) {
|
||||
if (animationService != nullptr && reinit == false) {
|
||||
return GSERROR_OK;
|
||||
}
|
||||
|
||||
|
@ -22,16 +22,20 @@
|
||||
namespace OHOS {
|
||||
class IAnimationService : public IRemoteBroker {
|
||||
public:
|
||||
static GSError Init();
|
||||
static GSError Init(bool reinit = false);
|
||||
static sptr<IAnimationService> Get();
|
||||
|
||||
virtual GSError StartRotationAnimation(int32_t did, int32_t degree) = 0;
|
||||
virtual GSError SplitModeCreateBackground() = 0;
|
||||
virtual GSError SplitModeCreateMiddleLine() = 0;
|
||||
|
||||
DECLARE_INTERFACE_DESCRIPTOR(u"IAnimationService");
|
||||
|
||||
protected:
|
||||
enum {
|
||||
START_ROTATION_ANIMATION = 0,
|
||||
SPLIT_MODE_CREATE_BACKGOUND = 1,
|
||||
SPLIT_MODE_CREATE_MIDDLE_LINE = 2,
|
||||
};
|
||||
|
||||
private:
|
||||
|
@ -20,14 +20,19 @@
|
||||
#include <functional>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <egl_surface.h>
|
||||
#include <promise.h>
|
||||
#include <touch_event_handler.h>
|
||||
#include <vsync_helper.h>
|
||||
#include <window_manager.h>
|
||||
#include <window_manager_service_client.h>
|
||||
|
||||
#include "animation_service_stub.h"
|
||||
#include "rotation_animation.h"
|
||||
|
||||
#ifdef ACE_ENABLE_GPU
|
||||
#include <egl_surface.h>
|
||||
#endif
|
||||
|
||||
namespace OHOS {
|
||||
using PromiseGSError = Promise<GSError>;
|
||||
|
||||
@ -47,22 +52,55 @@ public:
|
||||
GSError Init();
|
||||
|
||||
GSError StartRotationAnimation(int32_t did, int32_t degree) override;
|
||||
GSError SplitModeCreateBackground() override;
|
||||
GSError SplitModeCreateMiddleLine() override;
|
||||
|
||||
void OnScreenShot(const struct WMImageInfo &info) override;
|
||||
void OnSplitStatusChange(SplitStatus status);
|
||||
bool OnTouch(const TouchEvent &event);
|
||||
|
||||
private:
|
||||
void StartAnimation(struct Animation &animation);
|
||||
void AnimationSync(int64_t time, void *data);
|
||||
void RotationDraw();
|
||||
VsyncError RequestNextVsync();
|
||||
|
||||
void SplitWindowUpdate();
|
||||
void SplitWindowDraw(void *vaddr, uint32_t width, uint32_t height, uint32_t count);
|
||||
|
||||
std::shared_ptr<AppExecFwk::EventHandler> handler = nullptr;
|
||||
sptr<VsyncHelper> vhelper = nullptr;
|
||||
sptr<Window> window = nullptr;
|
||||
#ifdef ACE_ENABLE_GPU
|
||||
sptr<EglRenderSurface> eglSurface = nullptr;
|
||||
|
||||
std::atomic<bool> isAnimationRunning = false;
|
||||
sptr<PromiseAnimationScreenshotInfo> screenshotPromise = nullptr;
|
||||
std::unique_ptr<RotationAnimation> ranimation = nullptr;
|
||||
#endif
|
||||
|
||||
sptr<Window> splitWindow = nullptr;
|
||||
bool haveMiddleLine = false;
|
||||
bool midlineDown = false;
|
||||
int32_t midlineYBackup = -100;
|
||||
int32_t midlineY = -100;
|
||||
int32_t downX = 0;
|
||||
int32_t downY = 0;
|
||||
|
||||
class TouchEventHandler : public MMI::TouchEventHandler {
|
||||
public:
|
||||
explicit TouchEventHandler(AnimationServer *server) : server_(server)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool OnTouch(const TouchEvent &event) override
|
||||
{
|
||||
return server_->OnTouch(event);
|
||||
}
|
||||
|
||||
private:
|
||||
AnimationServer *server_ = nullptr;
|
||||
};
|
||||
sptr<TouchEventHandler> thandler = nullptr;
|
||||
sptr<IRemoteObject> token = new IPCObjectStub(u"animation_server");
|
||||
};
|
||||
} // namespace OHOS
|
||||
|
||||
|
@ -31,6 +31,8 @@ public:
|
||||
|
||||
private:
|
||||
int32_t StartRotationAnimationRemote(MessageParcel& data, MessageParcel& reply, MessageOption& options);
|
||||
int32_t SplitModeCreateBackgroundRemote(MessageParcel& data, MessageParcel& reply, MessageOption& options);
|
||||
int32_t SplitModeCreateMiddleLineRemote(MessageParcel& data, MessageParcel& reply, MessageOption& options);
|
||||
|
||||
using AnimationServiceStubFunc = int32_t (AnimationServiceStub::*)(MessageParcel &arguments,
|
||||
MessageParcel &reply, MessageOption &option);
|
||||
|
@ -18,9 +18,11 @@
|
||||
#include <cassert>
|
||||
#include <chrono>
|
||||
#include <fstream>
|
||||
#include <sys/time.h>
|
||||
#include <multimodal_event_handler.h>
|
||||
#include <securec.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <cpudraw.h>
|
||||
#include <graphic_bytrace.h>
|
||||
#include <gslogger.h>
|
||||
|
||||
@ -29,19 +31,6 @@ namespace {
|
||||
DEFINE_HILOG_LABEL("AnimationServer");
|
||||
} // namespace
|
||||
|
||||
GSError AnimationServer::StartRotationAnimation(int32_t did, int32_t degree)
|
||||
{
|
||||
if (isAnimationRunning == false) {
|
||||
struct Animation animation {
|
||||
.degree = degree,
|
||||
.retval = new Promise<GSError>(),
|
||||
};
|
||||
handler->PostTask(std::bind(&AnimationServer::StartAnimation, this, std::ref(animation)));
|
||||
return animation.retval->Await();
|
||||
}
|
||||
return GSERROR_ANIMATION_RUNNING;
|
||||
}
|
||||
|
||||
GSError AnimationServer::Init()
|
||||
{
|
||||
handler = AppExecFwk::EventHandler::Current();
|
||||
@ -53,6 +42,19 @@ GSError AnimationServer::Init()
|
||||
return static_cast<enum GSError>(wret);
|
||||
}
|
||||
|
||||
WindowManagerServiceClient::GetInstance()->Init();
|
||||
|
||||
auto splitOption = WindowOption::Get();
|
||||
splitOption->SetWindowType(WINDOW_TYPE_SPLIT_LINE);
|
||||
wret = wm->CreateWindow(splitWindow, splitOption);
|
||||
if (wret != WM_OK || splitWindow == nullptr) {
|
||||
GSLOG2HI(ERROR) << "WindowManager::CreateWindow failed: " << WMErrorStr(wret);
|
||||
return static_cast<enum GSError>(wret);
|
||||
}
|
||||
splitWindow->Hide();
|
||||
auto func = std::bind(&AnimationServer::OnSplitStatusChange, this, std::placeholders::_1);
|
||||
splitWindow->OnSplitStatusChange(func);
|
||||
|
||||
auto option = WindowOption::Get();
|
||||
option->SetWindowType(WINDOW_TYPE_ANIMATION);
|
||||
wret = wm->CreateWindow(window, option);
|
||||
@ -62,11 +64,55 @@ GSError AnimationServer::Init()
|
||||
}
|
||||
|
||||
window->Hide();
|
||||
#ifdef ACE_ENABLE_GPU
|
||||
auto producer = window->GetProducer();
|
||||
eglSurface = EglRenderSurface::CreateEglSurfaceAsProducer(producer);
|
||||
#endif
|
||||
return GSERROR_OK;
|
||||
}
|
||||
|
||||
GSError AnimationServer::StartRotationAnimation(int32_t did, int32_t degree)
|
||||
{
|
||||
#ifdef ACE_ENABLE_GPU
|
||||
if (isAnimationRunning == false) {
|
||||
struct Animation animation {
|
||||
.degree = degree,
|
||||
.retval = new Promise<GSError>(),
|
||||
};
|
||||
handler->PostTask(std::bind(&AnimationServer::StartAnimation, this, std::ref(animation)));
|
||||
return animation.retval->Await();
|
||||
}
|
||||
return GSERROR_ANIMATION_RUNNING;
|
||||
#else
|
||||
return GSERROR_NOT_SUPPORT;
|
||||
#endif
|
||||
}
|
||||
|
||||
GSError AnimationServer::SplitModeCreateBackground()
|
||||
{
|
||||
ScopedBytrace trace(__func__);
|
||||
GSLOG2HI(DEBUG);
|
||||
splitWindow->Show();
|
||||
splitWindow->SwitchTop();
|
||||
if (thandler == nullptr) {
|
||||
thandler = new TouchEventHandler(this);
|
||||
MMIEventHdl.RegisterStandardizedEventHandle(this, splitWindow->GetID(), thandler);
|
||||
}
|
||||
handler->PostTask(std::bind(&AnimationServer::SplitWindowUpdate, this));
|
||||
return GSERROR_OK;
|
||||
}
|
||||
|
||||
GSError AnimationServer::SplitModeCreateMiddleLine()
|
||||
{
|
||||
ScopedBytrace trace(__func__);
|
||||
GSLOG2HI(DEBUG);
|
||||
midlineY = splitWindow->GetHeight() / 2 + splitWindow->GetY();
|
||||
haveMiddleLine = true;
|
||||
handler->PostTask(std::bind(&AnimationServer::SplitWindowUpdate, this));
|
||||
return GSERROR_OK;
|
||||
}
|
||||
|
||||
#ifdef ACE_ENABLE_GPU
|
||||
void AnimationServer::StartAnimation(struct Animation &animation)
|
||||
{
|
||||
if (isAnimationRunning) {
|
||||
@ -74,7 +120,7 @@ void AnimationServer::StartAnimation(struct Animation &animation)
|
||||
return;
|
||||
}
|
||||
|
||||
ScopedBytrace(__func__);
|
||||
ScopedBytrace trace(__func__);
|
||||
isAnimationRunning = true;
|
||||
GSLOG2HI(INFO) << "Animation Start";
|
||||
window->Hide();
|
||||
@ -121,15 +167,17 @@ void AnimationServer::StartAnimation(struct Animation &animation)
|
||||
return;
|
||||
}
|
||||
|
||||
animation.retval->Resolve(static_cast<enum GSError>(RequestNextVsync()));
|
||||
struct FrameCallback cb = { .callback_ = std::bind(&AnimationServer::AnimationSync, this, SYNC_FUNC_ARG) };
|
||||
animation.retval->Resolve(static_cast<enum GSError>(vhelper->RequestFrameCallback(cb)));
|
||||
}
|
||||
|
||||
void AnimationServer::AnimationSync(int64_t time, void *data)
|
||||
{
|
||||
ScopedBytrace sb(__func__);
|
||||
ScopedBytrace trace(__func__);
|
||||
if (ranimation->Draw()) {
|
||||
eglSurface->SwapBuffers();
|
||||
RequestNextVsync();
|
||||
struct FrameCallback cb = { .callback_ = std::bind(&AnimationServer::AnimationSync, this, SYNC_FUNC_ARG) };
|
||||
vhelper->RequestFrameCallback(cb);
|
||||
sb.End();
|
||||
} else {
|
||||
sb.End();
|
||||
@ -139,14 +187,6 @@ void AnimationServer::AnimationSync(int64_t time, void *data)
|
||||
}
|
||||
}
|
||||
|
||||
VsyncError AnimationServer::RequestNextVsync()
|
||||
{
|
||||
struct FrameCallback cb = {
|
||||
.callback_ = std::bind(&AnimationServer::AnimationSync, this, SYNC_FUNC_ARG),
|
||||
};
|
||||
return vhelper->RequestFrameCallback(cb);
|
||||
}
|
||||
|
||||
void AnimationServer::OnScreenShot(const struct WMImageInfo &info)
|
||||
{
|
||||
int32_t length = info.size;
|
||||
@ -171,4 +211,115 @@ void AnimationServer::OnScreenShot(const struct WMImageInfo &info)
|
||||
|
||||
screenshotPromise->Resolve(ainfo);
|
||||
}
|
||||
#else
|
||||
void AnimationServer::StartAnimation(struct Animation &animation)
|
||||
{
|
||||
}
|
||||
|
||||
void AnimationServer::AnimationSync(int64_t time, void *data)
|
||||
{
|
||||
}
|
||||
|
||||
void AnimationServer::OnScreenShot(const struct WMImageInfo &info)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
void AnimationServer::SplitWindowUpdate()
|
||||
{
|
||||
ScopedBytrace trace(__func__);
|
||||
sptr<SurfaceBuffer> buffer;
|
||||
auto surface = splitWindow->GetSurface();
|
||||
BufferRequestConfig rconfig = {
|
||||
.width = surface->GetDefaultWidth(),
|
||||
.height = surface->GetDefaultHeight(),
|
||||
.strideAlignment = 0x8,
|
||||
.format = PIXEL_FMT_RGBA_8888,
|
||||
.usage = surface->GetDefaultUsage(),
|
||||
.timeout = 0,
|
||||
};
|
||||
|
||||
SurfaceError ret = surface->RequestBufferNoFence(buffer, rconfig);
|
||||
if (ret == SURFACE_ERROR_NO_BUFFER) {
|
||||
return;
|
||||
} else if (ret != SURFACE_ERROR_OK || buffer == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto addr = buffer->GetVirAddr();
|
||||
if (addr == nullptr) {
|
||||
surface->CancelBuffer(buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
static int32_t count = 0;
|
||||
SplitWindowDraw(buffer->GetVirAddr(), rconfig.width, rconfig.height, count);
|
||||
count++;
|
||||
|
||||
BufferFlushConfig fconfig = {
|
||||
.damage = {
|
||||
.w = rconfig.width,
|
||||
.h = rconfig.height,
|
||||
},
|
||||
};
|
||||
surface->FlushBuffer(buffer, -1, fconfig);
|
||||
}
|
||||
|
||||
void AnimationServer::SplitWindowDraw(void *vaddr, uint32_t width, uint32_t height, uint32_t count)
|
||||
{
|
||||
ScopedBytrace trace(__func__);
|
||||
GSLOG2HI(DEBUG) << "midlineY: " << midlineY << ", midlineDown: " << midlineDown;
|
||||
CPUDraw draw(vaddr, width, height);
|
||||
|
||||
draw.SetColor(0xff000000);
|
||||
draw.DrawRect(0, 0, width, height);
|
||||
if (haveMiddleLine == false) {
|
||||
draw.SetColor(0xff333333);
|
||||
draw.DrawRect(0.1 * width, 0.025 * height, 0.8 * width, 0.4 * height);
|
||||
draw.DrawRect(0.1 * width, 0.575 * height, 0.8 * width, 0.4 * height);
|
||||
} else {
|
||||
auto midlineYlocal = midlineY - splitWindow->GetY();
|
||||
draw.SetColor(midlineDown ? 0xffffffff : 0xffcccccc);
|
||||
draw.DrawRect(0, midlineYlocal - height * 0.05, width, height * 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationServer::OnSplitStatusChange(SplitStatus status)
|
||||
{
|
||||
ScopedBytrace trace(__func__);
|
||||
if (status == SPLIT_STATUS_DESTROY) {
|
||||
splitWindow->Hide();
|
||||
haveMiddleLine = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool AnimationServer::OnTouch(const TouchEvent &event)
|
||||
{
|
||||
ScopedBytrace trace(__func__);
|
||||
auto wms = WindowManagerServiceClient::GetInstance()->GetService();
|
||||
int32_t index = event.GetIndex();
|
||||
int32_t x = event.GetPointerPosition(index).GetX();
|
||||
int32_t y = event.GetPointerPosition(index).GetY();
|
||||
GSLOG2HI(DEBUG) << "touch event: " << event.GetAction() << " " << x << " " << y;
|
||||
if (event.GetAction() == TouchEnum::PRIMARY_POINT_DOWN) {
|
||||
wms->SetSplitMode(SPLIT_MODE_DIVIDER_TOUCH_DOWN);
|
||||
midlineDown = true;
|
||||
downX = x;
|
||||
downY = y;
|
||||
midlineYBackup = midlineY;
|
||||
handler->PostTask(std::bind(&AnimationServer::SplitWindowUpdate, this));
|
||||
} else if (event.GetAction() == TouchEnum::POINT_MOVE) {
|
||||
midlineY = midlineYBackup + y - downY;
|
||||
wms->SetSplitMode(SPLIT_MODE_DIVIDER_TOUCH_MOVE, x, midlineY);
|
||||
handler->PostTask(std::bind(&AnimationServer::SplitWindowUpdate, this));
|
||||
} else if (event.GetAction() == TouchEnum::PRIMARY_POINT_UP) {
|
||||
wms->SetSplitMode(SPLIT_MODE_DIVIDER_TOUCH_UP);
|
||||
midlineDown = false;
|
||||
handler->PostTask(std::bind(&AnimationServer::SplitWindowUpdate, this));
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
} // namespace OHOS
|
||||
|
@ -25,6 +25,8 @@ DEFINE_HILOG_LABEL("AnimationServiceStub");
|
||||
AnimationServiceStub::AnimationServiceStub()
|
||||
{
|
||||
memberFuncMap_[START_ROTATION_ANIMATION] = &AnimationServiceStub::StartRotationAnimationRemote;
|
||||
memberFuncMap_[SPLIT_MODE_CREATE_BACKGOUND] = &AnimationServiceStub::SplitModeCreateBackgroundRemote;
|
||||
memberFuncMap_[SPLIT_MODE_CREATE_MIDDLE_LINE] = &AnimationServiceStub::SplitModeCreateMiddleLineRemote;
|
||||
}
|
||||
|
||||
int32_t AnimationServiceStub::OnRemoteRequest(uint32_t code,
|
||||
@ -54,4 +56,18 @@ int32_t AnimationServiceStub::StartRotationAnimationRemote(MessageParcel& data,
|
||||
reply.WriteInt32(gret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t AnimationServiceStub::SplitModeCreateBackgroundRemote(MessageParcel& data,
|
||||
MessageParcel& reply, MessageOption& options)
|
||||
{
|
||||
reply.WriteInt32(SplitModeCreateBackground());
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t AnimationServiceStub::SplitModeCreateMiddleLineRemote(MessageParcel& data,
|
||||
MessageParcel& reply, MessageOption& options)
|
||||
{
|
||||
reply.WriteInt32(SplitModeCreateMiddleLine());
|
||||
return 0;
|
||||
}
|
||||
} // namespace OHOS
|
||||
|
@ -66,6 +66,7 @@ public:
|
||||
virtual void OnVisibilityChange(WindowVisibilityChangeFunc func) override;
|
||||
virtual void OnTypeChange(WindowTypeChangeFunc func) override;
|
||||
virtual void OnModeChange(WindowModeChangeFunc func) override;
|
||||
virtual void OnSplitStatusChange(SplitStatusChangeFunc func) override;
|
||||
|
||||
// listener
|
||||
virtual WMError OnTouch(OnTouchFunc cb) override;
|
||||
|
@ -47,6 +47,9 @@ public:
|
||||
MOCKABLE sptr<Promise<struct WMSWindowInfo>> CreateWindow(
|
||||
const sptr<WlSurface> &wlSurface, int32_t did, WindowType type);
|
||||
|
||||
virtual void RegisterWindowSizeChange(WindowSizeChangeFunc func);
|
||||
virtual void RegisterSplitModeChange(SplitStatusChangeFunc func);
|
||||
|
||||
private:
|
||||
WindowManagerServer() = default;
|
||||
MOCKABLE ~WindowManagerServer() = default;
|
||||
@ -58,8 +61,12 @@ private:
|
||||
|
||||
static void OnWindowChange(void *, struct wms *,
|
||||
uint32_t status, uint32_t wid, int32_t x, int32_t y, int32_t width, int32_t height);
|
||||
static void OnWindowSizeChange(void *, struct wms *, int32_t width, int32_t height);
|
||||
static void OnSplitStatusChange(void *, struct wms *, uint32_t status);
|
||||
|
||||
static inline std::queue<sptr<Promise<struct WMSWindowInfo>>> promiseQueue;
|
||||
static inline WindowSizeChangeFunc onWindowSizeChange;
|
||||
static inline SplitStatusChangeFunc onSplitModeChange;
|
||||
};
|
||||
} // namespace OHOS
|
||||
|
||||
|
@ -89,6 +89,11 @@ WMError WindowImpl::CreateRemoteWindow(sptr<WindowImpl> &wi,
|
||||
return wminfo.wret;
|
||||
}
|
||||
|
||||
auto onWindowSizeChange = [&attr = wi->attr](int32_t width, int32_t height) {
|
||||
attr.SetWidthHeight(width, height);
|
||||
};
|
||||
windowManagerServer->RegisterWindowSizeChange(onWindowSizeChange);
|
||||
|
||||
wi->attr.SetID(wminfo.wid);
|
||||
wi->attr.SetType(option->GetWindowType());
|
||||
wi->attr.SetVisibility(true);
|
||||
@ -401,6 +406,12 @@ void WindowImpl::OnModeChange(WindowModeChangeFunc func)
|
||||
attr.OnModeChange(func);
|
||||
}
|
||||
|
||||
void WindowImpl::OnSplitStatusChange(SplitStatusChangeFunc func)
|
||||
{
|
||||
auto windowManagerServer = SingletonContainer::Get<WindowManagerServer>();
|
||||
windowManagerServer->RegisterSplitModeChange(func);
|
||||
}
|
||||
|
||||
WMError WindowImpl::OnTouch(OnTouchFunc cb)
|
||||
{
|
||||
CHECK_DESTROY(WM_ERROR_DESTROYED_OBJECT);
|
||||
|
@ -56,6 +56,8 @@ void WindowManagerServer::OnAppear(const GetServiceFunc get, const std::string &
|
||||
wms = static_cast<struct wms *>(ret);
|
||||
const struct wms_listener listener = {
|
||||
.window_status = &WindowManagerServer::OnWindowChange,
|
||||
.window_size_change = &WindowManagerServer::OnWindowSizeChange,
|
||||
.split_mode_change = &WindowManagerServer::OnSplitStatusChange,
|
||||
};
|
||||
wms_add_listener(wms, &listener, nullptr);
|
||||
}
|
||||
@ -87,6 +89,22 @@ void WindowManagerServer::OnWindowChange(void *, struct wms *,
|
||||
}
|
||||
}
|
||||
|
||||
void WindowManagerServer::OnWindowSizeChange(void *, struct wms *, int32_t width, int32_t height)
|
||||
{
|
||||
WMLOGFI("%{public}dx%{public}d", width, height);
|
||||
if (onWindowSizeChange) {
|
||||
onWindowSizeChange(width, height);
|
||||
}
|
||||
}
|
||||
|
||||
void WindowManagerServer::OnSplitStatusChange(void *, struct wms *, uint32_t status)
|
||||
{
|
||||
WMLOGFI("OnSplitStatusChange status: %{public}u", status);
|
||||
if (onSplitModeChange) {
|
||||
onSplitModeChange(static_cast<enum SplitStatus>(status));
|
||||
}
|
||||
}
|
||||
|
||||
sptr<Promise<struct WMSWindowInfo>> WindowManagerServer::CreateWindow(
|
||||
const sptr<WlSurface> &wlSurface, int32_t did, WindowType type)
|
||||
{
|
||||
@ -104,4 +122,14 @@ sptr<Promise<struct WMSWindowInfo>> WindowManagerServer::CreateWindow(
|
||||
delegator.Dep<WlDisplay>()->Flush();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void WindowManagerServer::RegisterSplitModeChange(SplitStatusChangeFunc func)
|
||||
{
|
||||
onSplitModeChange = func;
|
||||
}
|
||||
|
||||
void WindowManagerServer::RegisterWindowSizeChange(WindowSizeChangeFunc func)
|
||||
{
|
||||
onWindowSizeChange = func;
|
||||
}
|
||||
} // namespace OHOS
|
||||
|
@ -33,6 +33,7 @@ config("wmserver_config") {
|
||||
"//third_party/wayland-ivi-extension/ivi-input-modules/ivi-input-controller/src/",
|
||||
"//utils/native/base/include",
|
||||
"//foundation/graphic/standard/interfaces/innerkits/wmclient",
|
||||
"//foundation/graphic/standard/interfaces/innerkits/wmservice",
|
||||
]
|
||||
|
||||
cflags = [
|
||||
@ -51,6 +52,7 @@ ohos_shared_library("wmserver") {
|
||||
"src/layout_controller.cpp",
|
||||
"src/rects.cpp",
|
||||
"src/screen_info.c",
|
||||
"src/split_mode.cpp",
|
||||
"src/wmserver.c",
|
||||
]
|
||||
|
||||
@ -61,9 +63,12 @@ ohos_shared_library("wmserver") {
|
||||
deps = [
|
||||
":layout_header",
|
||||
"//drivers/peripheral/display/hal:hdi_display_device",
|
||||
"//foundation/graphic/standard/frameworks/animation_server:libanimation_service",
|
||||
"//foundation/graphic/standard/utils:graphic_bytrace",
|
||||
"//foundation/multimodalinput/input/patch/diff_libinput_mmi:libinput-third-mmi",
|
||||
"//third_party/wayland_standard:wayland_core_protocol",
|
||||
"//third_party/weston:libexec_weston",
|
||||
"//third_party/weston:trace",
|
||||
"//utils/native/base:utils",
|
||||
]
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
<entry name="inner_error" value="4"/>
|
||||
<entry name="other" value="5"/>
|
||||
<entry name="api_failed" value="6"/>
|
||||
<entry name="invalid_operation" value="7"/>
|
||||
</enum>
|
||||
|
||||
<event name="reply_error">
|
||||
@ -146,6 +147,12 @@
|
||||
<arg name="width" type="int"/>
|
||||
<arg name="height" type="int"/>
|
||||
</event>
|
||||
|
||||
<event name="window_size_change">
|
||||
<description summary="window size change"/>
|
||||
<arg name="width" type="int"/>
|
||||
<arg name="height" type="int"/>
|
||||
</event>
|
||||
<!-- Window Ctor Dtor }}} -->
|
||||
|
||||
<!-- Global Window Event {{{ -->
|
||||
@ -298,6 +305,19 @@
|
||||
</request>
|
||||
<!-- Virtual Display }}}-->
|
||||
|
||||
<!-- Split Mode {{{ -->
|
||||
<request name="set_split_mode">
|
||||
<description summary="set split mode"/>
|
||||
<arg name="mode" type="uint" summary="split mode"/>
|
||||
<arg name="x" type="int" summary="x"/>
|
||||
<arg name="y" type="int" summary="y"/>
|
||||
</request>
|
||||
|
||||
<event name="split_mode_change">
|
||||
<description summary="split_mode return value"/>
|
||||
<arg name="status" type="uint" summary="status"/>
|
||||
</event>
|
||||
<!-- Split Mode }}} -->
|
||||
</interface>
|
||||
|
||||
<interface name="screen_info" version="1">
|
||||
|
543
frameworks/wmserver/src/split_mode.cpp
Normal file
543
frameworks/wmserver/src/split_mode.cpp
Normal file
@ -0,0 +1,543 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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 "split_mode.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <graphic_bytrace.h>
|
||||
#include <ianimation_service.h>
|
||||
#include <ivi-layout-private.h>
|
||||
#include <window_manager_type.h>
|
||||
#include <wms-server-protocol.h>
|
||||
|
||||
#include "wmserver.h"
|
||||
#include "layout_controller.h"
|
||||
|
||||
#include <trace.h>
|
||||
DEFINE_LOG_LABEL("SplitMode");
|
||||
|
||||
using namespace OHOS;
|
||||
|
||||
int32_t g_x = 0;
|
||||
int32_t g_y = 0;
|
||||
bool g_reinit = false;
|
||||
constexpr double lineHeight = 0.1;
|
||||
constexpr double lineHeightHalf = lineHeight / 2;
|
||||
|
||||
void GetSplitModeShowArea(int32_t &x, int32_t &y, int32_t &width, int32_t &height)
|
||||
{
|
||||
struct layout layout = {};
|
||||
LayoutControllerCalcWindowDefaultLayout(WINDOW_TYPE_NORMAL, WINDOW_MODE_UNSET, NULL, &layout);
|
||||
x = layout.x;
|
||||
y = layout.y;
|
||||
width = layout.w;
|
||||
height = layout.h;
|
||||
}
|
||||
|
||||
void ChangeSplitMode(struct WindowSurface *ws, enum SplitStatus status)
|
||||
{
|
||||
ScopedBytrace trace(__func__);
|
||||
wms_send_split_mode_change(ws->controller->pWlResource, status);
|
||||
LOG_INFO("%d", status);
|
||||
}
|
||||
|
||||
void ChangeWindowPosition(struct WindowSurface *ws, int32_t x, int32_t y)
|
||||
{
|
||||
ScopedBytrace trace(__func__);
|
||||
SetWindowPosition(ws, x, y);
|
||||
LOG_INFO("%d move to (%d, %d)", ws->surfaceId, x, y);
|
||||
}
|
||||
|
||||
void ChangeWindowSize(struct WindowSurface *ws, int32_t w, int32_t h)
|
||||
{
|
||||
ScopedBytrace trace(__func__);
|
||||
wms_send_window_size_change(ws->controller->pWlResource, w, h);
|
||||
LOG_INFO("%d resize to %dx%d", ws->surfaceId, w, h);
|
||||
}
|
||||
|
||||
uint32_t GetSplitMode()
|
||||
{
|
||||
struct WmsContext *ctx = GetWmsInstance();
|
||||
return ctx->splitMode;
|
||||
}
|
||||
|
||||
void SetSplitMode(uint32_t type)
|
||||
{
|
||||
ScopedBytrace trace(__func__);
|
||||
struct WmsContext *ctx = GetWmsInstance();
|
||||
ctx->splitMode = type;
|
||||
LOG_INFO("splitMode -> %d", ctx->splitMode);
|
||||
}
|
||||
|
||||
struct WindowSurface *GetWindow(std::function<bool(struct WindowSurface *ws)> condition)
|
||||
{
|
||||
struct WmsContext *ctx = GetWmsInstance();
|
||||
struct WindowSurface *ws = NULL;
|
||||
wl_list_for_each(ws, &ctx->wlListWindow, link) {
|
||||
if (condition(ws)) {
|
||||
return ws;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ForeachWindow(std::function<bool(struct WindowSurface *ws)> condition,
|
||||
std::function<void(struct WindowSurface *ws)> action)
|
||||
{
|
||||
ScopedBytrace trace(__func__);
|
||||
struct WmsContext *ctx = GetWmsInstance();
|
||||
struct WindowSurface *ws = NULL;
|
||||
wl_list_for_each(ws, &ctx->wlListWindow, link) {
|
||||
if (condition(ws)) {
|
||||
action(ws);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct WindowSurface *GetSplitedWindow()
|
||||
{
|
||||
auto condition = [](struct WindowSurface *ws) {
|
||||
return ws->isSplited;
|
||||
};
|
||||
return GetWindow(condition);
|
||||
}
|
||||
|
||||
struct WindowSurface *GetLineWindow()
|
||||
{
|
||||
auto condition = [](struct WindowSurface *ws) {
|
||||
return ws->type == WINDOW_TYPE_SPLIT_LINE;
|
||||
};
|
||||
return GetWindow(condition);
|
||||
}
|
||||
|
||||
bool GetSplitedWindows(struct WindowSurface *&top, struct WindowSurface *&bottom)
|
||||
{
|
||||
top = GetSplitedWindow();
|
||||
if (top == nullptr) {
|
||||
LOG_ERROR("no splitWindow");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto condition = [top](struct WindowSurface *ws) {
|
||||
return ws->isSplited && ws != top;
|
||||
};
|
||||
bottom = GetWindow(condition);
|
||||
if (bottom == nullptr) {
|
||||
LOG_ERROR("no two splitWindow");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (top->y > bottom->y) {
|
||||
auto tmp = top;
|
||||
top = bottom;
|
||||
bottom = tmp;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool To0Null()
|
||||
{
|
||||
auto condition = [](struct WindowSurface *ws) {
|
||||
return ws->isSplited;
|
||||
};
|
||||
auto action = [](struct WindowSurface *ws) {
|
||||
ws->isSplited = false;
|
||||
int32_t defX = 0, defY = 0, defWidth = 0, defHeight = 0;
|
||||
GetSplitModeShowArea(defX, defY, defWidth, defHeight);
|
||||
ChangeWindowPosition(ws, defX, defY);
|
||||
ChangeWindowSize(ws, defWidth, defHeight);
|
||||
ChangeSplitMode(ws, SPLIT_STATUS_RETAIN);
|
||||
return false;
|
||||
};
|
||||
ForeachWindow(condition, action);
|
||||
|
||||
auto lineWindow = GetLineWindow();
|
||||
if (lineWindow) {
|
||||
ChangeSplitMode(lineWindow, SPLIT_STATUS_DESTROY);
|
||||
}
|
||||
AddSurfaceDestroyListener(nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool To1Unenable()
|
||||
{
|
||||
auto condition = [](struct WindowSurface *ws) {
|
||||
return ws->type == WINDOW_TYPE_NORMAL;
|
||||
};
|
||||
auto ws = GetWindow(condition);
|
||||
ws->isSplited = true;
|
||||
ChangeSplitMode(ws, SPLIT_STATUS_VAGUE);
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSwitchTop(struct WindowSurface *ws)
|
||||
{
|
||||
if (ws->type != WINDOW_TYPE_SPLIT_LINE) {
|
||||
return;
|
||||
}
|
||||
|
||||
ws = GetSplitedWindow();
|
||||
if (ws == nullptr) {
|
||||
LOG_ERROR("no splitWindow");
|
||||
return;
|
||||
}
|
||||
|
||||
struct WmsContext *ctx = GetWmsInstance();
|
||||
ctx->pLayoutInterface->surface_change_top(ws->layoutSurface);
|
||||
ctx->pLayoutInterface->commit_changes();
|
||||
AddSetWindowTopListener(nullptr);
|
||||
}
|
||||
|
||||
void OnSurfaceDestroy(struct WindowSurface *surface)
|
||||
{
|
||||
LOG_INFO("OnSurfaceDestroy: %d", surface->surfaceId);
|
||||
if (surface->isSplited == false) {
|
||||
return;
|
||||
}
|
||||
AddSurfaceDestroyListener(nullptr);
|
||||
SetSplitMode(SPLIT_MODE_NULL);
|
||||
LOG_INFO("exit split mode");
|
||||
|
||||
auto lineWindow = GetLineWindow();
|
||||
if (lineWindow) {
|
||||
ChangeSplitMode(lineWindow, SPLIT_STATUS_DESTROY);
|
||||
}
|
||||
|
||||
auto condition = [surface](struct WindowSurface *ws) {
|
||||
return ws->isSplited && ws != surface;
|
||||
};
|
||||
auto ws = GetWindow(condition);
|
||||
if (ws == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
ws->isSplited = false;
|
||||
int32_t defX = 0, defY = 0, defWidth = 0, defHeight = 0;
|
||||
GetSplitModeShowArea(defX, defY, defWidth, defHeight);
|
||||
ChangeWindowPosition(ws, defX, defY);
|
||||
ChangeWindowSize(ws, defWidth, defHeight);
|
||||
ChangeSplitMode(ws, SPLIT_STATUS_RETAIN);
|
||||
|
||||
auto ctx = GetWmsInstance();
|
||||
ctx->pLayoutInterface->surface_change_top(ws->layoutSurface);
|
||||
ctx->pLayoutInterface->commit_changes();
|
||||
}
|
||||
|
||||
bool To2Single(struct WindowSurface *ws)
|
||||
{
|
||||
int32_t defX = 0, defY = 0, defWidth = 0, defHeight = 0;
|
||||
GetSplitModeShowArea(defX, defY, defWidth, defHeight);
|
||||
|
||||
// vectical-align: middle, height: 1 - lineHeight
|
||||
ChangeWindowPosition(ws, defX, defY + defHeight * lineHeightHalf);
|
||||
ChangeWindowSize(ws, defWidth, defHeight * (1 - lineHeight));
|
||||
ws->isSplited = true;
|
||||
ChangeSplitMode(ws, SPLIT_STATUS_VAGUE);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool To2Single0()
|
||||
{
|
||||
AddSurfaceDestroyListener(OnSurfaceDestroy);
|
||||
auto condition = [](struct WindowSurface *ws) {
|
||||
return ws->type == WINDOW_TYPE_NORMAL;
|
||||
};
|
||||
struct WindowSurface *ws = GetWindow(condition);
|
||||
if (ws == nullptr) {
|
||||
LOG_ERROR("ws is nullptr, cannot found WINDOW_TYPE_NORMAL window");
|
||||
return false;
|
||||
}
|
||||
|
||||
AddSetWindowTopListener(OnSwitchTop);
|
||||
if (IAnimationService::Get() == nullptr) {
|
||||
LOG_ERROR("IAnimationService::Get is nullptr");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto ret = IAnimationService::Get()->SplitModeCreateBackground();
|
||||
if (ret) {
|
||||
LOG_ERROR("SplitModeCreateBackground failed: %s", GSErrorStr(ret).c_str());
|
||||
if (ret == GSERROR_BINDER) {
|
||||
g_reinit = true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return To2Single(ws);
|
||||
}
|
||||
|
||||
bool To2Single3()
|
||||
{
|
||||
struct WindowSurface *ws = nullptr;
|
||||
ws = GetSplitedWindow();
|
||||
if (ws == nullptr) {
|
||||
LOG_ERROR("no split window");
|
||||
return false;
|
||||
}
|
||||
return To2Single(ws);
|
||||
}
|
||||
|
||||
bool To3Select()
|
||||
{
|
||||
auto ws = GetSplitedWindow();
|
||||
int32_t defX = 0, defY = 0, defWidth = 0, defHeight = 0;
|
||||
GetSplitModeShowArea(defX, defY, defWidth, defHeight);
|
||||
|
||||
LOG_INFO("Select g_y: %d %p", g_y, ws);
|
||||
if (ws == nullptr) {
|
||||
LOG_ERROR("ws is nullptr");
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t height = defHeight * (1 - lineHeight) / 2;
|
||||
if (g_y > defY + defHeight * 0.5) {
|
||||
// select bottom, ws move to top
|
||||
LOG_INFO("Select bottom");
|
||||
// vectical-align: top
|
||||
ChangeWindowPosition(ws, defX, defY);
|
||||
ChangeWindowSize(ws, defWidth, height);
|
||||
} else {
|
||||
// select bottom, ws move to bottom
|
||||
LOG_INFO("Select top");
|
||||
// vectical-align: bottom
|
||||
ChangeWindowPosition(ws, defX, defY + defHeight - height);
|
||||
ChangeWindowSize(ws, defWidth, height);
|
||||
}
|
||||
|
||||
ChangeSplitMode(ws, SPLIT_STATUS_VAGUE);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool To4Confirm()
|
||||
{
|
||||
if (IAnimationService::Get() == nullptr) {
|
||||
LOG_ERROR("IAnimationService::Get is nullptr");
|
||||
return false;
|
||||
}
|
||||
auto ret = IAnimationService::Get()->SplitModeCreateMiddleLine();
|
||||
if (ret) {
|
||||
LOG_ERROR("SplitModeCreateMiddleLine failed: %d", ret);
|
||||
if (ret == GSERROR_BINDER) {
|
||||
g_reinit = true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
auto condition = [](struct WindowSurface *ws) {
|
||||
return ws->type == WINDOW_TYPE_NORMAL && ws->isSplited == false;
|
||||
};
|
||||
auto win1 = GetWindow(condition);
|
||||
if (win1 == nullptr) {
|
||||
LOG_ERROR("win1 is nullptr");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto win2 = GetSplitedWindow();
|
||||
if (win2 == nullptr) {
|
||||
LOG_ERROR("win2 is nullptr");
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t defX = 0, defY = 0, defWidth = 0, defHeight = 0;
|
||||
GetSplitModeShowArea(defX, defY, defWidth, defHeight);
|
||||
int32_t y = 0;
|
||||
if (win2->y <= defY + defHeight / 2) {
|
||||
y = defHeight - (defHeight * (1 - lineHeight) / 2);
|
||||
}
|
||||
|
||||
win1->isSplited = true;
|
||||
ChangeWindowPosition(win1, defX, defY + y);
|
||||
ChangeWindowSize(win1, win2->width, win2->height);
|
||||
|
||||
ChangeSplitMode(win1, SPLIT_STATUS_CLEAR);
|
||||
ChangeSplitMode(win2, SPLIT_STATUS_CLEAR);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool To5TouchDown()
|
||||
{
|
||||
auto condition = [](struct WindowSurface *ws) {
|
||||
return ws->isSplited;
|
||||
};
|
||||
auto action = [](struct WindowSurface *ws) {
|
||||
ChangeSplitMode(ws, SPLIT_STATUS_VAGUE);
|
||||
};
|
||||
ForeachWindow(condition, action);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool To6TouchMove()
|
||||
{
|
||||
struct WindowSurface *topWindow;
|
||||
struct WindowSurface *bottomWindow;
|
||||
if (!GetSplitedWindows(topWindow, bottomWindow)) {
|
||||
LOG_ERROR("no two splitWindow");
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t defX = 0, defY = 0, defWidth = 0, defHeight = 0;
|
||||
GetSplitModeShowArea(defX, defY, defWidth, defHeight);
|
||||
|
||||
LOG_INFO("g_y: %d", g_y);
|
||||
ChangeWindowSize(topWindow, defWidth, g_y - defY - defHeight * lineHeightHalf);
|
||||
ChangeSplitMode(topWindow, SPLIT_STATUS_VAGUE);
|
||||
|
||||
ChangeWindowPosition(bottomWindow, defX, g_y + defHeight * lineHeightHalf);
|
||||
ChangeWindowSize(bottomWindow, defWidth, defY + defHeight - g_y - defHeight * lineHeightHalf);
|
||||
ChangeSplitMode(bottomWindow, SPLIT_STATUS_VAGUE);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool To7TouchUp5()
|
||||
{
|
||||
struct WindowSurface *topWindow;
|
||||
struct WindowSurface *bottomWindow;
|
||||
if (!GetSplitedWindows(topWindow, bottomWindow)) {
|
||||
LOG_ERROR("no two splitWindow");
|
||||
return false;
|
||||
}
|
||||
|
||||
ChangeSplitMode(topWindow, SPLIT_STATUS_CLEAR);
|
||||
ChangeSplitMode(bottomWindow, SPLIT_STATUS_CLEAR);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool To7TouchUp6()
|
||||
{
|
||||
struct WindowSurface *topWindow;
|
||||
struct WindowSurface *bottomWindow;
|
||||
if (!GetSplitedWindows(topWindow, bottomWindow)) {
|
||||
LOG_ERROR("no two splitWindow");
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t x = 0, y = 0, w = 0, h = 0;
|
||||
GetSplitModeShowArea(x, y, w, h);
|
||||
|
||||
int32_t diff = g_y - y;
|
||||
LOG_INFO("diff: %d", diff);
|
||||
if (0.2 * h <= diff && diff <= h * 0.8) {
|
||||
ChangeSplitMode(topWindow, SPLIT_STATUS_CLEAR);
|
||||
ChangeSplitMode(bottomWindow, SPLIT_STATUS_CLEAR);
|
||||
return true;
|
||||
}
|
||||
|
||||
auto longWindow = topWindow;
|
||||
auto shortWindow = bottomWindow;
|
||||
if (bottomWindow->height > topWindow->height) {
|
||||
longWindow = bottomWindow;
|
||||
shortWindow = topWindow;
|
||||
}
|
||||
ChangeSplitMode(shortWindow, SPLIT_STATUS_DESTROY);
|
||||
ChangeSplitMode(GetLineWindow(), SPLIT_STATUS_DESTROY);
|
||||
|
||||
longWindow->isSplited = false;
|
||||
ChangeWindowPosition(longWindow, x, y);
|
||||
ChangeWindowSize(longWindow, w, h);
|
||||
ChangeSplitMode(longWindow, SPLIT_STATUS_RETAIN);
|
||||
|
||||
struct WmsContext *ctx = GetWmsInstance();
|
||||
SetSplitMode(SPLIT_MODE_NULL);
|
||||
LOG_INFO("exit split mode");
|
||||
ctx->pLayoutInterface->surface_change_top(longWindow->layoutSurface);
|
||||
ctx->pLayoutInterface->commit_changes();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Ignore()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/* split mode state machine:
|
||||
* /-\ /-* /-*
|
||||
* |7| ----> |0| <---> |1|
|
||||
* \-/ \-/ \-/
|
||||
* ^
|
||||
* ^ \ ^
|
||||
* | \ |
|
||||
* | \ v
|
||||
* | |
|
||||
* | | /-* /-*
|
||||
* | | |2| <---> |3|
|
||||
* | \ \-/ \-/
|
||||
* | \
|
||||
* | \ |
|
||||
* | \ |
|
||||
* | \ v
|
||||
* v
|
||||
* /-* /-\ /-\
|
||||
* |6| <---- |5| <---- |4|
|
||||
* \-/ \-/ \-/
|
||||
*/
|
||||
bool(* stateMachine[SPLIT_MODE_MAX][SPLIT_MODE_MAX])() = {
|
||||
/* From 0NULL 1UNENABLE 2SINGLE 3SELECT 4CONFIRM 5TOUCHDOWN 6TOUCHMOVE 7TOUCHUP */
|
||||
{ Ignore, To0Null, To0Null, nullptr, nullptr, nullptr, nullptr, To0Null },
|
||||
{ To1Unenable, Ignore, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr },
|
||||
{ To2Single0, nullptr, Ignore, To2Single3, nullptr, nullptr, nullptr, nullptr },
|
||||
{ nullptr, nullptr, To3Select, To3Select, nullptr, nullptr, nullptr, nullptr },
|
||||
{ nullptr, nullptr, nullptr, To4Confirm, nullptr, nullptr, nullptr, nullptr },
|
||||
{ nullptr, nullptr, nullptr, nullptr, To5TouchDown, nullptr, nullptr, To5TouchDown },
|
||||
{ nullptr, nullptr, nullptr, nullptr, nullptr, To6TouchMove, To6TouchMove, nullptr },
|
||||
{ nullptr, nullptr, nullptr, nullptr, nullptr, To7TouchUp5, To7TouchUp6, nullptr },
|
||||
};
|
||||
|
||||
void ControllerSetSplitMode(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t type, int32_t x, int32_t y)
|
||||
{
|
||||
ScopedBytrace trace(__func__);
|
||||
LOG_SCOPE();
|
||||
LOG_INFO("type: %d", type);
|
||||
if (!(0 <= type && type < SPLIT_MODE_MAX)) {
|
||||
LOG_ERROR("invalid");
|
||||
wms_send_reply_error(resource, WMS_ERROR_INVALID_PARAM);
|
||||
return;
|
||||
}
|
||||
|
||||
if (IAnimationService::Init(g_reinit) == GSERROR_OK) {
|
||||
g_reinit = false;
|
||||
}
|
||||
|
||||
auto currentType = GetSplitMode();
|
||||
LOG_INFO("from %u to %u", currentType, type);
|
||||
auto func = stateMachine[type][currentType];
|
||||
if (func == nullptr) {
|
||||
LOG_ERROR("cannot");
|
||||
wms_send_reply_error(resource, WMS_ERROR_INVALID_OPERATION);
|
||||
return;
|
||||
}
|
||||
|
||||
if (type == SPLIT_MODE_SELECT || type == SPLIT_MODE_DIVIDER_TOUCH_MOVE) {
|
||||
g_x = x;
|
||||
g_y = y;
|
||||
}
|
||||
|
||||
LOG_ENTERS("stateMachine");
|
||||
ScopedBytrace trace2("stateMachine");
|
||||
auto ret = func();
|
||||
trace2.End();
|
||||
LOG_EXITS("stateMachine");
|
||||
if (ret) {
|
||||
LOG_INFO("success");
|
||||
SetSplitMode(type);
|
||||
wms_send_reply_error(resource, WMS_ERROR_OK);
|
||||
} else {
|
||||
LOG_ERROR("failure");
|
||||
wms_send_reply_error(resource, WMS_ERROR_API_FAILED);
|
||||
}
|
||||
return;
|
||||
}
|
36
frameworks/wmserver/src/split_mode.h
Normal file
36
frameworks/wmserver/src/split_mode.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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 FRAMEWORKS_WMSERVER_SRC_SPLIT_MODE_H
|
||||
#define FRAMEWORKS_WMSERVER_SRC_SPLIT_MODE_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct wl_client;
|
||||
struct wl_resource;
|
||||
struct WindowSurface;
|
||||
void ControllerSetSplitMode(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t type, int32_t x, int32_t y);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // FRAMEWORKS_WMSERVER_SRC_SPLIT_MODE_H
|
@ -29,6 +29,7 @@
|
||||
#include "libweston-internal.h"
|
||||
#include "screen_info.h"
|
||||
#include "weston.h"
|
||||
#include "split_mode.h"
|
||||
|
||||
#define LOG_LABEL "wms-controller"
|
||||
|
||||
@ -57,46 +58,6 @@
|
||||
#define ASSERT assert
|
||||
#define DEFAULT_SEAT_NAME "default"
|
||||
|
||||
struct WindowSurface {
|
||||
struct WmsController *controller;
|
||||
struct ivi_layout_surface *layoutSurface;
|
||||
struct weston_surface *surface;
|
||||
struct wl_listener surfaceDestroyListener;
|
||||
struct wl_listener propertyChangedListener;
|
||||
|
||||
uint32_t surfaceId;
|
||||
uint32_t screenId;
|
||||
uint32_t type;
|
||||
uint32_t mode;
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
int32_t lastSurfaceWidth;
|
||||
int32_t lastSurfaceHeight;
|
||||
int32_t firstCommit;
|
||||
|
||||
struct wl_list link;
|
||||
};
|
||||
|
||||
struct ScreenshotFrameListener {
|
||||
struct wl_listener frameListener;
|
||||
struct wl_listener outputDestroyed;
|
||||
uint32_t idScreen;
|
||||
struct weston_output *output;
|
||||
};
|
||||
|
||||
struct WmsController {
|
||||
struct wl_resource *pWlResource;
|
||||
uint32_t id;
|
||||
uint32_t windowIdFlags;
|
||||
struct wl_client *pWlClient;
|
||||
struct wl_list wlListLink;
|
||||
struct wl_list wlListLinkRes;
|
||||
struct WmsContext *pWmsCtx;
|
||||
struct ScreenshotFrameListener stListener;
|
||||
};
|
||||
|
||||
static struct WmsContext g_wmsCtx = {0};
|
||||
|
||||
static ScreenInfoChangeListener g_screenInfoChangeListener = NULL;
|
||||
@ -203,7 +164,7 @@ static struct WindowSurface *GetWindowSurface(const struct weston_surface *surfa
|
||||
return windowSurface;
|
||||
}
|
||||
|
||||
static void SetSourceRectangle(const struct WindowSurface *windowSurface,
|
||||
void SetSourceRectangle(const struct WindowSurface *windowSurface,
|
||||
int32_t x, int32_t y, int32_t width, int32_t height)
|
||||
{
|
||||
const struct ivi_layout_interface_for_wms *layoutInterface = windowSurface->controller->pWmsCtx->pLayoutInterface;
|
||||
@ -230,7 +191,7 @@ static void SetSourceRectangle(const struct WindowSurface *windowSurface,
|
||||
(uint32_t)x, (uint32_t)y, (uint32_t)width, (uint32_t)height);
|
||||
}
|
||||
|
||||
static void SetDestinationRectangle(struct WindowSurface *windowSurface,
|
||||
void SetDestinationRectangle(struct WindowSurface *windowSurface,
|
||||
int32_t x, int32_t y, int32_t width, int32_t height)
|
||||
{
|
||||
const struct ivi_layout_interface_for_wms *layoutInterface = windowSurface->controller->pWmsCtx->pLayoutInterface;
|
||||
@ -380,10 +341,9 @@ static uint32_t GetWindowId(struct WmsController *pController)
|
||||
return windowId;
|
||||
}
|
||||
|
||||
static struct ivi_layout_layer *GetLayer(struct weston_output *westonOutput,
|
||||
struct ivi_layout_interface_for_wms *pLayoutInterface,
|
||||
uint32_t layerId, bool *isNewLayer)
|
||||
struct ivi_layout_layer *GetLayer(struct weston_output *westonOutput, uint32_t layerId, bool *isNewLayer)
|
||||
{
|
||||
struct ivi_layout_interface_for_wms *pLayoutInterface = GetWmsInstance()->pLayoutInterface;
|
||||
LOGD("start.");
|
||||
struct ivi_layout_layer *layoutLayer = pLayoutInterface->get_layer_from_id(layerId);
|
||||
if (!layoutLayer) {
|
||||
@ -475,8 +435,7 @@ static bool AddSurface(struct WindowSurface *windowSurface,
|
||||
bool isNewLayer = false;
|
||||
struct weston_output *westonOutput = screen->westonOutput;
|
||||
uint32_t layerId = GetLayerId(screen->screenId, windowType, windowMode);
|
||||
struct ivi_layout_layer *layoutLayer = GetLayer(screen->westonOutput,
|
||||
layoutInterface, layerId, &isNewLayer);
|
||||
struct ivi_layout_layer *layoutLayer = GetLayer(screen->westonOutput, layerId, &isNewLayer);
|
||||
if (!layoutLayer) {
|
||||
LOGE("GetLayer failed.");
|
||||
return false;
|
||||
@ -544,7 +503,6 @@ static bool AddWindow(struct WindowSurface *windowSurface)
|
||||
|
||||
// window position,size calc.
|
||||
CalcWindowInfo(windowSurface);
|
||||
|
||||
LOGD("end.");
|
||||
return true;
|
||||
}
|
||||
@ -686,8 +644,7 @@ static bool ScreenCopyLayers(struct WmsContext *ctx, struct WmsScreen *screenFro
|
||||
for (int32_t layer_i = 0; layer_i < layersCount; layer_i++) {
|
||||
uint32_t layerIdOld = ctx->pLayoutInterface->get_id_of_layer(layers[layer_i]);
|
||||
uint32_t layerIdNew = ChangeLayerId(layerIdOld, screenFrom->screenId, screenTo->screenId);
|
||||
struct ivi_layout_layer *layerNew = GetLayer(screenTo->westonOutput,
|
||||
ctx->pLayoutInterface, layerIdNew, NULL);
|
||||
struct ivi_layout_layer *layerNew = GetLayer(screenTo->westonOutput, layerIdNew, NULL);
|
||||
if (!layerNew) {
|
||||
LOGE("GetLayer failed.");
|
||||
free(layers);
|
||||
@ -981,7 +938,7 @@ static void ControllerDestroyVirtualDisplay(struct wl_client *pWlClient,
|
||||
LOGD("end. DestroyVirtualDisplay");
|
||||
}
|
||||
|
||||
static void SetWindowPosition(struct WindowSurface *ws,
|
||||
void SetWindowPosition(struct WindowSurface *ws,
|
||||
int32_t x, int32_t y)
|
||||
{
|
||||
SetDestinationRectangle(ws, x, y, ws->width, ws->height);
|
||||
@ -989,7 +946,7 @@ static void SetWindowPosition(struct WindowSurface *ws,
|
||||
ws->y = y;
|
||||
}
|
||||
|
||||
static void SetWindowSize(struct WindowSurface *ws,
|
||||
void SetWindowSize(struct WindowSurface *ws,
|
||||
uint32_t width, uint32_t height)
|
||||
{
|
||||
SetSourceRectangle(ws, 0, 0, width, height);
|
||||
@ -1464,6 +1421,12 @@ static void ControllerSetNavigationBarVisibility(const struct wl_client *client,
|
||||
LOGD("end.");
|
||||
}
|
||||
|
||||
void(*g_onSetWindowTop)(struct WindowSurface *ws);
|
||||
void AddSetWindowTopListener(void(*fn)(struct WindowSurface *ws))
|
||||
{
|
||||
g_onSetWindowTop = fn;
|
||||
}
|
||||
|
||||
static void ControllerSetWindowTop(struct wl_client *client,
|
||||
struct wl_resource *resource, uint32_t windowId)
|
||||
{
|
||||
@ -1489,6 +1452,10 @@ static void ControllerSetWindowTop(struct wl_client *client,
|
||||
|
||||
ctx->pLayoutInterface->surface_change_top(windowSurface->layoutSurface);
|
||||
|
||||
if (g_onSetWindowTop) {
|
||||
g_onSetWindowTop(windowSurface);
|
||||
}
|
||||
|
||||
if (!SetWindowFocus(windowSurface)) {
|
||||
LOGE("SetWindowFocus failed.");
|
||||
wms_send_reply_error(resource, WMS_ERROR_INNER_ERROR);
|
||||
@ -1501,10 +1468,19 @@ static void ControllerSetWindowTop(struct wl_client *client,
|
||||
LOGD("end.");
|
||||
}
|
||||
|
||||
void(*g_onSurfaceDestroy)(struct WindowSurface *ws);
|
||||
void AddSurfaceDestroyListener(void(*fn)(struct WindowSurface *ws))
|
||||
{
|
||||
g_onSurfaceDestroy = fn;
|
||||
}
|
||||
|
||||
static void SurfaceDestroy(const struct WindowSurface *surface)
|
||||
{
|
||||
ASSERT(surface != NULL);
|
||||
LOGD("surfaceId:%{public}d start.", surface->surfaceId);
|
||||
if (g_onSurfaceDestroy) {
|
||||
g_onSurfaceDestroy(surface);
|
||||
}
|
||||
|
||||
wl_list_remove(&surface->surfaceDestroyListener.link);
|
||||
wl_list_remove(&surface->propertyChangedListener.link);
|
||||
@ -1585,6 +1561,7 @@ static void WindowSurfaceDestroy(const struct wl_listener *listener,
|
||||
LOGD("end.");
|
||||
}
|
||||
|
||||
|
||||
static void CreateWindow(struct WmsController *pWmsController,
|
||||
struct weston_surface *pWestonSurface,
|
||||
uint32_t windowId, uint32_t screenId, uint32_t windowType)
|
||||
@ -1623,6 +1600,7 @@ static void CreateWindow(struct WmsController *pWmsController,
|
||||
pWindow->surfaceId = windowId;
|
||||
pWindow->type = windowType;
|
||||
pWindow->mode = WINDOW_MODE_UNSET;
|
||||
pWindow->isSplited = false;
|
||||
pWindow->screenId = screenId;
|
||||
|
||||
if (!AddWindow(pWindow)) {
|
||||
@ -2006,6 +1984,7 @@ static const struct wms_interface g_controllerImplementation = {
|
||||
ControllerWindowshot,
|
||||
ControllerCreateVirtualDisplay,
|
||||
ControllerDestroyVirtualDisplay,
|
||||
ControllerSetSplitMode,
|
||||
};
|
||||
|
||||
static void UnbindWmsController(struct wl_resource *pResource)
|
||||
@ -2291,6 +2270,8 @@ static int WmsContextInit(struct WmsContext *ctx, struct weston_compositor *comp
|
||||
|
||||
wl_signal_add(&compositor->destroy_signal, &ctx->wlListenerDestroy);
|
||||
|
||||
ctx->splitMode = SPLIT_MODE_NULL;
|
||||
|
||||
LayoutControllerInit(0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
@ -24,6 +24,10 @@
|
||||
#include <ivi-layout-export.h>
|
||||
#include <wms-server-protocol.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef USE_IVI_INPUT_FOCUS
|
||||
#define INPUT_DEVICE_KEYBOARD ((unsigned int) 1 << 0)
|
||||
#define INPUT_DEVICE_POINTER ((unsigned int) 1 << 1)
|
||||
@ -49,6 +53,7 @@ struct WmsContext {
|
||||
const struct ivi_input_interface_for_wms *pInputInterface;
|
||||
#endif
|
||||
DeviceFuncs *deviceFuncs;
|
||||
uint32_t splitMode;
|
||||
};
|
||||
|
||||
struct WmsSeat {
|
||||
@ -70,4 +75,59 @@ struct WmsScreen {
|
||||
|
||||
struct WmsContext *GetWmsInstance(void);
|
||||
|
||||
struct WindowSurface {
|
||||
struct WmsController *controller;
|
||||
struct ivi_layout_surface *layoutSurface;
|
||||
struct weston_surface *surface;
|
||||
struct wl_listener surfaceDestroyListener;
|
||||
struct wl_listener propertyChangedListener;
|
||||
|
||||
uint32_t surfaceId;
|
||||
uint32_t screenId;
|
||||
uint32_t type;
|
||||
uint32_t mode;
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
int32_t lastSurfaceWidth;
|
||||
int32_t lastSurfaceHeight;
|
||||
int32_t firstCommit;
|
||||
bool isSplited;
|
||||
|
||||
struct wl_list link;
|
||||
};
|
||||
|
||||
struct ScreenshotFrameListener {
|
||||
struct wl_listener frameListener;
|
||||
struct wl_listener outputDestroyed;
|
||||
uint32_t idScreen;
|
||||
struct weston_output *output;
|
||||
};
|
||||
|
||||
struct WmsController {
|
||||
struct wl_resource *pWlResource;
|
||||
uint32_t id;
|
||||
uint32_t windowIdFlags;
|
||||
struct wl_client *pWlClient;
|
||||
struct wl_list wlListLink;
|
||||
struct wl_list wlListLinkRes;
|
||||
struct WmsContext *pWmsCtx;
|
||||
struct ScreenshotFrameListener stListener;
|
||||
};
|
||||
|
||||
void SetDestinationRectangle(struct WindowSurface *windowSurface,
|
||||
int32_t x, int32_t y, int32_t width, int32_t height);
|
||||
void SetSourceRectangle(const struct WindowSurface *windowSurface,
|
||||
int32_t x, int32_t y, int32_t width, int32_t height);
|
||||
void SetWindowPosition(struct WindowSurface *ws, int32_t x, int32_t y);
|
||||
void SetWindowSize(struct WindowSurface *ws, uint32_t width, uint32_t height);
|
||||
struct ivi_layout_layer *GetLayer(struct weston_output *westonOutput, uint32_t layerId, bool *isNewLayer);
|
||||
void AddSetWindowTopListener(void(*fn)(struct WindowSurface *ws));
|
||||
void AddSurfaceDestroyListener(void(*fn)(struct WindowSurface *ws));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // FRAMEWORKS_WMSERVER_SRC_WMSERVER_H
|
||||
|
@ -64,6 +64,8 @@ public:
|
||||
|
||||
virtual GSError StartRotationAnimation(uint32_t did, int32_t degree) override;
|
||||
|
||||
virtual sptr<PromiseWMError> SetSplitMode(SplitMode mode, int32_t x, int32_t y) override;
|
||||
|
||||
static void OnReply(wms_error);
|
||||
static void OnDisplayChange(uint32_t, const char *, wms_screen_status, int32_t, int32_t, wms_screen_type type);
|
||||
static void OnDisplayPower(uint32_t, int32_t);
|
||||
|
@ -114,11 +114,13 @@ void RegistryGlobal(void *ppwms, struct wl_registry *registry,
|
||||
OnDisplayBacklight,
|
||||
OnDisplayModeChange,
|
||||
nullptr,
|
||||
nullptr,
|
||||
OnGlobalWindowStatus,
|
||||
OnScreenShotDone,
|
||||
OnScreenShotError,
|
||||
OnWindowShotDone,
|
||||
OnWindowShotError,
|
||||
nullptr,
|
||||
};
|
||||
if (pwms != nullptr) {
|
||||
wms_add_listener(pwms, &listener, nullptr);
|
||||
|
@ -510,4 +510,15 @@ GSError WindowManagerServiceProxy::StartRotationAnimation(uint32_t did, int32_t
|
||||
|
||||
return as->StartRotationAnimation(did, degree);
|
||||
}
|
||||
|
||||
sptr<PromiseWMError> WindowManagerServiceProxy::SetSplitMode(SplitMode mode, int32_t x, int32_t y)
|
||||
{
|
||||
WMLOGFI("mode: %{public}d, x: %{public}d, y: %{public}d", mode, x, y);
|
||||
sptr<PromiseWMError> ret = new PromiseWMError();
|
||||
std::lock_guard<std::mutex> lock(promiseQueueMutex);
|
||||
promiseQueue.push(ret);
|
||||
wms_set_split_mode(wms, mode, x, y);
|
||||
wl_display_flush(display);
|
||||
return ret;
|
||||
}
|
||||
} // namespace OHOS
|
||||
|
@ -57,6 +57,7 @@ ohos_executable("wmtest") {
|
||||
"test/wmclient_native_test_18.cpp",
|
||||
"test/wmclient_native_test_19.cpp",
|
||||
"test/wmclient_native_test_2.cpp",
|
||||
"test/wmclient_native_test_20.cpp",
|
||||
"test/wmclient_native_test_26.cpp",
|
||||
"test/wmclient_native_test_27.cpp",
|
||||
"test/wmclient_native_test_28.cpp",
|
||||
@ -82,6 +83,7 @@ ohos_executable("wmtest") {
|
||||
|
||||
if (ace_enable_gpu) {
|
||||
sources += [
|
||||
"frameworks/egl_native_test_class.cpp",
|
||||
"test/wmclient_native_test_31.cpp",
|
||||
"test/wmservice_native_test_6.cpp",
|
||||
]
|
||||
@ -96,6 +98,9 @@ ohos_executable("wmtest") {
|
||||
"//foundation/graphic/standard:libvsync_client",
|
||||
"//foundation/graphic/standard:libwmclient",
|
||||
"//foundation/graphic/standard:libwmservice",
|
||||
"//foundation/graphic/standard/frameworks/animation_server:libanimation_service",
|
||||
"//foundation/graphic/standard/utils:cpudraw",
|
||||
"//foundation/graphic/standard/utils:graphic_bytrace",
|
||||
"//foundation/graphic/standard/utils:libgslogger",
|
||||
"//foundation/graphic/standard/utils:option_parser",
|
||||
"//foundation/graphic/standard/utils:raw_parser",
|
||||
|
207
frameworks/wmtest/frameworks/egl_native_test_class.cpp
Normal file
207
frameworks/wmtest/frameworks/egl_native_test_class.cpp
Normal file
@ -0,0 +1,207 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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 "native_test_class.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
#include <securec.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <display_type.h>
|
||||
|
||||
#include "inative_test.h"
|
||||
#include "util.h"
|
||||
|
||||
namespace OHOS {
|
||||
sptr<EGLNativeTestSync> EGLNativeTestSync::CreateSync(EGLDrawFunc drawFunc,
|
||||
sptr<EglSurface> &peglsurface, uint32_t width, uint32_t height, void *data)
|
||||
{
|
||||
if (drawFunc != nullptr && peglsurface != nullptr) {
|
||||
sptr<EGLNativeTestSync> nts = new EGLNativeTestSync();
|
||||
nts->draw = drawFunc;
|
||||
nts->eglsurface = peglsurface;
|
||||
nts->width_ = width;
|
||||
nts->height_ = height;
|
||||
RequestSync(std::bind(&EGLNativeTestSync::Sync, nts, SYNC_FUNC_ARG), data);
|
||||
return nts;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void EGLNativeTestSync::Sync(int64_t, void *data)
|
||||
{
|
||||
if (!GLContextInit()) {
|
||||
printf("GLContextInit failed.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (sret == SURFACE_ERROR_OK) {
|
||||
draw(&glCtx, eglsurface, width_, height_);
|
||||
count++;
|
||||
}
|
||||
|
||||
sret = eglsurface->SwapBuffers();
|
||||
|
||||
RequestSync(std::bind(&EGLNativeTestSync::Sync, this, SYNC_FUNC_ARG), data);
|
||||
}
|
||||
|
||||
namespace {
|
||||
const char *g_vertShaderText =
|
||||
"uniform float offset;\n"
|
||||
"attribute vec4 pos;\n"
|
||||
"attribute vec4 color;\n"
|
||||
"varying vec4 v_color;\n"
|
||||
"void main() {\n"
|
||||
" gl_Position = pos + vec4(offset, offset, 0.0, 0.0);\n"
|
||||
" v_color = color;\n"
|
||||
"}\n";
|
||||
|
||||
const char *g_fragShaderText =
|
||||
"precision mediump float;\n"
|
||||
"varying vec4 v_color;\n"
|
||||
"void main() {\n"
|
||||
" gl_FragColor = v_color;\n"
|
||||
"}\n";
|
||||
|
||||
static GLuint CreateShader(const char *source, GLenum shaderType)
|
||||
{
|
||||
GLuint shader;
|
||||
GLint status;
|
||||
|
||||
shader = glCreateShader(shaderType);
|
||||
assert(shader != 0);
|
||||
|
||||
glShaderSource(shader, 1, (const char **) &source, NULL);
|
||||
glCompileShader(shader);
|
||||
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
|
||||
if (!status) {
|
||||
constexpr int32_t maxLogLength = 1000;
|
||||
char log[maxLogLength];
|
||||
GLsizei len;
|
||||
glGetShaderInfoLog(shader, maxLogLength, &len, log);
|
||||
fprintf(stderr, "Error: compiling %s: %.*s\n",
|
||||
shaderType == GL_VERTEX_SHADER ? "vertex" : "fragment", len, log);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
static GLuint CreateAndLinkProgram(GLuint vert, GLuint frag)
|
||||
{
|
||||
GLint status;
|
||||
GLuint program = glCreateProgram();
|
||||
|
||||
glAttachShader(program, vert);
|
||||
glAttachShader(program, frag);
|
||||
glLinkProgram(program);
|
||||
|
||||
glGetProgramiv(program, GL_LINK_STATUS, &status);
|
||||
if (!status) {
|
||||
constexpr int32_t maxLogLength = 1000;
|
||||
char log[maxLogLength];
|
||||
GLsizei len;
|
||||
glGetProgramInfoLog(program, maxLogLength, &len, log);
|
||||
fprintf(stderr, "Error: linking:\n%.*s\n", len, log);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return program;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
bool EGLNativeTestSync::GLContextInit()
|
||||
{
|
||||
if (bInit) {
|
||||
return bInit;
|
||||
}
|
||||
|
||||
if (eglsurface == nullptr) {
|
||||
printf("GLContextInit eglsurface is nullptr\n");
|
||||
return bInit;
|
||||
}
|
||||
|
||||
if (eglsurface->InitContext() != SURFACE_ERROR_OK) {
|
||||
printf("GLContextInit InitContext failed\n");
|
||||
return bInit;
|
||||
}
|
||||
|
||||
GLuint vert = CreateShader(g_vertShaderText, GL_VERTEX_SHADER);
|
||||
GLuint frag = CreateShader(g_fragShaderText, GL_FRAGMENT_SHADER);
|
||||
|
||||
glCtx.program = CreateAndLinkProgram(vert, frag);
|
||||
|
||||
glDeleteShader(vert);
|
||||
glDeleteShader(frag);
|
||||
|
||||
glCtx.pos = glGetAttribLocation(glCtx.program, "pos");
|
||||
glCtx.color = glGetAttribLocation(glCtx.program, "color");
|
||||
|
||||
glUseProgram(glCtx.program);
|
||||
|
||||
glCtx.offsetUniform = glGetUniformLocation(glCtx.program, "offset");
|
||||
|
||||
if (glCtx.program == 0) {
|
||||
printf("glCtx.program = 0.\n");
|
||||
} else {
|
||||
bInit = true;
|
||||
}
|
||||
return bInit;
|
||||
}
|
||||
|
||||
void EGLNativeTestDraw::FlushDraw(GLContext *ctx, sptr<EglSurface> &eglsurface, uint32_t width, uint32_t height)
|
||||
{
|
||||
/* Complete a movement iteration in 5000 ms. */
|
||||
static const GLfloat verts[][0x2] = {
|
||||
{ -0.5, -0.5 },
|
||||
{ -0.5, 0.5 },
|
||||
{ 0.5, -0.5 },
|
||||
{ 0.5, 0.5 }
|
||||
};
|
||||
static const GLfloat colors[][0x3] = {
|
||||
{ 1, 0, 0 },
|
||||
{ 0, 1, 0 },
|
||||
{ 0, 0, 1 },
|
||||
{ 1, 1, 0 }
|
||||
};
|
||||
|
||||
/* Split time_ms in repeating windows of [0, iterationMs) and map them
|
||||
* to offsets in the [-0.5, 0.5) range. */
|
||||
constexpr uint64_t iterationMs = 5000000000;
|
||||
GLfloat offset = (GetNowTime() % iterationMs) / static_cast<double>(iterationMs);
|
||||
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
glUniform1f(ctx->offsetUniform, offset - 0.5);
|
||||
|
||||
glClearColor(0.0, 1.0, 0.0, 1.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
constexpr int32_t sizePosVertexAttribute = 2;
|
||||
constexpr int32_t sizeColorsVertexAttribute = 3;
|
||||
glVertexAttribPointer(ctx->pos, sizePosVertexAttribute, GL_FLOAT, GL_FALSE, 0, verts);
|
||||
glVertexAttribPointer(ctx->color, sizeColorsVertexAttribute, GL_FLOAT, GL_FALSE, 0, colors);
|
||||
glEnableVertexAttribArray(ctx->pos);
|
||||
glEnableVertexAttribArray(ctx->color);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 0x4);
|
||||
|
||||
glDisableVertexAttribArray(ctx->pos);
|
||||
glDisableVertexAttribArray(ctx->color);
|
||||
}
|
||||
} // namespace OHOS
|
65
frameworks/wmtest/frameworks/egl_native_test_class.h
Normal file
65
frameworks/wmtest/frameworks/egl_native_test_class.h
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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 FRAMEWORKS_WMTEST_FRAMEWORKS_EGL_NATIVE_TEST_CLASS
|
||||
#define FRAMEWORKS_WMTEST_FRAMEWORKS_EGL_NATIVE_TEST_CLASS
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
|
||||
#include <refbase.h>
|
||||
#include <window_manager.h>
|
||||
|
||||
#include <egl_surface.h>
|
||||
#include <GLES2/gl2.h>
|
||||
#include <GLES2/gl2ext.h>
|
||||
|
||||
namespace OHOS {
|
||||
typedef struct {
|
||||
GLuint program;
|
||||
GLuint pos;
|
||||
GLuint color;
|
||||
GLuint offsetUniform;
|
||||
} GLContext;
|
||||
|
||||
using EGLDrawFunc = std::function<void(GLContext *,
|
||||
sptr<EglSurface> &psurface, uint32_t width, uint32_t height)>;
|
||||
|
||||
class EGLNativeTestSync : public RefBase {
|
||||
public:
|
||||
static sptr<EGLNativeTestSync> CreateSync(EGLDrawFunc drawFunc,
|
||||
sptr<EglSurface> &psurface, uint32_t width, uint32_t height, void *data = nullptr);
|
||||
|
||||
private:
|
||||
void Sync(int64_t, void *);
|
||||
bool GLContextInit();
|
||||
|
||||
sptr<EglSurface> eglsurface = nullptr;
|
||||
EGLDrawFunc draw = nullptr;
|
||||
GLContext glCtx;
|
||||
bool bInit = false;
|
||||
SurfaceError sret = SURFACE_ERROR_OK;
|
||||
uint32_t width_ = 0;
|
||||
uint32_t height_ = 0;
|
||||
};
|
||||
|
||||
class EGLNativeTestDraw {
|
||||
public:
|
||||
static void FlushDraw(GLContext *ctx, sptr<EglSurface> &eglsurface, uint32_t width, uint32_t height);
|
||||
};
|
||||
} // namespace OHOS
|
||||
|
||||
#endif // FRAMEWORKS_WMTEST_FRAMEWORKS_EGL_NATIVE_TEST_CLASS
|
@ -16,26 +16,157 @@
|
||||
#include "inative_test.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <codecvt>
|
||||
#include <gslogger.h>
|
||||
#include <sstream>
|
||||
#include <sys/shm.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <vector>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "inative_test_key_handler.h"
|
||||
#include "inative_test_touch_handler.h"
|
||||
#include "util.h"
|
||||
|
||||
namespace OHOS {
|
||||
void INativeTest::VisitTests(VisitTestFunc func)
|
||||
INativeTest *INativeTest::VisitTests(VisitTestFunc func)
|
||||
{
|
||||
auto sortFunc = [](const auto &it, const auto &jt) {
|
||||
if (it->GetDomain() == jt->GetDomain()) {
|
||||
if (it->GetDomain() != jt->GetDomain()) {
|
||||
return it->GetDomain() < jt->GetDomain();
|
||||
}
|
||||
if (it->GetID() != jt->GetID()) {
|
||||
return it->GetID() < jt->GetID();
|
||||
}
|
||||
return it->GetDomain() < jt->GetDomain();
|
||||
return it->GetProcessSequence() < jt->GetProcessSequence();
|
||||
};
|
||||
std::sort(tests.begin(), tests.end(), sortFunc);
|
||||
|
||||
for (auto &test : tests) {
|
||||
func(test);
|
||||
if (func(test)) {
|
||||
return test;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
INativeTest::INativeTest()
|
||||
{
|
||||
tests.push_back(this);
|
||||
keyHandler = new INativeTestKeyEventHandler(this);
|
||||
touchHandler = new INativeTestTouchEventHandler(this);
|
||||
}
|
||||
|
||||
uint32_t INativeTest::GetLastTime() const
|
||||
{
|
||||
return LAST_TIME_FOREVER;
|
||||
}
|
||||
|
||||
enum AutoLoadService operator |(const enum AutoLoadService &l, const enum AutoLoadService &r)
|
||||
{
|
||||
return static_cast<enum AutoLoadService>(static_cast<int32_t>(l) | static_cast<int32_t>(r));
|
||||
}
|
||||
|
||||
bool operator &(const enum AutoLoadService &l, const enum AutoLoadService &r)
|
||||
{
|
||||
return (static_cast<int32_t>(l) & static_cast<int32_t>(r)) != 0;
|
||||
}
|
||||
|
||||
enum AutoLoadService INativeTest::GetAutoLoadService() const
|
||||
{
|
||||
return AutoLoadService::Null;
|
||||
}
|
||||
|
||||
bool INativeTest::OnKey(const KeyEvent &event)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool INativeTest::OnTouch(const TouchEvent &event)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void INativeTest::GetToken()
|
||||
{
|
||||
if (token == nullptr) {
|
||||
std::stringstream ss;
|
||||
ss << GetDomain() << GetID() << GetProcessSequence();
|
||||
auto sss = ss.str();
|
||||
auto u16 = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t >().from_bytes(sss);
|
||||
token = new IPCObjectStub(u16);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t INativeTest::ListenWindowKeyEvent(int32_t windowID)
|
||||
{
|
||||
GetToken();
|
||||
return MMIEventHdl.RegisterStandardizedEventHandle(token, windowID, keyHandler);
|
||||
}
|
||||
|
||||
int32_t INativeTest::ListenWindowTouchEvent(int32_t windowID)
|
||||
{
|
||||
GetToken();
|
||||
return MMIEventHdl.RegisterStandardizedEventHandle(token, windowID, touchHandler);
|
||||
}
|
||||
|
||||
void INativeTest::ListenWindowInputEvent(int32_t windowID)
|
||||
{
|
||||
ListenWindowKeyEvent(windowID);
|
||||
ListenWindowTouchEvent(windowID);
|
||||
}
|
||||
|
||||
int32_t INativeTest::GetProcessNumber() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t INativeTest::GetProcessSequence() const
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t INativeTest::StartSubprocess(int32_t id)
|
||||
{
|
||||
GSLOG7SO(INFO) << "StartSubprocess " << id;
|
||||
auto pid = fork();
|
||||
if (pid < 0) {
|
||||
return pid;
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
std::vector<const char *> args;
|
||||
for (const char **p = processArgv; *p != nullptr; p++) {
|
||||
args.push_back(*p);
|
||||
}
|
||||
|
||||
std::stringstream ss;
|
||||
ss << "--process=" << id;
|
||||
auto sss = ss.str();
|
||||
args.push_back(sss.c_str());
|
||||
args.insert(args.end(), extraArgs.begin(), extraArgs.end());
|
||||
args.push_back(nullptr);
|
||||
auto ret = execvp(args[0], const_cast<char *const *>(args.data()));
|
||||
GSLOG7SO(ERROR) << "execvp return: " << ret << ", " << errno;
|
||||
ExitTest();
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void INativeTest::SetEventHandler(const std::shared_ptr<AppExecFwk::EventHandler> &handler)
|
||||
{
|
||||
this->handler = handler;
|
||||
}
|
||||
|
||||
void INativeTest::PostTask(std::function<void()> func, uint32_t delayTime) const
|
||||
{
|
||||
handler->PostTask(func, delayTime);
|
||||
}
|
||||
|
||||
void INativeTest::ExitTest() const
|
||||
{
|
||||
GSLOG7SO(INFO) << "exiting, call PostTask(&AppExecFwk::EventRunner::Stop)";
|
||||
PostTask(std::bind(&AppExecFwk::EventRunner::Stop, handler->GetEventRunner()));
|
||||
}
|
||||
} // namespace OHOS
|
||||
|
@ -21,9 +21,25 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <ipc_object_stub.h>
|
||||
#include <key_event_handler.h>
|
||||
#include <multimodal_event_handler.h>
|
||||
#include <touch_event_handler.h>
|
||||
#include <vsync_helper.h>
|
||||
#include <window_manager.h>
|
||||
#include <window_manager_service_client.h>
|
||||
|
||||
namespace OHOS {
|
||||
class INativeTest;
|
||||
using VisitTestFunc = std::function<void(INativeTest *)>;
|
||||
using VisitTestFunc = std::function<bool(INativeTest *)>;
|
||||
|
||||
enum class AutoLoadService : int32_t {
|
||||
Null = 0,
|
||||
WindowManager = 1 << 0,
|
||||
WindowManagerService = 1 << 1,
|
||||
};
|
||||
enum AutoLoadService operator |(const enum AutoLoadService &l, const enum AutoLoadService &r);
|
||||
bool operator &(const enum AutoLoadService &l, const enum AutoLoadService &r);
|
||||
|
||||
class INativeTest {
|
||||
public:
|
||||
@ -31,17 +47,48 @@ public:
|
||||
LAST_TIME_FOREVER = 999999999,
|
||||
};
|
||||
|
||||
static void VisitTests(VisitTestFunc func);
|
||||
static INativeTest *VisitTests(VisitTestFunc func);
|
||||
INativeTest();
|
||||
virtual ~INativeTest() = default;
|
||||
|
||||
virtual std::string GetDescription() const = 0;
|
||||
virtual std::string GetDomain() const = 0;
|
||||
virtual int32_t GetID() const = 0;
|
||||
virtual uint32_t GetLastTime() const = 0;
|
||||
virtual void Run(int32_t argc, const char **argv) = 0;
|
||||
virtual uint32_t GetLastTime() const;
|
||||
|
||||
// auto load service
|
||||
virtual enum AutoLoadService GetAutoLoadService() const;
|
||||
sptr<WindowManager> windowManager = nullptr;
|
||||
sptr<IWindowManagerService> windowManagerService = nullptr;
|
||||
|
||||
// input
|
||||
virtual bool OnKey(const KeyEvent &event);
|
||||
virtual bool OnTouch(const TouchEvent &event);
|
||||
void GetToken();
|
||||
int32_t ListenWindowKeyEvent(int32_t windowID);
|
||||
int32_t ListenWindowTouchEvent(int32_t windowID);
|
||||
void ListenWindowInputEvent(int32_t windowID); // key and touch
|
||||
|
||||
// multiple process
|
||||
virtual int32_t GetProcessNumber() const;
|
||||
virtual int32_t GetProcessSequence() const;
|
||||
|
||||
const char **processArgv = nullptr;
|
||||
std::vector<const char *> extraArgs;
|
||||
int32_t StartSubprocess(int32_t id);
|
||||
|
||||
// thread pool
|
||||
void SetEventHandler(const std::shared_ptr<AppExecFwk::EventHandler> &handler);
|
||||
void PostTask(std::function<void()> func, uint32_t delayTime = 0) const;
|
||||
void ExitTest() const;
|
||||
|
||||
private:
|
||||
static inline std::vector<INativeTest *> tests;
|
||||
std::shared_ptr<AppExecFwk::EventHandler> handler = nullptr;
|
||||
sptr<MMI::KeyEventHandler> keyHandler = nullptr;
|
||||
sptr<MMI::TouchEventHandler> touchHandler = nullptr;
|
||||
sptr<IRemoteObject> token = nullptr;
|
||||
};
|
||||
} // namespace OHOS
|
||||
|
||||
|
42
frameworks/wmtest/frameworks/inative_test_key_handler.h
Normal file
42
frameworks/wmtest/frameworks/inative_test_key_handler.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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 FRAMEWORKS_WM_SRC_TEST_INATIVE_TEST_KEY_EVENT_HANDLER_H
|
||||
#define FRAMEWORKS_WM_SRC_TEST_INATIVE_TEST_KEY_EVENT_HANDLER_H
|
||||
|
||||
#include <graphic_bytrace.h>
|
||||
|
||||
#include "inative_test.h"
|
||||
|
||||
namespace OHOS {
|
||||
class INativeTest;
|
||||
class INativeTestKeyEventHandler : public MMI::KeyEventHandler {
|
||||
public:
|
||||
explicit INativeTestKeyEventHandler(INativeTest *test) : test_(test)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool OnKey(const KeyEvent &event) override
|
||||
{
|
||||
ScopedBytrace trace(__func__);
|
||||
return test_->OnKey(event);
|
||||
}
|
||||
|
||||
private:
|
||||
INativeTest *test_ = nullptr;
|
||||
};
|
||||
} // namespace OHOS
|
||||
|
||||
#endif // FRAMEWORKS_WM_SRC_TEST_INATIVE_TEST_KEY_EVENT_HANDLER_H
|
42
frameworks/wmtest/frameworks/inative_test_touch_handler.h
Normal file
42
frameworks/wmtest/frameworks/inative_test_touch_handler.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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 FRAMEWORKS_WM_SRC_TEST_INATIVE_TEST_TOUCH_EVENT_HANDLER_H
|
||||
#define FRAMEWORKS_WM_SRC_TEST_INATIVE_TEST_TOUCH_EVENT_HANDLER_H
|
||||
|
||||
#include <graphic_bytrace.h>
|
||||
|
||||
#include "inative_test.h"
|
||||
|
||||
namespace OHOS {
|
||||
class INativeTest;
|
||||
class INativeTestTouchEventHandler : public MMI::TouchEventHandler {
|
||||
public:
|
||||
explicit INativeTestTouchEventHandler(INativeTest *test) : test_(test)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool OnTouch(const TouchEvent &event) override
|
||||
{
|
||||
ScopedBytrace trace(__func__);
|
||||
return test_->OnTouch(event);
|
||||
}
|
||||
|
||||
private:
|
||||
INativeTest *test_ = nullptr;
|
||||
};
|
||||
} // namespace OHOS
|
||||
|
||||
#endif // FRAMEWORKS_WM_SRC_TEST_INATIVE_TEST_TOUCH_EVENT_HANDLER_H
|
@ -20,6 +20,7 @@
|
||||
#include <unistd.h>
|
||||
#include <vector>
|
||||
|
||||
#include <gslogger.h>
|
||||
#include <vsync_helper.h>
|
||||
#include <window_manager.h>
|
||||
|
||||
@ -32,10 +33,14 @@ using namespace OHOS;
|
||||
namespace {
|
||||
void Usage(const char *argv0)
|
||||
{
|
||||
std::cerr << "Usage: " << argv0 << " [option] type id" << std::endl;
|
||||
std::cerr << "-d, --display[=0] Created Window's Display ID" << std::endl;
|
||||
GSLOG0SE(INFO) << "Usage: " << argv0 << " [option] type id";
|
||||
GSLOG0SE(INFO) << " Option:";
|
||||
GSLOG0SE(INFO) << " -d, --display[=0] Created Window's Display ID";
|
||||
GSLOG0SE(INFO) << "";
|
||||
GSLOG0SE(INFO) << " Available Tests: type, id, description (time) [process]";
|
||||
auto visitFunc = [](const INativeTest *test) {
|
||||
std::stringstream ss;
|
||||
ss << " ";
|
||||
ss << test->GetDomain() << ", id=";
|
||||
ss << test->GetID() << ": ";
|
||||
ss << test->GetDescription();
|
||||
@ -43,10 +48,69 @@ void Usage(const char *argv0)
|
||||
constexpr double msecToSec = 1000.0;
|
||||
ss << " (last " << std::setprecision(1) << test->GetLastTime() / msecToSec << "s)";
|
||||
}
|
||||
std::cout << ss.str() << std::endl;
|
||||
|
||||
if (test->GetProcessNumber() <= 1) {
|
||||
GSLOG0SE(INFO) << ss.str();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (test->GetProcessSequence() == -1) {
|
||||
ss << " [process number:" << test->GetProcessNumber() << "]";
|
||||
GSLOG0SE(INFO) << ss.str();
|
||||
return false;
|
||||
}
|
||||
|
||||
ss << " [" << test->GetProcessSequence() << "/" << test->GetProcessNumber() << "]";
|
||||
auto sss = ss.str();
|
||||
auto size = sss.find_first_of(':') + 1;
|
||||
sss.erase(0, size);
|
||||
sss.insert(sss.begin(), size, ' ');
|
||||
GSLOG0SE(INFO) << sss;
|
||||
return false;
|
||||
};
|
||||
INativeTest::VisitTests(visitFunc);
|
||||
}
|
||||
|
||||
bool GetTestFunc(INativeTest *test, MainOption &option)
|
||||
{
|
||||
if (test->GetDomain() != option.domain) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (test->GetID() != option.testcase) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (test->GetProcessSequence() != option.processSequence) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
int32_t LoadService(INativeTest *test)
|
||||
{
|
||||
if (test->GetAutoLoadService() & AutoLoadService::WindowManager) {
|
||||
test->windowManager = WindowManager::GetInstance();
|
||||
auto wret = test->windowManager->Init();
|
||||
if (wret) {
|
||||
GSLOG7SO(ERROR) << "WindowManager Init failed with " << WMErrorStr(wret);
|
||||
return wret;
|
||||
}
|
||||
}
|
||||
|
||||
if (test->GetAutoLoadService() & AutoLoadService::WindowManagerService) {
|
||||
auto wmsc = WindowManagerServiceClient::GetInstance();
|
||||
auto wret = wmsc->Init();
|
||||
if (wret) {
|
||||
GSLOG7SO(ERROR) << "WindowManagerServiceClient Init failed with " << WMErrorStr(wret);
|
||||
return wret;
|
||||
}
|
||||
test->windowManagerService = wmsc->GetService();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
int32_t main(int32_t argc, const char **argv)
|
||||
@ -54,36 +118,38 @@ int32_t main(int32_t argc, const char **argv)
|
||||
// parse option
|
||||
MainOption option;
|
||||
if (option.Parse(argc, argv)) {
|
||||
std::cerr << option.GetErrorString() << std::endl;
|
||||
GSLOG0SE(ERROR) << option.GetErrorString() << std::endl;
|
||||
Usage(argv[0]);
|
||||
GSLOG7SE(ERROR) << "exiting, return 1";
|
||||
return 1;
|
||||
}
|
||||
|
||||
// find test
|
||||
INativeTest *found = nullptr;
|
||||
auto visitFunc = [&option, &found](INativeTest *test) {
|
||||
if (test->GetDomain() == option.domain && test->GetID() == option.testcase) {
|
||||
found = test;
|
||||
}
|
||||
};
|
||||
INativeTest::VisitTests(visitFunc);
|
||||
auto visitFunc = std::bind(GetTestFunc, std::placeholders::_1, std::ref(option));
|
||||
INativeTest *found = INativeTest::VisitTests(visitFunc);
|
||||
if (found == nullptr) {
|
||||
printf("not found test %d\n", option.testcase);
|
||||
GSLOG7SE(ERROR) << "not found test " << option.testcase << ", exiting, return 1";
|
||||
return 1;
|
||||
}
|
||||
|
||||
// default value assign
|
||||
NativeTestFactory::defaultDisplayID = option.displayID;
|
||||
found->processArgv = argv;
|
||||
if (LoadService(found)) {
|
||||
GSLOG7SE(ERROR) << "exiting, return 1";
|
||||
return 1;
|
||||
}
|
||||
|
||||
// run test
|
||||
auto runner = AppExecFwk::EventRunner::Create(false);
|
||||
auto handler = std::make_shared<AppExecFwk::EventHandler>(runner);
|
||||
handler->PostTask(std::bind(&INativeTest::Run, found, option.GetSkippedArgc(), option.GetSkippedArgv()));
|
||||
found->SetEventHandler(std::move(std::make_shared<AppExecFwk::EventHandler>(runner)));
|
||||
found->PostTask(std::bind(&INativeTest::Run, found, option.GetSkippedArgc(), option.GetSkippedArgv()));
|
||||
if (found->GetLastTime() != INativeTest::LAST_TIME_FOREVER) {
|
||||
handler->PostTask(std::bind(&AppExecFwk::EventRunner::Stop, runner), found->GetLastTime());
|
||||
found->PostTask(std::bind(&AppExecFwk::EventRunner::Stop, runner), found->GetLastTime());
|
||||
}
|
||||
|
||||
printf("%d %s run! pid=%d\n", found->GetID(), found->GetDescription().c_str(), getpid());
|
||||
runner->Run();
|
||||
GSLOG7SO(INFO) << "exiting, return 0";
|
||||
return 0;
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ MainOption::MainOption()
|
||||
AddArguments(domain);
|
||||
AddArguments(testcase);
|
||||
AddOption("d", "display", displayID);
|
||||
AddOption("p", "process", processSequence);
|
||||
}
|
||||
|
||||
int32_t MainOption::Parse(int32_t argc, const char **argv)
|
||||
|
@ -27,6 +27,7 @@ public:
|
||||
std::string domain = "";
|
||||
int32_t testcase = -1;
|
||||
int32_t displayID = 0;
|
||||
int32_t processSequence = -1;
|
||||
};
|
||||
|
||||
#endif // FRAMEWORKS_WMTEST_FRAMEWORKS_MAIN_OPTION_H
|
||||
|
@ -18,20 +18,15 @@
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
#include <securec.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <display_type.h>
|
||||
#include <graphic_bytrace.h>
|
||||
#include <securec.h>
|
||||
|
||||
#include "inative_test.h"
|
||||
#include "util.h"
|
||||
|
||||
#define TIME_BASE 1000
|
||||
#define TIMEMS_RANGER 0.5
|
||||
#define SIZE_POS_VERTEX_ATTRIBUTE 2
|
||||
#define SIZE_COLORS_VERTEX_ATTRIBUTE 3
|
||||
#define NUMBER_VERTICES 4
|
||||
|
||||
namespace OHOS {
|
||||
sptr<Window> NativeTestFactory::CreateWindow(WindowType type,
|
||||
sptr<Surface> csurface,
|
||||
@ -72,149 +67,9 @@ sptr<NativeTestSync> NativeTestSync::CreateSync(DrawFunc drawFunc, sptr<Surface>
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#ifdef ACE_ENABLE_GPU
|
||||
sptr<NativeTestSync> NativeTestSync::CreateSyncEgl(DrawFuncEgl drawFunc,
|
||||
sptr<EglSurface> &peglsurface, uint32_t width, uint32_t height, void *data)
|
||||
{
|
||||
if (drawFunc != nullptr && peglsurface != nullptr) {
|
||||
sptr<NativeTestSync> nts = new NativeTestSync();
|
||||
nts->drawEgl = drawFunc;
|
||||
nts->eglsurface = peglsurface;
|
||||
nts->width_ = width;
|
||||
nts->height_ = height;
|
||||
RequestSync(std::bind(&NativeTestSync::SyncEgl, nts, SYNC_FUNC_ARG), data);
|
||||
return nts;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void NativeTestSync::SyncEgl(int64_t, void *data)
|
||||
{
|
||||
if (!GLContextInit()) {
|
||||
printf("GLContextInit failed.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (sret == SURFACE_ERROR_OK) {
|
||||
drawEgl(&glCtx, eglsurface, width_, height_);
|
||||
count++;
|
||||
}
|
||||
|
||||
sret = eglsurface->SwapBuffers();
|
||||
|
||||
RequestSync(std::bind(&NativeTestSync::SyncEgl, this, SYNC_FUNC_ARG), data);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ACE_ENABLE_GPU
|
||||
namespace {
|
||||
const char *g_vertShaderText =
|
||||
"uniform float offset;\n"
|
||||
"attribute vec4 pos;\n"
|
||||
"attribute vec4 color;\n"
|
||||
"varying vec4 v_color;\n"
|
||||
"void main() {\n"
|
||||
" gl_Position = pos + vec4(offset, offset, 0.0, 0.0);\n"
|
||||
" v_color = color;\n"
|
||||
"}\n";
|
||||
|
||||
const char *g_fragShaderText =
|
||||
"precision mediump float;\n"
|
||||
"varying vec4 v_color;\n"
|
||||
"void main() {\n"
|
||||
" gl_FragColor = v_color;\n"
|
||||
"}\n";
|
||||
|
||||
static GLuint CreateShader(const char *source, GLenum shaderType)
|
||||
{
|
||||
GLuint shader;
|
||||
GLint status;
|
||||
|
||||
shader = glCreateShader(shaderType);
|
||||
assert(shader != 0);
|
||||
|
||||
glShaderSource(shader, 1, (const char **) &source, NULL);
|
||||
glCompileShader(shader);
|
||||
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
|
||||
if (!status) {
|
||||
constexpr int32_t maxLogLength = 1000;
|
||||
char log[maxLogLength];
|
||||
GLsizei len;
|
||||
glGetShaderInfoLog(shader, maxLogLength, &len, log);
|
||||
fprintf(stderr, "Error: compiling %s: %.*s\n",
|
||||
shaderType == GL_VERTEX_SHADER ? "vertex" : "fragment", len, log);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
static GLuint CreateAndLinkProgram(GLuint vert, GLuint frag)
|
||||
{
|
||||
GLint status;
|
||||
GLuint program = glCreateProgram();
|
||||
|
||||
glAttachShader(program, vert);
|
||||
glAttachShader(program, frag);
|
||||
glLinkProgram(program);
|
||||
|
||||
glGetProgramiv(program, GL_LINK_STATUS, &status);
|
||||
if (!status) {
|
||||
constexpr int32_t maxLogLength = 1000;
|
||||
char log[maxLogLength];
|
||||
GLsizei len;
|
||||
glGetProgramInfoLog(program, maxLogLength, &len, log);
|
||||
fprintf(stderr, "Error: linking:\n%.*s\n", len, log);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return program;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
bool NativeTestSync::GLContextInit()
|
||||
{
|
||||
if (bInit) {
|
||||
return bInit;
|
||||
}
|
||||
|
||||
if (eglsurface == nullptr) {
|
||||
printf("GLContextInit eglsurface is nullptr\n");
|
||||
return bInit;
|
||||
}
|
||||
|
||||
if (eglsurface->InitContext() != SURFACE_ERROR_OK) {
|
||||
printf("GLContextInit InitContext failed\n");
|
||||
return bInit;
|
||||
}
|
||||
|
||||
GLuint vert = CreateShader(g_vertShaderText, GL_VERTEX_SHADER);
|
||||
GLuint frag = CreateShader(g_fragShaderText, GL_FRAGMENT_SHADER);
|
||||
|
||||
glCtx.program = CreateAndLinkProgram(vert, frag);
|
||||
|
||||
glDeleteShader(vert);
|
||||
glDeleteShader(frag);
|
||||
|
||||
glCtx.pos = glGetAttribLocation(glCtx.program, "pos");
|
||||
glCtx.color = glGetAttribLocation(glCtx.program, "color");
|
||||
|
||||
glUseProgram(glCtx.program);
|
||||
|
||||
glCtx.offsetUniform = glGetUniformLocation(glCtx.program, "offset");
|
||||
|
||||
if (glCtx.program == 0) {
|
||||
printf("glCtx.program = 0.\n");
|
||||
} else {
|
||||
bInit = true;
|
||||
}
|
||||
return bInit;
|
||||
}
|
||||
#endif
|
||||
|
||||
void NativeTestSync::Sync(int64_t, void *data)
|
||||
{
|
||||
ScopedBytrace trace(__func__);
|
||||
if (surface == nullptr) {
|
||||
printf("NativeTestSync surface is nullptr\n");
|
||||
return;
|
||||
@ -256,6 +111,77 @@ void NativeTestSync::Sync(int64_t, void *data)
|
||||
RequestSync(std::bind(&NativeTestSync::Sync, this, SYNC_FUNC_ARG), data);
|
||||
}
|
||||
|
||||
sptr<NativeTestDrawer> NativeTestDrawer::CreateDrawer(DrawFunc drawFunc, sptr<Surface> &psurface, void *data)
|
||||
{
|
||||
if (drawFunc != nullptr && psurface != nullptr) {
|
||||
sptr<NativeTestDrawer> ntd = new NativeTestDrawer();
|
||||
ntd->draw = drawFunc;
|
||||
ntd->surface = psurface;
|
||||
ntd->data = data;
|
||||
return ntd;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void NativeTestDrawer::SetDrawFunc(DrawFunc draw)
|
||||
{
|
||||
this->draw = draw;
|
||||
}
|
||||
|
||||
void NativeTestDrawer::DrawOnce()
|
||||
{
|
||||
if (isDrawing == false) {
|
||||
RequestSync(std::bind(&NativeTestDrawer::Sync, this, SYNC_FUNC_ARG), data);
|
||||
isDrawing = true;
|
||||
}
|
||||
}
|
||||
|
||||
void NativeTestDrawer::Sync(int64_t, void *data)
|
||||
{
|
||||
ScopedBytrace trace(__func__);
|
||||
if (surface == nullptr) {
|
||||
printf("NativeTestDrawer surface is nullptr\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (isDrawing == true) {
|
||||
isDrawing = false;
|
||||
}
|
||||
|
||||
sptr<SurfaceBuffer> buffer;
|
||||
BufferRequestConfig rconfig = {
|
||||
.width = surface->GetDefaultWidth(),
|
||||
.height = surface->GetDefaultHeight(),
|
||||
.strideAlignment = 0x8,
|
||||
.format = PIXEL_FMT_RGBA_8888,
|
||||
.usage = surface->GetDefaultUsage(),
|
||||
.timeout = 0,
|
||||
};
|
||||
if (data != nullptr) {
|
||||
rconfig = *reinterpret_cast<BufferRequestConfig *>(data);
|
||||
}
|
||||
|
||||
SurfaceError ret = surface->RequestBufferNoFence(buffer, rconfig);
|
||||
if (ret == SURFACE_ERROR_NO_BUFFER) {
|
||||
DrawOnce();
|
||||
return;
|
||||
} else if (ret != SURFACE_ERROR_OK || buffer == nullptr) {
|
||||
printf("NativeTestDrawer surface request buffer failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
draw(buffer->GetVirAddr(), rconfig.width, rconfig.height, count);
|
||||
count++;
|
||||
|
||||
BufferFlushConfig fconfig = {
|
||||
.damage = {
|
||||
.w = rconfig.width,
|
||||
.h = rconfig.height,
|
||||
},
|
||||
};
|
||||
surface->FlushBuffer(buffer, -1, fconfig);
|
||||
}
|
||||
|
||||
void NativeTestDraw::FlushDraw(void *vaddr, uint32_t width, uint32_t height, uint32_t count)
|
||||
{
|
||||
auto addr = static_cast<uint8_t *>(vaddr);
|
||||
@ -379,8 +305,7 @@ void NativeTestDraw::RainbowDraw(void *vaddr, uint32_t width, uint32_t height, u
|
||||
(func(index + rOffset * (height / 0x6)) << rShift);
|
||||
};
|
||||
|
||||
constexpr uint32_t framerate = 100;
|
||||
uint32_t offset = (count % framerate) * height / framerate;
|
||||
uint32_t offset = (count % RainbowDrawFramerate) * height / RainbowDrawFramerate;
|
||||
for (uint32_t i = 0; i < height; i++) {
|
||||
auto color = selectColor(offset + i);
|
||||
drawOneLine(i, color);
|
||||
@ -440,50 +365,16 @@ void NativeTestDraw::BoxDraw(void *vaddr, uint32_t width, uint32_t height, uint3
|
||||
drawOnce(abs((count + 1) % (framecount * 0x2 - 1) - framecount), color);
|
||||
}
|
||||
|
||||
#ifdef ACE_ENABLE_GPU
|
||||
void NativeTestDraw::FlushDrawEgl(GlContext *ctx, sptr<EglSurface> &eglsurface, uint32_t width, uint32_t height)
|
||||
void NativeTestDraw::PureColorDraw(void *vaddr, uint32_t width, uint32_t height, uint32_t count, uint32_t *color)
|
||||
{
|
||||
/* Complete a movement iteration in 5000 ms. */
|
||||
static const uint64_t iterationMs = 5000;
|
||||
static const GLfloat verts[4][2] = {
|
||||
{ -0.5, -0.5 },
|
||||
{ -0.5, 0.5 },
|
||||
{ 0.5, -0.5 },
|
||||
{ 0.5, 0.5 }
|
||||
};
|
||||
static const GLfloat colors[4][3] = {
|
||||
{ 1, 0, 0 },
|
||||
{ 0, 1, 0 },
|
||||
{ 0, 0, 1 },
|
||||
{ 1, 1, 0 }
|
||||
};
|
||||
GLfloat offset;
|
||||
struct timeval tv;
|
||||
uint64_t timeMs;
|
||||
auto addr = static_cast<uint32_t *>(vaddr);
|
||||
if (addr == nullptr || color == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
timeMs = tv.tv_sec * TIME_BASE + tv.tv_usec / TIME_BASE;
|
||||
|
||||
/* Split time_ms in repeating windows of [0, iterationMs) and map them
|
||||
* to offsets in the [-0.5, 0.5) range. */
|
||||
offset = (timeMs % iterationMs) / (float) iterationMs - TIMEMS_RANGER;
|
||||
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
glUniform1f(ctx->offsetUniform, offset);
|
||||
|
||||
glClearColor(0.0, 1.0, 0.0, 1.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glVertexAttribPointer(ctx->pos, SIZE_POS_VERTEX_ATTRIBUTE, GL_FLOAT, GL_FALSE, 0, verts);
|
||||
glVertexAttribPointer(ctx->color, SIZE_COLORS_VERTEX_ATTRIBUTE, GL_FLOAT, GL_FALSE, 0, colors);
|
||||
glEnableVertexAttribArray(ctx->pos);
|
||||
glEnableVertexAttribArray(ctx->color);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, NUMBER_VERTICES);
|
||||
|
||||
glDisableVertexAttribArray(ctx->pos);
|
||||
glDisableVertexAttribArray(ctx->color);
|
||||
uint32_t c = *color;
|
||||
for (uint32_t i = 0; i < width * height; i++) {
|
||||
addr[i] = c;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} // namespace OHOS
|
||||
|
@ -23,21 +23,7 @@
|
||||
#include <refbase.h>
|
||||
#include <window_manager.h>
|
||||
|
||||
#ifdef ACE_ENABLE_GPU
|
||||
#include <egl_surface.h>
|
||||
#include <GLES2/gl2.h>
|
||||
#include <GLES2/gl2ext.h>
|
||||
#endif
|
||||
|
||||
namespace OHOS {
|
||||
#ifdef ACE_ENABLE_GPU
|
||||
typedef struct {
|
||||
GLuint program;
|
||||
GLuint pos;
|
||||
GLuint color;
|
||||
GLuint offsetUniform;
|
||||
} GlContext;
|
||||
#endif
|
||||
|
||||
class NativeTestFactory {
|
||||
public:
|
||||
@ -48,18 +34,9 @@ public:
|
||||
};
|
||||
|
||||
using DrawFunc = std::function<void(void *, uint32_t, uint32_t, uint32_t)>;
|
||||
#ifdef ACE_ENABLE_GPU
|
||||
using DrawFuncEgl = std::function<void(GlContext *,
|
||||
sptr<EglSurface> &psurface, uint32_t width, uint32_t height)>;
|
||||
#endif
|
||||
|
||||
class NativeTestSync : public RefBase {
|
||||
public:
|
||||
static sptr<NativeTestSync> CreateSync(DrawFunc drawFunc, sptr<Surface> &psurface, void *data = nullptr);
|
||||
#ifdef ACE_ENABLE_GPU
|
||||
static sptr<NativeTestSync> CreateSyncEgl(DrawFuncEgl drawFunc,
|
||||
sptr<EglSurface> &psurface, uint32_t width, uint32_t height, void *data = nullptr);
|
||||
#endif
|
||||
|
||||
private:
|
||||
void Sync(int64_t, void *);
|
||||
@ -67,18 +44,24 @@ private:
|
||||
sptr<Surface> surface = nullptr;
|
||||
DrawFunc draw = nullptr;
|
||||
uint32_t count = 0;
|
||||
};
|
||||
|
||||
#ifdef ACE_ENABLE_GPU
|
||||
void SyncEgl(int64_t, void *);
|
||||
bool GLContextInit();
|
||||
sptr<EglSurface> eglsurface = nullptr;
|
||||
DrawFuncEgl drawEgl = nullptr;
|
||||
GlContext glCtx;
|
||||
bool bInit = false;
|
||||
SurfaceError sret = SURFACE_ERROR_OK;
|
||||
uint32_t width_ = 0;
|
||||
uint32_t height_ = 0;
|
||||
#endif
|
||||
class NativeTestDrawer : public RefBase {
|
||||
public:
|
||||
static sptr<NativeTestDrawer> CreateDrawer(DrawFunc drawFunc, sptr<Surface> &psurface, void *data = nullptr);
|
||||
|
||||
void SetDrawFunc(DrawFunc draw);
|
||||
|
||||
void DrawOnce();
|
||||
|
||||
private:
|
||||
void Sync(int64_t, void *);
|
||||
|
||||
sptr<Surface> surface = nullptr;
|
||||
DrawFunc draw = nullptr;
|
||||
uint32_t count = 0;
|
||||
bool isDrawing = false;
|
||||
void *data = nullptr;
|
||||
};
|
||||
|
||||
class NativeTestDraw {
|
||||
@ -87,10 +70,9 @@ public:
|
||||
static void ColorDraw(void *vaddr, uint32_t width, uint32_t height, uint32_t count);
|
||||
static void BlackDraw(void *vaddr, uint32_t width, uint32_t height, uint32_t count);
|
||||
static void RainbowDraw(void *vaddr, uint32_t width, uint32_t height, uint32_t count);
|
||||
static inline constexpr int32_t RainbowDrawFramerate = 100;
|
||||
static void BoxDraw(void *vaddr, uint32_t width, uint32_t height, uint32_t count);
|
||||
#ifdef ACE_ENABLE_GPU
|
||||
static void FlushDrawEgl(GlContext *ctx, sptr<EglSurface> &eglsurface, uint32_t width, uint32_t height);
|
||||
#endif
|
||||
static void PureColorDraw(void *vaddr, uint32_t width, uint32_t height, uint32_t count, uint32_t *color);
|
||||
};
|
||||
} // namespace OHOS
|
||||
|
||||
|
@ -19,6 +19,8 @@
|
||||
#include <thread>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <gslogger.h>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
namespace OHOS {
|
||||
@ -42,26 +44,6 @@ uint32_t RequestSync(const SyncFunc syncFunc, void *data)
|
||||
return VsyncHelper::Current()->RequestFrameCallback(cb);
|
||||
}
|
||||
|
||||
void PostTask(std::function<void()> func, uint32_t delayTime)
|
||||
{
|
||||
auto handler = AppExecFwk::EventHandler::Current();
|
||||
if (handler) {
|
||||
handler->PostTask(func, delayTime);
|
||||
}
|
||||
}
|
||||
|
||||
void ExitTest()
|
||||
{
|
||||
auto runner = AppExecFwk::EventRunner::Current();
|
||||
if (runner) {
|
||||
printf("exiting\n");
|
||||
PostTask(std::bind(&AppExecFwk::EventRunner::Stop, runner));
|
||||
} else {
|
||||
printf("exit\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
int64_t GetNowTime()
|
||||
{
|
||||
auto now = std::chrono::steady_clock::now().time_since_epoch();
|
||||
|
@ -24,8 +24,6 @@
|
||||
namespace OHOS {
|
||||
void SetVsyncRate(int32_t rate);
|
||||
uint32_t RequestSync(const SyncFunc syncFunc, void *data = nullptr);
|
||||
void PostTask(std::function<void()> func, uint32_t delayTime = 0);
|
||||
void ExitTest();
|
||||
int64_t GetNowTime();
|
||||
} // namespace OHOS
|
||||
|
||||
|
@ -60,7 +60,7 @@ public:
|
||||
int32_t signals[] = {SIGINT, SIGKILL, SIGTERM, SIGTSTP, SIGQUIT, SIGHUP};
|
||||
for (uint32_t i = 0; i < sizeof(signals) / sizeof(*signals); i++) {
|
||||
if (signals[i] == signal) {
|
||||
ExitTest();
|
||||
exit(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ public:
|
||||
auto subpsurface = subwindow->GetSurface();
|
||||
config.width = subpsurface->GetDefaultWidth();
|
||||
config.height = subpsurface->GetDefaultHeight();
|
||||
config.strideAlignment = 0x8,
|
||||
config.strideAlignment = 0x8;
|
||||
config.format = PIXEL_FMT_RGBA_8888;
|
||||
config.usage = subpsurface->GetDefaultUsage();
|
||||
subwindowSync = NativeTestSync::CreateSync(NativeTestDraw::RainbowDraw, subpsurface, &config);
|
||||
|
@ -119,13 +119,28 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
window->SwitchTop();
|
||||
auto onSizeChange = [this](uint32_t w, uint32_t h) {
|
||||
printf("onSizeChange %u %u\n", w, h);
|
||||
config.width = w;
|
||||
config.height = h;
|
||||
window->Resize(w, h);
|
||||
};
|
||||
window->OnSizeChange(onSizeChange);
|
||||
|
||||
auto surface = window->GetSurface();
|
||||
windowSync = NativeTestSync::CreateSync(NativeTestDraw::FlushDraw, surface);
|
||||
config.width = surface->GetDefaultWidth();
|
||||
config.height = surface->GetDefaultHeight();
|
||||
config.strideAlignment = 0x8;
|
||||
config.format = PIXEL_FMT_RGBA_8888;
|
||||
config.usage = surface->GetDefaultUsage();
|
||||
|
||||
window->SwitchTop();
|
||||
windowSync = NativeTestSync::CreateSync(NativeTestDraw::FlushDraw, surface, &config);
|
||||
}
|
||||
|
||||
private:
|
||||
sptr<Window> window = nullptr;
|
||||
sptr<NativeTestSync> windowSync = nullptr;
|
||||
BufferRequestConfig config = {};
|
||||
} g_autoload;
|
||||
} // namespace
|
||||
|
441
frameworks/wmtest/test/wmclient_native_test_20.cpp
Normal file
441
frameworks/wmtest/test/wmclient_native_test_20.cpp
Normal file
@ -0,0 +1,441 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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 "wmclient_native_test_20.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <cstdio>
|
||||
#include <sstream>
|
||||
#include <thread>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <cpudraw.h>
|
||||
#include <graphic_bytrace.h>
|
||||
#include <gslogger.h>
|
||||
#include <ipc_object_stub.h>
|
||||
#include <option_parser.h>
|
||||
#include <window_manager.h>
|
||||
#include <window_manager_service_client.h>
|
||||
|
||||
#include "inative_test.h"
|
||||
#include "native_test_class.h"
|
||||
#include "util.h"
|
||||
|
||||
using namespace OHOS;
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
namespace {
|
||||
class WMClientNativeTest20 : public INativeTest {
|
||||
public:
|
||||
virtual std::string GetDescription() const override
|
||||
{
|
||||
constexpr const char *desc = "split mode";
|
||||
return desc;
|
||||
}
|
||||
|
||||
virtual std::string GetDomain() const override
|
||||
{
|
||||
constexpr const char *domain = "wmclient";
|
||||
return domain;
|
||||
}
|
||||
|
||||
virtual int32_t GetID() const override
|
||||
{
|
||||
constexpr int32_t id = 20;
|
||||
return id;
|
||||
}
|
||||
|
||||
virtual enum AutoLoadService GetAutoLoadService() const override
|
||||
{
|
||||
return AutoLoadService::WindowManager;
|
||||
}
|
||||
|
||||
virtual int32_t GetProcessNumber() const override
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
virtual void Run(int32_t argc, const char **argv) override
|
||||
{
|
||||
GSLOG7SO(INFO) << "fork return: " << StartSubprocess(0);
|
||||
GSLOG7SO(INFO) << "fork return: " << StartSubprocess(1);
|
||||
ExitTest();
|
||||
}
|
||||
} g_autoload;
|
||||
|
||||
class WMClientNativeTest20Sub0 : public WMClientNativeTest20 {
|
||||
public:
|
||||
virtual std::string GetDescription() const override
|
||||
{
|
||||
constexpr const char *desc = "splited application mocker";
|
||||
return desc;
|
||||
}
|
||||
|
||||
virtual int32_t GetProcessSequence() const override
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void Run(int32_t argc, const char **argv) override
|
||||
{
|
||||
ScopedBytrace trace(__func__);
|
||||
GSLOG7SO(INFO) << getpid() << " run0";
|
||||
window = NativeTestFactory::CreateWindow(WINDOW_TYPE_NORMAL);
|
||||
if (window == nullptr) {
|
||||
GSLOG7SO(ERROR) << "NativeTestFactory::CreateWindow return nullptr";
|
||||
ExitTest();
|
||||
return;
|
||||
}
|
||||
|
||||
auto onSizeChange = [this](uint32_t w, uint32_t h) {
|
||||
GSLOG7SO(INFO) << "onSizeChange " << w << "x" << h;
|
||||
config.width = w;
|
||||
config.height = h;
|
||||
window->Resize(w, h);
|
||||
PostTask(std::bind(&NativeTestDrawer::DrawOnce, windowDrawer));
|
||||
};
|
||||
window->OnSizeChange(onSizeChange);
|
||||
auto func = std::bind(&WMClientNativeTest20Sub0::OnSplitStatusChange, this, std::placeholders::_1);
|
||||
window->OnSplitStatusChange(func);
|
||||
ListenWindowInputEvent(window->GetID());
|
||||
|
||||
auto surface = window->GetSurface();
|
||||
config.width = surface->GetDefaultWidth();
|
||||
config.height = surface->GetDefaultHeight();
|
||||
config.strideAlignment = 0x8;
|
||||
config.format = PIXEL_FMT_RGBA_8888;
|
||||
config.usage = surface->GetDefaultUsage();
|
||||
|
||||
window->SwitchTop();
|
||||
auto draw = std::bind(&WMClientNativeTest20Sub0::Draw, this,
|
||||
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4);
|
||||
windowDrawer = NativeTestDrawer::CreateDrawer(draw, surface, &config);
|
||||
windowDrawer->DrawOnce();
|
||||
}
|
||||
|
||||
void Draw(void *vaddr, uint32_t width, uint32_t height, uint32_t count)
|
||||
{
|
||||
ScopedBytrace trace(__func__);
|
||||
count = NativeTestDraw::RainbowDrawFramerate / 0x2;
|
||||
if (adjStatus == SPLIT_STATUS_CLEAR) {
|
||||
count = 0;
|
||||
}
|
||||
|
||||
NativeTestDraw::RainbowDraw(vaddr, width, height, count);
|
||||
}
|
||||
|
||||
virtual bool OnKey(const KeyEvent &event) override
|
||||
{
|
||||
GSLOG7SO(DEBUG) << "[" << event.GetKeyCode() << "]";
|
||||
if (event.IsKeyDown() == true && event.GetKeyCode() == KeyEventEnum::KEY_BACK) {
|
||||
ExitTest();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool OnTouch(const TouchEvent &event) override
|
||||
{
|
||||
if (event.GetAction() == TouchEnum::PRIMARY_POINT_DOWN) {
|
||||
window->SwitchTop();
|
||||
}
|
||||
|
||||
GSLOG7SO(DEBUG) << "[" << event.GetAction() << "]"
|
||||
<< "(" << event.GetPointerPosition(event.GetIndex()).GetX()
|
||||
<< ", " << event.GetPointerPosition(event.GetIndex()).GetY()
|
||||
<< ")";
|
||||
return false;
|
||||
}
|
||||
|
||||
void OnSplitStatusChange(SplitStatus status)
|
||||
{
|
||||
ScopedBytrace trace(__func__);
|
||||
if (status == SPLIT_STATUS_DESTROY) {
|
||||
GSLOG7SO(INFO) << "SPLIT_STATUS_DESTROY";
|
||||
ExitTest();
|
||||
} else if (status == SPLIT_STATUS_RETAIN) {
|
||||
GSLOG7SO(INFO) << "SPLIT_STATUS_RETAIN";
|
||||
adjStatus = SPLIT_STATUS_CLEAR;
|
||||
PostTask(std::bind(&NativeTestDrawer::DrawOnce, windowDrawer));
|
||||
} else {
|
||||
if (adjStatus != status) {
|
||||
GSLOG7SO(INFO) << "SPLIT_STATUS_" << status;
|
||||
}
|
||||
adjStatus = status;
|
||||
PostTask(std::bind(&NativeTestDrawer::DrawOnce, windowDrawer));
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
sptr<NativeTestDrawer> windowDrawer = nullptr;
|
||||
SplitStatus adjStatus = SPLIT_STATUS_CLEAR;
|
||||
|
||||
private:
|
||||
sptr<Window> window = nullptr;
|
||||
BufferRequestConfig config = {};
|
||||
} g_autoload0;
|
||||
|
||||
class WMClientNativeTest20Sub1 : public WMClientNativeTest20 {
|
||||
public:
|
||||
virtual std::string GetDescription() const override
|
||||
{
|
||||
constexpr const char *desc = "systemui mocker";
|
||||
return desc;
|
||||
}
|
||||
|
||||
virtual int32_t GetProcessSequence() const override
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual enum AutoLoadService GetAutoLoadService() const override
|
||||
{
|
||||
return AutoLoadService::WindowManager | AutoLoadService::WindowManagerService;
|
||||
}
|
||||
|
||||
virtual void Run(int32_t argc, const char **argv) override
|
||||
{
|
||||
ScopedBytrace trace(__func__);
|
||||
window = NativeTestFactory::CreateWindow(WINDOW_TYPE_SYSTEM_UI);
|
||||
if (window == nullptr) {
|
||||
GSLOG7SO(ERROR) << "NativeTestFactory::CreateWindow return nullptr";
|
||||
ExitTest();
|
||||
return;
|
||||
}
|
||||
|
||||
auto surface = window->GetSurface();
|
||||
window->SwitchTop();
|
||||
auto draw = std::bind(&WMClientNativeTest20Sub1::Draw, this,
|
||||
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4);
|
||||
windowDrawer = NativeTestDrawer::CreateDrawer(draw, surface);
|
||||
windowDrawer->DrawOnce();
|
||||
for (auto &icon : icons) {
|
||||
icon.rect.x *= window->GetWidth();
|
||||
icon.rect.y *= window->GetHeight();
|
||||
icon.rect.w *= window->GetWidth();
|
||||
icon.rect.h *= window->GetHeight();
|
||||
}
|
||||
total.x *= window->GetWidth();
|
||||
total.y *= window->GetHeight();
|
||||
total.w *= window->GetWidth();
|
||||
total.h *= window->GetHeight();
|
||||
|
||||
ListenWindowInputEvent(window->GetID());
|
||||
}
|
||||
|
||||
void Draw(void *vaddr, uint32_t width, uint32_t height, uint32_t count)
|
||||
{
|
||||
ScopedBytrace trace(__func__);
|
||||
GSLOG7SO(INFO) << "currentIcon: " << currentIcon;
|
||||
CPUDraw draw(vaddr, width, height);
|
||||
|
||||
draw.SetColor(0x00000000);
|
||||
draw.DrawRect(0, 0, width, height);
|
||||
|
||||
draw.SetColor(0xffffffff);
|
||||
draw.DrawRect(total);
|
||||
|
||||
draw.SetColor(0xffaaaaaa);
|
||||
draw.SetBorder(0x2);
|
||||
draw.DrawBorder(total);
|
||||
|
||||
for (auto &icon : icons) {
|
||||
draw.SetColor(icon.c);
|
||||
draw.DrawRect(icon.rect);
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool OnKey(const KeyEvent &event) override
|
||||
{
|
||||
GSLOG7SO(DEBUG) << "[" << event.GetKeyCode() << "]";
|
||||
if (event.IsKeyDown() == true && event.GetKeyCode() == KeyEventEnum::KEY_BACK) {
|
||||
ExitTest();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool OnTouch(const TouchEvent &event) override
|
||||
{
|
||||
ScopedBytrace trace(__func__);
|
||||
if (event.GetAction() == TouchEnum::PRIMARY_POINT_DOWN) {
|
||||
window->SwitchTop();
|
||||
}
|
||||
|
||||
int32_t index = event.GetIndex();
|
||||
int32_t x = event.GetPointerPosition(index).GetX();
|
||||
int32_t y = event.GetPointerPosition(index).GetY();
|
||||
if (event.GetAction() == TouchEnum::PRIMARY_POINT_DOWN) {
|
||||
downX = x;
|
||||
downY = y;
|
||||
currentIcon = nullptr;
|
||||
for (auto &icon : icons) {
|
||||
if (icon.rect.Contain(x, y)) {
|
||||
currentIcon = &icon;
|
||||
backupIcon = icon;
|
||||
GSLOG7SO(INFO) << "selected: " << currentIcon
|
||||
<< " " << currentIcon->rect.x << ", " << currentIcon->rect.y;
|
||||
if (currentIcon != &icons[0]) {
|
||||
SetSplitMode(SPLIT_MODE_SINGLE);
|
||||
} else {
|
||||
SetSplitMode(SPLIT_MODE_UNENABLE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (event.GetAction() == TouchEnum::POINT_MOVE && currentIcon) {
|
||||
currentIcon->rect.x = backupIcon.rect.x + x - downX;
|
||||
currentIcon->rect.y = backupIcon.rect.y + y - downY;
|
||||
PostTask(std::bind(&NativeTestDrawer::DrawOnce, windowDrawer));
|
||||
|
||||
if (currentIcon != &icons[0]) {
|
||||
if (total.Contain(x, y)) {
|
||||
SetSplitMode(SPLIT_MODE_SINGLE);
|
||||
} else {
|
||||
static int32_t lastX = -1;
|
||||
static int32_t lastY = -1;
|
||||
if (lastX != x || lastY != y) {
|
||||
SetSplitMode(SPLIT_MODE_SELECT, x, y);
|
||||
}
|
||||
lastX = x;
|
||||
lastY = y;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (event.GetAction() == TouchEnum::PRIMARY_POINT_UP && currentIcon) {
|
||||
if (currentIcon != &icons[0]) {
|
||||
// center point (x, y)
|
||||
auto x = currentIcon->rect.x + currentIcon->rect.w / 0x2;
|
||||
auto y = currentIcon->rect.y + currentIcon->rect.y / 0x2;
|
||||
if (total.Contain(x, y)) {
|
||||
SetSplitMode(SPLIT_MODE_NULL);
|
||||
} else {
|
||||
StartProcess2();
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
SetSplitMode(SPLIT_MODE_NULL);
|
||||
}
|
||||
*currentIcon = backupIcon;
|
||||
PostTask(std::bind(&NativeTestDrawer::DrawOnce, windowDrawer));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
SplitMode lastMode = SPLIT_MODE_NULL;
|
||||
void SetSplitMode(SplitMode mode, int32_t x = 0, int32_t y = 0)
|
||||
{
|
||||
ScopedBytrace trace(__func__);
|
||||
if (lastMode != mode) {
|
||||
GSLOG7SO(INFO) << static_cast<int32_t>(mode);
|
||||
lastMode = mode;
|
||||
}
|
||||
windowManagerService->SetSplitMode(mode, x, y);
|
||||
}
|
||||
|
||||
void StartProcess2()
|
||||
{
|
||||
extraArgs.clear();
|
||||
std::stringstream ss;
|
||||
ss << "--color=" << std::hex << std::showbase << currentIcon->c;
|
||||
auto sss = ss.str();
|
||||
extraArgs.push_back(sss.c_str());
|
||||
GSLOG7SO(INFO) << "fork return: " << StartSubprocess(2);
|
||||
|
||||
std::this_thread::sleep_for(1s);
|
||||
SetSplitMode(SPLIT_MODE_CONFIRM);
|
||||
ExitTest();
|
||||
return;
|
||||
}
|
||||
|
||||
private:
|
||||
sptr<Window> window = nullptr;
|
||||
sptr<NativeTestDrawer> windowDrawer = nullptr;
|
||||
|
||||
static constexpr double xx = 0.7;
|
||||
static constexpr double ww = 0.3;
|
||||
static constexpr double yy = 0.1;
|
||||
static constexpr double hh = 0.8;
|
||||
|
||||
struct Position {
|
||||
struct CPUDrawRect rect;
|
||||
uint32_t c;
|
||||
};
|
||||
struct Position icons[0x4] = {
|
||||
{ { xx + 0.15 * ww, yy + 1 * hh / 9, 0.7 * ww, hh / 9 }, 0xffff0000 },
|
||||
{ { xx + 0.15 * ww, yy + 3 * hh / 9, 0.7 * ww, hh / 9 }, 0xff00ff00 },
|
||||
{ { xx + 0.15 * ww, yy + 5 * hh / 9, 0.7 * ww, hh / 9 }, 0xff0000ff },
|
||||
{ { xx + 0.15 * ww, yy + 7 * hh / 9, 0.7 * ww, hh / 9 }, 0xffff00ff },
|
||||
};
|
||||
struct Position *currentIcon = nullptr;
|
||||
struct Position backupIcon;
|
||||
struct CPUDrawRect total = { xx, yy, ww, hh };
|
||||
int32_t downX = 0;
|
||||
int32_t downY = 0;
|
||||
} g_autoload1;
|
||||
|
||||
class WMClientNativeTest20Sub2 : public WMClientNativeTest20Sub0 {
|
||||
public:
|
||||
virtual std::string GetDescription() const override
|
||||
{
|
||||
constexpr const char *desc = "spliting application mocker";
|
||||
return desc;
|
||||
}
|
||||
|
||||
virtual int32_t GetProcessSequence() const override
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
virtual void Run(int32_t argc, const char **argv) override
|
||||
{
|
||||
OptionParser parser;
|
||||
parser.AddOption("c", "color", color);
|
||||
if (parser.Parse(argc, argv)) {
|
||||
GSLOG7SE(ERROR) << parser.GetErrorString();
|
||||
ExitTest();
|
||||
return;
|
||||
}
|
||||
|
||||
GSLOG7SO(INFO) << "color: " << std::hex << std::showbase << color;
|
||||
WMClientNativeTest20Sub0::Run(argc, argv);
|
||||
auto draw = std::bind(&WMClientNativeTest20Sub2::Draw, this,
|
||||
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4);
|
||||
windowDrawer->SetDrawFunc(draw);
|
||||
windowDrawer->DrawOnce();
|
||||
}
|
||||
|
||||
void Draw(void *vaddr, uint32_t width, uint32_t height, uint32_t count)
|
||||
{
|
||||
ScopedBytrace trace(__func__);
|
||||
CPUDraw draw(vaddr, width, height);
|
||||
draw.SetColor(color);
|
||||
if (adjStatus == SPLIT_STATUS_VAGUE) {
|
||||
draw.SetColor((0xffffffff - color) | 0xff000000);
|
||||
}
|
||||
|
||||
draw.DrawRect(0, 0, width, height);
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t color = 0xffff0000;
|
||||
} g_autoload2;
|
||||
} // namespace
|
19
frameworks/wmtest/test/wmclient_native_test_20.h
Normal file
19
frameworks/wmtest/test/wmclient_native_test_20.h
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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 FRAMEWORKS_WMTEST_TEST_WMCLIENT_WMCLIENT_NATIVE_TEST_20_H
|
||||
#define FRAMEWORKS_WMTEST_TEST_WMCLIENT_WMCLIENT_NATIVE_TEST_20_H
|
||||
|
||||
#endif // FRAMEWORKS_WMTEST_TEST_WMCLIENT_WMCLIENT_NATIVE_TEST_20_H
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include "inative_test.h"
|
||||
#include "native_test_class.h"
|
||||
#include "egl_native_test_class.h"
|
||||
#include "util.h"
|
||||
|
||||
using namespace OHOS;
|
||||
|
@ -59,9 +59,7 @@ public:
|
||||
::std::placeholders::_3, ::std::placeholders::_4);
|
||||
mainSync = NativeTestSync::CreateSync(draw, surface);
|
||||
|
||||
token_ = new IPCObjectStub(u"token");
|
||||
keyEventHandle_ = new KeyEventHandle(this);
|
||||
MMIEventHdl.RegisterStandardizedEventHandle(token_, mainWindow->GetID(), keyEventHandle_);
|
||||
ListenWindowKeyEvent(mainWindow->GetID());
|
||||
}
|
||||
|
||||
void EnterPIPMode()
|
||||
@ -100,10 +98,7 @@ public:
|
||||
::std::placeholders::_3, ::std::placeholders::_4);
|
||||
|
||||
pipSync = NativeTestSync::CreateSync(draw, pipSurface);
|
||||
|
||||
token_ = new IPCObjectStub(u"token");
|
||||
touchEventHandle_ = new TouchEventHandle(this);
|
||||
MMIEventHdl.RegisterStandardizedEventHandle(token_, pipWindow->GetID(), touchEventHandle_);
|
||||
ListenWindowTouchEvent(pipWindow->GetID());
|
||||
|
||||
int x = 100, y = 100, w = 300, h = 200;
|
||||
pipWindow->Move(x, y);
|
||||
@ -137,15 +132,15 @@ public:
|
||||
onPIPModeChange = func;
|
||||
}
|
||||
|
||||
bool OnKeyPrivate(const KeyEvent &event)
|
||||
virtual bool OnKey(const KeyEvent &event) override
|
||||
{
|
||||
if (event.IsKeyDown() == true && event.GetKeyCode() == OHOS::KeyEventEnum::KEY_BACK) {
|
||||
return OnKey(event);
|
||||
return OnKeyPublic(event);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OnTouchPrivate(const TouchEvent &event)
|
||||
virtual bool OnTouch(const TouchEvent &event) override
|
||||
{
|
||||
int index = event.GetIndex();
|
||||
if (event.GetAction() == OHOS::TouchEnum::POINT_MOVE) {
|
||||
@ -157,7 +152,7 @@ public:
|
||||
touchUpFlag = false;
|
||||
return true;
|
||||
} else if (event.GetAction() == OHOS::TouchEnum::PRIMARY_POINT_UP && touchUpFlag == true) {
|
||||
return OnTouch(event);
|
||||
return OnTouchPublic(event);
|
||||
} else if (event.GetAction() == OHOS::TouchEnum::PRIMARY_POINT_UP && touchUpFlag == false) {
|
||||
DownX = 0;
|
||||
DownY = 0;
|
||||
@ -176,49 +171,15 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool OnKey(const KeyEvent &event) = 0;
|
||||
virtual bool OnTouch(const TouchEvent &event) = 0;
|
||||
virtual bool OnKeyPublic(const KeyEvent &event) = 0;
|
||||
virtual bool OnTouchPublic(const TouchEvent &event) = 0;
|
||||
|
||||
private:
|
||||
class KeyEventHandle : public MMI::KeyEventHandler {
|
||||
public:
|
||||
explicit KeyEventHandle(WMClientNativeTest32Ability *test) : test(test)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool OnKey(const KeyEvent &event) override
|
||||
{
|
||||
return test->OnKeyPrivate(event);
|
||||
}
|
||||
|
||||
private:
|
||||
WMClientNativeTest32Ability *test;
|
||||
};
|
||||
|
||||
class TouchEventHandle : public MMI::TouchEventHandler {
|
||||
public:
|
||||
explicit TouchEventHandle(WMClientNativeTest32Ability *test) : test(test)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool OnTouch(const TouchEvent &event) override
|
||||
{
|
||||
return test->OnTouchPrivate(event);
|
||||
}
|
||||
|
||||
private:
|
||||
WMClientNativeTest32Ability *test;
|
||||
};
|
||||
|
||||
sptr<Window> mainWindow = nullptr;
|
||||
sptr<Window> pipWindow = nullptr;
|
||||
sptr<NativeTestSync> mainSync = nullptr;
|
||||
sptr<NativeTestSync> pipSync = nullptr;
|
||||
|
||||
sptr<IRemoteObject> token_ = nullptr;
|
||||
sptr<KeyEventHandle> keyEventHandle_ = nullptr;
|
||||
sptr<TouchEventHandle> touchEventHandle_ = nullptr;
|
||||
|
||||
bool pipMode = false;
|
||||
bool touchUpFlag = true;
|
||||
std::function<void(bool)> onPIPModeChange = nullptr;
|
||||
@ -274,13 +235,13 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
bool OnTouch(const TouchEvent &event) override
|
||||
virtual bool OnTouchPublic(const TouchEvent &event) override
|
||||
{
|
||||
ExitPIPMode();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnKey(const KeyEvent &event) override
|
||||
virtual bool OnKeyPublic(const KeyEvent &event) override
|
||||
{
|
||||
drawptr = NativeTestDraw::ColorDraw;
|
||||
EnterPIPMode();
|
||||
@ -291,4 +252,4 @@ public:
|
||||
private:
|
||||
DrawFunc drawptr = NativeTestDraw::FlushDraw;
|
||||
} g_autoload;
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
@ -56,6 +56,7 @@ public:
|
||||
virtual void OnVisibilityChange(WindowVisibilityChangeFunc func) = 0;
|
||||
virtual void OnTypeChange(WindowTypeChangeFunc func) = 0;
|
||||
virtual void OnModeChange(WindowModeChangeFunc func) = 0;
|
||||
virtual void OnSplitStatusChange(SplitStatusChangeFunc func) = 0;
|
||||
|
||||
// listener
|
||||
virtual WMError OnTouch(OnTouchFunc cb) = 0;
|
||||
|
@ -67,6 +67,33 @@ enum DisplayType {
|
||||
DISPLAY_TYPE_VIRTUAL,
|
||||
DISPLAY_TYPE_MAX,
|
||||
};
|
||||
|
||||
enum SplitStatus {
|
||||
SPLIT_STATUS_CLEAR = 0,
|
||||
SPLIT_STATUS_VAGUE = 1,
|
||||
SPLIT_STATUS_RETAIN = 2,
|
||||
SPLIT_STATUS_DESTROY = 3,
|
||||
SPLIT_STATUS_MAX,
|
||||
};
|
||||
|
||||
enum WindowSplitMode {
|
||||
WINDOW_SPLIT_MODE_UNSET = 0,
|
||||
WINDOW_SPLIT_MODE_SET = 1,
|
||||
WINDOW_SPLIT_MODE_MAX,
|
||||
};
|
||||
|
||||
enum SplitMode {
|
||||
SPLIT_MODE_NULL = 0,
|
||||
SPLIT_MODE_UNENABLE = 1,
|
||||
SPLIT_MODE_SINGLE = 2,
|
||||
SPLIT_MODE_SELECT = 3,
|
||||
SPLIT_MODE_CONFIRM = 4,
|
||||
SPLIT_MODE_DIVIDER_TOUCH_DOWN = 5,
|
||||
SPLIT_MODE_DIVIDER_TOUCH_MOVE = 6,
|
||||
SPLIT_MODE_DIVIDER_TOUCH_UP = 7,
|
||||
SPLIT_MODE_MAX,
|
||||
};
|
||||
|
||||
struct WMDisplayInfo {
|
||||
int32_t id;
|
||||
uint32_t width;
|
||||
@ -78,8 +105,9 @@ struct WMDisplayInfo {
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
using WindowModeChangeFunc = std::function<void(WindowMode mode)>;
|
||||
using BeforeFrameSubmitFunc = std::function<void()>;
|
||||
using WindowModeChangeFunc = std::function<void(WindowMode mode)>;
|
||||
using BeforeFrameSubmitFunc = std::function<void()>;
|
||||
using SplitStatusChangeFunc = std::function<void(SplitStatus status)>;
|
||||
} // namespace OHOS
|
||||
#endif
|
||||
|
||||
|
@ -54,6 +54,7 @@ namespace OHOS {
|
||||
macro(WINDOW_TYPE_TOAST), \
|
||||
macro(WINDOW_TYPE_WALLPAPER), \
|
||||
macro(WINDOW_TYPE_ANIMATION), \
|
||||
macro(WINDOW_TYPE_SPLIT_LINE), \
|
||||
macro(WINDOW_TYPE_MAX),
|
||||
|
||||
#define DEFINE_ENUM_WINDOW_TYPE(id) id
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
#include "iwindow_change_listener_clazz.h"
|
||||
#include "iwindow_manager_display_listener_clazz.h"
|
||||
|
||||
#include "window_manager_service_type.h"
|
||||
|
||||
namespace OHOS {
|
||||
@ -65,6 +66,8 @@ public:
|
||||
virtual sptr<PromiseWMError> DestroyVirtualDisplay(uint32_t did) = 0;
|
||||
|
||||
virtual GSError StartRotationAnimation(uint32_t did, int32_t degree) = 0;
|
||||
|
||||
virtual sptr<PromiseWMError> SetSplitMode(SplitMode mode, int32_t x = 0, int32_t y = 0) = 0;
|
||||
};
|
||||
} // namespace OHOS
|
||||
|
||||
|
@ -56,6 +56,7 @@ using PromiseWMError = Promise<WMError>;
|
||||
using PromiseWMSImageInfo = Promise<WMSImageInfo>;
|
||||
using PromisePowerStatus = Promise<PowerStatus>;
|
||||
using PromiseBacklight = Promise<Backlight>;
|
||||
|
||||
} // namespace OHOS
|
||||
|
||||
#endif // INTERFACES_INNERKITS_WMSERVICE_WINDOW_MANAGER_SERVICE_TYPE_H
|
||||
|
@ -46,3 +46,7 @@ group("matrix") {
|
||||
group("raw_parser") {
|
||||
public_deps = [ "raw_parser:raw_parser" ]
|
||||
}
|
||||
|
||||
group("cpudraw") {
|
||||
public_deps = [ "cpudraw:cpudraw" ]
|
||||
}
|
||||
|
40
utils/cpudraw/BUILD.gn
Normal file
40
utils/cpudraw/BUILD.gn
Normal file
@ -0,0 +1,40 @@
|
||||
# Copyright (c) 2021 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("//build/ohos.gni")
|
||||
|
||||
## Build cpudraw.a {{{
|
||||
config("cpudraw_config") {
|
||||
visibility = [ ":*" ]
|
||||
|
||||
cflags = [
|
||||
"-Wall",
|
||||
"-Werror",
|
||||
"-g3",
|
||||
]
|
||||
}
|
||||
|
||||
config("cpudraw_public_config") {
|
||||
include_dirs = [ "export" ]
|
||||
}
|
||||
|
||||
ohos_static_library("cpudraw") {
|
||||
sources = [ "src/cpudraw.cpp" ]
|
||||
|
||||
configs = [ ":cpudraw_config" ]
|
||||
|
||||
public_configs = [ ":cpudraw_public_config" ]
|
||||
|
||||
deps = [ "..:graphic_bytrace" ]
|
||||
}
|
||||
## Build cpudraw.a }}}
|
54
utils/cpudraw/export/cpudraw.h
Normal file
54
utils/cpudraw/export/cpudraw.h
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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 UTILS_INCLUDE_CPUDRAW_EXPORT_CPUDRAW_H
|
||||
#define UTILS_INCLUDE_CPUDRAW_EXPORT_CPUDRAW_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
struct CPUDrawRect {
|
||||
double x;
|
||||
double y;
|
||||
double w;
|
||||
double h;
|
||||
|
||||
bool Contain(int32_t x2, int32_t y2);
|
||||
};
|
||||
|
||||
class CPUDraw {
|
||||
public:
|
||||
CPUDraw(void *vaddr, int32_t width, int32_t height);
|
||||
|
||||
void SetColor(const uint32_t &color);
|
||||
void SetBorder(const int32_t &border);
|
||||
|
||||
void DrawBorder(const int32_t &x, const int32_t &y, const int32_t &w, const int32_t &h);
|
||||
void DrawBorder(const struct CPUDrawRect &rect);
|
||||
|
||||
void DrawRect(const int32_t &x, const int32_t &y, const int32_t &w, const int32_t &h);
|
||||
void DrawRect(const struct CPUDrawRect &rect);
|
||||
|
||||
private:
|
||||
int32_t Min(const int32_t &a, const int32_t &b);
|
||||
int32_t Max(const int32_t &a, const int32_t &b);
|
||||
|
||||
uint32_t *addr = nullptr;
|
||||
int32_t width = 0;
|
||||
int32_t height = 0;
|
||||
uint32_t color = 0xffffffff;
|
||||
int32_t border = 0;
|
||||
};
|
||||
|
||||
#endif // UTILS_INCLUDE_CPUDRAW_EXPORT_CPUDRAW_H
|
77
utils/cpudraw/src/cpudraw.cpp
Normal file
77
utils/cpudraw/src/cpudraw.cpp
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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 "cpudraw.h"
|
||||
|
||||
#include <graphic_bytrace.h>
|
||||
|
||||
bool CPUDrawRect::Contain(int32_t x2, int32_t y2)
|
||||
{
|
||||
return x <= x2 && x2 <= x + w && y <= y2 && y2 <= y + h;
|
||||
}
|
||||
|
||||
CPUDraw::CPUDraw(void *vaddr, int32_t width, int32_t height)
|
||||
: addr(reinterpret_cast<uint32_t *>(vaddr)), width(width), height(height)
|
||||
{
|
||||
}
|
||||
|
||||
void CPUDraw::SetColor(const uint32_t &color)
|
||||
{
|
||||
this->color = color;
|
||||
}
|
||||
|
||||
void CPUDraw::SetBorder(const int32_t &border)
|
||||
{
|
||||
this->border = border;
|
||||
}
|
||||
|
||||
void CPUDraw::DrawBorder(const struct CPUDrawRect &rect)
|
||||
{
|
||||
DrawBorder(rect.x, rect.y, rect.w, rect.h);
|
||||
}
|
||||
|
||||
void CPUDraw::DrawBorder(const int32_t &x, const int32_t &y, const int32_t &w, const int32_t &h)
|
||||
{
|
||||
ScopedBytrace trace(__func__);
|
||||
DrawRect(x, y, border, h);
|
||||
DrawRect(x + w - border, y, border, h);
|
||||
DrawRect(x, y, w, border);
|
||||
DrawRect(x, y + h - border, w, border);
|
||||
}
|
||||
|
||||
void CPUDraw::DrawRect(const struct CPUDrawRect &rect)
|
||||
{
|
||||
DrawRect(rect.x, rect.y, rect.w, rect.h);
|
||||
}
|
||||
|
||||
void CPUDraw::DrawRect(const int32_t &x, const int32_t &y, const int32_t &w, const int32_t &h)
|
||||
{
|
||||
ScopedBytrace trace(__func__);
|
||||
for (int32_t j = Max(y, 0); j < Min(y + h, height); j++) {
|
||||
for (int32_t i = Max(x, 0); i < Min(x + w, width); i++) {
|
||||
addr[j * width + i] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32_t CPUDraw::Min(const int32_t &a, const int32_t &b)
|
||||
{
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
int32_t CPUDraw::Max(const int32_t &a, const int32_t &b)
|
||||
{
|
||||
return a > b ? a : b;
|
||||
}
|
@ -38,6 +38,7 @@ public:
|
||||
static void FuncLine(Gslogger &logger, enum LOG_PHASE phase); // 2
|
||||
static void FileLine(Gslogger &logger, enum LOG_PHASE phase); // 3
|
||||
static void FileFuncLine(Gslogger &logger, enum LOG_PHASE phase); // 4
|
||||
static void PidTid(Gslogger &logger, enum LOG_PHASE phase); // +5
|
||||
|
||||
Gslogger(const std::string &file, const std::string &func, int line, enum LOG_LEVEL level, ...);
|
||||
virtual ~Gslogger() override;
|
||||
@ -78,33 +79,83 @@ private:
|
||||
// hilog
|
||||
#define DEFINE_HILOG_LABEL(str) \
|
||||
namespace { constexpr const char *HILOG_LABEL = str; }
|
||||
#define GSLOG0HI(level) Gslogger(LOGGER_ARG(level), Gslogger::Hilog, HILOG_LABEL, NULL)
|
||||
#define GSLOG1HI(level) Gslogger(LOGGER_ARG(level), Gslogger::Func, Gslogger::Hilog, HILOG_LABEL, NULL)
|
||||
#define GSLOG2HI(level) Gslogger(LOGGER_ARG(level), Gslogger::FuncLine, Gslogger::Hilog, HILOG_LABEL, NULL)
|
||||
#define GSLOG3HI(level) Gslogger(LOGGER_ARG(level), Gslogger::FileLine, Gslogger::Hilog, HILOG_LABEL, NULL)
|
||||
#define GSLOG4HI(level) Gslogger(LOGGER_ARG(level), Gslogger::FileFuncLine, Gslogger::Hilog, HILOG_LABEL, NULL)
|
||||
#define GSLOG0HI(level) Gslogger(LOGGER_ARG(level), \
|
||||
Gslogger::Hilog, HILOG_LABEL, NULL)
|
||||
#define GSLOG1HI(level) Gslogger(LOGGER_ARG(level), \
|
||||
Gslogger::Func, Gslogger::Hilog, HILOG_LABEL, NULL)
|
||||
#define GSLOG2HI(level) Gslogger(LOGGER_ARG(level), \
|
||||
Gslogger::FuncLine, Gslogger::Hilog, HILOG_LABEL, NULL)
|
||||
#define GSLOG3HI(level) Gslogger(LOGGER_ARG(level), \
|
||||
Gslogger::FileLine, Gslogger::Hilog, HILOG_LABEL, NULL)
|
||||
#define GSLOG4HI(level) Gslogger(LOGGER_ARG(level), \
|
||||
Gslogger::FileFuncLine, Gslogger::Hilog, HILOG_LABEL, NULL)
|
||||
|
||||
// stdout
|
||||
#define GSLOG0SO(level) Gslogger(LOGGER_ARG(level), Gslogger::Stdout, NULL)
|
||||
#define GSLOG1SO(level) Gslogger(LOGGER_ARG(level), Gslogger::Func, Gslogger::Stdout, NULL)
|
||||
#define GSLOG2SO(level) Gslogger(LOGGER_ARG(level), Gslogger::FuncLine, Gslogger::Stdout, NULL)
|
||||
#define GSLOG3SO(level) Gslogger(LOGGER_ARG(level), Gslogger::FileLine, Gslogger::Stdout, NULL)
|
||||
#define GSLOG4SO(level) Gslogger(LOGGER_ARG(level), Gslogger::FileFuncLine, Gslogger::Stdout, NULL)
|
||||
#define GSLOG0SO(level) Gslogger(LOGGER_ARG(level), \
|
||||
Gslogger::Stdout, NULL)
|
||||
#define GSLOG1SO(level) Gslogger(LOGGER_ARG(level), \
|
||||
Gslogger::Func, Gslogger::Stdout, NULL)
|
||||
#define GSLOG2SO(level) Gslogger(LOGGER_ARG(level), \
|
||||
Gslogger::FuncLine, Gslogger::Stdout, NULL)
|
||||
#define GSLOG3SO(level) Gslogger(LOGGER_ARG(level), \
|
||||
Gslogger::FileLine, Gslogger::Stdout, NULL)
|
||||
#define GSLOG4SO(level) Gslogger(LOGGER_ARG(level), \
|
||||
Gslogger::FileFuncLine, Gslogger::Stdout, NULL)
|
||||
#define GSLOG5SO(level) Gslogger(LOGGER_ARG(level), \
|
||||
Gslogger::PidTid, Gslogger::Stdout, NULL)
|
||||
#define GSLOG6SO(level) Gslogger(LOGGER_ARG(level), \
|
||||
Gslogger::PidTid, Gslogger::Func, Gslogger::Stdout, NULL)
|
||||
#define GSLOG7SO(level) Gslogger(LOGGER_ARG(level), \
|
||||
Gslogger::PidTid, Gslogger::FuncLine, Gslogger::Stdout, NULL)
|
||||
#define GSLOG8SO(level) Gslogger(LOGGER_ARG(level), \
|
||||
Gslogger::PidTid, Gslogger::FileLine, Gslogger::Stdout, NULL)
|
||||
#define GSLOG9SO(level) Gslogger(LOGGER_ARG(level), \
|
||||
Gslogger::PidTid, Gslogger::FileFuncLine, Gslogger::Stdout, NULL)
|
||||
|
||||
// stderr
|
||||
#define GSLOG0SE(level) Gslogger(LOGGER_ARG(level), Gslogger::Stderr, NULL)
|
||||
#define GSLOG1SE(level) Gslogger(LOGGER_ARG(level), Gslogger::Func, Gslogger::Stderr, NULL)
|
||||
#define GSLOG2SE(level) Gslogger(LOGGER_ARG(level), Gslogger::FuncLine, Gslogger::Stderr, NULL)
|
||||
#define GSLOG3SE(level) Gslogger(LOGGER_ARG(level), Gslogger::FileLine, Gslogger::Stderr, NULL)
|
||||
#define GSLOG4SE(level) Gslogger(LOGGER_ARG(level), Gslogger::FileFuncLine, Gslogger::Stderr, NULL)
|
||||
#define GSLOG0SE(level) Gslogger(LOGGER_ARG(level), \
|
||||
Gslogger::Stderr, NULL)
|
||||
#define GSLOG1SE(level) Gslogger(LOGGER_ARG(level), \
|
||||
Gslogger::Func, Gslogger::Stderr, NULL)
|
||||
#define GSLOG2SE(level) Gslogger(LOGGER_ARG(level), \
|
||||
Gslogger::FuncLine, Gslogger::Stderr, NULL)
|
||||
#define GSLOG3SE(level) Gslogger(LOGGER_ARG(level), \
|
||||
Gslogger::FileLine, Gslogger::Stderr, NULL)
|
||||
#define GSLOG4SE(level) Gslogger(LOGGER_ARG(level), \
|
||||
Gslogger::FileFuncLine, Gslogger::Stderr, NULL)
|
||||
#define GSLOG5SE(level) Gslogger(LOGGER_ARG(level), \
|
||||
Gslogger::PidTid, Gslogger::Stderr, NULL)
|
||||
#define GSLOG6SE(level) Gslogger(LOGGER_ARG(level), \
|
||||
Gslogger::PidTid, Gslogger::Func, Gslogger::Stderr, NULL)
|
||||
#define GSLOG7SE(level) Gslogger(LOGGER_ARG(level), \
|
||||
Gslogger::PidTid, Gslogger::FuncLine, Gslogger::Stderr, NULL)
|
||||
#define GSLOG8SE(level) Gslogger(LOGGER_ARG(level), \
|
||||
Gslogger::PidTid, Gslogger::FileLine, Gslogger::Stderr, NULL)
|
||||
#define GSLOG9SE(level) Gslogger(LOGGER_ARG(level), \
|
||||
Gslogger::PidTid, Gslogger::FileFuncLine, Gslogger::Stderr, NULL)
|
||||
|
||||
// filelog
|
||||
#define DEFINE_FILE_LABEL(str) \
|
||||
namespace { constexpr const char *FILE_LABEL = str; }
|
||||
#define GSLOG0F(level) Gslogger(LOGGER_ARG(level), Gslogger::FileLog, FILE_LABEL, NULL)
|
||||
#define GSLOG1F(level) Gslogger(LOGGER_ARG(level), Gslogger::Func, Gslogger::FileLog, FILE_LABEL, NULL)
|
||||
#define GSLOG2F(level) Gslogger(LOGGER_ARG(level), Gslogger::FuncLine, Gslogger::FileLog, FILE_LABEL, NULL)
|
||||
#define GSLOG3F(level) Gslogger(LOGGER_ARG(level), Gslogger::FileLine, Gslogger::FileLog, FILE_LABEL, NULL)
|
||||
#define GSLOG4F(level) Gslogger(LOGGER_ARG(level), Gslogger::FileFuncLine, Gslogger::FileLog, FILE_LABEL, NULL)
|
||||
#define GSLOG0F(level) Gslogger(LOGGER_ARG(level), \
|
||||
Gslogger::FileLog, FILE_LABEL, NULL)
|
||||
#define GSLOG1F(level) Gslogger(LOGGER_ARG(level), \
|
||||
Gslogger::Func, Gslogger::FileLog, FILE_LABEL, NULL)
|
||||
#define GSLOG2F(level) Gslogger(LOGGER_ARG(level), \
|
||||
Gslogger::FuncLine, Gslogger::FileLog, FILE_LABEL, NULL)
|
||||
#define GSLOG3F(level) Gslogger(LOGGER_ARG(level), \
|
||||
Gslogger::FileLine, Gslogger::FileLog, FILE_LABEL, NULL)
|
||||
#define GSLOG4F(level) Gslogger(LOGGER_ARG(level), \
|
||||
Gslogger::FileFuncLine, Gslogger::FileLog, FILE_LABEL, NULL)
|
||||
#define GSLOG5F(level) Gslogger(LOGGER_ARG(level), \
|
||||
Gslogger::PidTid, Gslogger::FileLog, FILE_LABEL, NULL)
|
||||
#define GSLOG6F(level) Gslogger(LOGGER_ARG(level), \
|
||||
Gslogger::PidTid, Gslogger::Func, Gslogger::FileLog, FILE_LABEL, NULL)
|
||||
#define GSLOG7F(level) Gslogger(LOGGER_ARG(level), \
|
||||
Gslogger::PidTid, Gslogger::FuncLine, Gslogger::FileLog, FILE_LABEL, NULL)
|
||||
#define GSLOG8F(level) Gslogger(LOGGER_ARG(level), \
|
||||
Gslogger::PidTid, Gslogger::FileLine, Gslogger::FileLog, FILE_LABEL, NULL)
|
||||
#define GSLOG9F(level) Gslogger(LOGGER_ARG(level), \
|
||||
Gslogger::PidTid, Gslogger::FileFuncLine, Gslogger::FileLog, FILE_LABEL, NULL)
|
||||
|
||||
#endif // UTILS_INCLUDE_LOGGER_EXPORT_GSLOGGER_H
|
||||
|
@ -15,8 +15,10 @@
|
||||
|
||||
#include "gslogger.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <hilog/log.h>
|
||||
|
||||
namespace {
|
||||
@ -139,6 +141,13 @@ void Gslogger::FileFuncLine(Gslogger& logger, enum LOG_PHASE phase)
|
||||
}
|
||||
}
|
||||
|
||||
void Gslogger::PidTid(Gslogger &logger, enum LOG_PHASE phase)
|
||||
{
|
||||
if (phase == LOG_PHASE::BEGIN) {
|
||||
logger << "[" << getpid() << "][" << gettid() << "]";
|
||||
}
|
||||
}
|
||||
|
||||
Gslogger::Gslogger(const std::string &file, const std::string &func, int line, enum LOG_LEVEL level, ...)
|
||||
{
|
||||
file_ = file;
|
||||
|
@ -39,6 +39,12 @@ public:
|
||||
return AddOption(shortOpt, longOpt, &result, Option::ValueType::i32);
|
||||
}
|
||||
|
||||
template<>
|
||||
int32_t AddOption<uint32_t>(const std::string &shortOpt, const std::string &longOpt, uint32_t &result)
|
||||
{
|
||||
return AddOption(shortOpt, longOpt, &result, Option::ValueType::u32);
|
||||
}
|
||||
|
||||
template<>
|
||||
int32_t AddOption<int64_t>(const std::string &shortOpt, const std::string &longOpt, int64_t &result)
|
||||
{
|
||||
@ -76,6 +82,12 @@ public:
|
||||
return AddArguments(&result, Argument::ValueType::i32);
|
||||
}
|
||||
|
||||
template<>
|
||||
int32_t AddArguments<uint32_t>(uint32_t &result)
|
||||
{
|
||||
return AddArguments(&result, Argument::ValueType::u32);
|
||||
}
|
||||
|
||||
template<>
|
||||
int32_t AddArguments<int64_t>(int64_t &result)
|
||||
{
|
||||
@ -110,6 +122,7 @@ private:
|
||||
const std::string lo;
|
||||
union Value {
|
||||
int32_t i32;
|
||||
uint32_t u32;
|
||||
int64_t i64;
|
||||
double f64;
|
||||
std::string str;
|
||||
@ -117,6 +130,7 @@ private:
|
||||
} *result;
|
||||
enum class ValueType {
|
||||
i32,
|
||||
u32,
|
||||
i64,
|
||||
f64,
|
||||
str,
|
||||
@ -130,12 +144,14 @@ private:
|
||||
struct Argument {
|
||||
union Value {
|
||||
int32_t i32;
|
||||
uint32_t u32;
|
||||
int64_t i64;
|
||||
double f64;
|
||||
std::string str;
|
||||
} *result;
|
||||
enum class ValueType {
|
||||
i32,
|
||||
u32,
|
||||
i64,
|
||||
f64,
|
||||
str,
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
#include <option_parser.h>
|
||||
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
enum {
|
||||
@ -33,10 +34,13 @@ int32_t OptionParser::ParseArgument(const char *arg, const char *arg2)
|
||||
std::stringstream ss(arg);
|
||||
switch (arguments.front().type) {
|
||||
case Argument::ValueType::i32:
|
||||
ss >> arguments.front().result->i32;
|
||||
ss >> std::setbase(0) >> arguments.front().result->i32;
|
||||
break;
|
||||
case Argument::ValueType::u32:
|
||||
ss >> std::setbase(0) >> arguments.front().result->u32;
|
||||
break;
|
||||
case Argument::ValueType::i64:
|
||||
ss >> arguments.front().result->i64;
|
||||
ss >> std::setbase(0) >> arguments.front().result->i64;
|
||||
break;
|
||||
case Argument::ValueType::f64:
|
||||
ss >> arguments.front().result->f64;
|
||||
@ -93,10 +97,13 @@ int32_t OptionParser::ParseShortOption(const char *arg1, const char *arg2)
|
||||
std::stringstream ss(arg2);
|
||||
switch (option.type) {
|
||||
case Option::ValueType::i32:
|
||||
ss >> option.result->i32;
|
||||
ss >> std::setbase(0) >> option.result->i32;
|
||||
break;
|
||||
case Option::ValueType::u32:
|
||||
ss >> std::setbase(0) >> option.result->u32;
|
||||
break;
|
||||
case Option::ValueType::i64:
|
||||
ss >> option.result->i64;
|
||||
ss >> std::setbase(0) >> option.result->i64;
|
||||
break;
|
||||
case Option::ValueType::f64:
|
||||
ss >> option.result->f64;
|
||||
@ -168,10 +175,13 @@ int32_t OptionParser::ParseLongOption(const char *arg1, const char *arg2)
|
||||
std::stringstream ss(arg2);
|
||||
switch (option.type) {
|
||||
case Option::ValueType::i32:
|
||||
ss >> option.result->i32;
|
||||
ss >> std::setbase(0) >> option.result->i32;
|
||||
break;
|
||||
case Option::ValueType::u32:
|
||||
ss >> std::setbase(0) >> option.result->u32;
|
||||
break;
|
||||
case Option::ValueType::i64:
|
||||
ss >> option.result->i64;
|
||||
ss >> std::setbase(0) >> option.result->i64;
|
||||
break;
|
||||
case Option::ValueType::f64:
|
||||
ss >> option.result->f64;
|
||||
|
Loading…
x
Reference in New Issue
Block a user