demend & test of water mark

Signed-off-by: zhangkai <zhangkai324@huawei.com>
Change-Id: Ic68c249bb7100781fbf65dec3f23e3b696290353
This commit is contained in:
zhangkai 2023-03-01 10:57:03 +08:00
parent 60f1ef4aa2
commit 58d3e0281b
23 changed files with 618 additions and 6 deletions

View File

@ -111,6 +111,11 @@ public:
virtual void OnWindowUpdate(const std::vector<sptr<AccessibilityWindowInfo>>& infos, WindowUpdateType type) = 0;
};
class IWaterMarkFlagChangedListener : virtual public RefBase {
public:
virtual void OnWaterMarkFlagUpdate(bool showWaterMark) = 0;
};
class ICameraFloatWindowChangedListener : virtual public RefBase {
public:
virtual void OnCameraFloatWindowChange(uint32_t accessTokenId, bool isShowing) = 0;
@ -131,6 +136,8 @@ public:
WMError UnregisterVisibilityChangedListener(const sptr<IVisibilityChangedListener>& listener);
WMError RegisterCameraFloatWindowChangedListener(const sptr<ICameraFloatWindowChangedListener>& listener);
WMError UnregisterCameraFloatWindowChangedListener(const sptr<ICameraFloatWindowChangedListener>& listener);
WMError RegisterWaterMarkFlagChangedListener(const sptr<IWaterMarkFlagChangedListener>& listener);
WMError UnregisterWaterMarkFlagChangedListener(const sptr<IWaterMarkFlagChangedListener>& listener);
WMError MinimizeAllAppWindows(DisplayId displayId);
WMError ToggleShownStateForAllAppWindows();
WMError SetWindowLayoutMode(WindowLayoutMode mode);
@ -152,6 +159,7 @@ private:
void UpdateWindowVisibilityInfo(
const std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfos) const;
void UpdateCameraFloatWindowStatus(uint32_t accessTokenId, bool isShowing) const;
void NotifyWaterMarkFlagChangedResult(bool showWaterMark) const;
void OnRemoteDied() const;
};
} // namespace Rosen

View File

@ -190,7 +190,8 @@ enum class WindowFlag : uint32_t {
WINDOW_FLAG_PARENT_LIMIT = 1 << 1,
WINDOW_FLAG_SHOW_WHEN_LOCKED = 1 << 2,
WINDOW_FLAG_FORBID_SPLIT_MOVE = 1 << 3,
WINDOW_FLAG_END = 1 << 4,
WINDOW_FLAG_WATER_MARK = 1 << 4,
WINDOW_FLAG_END = 1 << 5,
};
enum class WindowSizeChangeReason : uint32_t {

View File

@ -41,7 +41,6 @@ public:
static NativeValue* GetTopWindow(NativeEngine* engine, NativeCallbackInfo* info);
static NativeValue* GetLastWindow(NativeEngine* engine, NativeCallbackInfo* info);
static NativeValue* SetWindowLayoutMode(NativeEngine* engine, NativeCallbackInfo* info);
private:
static NativeValue* OnCreate(NativeEngine& engine, NativeCallbackInfo& info);
static NativeValue* OnCreateWindow(NativeEngine& engine, NativeCallbackInfo& info);

View File

@ -581,6 +581,13 @@ NativeValue* JsWindow::SetBackdropBlurStyle(NativeEngine* engine, NativeCallback
return (me != nullptr) ? me->OnSetBackdropBlurStyle(*engine, *info) : nullptr;
}
NativeValue* JsWindow::SetWaterMarkFlag(NativeEngine* engine, NativeCallbackInfo* info)
{
WLOGI("SetWaterMarkFlag");
JsWindow* me = CheckParamsAndGetThis<JsWindow>(engine, info);
return (me != nullptr) ? me->OnSetWaterMarkFlag(*engine, *info) : nullptr;
}
NativeValue* JsWindow::SetAspectRatio(NativeEngine* engine, NativeCallbackInfo* info)
{
WLOGI("[NAPI]SetAspectRatio");
@ -3674,6 +3681,57 @@ NativeValue* JsWindow::OnSetBackdropBlurStyle(NativeEngine& engine, NativeCallba
return engine.CreateUndefined();
}
NativeValue* JsWindow::OnSetWaterMarkFlag(NativeEngine& engine, NativeCallbackInfo& info)
{
if (info.argc < 1) {
WLOGFE("Argc is invalid: %{public}zu", info.argc);
engine.Throw(CreateJsError(engine, static_cast<int32_t>(WmErrorCode::WM_ERROR_INVALID_PARAM)));
return engine.CreateUndefined();
}
NativeBoolean* nativeBool = ConvertNativeValueTo<NativeBoolean>(info.argv[0]);
if (nativeBool == nullptr) {
WLOGFE("SetWaterMarkFlag Invalid window flag");
engine.Throw(CreateJsError(engine, static_cast<int32_t>(WmErrorCode::WM_ERROR_INVALID_PARAM)));
return engine.CreateUndefined();
}
bool isAddSafetyLayer = static_cast<bool>(*nativeBool);
wptr<Window> weakToken(windowToken_);
AsyncTask::CompleteCallback complete =
[weakToken, isAddSafetyLayer](NativeEngine& engine, AsyncTask& task, int32_t status) {
auto window = weakToken.promote();
if (window == nullptr) {
task.Reject(engine,
CreateJsError(engine, static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY),
"OnSetWaterMarkFlag failed."));
return;
}
WMError ret = WMError::WM_OK;
if (isAddSafetyLayer) {
ret = window->AddWindowFlag(WindowFlag::WINDOW_FLAG_WATER_MARK);
} else {
ret = window->RemoveWindowFlag(WindowFlag::WINDOW_FLAG_WATER_MARK);
}
if (ret == WMError::WM_OK) {
task.Resolve(engine, engine.CreateUndefined());
} else {
task.Reject(engine, CreateJsError(engine,
static_cast<int32_t>(WM_JS_TO_ERROR_CODE_MAP.at(ret)), "SetWaterMarkFlag failed."));
}
WLOGI("[NAPI]Window [%{public}u, %{public}s] set waterMark flag end, ret = %{public}d",
window->GetWindowId(), window->GetWindowName().c_str(), ret);
};
NativeValue* lastParam = (info.argc == 1) ? nullptr :
(info.argv[1]->TypeOf() == NATIVE_FUNCTION ? info.argv[1] : nullptr);
NativeValue* result = nullptr;
AsyncTask::Schedule("JsWindow::OnSetWaterMarkFlag",
engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
return result;
}
NativeValue* JsWindow::OnSetAspectRatio(NativeEngine& engine, NativeCallbackInfo& info)
{
WMError errCode = WMError::WM_OK;
@ -3885,6 +3943,7 @@ void BindFunctions(NativeEngine& engine, NativeObject* object, const char *modul
BindNativeFunction(engine, *object, "setBackdropBlurStyle", moduleName, JsWindow::SetBackdropBlurStyle);
BindNativeFunction(engine, *object, "setAspectRatio", moduleName, JsWindow::SetAspectRatio);
BindNativeFunction(engine, *object, "resetAspectRatio", moduleName, JsWindow::ResetAspectRatio);
BindNativeFunction(engine, *object, "setWaterMarkFlag", moduleName, JsWindow::SetWaterMarkFlag);
}
} // namespace Rosen
} // namespace OHOS

View File

@ -117,6 +117,7 @@ public:
static NativeValue* SetBlur(NativeEngine* engine, NativeCallbackInfo* info);
static NativeValue* SetBackdropBlur(NativeEngine* engine, NativeCallbackInfo* info);
static NativeValue* SetBackdropBlurStyle(NativeEngine* engine, NativeCallbackInfo* info);
static NativeValue* SetWaterMarkFlag(NativeEngine* engine, NativeCallbackInfo* info);
private:
std::string GetWindowName();
static bool ParseScaleOption(NativeEngine& engine, NativeObject* jsObject, Transform& trans);
@ -204,6 +205,7 @@ private:
NativeValue* OnSetBlur(NativeEngine& engine, NativeCallbackInfo& info);
NativeValue* OnSetBackdropBlur(NativeEngine& engine, NativeCallbackInfo& info);
NativeValue* OnSetBackdropBlurStyle(NativeEngine& engine, NativeCallbackInfo& info);
NativeValue* OnSetWaterMarkFlag(NativeEngine& engine, NativeCallbackInfo& info);
sptr<Window> windowToken_ = nullptr;
std::unique_ptr<JsWindowRegisterManager> registerManager_ = nullptr;

View File

@ -12,6 +12,7 @@
# limitations under the License.
import("//build/ohos.gni")
import("//foundation/window/window_manager/windowmanager_aafwk.gni")
group("demo") {
testonly = true
@ -22,6 +23,7 @@ group("demo") {
":demo_screenshot_listener",
":demo_snapshot_virtual_screen",
":demo_system_sub_window",
":demo_water_mark_listener",
]
}
@ -116,3 +118,22 @@ ohos_executable("demo_freeze_display") {
part_name = "window_manager"
subsystem_name = "window"
}
ohos_executable("demo_water_mark_listener") {
sources = [ "demo_water_mark_listener.cpp" ]
include_dirs = [
"${window_base_path}/interfaces/innerkits/wm",
"${window_base_path}/test/common/utils/include",
]
deps = [
"${graphic_base_path}/graphic_2d/rosen/modules/render_service_base:librender_service_base",
"${window_base_path}/wm:libwm",
]
external_deps = [ "c_utils:utils" ]
part_name = "window_manager"
subsystem_name = "window"
}

View File

@ -0,0 +1,67 @@
/*
* Copyright (c) 2023 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 <iostream>
#include <refbase.h>
#include <unistd.h>
#include "window.h"
#include "wm_common.h"
#include "window_option.h"
#include "window_manager.h"
#include "future.h"
namespace OHOS {
namespace Rosen {
class WaterMarkFlagChangedListenerFuture : public IWaterMarkFlagChangedListener {
public:
void OnWaterMarkFlagUpdate(bool showWaterMark) override
{
future_.SetValue(showWaterMark);
};
RunnableFuture<bool> future_;
static constexpr long WAIT_TIME = 20000;
};
}
}
using namespace OHOS;
using namespace OHOS::Rosen;
int main(int argc, char *argv[])
{
std::cout << "===========================Start===========================" << std::endl;
std::cout << "RegisterWaterMarkFlagChangedListener" << std::endl;
sptr<WaterMarkFlagChangedListenerFuture> listener = new WaterMarkFlagChangedListenerFuture();
if (listener == nullptr) {
return 0;
}
WindowManager::GetInstance().RegisterWaterMarkFlagChangedListener(listener);
std::cout << "You can open a window with water mark flag in during 20s" << std::endl;
auto result = listener->future_.GetResult(WaterMarkFlagChangedListenerFuture::WAIT_TIME);
std::cout << "callback result = " << result << std::endl;
listener->future_.Reset(result);
std::cout << "You can close the window, hide it, or change the flag in during 20s" << std::endl;
result = listener->future_.GetResult(WaterMarkFlagChangedListenerFuture::WAIT_TIME);
std::cout << "callback result = " << result << std::endl;
WindowManager::GetInstance().UnregisterWaterMarkFlagChangedListener(listener);
std::cout << "============================End============================" << std::endl;
return 0;
}

View File

@ -44,6 +44,7 @@ group("systemtest") {
":wms_window_systemsubwindow_test",
":wms_window_touch_outside_test",
":wms_window_visibility_info_test",
":wms_window_water_mark_test",
]
}
@ -247,6 +248,14 @@ ohos_systemtest("wms_window_animation_transition_test") {
deps = [ ":wms_systemtest_common" ]
}
ohos_systemtest("wms_window_water_mark_test") {
module_out_path = module_out_path
sources = [ "window_water_mark_test.cpp" ]
deps = [ ":wms_systemtest_common" ]
}
## Build wms_systemtest_common.a {{{
config("wms_systemtest_common_public_config") {
include_dirs = [

View File

@ -23,11 +23,10 @@
#include <transaction/rs_transaction.h>
#include "display_manager.h"
#include "wm_common.h"
#include "window_manager.h"
#include "window_test_utils.h"
#include "surface_draw.h"
#include "window_manager.h"
#include "window_test_utils.h"
#include "wm_common.h"
using namespace testing;
using namespace testing::ext;

View File

@ -0,0 +1,159 @@
/*
* Copyright (c) 2023 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.
*/
// gtest
#include <gtest/gtest.h>
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <mutex>
#include <transaction/rs_transaction.h>
#include "display_manager.h"
#include "surface_draw.h"
#include "window_test_utils.h"
#include "window_manager.h"
#include "wm_common.h"
using namespace testing;
using namespace testing::ext;
namespace OHOS {
namespace Rosen {
namespace {
constexpr uint32_t COLOR_RED = 0xffff0000;
constexpr uint8_t ALPHA = 255;
constexpr int NORMAL_SLEEP_TIME = 3; // 1s
constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowWaterMarkTest"};
}
using Utils = WindowTestUtils;
class TestIWaterMarkFlagChangedListener : public IWaterMarkFlagChangedListener {
public:
void OnWaterMarkFlagUpdate(bool showWaterMark) override;
bool isShowing_ = false;
bool isCallbackCalled_ = false;
};
void TestIWaterMarkFlagChangedListener::OnWaterMarkFlagUpdate(bool showWaterMark)
{
WLOGFI("water mark flag update result:%{public}d", showWaterMark);
isShowing_ = showWaterMark;
isCallbackCalled_ = true;
}
class WaterMarkTest : public testing::Test {
public:
static void SetUpTestCase();
static void TearDownTestCase();
void SetUp() override;
void TearDown() override;
bool FillColor(sptr<Window> window);
static sptr<TestIWaterMarkFlagChangedListener> lisenter_;
Utils::TestWindowInfo appInfo_;
sptr<Window> CreateWindow(const Utils::TestWindowInfo& appinfo);
};
sptr<TestIWaterMarkFlagChangedListener> WaterMarkTest::lisenter_ = nullptr;
void WaterMarkTest::SetUpTestCase()
{
lisenter_= new TestIWaterMarkFlagChangedListener();
WindowManager::GetInstance().RegisterWaterMarkFlagChangedListener(lisenter_);
}
void WaterMarkTest::TearDownTestCase()
{
WindowManager::GetInstance().UnregisterWaterMarkFlagChangedListener(lisenter_);
}
void WaterMarkTest::SetUp()
{
appInfo_ = {
.name = "testWindow",
.rect = Utils::customAppRect_,
.type = WindowType::WINDOW_TYPE_APP_MAIN_WINDOW,
.mode = WindowMode::WINDOW_MODE_FLOATING,
.needAvoid = false,
.parentLimit = false,
.showWhenLocked = true,
.parentId = INVALID_WINDOW_ID,
};
}
void WaterMarkTest::TearDown()
{
}
sptr<Window> WaterMarkTest::CreateWindow(const Utils::TestWindowInfo& appinfo)
{
sptr<WindowOption> option = new WindowOption();
option->SetWindowRect(appinfo.rect);
option->SetWindowType(appinfo.type);
option->SetWindowMode(appinfo.mode);
sptr<Window> window = Window::Create(appinfo.name, option);
return window;
}
bool WaterMarkTest::FillColor(sptr<Window> window)
{
if (window == nullptr) {
return false;
}
auto surfaceNode = window->GetSurfaceNode();
if (surfaceNode == nullptr) {
return false;
}
Rect rect = window->GetRect();
bool isDrawSuccess = SurfaceDraw::DrawColor(surfaceNode, rect.width_, rect.height_, COLOR_RED);
surfaceNode->SetAbilityBGAlpha(ALPHA);
RSTransaction::FlushImplicitTransaction();
return isDrawSuccess;
}
namespace {
/**
* @tc.name: WindowVisibilityInfoTest01
* @tc.desc: window show or hide
* @tc.type: FUNC
* @tc.require: issueI5FSQW
*/
HWTEST_F(WaterMarkTest, SetWaterMarkFlag01, Function | MediumTest | Level1)
{
appInfo_.name = "window1";
appInfo_.rect = {0, 0, 300, 100};
sptr<Window> window = CreateWindow(appInfo_);
ASSERT_NE(window, nullptr);
window->Show();
sleep(NORMAL_SLEEP_TIME);
auto drawSuccess = FillColor(window);
sleep(NORMAL_SLEEP_TIME);
ASSERT_TRUE(drawSuccess);
window->AddWindowFlag(WindowFlag::WINDOW_FLAG_WATER_MARK);
sleep(NORMAL_SLEEP_TIME);
ASSERT_EQ(lisenter_->isShowing_, true);
window->Destroy();
sleep(NORMAL_SLEEP_TIME);
}
}
} // namespace Rosen
} // namespace OHOS

View File

@ -32,6 +32,7 @@ public:
WindowUpdateType type) override;
void UpdateWindowVisibilityInfo(const std::vector<sptr<WindowVisibilityInfo>>& visibilityInfos) override;
void UpdateCameraFloatWindowStatus(uint32_t accessTokenId, bool isShowing) override;
void NotifyWaterMarkFlagChangedResult(bool showWaterMark) override;
};
} // namespace Rosen
} // namespace OHOS

View File

@ -28,6 +28,7 @@ enum class WindowManagerAgentType : uint32_t {
WINDOW_MANAGER_AGENT_TYPE_WINDOW_UPDATE,
WINDOW_MANAGER_AGENT_TYPE_WINDOW_VISIBILITY,
WINDOW_MANAGER_AGENT_TYPE_CAMERA_FLOAT,
WINDOW_MANAGER_AGENT_TYPE_WATER_MARK_FLAG,
};
class IWindowManagerAgent : public IRemoteBroker {
@ -40,6 +41,7 @@ public:
TRANS_ID_UPDATE_WINDOW_STATUS,
TRANS_ID_UPDATE_WINDOW_VISIBILITY,
TRANS_ID_UPDATE_CAMERA_FLOAT,
TRANS_ID_UPDATE_WATER_MARK_FLAG,
};
virtual void UpdateFocusChangeInfo(const sptr<FocusChangeInfo>& focusChangeInfo, bool focused) = 0;
@ -48,6 +50,7 @@ public:
WindowUpdateType type) = 0;
virtual void UpdateWindowVisibilityInfo(const std::vector<sptr<WindowVisibilityInfo>>& visibilityInfos) = 0;
virtual void UpdateCameraFloatWindowStatus(uint32_t accessTokenId, bool isShowing) = 0;
virtual void NotifyWaterMarkFlagChangedResult(bool isShowing) = 0;
};
} // namespace Rosen
} // namespace OHOS

View File

@ -33,6 +33,7 @@ public:
WindowUpdateType type) override;
void UpdateWindowVisibilityInfo(const std::vector<sptr<WindowVisibilityInfo>>& visibilityInfos) override;
void UpdateCameraFloatWindowStatus(uint32_t accessTokenId, bool isShowing) override;
void NotifyWaterMarkFlagChangedResult(bool showWaterMark) override;
private:
static inline BrokerDelegator<WindowManagerAgentProxy> delegator_;

View File

@ -121,6 +121,7 @@ public:
void NotifyAccessibilityWindowInfo(const std::vector<sptr<AccessibilityWindowInfo>>& infos, WindowUpdateType type);
void NotifyWindowVisibilityInfoChanged(const std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfos);
void UpdateCameraFloatWindowStatus(uint32_t accessTokenId, bool isShowing);
void NotifyWaterMarkFlagChangedResult(bool showWaterMark);
static inline SingletonDelegator<WindowManager> delegator_;
std::recursive_mutex mutex_;
@ -134,6 +135,8 @@ public:
sptr<WindowManagerAgent> windowVisibilityListenerAgent_;
std::vector<sptr<ICameraFloatWindowChangedListener>> cameraFloatWindowChangedListeners_;
sptr<WindowManagerAgent> cameraFloatWindowChangedListenerAgent_;
std::vector<sptr<IWaterMarkFlagChangedListener>> waterMarkFlagChangeListeners_;
sptr<WindowManagerAgent> waterMarkFlagChangeAgent_;
};
void WindowManager::Impl::NotifyFocused(const sptr<FocusChangeInfo>& focusChangeInfo)
@ -237,6 +240,19 @@ void WindowManager::Impl::UpdateCameraFloatWindowStatus(uint32_t accessTokenId,
}
}
void WindowManager::Impl::NotifyWaterMarkFlagChangedResult(bool showWaterMark)
{
WLOGFI("Notify water mark flag changed result, showWaterMark = %{public}d", showWaterMark);
std::vector<sptr<IWaterMarkFlagChangedListener>> waterMarkFlagChangeListeners;
{
std::lock_guard<std::recursive_mutex> lock(mutex_);
waterMarkFlagChangeListeners = waterMarkFlagChangeListeners_;
}
for (auto& listener : waterMarkFlagChangeListeners) {
listener->OnWaterMarkFlagUpdate(showWaterMark);
}
}
WindowManager::WindowManager() : pImpl_(std::make_unique<Impl>()) {}
WMError WindowManager::RegisterFocusChangedListener(const sptr<IFocusChangedListener>& listener)
@ -285,6 +301,9 @@ WMError WindowManager::UnregisterFocusChangedListener(const sptr<IFocusChangedLi
if (pImpl_->focusChangedListeners_.empty() && pImpl_->focusChangedListenerAgent_ != nullptr) {
ret = SingletonContainer::Get<WindowAdapter>().UnregisterWindowManagerAgent(
WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_FOCUS, pImpl_->focusChangedListenerAgent_);
if (ret != WMError::WM_OK) {
return WMError::WM_OK;
}
pImpl_->focusChangedListenerAgent_ = nullptr;
}
return ret;
@ -338,6 +357,9 @@ WMError WindowManager::UnregisterSystemBarChangedListener(const sptr<ISystemBarC
if (pImpl_->systemBarChangedListeners_.empty() && pImpl_->systemBarChangedListenerAgent_ != nullptr) {
ret = SingletonContainer::Get<WindowAdapter>().UnregisterWindowManagerAgent(
WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_SYSTEM_BAR, pImpl_->systemBarChangedListenerAgent_);
if (ret != WMError::WM_OK) {
return WMError::WM_OK;
}
pImpl_->systemBarChangedListenerAgent_ = nullptr;
}
return ret;
@ -409,6 +431,9 @@ WMError WindowManager::UnregisterWindowUpdateListener(const sptr<IWindowUpdateLi
if (pImpl_->windowUpdateListeners_.empty() && pImpl_->windowUpdateListenerAgent_ != nullptr) {
ret = SingletonContainer::Get<WindowAdapter>().UnregisterWindowManagerAgent(
WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_UPDATE, pImpl_->windowUpdateListenerAgent_);
if (ret != WMError::WM_OK) {
return WMError::WM_OK;
}
pImpl_->windowUpdateListenerAgent_ = nullptr;
}
return ret;
@ -460,6 +485,9 @@ WMError WindowManager::UnregisterVisibilityChangedListener(const sptr<IVisibilit
ret = SingletonContainer::Get<WindowAdapter>().UnregisterWindowManagerAgent(
WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_VISIBILITY,
pImpl_->windowVisibilityListenerAgent_);
if (ret != WMError::WM_OK) {
return WMError::WM_OK;
}
pImpl_->windowVisibilityListenerAgent_ = nullptr;
}
return ret;
@ -517,11 +545,75 @@ WMError WindowManager::UnregisterCameraFloatWindowChangedListener(
ret = SingletonContainer::Get<WindowAdapter>().UnregisterWindowManagerAgent(
WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_CAMERA_FLOAT,
pImpl_->cameraFloatWindowChangedListenerAgent_);
if (ret != WMError::WM_OK) {
return WMError::WM_OK;
}
pImpl_->cameraFloatWindowChangedListenerAgent_ = nullptr;
}
return ret;
}
WMError WindowManager::RegisterWaterMarkFlagChangedListener(const sptr<IWaterMarkFlagChangedListener>& listener)
{
if (listener == nullptr) {
WLOGFE("listener could not be null");
return WMError::WM_ERROR_NULLPTR;
}
std::lock_guard<std::recursive_mutex> lock(pImpl_->mutex_);
WMError ret = WMError::WM_OK;
if (pImpl_->waterMarkFlagChangeAgent_ == nullptr) {
pImpl_->waterMarkFlagChangeAgent_ = new WindowManagerAgent();
ret = SingletonContainer::Get<WindowAdapter>().RegisterWindowManagerAgent(
WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WATER_MARK_FLAG,
pImpl_->waterMarkFlagChangeAgent_);
}
if (ret != WMError::WM_OK) {
WLOGFW("RegisterWindowManagerAgent failed !");
pImpl_->waterMarkFlagChangeAgent_ = nullptr;
} else {
auto iter = std::find(pImpl_->waterMarkFlagChangeListeners_.begin(),
pImpl_->waterMarkFlagChangeListeners_.end(), listener);
if (iter != pImpl_->waterMarkFlagChangeListeners_.end()) {
WLOGFW("Listener is already registered.");
return WMError::WM_OK;
}
pImpl_->waterMarkFlagChangeListeners_.push_back(listener);
}
WLOGFD("Try to registerWaterMarkFlagChangedListener && result : %{public}u", static_cast<uint32_t>(ret));
return ret;
}
WMError WindowManager::UnregisterWaterMarkFlagChangedListener(const sptr<IWaterMarkFlagChangedListener>& listener)
{
if (listener == nullptr) {
WLOGFE("listener could not be null");
return WMError::WM_ERROR_NULLPTR;
}
std::lock_guard<std::recursive_mutex> lock(pImpl_->mutex_);
auto iter = std::find(pImpl_->waterMarkFlagChangeListeners_.begin(),
pImpl_->waterMarkFlagChangeListeners_.end(), listener);
if (iter == pImpl_->waterMarkFlagChangeListeners_.end()) {
WLOGFE("could not find this listener");
return WMError::WM_OK;
}
pImpl_->waterMarkFlagChangeListeners_.erase(iter);
WMError ret = WMError::WM_OK;
if (pImpl_->waterMarkFlagChangeListeners_.empty() &&
pImpl_->waterMarkFlagChangeAgent_ != nullptr) {
ret = SingletonContainer::Get<WindowAdapter>().UnregisterWindowManagerAgent(
WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WATER_MARK_FLAG,
pImpl_->waterMarkFlagChangeAgent_);
if (ret != WMError::WM_OK) {
return WMError::WM_OK;
}
pImpl_->waterMarkFlagChangeAgent_ = nullptr;
}
WLOGFD("Try to unregisterWaterMarkFlagChangedListener && result : %{public}u", static_cast<uint32_t>(ret));
return ret;
}
void WindowManager::UpdateFocusChangeInfo(const sptr<FocusChangeInfo>& focusChangeInfo, bool focused) const
{
if (focusChangeInfo == nullptr) {
@ -581,6 +673,11 @@ void WindowManager::UpdateCameraFloatWindowStatus(uint32_t accessTokenId, bool i
pImpl_->UpdateCameraFloatWindowStatus(accessTokenId, isShowing);
}
void WindowManager::NotifyWaterMarkFlagChangedResult(bool showWaterMark) const
{
pImpl_->NotifyWaterMarkFlagChangedResult(showWaterMark);
}
void WindowManager::OnRemoteDied() const
{
WLOGI("wms is died");

View File

@ -45,5 +45,10 @@ void WindowManagerAgent::UpdateCameraFloatWindowStatus(uint32_t accessTokenId, b
{
SingletonContainer::Get<WindowManager>().UpdateCameraFloatWindowStatus(accessTokenId, isShowing);
}
void WindowManagerAgent::NotifyWaterMarkFlagChangedResult(bool showWaterMark)
{
SingletonContainer::Get<WindowManager>().NotifyWaterMarkFlagChangedResult(showWaterMark);
}
} // namespace Rosen
} // namespace OHOS

View File

@ -167,6 +167,26 @@ void WindowManagerAgentProxy::UpdateCameraFloatWindowStatus(uint32_t accessToken
WLOGFE("SendRequest failed");
}
}
void WindowManagerAgentProxy::NotifyWaterMarkFlagChangedResult(bool showWaterMark)
{
MessageParcel data;
if (!data.WriteInterfaceToken(GetDescriptor())) {
WLOGFE("WriteInterfaceToken failed");
return;
}
if (!data.WriteBool(showWaterMark)) {
WLOGFE("Write is showing status failed");
return;
}
MessageParcel reply;
MessageOption option(MessageOption::TF_ASYNC);
if (Remote()->SendRequest(static_cast<uint32_t>(WindowManagerAgentMsg::TRANS_ID_UPDATE_WATER_MARK_FLAG),
data, reply, option) != ERR_NONE) {
WLOGFE("SendRequest failed");
}
}
} // namespace Rosen
} // namespace OHOS

View File

@ -94,6 +94,11 @@ int WindowManagerAgentStub::OnRemoteRequest(uint32_t code, MessageParcel& data,
UpdateCameraFloatWindowStatus(accessTokenId, isShowing);
break;
}
case WindowManagerAgentMsg::TRANS_ID_UPDATE_WATER_MARK_FLAG: {
bool showWaterMark = data.ReadBool();
NotifyWaterMarkFlagChangedResult(showWaterMark);
break;
}
default:
break;
}

View File

@ -58,6 +58,14 @@ public:
};
};
class TestWaterMarkFlagChangeListener : public IWaterMarkFlagChangedListener {
public:
void OnWaterMarkFlagUpdate(bool showWaterMark) override
{
WLOGI("TestWaterMarkFlagChangeListener");
};
};
class WindowManagerTest : public testing::Test {
public:
static void SetUpTestCase();
@ -398,6 +406,74 @@ HWTEST_F(WindowManagerTest, UnregisterSystemBarChangedListener01, Function | Sma
windowManager.pImpl_->systemBarChangedListenerAgent_ = oldWindowManagerAgent;
windowManager.pImpl_->systemBarChangedListeners_ = oldListeners;
}
/**
* @tc.name: RegisterWaterMarkListener01
* @tc.desc: check RegisterWaterMarkListener
* @tc.type: FUNC
*/
HWTEST_F(WindowManagerTest, RegisterWaterMarkFlagChangedListener01, Function | SmallTest | Level2)
{
auto& windowManager = WindowManager::GetInstance();
windowManager.pImpl_->waterMarkFlagChangeAgent_ = nullptr;
windowManager.pImpl_->waterMarkFlagChangeListeners_.clear();
ASSERT_EQ(WMError::WM_ERROR_NULLPTR, windowManager.RegisterWaterMarkFlagChangedListener(nullptr));
std::unique_ptr<Mocker> m = std::make_unique<Mocker>();
sptr<TestWaterMarkFlagChangeListener> listener = new TestWaterMarkFlagChangeListener();
EXPECT_CALL(m->Mock(), RegisterWindowManagerAgent(_, _)).Times(1).WillOnce(Return(WMError::WM_ERROR_NULLPTR));
ASSERT_EQ(WMError::WM_ERROR_NULLPTR, windowManager.RegisterWaterMarkFlagChangedListener(listener));
ASSERT_EQ(0, windowManager.pImpl_->waterMarkFlagChangeListeners_.size());
ASSERT_EQ(nullptr, windowManager.pImpl_->waterMarkFlagChangeAgent_);
EXPECT_CALL(m->Mock(), RegisterWindowManagerAgent(_, _)).Times(1).WillOnce(Return(WMError::WM_OK));
ASSERT_EQ(WMError::WM_OK, windowManager.RegisterWaterMarkFlagChangedListener(listener));
ASSERT_EQ(1, windowManager.pImpl_->waterMarkFlagChangeListeners_.size());
ASSERT_NE(nullptr, windowManager.pImpl_->waterMarkFlagChangeAgent_);
// to check that the same listner can not be registered twice
ASSERT_EQ(WMError::WM_OK, windowManager.RegisterWaterMarkFlagChangedListener(listener));
ASSERT_EQ(1, windowManager.pImpl_->waterMarkFlagChangeListeners_.size());
}
/**
* @tc.name: UnregisterWaterMarkFlagChangedListener01
* @tc.desc: check UnregisterWaterMarkFlagChangedListener
* @tc.type: FUNC
*/
HWTEST_F(WindowManagerTest, UnregisterWaterMarkFlagChangedListener01, Function | SmallTest | Level2)
{
auto& windowManager = WindowManager::GetInstance();
windowManager.pImpl_->waterMarkFlagChangeAgent_ = nullptr;
windowManager.pImpl_->waterMarkFlagChangeListeners_.clear();
std::unique_ptr<Mocker> m = std::make_unique<Mocker>();
// check nullpter
ASSERT_EQ(WMError::WM_ERROR_NULLPTR, windowManager.UnregisterWaterMarkFlagChangedListener(nullptr));
sptr<TestWaterMarkFlagChangeListener> listener1 = new TestWaterMarkFlagChangeListener();
sptr<TestWaterMarkFlagChangeListener> listener2 = new TestWaterMarkFlagChangeListener();
ASSERT_EQ(WMError::WM_OK, windowManager.UnregisterWaterMarkFlagChangedListener(listener1));
EXPECT_CALL(m->Mock(), RegisterWindowManagerAgent(_, _)).Times(1).WillOnce(Return(WMError::WM_OK));
windowManager.RegisterWaterMarkFlagChangedListener(listener1);
windowManager.RegisterWaterMarkFlagChangedListener(listener2);
ASSERT_EQ(2, windowManager.pImpl_->waterMarkFlagChangeListeners_.size());
EXPECT_CALL(m->Mock(), UnregisterWindowManagerAgent(_, _)).Times(1).WillOnce(Return(WMError::WM_OK));
ASSERT_EQ(WMError::WM_OK, windowManager.UnregisterWaterMarkFlagChangedListener(listener1));
ASSERT_EQ(WMError::WM_OK, windowManager.UnregisterWaterMarkFlagChangedListener(listener2));
ASSERT_EQ(0, windowManager.pImpl_->waterMarkFlagChangeListeners_.size());
ASSERT_EQ(nullptr, windowManager.pImpl_->waterMarkFlagChangeAgent_);
// if agent == nullptr, it can not be crashed.
windowManager.pImpl_->waterMarkFlagChangeListeners_.push_back(listener1);
ASSERT_EQ(WMError::WM_OK, windowManager.UnregisterWaterMarkFlagChangedListener(listener1));
ASSERT_EQ(0, windowManager.pImpl_->waterMarkFlagChangeListeners_.size());
}
}
} // namespace Rosen
} // namespace OHOS

View File

@ -36,6 +36,7 @@ public:
void NotifyAccessibilityWindowInfo(const std::vector<sptr<AccessibilityWindowInfo>>& infos, WindowUpdateType type);
void UpdateWindowVisibilityInfo(const std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfos);
void UpdateCameraFloatWindowStatus(uint32_t accessTokenId, bool isShowing);
void NotifyWaterMarkFlagChangedResult(bool showWaterMark);
private:
WindowManagerAgentController() {}

View File

@ -153,6 +153,7 @@ private:
void ChangeRSRenderModeIfNeeded(bool isToUnified);
bool IsAppWindowExceed() const;
void SetDisplayOrientationFromWindow(sptr<WindowNode>& node, bool withAnimation);
void CheckAndNotifyWaterMarkChangedResult();
std::map<uint32_t, sptr<WindowNode>> windowNodeMap_;
std::map<sptr<IRemoteObject>, uint32_t> windowIdMap_;
@ -160,6 +161,7 @@ private:
std::shared_ptr<RSOcclusionData> lastOcclusionData_ = std::make_shared<RSOcclusionData>();
std::map<ScreenId, sptr<WindowNodeContainer>> windowNodeContainerMap_;
std::map<ScreenId, std::vector<DisplayId>> displayIdMap_;
bool lastWaterMarkShowStates_ { false };
bool needCheckFocusWindow = false;
std::map<WindowManagerAgentType, std::vector<sptr<IWindowManagerAgent>>> windowManagerAgents_;

View File

@ -82,5 +82,14 @@ void WindowManagerAgentController::UpdateCameraFloatWindowStatus(uint32_t access
agent->UpdateCameraFloatWindowStatus(accessTokenId, isShowing);
}
}
void WindowManagerAgentController::NotifyWaterMarkFlagChangedResult(bool showWaterMark)
{
WLOGFD("NotifyWaterMarkFlagChanged with result:%{public}d", showWaterMark);
for (auto& agent : wmAgentContainer_.GetAgentsByType(
WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WATER_MARK_FLAG)) {
agent->NotifyWaterMarkFlagChangedResult(showWaterMark);
}
}
} // namespace Rosen
} // namespace OHOS

View File

@ -393,6 +393,7 @@ void WindowRoot::NotifyWindowVisibilityChange(std::shared_ptr<RSOcclusionData> o
WLOGFD("NotifyWindowVisibilityChange: covered status changed window:%{public}u, isVisible:%{public}d",
node->GetWindowId(), isVisible);
}
CheckAndNotifyWaterMarkChangedResult();
if (hasAppWindowChange) {
SwitchRenderModeIfNeeded();
}
@ -795,7 +796,12 @@ WMError WindowRoot::UpdateWindowNode(uint32_t windowId, WindowUpdateReason reaso
WLOGFE("update window failed, window container could not be found");
return WMError::WM_ERROR_INVALID_DISPLAY;
}
return container->UpdateWindowNode(node, reason);
auto ret = container->UpdateWindowNode(node, reason);
if (ret == WMError::WM_OK && reason == WindowUpdateReason::UPDATE_FLAGS) {
CheckAndNotifyWaterMarkChangedResult();
}
return ret;
}
WMError WindowRoot::UpdateSizeChangeReason(uint32_t windowId, WindowSizeChangeReason reason)
@ -985,6 +991,8 @@ WMError WindowRoot::DestroyWindowInner(sptr<WindowNode>& node)
WLOGFD("NotifyWindowVisibilityChange: covered status changed window:%{public}u, isVisible:%{public}d",
node->GetWindowId(), node->isVisible_);
WindowManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
CheckAndNotifyWaterMarkChangedResult();
}
auto cmpFunc = [node](const std::map<uint64_t, sptr<WindowNode>>::value_type& pair) {
@ -1831,5 +1839,33 @@ void WindowRoot::ClearWindowPairSnapshot(DisplayId displayId)
}
return container->ClearWindowPairSnapshot(displayId);
}
void WindowRoot::CheckAndNotifyWaterMarkChangedResult()
{
auto searchWaterMarkWindow = [](wptr<WindowNode> node) {
return (node != nullptr && node->isVisible_ &&
(node->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK)));
};
bool currentWaterMarkState = false;
for (auto& containerPair : windowNodeContainerMap_) {
auto container = containerPair.second;
if (container == nullptr) {
continue;
}
std::vector<sptr<WindowNode>> allWindowNode;
container->TraverseContainer(allWindowNode);
auto itor = std::find_if(allWindowNode.begin(), allWindowNode.end(), searchWaterMarkWindow);
if (itor != allWindowNode.end()) {
currentWaterMarkState = true;
break;
}
}
if (lastWaterMarkShowStates_ != currentWaterMarkState) {
WLOGFD("WaterMarkWindows has been changed. lastWaterMarkState : %{public}d, newState:%{public}d",
lastWaterMarkShowStates_, currentWaterMarkState);
WindowManagerAgentController::GetInstance().NotifyWaterMarkFlagChangedResult(currentWaterMarkState);
lastWaterMarkShowStates_ = currentWaterMarkState;
}
}
} // namespace Rosen
} // namespace OHOS

View File

@ -468,6 +468,38 @@ HWTEST_F(WindowRootTest, WindowRootTest25, Function | SmallTest | Level2)
ASSERT_EQ(true, true);
}
/**
* @tc.name: CheckAndNotifyWaterMarkChangedResult
* @tc.desc: test WindowRoot CheckAndNotifyWaterMarkChangedResult
* @tc.type: FUNC
*/
HWTEST_F(WindowRootTest, CheckAndNotifyWaterMarkChangedResult, Function | SmallTest | Level2)
{
auto display = DisplayManager::GetInstance().GetDefaultDisplay();
ASSERT_NE(display, nullptr);
sptr<DisplayInfo> displayInfo = display->GetDisplayInfo();
auto container = windowRoot_->CreateWindowNodeContainer(display->GetId(), displayInfo);
ASSERT_NE(container, nullptr);
windowRoot_->lastWaterMarkShowStates_ = false;
windowRoot_->CheckAndNotifyWaterMarkChangedResult();
ASSERT_EQ(windowRoot_->lastWaterMarkShowStates_, false);
auto windowNode = new (std::nothrow)WindowNode();
ASSERT_NE(windowNode, nullptr);
windowNode->isVisible_ = true;
windowNode->SetDisplayId(displayInfo->GetDisplayId());
windowNode->property_->flags_ |= static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK);
container->appWindowNode_->children_.push_back(windowNode);
windowRoot_->CheckAndNotifyWaterMarkChangedResult();
ASSERT_EQ(windowRoot_->lastWaterMarkShowStates_, true);
container->appWindowNode_->children_.clear();
windowRoot_->CheckAndNotifyWaterMarkChangedResult();
ASSERT_EQ(windowRoot_->lastWaterMarkShowStates_, false);
}
}
}
}