/*
* Copyright (c) 2023-2026 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 "adapter/ios/entrance/virtual_rs_window.h"
#include <__nullptr>
#include <_types/_uint32_t.h>
#include <memory>
#include <UIKit/UIKit.h>
#include <objc/objc.h>
#include "WindowView.h"
#include "adapter/ios/stage/uicontent/ui_content_impl.h"
#include "base/log/log.h"
#include "foundation/appframework/arkui/uicontent/ui_content.h"
#include "transaction/rs_interfaces.h"
#include "render_service_client/core/ui/rs_ui_director.h"
#include "render_service_client/core/ui/rs_ui_context.h"
#include "virtual_rs_window.h"
#include "StageViewController.h"
#include "StageApplication.h"
#include "window_view_adapter.h"
#include "window_interface.h"
#include "window_option.h"
#include "InstanceIdGenerator.h"
#include "hilog.h"
#include "napi/native_api.h"
#include "core/event/touch_event.h"
#include "core/event/key_event.h"
#include "core/pipeline/pipeline_base.h"
#include "interaction/interaction_impl.h"
#include "mmi_event_convertor.h"
#include "AccessibilityWindowView.h"
namespace OHOS::Rosen {
#define BOTTOM_SAFE_AREA_HEIGHT_VP 28.0
const std::string DRAG_WINDOW_NAME = "dragWindow";
Ace::KeyCode KeyCodeToAceKeyCode(int32_t keyCode)
{
Ace::KeyCode aceKeyCode = Ace::KeyCode::KEY_UNKNOWN;
const static std::map<int32_t, Ace::KeyCode> TO_OHOS_KEYCODE_MAP = {
{ 4 /* UIKeyboardHIDUsageKeyboardA */, Ace::KeyCode::KEY_A },
{ 5 /* UIKeyboardHIDUsageKeyboardB */, Ace::KeyCode::KEY_B },
{ 6 /* UIKeyboardHIDUsageKeyboardC */, Ace::KeyCode::KEY_C },
{ 7 /* UIKeyboardHIDUsageKeyboardD */, Ace::KeyCode::KEY_D },
{ 8 /* UIKeyboardHIDUsageKeyboardE */, Ace::KeyCode::KEY_E },
{ 9 /* UIKeyboardHIDUsageKeyboardF */, Ace::KeyCode::KEY_F },
{ 10 /* UIKeyboardHIDUsageKeyboardG */, Ace::KeyCode::KEY_G },
{ 11 /* UIKeyboardHIDUsageKeyboardH */, Ace::KeyCode::KEY_H },
{ 12 /* UIKeyboardHIDUsageKeyboardI */, Ace::KeyCode::KEY_I },
{ 13 /* UIKeyboardHIDUsageKeyboardJ */, Ace::KeyCode::KEY_J },
{ 14 /* UIKeyboardHIDUsageKeyboardK */, Ace::KeyCode::KEY_K },
{ 15 /* UIKeyboardHIDUsageKeyboardL */, Ace::KeyCode::KEY_L },
{ 16 /* UIKeyboardHIDUsageKeyboardM */, Ace::KeyCode::KEY_M },
{ 17 /* UIKeyboardHIDUsageKeyboardN */, Ace::KeyCode::KEY_N },
{ 18 /* UIKeyboardHIDUsageKeyboardO */, Ace::KeyCode::KEY_O },
{ 19 /* UIKeyboardHIDUsageKeyboardP */, Ace::KeyCode::KEY_P },
{ 20 /* UIKeyboardHIDUsageKeyboardQ */, Ace::KeyCode::KEY_Q },
{ 21 /* UIKeyboardHIDUsageKeyboardR */, Ace::KeyCode::KEY_R },
{ 22 /* UIKeyboardHIDUsageKeyboardS */, Ace::KeyCode::KEY_S },
{ 23 /* UIKeyboardHIDUsageKeyboardT */, Ace::KeyCode::KEY_T },
{ 24 /* UIKeyboardHIDUsageKeyboardU */, Ace::KeyCode::KEY_U },
{ 25 /* UIKeyboardHIDUsageKeyboardV */, Ace::KeyCode::KEY_V },
{ 26 /* UIKeyboardHIDUsageKeyboardW */, Ace::KeyCode::KEY_W },
{ 27 /* UIKeyboardHIDUsageKeyboardX */, Ace::KeyCode::KEY_X },
{ 28 /* UIKeyboardHIDUsageKeyboardY */, Ace::KeyCode::KEY_Y },
{ 29 /* UIKeyboardHIDUsageKeyboardZ */, Ace::KeyCode::KEY_Z },
{ 30 /* UIKeyboardHIDUsageKeyboard1 */, Ace::KeyCode::KEY_1 },
{ 31 /* UIKeyboardHIDUsageKeyboard2 */, Ace::KeyCode::KEY_2 },
{ 32 /* UIKeyboardHIDUsageKeyboard3 */, Ace::KeyCode::KEY_3 },
{ 33 /* UIKeyboardHIDUsageKeyboard4 */, Ace::KeyCode::KEY_4 },
{ 34 /* UIKeyboardHIDUsageKeyboard5 */, Ace::KeyCode::KEY_5 },
{ 35 /* UIKeyboardHIDUsageKeyboard6 */, Ace::KeyCode::KEY_6 },
{ 36 /* UIKeyboardHIDUsageKeyboard7 */, Ace::KeyCode::KEY_7 },
{ 37 /* UIKeyboardHIDUsageKeyboard8 */, Ace::KeyCode::KEY_8 },
{ 38 /* UIKeyboardHIDUsageKeyboard9 */, Ace::KeyCode::KEY_9 },
{ 39 /* UIKeyboardHIDUsageKeyboard0 */, Ace::KeyCode::KEY_0 },
{ 40 /* UIKeyboardHIDUsageKeyboardReturnOrEnter */, Ace::KeyCode::KEY_ENTER },
{ 41 /* UIKeyboardHIDUsageKeyboardEscape */, Ace::KeyCode::KEY_ESCAPE },
{ 42 /* UIKeyboardHIDUsageKeyboardDeleteOrBackspace */, Ace::KeyCode::KEY_DEL },
{ 43 /* UIKeyboardHIDUsageKeyboardTab */, Ace::KeyCode::KEY_TAB },
{ 44 /* UIKeyboardHIDUsageKeyboardSpacebar */, Ace::KeyCode::KEY_SPACE },
{ 45 /* UIKeyboardHIDUsageKeyboardHyphen */, Ace::KeyCode::KEY_MINUS },
{ 46 /* UIKeyboardHIDUsageKeyboardEqualSign */, Ace::KeyCode::KEY_EQUALS },
{ 47 /* UIKeyboardHIDUsageKeyboardOpenBracket */, Ace::KeyCode::KEY_LEFT_BRACKET },
{ 48 /* UIKeyboardHIDUsageKeyboardCloseBracket */, Ace::KeyCode::KEY_RIGHT_BRACKET },
{ 49 /* UIKeyboardHIDUsageKeyboardBackslash */, Ace::KeyCode::KEY_BACKSLASH },
{ 51 /* UIKeyboardHIDUsageKeyboardSemicolon */, Ace::KeyCode::KEY_SEMICOLON },
{ 52 /* UIKeyboardHIDUsageKeyboardQuote */, Ace::KeyCode::KEY_APOSTROPHE },
{ 53 /* UIKeyboardHIDUsageKeyboardGraveAccentAndTilde */, Ace::KeyCode::KEY_GRAVE },
{ 54 /* UIKeyboardHIDUsageKeyboardComma */, Ace::KeyCode::KEY_COMMA },
{ 55 /* UIKeyboardHIDUsageKeyboardPeriod */, Ace::KeyCode::KEY_PERIOD },
{ 56 /* UIKeyboardHIDUsageKeyboardSlash */, Ace::KeyCode::KEY_SLASH },
{ 57 /* UIKeyboardHIDUsageKeyboardCapsLock */, Ace::KeyCode::KEY_CAPS_LOCK },
{ 58 /* UIKeyboardHIDUsageKeyboardF1 */, Ace::KeyCode::KEY_F1 },
{ 59 /* UIKeyboardHIDUsageKeyboardF2 */, Ace::KeyCode::KEY_F2 },
{ 60 /* UIKeyboardHIDUsageKeyboardF3 */, Ace::KeyCode::KEY_F3 },
{ 61 /* UIKeyboardHIDUsageKeyboardF4 */, Ace::KeyCode::KEY_F4 },
{ 62 /* UIKeyboardHIDUsageKeyboardF5 */, Ace::KeyCode::KEY_F5 },
{ 63 /* UIKeyboardHIDUsageKeyboardF6 */, Ace::KeyCode::KEY_F6 },
{ 64 /* UIKeyboardHIDUsageKeyboardF7 */, Ace::KeyCode::KEY_F7 },
{ 65 /* UIKeyboardHIDUsageKeyboardF8 */, Ace::KeyCode::KEY_F8 },
{ 66 /* UIKeyboardHIDUsageKeyboardF9 */, Ace::KeyCode::KEY_F9 },
{ 67 /* UIKeyboardHIDUsageKeyboardF10 */, Ace::KeyCode::KEY_F10 },
{ 68 /* UIKeyboardHIDUsageKeyboardF11 */, Ace::KeyCode::KEY_F11 },
{ 69 /* UIKeyboardHIDUsageKeyboardF12 */, Ace::KeyCode::KEY_F12 },
{ 70 /* UIKeyboardHIDUsageKeyboardPrintScreen */, Ace::KeyCode::KEY_SYSRQ },
{ 71 /* UIKeyboardHIDUsageKeyboardScrollLock */, Ace::KeyCode::KEY_SCROLL_LOCK },
{ 72 /* UIKeyboardHIDUsageKeyboardPause */, Ace::KeyCode::KEY_BREAK },
{ 73 /* UIKeyboardHIDUsageKeyboardInsert */, Ace::KeyCode::KEY_INSERT },
{ 74 /* UIKeyboardHIDUsageKeyboardHome */, Ace::KeyCode::KEY_MOVE_HOME },
{ 75 /* UIKeyboardHIDUsageKeyboardPageUp */, Ace::KeyCode::KEY_PAGE_UP },
{ 76 /* UIKeyboardHIDUsageKeyboardDeleteForward */, Ace::KeyCode::KEY_FORWARD_DEL },
{ 77 /* UIKeyboardHIDUsageKeyboardEnd */, Ace::KeyCode::KEY_MOVE_END },
{ 78 /* UIKeyboardHIDUsageKeyboardPageDown */, Ace::KeyCode::KEY_PAGE_DOWN },
{ 79 /* UIKeyboardHIDUsageKeyboardRightArrow */, Ace::KeyCode::KEY_DPAD_RIGHT },
{ 80 /* UIKeyboardHIDUsageKeyboardLeftArrow */, Ace::KeyCode::KEY_DPAD_LEFT },
{ 81 /* UIKeyboardHIDUsageKeyboardDownArrow */, Ace::KeyCode::KEY_DPAD_DOWN },
{ 82 /* UIKeyboardHIDUsageKeyboardUpArrow */, Ace::KeyCode::KEY_DPAD_UP },
{ 83 /* UIKeyboardHIDUsageKeypadNumLock */, Ace::KeyCode::KEY_NUM_LOCK },
{ 84 /* UIKeyboardHIDUsageKeypadSlash */, Ace::KeyCode::KEY_NUMPAD_DIVIDE },
{ 85 /* UIKeyboardHIDUsageKeypadAsterisk */, Ace::KeyCode::KEY_NUMPAD_MULTIPLY },
{ 86 /* UIKeyboardHIDUsageKeypadHyphen */, Ace::KeyCode::KEY_NUMPAD_SUBTRACT },
{ 87 /* UIKeyboardHIDUsageKeypadPlus */, Ace::KeyCode::KEY_NUMPAD_ADD },
{ 88 /* UIKeyboardHIDUsageKeypadEnter */, Ace::KeyCode::KEY_NUMPAD_ENTER },
{ 89 /* UIKeyboardHIDUsageKeypad1 */, Ace::KeyCode::KEY_NUMPAD_1 },
{ 90 /* UIKeyboardHIDUsageKeypad2 */, Ace::KeyCode::KEY_NUMPAD_2 },
{ 91 /* UIKeyboardHIDUsageKeypad3 */, Ace::KeyCode::KEY_NUMPAD_3 },
{ 92 /* UIKeyboardHIDUsageKeypad4 */, Ace::KeyCode::KEY_NUMPAD_4 },
{ 93 /* UIKeyboardHIDUsageKeypad5 */, Ace::KeyCode::KEY_NUMPAD_5 },
{ 94 /* UIKeyboardHIDUsageKeypad6 */, Ace::KeyCode::KEY_NUMPAD_6 },
{ 95 /* UIKeyboardHIDUsageKeypad7 */, Ace::KeyCode::KEY_NUMPAD_7 },
{ 96 /* UIKeyboardHIDUsageKeypad8 */, Ace::KeyCode::KEY_NUMPAD_8 },
{ 97 /* UIKeyboardHIDUsageKeypad9 */, Ace::KeyCode::KEY_NUMPAD_9 },
{ 98 /* UIKeyboardHIDUsageKeypad0 */, Ace::KeyCode::KEY_NUMPAD_0 },
{ 99 /* UIKeyboardHIDUsageKeypadPeriod */, Ace::KeyCode::KEY_NUMPAD_DOT },
{ 101 /* UIKeyboardHIDUsageKeyboardApplication */, (Ace::KeyCode)2466 },
{ 224 /* UIKeyboardHIDUsageKeyboardLeftControl */, Ace::KeyCode::KEY_CTRL_LEFT },
{ 225 /* UIKeyboardHIDUsageKeyboardLeftShift */, Ace::KeyCode::KEY_SHIFT_LEFT },
{ 226 /* UIKeyboardHIDUsageKeyboardLeftAlt */, Ace::KeyCode::KEY_ALT_LEFT },
{ 227 /* UIKeyboardHIDUsageKeyboardLeftGUI */, Ace::KeyCode::KEY_META_LEFT },
{ 228 /* UIKeyboardHIDUsageKeyboardRightControl */, Ace::KeyCode::KEY_CTRL_RIGHT },
{ 229 /* UIKeyboardHIDUsageKeyboardRightShift */, Ace::KeyCode::KEY_SHIFT_RIGHT },
{ 230 /* UIKeyboardHIDUsageKeyboardRightAlt */, Ace::KeyCode::KEY_ALT_RIGHT },
{ 231 /* UIKeyboardHIDUsageKeyboardRightGUI */, Ace::KeyCode::KEY_META_RIGHT },
};
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 },
};
const char* const kOrientationMaskUpdateNotificationName = "arkui_x.iosPlatform.setPreferredOrientationNotificationName";
const char* const kOrientationMaskUpdateNotificationKey = "arkui_x.iosPlatform.setPreferredOrientationNotificationKey";
void DummyWindowRelease(Window* window)
{
window->DecStrongRef(window);
LOGI("Rosenwindow rsWindow_Window: dummy release");
}
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<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<IWindowStatusChangeListener>>> Window::windowStatusChangeListeners_;
std::map<uint32_t, std::vector<sptr<IAvoidAreaChangedListener>>> Window::avoidAreaChangeListeners_;
std::recursive_mutex Window::globalMutex_;
std::map<uint32_t, std::vector<sptr<IOccupiedAreaChangeListener>>> Window::occupiedAreaChangeListeners_;
std::map<uint32_t, std::vector<sptr<IAvoidAreaChangedListener>>> Window::avoidAreaChangedListeners_;
constexpr Rect emptyRect = {0, 0, 0, 0};
static Rect MakeAvoidRect(float left, float top , float width, float height) {
if (width <= 0 || height <= 0) {
width = 0;
height = 0;
left = 0;
top = 0;
}
return (Rect){left, top, width, height};
}
static uint32_t ColorConvertFromUIColor(UIColor* uiColor)
{
if (uiColor == nullptr) {
return 0;
}
CGFloat red = 0;
CGFloat green = 0;
CGFloat blue = 0;
CGFloat alpha = 0;
[uiColor getRed:&red green:&green blue:&blue alpha:&alpha];
uint32_t result = ((uint8_t)(red * UINT8_MAX)<<24) |
((uint8_t)(green * UINT8_MAX)<<16) |
((uint8_t)(blue * UINT8_MAX)<<8) |
((uint8_t)(alpha * UINT8_MAX));
return result;
}
static UIColor* ColorConvertToUIColor(uint32_t color)
{
return [UIColor colorWithRed:(((color>>24)&UINT8_MAX)*1.0/UINT8_MAX)
green:(((color>>16)&UINT8_MAX)*1.0/UINT8_MAX)
blue:(((color>>8)&UINT8_MAX)*1.0/UINT8_MAX)
alpha:((color&UINT8_MAX)*1.0/UINT8_MAX)];
}
static WMError SetSystemBar(WindowType type, const SystemBarProperty& property)
{
StageViewController *controller = [StageApplication getApplicationTopViewController];
if (![controller isKindOfClass:[StageViewController class]]) {
return WMError::WM_ERROR_INVALID_WINDOW;
}
if (type == WindowType::WINDOW_TYPE_NAVIGATION_BAR) {
if (!property.enable_) {
[controller.navigationController setNavigationBarHidden:YES animated:NO];
} else {
[controller.navigationController setNavigationBarHidden:NO animated:NO];
[controller setNeedsStatusBarAppearanceUpdate];
}
} else if (type == WindowType::WINDOW_TYPE_STATUS_BAR) {
if (!property.enable_) {
controller.statusBarHidden = YES;
} else {
controller.statusBarHidden = NO;
}
[[UIApplication sharedApplication]setStatusBarHidden:!property.enable_ animated:property.enableAnimation_];
if (property.enableAnimation_) {
[UIView animateWithDuration:0.25 animations:^{
[controller setNeedsStatusBarAppearanceUpdate];
}];
} else {
[controller setNeedsStatusBarAppearanceUpdate];
}
}
[controller.view setNeedsLayout];
[controller.view layoutIfNeeded];
return WMError::WM_OK;
}
static WMError SetSpecificBar(WindowType type, const SystemBarProperty& property) {
StageViewController* controller = [StageApplication getApplicationTopViewController];
WMError ret = WMError::WM_OK;
if (![controller isKindOfClass:[StageViewController class]]) {
return WMError::WM_ERROR_INVALID_WINDOW;
}
if (type == WindowType::WINDOW_TYPE_STATUS_BAR || type == WindowType::WINDOW_TYPE_NAVIGATION_BAR) {
ret = SetSystemBar(type, property);
} else if (type == WindowType::WINDOW_TYPE_NAVIGATION_INDICATOR) {
if (@available(iOS 11.0, *)) {
if (!property.enable_) {
LOGI("Set homeIndicatorAutoHidden - hidden");
controller.homeIndicatorHidden = YES;
[controller setNeedsUpdateOfHomeIndicatorAutoHidden];
} else {
LOGI("Set homeIndicatorAutoHidden - show");
controller.homeIndicatorHidden = NO;
[controller setNeedsUpdateOfHomeIndicatorAutoHidden];
}
[controller.view setNeedsLayout];
[controller.view layoutIfNeeded];
} else {
LOGE("Set SetSpecificBarProperty failed, iOS version less than 11");
return WMError::WM_ERROR_INVALID_PARAM;
}
} else {
LOGE("Set SetSpecificBarProperty failed, invalid parm");
return WMError::WM_ERROR_INVALID_PARAM;
}
// WINDOW_TYPE_NAVIGATION_INDICATOR
return WMError::WM_OK;
}
Window::Window(std::shared_ptr<AbilityRuntime::Platform::Context> context, uint32_t windowId)
: context_(context), windowId_(windowId)
{
}
Window::~Window()
{
LOGI("Window: release id = %u", windowId_);
ReleaseWindowView();
}
std::shared_ptr<Window> Window::Create(
std::shared_ptr<OHOS::AbilityRuntime::Platform::Context> context, void* windowView)
{
LOGI("Window::Create with %{public}p", windowView);
std::string windowName = AbilityRuntime::Platform::WindowViewAdapter::GetInstance()->GetWindowName(windowView);
if (CheckWindowNameExist(windowName)) {
HILOG_ERROR("Window::Create : windowName exist! windowName=%{public}s", windowName.c_str());
return nullptr;
}
uint32_t windowId = [InstanceIdGenerator getAndIncrement];
auto window = std::shared_ptr<Window>(new Window(context, windowId), DummyWindowRelease);
window->SetWindowView((WindowView*)windowView);
window->SetWindowName(windowName);
window->IncStrongRef(window.get());
window->SetMode(Rosen::WindowMode::WINDOW_MODE_FULLSCREEN);
[(WindowView*)windowView setWindowDelegate:window];
AddToWindowMap(window);
return window;
}
std::shared_ptr<Window> Window::CreateSubWindow(
std::shared_ptr<OHOS::AbilityRuntime::Platform::Context> context,
std::shared_ptr<OHOS::Rosen::WindowOption> option)
{
if (CheckWindowNameExist(option->GetWindowName())) {
HILOG_ERROR("Window::CreateSubWindow : windowName exist! windowName=%{public}s", option->GetWindowName().c_str());
return nullptr;
}
uint32_t windowId = [InstanceIdGenerator getAndIncrement];
if (option->GetWindowType() != OHOS::Rosen::WindowType::WINDOW_TYPE_APP_SUB_WINDOW) {
LOGI("Window::CreateSubWindow failed, window type error![windowType=%{public}d]", static_cast<int32_t>(option->GetWindowType()));
return nullptr;
}
auto window = std::shared_ptr<Window>(new Window(context, windowId), DummyWindowRelease);
AccessibilityWindowView* windowView = [[AccessibilityWindowView alloc]init];
LOGI("Window::Createsubwindow with %{public}p", windowView);
window->SetWindowView(windowView);
[windowView setWindowDelegate:window];
[windowView createSurfaceNode];
window->IncStrongRef(window.get());
window->SetWindowName(option->GetWindowName());
window->SetWindowType(option->GetWindowType());
window->SetMode(Rosen::WindowMode::WINDOW_MODE_FLOATING);
LOGI("Window::Createsubwindow with name:%s, parentId=%{public}u", window->GetWindowName().c_str(), option->GetParentId());
window->SetParentId(option->GetParentId());
AddToSubWindowMap(window);
AddToWindowMap(window);
ShowSubWindowMap("Window::CreateSubWindow", window->GetParentId());
return window;
}
std::shared_ptr<Window> Window::CreateDragWindow(
std::shared_ptr<OHOS::AbilityRuntime::Platform::Context> context)
{
auto mainWindow = Window::GetTopWindow(context);
if (!mainWindow) {
LOGI("Window::CreateDragWindow failed,can not find mainWindow");
return nullptr;
}
std::shared_ptr<WindowOption> option = std::make_shared<WindowOption>();
if (!option) {
LOGI("Window::CreateDragWindow failed,option ==nullptr");
return nullptr;
}
option->SetParentId(mainWindow->GetWindowId());
option->SetWindowType(Rosen::WindowType::WINDOW_TYPE_APP_SUB_WINDOW);
option->SetWindowMode(Rosen::WindowMode::WINDOW_MODE_FLOATING);
std::string windowName = mainWindow->GetWindowName() + DRAG_WINDOW_NAME;
option->SetWindowName(windowName);
std::shared_ptr<Window> window = Window::CreateSubWindow(context, option);
if (window == nullptr) {
HILOG_ERROR("drag window is null");
return nullptr;
}
window->SetTouchable(false);
window->SetFocusable(false);
window->SetFullScreen(true);
window->SetOnTop(true);
return window;
}
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)));
}
bool Window::CheckWindowNameExist(const std::string& windowName)
{
auto iter = windowMap_.find(windowName);
if (iter == windowMap_.end()) {
return false;
}
return true;
}
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)
{
HILOG_INFO("Window::AddToSubWindowMap : Start...");
if (window == nullptr) {
HILOG_ERROR("window is null");
return;
}
if (window->GetType() != OHOS::Rosen::WindowType::WINDOW_TYPE_APP_SUB_WINDOW ||
window->GetParentId() == INVALID_WINDOW_ID) {
HILOG_ERROR("window is not subwindow");
return;
}
DeleteFromSubWindowMap(window);
uint32_t parentId = window->GetParentId();
subWindowMap_[parentId].push_back(window);
HILOG_INFO("Window::AddToSubWindowMap : End!!!");
}
void Window::DeleteFromSubWindowMap(std::shared_ptr<Window> window)
{
HILOG_INFO("Window::DeleteFromSubWindowMap : Start...");
if (window == nullptr) {
HILOG_INFO("Window::DeleteFromSubWindowMap : window is null");
return;
}
uint32_t parentId = window->GetParentId();
if (parentId == INVALID_WINDOW_ID) {
HILOG_INFO("Window::DeleteFromSubWindowMap : parentId is invalid");
return;
}
auto iter1 = subWindowMap_.find(parentId);
if (iter1 == subWindowMap_.end()) {
HILOG_INFO("Window::DeleteFromSubWindowMap : find parentId failed");
return;
}
auto subWindows = iter1->second;
auto iter2 = subWindows.begin();
while (iter2 != subWindows.end()) {
if (*iter2 == window) {
subWindows.erase(iter2);
((*iter2)->Destroy());
break;
} else {
iter2++;
}
}
HILOG_INFO("Window::AddToSubWindowMap : End!!!");
}
void Window::ShowSubWindowMap(const std::string& str, uint32_t parentId)
{
auto iter1 = subWindowMap_.find(parentId);
if (iter1 == subWindowMap_.end()) {
HILOG_INFO("Window::ShowSubWindowMap : %{public}s : find parentId failed! parentId=%{public}u",
str.c_str(), parentId);
return;
}
auto subWindows = iter1->second;
auto iter2 = subWindows.begin();
while (iter2 != subWindows.end()) {
HILOG_INFO("Window::ShowSubWindowMap : %{public}s : windowId=%{public}u, windowName=%{public}s",
str.c_str(), (*iter2)->GetWindowId(), (*iter2)->GetWindowName().c_str());
iter2++;
}
}
WMError Window::Destroy()
{
HILOG_INFO("Window::Destroy");
if (uiContent_ != nullptr) {
uiContent_->Destroy();
uiContent_ = nullptr;
}
NotifyBeforeDestroy(GetWindowName());
if (windowView_ != nullptr) {
[windowView_ hide];
[windowView_ release];
windowView_ = nullptr;
}
isWindowShow_ = false;
ClearListenersById(GetWindowId());
// Remove subWindows of current window from subWindowMap_
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);
DeleteFromWindowMap(windowPtr);
windowPtr->Destroy();
}
subWindowMap_[GetWindowId()].clear();
subWindowMap_.erase(GetWindowId());
}
// Rmove current window from subWindowMap_ of parent window
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;
}
}
}
// Remove current window from windowMap_
if (windowMap_.count(GetWindowName()) > 0) {
DeleteFromWindowMap(this);
}
NotifyAfterBackground();
return WMError::WM_OK;
}
void Window::RegisterWindowDestroyedListener(const NotifyNativeWinDestroyFunc& func)
{
LOGD("Start register");
notifyNativefunc_ = std::move(func);
}
void Window::RegisterWillTerminateListener(const NotifyWillTerminateFunc& func)
{
notifyWillTerminatefunc_ = std::move(func);
}
void Window::NotifyApplicationForeground(bool applicationForeground)
{
LOGI("NotifyApplicationForeground: %{public}d", applicationForeground);
applicationForeground_ = applicationForeground;
}
std::vector<std::shared_ptr<Window>> Window::GetSubWindow(uint32_t parentId)
{
HILOG_INFO("Window::GetSubWindow : Start... / parentId = %{public}u, subWIndowMapSize=%{public}u",
parentId, subWindowMap_.size());
if (subWindowMap_.find(parentId) == subWindowMap_.end()) {
HILOG_INFO("Window::GetSubWindow : find subwindow failed");
return std::vector<std::shared_ptr<Window>>();
}
HILOG_INFO("Window::GetSubWindow : find subwindow success, parentId=%u, subwindowSize=%u",
parentId, subWindowMap_[parentId].size());
ShowSubWindowMap("Window::GetSubWindow", parentId);
return subWindowMap_[parentId];
}
std::shared_ptr<Window> Window::FindWindow(const std::string& name)
{
auto iter = windowMap_.find(name);
if (iter == windowMap_.end()) {
return nullptr;
}
return iter->second.second;
}
std::shared_ptr<Window> Window::FindWindow(const int windowId)
{
for (auto iter = windowMap_.begin(); iter != windowMap_.end(); iter++) {
if (iter->second.first == windowId) {
return iter->second.second;
}
}
return nullptr;
}
std::shared_ptr<Window> Window::GetTopWindow(const std::shared_ptr<OHOS::AbilityRuntime::Platform::Context>& context)
{
StageViewController *controller = [StageApplication getApplicationTopViewController];
if (![controller isKindOfClass:[StageViewController class]]) {
return nullptr;
}
NSString *instanceName = controller.instanceName;
WindowView *windowView = static_cast<WindowView*>(OHOS::AbilityRuntime::Platform
::WindowViewAdapter::GetInstance()->GetWindowView([instanceName UTF8String]));
return [windowView getWindow];
}
WMError Window::ShowWindow()
{
if (!windowView_) {
LOGE("Window: showWindow failed");
return WMError::WM_ERROR_INVALID_PARENT;
}
StageViewController *controller = [StageApplication getApplicationTopViewController];
if (![controller isKindOfClass:[StageViewController class]]) {
return WMError::WM_ERROR_INVALID_PARENT;
}
UIView *mainWindowView = [controller getWindowView];
if ([windowView_ showOnView:mainWindowView.superview]) {
DelayNotifyUIContentIfNeeded();
NotifyAfterForeground();
isWindowShow_ = true;
UpdateWindowStatus();
return WMError::WM_OK;
}
return WMError::WM_ERROR_INVALID_PARENT;
}
WMError Window::Hide()
{
if (!windowView_) {
LOGE("Window: showWindow failed");
return WMError::WM_ERROR_INVALID_PARENT;
}
if ([windowView_ hide]) {
isWindowShow_ = false;
NotifyAfterBackground();
UpdateWindowStatus();
return WMError::WM_OK;
}
return WMError::WM_ERROR_INVALID_PARENT;
}
WMError Window::MoveWindowTo(int32_t x, int32_t y)
{
if (!windowView_) {
LOGE("Window: MoveWindowTo failed");
return WMError::WM_ERROR_INVALID_PARENT;
}
if (isFullScreen_) {
return WMError::WM_ERROR_INVALID_PARENT;
}
UIScreen *screen = [UIScreen mainScreen];
CGFloat scale = screen.scale;
if (scale == 0) {
scale = 2;
}
rect_.posX_ = x;
rect_.posY_ = y;
x = x < 0 ? 0 : x / scale;
y = y < 0 ? 0 : y / scale;
windowView_.frame = CGRectMake(x, y, windowView_.frame.size.width, windowView_.frame.size.height);
return WMError::WM_OK;
}
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);
}
WMError Window::SetFullScreen(bool status)
{
if (!windowView_) {
LOGE("Window: SetFullScreen failed");
return WMError::WM_ERROR_INVALID_WINDOW;
}
windowView_.fullScreen = status;
isFullScreen_ = status;
return WMError::WM_OK;
}
WMError Window::SetOnTop(bool status)
{
if (!windowView_) {
LOGE("Window: SetFullScreen failed");
return WMError::WM_ERROR_INVALID_WINDOW;
}
if (status) {
windowView_.zOrder = NSIntegerMax;
} else {
windowView_.zOrder = 0;
}
return WMError::WM_OK;
}
WMError Window::SetFocusable(bool focusable)
{
if (!windowView_) {
LOGE("Window: SetFocusable failed");
return WMError::WM_ERROR_INVALID_WINDOW;
}
windowView_.focusable = focusable;
focusable_ = focusable;
return WMError::WM_OK;
}
bool Window::GetFocusable() const
{
return focusable_;
}
WMError Window::SetTouchHotAreas(const std::vector<Rect>& rects)
{
if (!windowView_) {
return WMError::WM_ERROR_INVALID_WINDOW;
}
int size = rects.size();
if (size == 0) {
[windowView_ setTouchHotAreas:nullptr size:0];
return WMError::WM_OK;
}
CGRect* cgRects = (CGRect *)malloc(sizeof(CGRect) * size);
UIScreen *screen = [UIScreen mainScreen];
CGFloat scale = screen.scale;
if (scale < 1) {
return WMError::WM_ERROR_INVALID_WINDOW;
}
for (int i = 0; i < size; i++) {
cgRects[i] = CGRectMake(rects[i].posX_/scale , rects[i].posY_/scale,
rects[i].width_/scale, rects[i].height_/scale);
}
[windowView_ setTouchHotAreas:cgRects size:size];
free(cgRects);
return WMError::WM_OK;
}
WMError Window::RequestFocus()
{
if (!windowView_ || !focusable_ || !isWindowShow_) {
return WMError::WM_ERROR_INVALID_WINDOW;
}
if ([windowView_ requestFocus]) {
return WMError::WM_OK;
} else {
return WMError::WM_ERROR_INVALID_WINDOW;
}
}
bool Window::IsFocused() const
{
return isFocused_;
}
WMError Window::SetTouchable(bool isTouchable)
{
if (!windowView_) {
LOGE("Window: SetTouchable failed");
return WMError::WM_ERROR_INVALID_WINDOW;
}
windowView_.userInteractionEnabled = isTouchable;
isTouchable_ = isTouchable;
return WMError::WM_OK;
}
bool Window::GetTouchable() const
{
if(!windowView_) {
LOGE("Window: GetTouchable failed");
return true;
}
return isTouchable_;
}
WMError Window::ResizeWindowTo(int32_t width, int32_t height) {
if (!windowView_) {
LOGE("Window: ResizeWindowTo failed");
return WMError::WM_ERROR_INVALID_PARENT;
}
LOGI("Window: ResizeWindowTo %d %d", width, height);
if (isFullScreen_) {
return WMError::WM_ERROR_INVALID_PARENT;
}
UIScreen *screen = [UIScreen mainScreen];
CGFloat scale = screen.scale;
windowView_.frame = CGRectMake(windowView_.frame.origin.x, windowView_.frame.origin.y, width / scale, height / scale);
rect_.width_ = width;
rect_.height_ = height;
return WMError::WM_OK;
}
bool Window::IsWindowValid() const
{
bool res = ((state_ > WindowState::STATE_INITIAL) && (state_ < WindowState::STATE_BOTTOM));
if (!res) {
LOGW("already destroyed or not created! id: %{public}u", GetWindowId());
}
return res;
}
void Window::RequestVsync(const std::shared_ptr<VsyncCallback>& vsyncCallback)
{
// stage model
if (receiver_) {
auto callback = [vsyncCallback](int64_t timestamp, void*) {
vsyncCallback->onCallback(timestamp, 0);
};
OHOS::Rosen::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_IOS", handler);
VsyncError ret = receiver_->Init();
if (ret) {
LOGE("Window_IOS: 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* layer)
{
rsUidriect_ = Rosen::RSUIDirector::Create(nullptr);
struct OHOS::Rosen::RSSurfaceNodeConfig rsSurfaceNodeConfig = { .SurfaceNodeName = "arkui-x_surface",
.additionalData = layer };
surfaceNode_ = Rosen::RSSurfaceNode::Create(rsSurfaceNodeConfig, true, rsUidriect_->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();
}
}
}
WindowStatus Window::GetWindowStatusInner(WindowMode mode)
{
LOGD("GetWindowStatusInner mode= %d",mode);
auto windowStatus = WindowStatus::WINDOW_STATUS_UNDEFINED;
if (mode == WindowMode::WINDOW_MODE_FLOATING) {
windowStatus = WindowStatus::WINDOW_STATUS_FLOATING;
} else if (mode == WindowMode::WINDOW_MODE_FULLSCREEN) {
windowStatus = WindowStatus::WINDOW_STATUS_FULLSCREEN;
} if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
windowStatus = WindowStatus::WINDOW_STATUS_SPLITSCREEN;
}
if (!isWindowShow_) {
windowStatus = WindowStatus::WINDOW_STATUS_MINIMIZE;
}
return windowStatus;
}
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;
surfaceNode_->SetBoundsWidth(surfaceWidth_);
surfaceNode_->SetBoundsHeight(surfaceHeight_);
density_ = density;
if (!uiContent_) {
LOGW("Window Notify uiContent_ Surface Created, uiContent_ is nullptr, delay notify.");
} else {
LOGI("Window Notify uiContent_ Surface Created");
Ace::ViewportConfig config;
config.SetDensity(density_);
config.SetSize(surfaceWidth_, surfaceHeight_);
config.SetOrientation(surfaceWidth_ <= surfaceHeight_ ? 0 : 1);
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::NotifyTraitCollectionDidChange(bool isSplitScreen)
{
if (windowMode_ == WindowMode::WINDOW_MODE_FULLSCREEN && isSplitScreen) {
windowMode_ = WindowMode::WINDOW_MODE_SPLIT_PRIMARY;
} else if (windowMode_ == WindowMode::WINDOW_MODE_SPLIT_PRIMARY && !isSplitScreen) {
windowMode_ = WindowMode::WINDOW_MODE_FULLSCREEN;
}
UpdateWindowStatus();
}
void Window::UpdateWindowStatus()
{
auto windowStatus = GetWindowStatusInner(windowMode_);
if (status_ != windowStatus) {
status_ = windowStatus;
NotifyWindowStatusChange(windowStatus);
}
}
void Window::NotifyWindowStatusChange(WindowStatus windowStatus)
{
LOGD("NotifyWindowStatusChange %d",windowStatus);
auto windowStatusChangeListeners = GetListeners<IWindowStatusChangeListener>();
for (auto& listener : windowStatusChangeListeners) {
if (listener != nullptr) {
listener->OnWindowStatusChange(windowStatus);
}
}
}
void Window::NotifySafeAreaChanged()
{
for (auto type : {
AvoidAreaType::TYPE_SYSTEM,
AvoidAreaType::TYPE_CUTOUT,
AvoidAreaType::TYPE_NAVIGATION_INDICATOR
}) {
auto avoidArea = std::make_shared<Rosen::AvoidArea>();
GetAvoidAreaByType(type, *avoidArea);
UpdateAvoidArea(avoidArea, type);
}
}
void Window::NotifyAfterForeground(bool needNotifyListeners, bool needNotifyUiContent)
{
if (needNotifyUiContent) {
if (uiContent_ != nullptr) {
uiContent_->Foreground();
}
}
if (needNotifyListeners) {
auto lifecycleListeners = GetListeners<IWindowLifeCycle>();
CALL_LIFECYCLE_LISTENER(AfterForeground, lifecycleListeners);
}
}
void Window::NotifyAfterBackground(bool needNotifyListeners, bool needNotifyUiContent)
{
if (needNotifyUiContent) {
if (uiContent_ != nullptr) {
uiContent_->Background();
}
}
if (needNotifyListeners) {
auto lifecycleListeners = GetListeners<IWindowLifeCycle>();
CALL_LIFECYCLE_LISTENER(AfterBackground, lifecycleListeners);
}
}
void Window::UpdateAvoidArea(const std::shared_ptr<Rosen::AvoidArea>& avoidArea, AvoidAreaType type)
{
if (!avoidArea) {
LOGE("invalid avoidArea");
return;
}
LOGD("UpdateAvoidArea 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}",
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_);
if (avoidAreaMap_[type] != *avoidArea) {
avoidAreaMap_[type] = *avoidArea;
NotifyAvoidAreaChange(avoidArea, type);
}
}
}
void Window::NotifyAvoidAreaChange(const std::shared_ptr<AvoidArea>& avoidArea, AvoidAreaType type)
{
auto avoidAreaChangeListeners = GetListeners<IAvoidAreaChangedListener>();
for (auto& listener : avoidAreaChangeListeners) {
if (listener != nullptr) {
LOGD("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::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();
}
}
}
bool Window::ProcessPointerEvent(const std::vector<uint8_t>& data)
{
if (!uiContent_) {
LOGW("Window::ProcessPointerEvent failed ,uicontent is nullptr");
return false;
}
std::vector<std::shared_ptr<MMI::PointerEvent>> pointerEvents;
Ace::Platform::ConvertMmiPointerEvent(pointerEvents, data);
bool result = true;
for (auto& pointerEvent : pointerEvents) {
result &= uiContent_->ProcessPointerEvent(pointerEvent);
}
return result;
}
bool Window::ProcessSyntheticPointerEvent(const std::vector<uint8_t>& data)
{
if (!uiContent_) {
LOGE("Window::ProcessSyntheticPointerEvent failed, uicontent is nullptr");
return false;
}
auto* uiContentImpl = static_cast<Ace::Platform::UIContentImpl*>(uiContent_.get());
CHECK_NULL_RETURN(uiContentImpl, false);
std::vector<std::shared_ptr<MMI::PointerEvent>> pointerEvents;
Ace::Platform::ConvertSyntheticMmiPointerEvent(pointerEvents, data);
bool result = true;
for (auto& pointerEvent : pointerEvents) {
result &= uiContentImpl->ProcessSyntheticPointerEvent(pointerEvent);
}
return result;
}
bool Window::ProcessPointerEventTargetHitTest(const std::vector<uint8_t>& data, const std::string& target)
{
if (!uiContent_) {
LOGW("Window::ProcessPointerEventTargetHitTest failed, uicontent is nullptr");
return false;
}
std::shared_ptr<OHOS::MMI::PointerEvent> pointerEvent = OHOS::MMI::PointerEvent::Create();
Ace::Platform::ConvertMmiPointerEvent(pointerEvent, data);
return uiContent_->ProcessPointerEventTargetHitTest(pointerEvent, target);
}
bool Window::ProcessKeyEvent(int32_t keyCode, int32_t keyAction, int32_t repeatTime, int64_t timeStamp,
int64_t timeStampStart, int32_t metaKey)
{
if (!uiContent_) {
return false;
}
Ace::KeyCode aceKeyCode = KeyCodeToAceKeyCode(keyCode);
Ace::SourceType sourceType = Ace::SourceType::NONE;
if (aceKeyCode != Ace::KeyCode::KEY_UNKNOWN) {
sourceType = Ace::SourceType::KEYBOARD;
}
return uiContent_->ProcessKeyEvent(static_cast<int32_t>(aceKeyCode), keyAction, repeatTime, timeStamp, timeStampStart, metaKey, static_cast<int32_t>(sourceType));
}
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(surfaceWidth_ <= surfaceHeight_ ? 0 : 1);
uiContent_->UpdateViewportConfig(config, WindowSizeChangeReason::RESIZE);
}
if (delayNotifySurfaceDestroyed_) {
LOGI("Window Delay Notify uiContent_ Surface Destroyed");
uiContent_->NotifySurfaceDestroyed();
delayNotifySurfaceDestroyed_ = false;
}
if (delayNotifyFocusChanged_) {
if (isFocused_) {
uiContent_->Focus();
} else {
uiContent_->UnFocus();
}
delayNotifyFocusChanged_ = false;
}
}
WMError Window::SetUIContent(const std::string& contentInfo,
NativeEngine* engine, napi_value storage, bool isdistributed,
AbilityRuntime::Platform::Ability* ability, bool loadContentByName)
{
LOGI("Window::SetUIContent : Start");
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) {
LOGE("Window::SetUIContent : Create UIContent Failed!");
return WMError::WM_ERROR_NULLPTR;
}
if (loadContentByName) {
LOGI("Window::SetUIContent: InitializeByName");
uiContent->InitializeByName(this, contentInfo, storage);
}else {
uiContent->Initialize(this, contentInfo, storage);
}
// make uiContent available after Initialize/Restore
uiContent_ = std::move(uiContent);
if(isWindowShow_ && ([UIApplication sharedApplication].applicationState != UIApplicationStateBackground)) {
uiContent_->Foreground();
}
DelayNotifyUIContentIfNeeded();
LOGI("Window::SetUIContent : End!!!");
return WMError::WM_OK;
}
Ace::Platform::UIContent* Window::GetUIContent() {
return uiContent_.get();
}
void Window::SetWindowView(WindowView* windowView)
{
if (windowView == nullptr) {
LOGE("Window::SetWindowView: WindowView is nullptr!");
return;
}
if (windowView_ != nullptr) {
LOGW("Window::SetWindowView: windowView_ has already been set!");
return;
}
LOGI("Window::SetWindowView");
[windowView_ release];
windowView_ = [windowView retain];
}
void Window::SetWindowName(const std::string& windowName)
{
name_ = windowName;
}
void Window::SetWindowType(WindowType windowType)
{
windowType_ = windowType;
}
void Window::SetMode(WindowMode windowMode)
{
windowMode_ = windowMode;
}
void Window::SetParentId(uint32_t parentId)
{
parentId_ = parentId;
}
void Window::WindowActiveChanged(bool isActive)
{
if (uiContent_) {
if (isActive && isFocused_) {
LOGI("Window: notify uiContent Focus");
uiContent_->Focus();
} else {
Ace::DragState dragState;
Ace::InteractionInterface::GetInstance()->GetDragState(dragState);
if (dragState == Ace::DragState::START) {
OHOS::Ace::DragDropRet dropResult { OHOS::Ace::DragRet::DRAG_CANCEL, false, GetWindowId(),
OHOS::Ace::DragBehavior::UNKNOWN };
Ace::InteractionInterface::GetInstance()->StopDrag(dropResult);
}
LOGI("Window: notify uiContent UnFocus");
uiContent_->UnFocus();
}
}
}
void Window::WindowFocusChanged(bool hasWindowFocus)
{
isFocused_ = hasWindowFocus;
if (uiContent_) {
if (hasWindowFocus) {
LOGI("Window: notify uiContent Focus");
uiContent_->Focus();
} else {
LOGI("Window: notify uiContent UnFocus");
uiContent_->UnFocus();
}
} else {
delayNotifyFocusChanged_ = true;
}
if (isActive_ != hasWindowFocus) {
isActive_ = hasWindowFocus;
if (isActive_) {
NotifyAfterActive();
} else {
NotifyAfterInactive();
}
}
}
void Window::Foreground()
{
LOGI("Window: notify uiContent Foreground");
NotifyAfterForeground();
isWindowShow_ = true;
UpdateWindowStatus();
}
void Window::Background()
{
LOGI("Window: notify uiContent Background");
isWindowShow_ = false;
NotifyAfterBackground();
UpdateWindowStatus();
}
void Window::ReleaseWindowView()
{
if (windowView_ == nullptr) {
return;
}
[windowView_ release];
}
void Window::UpdateConfiguration(const std::shared_ptr<OHOS::AbilityRuntime::Platform::Configuration>& config)
{
if (uiContent_ != nullptr) {
LOGI("Window::UpdateConfiguration called.");
uiContent_->UpdateConfiguration(config);
}
}
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)
{
if (brightness < MINIMUM_BRIGHTNESS || brightness > MAXIMUM_BRIGHTNESS) {
LOGE("invalid brightness value: %{public}f", brightness);
return WMError::WM_ERROR_INVALID_PARAM;
}
windowView_.brightness = brightness;
if (isWindowShow_) {
[windowView_ updateBrightness:true];
}
return WMError::WM_OK;
}
float Window::GetBrightness() const
{
if (windowView_ != nullptr) {
return windowView_.brightness;
}
return [UIScreen mainScreen].brightness;
}
WMError Window::SetKeepScreenOn(bool keepScreenOn)
{
if (keepScreenOn) {
[UIApplication sharedApplication].idleTimerDisabled = YES;
} else {
[UIApplication sharedApplication].idleTimerDisabled = NO;
}
return WMError::WM_OK;
}
bool Window::IsKeepScreenOn()
{
if ([UIApplication sharedApplication].idleTimerDisabled == YES) {
return true;
} else {
return false;
}
}
WMError Window::SetWindowPrivacyMode(bool isPrivacyMode) {
if (IsSubWindow()) {
return WMError::WM_OK;
}
StageViewController* controller = [StageApplication getApplicationTopViewController];
if (![controller isKindOfClass:[StageViewController class]]) {
return WMError::WM_ERROR_INVALID_WINDOW;;
}
controller.privacyMode = isPrivacyMode;
return WMError::WM_OK;
}
WMError Window::SetSystemBarProperty(WindowType type, const SystemBarProperty& property)
{
WMError ret = SetSystemBar(type, property);
if ( ret == WMError::WM_OK) {
sysBarPropMap_[type] = property;
}
return WMError::WM_OK;
}
WMError Window::UpdateSystemBarProperties(
const std::unordered_map<WindowType, SystemBarProperty>& systemBarProperties,
const std::unordered_map<WindowType, SystemBarPropertyFlag>& systemBarPropertyFlags)
{
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) {
SetStatusBar(property.contentColor_, property.backgroundColor_, property.enableAnimation_);
} 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;
}
void Window::SetStatusBar(uint32_t titleColor, uint32_t backgroundColor, bool animation)
{
StageViewController* controller = [StageApplication getApplicationTopViewController];
if (![controller isKindOfClass:[StageViewController class]]) {
return;
}
if (titleColor == SYSTEM_COLOR_WHITE) {
controller.statusBarStyle = UIStatusBarStyleLightContent;
} else if (titleColor == SYSTEM_COLOR_BLACK) {
if (@available(iOS 13.0, *)) {
controller.statusBarStyle = UIStatusBarStyleDarkContent;
} else {
controller.statusBarStyle = UIStatusBarStyleDefault;
}
} else {
controller.statusBarStyle = UIStatusBarStyleDefault;
}
controller.statusBarAnimation = animation;
[[UIApplication sharedApplication]setStatusBarStyle:controller.statusBarStyle animated:animation];
[controller setNeedsStatusBarAppearanceUpdate];
}
void Window::SetRequestedOrientation(Orientation orientation)
{
if (orientation == Orientation::UNSPECIFIED || orientation == Orientation::VERTICAL) {
windowView_.OrientationMask = UIInterfaceOrientationMaskPortrait;
} else if (orientation == Orientation::HORIZONTAL) {
windowView_.OrientationMask = UIInterfaceOrientationMaskLandscapeRight;
} else if (orientation == Orientation::REVERSE_HORIZONTAL) {
windowView_.OrientationMask = UIInterfaceOrientationMaskLandscapeLeft;
} else if (orientation == Orientation::REVERSE_VERTICAL) {
windowView_.OrientationMask = UIInterfaceOrientationMaskPortraitUpsideDown;
} else if (orientation == Orientation::SENSOR) {
windowView_.OrientationMask = UIInterfaceOrientationMaskAll;
} else if (orientation == Orientation::SENSOR_VERTICAL) {
windowView_.OrientationMask = UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
} else if (orientation == Orientation::SENSOR_HORIZONTAL) {
windowView_.OrientationMask = UIInterfaceOrientationMaskLandscape;
}
[[NSNotificationCenter defaultCenter]postNotificationName:@(kOrientationMaskUpdateNotificationName)
object:nil userInfo:@{@(kOrientationMaskUpdateNotificationKey):@(windowView_.OrientationMask)}];
}
SystemBarProperty Window::GetSystemBarPropertyByType(WindowType type) const
{
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(windowChangeListeners_, winId);
ClearUselessListeners(touchOutsideListeners_, winId);
ClearUselessListeners(surfaceNodeListeners_, winId);
ClearUselessListeners(windowStatusChangeListeners_, winId);
ClearUselessListeners(avoidAreaChangeListeners_, winId);
}
void Window::NotifyWillTeminate()
{
if (notifyWillTerminatefunc_) {
notifyWillTerminatefunc_();
}
}
void Window::NotifySizeChange(Rect rect)
{
auto windowChangeListeners = GetListeners<IWindowChangeListener>();
for (auto& listener : windowChangeListeners) {
if (listener != nullptr) {
listener->OnSizeChange(rect);
}
}
}
void Window::NotifyKeyboardHeightChanged(int32_t height)
{
if (keyBoardHieght_ == height) {
return;
}
keyBoardHieght_ = height;
auto occupiedAreaChangeListeners = GetListeners<IOccupiedAreaChangeListener>();
for (auto& listener : occupiedAreaChangeListeners) {
if (listener != nullptr) {
Rect rect = { 0, 0, 0, height };
listener->OnSizeChange(rect, OccupiedAreaType::TYPE_INPUT);
}
}
LOGD("NotifyKeyboardHeightChanged %d",height);
auto type = AvoidAreaType::TYPE_KEYBOARD;
auto avoidArea = std::make_shared<Rosen::AvoidArea>();
GetAvoidAreaByType(type, *avoidArea);
UpdateAvoidArea(avoidArea, type);
}
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::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::RegisterAvoidAreaChangeListener(const sptr<IAvoidAreaChangedListener>& listener)
{
LOGD("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)
{
LOGD("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)
{
LOGD("Start register WindowChangeListener");
std::lock_guard<std::recursive_mutex> lock(globalMutex_);
return RegisterListener(windowStatusChangeListeners_[GetWindowId()], listener);
}
WMError Window::UnregisterWindowStatusChangeListener(const sptr<IWindowStatusChangeListener>& listener)
{
LOGD("Start unregister WindowChangeListener");
std::lock_guard<std::recursive_mutex> lock(globalMutex_);
return UnregisterListener(windowStatusChangeListeners_[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);
}
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);
}
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)
{
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
{
GraphicColorGamut gamut = surfaceNode_->GetColorSpace();
ColorSpace colorSpace = GetColorSpaceFromSurfaceGamut(gamut);
return colorSpace;
}
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;
}
WMError Window::SetLayoutFullScreen(bool status) {
StageViewController* controller = [StageApplication getApplicationTopViewController];
if (![controller isKindOfClass:[StageViewController class]]) {
return WMError::WM_ERROR_INVALID_WINDOW;
}
if (status == true) {
LOGI("isLayoutFullScreen is ture");
controller.edgesForExtendedLayout = UIRectEdgeAll;
controller.navigationController.navigationBar.translucent = YES;
} else {
LOGI("isLayoutFullScreen is false");
controller.edgesForExtendedLayout = UIRectEdgeNone;
controller.navigationController.navigationBar.translucent = NO;
}
return WMError::WM_OK;
}
WMError Window::SetSpecificBarProperty(WindowType type, const SystemBarProperty& property) {
WMError ret = SetSpecificBar(type, property);
if (ret == WMError::WM_OK) {
sysBarPropMap_[type] = property;
}
// WINDOW_TYPE_NAVIGATION_INDICATOR
return ret;
}
WMError Window::GetAvoidAreaByType(AvoidAreaType type, AvoidArea& avoidArea) {
avoidArea.topRect_ = emptyRect;
avoidArea.leftRect_ = emptyRect;
avoidArea.rightRect_ = emptyRect;
avoidArea.bottomRect_ = emptyRect;
if (@available(iOS 11.0, *)) {
StageViewController* controller = [StageApplication getApplicationTopViewController];
if (![controller isKindOfClass:[StageViewController class]]) {
return WMError::WM_ERROR_INVALID_WINDOW;
}
UIEdgeInsets insets = windowView_.safeAreaInsets;
UIScreen *screen = [UIScreen mainScreen];
AvoidArea area;
CGFloat scale = screen.scale;
insets.left = insets.left * scale;
insets.right = insets.right * scale;
insets.top = insets.top * scale;
insets.bottom = insets.bottom * scale;
CGFloat width = windowView_.bounds.size.width * scale;
CGFloat height = windowView_.bounds.size.height * scale;
area.topRect_ = MakeAvoidRect(0, 0, width, insets.top);
area.leftRect_ = MakeAvoidRect(0, 0, insets.left, height);
area.rightRect_ = MakeAvoidRect(width, 0, insets.right ,height);
area.bottomRect_ = MakeAvoidRect(0, height, width, insets.bottom);
LOGD("UpdateAvoidAreaNew 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}",
type, area.topRect_.posX_, area.topRect_.posY_, area.topRect_.width_,
area.topRect_.height_, area.leftRect_.posX_, area.leftRect_.posY_,
area.leftRect_.width_, area.leftRect_.height_, area.rightRect_.posX_,
area.rightRect_.posY_, area.rightRect_.width_, area.rightRect_.height_,
area.bottomRect_.posX_, area.bottomRect_.posY_, area.bottomRect_.width_,
area.bottomRect_.height_);
if (type == AvoidAreaType::TYPE_CUTOUT) {
static UIDeviceOrientation orientation = UIDeviceOrientationPortrait;
if ([UIDevice currentDevice].orientation == UIDeviceOrientationPortrait) {
orientation = UIDeviceOrientationPortrait;
avoidArea.topRect_ = area.topRect_;
} else if ([UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeLeft) {
orientation = UIDeviceOrientationLandscapeLeft;
avoidArea.leftRect_ = area.leftRect_;
} else if ([UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeRight) {
orientation = UIDeviceOrientationLandscapeRight;
avoidArea.rightRect_ = area.rightRect_;
}
if (orientation == UIDeviceOrientationPortrait) {
avoidArea.topRect_ = area.topRect_;
} else if (orientation == UIDeviceOrientationLandscapeLeft) {
avoidArea.leftRect_ = area.leftRect_;
} else if (orientation == UIDeviceOrientationLandscapeRight) {
avoidArea.rightRect_ = area.rightRect_;
}
} else if (type == AvoidAreaType::TYPE_KEYBOARD) {
CGFloat screenHeight = windowView_.window.bounds.size.height;
CGRect rect = [windowView_ convertRect:windowView_.bounds toView:windowView_.window];
CGFloat windowViewMaxY = (rect.size.height + rect.origin.y) * scale;
CGFloat avoidHeight = windowViewMaxY - (screenHeight * scale - keyBoardHieght_);
avoidHeight = avoidHeight > 0 ? avoidHeight : 0;
avoidArea.bottomRect_ = MakeAvoidRect(0, rect.size.height * scale - avoidHeight, width, avoidHeight);
LOGD("GetAvoidAreaByType screenHeight=%f,windowViewMaxY = %f avoidHeight = %f recty = %f,rectH= %f",
screenHeight * scale, windowViewMaxY,avoidHeight,rect.origin.y,rect.size.height);
} else if (type == AvoidAreaType::TYPE_SYSTEM) {
avoidArea.topRect_ = area.topRect_;
avoidArea.bottomRect_ = area.bottomRect_;
} else if (type == AvoidAreaType::TYPE_NAVIGATION_INDICATOR) {
avoidArea.bottomRect_ = area.bottomRect_;
} else if (type == AvoidAreaType::TYPE_SYSTEM_GESTURE) {
} else {
LOGE("GetAvoidAreaByType failed, AvoidAreaType is invalid");
return WMError::WM_ERROR_INVALID_PARAM;
}
} else {
return WMError::WM_ERROR_INVALID_PARAM;
LOGE("GetAvoidAreaByType failed, iOS version less than 11");
}
return WMError::WM_OK;
}
} // namespace OHOS::Rosen