!76 多模提交联调代码

Merge pull request !76 from licheng_1123/multimodal_1018
This commit is contained in:
openharmony_ci 2021-10-20 08:37:05 +00:00 committed by Gitee
commit 6b351122ff
14 changed files with 146 additions and 904 deletions

View File

@ -45,7 +45,6 @@ ohos_shared_library("wms_client") {
"src/client/window_manager_controller_client.cpp",
"src/input_listener_manager.cpp",
"src/log_listener.cpp",
"src/multimodal_listener_manager.cpp",
"src/singleton_container.cpp",
"src/tester.cpp",
"src/wayland_service.cpp",
@ -108,10 +107,7 @@ ohos_shared_library("wms_client") {
"samgr_standard:samgr_proxy",
]
public_deps = [
"//foundation/graphic/standard:libsurface",
"//foundation/multimodalinput/input/interfaces/native/innerkits/event:mmi_event",
]
public_deps = [ "//foundation/graphic/standard:libsurface" ]
part_name = "graphic_standard"
subsystem_name = "graphic"
@ -145,7 +141,6 @@ ohos_shared_library("libwmclient") {
sources = [
"src/input_listener_manager.cpp",
"src/log_listener.cpp",
"src/multimodal_listener_manager.cpp",
"src/singleton_container.cpp",
"src/static_call.cpp",
"src/subwindow_normal_impl.cpp",
@ -219,7 +214,6 @@ ohos_shared_library("libwmclient") {
public_deps = [
"//foundation/graphic/standard:libsurface",
"//foundation/graphic/standard/utils:promise",
"//foundation/multimodalinput/input/interfaces/native/innerkits/event:mmi_event",
]
part_name = "graphic_standard"

View File

@ -26,7 +26,6 @@
#include "input_listener_manager.h"
#include "log_listener.h"
#include "multimodal_listener_manager.h"
#include "wayland_service.h"
#include "window_manager_server.h"
#include "wl_buffer_cache.h"
@ -60,7 +59,6 @@ struct InnerWindowInfo {
funcWindowInfoChange windowInfoChangeCb;
void (* onWindowCreateCb)(uint32_t pid);
sptr<InputListener> logListener;
sptr<MultimodalListener> mmiListener;
bool operator ==(const InnerWindowInfo &other) const
{

View File

@ -1,114 +0,0 @@
/*
* 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_INCLUDE_MULTIMODAL_LISTENER_MANAGER_H
#define FRAMEWORKS_WM_INCLUDE_MULTIMODAL_LISTENER_MANAGER_H
#include <map>
#include <vector>
#include <key_event.h>
#include <mouse_event.h>
#include <refbase.h>
#include <touch_event.h>
#include "input_listener_manager.h"
#include "singleton_delegator.h"
namespace OHOS {
class MultimodalListenerManager;
class MultimodalListener : public RefBase {
friend class MultimodalListenerManager;
public:
OnKeyFunc keyboardKeyCb = nullptr;
OnTouchFunc onTouchCb = nullptr;
void *GetWindow() const
{
return window;
}
private:
MultimodalListener(void *w);
~MultimodalListener() = default;
void *window;
sptr<InputListener> input;
};
struct TouchEventInfo {
bool isRefreshed;
bool isValid;
int32_t serial;
uint32_t startTime;
uint32_t currentTime;
int32_t x;
int32_t y;
float touchPressure;
};
struct ActionEventInfo {
int32_t touchCount;
bool isDown;
bool isUp;
bool isMotion;
TouchEventInfo touchEventInfos[MAX_TOUCH_NUM];
};
class MultimodalListenerManager : public RefBase {
public:
static sptr<MultimodalListenerManager> GetInstance();
MOCKABLE sptr<MultimodalListener> AddListener(void *window);
MOCKABLE void RemoveListener(sptr<MultimodalListener> &listener);
private:
MultimodalListenerManager() = default;
MOCKABLE ~MultimodalListenerManager() = default;
static inline sptr<MultimodalListenerManager> instance = nullptr;
static inline SingletonDelegator<MultimodalListenerManager> delegator;
void PointerHandleMotion(void *data, uint32_t time, double x, double y);
void PointerHandleButton(void *data,
uint32_t serial, uint32_t time, uint32_t button, PointerButtonState state);
void PointerHandleFrame(void *data);
void PointerHandleAxis(void *data, uint32_t time, PointerAxis axis, double value);
void KeyboardHandleKey(void *data,
uint32_t serial, uint32_t time, uint32_t key, KeyboardKeyState state);
void TouchHandleDown(void *data, uint32_t serial, uint32_t time, int32_t id, double x, double y);
void TouchHandleUp(void *data, uint32_t serial, uint32_t time, int32_t id);
void TouchHandleMotion(void *data, uint32_t time, int32_t id, double x, double y);
void TouchHandleFrame(void *data);
void TouchHandleShape(void *data, int32_t id, double major, double minor);
void TouchHandleOrientation(void *data, int32_t id, double orientation);
int32_t SendCallbackForMouse(void *data);
uint32_t GetMouseButton(uint32_t button);
void ProcessActionEvent(ActionEventInfo &actionEvent, TouchProperty &touchProperty);
void TouchEventEncap(ActionEventInfo &actionEvent, TouchEvent &touchEvent, int32_t size);
struct ActionEventInfo actionEventInfo = {};
void *touchWindows[MAX_TOUCH_NUM] = {};
struct MouseProperty mouseProperty;
uint32_t occurredTime = 0;
uint32_t buttonSerial = 0;
std::vector<sptr<MultimodalListener>> GetInputCallback(void *window);
std::map<void *, std::vector<sptr<MultimodalListener>>> windowCallback;
};
} // namespace OHOS
#endif // FRAMEWORKS_WM_INCLUDE_MULTIMODAL_LISTENER_MANAGER_H

View File

@ -23,7 +23,6 @@
#include <window_manager_service_client.h>
#include "log_listener.h"
#include "multimodal_listener_manager.h"
#include "wl_surface.h"
#include "window_attribute.h"
#include "window_option_impl.h"
@ -127,7 +126,6 @@ private:
sptr<Surface> psurface = nullptr;
sptr<InputListener> logListener = nullptr;
sptr<MultimodalListener> mmiListener = nullptr;
sptr<InputListener> exportListener = nullptr;
};
} // namespace OHOS

View File

@ -231,7 +231,6 @@ InnerWindowInfo *LayerControllerClient::CreateWindow(int32_t id, WindowConfig &c
auto info = GetInnerWindowInfoFromId(id);
info->logListener = LogListener::GetInstance()->AddListener(&info->windowid);
info->mmiListener = MultimodalListenerManager::GetInstance()->AddListener(&info->windowid);
return info;
}
@ -338,7 +337,6 @@ void LayerControllerClient::RegistOnTouchCb(int id, funcOnTouch cb)
if (cb) {
WMLOG_I("LayerControllerClient::RegistOnTouchCb OK");
GET_WINDOWINFO_VOID(windowInfo, id);
windowInfo->mmiListener->onTouchCb = cb;
}
}
@ -349,7 +347,6 @@ void LayerControllerClient::RegistOnKeyCb(int id, funcOnKey cb)
if (cb) {
WMLOG_I("LayerControllerClient::RegistOnKeyCb OK");
GET_WINDOWINFO_VOID(windowInfo, id);
windowInfo->mmiListener->keyboardKeyCb = cb;
}
}
@ -543,7 +540,6 @@ void ProcessWindowInfo(InnerWindowInfo &info, sptr<IWindowManagerService> &wms)
}
LogListener::GetInstance()->RemoveListener(info.logListener);
MultimodalListenerManager::GetInstance()->RemoveListener(info.mmiListener);
}
void LayerControllerClient::RemoveInnerWindowInfo(uint32_t id)

View File

@ -1,451 +0,0 @@
/*
* 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 "multimodal_listener_manager.h"
#include "window_manager_hilog.h"
namespace OHOS {
namespace {
constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0, "WMMultimodalListener" };
constexpr int32_t SEND_OK = 0;
constexpr int32_t SEND_ERROR = -1;
}
MultimodalListener::MultimodalListener(void *w)
{
window = w;
}
sptr<MultimodalListenerManager> MultimodalListenerManager::GetInstance()
{
if (instance == nullptr) {
static std::mutex mutex;
std::lock_guard<std::mutex> lock(mutex);
if (instance == nullptr) {
instance = new MultimodalListenerManager();
}
}
return instance;
}
sptr<MultimodalListener> MultimodalListenerManager::AddListener(void *window)
{
auto l = delegator.Dep<InputListenerManager>()->AddListener(window);
sptr<MultimodalListener> ml = new MultimodalListener(window);
ml->input = l;
l->pointerMotion = std::bind(&MultimodalListenerManager::PointerHandleMotion, this, POINTER_ENTER_ARG);
l->pointerButton = std::bind(&MultimodalListenerManager::PointerHandleButton, this, POINTER_BUTTON_ARG);
l->pointerFrame = std::bind(&MultimodalListenerManager::PointerHandleFrame, this, POINTER_FRAME_ARG);
l->pointerAxis = std::bind(&MultimodalListenerManager::PointerHandleAxis, this, POINTER_AXIS_ARG);
l->keyboardKey = std::bind(&MultimodalListenerManager::KeyboardHandleKey, this, KEYBOARD_KEY_ARG);
l->touchDown = std::bind(&MultimodalListenerManager::TouchHandleDown, this, TOUCH_DOWN_ARG);
l->touchUp = std::bind(&MultimodalListenerManager::TouchHandleUp, this, TOUCH_UP_ARG);
l->touchMotion = std::bind(&MultimodalListenerManager::TouchHandleMotion, this, TOUCH_MOTION_ARG);
l->touchFrame = std::bind(&MultimodalListenerManager::TouchHandleFrame, this, TOUCH_FRAME_ARG);
l->touchShape = std::bind(&MultimodalListenerManager::TouchHandleShape, this, TOUCH_SHAPE_ARG);
l->touchOrientation = std::bind(
&MultimodalListenerManager::TouchHandleOrientation, this, TOUCH_ORIENTATION_ARG);
if (windowCallback.find(window) == windowCallback.end()) {
windowCallback[window] = std::vector<sptr<MultimodalListener>>();
}
windowCallback[window].push_back(ml);
return ml;
}
void MultimodalListenerManager::RemoveListener(sptr<MultimodalListener> &listener)
{
if (listener == nullptr) {
return;
}
auto &v = windowCallback[listener->GetWindow()];
auto match = [&listener](const auto &l) {
return listener == l;
};
auto it = std::find_if(v.begin(), v.end(), match);
if (it != v.end()) {
v.erase(it);
}
if (v.empty()) {
windowCallback.erase(listener->GetWindow());
}
delegator.Dep<InputListenerManager>()->RemoveListener(listener->input);
}
void MultimodalListenerManager::PointerHandleMotion(void *data, uint32_t time, double x, double y)
{
if (static_cast<uint64_t>(mouseProperty.actionButton) & MouseEvent::LEFT_BUTTON) {
mouseProperty.action = MouseEvent::MOVE;
} else {
mouseProperty.action = MouseEvent::HOVER_MOVE;
}
MmiPoint point(x, y, 0);
mouseProperty.mmiPoint = point;
occurredTime = time;
SendCallbackForMouse(data);
}
uint32_t MultimodalListenerManager::GetMouseButton(uint32_t button)
{
constexpr uint32_t left = 0x110;
constexpr uint32_t right = 0x111;
constexpr uint32_t middle = 0x112;
constexpr uint32_t forward = 0x115;
constexpr uint32_t back = 0x116;
switch (button) {
case left:
return MouseEvent::LEFT_BUTTON;
case right:
return MouseEvent::RIGHT_BUTTON;
case middle:
return MouseEvent::MIDDLE_BUTTON;
case forward:
return MouseEvent::FORWARD_BUTTON;
case back:
return MouseEvent::BACK_BUTTON;
default:
return MouseEvent::NONE_BUTTON;
}
}
void MultimodalListenerManager::ProcessActionEvent(ActionEventInfo &actionEvent, TouchProperty &touchProperty)
{
constexpr uint32_t actionTypeOne = 1;
constexpr uint32_t actionTypeTwo = 2;
constexpr uint32_t actionTypeThree = 3;
constexpr uint32_t actionTypeFour = 4;
constexpr uint32_t actionTypeFive = 5;
if (actionEvent.isUp) {
if (actionEventInfo.touchCount == 0) {
touchProperty.action = actionTypeTwo;
} else {
touchProperty.action = actionTypeFive;
}
actionEvent.isUp = false;
} else if (actionEvent.isDown) {
if (actionEventInfo.touchCount == actionTypeOne) {
touchProperty.action = actionTypeOne;
} else {
touchProperty.action = actionTypeFour;
}
actionEvent.isDown = false;
} else if (actionEvent.isMotion) {
if (actionEventInfo.touchCount > 0) {
touchProperty.action = actionTypeThree;
}
actionEvent.isMotion = false;
}
}
void MultimodalListenerManager::TouchEventEncap(
ActionEventInfo &actionEvent, TouchEvent &touchEvent, int32_t size)
{
MultimodalProperty multimodalProperty = {
.highLevelEvent = 0,
.uuid = "",
.sourceType = 0,
.occurredTime = 0,
.deviceId = "",
.inputDeviceId = 0,
.isHighLevelEvent = false,
};
MmiPoint mp(0, 0, 0);
ManipulationProperty manipulationProperty = {
.startTime = 0,
.operationState = 0,
.pointerCount = 0,
.pointerId = 0,
.mp = MmiPoint(0, 0, 0),
.touchArea = 0,
.touchPressure = 0,
.offsetX = 0,
.offsetY = 0
};
TouchProperty touchProperty = {
.action = 0,
.index = 0,
.forcePrecision = 0,
.maxForce = 0,
.tapCount = 0
};
WMLOGFD("touchCount = %{public}d", actionEventInfo.touchCount);
ProcessActionEvent(actionEvent, touchProperty);
if (actionEvent.touchEventInfos[0].isRefreshed) {
mp.px_ = actionEvent.touchEventInfos[0].x;
mp.py_ = actionEvent.touchEventInfos[0].y;
manipulationProperty.startTime = actionEvent.touchEventInfos[0].startTime;
manipulationProperty.mp = mp;
manipulationProperty.touchPressure = actionEvent.touchEventInfos[0].touchPressure;
actionEvent.touchEventInfos[0].isRefreshed = false;
}
touchEvent.Initialize(multimodalProperty, manipulationProperty, touchProperty);
}
void MultimodalListenerManager::PointerHandleButton(void *data, uint32_t serial,
uint32_t time, uint32_t button, PointerButtonState state)
{
constexpr uint32_t buttonSerialBase = 1;
if (serial <= buttonSerial && serial > buttonSerialBase) {
WMLOGFI("recv repeat button %{public}d %{public}d %{public}d %{public}d",
serial, button, state, time);
return;
}
uint32_t changeButton = GetMouseButton(button);
uint32_t pressedButtons = mouseProperty.pressedButtons;
if (state == POINTER_BUTTON_STATE_PRESSED) {
pressedButtons |= changeButton;
} else {
pressedButtons ^= changeButton;
}
mouseProperty.pressedButtons = pressedButtons;
mouseProperty.actionButton = changeButton;
occurredTime = time;
int32_t result = SendCallbackForMouse(data);
if (result == SEND_OK) {
buttonSerial = serial;
}
}
void MultimodalListenerManager::PointerHandleFrame(void *data)
{
WMLOGFI("%{public}d %{public}f %{public}f %{public}d %{public}d",
mouseProperty.action,
mouseProperty.mmiPoint.GetX(), mouseProperty.mmiPoint.GetY(),
mouseProperty.actionButton, mouseProperty.pressedButtons);
SendCallbackForMouse(data);
}
void MultimodalListenerManager::PointerHandleAxis(void *data, uint32_t time, PointerAxis axis, double value)
{
mouseProperty.action = MouseEvent::SCROLL;
mouseProperty.scrollingDelta = value;
mouseProperty.scrollType = axis;
occurredTime = time;
}
void MultimodalListenerManager::KeyboardHandleKey(void *data,
uint32_t serial, uint32_t time, uint32_t key, KeyboardKeyState state)
{
KeyEvent event;
struct MultimodalProperty multiProperty = {
.highLevelEvent = 0,
.uuid = "",
.sourceType = MultimodalEvent::KEYBOARD,
.occurredTime = time,
.deviceId = "",
.inputDeviceId = 0,
.isHighLevelEvent = false,
};
struct KeyProperty keyProperty = {
.isPressed = (state == KEYBOARD_KEY_STATE_PRESSED),
.keyCode = key,
.keyDownDuration = 0,
};
static uint32_t keyDownTime = 0;
if (state == KEYBOARD_KEY_STATE_PRESSED) {
keyDownTime = time;
} else {
keyProperty.keyDownDuration = time - keyDownTime;
}
constexpr uint32_t linuxKeyBack = 158;
if (key == linuxKeyBack) {
keyProperty.keyCode = KeyEvent::CODE_BACK;
}
event.Initialize(multiProperty, keyProperty);
const auto &mls = GetInputCallback(data);
for (const auto &ml : mls) {
if (ml->keyboardKeyCb) {
ml->keyboardKeyCb(event);
}
}
}
void MultimodalListenerManager::TouchHandleDown(void *data,
uint32_t serial, uint32_t time, int32_t id, double x, double y)
{
if (id < MAX_TOUCH_NUM) {
actionEventInfo.touchCount++;
actionEventInfo.isDown = true;
actionEventInfo.touchEventInfos[id].isRefreshed = true;
actionEventInfo.touchEventInfos[id].serial = serial;
actionEventInfo.touchEventInfos[id].startTime = time;
actionEventInfo.touchEventInfos[id].currentTime = time;
actionEventInfo.touchEventInfos[id].x = x;
actionEventInfo.touchEventInfos[id].y = y;
}
if (id < MAX_TOUCH_NUM) {
touchWindows[id] = data;
}
}
void MultimodalListenerManager::TouchHandleUp(void *data, uint32_t serial, uint32_t time, int32_t id)
{
if (id < MAX_TOUCH_NUM) {
actionEventInfo.touchCount--;
actionEventInfo.isUp = true;
actionEventInfo.touchEventInfos[id].isRefreshed = true;
actionEventInfo.touchEventInfos[id].serial = serial;
actionEventInfo.touchEventInfos[id].currentTime = time;
}
void *window = nullptr;
if (id < MAX_TOUCH_NUM) {
window = touchWindows[id];
touchWindows[id] = nullptr;
}
WMLOGFD("window: %{public}p", window);
while (actionEventInfo.isUp || actionEventInfo.isDown || actionEventInfo.isMotion) {
TouchEvent touchEvent;
TouchEventEncap(actionEventInfo, touchEvent, MAX_TOUCH_NUM);
const auto &mls = GetInputCallback(data);
for (const auto &ml : mls) {
if (ml->onTouchCb) {
ml->onTouchCb(touchEvent);
}
}
}
}
void MultimodalListenerManager::TouchHandleMotion(void *data, uint32_t time, int32_t id, double x, double y)
{
if (id < MAX_TOUCH_NUM) {
actionEventInfo.isMotion = true;
actionEventInfo.touchEventInfos[id].isRefreshed = true;
actionEventInfo.touchEventInfos[id].currentTime = time;
actionEventInfo.touchEventInfos[id].x = x;
actionEventInfo.touchEventInfos[id].y = y;
}
void *window = nullptr;
if (id < MAX_TOUCH_NUM) {
window = touchWindows[id];
}
WMLOGFD("window: %{public}p", window);
}
void MultimodalListenerManager::TouchHandleFrame(void *data)
{
while (actionEventInfo.isUp || actionEventInfo.isDown || actionEventInfo.isMotion) {
TouchEvent touchEvent;
TouchEventEncap(actionEventInfo, touchEvent, MAX_TOUCH_NUM);
const auto &mls = GetInputCallback(data);
for (const auto &ml : mls) {
if (ml->onTouchCb) {
ml->onTouchCb(touchEvent);
}
}
}
}
void MultimodalListenerManager::TouchHandleShape(void *data, int32_t id, double major, double minor)
{
if (id < MAX_TOUCH_NUM) {
actionEventInfo.touchEventInfos[id].touchPressure = (major + minor) / 2.0f;
}
void *window = nullptr;
if (id < MAX_TOUCH_NUM) {
window = touchWindows[id];
}
WMLOGFD("window: %{public}p", window);
}
void MultimodalListenerManager::TouchHandleOrientation(void *data, int32_t id, double orientation)
{
void *window = nullptr;
if (id < MAX_TOUCH_NUM) {
window = touchWindows[id];
}
WMLOGFD("window: %{public}p", window);
}
int32_t MultimodalListenerManager::SendCallbackForMouse(void *data)
{
WMLOGFI("%{public}d %{public}f %{public}f %{public}d %{public}x",
mouseProperty.action,
mouseProperty.mmiPoint.GetX(),
mouseProperty.mmiPoint.GetY(),
mouseProperty.actionButton,
mouseProperty.pressedButtons);
TouchEvent touchEvent;
std::shared_ptr<MouseEvent> mouseEvent = std::make_shared<MouseEvent>();
struct MultimodalProperty multimodal = {
.highLevelEvent = 0,
.uuid = "",
.sourceType = MultimodalEvent::MOUSE,
.occurredTime = occurredTime,
.deviceId = "",
.inputDeviceId = 0,
.isHighLevelEvent = false,
};
struct ManipulationProperty manipulationProperty = {
.startTime = occurredTime,
.operationState = 0,
.pointerCount = 0,
.pointerId = 0,
.mp = MmiPoint(),
.touchArea = 0,
.touchPressure = 0,
.offsetX = 0,
.offsetY = 0
};
struct TouchProperty touch = {
.action = TouchEvent::OTHER,
.index = 0,
.forcePrecision = 0,
.maxForce = 0,
.tapCount = 0
};
mouseEvent->Initialize(multimodal, mouseProperty);
touchEvent.Initialize(multimodal, manipulationProperty, touch);
touchEvent.SetMultimodalEvent(mouseEvent);
const auto &mls = GetInputCallback(data);
for (const auto &ml : mls) {
if (ml->onTouchCb) {
ml->onTouchCb(touchEvent);
}
}
return SEND_ERROR;
}
std::vector<sptr<MultimodalListener>> MultimodalListenerManager::GetInputCallback(void *window)
{
static std::vector<sptr<MultimodalListener>> nullInputCallback;
if (windowCallback.find(window) == windowCallback.end()) {
return nullInputCallback;
}
return windowCallback[window];
}
} // namespace OHOS

View File

@ -162,7 +162,6 @@ WMError WindowImpl::Create(sptr<Window> &window,
}
wi->logListener = SingletonContainer::Get<LogListener>()->AddListener(wi.GetRefPtr());
wi->mmiListener = SingletonContainer::Get<MultimodalListenerManager>()->AddListener(wi.GetRefPtr());
wi->exportListener = SingletonContainer::Get<InputListenerManager>()->AddListener(wi.GetRefPtr());
window = wi;
@ -395,14 +394,12 @@ void WindowImpl::OnModeChange(WindowModeChangeFunc func)
WMError WindowImpl::OnTouch(OnTouchFunc cb)
{
CHECK_DESTROY(WM_ERROR_DESTROYED_OBJECT);
mmiListener->onTouchCb = cb;
return WM_OK;
}
WMError WindowImpl::OnKey(OnKeyFunc cb)
{
CHECK_DESTROY(WM_ERROR_DESTROYED_OBJECT);
mmiListener->keyboardKeyCb = cb;
return WM_OK;
}
@ -623,10 +620,6 @@ WindowImpl::~WindowImpl()
SingletonContainer::Get<LogListener>()->RemoveListener(logListener);
}
if (mmiListener != nullptr) {
SingletonContainer::Get<MultimodalListenerManager>()->RemoveListener(mmiListener);
}
if (exportListener != nullptr) {
SingletonContainer::Get<InputListenerManager>()->RemoveListener(exportListener);
}

View File

@ -21,7 +21,6 @@ group("unittest") {
deps = [
":input_listener_manager_test",
":log_listener_test",
":multimodal_listener_manager_test",
":subwindow_normal_impl_test",
":subwindow_option_impl_test",
":wayland_service_test",
@ -62,17 +61,6 @@ ohos_unittest("log_listener_test") {
## UnitTest log_listener_test }}}
## UnitTest multimodal_listener_manager_test {{{
ohos_unittest("multimodal_listener_manager_test") {
module_out_path = module_out_path
sources = [ "multimodal_listener_manager_test.cpp" ]
deps = [ ":wm_test_common" ]
}
## UnitTest multimodal_listener_manager_test }}}
## UnitTest subwindow_normal_impl_test {{{
ohos_unittest("subwindow_normal_impl_test") {
module_out_path = module_out_path

View File

@ -1,202 +0,0 @@
/*
* 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 "multimodal_listener_manager_test.h"
namespace OHOS {
void MultimodalListenerManagerTest::SetUp()
{
}
void MultimodalListenerManagerTest::TearDown()
{
}
void MultimodalListenerManagerTest::SetUpTestCase()
{
GTEST_LOG_(INFO) << getpid() << std::endl;
initRet = WindowManager::GetInstance()->Init();
}
void MultimodalListenerManagerTest::TearDownTestCase()
{
}
namespace {
/*
* Feature: MultimodalListenerManager AddListener
* Function: MultimodalListenerManager
* SubFunction: AddListener
* FunctionPoints: MultimodalListenerManager AddListener
* EnvConditions: WindowManager init success.
* CaseDescription: 1. add listener[0] by an address A
* 2. check listener[0]
* a. check listener[0] isn't nullptr
* b. check listener[0].GetWindow() is address A
* c. check map size is 1
* d. check vector size of address A is 1
* 3. add listener[1] by nullptr
* 4. check listener[1]
* a. check listener[1] isn't nullptr
* b. check listener[1].GetWindow() is nullptr
* c. check map size is 2
* d. check vector size of nullptr is 1
* 5. add listener[2] by the address A
* 6. check listener[2]
* a. check listener[2] isn't nullptr
* b. check listener[2].GetWindow() is address A
* c. check map size is 2
* d. check vector size of address A is 2
* 7. add listener[3] by nullptr
* 8. check listener[3]
* a. check listener[3] isn't nullptr
* b. check listener[3].GetWindow() is nullptr
* c. check map size is 2
* d. check vector size of nullptr is 2
*/
HWTEST_F(MultimodalListenerManagerTest, AddListener, testing::ext::TestSize.Level0)
{
// WindowManager init success.
ASSERT_EQ(initRet, WM_OK) << "EnvConditions: WindowManager init success. (initRet == WM_OK)";
auto manager = MultimodalListenerManager::GetInstance();
// 1. add listener[0] by an address A
listener[0] = manager->AddListener(&addressA);
// 2. check listener[0]
{
// a. check listener[0] isn't nullptr
ASSERT_NE(listener[0], nullptr) << "CaseDescription:"
<< " 2.a check listener[0] isn't nullptr (listener[0] != nullptr)";
// b. check listener[0].GetWindow() is address A
ASSERT_EQ(listener[0]->GetWindow(), &addressA) << "CaseDescription:"
<< " 2.b. check listener[0].GetWindow() is address A (listener[0].GetWindow() == address A)";
// c. check map size is 1
ASSERT_EQ(manager->windowCallback.size(), 1u) << "CaseDescription:"
<< " 2.c check map size is 1 (map.size() == 1)";
// d. check vector size of address A is 1
ASSERT_EQ(manager->windowCallback[&addressA].size(), 1u) << "CaseDescription:"
<< " 2.d check vector size of address A is 1 (vector.size() == 1)";
}
// 3. add listener[1] by nullptr
listener[1] = manager->AddListener(nullptr);
// 4. check listener[1]
{
// a. check listener[1] isn't nullptr
ASSERT_NE(listener[1], nullptr) << "CaseDescription:"
<< " 4.a check listener[1] isn't nullptr (listener[1] != nullptr)";
// b. check listener[1].GetWindow() is address A
ASSERT_EQ(listener[1]->GetWindow(), nullptr) << "CaseDescription:"
<< " 4.b. check listener[1].GetWindow() is address A (listener[1].GetWindow() == nullptr)";
// c. check map size is 2
ASSERT_EQ(manager->windowCallback.size(), 2u) << "CaseDescription:"
<< " 4.c check map size is 2 (map.size() == 2)";
// d. check vector size of nullptr is 1
ASSERT_EQ(manager->windowCallback[nullptr].size(), 1u) << "CaseDescription:"
<< " 4.d check vector size of nullptr is 1 (vector.size() == 1)";
}
// 5. add listener[2] by the address A
listener[2] = manager->AddListener(&addressA);
// 6. check listener[2]
{
// a. check listener[2] isn't nullptr
ASSERT_NE(listener[2], nullptr) << "CaseDescription:"
<< " 6.a check listener[2] isn't nullptr (listener[2] != nullptr)";
// b. check listener[2].GetWindow() is address A
ASSERT_EQ(listener[2]->GetWindow(), &addressA) << "CaseDescription:"
<< " 6.b. check listener[2].GetWindow() is address A (listener[2].GetWindow() == address A)";
// c. check map size is 2
ASSERT_EQ(manager->windowCallback.size(), 2u) << "CaseDescription:"
<< " 6.c check map size is 2 (map.size() == 2)";
// d. check vector size of address A is 2
ASSERT_EQ(manager->windowCallback[&addressA].size(), 2u) << "CaseDescription:"
<< " 6.d check vector size of address A is 2 (vector.size() == 2)";
}
// 7. add listener[3] by nullptr
listener[3] = manager->AddListener(nullptr);
// 8. check listener[3]
{
// a. check listener[3] isn't nullptr
ASSERT_NE(listener[3], nullptr) << "CaseDescription:"
<< " 8.a check listener[3] isn't nullptr (listener[3] != nullptr)";
// b. check listener[3].GetWindow() is address A
ASSERT_EQ(listener[3]->GetWindow(), nullptr) << "CaseDescription:"
<< " 8.b. check listener[3].GetWindow() is address A (listener[3].GetWindow() == nullptr)";
// c. check map size is 2
ASSERT_EQ(manager->windowCallback.size(), 2u) << "CaseDescription:"
<< " 8.c check map size is 2 (map.size() == 2)";
// d. check vector size of nullptr is 2
ASSERT_EQ(manager->windowCallback[nullptr].size(), 2u) << "CaseDescription:"
<< " 8.d check vector size of nullptr is 2 (vector.size() == 2)";
}
}
/*
* Feature: MultimodalListenerManager RemoveListener
* Function: MultimodalListenerManager
* SubFunction: RemoveListener
* FunctionPoints: MultimodalListenerManager RemoveListener
* EnvConditions: WindowManager init success.
* CaseDescription: 1. remove listener[0]
* 2. check map size is 2, check vector size of address A is 1
* 3. remove listener[2]
* 4. check map size is 1
* 5. remove listener[1], listener[3]
* 6. check map size is 0
*/
HWTEST_F(MultimodalListenerManagerTest, RemoveListener, testing::ext::TestSize.Level0)
{
// WindowManager init success.
ASSERT_EQ(initRet, WM_OK) << "EnvConditions: WindowManager init success. (initRet == WM_OK)";
auto manager = MultimodalListenerManager::GetInstance();
// 1. remove listener[0]
ASSERT_NE(listener[0], nullptr) << "CaseDescription: 1. remove listener[0] (listener[0] != nullptr)";
manager->RemoveListener(listener[0]);
// 2. check map size is 2, check vector size of address A is 1
ASSERT_EQ(manager->windowCallback.size(), 2u) << "CaseDescription:"
<< " 2. check map size is 2 (map.size() == 2)";
ASSERT_EQ(manager->windowCallback[&addressA].size(), 1u) << "CaseDescription:"
<< " 2. check vector size of address A is 1 (vector.size() == 1)";
// 3. remove listener[2]
ASSERT_NE(listener[2], nullptr) << "CaseDescription: 3. remove listener[2] (listener[2] != nullptr)";
manager->RemoveListener(listener[2]);
// 4. check map size is 1
ASSERT_EQ(manager->windowCallback.size(), 1u) << "CaseDescription:"
<< " 4. check map size is 1 (map.size() == 1)";
// 5. remove listener[1], listener[3]
ASSERT_NE(listener[1], nullptr) << "CaseDescription: 5. remove listener[1] (listener[1] != nullptr)";
ASSERT_NE(listener[3], nullptr) << "CaseDescription: 5. remove listener[3] (listener[3] != nullptr)";
manager->RemoveListener(listener[1]);
manager->RemoveListener(listener[3]);
// 6. check map size is 0
ASSERT_EQ(manager->windowCallback.size(), 0u) << "CaseDescription:"
<< " 6. check map size is 0 (map.size() == 0)";
}
} // namespace
} // namespace OHOS

View File

@ -1,40 +0,0 @@
/*
* 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_TEST_UNITTEST_MULTIMODAL_LISTENER_MANAGER_TEST_H
#define FRAMEWORKS_WM_TEST_UNITTEST_MULTIMODAL_LISTENER_MANAGER_TEST_H
#include <gtest/gtest.h>
#include <refbase.h>
#include <window_manager.h>
#include "multimodal_listener_manager.h"
namespace OHOS {
class MultimodalListenerManagerTest : public testing::Test {
public:
static void SetUpTestCase();
static void TearDownTestCase();
virtual void SetUp() override;
virtual void TearDown() override;
private:
static inline WMError initRet = WM_ERROR_NOT_INIT;
static inline sptr<MultimodalListener> listener[4] = {};
static inline int32_t addressA = 0;
};
}
#endif // FRAMEWORKS_WM_TEST_UNITTEST_MULTIMODAL_LISTENER_MANAGER_TEST_H

View File

@ -60,7 +60,7 @@ ohos_shared_library("wmserver") {
deps = [
":layout_header",
"//third_party/libinput:libinput-third",
"//foundation/multimodalinput/input/patch/diff_libinput_mmi:libinput-third-mmi",
"//third_party/wayland_standard:wayland_core_protocol",
"//third_party/weston:drm-backend",
"//third_party/weston:libexec_weston",
@ -93,7 +93,7 @@ ohos_executable("screen-info-test") {
deps = [
":wms_protocol",
"//third_party/libinput:libinput-third",
"//foundation/multimodalinput/input/patch/diff_libinput_mmi:libinput-third-mmi",
"//third_party/wayland_standard:libwayland_client",
]

View File

@ -201,6 +201,7 @@ struct LayerInfo *GetLayerInfo(struct ivi_layout_layer *layer)
pLayerInfo->surfaces = (struct SurfaceInfo **)calloc(surfaceCnt, sizeof(intptr_t));
if (!pLayerInfo->surfaces) {
LOGE("calloc error!");
free(surfaceList);
FreeLayerInfo(pLayerInfo);
return NULL;
}
@ -209,11 +210,13 @@ struct LayerInfo *GetLayerInfo(struct ivi_layout_layer *layer)
pLayerInfo->surfaces[j] = GetSurfaceInfo(surfaceList[j]);
if (!pLayerInfo->surfaces[j]) {
LOGE("GetSurfaceInfo error!");
free(surfaceList);
FreeLayerInfo(pLayerInfo);
return NULL;
}
pLayerInfo->surfaces[j]->onLayerId = pLayerInfo->layerId;
}
free(surfaceList);
}
return pLayerInfo;
}
@ -253,6 +256,7 @@ struct ScreenInfo *GetScreenInfo(const struct WmsScreen *pWmsScreen)
pScreenInfo->layers = (struct LayerInfo **)calloc(layerCount, sizeof(intptr_t));
if (!pScreenInfo->layers) {
LOGE("calloc error!");
free(layerList);
FreeScreenInfo(pScreenInfo);
return NULL;
}
@ -260,11 +264,13 @@ struct ScreenInfo *GetScreenInfo(const struct WmsScreen *pWmsScreen)
pScreenInfo->layers[i] = GetLayerInfo(layerList[i]);
if (!pScreenInfo->layers[i]) {
LOGE("calloc error!");
free(layerList);
FreeScreenInfo(pScreenInfo);
return NULL;
}
pScreenInfo->layers[i]->onScreenId = pScreenInfo->screenId;
}
free(layerList);
}
return pScreenInfo;
}

View File

@ -55,6 +55,7 @@
#define PIXMAN_FORMAT_AVERAGE 8
#define BYTE_SPP_SIZE 4
#define ASSERT assert
#define DEFAULT_SEAT_NAME "default"
struct WindowSurface {
struct WmsController *controller;
@ -359,47 +360,6 @@ static uint32_t GetWindowId(struct WmsController *pController)
return windowId;
}
static void SurfaceDestroy(struct WindowSurface *surface)
{
ASSERT(surface != NULL);
LOGD("surfaceId:%{public}d start.", surface->surfaceId);
wl_list_remove(&surface->surfaceDestroyListener.link);
wl_list_remove(&surface->propertyChangedListener.link);
if (surface->layoutSurface != NULL) {
surface->controller->pWmsCtx->pLayoutInterface->surface_destroy(
surface->layoutSurface);
}
ClearWindowId(surface->controller, surface->surfaceId);
wl_list_remove(&surface->link);
if (surface->surface) {
surface->surface->committed = NULL;
surface->surface->committed_private = NULL;
}
wms_send_window_status(surface->controller->pWlResource,
WMS_WINDOW_STATUS_DESTROYED, surface->surfaceId, 0, 0, 0, 0);
SendGlobalWindowStatus(surface->controller, surface->surfaceId, WMS_WINDOW_STATUS_DESTROYED);
free(surface);
LOGD(" end.");
}
static void WindowSurfaceDestroy(struct wl_listener *listener, void *data)
{
LOGD("start.");
struct WindowSurface *windowSurface = wl_container_of(listener, windowSurface, surfaceDestroyListener);
SurfaceDestroy(windowSurface);
LOGD("end.");
}
static struct ivi_layout_layer *GetLayer(struct weston_output *westonOutput,
struct ivi_layout_interface_for_wms *pLayoutInterface,
uint32_t layerId)
@ -944,7 +904,61 @@ static void PointerSetFocus(const struct WmsSeat *seat)
}
#endif
static bool FocusUpdate(const struct WindowSurface *surface)
static struct WmsSeat *GetWmsSeat(const char *seatName)
{
struct WmsContext *pWmsCtx = GetWmsInstance();
struct WmsSeat *pSeat = NULL;
wl_list_for_each(pSeat, &pWmsCtx->wlListSeat, wlListLink) {
if (!strcmp(pSeat->pWestonSeat->seat_name, seatName)) {
return pSeat;
}
}
return NULL;
}
static struct WindowSurface *GetDefaultFocusableWindow(uint32_t screenId)
{
struct WmsContext *pWmsCtx = GetWmsInstance();
struct WmsScreen *pWmsScreen = GetScreenFromId(pWmsCtx, screenId);
if (!pWmsScreen) {
LOGE("GetScreenFromId failed.");
return NULL;
}
int layerCount = 0;
struct ivi_layout_layer **layerList = NULL;
struct ivi_layout_interface_for_wms *pLayoutInterface = pWmsCtx->pLayoutInterface;
pLayoutInterface->get_layers_on_screen(pWmsScreen->westonOutput, &layerCount, &layerList);
for (int i = layerCount - 1; i >= 0; i--) {
int surfaceCnt = 0;
struct ivi_layout_surface **surfaceList = NULL;
pLayoutInterface->get_surfaces_on_layer(layerList[i], &surfaceCnt, &surfaceList);
for (int j = surfaceCnt - 1; j >= 0; j--) {
struct WindowSurface *pWindow = GetSurface(&pWmsCtx->wlListWindow, surfaceList[j]->id_surface);
if (pWindow && pWindow->type != WINDOW_TYPE_STATUS_BAR
&& pWindow->type != WINDOW_TYPE_NAVI_BAR) {
LOGI("DefaultFocusableWindow found %{public}d.", pWindow->surfaceId);
free(surfaceList);
free(layerList);
return pWindow;
}
}
if (surfaceCnt > 0) {
free(surfaceList);
}
}
if (layerCount > 0) {
free(layerList);
}
LOGI("DefaultFocusableWindow not found.");
return NULL;
}
static bool SetWindowFocus(const struct WindowSurface *surface)
{
LOGD("start.");
int flag = INPUT_DEVICE_ALL;
@ -975,25 +989,21 @@ static bool FocusUpdate(const struct WindowSurface *surface)
}
pInputInterface->set_focus(surface->surfaceId, flag, true);
free(surfaceList);
#else
struct WmsContext *pWmsCtx = surface->controller->pWmsCtx;
struct WmsScreen *pScreen = GetScreen(surface);
if (!pScreen) {
LOGE("GetScreen error.");
if (surfaceCount) {
free(surfaceList);
}
#endif
struct WmsSeat *pSeat = GetWmsSeat(DEFAULT_SEAT_NAME);
if (!pSeat) {
LOGE("GetWmsSeat error.");
return false;
}
struct WmsSeat *pSeat = NULL;
wl_list_for_each(pSeat, &pWmsCtx->wlListSeat, wlListLink) {
if (!strcmp(pSeat->pWestonSeat->seat_name, "default")) {
pSeat->deviceFlags = flag;
pSeat->focusWindowId = surface->surfaceId;
PointerSetFocus(pSeat);
}
}
SeatInfoChangerNotify();
pSeat->deviceFlags = flag;
pSeat->focusWindowId = surface->surfaceId;
#ifndef USE_IVI_INPUT_FOCUS
PointerSetFocus(pSeat);
#endif
SeatInfoChangerNotify();
LOGD("end.");
return true;
@ -1027,6 +1037,25 @@ static void ControllerSetStatusBarVisibility(const struct wl_client *client,
LOGD("end.");
}
static bool FocusWindowUpdate(const struct WindowSurface *surface)
{
struct WmsSeat *pSeat = GetWmsSeat(DEFAULT_SEAT_NAME);
if (!pSeat) {
LOGE("GetWmsSeat error.");
return false;
}
if (pSeat->focusWindowId == surface->surfaceId) {
struct WindowSurface *focus = GetDefaultFocusableWindow(surface->screenId);
if (focus && !SetWindowFocus(focus)) {
LOGE("SetWindowFocus failed.");
return false;
}
}
return true;
}
static void ControllerSetNavigationBarVisibility(const struct wl_client *client,
const struct wl_resource *resource,
uint32_t visibility)
@ -1078,8 +1107,9 @@ static void ControllerSetWindowTop(struct wl_client *client,
}
ctx->pLayoutInterface->surface_change_top(windowSurface->layoutSurface);
if (!FocusUpdate(windowSurface)) {
LOGE("FocusUpdate failed.");
if (!SetWindowFocus(windowSurface)) {
LOGE("SetWindowFocus failed.");
wms_send_reply_error(resource, WMS_ERROR_INNER_ERROR);
return;
}
@ -1088,6 +1118,42 @@ static void ControllerSetWindowTop(struct wl_client *client,
LOGD("end.");
}
static void SurfaceDestroy(const struct WindowSurface *surface)
{
ASSERT(surface != NULL);
LOGD("surfaceId:%{public}d start.", surface->surfaceId);
wl_list_remove(&surface->surfaceDestroyListener.link);
wl_list_remove(&surface->propertyChangedListener.link);
if (surface->layoutSurface != NULL) {
surface->controller->pWmsCtx->pLayoutInterface->surface_destroy(
surface->layoutSurface);
}
ClearWindowId(surface->controller, surface->surfaceId);
wl_list_remove(&surface->link);
if (surface->surface) {
surface->surface->committed = NULL;
surface->surface->committed_private = NULL;
}
if (!FocusWindowUpdate(surface)) {
LOGE("FocusWindowUpdate failed.");
}
wms_send_window_status(surface->controller->pWlResource,
WMS_WINDOW_STATUS_DESTROYED, surface->surfaceId, 0, 0, 0, 0);
SendGlobalWindowStatus(surface->controller, surface->surfaceId, WMS_WINDOW_STATUS_DESTROYED);
ScreenInfoChangerNotify();
free(surface);
LOGD(" end.");
}
static void ControllerDestroyWindow(struct wl_client *client,
struct wl_resource *resource, uint32_t windowId)
{
@ -1121,6 +1187,17 @@ static void WindowPropertyChanged(struct wl_listener *listener, void *data)
LOGD("end.");
}
static void WindowSurfaceDestroy(const struct wl_listener *listener,
const struct weston_compositor *data)
{
LOGD("start.");
struct WindowSurface *windowSurface = wl_container_of(listener, windowSurface, surfaceDestroyListener);
SurfaceDestroy(windowSurface);
LOGD("end.");
}
static void CreateWindow(struct WmsController *pWmsController,
struct weston_surface *pWestonSurface,
uint32_t windowId, uint32_t screenId, uint32_t windowType)

View File

@ -18,7 +18,6 @@
#include <display_device.h>
#define USE_IVI_INPUT_FOCUS
#ifdef USE_IVI_INPUT_FOCUS
#include <ivi-input-export.h>
#endif