* Copyright (c) 2023-2025 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 "virtual_rs_window.h"
#include <cstdint>
#include <memory>
#include "ability_context.h"
#include "display_info_jni.h"
#include "foundation/appframework/arkui/uicontent/ui_content.h"
#include "hilog.h"
#include "mmi_event_convertor.h"
#include "napi/native_api.h"
#include "render_service_client/core/pipeline/rs_render_thread.h"
#include "render_service_client/core/ui/rs_ui_context.h"
#include "render_service_client/core/ui/rs_ui_director.h"
#include "subwindow_manager_jni.h"
#include "transaction/rs_interfaces.h"
#include "window_view_adapter.h"
#include "window_view_jni.h"
#include "adapter/android/entrance/java/jni/ace_env_jni.h"
#include "adapter/android/entrance/java/jni/jni_environment.h"
#include "base/log/log.h"
#include "base/utils/utils.h"
#include "core/event/touch_event.h"
using namespace OHOS::Ace::Platform;
namespace OHOS::Rosen {
namespace {
static constexpr Rect EMPTY_RECT = { 0, 0, 0, 0 };
static constexpr int32_t ORIENTATION_LANDSCAPE = 0;
static constexpr int32_t ORIENTATION_PORTRAIT = 1;
}
void DummyWindowRelease(Window* window)
{
window->DecStrongRef(window);
LOGI("Rosenwindow rsWindow_Window: dummy release");
}
Ace::KeyCode KeyCodeToAceKeyCode(int keyCode)
{
Ace::KeyCode aceKeyCode = Ace::KeyCode::KEY_UNKNOWN;
const static std::map<int32_t, Ace::KeyCode> TO_OHOS_KEYCODE_MAP = {
{ 4 , Ace::KeyCode::KEY_BACK },
{ 7 , Ace::KeyCode::KEY_0 },
{ 8 , Ace::KeyCode::KEY_1 },
{ 9 , Ace::KeyCode::KEY_2 },
{ 10 , Ace::KeyCode::KEY_3 },
{ 11 , Ace::KeyCode::KEY_4 },
{ 12 , Ace::KeyCode::KEY_5 },
{ 13 , Ace::KeyCode::KEY_6 },
{ 14 , Ace::KeyCode::KEY_7 },
{ 15 , Ace::KeyCode::KEY_8 },
{ 16 , Ace::KeyCode::KEY_9 },
{ 19 , Ace::KeyCode::KEY_DPAD_UP },
{ 20 , Ace::KeyCode::KEY_DPAD_DOWN },
{ 21 , Ace::KeyCode::KEY_DPAD_LEFT },
{ 22 , Ace::KeyCode::KEY_DPAD_RIGHT },
{ 23 , Ace::KeyCode::KEY_DPAD_CENTER },
{ 29 , Ace::KeyCode::KEY_A },
{ 30 , Ace::KeyCode::KEY_B },
{ 31 , Ace::KeyCode::KEY_C },
{ 32 , Ace::KeyCode::KEY_D },
{ 33 , Ace::KeyCode::KEY_E },
{ 34 , Ace::KeyCode::KEY_F },
{ 35 , Ace::KeyCode::KEY_G },
{ 36 , Ace::KeyCode::KEY_H },
{ 37 , Ace::KeyCode::KEY_I },
{ 38 , Ace::KeyCode::KEY_J },
{ 39 , Ace::KeyCode::KEY_K },
{ 40 , Ace::KeyCode::KEY_L },
{ 41 , Ace::KeyCode::KEY_M },
{ 42 , Ace::KeyCode::KEY_N },
{ 43 , Ace::KeyCode::KEY_O },
{ 44 , Ace::KeyCode::KEY_P },
{ 45 , Ace::KeyCode::KEY_Q },
{ 46 , Ace::KeyCode::KEY_R },
{ 47 , Ace::KeyCode::KEY_S },
{ 48 , Ace::KeyCode::KEY_T },
{ 49 , Ace::KeyCode::KEY_U },
{ 50 , Ace::KeyCode::KEY_V },
{ 51 , Ace::KeyCode::KEY_W },
{ 52 , Ace::KeyCode::KEY_X },
{ 53 , Ace::KeyCode::KEY_Y },
{ 54 , Ace::KeyCode::KEY_Z },
{ 55 , Ace::KeyCode::KEY_COMMA },
{ 56 , Ace::KeyCode::KEY_PERIOD },
{ 57 , Ace::KeyCode::KEY_ALT_LEFT },
{ 58 , Ace::KeyCode::KEY_ALT_RIGHT },
{ 59 , Ace::KeyCode::KEY_SHIFT_LEFT },
{ 60 , Ace::KeyCode::KEY_SHIFT_RIGHT },
{ 61 , Ace::KeyCode::KEY_TAB },
{ 62 , Ace::KeyCode::KEY_SPACE },
{ 66 , Ace::KeyCode::KEY_ENTER },
{ 67 , Ace::KeyCode::KEY_DEL },
{ 68 , Ace::KeyCode::KEY_GRAVE },
{ 69 , Ace::KeyCode::KEY_MINUS },
{ 70 , Ace::KeyCode::KEY_EQUALS },
{ 71 , Ace::KeyCode::KEY_LEFT_BRACKET },
{ 72 , Ace::KeyCode::KEY_RIGHT_BRACKET },
{ 73 , Ace::KeyCode::KEY_BACKSLASH },
{ 74 , Ace::KeyCode::KEY_SEMICOLON },
{ 75 , Ace::KeyCode::KEY_APOSTROPHE },
{ 76 , Ace::KeyCode::KEY_SLASH },
{ 82 , (Ace::KeyCode)2466 },
{ 84 , Ace::KeyCode::KEY_SEARCH },
{ 92 , Ace::KeyCode::KEY_PAGE_UP },
{ 93 , Ace::KeyCode::KEY_PAGE_DOWN },
{ 111 , Ace::KeyCode::KEY_ESCAPE },
{ 112 , Ace::KeyCode::KEY_FORWARD_DEL },
{ 113 , Ace::KeyCode::KEY_CTRL_LEFT },
{ 114 , Ace::KeyCode::KEY_CTRL_RIGHT },
{ 115 , Ace::KeyCode::KEY_CAPS_LOCK },
{ 116 , Ace::KeyCode::KEY_SCROLL_LOCK },
{ 117 , Ace::KeyCode::KEY_META_LEFT },
{ 118 , Ace::KeyCode::KEY_META_RIGHT },
{ 120 , Ace::KeyCode::KEY_SYSRQ },
{ 121 , Ace::KeyCode::KEY_BREAK },
{ 122 , Ace::KeyCode::KEY_MOVE_HOME },
{ 123 , Ace::KeyCode::KEY_MOVE_END },
{ 124 , Ace::KeyCode::KEY_INSERT },
{ 131 , Ace::KeyCode::KEY_F1 },
{ 132 , Ace::KeyCode::KEY_F2 },
{ 133 , Ace::KeyCode::KEY_F3 },
{ 134 , Ace::KeyCode::KEY_F4 },
{ 135 , Ace::KeyCode::KEY_F5 },
{ 136 , Ace::KeyCode::KEY_F6 },
{ 137 , Ace::KeyCode::KEY_F7 },
{ 138 , Ace::KeyCode::KEY_F8 },
{ 139 , Ace::KeyCode::KEY_F9 },
{ 140 , Ace::KeyCode::KEY_F10 },
{ 141 , Ace::KeyCode::KEY_F11 },
{ 142 , Ace::KeyCode::KEY_F12 },
{ 143 , Ace::KeyCode::KEY_NUM_LOCK },
{ 144 , Ace::KeyCode::KEY_NUMPAD_0 },
{ 145 , Ace::KeyCode::KEY_NUMPAD_1 },
{ 146 , Ace::KeyCode::KEY_NUMPAD_2 },
{ 147 , Ace::KeyCode::KEY_NUMPAD_3 },
{ 148 , Ace::KeyCode::KEY_NUMPAD_4 },
{ 149 , Ace::KeyCode::KEY_NUMPAD_5 },
{ 150 , Ace::KeyCode::KEY_NUMPAD_6 },
{ 151 , Ace::KeyCode::KEY_NUMPAD_7 },
{ 152 , Ace::KeyCode::KEY_NUMPAD_8 },
{ 153 , Ace::KeyCode::KEY_NUMPAD_9 },
{ 154 , Ace::KeyCode::KEY_NUMPAD_DIVIDE },
{ 155 , Ace::KeyCode::KEY_NUMPAD_MULTIPLY },
{ 156 , Ace::KeyCode::KEY_NUMPAD_SUBTRACT },
{ 157 , Ace::KeyCode::KEY_NUMPAD_ADD },
{ 158 , Ace::KeyCode::KEY_NUMPAD_DOT },
{ 160 , Ace::KeyCode::KEY_NUMPAD_ENTER },
};
auto checkIter = TO_OHOS_KEYCODE_MAP.find(keyCode);
if (checkIter != TO_OHOS_KEYCODE_MAP.end()) {
aceKeyCode = checkIter->second;
}
return aceKeyCode;
}
const std::map<ColorSpace, GraphicColorGamut> COLOR_SPACE_JS_TO_GAMUT_MAP {
{ ColorSpace::COLOR_SPACE_DEFAULT, GraphicColorGamut::GRAPHIC_COLOR_GAMUT_SRGB },
{ ColorSpace::COLOR_SPACE_WIDE_GAMUT, GraphicColorGamut::GRAPHIC_COLOR_GAMUT_DCI_P3 },
};
std::map<uint32_t, std::vector<std::shared_ptr<Window>>> Window::subWindowMap_;
std::map<std::string, std::pair<uint32_t, std::shared_ptr<Window>>> Window::windowMap_;
std::map<uint32_t, std::vector<sptr<IOccupiedAreaChangeListener>>> Window::occupiedAreaChangeListeners_;
std::map<uint32_t, std::vector<sptr<IWindowLifeCycle>>> Window::lifecycleListeners_;
std::map<uint32_t, std::vector<sptr<IWindowChangeListener>>> Window::windowChangeListeners_;
std::map<uint32_t, std::vector<sptr<ITouchOutsideListener>>> Window::touchOutsideListeners_;
std::map<uint32_t, std::vector<sptr<IWindowSurfaceNodeListener>>> Window::surfaceNodeListeners_;
std::map<uint32_t, std::vector<sptr<IAvoidAreaChangedListener>>> Window::avoidAreaChangeListeners_;
std::map<uint32_t, std::vector<sptr<IWindowStatusChangeListener>>> Window::windowStatusChangeListeners_;
std::recursive_mutex Window::globalMutex_;
std::recursive_mutex g_sysBarPropMapMutex;
uint32_t g_KeyboardHeight = 0;
bool g_IsFullScreen = false;
bool g_IsStatusBarHide = false;
Window::Window(std::shared_ptr<AbilityRuntime::Platform::Context> context, uint32_t windowId)
: context_(context), windowId_(windowId), brightness_(SubWindowManagerJni::GetAppScreenBrightness())
{}
Window::Window(std::shared_ptr<AbilityRuntime::Platform::Context> context)
: context_(context), brightness_(SubWindowManagerJni::GetAppScreenBrightness())
{}
Window::~Window()
{
LOGI("Rosenwindow rsWindow_Window: release id = %u", windowId_);
ReleaseWindowView();
}
void Window::AddToWindowMap(std::shared_ptr<Window> window)
{
DeleteFromWindowMap(window);
windowMap_.insert(std::make_pair(
window->GetWindowName(), std::pair<uint32_t, std::shared_ptr<Window>>(window->GetWindowId(), window)));
}
void Window::DeleteFromWindowMap(std::shared_ptr<Window> window)
{
auto iter = windowMap_.find(window->GetWindowName());
if (iter != windowMap_.end()) {
windowMap_.erase(iter);
}
}
void Window::DeleteFromWindowMap(Window* window)
{
if (window == nullptr) {
return;
}
auto iter = windowMap_.find(window->GetWindowName());
if (iter != windowMap_.end()) {
windowMap_.erase(iter);
}
}
void Window::AddToSubWindowMap(std::shared_ptr<Window> window)
{
if (window == nullptr) {
LOGE("window is null");
return;
}
if (window->GetType() != OHOS::Rosen::WindowType::WINDOW_TYPE_APP_SUB_WINDOW ||
window->GetParentId() == INVALID_WINDOW_ID) {
LOGE("window is not subwindow");
return;
}
DeleteFromSubWindowMap(window);
uint32_t parentId = window->GetParentId();
subWindowMap_[parentId].push_back(window);
}
void Window::DeleteFromSubWindowMap(std::shared_ptr<Window> window)
{
if (window == nullptr) {
return;
}
uint32_t parentId = window->GetParentId();
if (parentId == INVALID_WINDOW_ID) {
return;
}
auto iter1 = subWindowMap_.find(parentId);
if (iter1 == subWindowMap_.end()) {
return;
}
auto subWindows = iter1->second;
auto iter2 = subWindows.begin();
while (iter2 != subWindows.end()) {
if (*iter2 == window) {
subWindows.erase(iter2);
((*iter2)->Destroy());
break;
}
iter2++;
}
}
std::shared_ptr<Window> Window::Create(
std::shared_ptr<OHOS::AbilityRuntime::Platform::Context> context, JNIEnv* env, jobject windowView)
{
std::string windowName = AbilityRuntime::Platform::WindowViewAdapter::GetInstance()->GetWindowName(windowView);
if (windowName.empty()) {
LOGE("Window::Create called failed due to null windowName");
return nullptr;
}
LOGI("Window::Create called. windowName=%s", windowName.c_str());
auto window = std::shared_ptr<Window>(new Window(context), DummyWindowRelease);
window->SetWindowView(env, windowView);
window->SetWindowName(windowName);
auto abilityContext =
OHOS::AbilityRuntime::Platform::Context::ConvertTo<OHOS::AbilityRuntime::Platform::AbilityContext>(context);
std::shared_ptr<OHOS::AppExecFwk::AbilityInfo> info;
CHECK_NULL_RETURN(abilityContext, nullptr);
info = abilityContext->GetAbilityInfo();
if (info) {
LOGI("info->name = %s, info->instanceId = %d", info->name.c_str(), info->instanceId);
window->SetWindowId(info->instanceId);
}
window->IncStrongRef(window.get());
AddToWindowMap(window);
AvoidAreaMapInit(window);
return window;
}
void Window::AvoidAreaMapInit(std::shared_ptr<Window> window)
{
for (auto type : { AvoidAreaType::TYPE_SYSTEM, AvoidAreaType::TYPE_CUTOUT, AvoidAreaType::TYPE_SYSTEM_GESTURE,
AvoidAreaType::TYPE_KEYBOARD, AvoidAreaType::TYPE_NAVIGATION_INDICATOR }) {
auto avoidArea = std::make_shared<Rosen::AvoidArea>();
window->GetAvoidAreaByType(type, *avoidArea);
window->avoidAreaMap_.insert(std::make_pair(type, *avoidArea));
}
}
std::shared_ptr<Window> Window::CreateDragWindow(std::shared_ptr<OHOS::AbilityRuntime::Platform::Context> context)
{
LOGI("CreateDragWindow");
auto mainWindow = OHOS::Rosen::Window::GetTopWindow(context);
CHECK_NULL_RETURN(mainWindow, nullptr);
std::string windowName = mainWindow->GetWindowName() + ":Drag";
std::shared_ptr<OHOS::Rosen::WindowOption> option = std::make_shared<OHOS::Rosen::WindowOption>();
option->SetWindowType(OHOS::Rosen::WindowType::WINDOW_TYPE_APP_SUB_WINDOW);
option->SetWindowMode(OHOS::Rosen::WindowMode::WINDOW_MODE_FLOATING);
option->SetParentId(mainWindow->GetWindowId());
option->SetWindowName(windowName);
std::shared_ptr<OHOS::Rosen::Window> window = OHOS::Rosen::Window::CreateSubWindow(context, option);
CHECK_NULL_RETURN(window, nullptr);
window->SetFocusable(false);
window->SetTouchable(false);
window->SetFullScreen(true);
window->SetOnTop(true);
return window;
}
std::shared_ptr<Window> Window::CreateSubWindow(
std::shared_ptr<OHOS::AbilityRuntime::Platform::Context> context, std::shared_ptr<OHOS::Rosen::WindowOption> option)
{
if (option == nullptr) {
LOGE("Window::CreateSubWindow called failed due to null option");
return nullptr;
}
LOGI("Window::CreateSubWindow called. windowName=%s", option->GetWindowName().c_str());
JNIEnv* env = JniEnvironment::GetInstance().GetJniEnv().get();
bool result = SubWindowManagerJni::CreateSubWindow(option);
if (result) {
jobject view = SubWindowManagerJni::GetContentView(option->GetWindowName());
uint32_t windowId = SubWindowManagerJni::GetWindowId(option->GetWindowName());
auto window = std::shared_ptr<Window>(new Window(context), DummyWindowRelease);
window->SetWindowId(windowId);
window->SetWindowName(option->GetWindowName());
window->SetWindowType(option->GetWindowType());
window->SetParentId(option->GetParentId());
window->SetWindowMode(option->GetWindowMode());
window->SetRect(option);
window->IncStrongRef(window.get());
AddToSubWindowMap(window);
AddToWindowMap(window);
AvoidAreaMapInit(window);
window->SetSubWindowView(env, view);
return window;
}
LOGI("Window::CreateSubWindow: failed");
return nullptr;
}
WMError Window::Destroy()
{
LOGI("Window::Destroy: %s", this->GetWindowName().c_str());
if (uiContent_ != nullptr) {
uiContent_->Destroy();
uiContent_ = nullptr;
}
if (GetType() == OHOS::Rosen::WindowType::WINDOW_TYPE_APP_SUB_WINDOW && !GetWindowName().empty()) {
SubWindowManagerJni::DestroyWindow(GetWindowName());
}
NotifyBeforeDestroy(GetWindowName());
if (subWindowMap_.count(GetWindowId()) > 0) {
auto& subWindows = subWindowMap_.at(GetWindowId());
for (auto iter = subWindows.begin(); iter != subWindows.end(); iter = subWindows.begin()) {
if ((*iter) == nullptr) {
subWindows.erase(iter);
continue;
}
auto windowPtr = (*iter);
subWindows.erase(iter);
LOGI("Window::Destroy SubWindow %s", (windowPtr)->GetWindowName().c_str());
DeleteFromWindowMap(windowPtr);
(windowPtr)->Destroy();
}
subWindowMap_[GetWindowId()].clear();
subWindowMap_.erase(GetWindowId());
}
if (subWindowMap_.count(GetParentId()) > 0) {
auto& subWindows = subWindowMap_.at(GetParentId());
for (auto iter = subWindows.begin(); iter < subWindows.end(); ++iter) {
if ((*iter) == nullptr) {
continue;
}
if ((*iter)->GetWindowId() == GetWindowId()) {
subWindows.erase(iter);
break;
}
}
}
if (windowMap_.count(GetWindowName()) > 0) {
DeleteFromWindowMap(this);
}
NotifyAfterBackground();
ReleaseWindowView();
ClearListenersById(GetWindowId());
return WMError::WM_OK;
}
void Window::RegisterWindowDestroyedListener(const NotifyNativeWinDestroyFunc& func)
{
LOGD("Start register");
notifyNativefunc_ = std::move(func);
}
WMError Window::RegisterOccupiedAreaChangeListener(const sptr<IOccupiedAreaChangeListener>& listener)
{
LOGD("Start register");
std::lock_guard<std::recursive_mutex> lock(globalMutex_);
return RegisterListener(occupiedAreaChangeListeners_[GetWindowId()], listener);
}
WMError Window::UnregisterOccupiedAreaChangeListener(const sptr<IOccupiedAreaChangeListener>& listener)
{
LOGD("Start unregister");
std::lock_guard<std::recursive_mutex> lock(globalMutex_);
return UnregisterListener(occupiedAreaChangeListeners_[GetWindowId()], listener);
}
WMError Window::RegisterWindowChangeListener(const sptr<IWindowChangeListener>& listener)
{
LOGD("Start register");
std::lock_guard<std::recursive_mutex> lock(globalMutex_);
return RegisterListener(windowChangeListeners_[GetWindowId()], listener);
}
WMError Window::UnregisterWindowChangeListener(const sptr<IWindowChangeListener>& listener)
{
LOGD("Start unregister");
std::lock_guard<std::recursive_mutex> lock(globalMutex_);
return UnregisterListener(windowChangeListeners_[GetWindowId()], listener);
}
std::vector<std::shared_ptr<Window>> Window::GetSubWindow(uint32_t parentId)
{
LOGI("Window::GetSubWindow called. parentId=%d", parentId);
if (subWindowMap_.find(parentId) == subWindowMap_.end()) {
return std::vector<std::shared_ptr<Window>>();
}
return subWindowMap_[parentId];
}
std::shared_ptr<Window> Window::FindWindow(const std::string& name)
{
LOGI("Window::FindWindow called. name=%s", name.c_str());
auto iter = windowMap_.find(name);
if (iter == windowMap_.end()) {
return nullptr;
}
return iter->second.second;
}
std::shared_ptr<Window> Window::GetTopWindow(const std::shared_ptr<OHOS::AbilityRuntime::Platform::Context>& context)
{
LOGI("Window::GetTopWindow");
auto iter = windowMap_.begin();
while (iter != windowMap_.end()) {
std::pair<uint32_t, std::shared_ptr<Window>> pair = iter->second;
std::shared_ptr<Window> window = pair.second;
if (context.get() == window->GetContext().get() &&
window->GetType() != OHOS::Rosen::WindowType::WINDOW_TYPE_APP_SUB_WINDOW) {
return window;
}
iter++;
}
LOGE("Window::GetTopWindow no window on forground");
return nullptr;
}
WMError Window::ShowWindow()
{
LOGI("Window::ShowWindow called.");
if (this->GetWindowName().empty()) {
LOGI("Window::ShowWindow called failed due to null option");
return WMError::WM_ERROR_INVALID_WINDOW;
}
bool result = SubWindowManagerJni::ShowWindow(this->GetWindowName());
if (result) {
isForground_ = true;
NotifyAfterForeground();
return WMError::WM_OK;
} else {
return WMError::WM_ERROR_INVALID_WINDOW;
}
}
bool Window::IsWindowShow()
{
if (this->GetWindowName().empty()) {
LOGE("Window::IsWindowShow called failed due to null window name");
return false;
}
return SubWindowManagerJni::IsWindowShowing(this->GetWindowName());
}
WMError Window::MoveWindowTo(int32_t x, int32_t y)
{
LOGI("Window::MoveWindowTo called. x=%d, y=%d", x, y);
if (this->GetWindowName().empty()) {
LOGI("Window::MoveWindowTo called failed due to null option");
return WMError::WM_ERROR_INVALID_WINDOW;
}
rect_.posX_ = x;
rect_.posY_ = y;
bool result = SubWindowManagerJni::MoveWindowTo(this->GetWindowName(), x, y);
if (result) {
NotifySizeChange(rect_);
return WMError::WM_OK;
} else {
return WMError::WM_ERROR_INVALID_WINDOW;
}
}
WMError Window::ResizeWindowTo(int32_t width, int32_t height)
{
LOGI("Window::ResizeWindowTo called. width=%d, height=%d", width, height);
if (this->GetWindowName().empty()) {
LOGI("Window::ResizeWindowTo called failed due to null option");
return WMError::WM_ERROR_INVALID_WINDOW;
}
rect_.width_ = width;
rect_.height_ = height;
bool result = SubWindowManagerJni::ResizeWindowTo(this->GetWindowName(), width, height);
if (result) {
NotifySizeChange(rect_);
return WMError::WM_OK;
} else {
LOGI("Window::ResizeWindowTo: failed");
return WMError::WM_ERROR_INVALID_WINDOW;
}
}
WMError Window::SetBackgroundColor(uint32_t color)
{
LOGI("Window::SetBackgroundColor called. color=%u", color);
backgroundColor_ = color;
if (uiContent_) {
uiContent_->SetBackgroundColor(color);
return WMError::WM_OK;
}
return WMError::WM_ERROR_INVALID_OPERATION;
}
WMError Window::SetBrightness(float brightness)
{
LOGI("Window::SetBrightness called. brightness=%.3f", brightness);
if (brightness < MINIMUM_BRIGHTNESS || brightness > MAXIMUM_BRIGHTNESS) {
LOGE("invalid brightness value: %{public}f", brightness);
return WMError::WM_ERROR_INVALID_PARAM;
}
bool result = SubWindowManagerJni::SetAppScreenBrightness(brightness);
brightness_ = brightness;
if (result) {
return WMError::WM_OK;
} else {
LOGI("Window::SetBrightness: failed");
return WMError::WM_ERROR_INVALID_WINDOW;
}
}
WMError Window::SetKeepScreenOn(bool keepScreenOn)
{
LOGI("Window::SetKeepScreenOn called. keepScreenOn=%d", keepScreenOn);
bool result = SubWindowManagerJni::SetKeepScreenOn(keepScreenOn);
if (result) {
return WMError::WM_OK;
} else {
LOGI("Window::SetKeepScreenOn: failed");
return WMError::WM_ERROR_INVALID_WINDOW;
}
}
ColorSpace Window::GetColorSpaceFromSurfaceGamut(GraphicColorGamut colorGamut) const
{
for (auto& item : COLOR_SPACE_JS_TO_GAMUT_MAP) {
if (item.second == colorGamut) {
return item.first;
}
}
return ColorSpace::COLOR_SPACE_DEFAULT;
}
GraphicColorGamut Window::GetSurfaceGamutFromColorSpace(ColorSpace colorSpace) const
{
for (auto& item : COLOR_SPACE_JS_TO_GAMUT_MAP) {
if (item.first == colorSpace) {
return item.second;
}
}
return GraphicColorGamut::GRAPHIC_COLOR_GAMUT_SRGB;
}
WMError Window::SetColorSpace(ColorSpace colorSpace)
{
if (!surfaceNode_) {
LOGE("Window::SetColorSpace called. surfaceNode_ is null");
return WMError::WM_ERROR_NULLPTR;
}
auto surfaceGamut = GetSurfaceGamutFromColorSpace(colorSpace);
LOGI("Window::SetColorSpace called. colorSpace=%{public}d, surfaceGamut=%{public}d", colorSpace, surfaceGamut);
surfaceNode_->SetColorSpace(surfaceGamut);
return WMError::WM_OK;
}
ColorSpace Window::GetColorSpace() const
{
if (!surfaceNode_) {
LOGE("Window::GetColorSpace called. surfaceNode_ is null");
return ColorSpace::COLOR_SPACE_DEFAULT;
}
GraphicColorGamut gamut = surfaceNode_->GetColorSpace();
ColorSpace colorSpace = GetColorSpaceFromSurfaceGamut(gamut);
return colorSpace;
}
bool Window::IsKeepScreenOn()
{
LOGI("Window::IsKeepScreenOn called.");
return SubWindowManagerJni::IsKeepScreenOn();
}
WMError Window::SetSystemBarProperty(WindowType type, const SystemBarProperty& property)
{
bool hide = !property.enable_;
bool result = false;
if (type == WindowType::WINDOW_TYPE_NAVIGATION_BAR) {
result = SubWindowManagerJni::SetNavigationBarStatus(hide);
} else if (type == WindowType::WINDOW_TYPE_STATUS_BAR) {
result = SubWindowManagerJni::SetStatusBarStatus(hide);
if (result) {
g_IsStatusBarHide = hide;
}
} else {
LOGE("The WindowType is not set to SystemBarProperty. The WindowType is %{public}d", type);
}
std::lock_guard<std::recursive_mutex> lock(g_sysBarPropMapMutex);
sysBarPropMap_[type] = property;
if (result) {
return WMError::WM_OK;
} else {
LOGE("Window::SetSystemBarProperty: failed. The WindowType is %{public}d", type);
return WMError::WM_ERROR_INVALID_WINDOW;
}
}
void Window::SetRequestedOrientation(Orientation orientation)
{
LOGI("Window::SetRequestedOrientation called.");
bool result = SubWindowManagerJni::RequestOrientation(orientation);
if (!result) {
LOGI("Window::SetRequestedOrientation: failed");
}
}
SystemBarProperty Window::GetSystemBarPropertyByType(WindowType type) const
{
LOGI("Window::GetSystemBarPropertyByType called.");
for (auto& it : sysBarPropMap_) {
if (it.first == type) {
return it.second;
}
}
}
void Window::ClearListenersById(uint32_t winId)
{
std::lock_guard<std::recursive_mutex> lock(globalMutex_);
ClearUselessListeners(lifecycleListeners_, winId);
ClearUselessListeners(avoidAreaChangeListeners_, winId);
}
WMError Window::RegisterLifeCycleListener(const sptr<IWindowLifeCycle>& listener)
{
LOGD("Start register");
std::lock_guard<std::recursive_mutex> lock(globalMutex_);
return RegisterListener(lifecycleListeners_[GetWindowId()], listener);
}
WMError Window::UnregisterLifeCycleListener(const sptr<IWindowLifeCycle>& listener)
{
LOGD("Start unregister");
std::lock_guard<std::recursive_mutex> lock(globalMutex_);
return UnregisterListener(lifecycleListeners_[GetWindowId()], listener);
}
WMError Window::RegisterTouchOutsideListener(const sptr<ITouchOutsideListener>& listener)
{
LOGD("Start register TouchOutsideListener");
std::lock_guard<std::recursive_mutex> lock(globalMutex_);
return RegisterListener(touchOutsideListeners_[GetWindowId()], listener);
}
WMError Window::UnregisterTouchOutsideListener(const sptr<ITouchOutsideListener>& listener)
{
LOGD("Start unregister TouchOutsideListener");
std::lock_guard<std::recursive_mutex> lock(globalMutex_);
return UnregisterListener(touchOutsideListeners_[GetWindowId()], listener);
}
WMError Window::RegisterSurfaceNodeListener(const sptr<IWindowSurfaceNodeListener>& listener)
{
LOGI("Start register SurfaceNodeListener");
std::lock_guard<std::recursive_mutex> lock(globalMutex_);
return RegisterListener(surfaceNodeListeners_[GetWindowId()], listener);
}
WMError Window::UnregisterSurfaceNodeListener(const sptr<IWindowSurfaceNodeListener>& listener)
{
LOGI("Start unregister SurfaceNodeListener");
std::lock_guard<std::recursive_mutex> lock(globalMutex_);
return UnregisterListener(surfaceNodeListeners_[GetWindowId()], listener);
}
WMError Window::RegisterAvoidAreaChangeListener(const sptr<IAvoidAreaChangedListener>& listener)
{
LOGI("Start register AvoidAreaChangeListener");
std::lock_guard<std::recursive_mutex> lock(globalMutex_);
WMError ret = RegisterListener(avoidAreaChangeListeners_[GetWindowId()], listener);
return ret;
}
WMError Window::UnregisterAvoidAreaChangeListener(const sptr<IAvoidAreaChangedListener>& listener)
{
LOGI("Start unregister AvoidAreaChangeListener");
std::lock_guard<std::recursive_mutex> lock(globalMutex_);
WMError ret = UnregisterListener(avoidAreaChangeListeners_[GetWindowId()], listener);
return ret;
}
WMError Window::RegisterWindowStatusChangeListener(const sptr<IWindowStatusChangeListener>& listener)
{
LOGI("Start register WindowChangeListener");
std::lock_guard<std::recursive_mutex> lock(globalMutex_);
return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
}
WMError Window::UnregisterWindowStatusChangeListener(const sptr<IWindowStatusChangeListener>& listener)
{
LOGI("Start unregister WindowChangeListener");
std::lock_guard<std::recursive_mutex> lock(globalMutex_);
return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
}
template<typename T>
WMError Window::RegisterListener(std::vector<sptr<T>>& holder, const sptr<T>& listener)
{
if (listener == nullptr) {
LOGE("listener is nullptr");
return WMError::WM_ERROR_NULLPTR;
}
if (std::find(holder.begin(), holder.end(), listener) != holder.end()) {
LOGE("Listener already registered");
return WMError::WM_OK;
}
holder.emplace_back(listener);
return WMError::WM_OK;
}
template<typename T>
WMError Window::UnregisterListener(std::vector<sptr<T>>& holder, const sptr<T>& listener)
{
if (listener == nullptr) {
LOGE("listener could not be null");
return WMError::WM_ERROR_NULLPTR;
}
holder.erase(std::remove_if(holder.begin(), holder.end(),
[listener](sptr<T> registeredListener) { return registeredListener == listener; }),
holder.end());
return WMError::WM_OK;
}
void Window::RequestVsync(const std::shared_ptr<VsyncCallback>& vsyncCallback)
{
if (receiver_) {
SetUpThreadInfo();
auto callback = [vsyncCallback](int64_t timestamp, void*) { vsyncCallback->onCallback(timestamp, 0); };
VSyncReceiver::FrameCallback fcb = {
.userData_ = this,
.callback_ = callback,
};
receiver_->RequestNextVSync(fcb);
return;
}
}
bool Window::CreateVSyncReceiver(std::shared_ptr<AppExecFwk::EventHandler> handler)
{
if (receiver_) {
return true;
}
auto& rsClient = Rosen::RSInterfaces::GetInstance();
receiver_ = rsClient.CreateVSyncReceiver("Window_Andorid", handler);
VsyncError ret = receiver_->Init();
if (ret) {
LOGE("Window_Andorid: vsync receiver init failed: %{public}d", ret);
return false;
}
return true;
}
void Window::RequestNextVsync(std::function<void(int64_t, void*)> callback)
{
if (!receiver_) {
return;
}
VSyncReceiver::FrameCallback fcb = {
.userData_ = this,
.callback_ = callback,
};
receiver_->RequestNextVSync(fcb);
}
void Window::CreateSurfaceNode(void* nativeWindow)
{
rsUIDirector_ = Rosen::RSUIDirector::Create(nullptr);
struct Rosen::RSSurfaceNodeConfig rsSurfaceNodeConfig = { .SurfaceNodeName = "arkui-x_surface",
.additionalData = nativeWindow };
if (!rsUIDirector_) {
LOGE("rsUIDirector_ is nullptr");
return;
}
surfaceNode_ = Rosen::RSSurfaceNode::Create(rsSurfaceNodeConfig, true, rsUIDirector_->GetRSUIContext());
if (!uiContent_) {
LOGW("Window Notify uiContent_ Surface Created, uiContent_ is nullptr, delay notify.");
} else {
LOGI("Window Notify uiContent_ Surface Created");
uiContent_->NotifySurfaceCreated();
}
delayNotifySurfaceCreated_ = true;
auto surfaceNodeListeners = GetListeners<IWindowSurfaceNodeListener>();
for (auto& listener : surfaceNodeListeners) {
if (listener != nullptr) {
listener->OnSurfaceNodeCreated();
}
}
}
void Window::NotifySurfaceChanged(int32_t width, int32_t height, float density)
{
rect_.width_ = width;
rect_.height_ = height;
NotifySizeChange(rect_);
if (!surfaceNode_) {
LOGE("Window Notify Surface Changed, surfaceNode_ is nullptr!");
return;
}
LOGI("Window Notify Surface Changed wh:[%{public}d, %{public}d] density: %{public}f", width, height, density);
surfaceWidth_ = width;
surfaceHeight_ = height;
density_ = density;
surfaceNode_->SetBoundsWidth(surfaceWidth_);
surfaceNode_->SetBoundsHeight(surfaceHeight_);
if (!uiContent_) {
LOGW("Window Notify uiContent_ Surface Changed, uiContent_ is nullptr, delay notify.");
} else {
Ace::ViewportConfig config;
config.SetDensity(density_);
config.SetSize(surfaceWidth_, surfaceHeight_);
LOGI("Window Notify uiContent_ Surface Changed %{public}s", config.ToString().c_str());
uiContent_->UpdateViewportConfig(config, WindowSizeChangeReason::RESIZE);
}
delayNotifySurfaceChanged_ = true;
auto surfaceNodeListeners = GetListeners<IWindowSurfaceNodeListener>();
for (auto& listener : surfaceNodeListeners) {
if (listener != nullptr) {
listener->OnSurfaceNodeChanged(width, height, density);
}
}
}
void Window::NotifyKeyboardHeightChanged(int32_t height)
{
g_KeyboardHeight = height;
auto occupiedAreaChangeListeners = GetListeners<IOccupiedAreaChangeListener>();
for (auto& listener : occupiedAreaChangeListeners) {
if (listener != nullptr) {
Rect rect = { 0, 0, 0, height };
listener->OnSizeChange(rect, OccupiedAreaType::TYPE_INPUT);
}
}
}
void Window::NotifySizeChange(Rect rect)
{
auto windowChangeListeners = GetListeners<IWindowChangeListener>();
for (auto& listener : windowChangeListeners) {
if (listener != nullptr) {
listener->OnSizeChange(rect);
}
}
}
void Window::NotifyAfterForeground(bool needNotifyListeners, bool needNotifyUiContent)
{
if (needNotifyUiContent) {
if (uiContent_ != nullptr) {
uiContent_->Foreground();
}
}
if (needNotifyListeners) {
CALL_LIFECYCLE_LISTENER(AfterForeground);
}
}
void Window::NotifyAfterBackground(bool needNotifyListeners, bool needNotifyUiContent)
{
if (needNotifyUiContent) {
if (uiContent_ != nullptr) {
uiContent_->Background();
}
}
if (needNotifyListeners) {
CALL_LIFECYCLE_LISTENER(AfterBackground);
}
}
void Window::UpdateAvoidArea(const std::shared_ptr<Rosen::AvoidArea>& avoidArea, AvoidAreaType type)
{
LOGD("UpdateAvoidArea WindowId:%{public}d, type:%{public}d, top:{%{public}d,%{public}d,%{public}d,%{public}d}, "
"left:{%{public}d,%{public}d,%{public}d,%{public}d}, right:{%{public}d,%{public}d,%{public}d,%{public}d}, "
"bottom:{%{public}d,%{public}d,%{public}d,%{public}d}",
GetWindowId(), type, avoidArea->topRect_.posX_, avoidArea->topRect_.posY_, avoidArea->topRect_.width_,
avoidArea->topRect_.height_, avoidArea->leftRect_.posX_, avoidArea->leftRect_.posY_,
avoidArea->leftRect_.width_, avoidArea->leftRect_.height_, avoidArea->rightRect_.posX_,
avoidArea->rightRect_.posY_, avoidArea->rightRect_.width_, avoidArea->rightRect_.height_,
avoidArea->bottomRect_.posX_, avoidArea->bottomRect_.posY_, avoidArea->bottomRect_.width_,
avoidArea->bottomRect_.height_);
std::lock_guard<std::recursive_mutex> lock(globalMutex_);
avoidAreaMap_[type] = *avoidArea;
NotifyAvoidAreaChange(avoidArea, type);
}
void Window::NotifyAvoidAreaChange(const std::shared_ptr<AvoidArea>& avoidArea, AvoidAreaType type)
{
auto avoidAreaChangeListeners = GetListeners<IAvoidAreaChangedListener>();
LOGD("window NotifyAvoidAreaChange");
for (auto& listener : avoidAreaChangeListeners) {
if (listener != nullptr) {
LOGD("window OnAvoidAreaChanged type=%{public}u", type);
listener->OnAvoidAreaChanged(*avoidArea, type);
}
}
}
void Window::NotifyTouchOutside()
{
auto touchOutsideListeners = GetListeners<ITouchOutsideListener>();
for (auto& listener : touchOutsideListeners) {
if (listener != nullptr) {
listener->OnTouchOutside();
}
}
}
void Window::SubWindowHide()
{
NotifyAfterBackground();
}
void Window::NotifySurfaceDestroyed()
{
surfaceNode_ = nullptr;
if (!uiContent_) {
LOGW("Window Notify Surface Destroyed, uiContent_ is nullptr, delay notify.");
delayNotifySurfaceDestroyed_ = true;
} else {
LOGI("Window Notify uiContent_ Surface Destroyed");
uiContent_->NotifySurfaceDestroyed();
}
auto surfaceNodeListeners = GetListeners<IWindowSurfaceNodeListener>();
for (auto& listener : surfaceNodeListeners) {
if (listener != nullptr) {
listener->OnSurfaceNodeDestroyed();
}
}
}
void Window::WindowFocusChanged(bool hasWindowFocus)
{
if (!uiContent_) {
LOGW("Window::Focus uiContent_ is nullptr");
return;
}
if (hasWindowFocus) {
LOGI("Window(%{public}s): notify uiContent Focus", GetWindowName().c_str());
uiContent_->Focus();
NotifyAfterActive();
isForground_ = true;
isFocused_ = true;
if (IsSubWindow() || subWindowMap_.count(GetWindowId()) == 0) {
return;
}
auto windows = subWindowMap_.at(GetWindowId());
for (auto const& window : windows) {
if (!window->IsWindowShow()) {
window->NotifyAfterInactive();
}
}
} else {
LOGI("Window(%{public}s): notify uiContent UnFocus", GetWindowName().c_str());
uiContent_->UnFocus();
NotifyAfterInactive();
isForground_ = false;
isFocused_ = false;
}
}
void Window::Foreground()
{
LOGI("Window: notify uiContent Background");
NotifyAfterForeground();
isForground_ = true;
}
void Window::Background()
{
LOGI("Window: notify uiContent Background");
NotifyAfterBackground();
isForground_ = false;
}
bool Window::ProcessBackPressed()
{
if (!uiContent_) {
LOGW("Window::ProcessBackPressed uiContent_ is nullptr");
return false;
}
return uiContent_->ProcessBackPressed();
}
bool Window::ProcessBasicEvent(const std::vector<Ace::TouchEvent>& touchEvents)
{
if (!uiContent_) {
LOGW("Window::ProcessBasicEvent uiContent_ is nullptr");
return false;
}
return uiContent_->ProcessBasicEvent(touchEvents);
}
bool Window::ProcessPointerEvent(const std::vector<uint8_t>& data)
{
if (!uiContent_) {
LOGW("Window::ProcessPointerEvent uiContent_ is nullptr");
return false;
}
std::vector<std::shared_ptr<MMI::PointerEvent>> pointerEvents;
CreatePointerEventsFromBytes(pointerEvents, data);
bool result = true;
for (auto& pointerEvent : pointerEvents) {
result &= uiContent_->ProcessPointerEvent(pointerEvent);
}
return result;
}
bool Window::ProcessMouseEvent(const std::vector<uint8_t>& data)
{
if (!uiContent_) {
LOGW("Window::ProcessMouseEvent uiContent_ is nullptr");
return false;
}
return uiContent_->ProcessMouseEvent(data);
}
bool Window::ProcessKeyEvent(int32_t keyCode, int32_t keyAction, int32_t repeatTime, int64_t timeStamp,
int64_t timeStampStart, int32_t source, int32_t deviceId, int32_t metaKey)
{
if (!uiContent_) {
LOGW("Window::ProcessKeyEvent uiContent_ is nullptr");
return false;
}
Ace::KeyCode aceKeyCode = KeyCodeToAceKeyCode(keyCode);
return uiContent_->ProcessKeyEvent(
static_cast<int32_t>(aceKeyCode), keyAction, repeatTime, timeStamp, timeStampStart, metaKey, source, deviceId);
}
void Window::DelayNotifyUIContentIfNeeded()
{
if (!uiContent_) {
LOGE("Window Delay Notify uiContent_ is nullptr!");
return;
}
if (delayNotifySurfaceCreated_) {
LOGD("Window Delay Notify uiContent_ Surface Created");
uiContent_->NotifySurfaceCreated();
}
if (delayNotifySurfaceChanged_) {
LOGD("Window Delay Notify uiContent_ Surface Changed wh:[%{public}d, %{public}d]", surfaceWidth_,
surfaceHeight_);
Ace::ViewportConfig config;
config.SetDensity(density_);
config.SetSize(surfaceWidth_, surfaceHeight_);
config.SetOrientation(surfaceHeight_ >= surfaceWidth_ ? 0 : 1);
uiContent_->UpdateViewportConfig(config, WindowSizeChangeReason::RESIZE);
}
if (delayNotifySurfaceDestroyed_) {
LOGD("Window Delay Notify uiContent_ Surface Destroyed");
uiContent_->NotifySurfaceDestroyed();
delayNotifySurfaceDestroyed_ = false;
}
}
WMError Window::SetUIContent(const std::string& contentInfo, NativeEngine* engine, napi_value storage,
bool isdistributed, AbilityRuntime::Platform::Ability* ability, bool loadContentByName)
{
using namespace OHOS::Ace::Platform;
(void)ability;
if (uiContent_) {
uiContent_->Destroy();
}
std::unique_ptr<UIContent> uiContent;
uiContent = UIContent::Create(context_.get(), engine);
if (uiContent == nullptr) {
return WMError::WM_ERROR_NULLPTR;
}
if (loadContentByName) {
uiContent->InitializeByName(this, contentInfo, storage);
} else {
uiContent->Initialize(this, contentInfo, storage);
}
uiContent_ = std::move(uiContent);
if (isForground_) {
uiContent_->Foreground();
}
DelayNotifyUIContentIfNeeded();
return WMError::WM_OK;
}
UIContent* Window::GetUIContent()
{
return uiContent_.get();
}
void Window::SetWindowView(JNIEnv* env, jobject windowView)
{
if (windowView == nullptr) {
LOGE("Window::SetWindowView: jobject of WindowView is nullptr!");
return;
}
if (windowView_ != nullptr) {
LOGW("Window::SetWindowView: windowView_ has already been set!");
return;
}
windowView_ = env->NewGlobalRef(windowView);
Ace::Platform::WindowViewJni::RegisterWindow(env, this, windowView);
}
void Window::SetSubWindowView(JNIEnv* env, jobject windowView)
{
if (windowView == nullptr) {
LOGE("Window::SetWindowView: jobject of WindowView is nullptr!");
return;
}
windowView_ = env->NewGlobalRef(windowView);
Ace::Platform::WindowViewJni::RegisterWindow(env, this, windowView);
SubWindowManagerJni::RegisterSubWindow(GetWindowName(), this);
}
void Window::ReleaseWindowView()
{
if (windowView_ == nullptr) {
return;
}
auto jniEnv = Ace::Platform::JniEnvironment::GetInstance().GetJniEnv();
Ace::Platform::WindowViewJni::UnRegisterWindow(jniEnv.get(), windowView_);
if (IsSubWindow()) {
SubWindowManagerJni::UnregisterSubWindow(GetWindowName());
}
Ace::Platform::JniEnvironment::DeleteJavaGlobalRef(windowView_);
windowView_ = nullptr;
}
void Window::UpdateConfiguration(const std::shared_ptr<OHOS::AbilityRuntime::Platform::Configuration>& config)
{
if (uiContent_ != nullptr) {
LOGI("Window::UpdateConfiguration called.");
uiContent_->UpdateConfiguration(config);
}
}
void Window::SetUpThreadInfo()
{
static int32_t renderTid = -1;
if (renderTid < 0) {
int32_t tid = -1;
RSRenderThread::Instance().PostSyncTask([&tid]() { tid = gettid(); });
renderTid = tid;
bool ret = AceEnvJni::SetThreadInfo(renderTid);
LOGI("Window::SetUpThreadInfo tid:%{public}d ret:%{public}d.", renderTid, ret);
}
}
WMError Window::SetLayoutFullScreen(bool status)
{
if (SubWindowManagerJni::SetWindowLayoutFullScreen(status)) {
g_IsFullScreen = status;
return WMError::WM_OK;
} else {
LOGE("Window::SetLayoutFullScreen: failed");
return WMError::WM_ERROR_OPER_FULLSCREEN_FAILED;
}
}
WMError Window::SetSpecificBarProperty(WindowType type, const SystemBarProperty& property)
{
bool hide = !property.enable_;
bool result = false;
if (type == WindowType::WINDOW_TYPE_STATUS_BAR) {
result = SubWindowManagerJni::SetStatusBarStatus(hide);
if (result) {
g_IsStatusBarHide = hide;
}
} else if (type == WindowType::WINDOW_TYPE_NAVIGATION_BAR) {
result = SubWindowManagerJni::SetNavigationBarStatus(hide);
} else if (type == WindowType::WINDOW_TYPE_NAVIGATION_INDICATOR) {
result = SubWindowManagerJni::SetNavigationIndicatorStatus(hide);
} else {
LOGE("The WindowType is not set to SpecificBarProperty. The WindowType is %{public}d", type);
}
std::lock_guard<std::recursive_mutex> lock(g_sysBarPropMapMutex);
sysBarPropMap_[type] = property;
if (result) {
return WMError::WM_OK;
} else {
LOGE("Window::SetSpecificBarProperty: failed. The WindowType is %{public}d", type);
return WMError::WM_ERROR_INVALID_WINDOW;
}
}
void Window::OnSafeAreaChange(int type, AvoidArea avoidArea)
{
auto avoidType = static_cast<AvoidAreaType>(type);
std::shared_ptr<Rosen::AvoidArea> avoidArea1 = std::make_shared<Rosen::AvoidArea>(avoidArea);
UpdateAvoidArea(avoidArea1, avoidType);
LOGD("Window OnSafeAreaChange");
}
WMError Window::GetAvoidAreaByType(AvoidAreaType type, AvoidArea& avoidArea)
{
std::lock_guard<std::recursive_mutex> lock(globalMutex_);
auto avoidArea_ = avoidAreaMap_[type];
avoidArea = avoidArea_;
return WMError::WM_OK;
}
WMError Window::UpdateSystemBarProperties(const std::unordered_map<WindowType, SystemBarProperty>& systemBarProperties,
const std::unordered_map<WindowType, SystemBarPropertyFlag>& systemBarPropertyFlags)
{
if (IsSubWindow()) {
return WMError::WM_OK;
}
for (auto& [systemBarType, systemBarPropertyFlag] : systemBarPropertyFlags) {
if (systemBarProperties.find(systemBarType) == systemBarProperties.end()) {
LOGI("Window::UpdateSystemBarProperties system bar type is invalid");
return WMError::WM_DO_NOTHING;
}
auto property = GetSystemBarPropertyByType(systemBarType);
property.enable_ =
systemBarPropertyFlag.enableFlag ? systemBarProperties.at(systemBarType).enable_ : property.enable_;
property.backgroundColor_ = systemBarPropertyFlag.backgroundColorFlag
? systemBarProperties.at(systemBarType).backgroundColor_
: property.backgroundColor_;
property.contentColor_ = systemBarPropertyFlag.contentColorFlag
? systemBarProperties.at(systemBarType).contentColor_
: property.contentColor_;
property.enableAnimation_ = systemBarPropertyFlag.enableAnimationFlag
? systemBarProperties.at(systemBarType).enableAnimation_
: property.enableAnimation_;
if (systemBarPropertyFlag.enableFlag) {
property.settingFlag_ |= SystemBarSettingFlag::ENABLE_SETTING;
}
if (systemBarPropertyFlag.backgroundColorFlag || systemBarPropertyFlag.contentColorFlag) {
property.settingFlag_ |= SystemBarSettingFlag::COLOR_SETTING;
}
if (systemBarPropertyFlag.enableFlag || systemBarPropertyFlag.backgroundColorFlag ||
systemBarPropertyFlag.contentColorFlag || systemBarPropertyFlag.enableAnimationFlag) {
if (systemBarType == WindowType::WINDOW_TYPE_STATUS_BAR) {
SubWindowManagerJni::SetStatusBar(property.backgroundColor_, property.contentColor_);
} else if (systemBarType == WindowType::WINDOW_TYPE_NAVIGATION_BAR) {
SubWindowManagerJni::SetNavigationBar(property.backgroundColor_, property.contentColor_);
} else {
LOGE("The WindowType is not set to UpdateSystemBarProperties. The WindowType is %{public}d",
systemBarType);
}
}
std::lock_guard<std::recursive_mutex> lock(g_sysBarPropMapMutex);
sysBarPropMap_[systemBarType] = property;
}
return WMError::WM_OK;
}
WMError Window::SetWindowPrivacyMode(bool isPrivacyMode)
{
if (IsSubWindow()) {
return WMError::WM_OK;
}
LOGI("Window::SetWindowPrivacyMode called. isPrivacyMode=%d", isPrivacyMode);
bool result = SubWindowManagerJni::SetWindowPrivacyMode(isPrivacyMode);
if (result) {
return WMError::WM_OK;
} else {
LOGI("Window::SetWindowPrivacyMode: failed");
return WMError::WM_ERROR_INVALID_WINDOW;
}
}
WMError Window::Hide()
{
LOGI("Window::Hide called.");
if (GetWindowName().empty()) {
LOGI("Window::Hide called failed due to null option");
return WMError::WM_ERROR_INVALID_WINDOW;
}
bool result = SubWindowManagerJni::Hide(GetWindowName());
if (result) {
isForground_ = false;
NotifyAfterBackground();
return WMError::WM_OK;
} else {
return WMError::WM_ERROR_INVALID_WINDOW;
}
}
WMError Window::SetFocusable(bool isFocusable)
{
LOGI("Window::SetFocusable called. isFocusable=%{public}d", isFocusable);
bool result = SubWindowManagerJni::SetFocusable(this->GetWindowName(), isFocusable);
if (result) {
LOGI("Window::SetFocusable: success");
return WMError::WM_OK;
} else {
LOGI("Window::SetFocusable: failed");
return WMError::WM_ERROR_INVALID_WINDOW;
}
}
WMError Window::SetTouchable(bool isTouchable)
{
LOGI("Window::SetTouchable called. isTouchable=%{public}d", isTouchable);
bool result = SubWindowManagerJni::SetTouchable(GetWindowName(), isTouchable);
if (result) {
LOGI("Window::SetTouchable: success");
return WMError::WM_OK;
} else {
LOGI("Window::SetTouchable: failed");
return WMError::WM_ERROR_INVALID_WINDOW;
}
}
bool Window::RequestFocus()
{
bool result = SubWindowManagerJni::RequestFocus(GetWindowName());
LOGI("Window::RequestFocus return %{public}d", result);
return result;
}
bool Window::IsFocused()
{
LOGI("Window::IsFocused called(%{public}s). isFocused_=%{public}d", GetWindowName().c_str(), isFocused_);
return isFocused_;
}
WMError Window::SetTouchHotAreas(const std::vector<Rect>& rects)
{
LOGI("Window::SetTouchHotAreas called");
if (rects.empty()) {
LOGI("rects is empty");
return WMError::WM_ERROR_INVALID_PARAM;
}
bool result = SubWindowManagerJni::SetTouchHotAreas(GetWindowName(), rects);
if (result) {
LOGI("Window::SetTouchable: success");
return WMError::WM_OK;
} else {
LOGI("Window::SetTouchable: failed");
return WMError::WM_ERROR_INVALID_WINDOW;
}
}
WMError Window::SetFullScreen(bool status)
{
LOGI("Window::SetFullScreen called. status=%{public}d", status);
bool result = SubWindowManagerJni::SetFullScreen(GetWindowName(), status);
if (result) {
LOGI("Window::SetFullScreen: success");
return WMError::WM_OK;
} else {
LOGI("Window::SetFullScreen: failed");
return WMError::WM_ERROR_INVALID_WINDOW;
}
}
WMError Window::SetOnTop(bool status)
{
LOGI("Window::SetOnTop called. status=%{public}d", status);
bool result = SubWindowManagerJni::SetOnTop(GetWindowName(), status);
if (result) {
LOGI("Window::SetOnTop: success");
return WMError::WM_OK;
} else {
LOGI("Window::SetOnTop: failed");
return WMError::WM_ERROR_INVALID_WINDOW;
}
}
std::shared_ptr<RSUIContext> Window::GetRSUIContext() const
{
auto rsUIContext = rsUIDirector_ ? rsUIDirector_->GetRSUIContext() : nullptr;
return rsUIContext;
}
}