diff --git a/interfaces/innerkits/wm/window.h b/interfaces/innerkits/wm/window.h index 486f23b8f0a54ed38d130f6d4c6ecacca616f2e7..f5c9b64e5c5bde7136165a75669239b792653fd0 100644 --- a/interfaces/innerkits/wm/window.h +++ b/interfaces/innerkits/wm/window.h @@ -41,7 +41,7 @@ namespace OHOS::AbilityRuntime { namespace OHOS { namespace Rosen { -class IWindowChangeListener : public RefBase { +class IWindowChangeListener : virtual public RefBase { public: virtual void OnSizeChange(Rect rect) = 0; }; diff --git a/interfaces/innerkits/wm/window_manager.h b/interfaces/innerkits/wm/window_manager.h index acd457cf5db5f5b5828bfcdaf8e277d0c44e5ff9..37221d1e2cf52fea0aada131277712f58d598e89 100644 --- a/interfaces/innerkits/wm/window_manager.h +++ b/interfaces/innerkits/wm/window_manager.h @@ -34,9 +34,9 @@ public: WindowType windowType, int32_t displayId) = 0; }; -class ISystemBarChangedListener : public RefBase { +class ISystemBarChangedListener : virtual public RefBase { public: - virtual void OnSystemBarPropertyChange(uint64_t displayId, const SystemBarProps& props) = 0; + virtual void OnSystemBarPropertyChange(uint64_t displayId, SystemBarProps props) = 0; }; class WindowManager { diff --git a/interfaces/innerkits/wm/wm_common.h b/interfaces/innerkits/wm/wm_common.h index a9d762d4c2bae3537a5d1c21c83d5ab2c5f459ca..34f5ca6768294d5628fd5c15be0c298ec176062d 100644 --- a/interfaces/innerkits/wm/wm_common.h +++ b/interfaces/innerkits/wm/wm_common.h @@ -102,8 +102,8 @@ struct Rect { }; namespace { - constexpr uint32_t SYSTEM_COLOR_WHITE = 0xE5FFFFFF; - constexpr uint32_t SYSTEM_COLOR_BLACK = 0x66000000; + constexpr uint32_t SYSTEM_COLOR_WHITE = 0xFFFFFFE5; + constexpr uint32_t SYSTEM_COLOR_BLACK = 0x00000066; } struct SystemBarProperty { diff --git a/interfaces/kits/napi/window_runtime/BUILD.gn b/interfaces/kits/napi/window_runtime/BUILD.gn index f6e2c9805868b1767d573f71eeed15756d326f9a..4247bde251baf86e454092b7ba9326675363822d 100644 --- a/interfaces/kits/napi/window_runtime/BUILD.gn +++ b/interfaces/kits/napi/window_runtime/BUILD.gn @@ -37,6 +37,8 @@ ohos_shared_library("windowmanager_napi") { configs = [ ":window_manager_napi_config" ] deps = [ + "//foundation/appexecfwk/standard/kits:app_context", + "//foundation/appexecfwk/standard/kits:appkit_native", "//foundation/windowmanager/utils:libwmutil", "//foundation/windowmanager/wm:libwm", "//foundation/windowmanager/wmserver:libwms", diff --git a/interfaces/kits/napi/window_runtime/js_window.cpp b/interfaces/kits/napi/window_runtime/js_window.cpp index 53581baf1f83f7ae3331e361dce3bb877d00048c..7574d785687c4af098d1480322bc91099880f050 100644 --- a/interfaces/kits/napi/window_runtime/js_window.cpp +++ b/interfaces/kits/napi/window_runtime/js_window.cpp @@ -23,9 +23,8 @@ using namespace AbilityRuntime; namespace { constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0, "JsWindow"}; } -JsWindow::JsWindow(const sptr& window, NativeEngine& engine) : windowToken_(window) +JsWindow::JsWindow(const sptr& window) : windowToken_(window) { - windowListener_ = new JsWindowListener(&engine); } void JsWindow::Finalizer(NativeEngine* engine, void* data, void* hint) @@ -97,11 +96,11 @@ NativeValue* JsWindow::RegisterWindowCallback(NativeEngine* engine, NativeCallba return (me != nullptr) ? me->OnRegisterWindowCallback(*engine, *info) : nullptr; } -NativeValue* JsWindow::UnRegisterWindowCallback(NativeEngine* engine, NativeCallbackInfo* info) +NativeValue* JsWindow::UnregisterWindowCallback(NativeEngine* engine, NativeCallbackInfo* info) { - WLOGFI("JsWindow::UnRegisterWindowCallback is called"); + WLOGFI("JsWindow::UnregisterWindowCallback is called"); JsWindow* me = CheckParamsAndGetThis(engine, info); - return (me != nullptr) ? me->OnUnRegisterWindowCallback(*engine, *info) : nullptr; + return (me != nullptr) ? me->OnUnregisterWindowCallback(*engine, *info) : nullptr; } NativeValue* JsWindow::LoadContent(NativeEngine* engine, NativeCallbackInfo* info) @@ -111,6 +110,34 @@ NativeValue* JsWindow::LoadContent(NativeEngine* engine, NativeCallbackInfo* inf return (me != nullptr) ? me->OnLoadContent(*engine, *info) : nullptr; } +NativeValue* JsWindow::SetFullScreen(NativeEngine* engine, NativeCallbackInfo* info) +{ + WLOGFI("JsWindow::SetFullScreen is called"); + JsWindow* me = CheckParamsAndGetThis(engine, info); + return (me != nullptr) ? me->OnSetFullScreen(*engine, *info) : nullptr; +} + +NativeValue* JsWindow::SetLayoutFullScreen(NativeEngine* engine, NativeCallbackInfo* info) +{ + WLOGFI("JsWindow::SetLayoutFullScreen is called"); + JsWindow* me = CheckParamsAndGetThis(engine, info); + return (me != nullptr) ? me->OnSetLayoutFullScreen(*engine, *info) : nullptr; +} + +NativeValue* JsWindow::SetSystemBarEnable(NativeEngine* engine, NativeCallbackInfo* info) +{ + WLOGFI("JsWindow::SetSystemBarEnable is called"); + JsWindow* me = CheckParamsAndGetThis(engine, info); + return (me != nullptr) ? me->OnSetSystemBarEnable(*engine, *info) : nullptr; +} + +NativeValue* JsWindow::SetSystemBarProperties(NativeEngine* engine, NativeCallbackInfo* info) +{ + WLOGFI("JsWindow::SetBarProperties is called"); + JsWindow* me = CheckParamsAndGetThis(engine, info); + return (me != nullptr) ? me->OnSetSystemBarProperties(*engine, *info) : nullptr; +} + NativeValue* JsWindow::OnShow(NativeEngine& engine, NativeCallbackInfo& info) { WLOGFI("JsWindow::OnShow is called"); @@ -201,7 +228,7 @@ NativeValue* JsWindow::OnMoveTo(NativeEngine& engine, NativeCallbackInfo& info) } int32_t y; - if (!ConvertFromJsValue(engine, info.argv[1], y)) { + if (!ConvertFromJsValue(engine, info.argv[ARGC_ONE], y)) { WLOGFE("Failed to convert parameter to y"); return engine.CreateUndefined(); } @@ -237,7 +264,7 @@ NativeValue* JsWindow::OnResize(NativeEngine& engine, NativeCallbackInfo& info) } uint32_t height; - if (!ConvertFromJsValue(engine, info.argv[1], height)) { + if (!ConvertFromJsValue(engine, info.argv[ARGC_ONE], height)) { WLOGFE("Failed to convert parameter to height"); return engine.CreateUndefined(); } @@ -348,11 +375,103 @@ NativeValue* JsWindow::OnGetProperties(NativeEngine& engine, NativeCallbackInfo& return result; } +bool JsWindow::IfCallbackRegistered(std::string type, NativeValue* jsListenerObject) +{ + if (jsCallbackMap_.empty() || jsCallbackMap_.find(type) == jsCallbackMap_.end()) { + WLOGFI("JsWindow::IfCallbackRegistered methodName %{public}s not registertd!", type.c_str()); + return false; + } + + for (auto iter = jsCallbackMap_[type].begin(); iter != jsCallbackMap_[type].end(); iter++) { + if (jsListenerObject->StrictEquals((*iter)->Get())) { + WLOGFE("JsWindow::IfCallbackRegistered callback already registered!"); + return true; + } + } + return false; +} + +void JsWindow::RegisterWindowListenerWithType(NativeEngine& engine, std::string type, NativeValue* value) +{ + if (IfCallbackRegistered(type, value)) { + WLOGFE("JsWindow::RegisterWindowListenerWithType callback already registered!"); + return; + } + std::unique_ptr callbackRef; + callbackRef.reset(engine.CreateReference(value, 1)); + if (jsListenerMap_.find(type) == jsListenerMap_.end()) { + sptr windowListener = new JsWindowListener(&engine); + if (type.compare("windowSizeChange") == 0) { + sptr thisListener(windowListener); + windowToken_->RegisterWindowChangeListener(thisListener); + WLOGFI("JsWindow::RegisterWindowListenerWithType windowSizeChange success"); + } else { + WLOGFE("JsWindow::RegisterWindowListenerWithType failed method: %{public}s not support!", + type.c_str()); + return; + } + windowListener->AddCallback(value); + jsListenerMap_[type] = windowListener; + } else { + jsListenerMap_[type]->AddCallback(value); + } + jsCallbackMap_[type].push_back(std::move(callbackRef)); + return; +} + +void JsWindow::UnregisterAllWindowListenerWithType(std::string type) +{ + if (jsListenerMap_.empty() || jsListenerMap_.find(type) == jsListenerMap_.end()) { + WLOGFI("JsWindow::UnregisterAllWindowListenerWithType methodName %{public}s not registerted!", + type.c_str()); + return; + } + jsListenerMap_[type]->RemoveAllCallback(); + if (type.compare("windowSizeChange") == 0) { + sptr thisListener(nullptr); + windowToken_->RegisterWindowChangeListener(thisListener); + WLOGFI("JsWindow::UnregisterAllWindowListenerWithType windowSizeChange success"); + } + jsListenerMap_.erase(type); + jsCallbackMap_.erase(type); + return; +} + +void JsWindow::UnregisterWindowListenerWithType(std::string type, NativeValue* value) +{ + if (jsListenerMap_.empty() || jsListenerMap_.find(type) == jsListenerMap_.end()) { + WLOGFI("JsWindow::UnregisterWindowListenerWithType methodName %{public}s not registerted!", + type.c_str()); + return; + } + for (auto it = jsCallbackMap_[type].begin(); it != jsCallbackMap_[type].end();) { + if (value->StrictEquals((*it)->Get())) { + jsListenerMap_[type]->RemoveCallback(value); + jsCallbackMap_[type].erase(it++); + break; + } else { + it++; + } + } + // one type with multi jscallback, erase type when there is no callback in one type + if (jsCallbackMap_[type].empty()) { + if (type.compare("windowSizeChange") == 0) { + sptr thisListener(nullptr); + windowToken_->RegisterWindowChangeListener(thisListener); + WLOGFI("JsWindow::UnregisterWindowListenerWithType windowSizeChange success"); + } + jsCallbackMap_.erase(type); + jsListenerMap_.erase(type); + } + return; +} + NativeValue* JsWindow::OnRegisterWindowCallback(NativeEngine& engine, NativeCallbackInfo& info) + { WLOGFI("JsWindow::OnRegisterWindowCallback is called"); - if (windowToken_ == nullptr || windowListener_ == nullptr) { - WLOGFE("JsWindow windowToken_ or windowListener_ is nullptr"); + if (windowToken_ == nullptr) { + WLOGFE("JsWindow windowToken_ is nullptr"); return engine.CreateUndefined(); } if (info.argc != ARGC_TWO) { @@ -369,23 +488,16 @@ NativeValue* JsWindow::OnRegisterWindowCallback(NativeEngine& engine, NativeCall WLOGFI("JsWindow::OnRegisterWindowCallback info->argv[1] is not callable"); return engine.CreateUndefined(); } - if (!windowListener_->AddJsListenerObject(cbType, info.argv[1])) { - WLOGFI("JsWindow::OnRegisterWindowCallback failed"); + std::lock_guard lock(mtx_); + RegisterWindowListenerWithType(engine, cbType, value); return engine.CreateUndefined(); } - if (cbType.compare("windowSizeChange") == 0) { - sptr thisListener(windowListener_); - windowToken_->RegisterWindowChangeListener(thisListener); - WLOGFI("JsWindow::OnRegisterWindowCallback success"); - } - return engine.CreateUndefined(); -} -NativeValue* JsWindow::OnUnRegisterWindowCallback(NativeEngine& engine, NativeCallbackInfo& info) +NativeValue* JsWindow::OnUnregisterWindowCallback(NativeEngine& engine, NativeCallbackInfo& info) { - WLOGFI("JsWindow::OnUnRegisterWindowCallback is called"); - if (windowToken_ == nullptr || windowListener_ == nullptr) { - WLOGFE("JsWindow windowToken_ or windowListener_ is nullptr"); + WLOGFI("JsWindow::OnUnregisterWindowCallback is called"); + if (windowToken_ == nullptr) { + WLOGFE("JsWindow windowToken_ is nullptr"); return engine.CreateUndefined(); } if (info.argc == 0) { @@ -397,8 +509,17 @@ NativeValue* JsWindow::OnUnRegisterWindowCallback(NativeEngine& engine, NativeCa WLOGFE("Failed to convert parameter to callbackType"); return engine.CreateUndefined(); } - NativeValue* lastParam = (info.argc == 1) ? nullptr : info.argv[1]; - windowListener_->RemoveJsListenerObject(cbType, lastParam); + if (info.argc == 1) { + UnregisterAllWindowListenerWithType(cbType); + } else { + NativeValue* value = info.argv[ARGC_ONE]; + if (!value->IsCallable()) { + WLOGFI("JsWindowManager::OnUnregisterWindowManagerCallback info->argv[1] is not callable"); + return engine.CreateUndefined(); + } + UnregisterWindowListenerWithType(cbType, value); + } + return engine.CreateUndefined(); } @@ -447,13 +568,164 @@ NativeValue* JsWindow::OnLoadContent(NativeEngine& engine, NativeCallbackInfo& i return result; } +NativeValue* JsWindow::OnSetFullScreen(NativeEngine& engine, NativeCallbackInfo& info) +{ + WLOGFI("JsWindow::OnSetFullScreen is called"); + if (windowToken_ == nullptr || info.argc < ARGC_ONE) { + WLOGFE("JsWindow windowToken_ is nullptr or param is too small!"); + return engine.CreateUndefined(); + } + NativeBoolean* nativeVal = ConvertNativeValueTo(info.argv[0]); + if (nativeVal == nullptr) { + WLOGFE("Failed to convert parameter to isFullScreen"); + return engine.CreateUndefined(); + } + // when false, Do nothing + bool isFullScreen = static_cast(*nativeVal); + if (!isFullScreen) { + return engine.CreateUndefined(); + } + AsyncTask::CompleteCallback complete = + [this](NativeEngine& engine, AsyncTask& task, int32_t status) { + WMError ret = windowToken_->SetWindowMode(WindowMode::WINDOW_MODE_FULLSCREEN); + SystemBarProperty statusProperty = windowToken_->GetSystemBarPropertyByType( + WindowType::WINDOW_TYPE_STATUS_BAR); + SystemBarProperty navProperty = windowToken_->GetSystemBarPropertyByType( + WindowType::WINDOW_TYPE_NAVIGATION_BAR); + statusProperty.enable_ = false; + navProperty.enable_ = false; + ret = windowToken_->SetSystemBarProperty(WindowType::WINDOW_TYPE_STATUS_BAR, statusProperty); + ret = windowToken_->SetSystemBarProperty(WindowType::WINDOW_TYPE_NAVIGATION_BAR, navProperty); + if (ret == WMError::WM_OK) { + task.Resolve(engine, engine.CreateUndefined()); + WLOGFI("JsWindow::OnSetFullScreen success"); + } else { + task.Reject(engine, CreateJsError(engine, + static_cast(ret), "JsWindow::OnSetFullScreen failed.")); + } + }; + + NativeValue* lastParam = (info.argc == ARGC_ONE) ? nullptr : info.argv[INDEX_ONE]; + NativeValue* result = nullptr; + AsyncTask::Schedule( + engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result)); + return result; +} + +NativeValue* JsWindow::OnSetLayoutFullScreen(NativeEngine& engine, NativeCallbackInfo& info) +{ + WLOGFI("JsWindow::OnSetLayoutFullScreen is called"); + if (windowToken_ == nullptr || info.argc < ARGC_ONE) { + WLOGFE("JsWindow windowToken_ is nullptr or param is too small!"); + return engine.CreateUndefined(); + } + NativeBoolean* nativeVal = ConvertNativeValueTo(info.argv[0]); + if (nativeVal == nullptr) { + WLOGFE("Failed to convert parameter to isLayoutFullScreen"); + return engine.CreateUndefined(); + } + bool isLayoutFullScreen = static_cast(*nativeVal); + // when false, Do nothing + if (!isLayoutFullScreen) { + return engine.CreateUndefined(); + } + AsyncTask::CompleteCallback complete = + [this](NativeEngine& engine, AsyncTask& task, int32_t status) { + WMError ret = windowToken_->SetWindowMode(WindowMode::WINDOW_MODE_FULLSCREEN); + ret = windowToken_->RemoveWindowFlag(WindowFlag::WINDOW_FLAG_NEED_AVOID); + if (ret == WMError::WM_OK) { + task.Resolve(engine, engine.CreateUndefined()); + WLOGFI("JsWindow::OnSetLayoutFullScreen success"); + } else { + task.Reject(engine, CreateJsError(engine, + static_cast(ret), "JsWindow::OnSetLayoutFullScreen failed.")); + } + }; + NativeValue* lastParam = (info.argc == ARGC_ONE) ? nullptr : info.argv[INDEX_ONE]; + NativeValue* result = nullptr; + AsyncTask::Schedule( + engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result)); + return result; +} + +NativeValue* JsWindow::OnSetSystemBarEnable(NativeEngine& engine, NativeCallbackInfo& info) +{ + WLOGFI("JsWindow::OnSetSystemBarEnable is called"); + if (windowToken_ == nullptr || info.argc < ARGC_ONE) { + WLOGFE("JsWindow windowToken_ is nullptr or param is too small!"); + return engine.CreateUndefined(); + } + std::map systemBarProperties; + if (!GetSystemBarStatus(systemBarProperties, engine, info, windowToken_)) { + return engine.CreateUndefined(); + } + AsyncTask::CompleteCallback complete = + [this, systemBarProperties](NativeEngine& engine, AsyncTask& task, int32_t status) { + WMError ret = windowToken_->SetSystemBarProperty(WindowType::WINDOW_TYPE_STATUS_BAR, + systemBarProperties.at(WindowType::WINDOW_TYPE_STATUS_BAR)); + ret = windowToken_->SetSystemBarProperty(WindowType::WINDOW_TYPE_NAVIGATION_BAR, + systemBarProperties.at(WindowType::WINDOW_TYPE_NAVIGATION_BAR)); + if (ret == WMError::WM_OK) { + task.Resolve(engine, engine.CreateUndefined()); + WLOGFI("JsWindow::OnSetSystemBarEnable success"); + } else { + task.Reject(engine, CreateJsError(engine, + static_cast(ret), "JsWindow::OnSetSystemBarEnable failed.")); + } + }; + + NativeValue* lastParam = (info.argc == ARGC_TWO) ? info.argv[INDEX_ONE] : nullptr; + NativeValue* result = nullptr; + AsyncTask::Schedule( + engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result)); + return result; +} + +NativeValue* JsWindow::OnSetSystemBarProperties(NativeEngine& engine, NativeCallbackInfo& info) +{ + WLOGFI("JsWindow::OnSetSystemBarProperties is called"); + if (windowToken_ == nullptr || info.argc < ARGC_ONE) { + WLOGFE("JsWindow windowToken_ is nullptr or param is too small!"); + return engine.CreateUndefined(); + } + NativeObject* nativeObj = ConvertNativeValueTo(info.argv[0]); + if (nativeObj == nullptr) { + WLOGFE("Failed to convert object to SystemBarProperties"); + return engine.CreateUndefined(); + } + std::map systemBarProperties; + if (!SetSystemBarPropertiesFromJs(engine, nativeObj, systemBarProperties, windowToken_)) { + WLOGFE("Failed to GetSystemBarProperties From Js Object"); + return engine.CreateUndefined(); + } + AsyncTask::CompleteCallback complete = + [this, systemBarProperties](NativeEngine& engine, AsyncTask& task, int32_t status) { + WMError ret = windowToken_->SetSystemBarProperty(WindowType::WINDOW_TYPE_STATUS_BAR, + systemBarProperties.at(WindowType::WINDOW_TYPE_STATUS_BAR)); + ret = windowToken_->SetSystemBarProperty(WindowType::WINDOW_TYPE_NAVIGATION_BAR, + systemBarProperties.at(WindowType::WINDOW_TYPE_NAVIGATION_BAR)); + if (ret == WMError::WM_OK) { + task.Resolve(engine, engine.CreateUndefined()); + WLOGFI("JsWindow::OnSetSystemBarProperties success"); + } else { + task.Reject(engine, CreateJsError(engine, + static_cast(WMError::WM_ERROR_NULLPTR), "JsWindow::OnSetSystemBarProperties failed.")); + } + }; + + NativeValue* lastParam = (info.argc == ARGC_ONE) ? nullptr : info.argv[INDEX_ONE]; + NativeValue* result = nullptr; + AsyncTask::Schedule( + engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result)); + return result; +} NativeValue* CreateJsWindowObject(NativeEngine& engine, sptr& window) { WLOGFI("JsWindow::CreateJsWindow is called"); NativeValue* objValue = engine.CreateObject(); NativeObject* object = ConvertNativeValueTo(objValue); - std::unique_ptr jsWindow = std::make_unique(window, engine); + std::unique_ptr jsWindow = std::make_unique(window); object->SetNativePointer(jsWindow.release(), JsWindow::Finalizer, nullptr); BindNativeFunction(engine, *object, "show", JsWindow::Show); @@ -465,8 +737,12 @@ NativeValue* CreateJsWindowObject(NativeEngine& engine, sptr& window) BindNativeFunction(engine, *object, "setWindowMode", JsWindow::SetWindowMode); BindNativeFunction(engine, *object, "getProperties", JsWindow::GetProperties); BindNativeFunction(engine, *object, "on", JsWindow::RegisterWindowCallback); - BindNativeFunction(engine, *object, "off", JsWindow::UnRegisterWindowCallback); + BindNativeFunction(engine, *object, "off", JsWindow::UnregisterWindowCallback); BindNativeFunction(engine, *object, "loadContent", JsWindow::LoadContent); + BindNativeFunction(engine, *object, "setFullScreen", JsWindow::SetFullScreen); + BindNativeFunction(engine, *object, "setLayoutFullScreen", JsWindow::SetLayoutFullScreen); + BindNativeFunction(engine, *object, "setSystemBarEnable", JsWindow::SetSystemBarEnable); + BindNativeFunction(engine, *object, "setSystemBarProperties", JsWindow::SetSystemBarProperties); return objValue; } } // namespace Rosen diff --git a/interfaces/kits/napi/window_runtime/js_window.h b/interfaces/kits/napi/window_runtime/js_window.h index b449dccad97c3e96cb73e86635bd0928c4a2b06a..48c993d4c92e11ca67a466e567112fe2ce74730a 100644 --- a/interfaces/kits/napi/window_runtime/js_window.h +++ b/interfaces/kits/napi/window_runtime/js_window.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 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 @@ -27,7 +27,7 @@ NativeValue* CreateJsWindowObject(NativeEngine& engine, sptr& window); class JsWindow final { public: - JsWindow(const sptr& window, NativeEngine& engine); + explicit JsWindow(const sptr& window); ~JsWindow() = default; static void Finalizer(NativeEngine* engine, void* data, void* hint); static NativeValue* Show(NativeEngine* engine, NativeCallbackInfo* info); @@ -39,10 +39,18 @@ public: static NativeValue* SetWindowMode(NativeEngine* engine, NativeCallbackInfo* info); static NativeValue* GetProperties(NativeEngine* engine, NativeCallbackInfo* info); static NativeValue* RegisterWindowCallback(NativeEngine* engine, NativeCallbackInfo* info); - static NativeValue* UnRegisterWindowCallback(NativeEngine* engine, NativeCallbackInfo* info); + static NativeValue* UnregisterWindowCallback(NativeEngine* engine, NativeCallbackInfo* info); static NativeValue* LoadContent(NativeEngine* engine, NativeCallbackInfo* info); + static NativeValue* SetFullScreen(NativeEngine* engine, NativeCallbackInfo* info); + static NativeValue* SetLayoutFullScreen(NativeEngine* engine, NativeCallbackInfo* info); + static NativeValue* SetSystemBarEnable(NativeEngine* engine, NativeCallbackInfo* info); + static NativeValue* SetSystemBarProperties(NativeEngine* engine, NativeCallbackInfo* info); private: + bool IfCallbackRegistered(std::string type, NativeValue* jsListenerObject); + void RegisterWindowListenerWithType(NativeEngine& engine, std::string type, NativeValue* value); + void UnregisterWindowListenerWithType(std::string type, NativeValue* value); + void UnregisterAllWindowListenerWithType(std::string type); NativeValue* OnShow(NativeEngine& engine, NativeCallbackInfo& info); NativeValue* OnDestroy(NativeEngine& engine, NativeCallbackInfo& info); NativeValue* OnHide(NativeEngine& engine, NativeCallbackInfo& info); @@ -52,10 +60,16 @@ private: NativeValue* OnSetWindowMode(NativeEngine& engine, NativeCallbackInfo& info); NativeValue* OnGetProperties(NativeEngine& engine, NativeCallbackInfo& info); NativeValue* OnRegisterWindowCallback(NativeEngine& engine, NativeCallbackInfo& info); - NativeValue* OnUnRegisterWindowCallback(NativeEngine& engine, NativeCallbackInfo& info); + NativeValue* OnUnregisterWindowCallback(NativeEngine& engine, NativeCallbackInfo& info); + NativeValue* OnSetFullScreen(NativeEngine& engine, NativeCallbackInfo& info); + NativeValue* OnSetLayoutFullScreen(NativeEngine& engine, NativeCallbackInfo& info); + NativeValue* OnSetSystemBarEnable(NativeEngine& engine, NativeCallbackInfo& info); + NativeValue* OnSetSystemBarProperties(NativeEngine& engine, NativeCallbackInfo& info); NativeValue* OnLoadContent(NativeEngine& engine, NativeCallbackInfo& info); sptr windowToken_ = nullptr; - sptr windowListener_ = nullptr; + std::map>> jsCallbackMap_; + std::map> jsListenerMap_; + std::mutex mtx_; void* contentStorage_ = nullptr; }; } // namespace Rosen diff --git a/interfaces/kits/napi/window_runtime/js_window_listener.cpp b/interfaces/kits/napi/window_runtime/js_window_listener.cpp index 63e72381712a668a15828d3dc6c6d86fb7d0b6e6..274e2a2ae1cd2e60f990beb1ae54639982900c9f 100644 --- a/interfaces/kits/napi/window_runtime/js_window_listener.cpp +++ b/interfaces/kits/napi/window_runtime/js_window_listener.cpp @@ -14,6 +14,7 @@ */ #include "js_window_listener.h" #include "js_runtime_utils.h" +#include "js_window_utils.h" #include "window_manager_hilog.h" namespace OHOS { namespace Rosen { @@ -21,65 +22,66 @@ using namespace AbilityRuntime; namespace { constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0, "JsWindowListener"}; } -bool JsWindowListener::IsCallbackExists(std::string type, NativeValue* jsListenerObject) -{ - if (jsWinodwListenerObjectMap_.find(type) == jsWinodwListenerObjectMap_.end()) { - WLOGFE("JsWindowListener::IsCallbackExists methodName %{public}s not exist!", type.c_str()); - return false; - } - for (auto iter = jsWinodwListenerObjectMap_[type].begin(); - iter != jsWinodwListenerObjectMap_[type].end(); iter++) { - if (jsListenerObject->StrictEquals((*iter)->Get())) { - WLOGFI("JsWindowListener::AddJsListenerObject callback already exists!"); - return true; - } - } - return false; -} -bool JsWindowListener::AddJsListenerObject(std::string type, NativeValue* jsListenerObject) +void JsWindowListener::AddCallback(NativeValue* jsListenerObject) { - WLOGFI("JsWindowListener::AddJsListenerObject is called"); - std::lock_guard lock(listenerMutex_); + WLOGFI("JsWindowListener::AddCallbackAndRegister is called"); + std::lock_guard lock(mtx_); std::unique_ptr callbackRef; callbackRef.reset(engine_->CreateReference(jsListenerObject, 1)); - if (IsCallbackExists(type, jsListenerObject)) { - WLOGFI("JsWindowListener::AddJsListenerObject jsWinodwListenerObjectMap_ size: %{public}d!", - static_cast(jsWinodwListenerObjectMap_[type].size())); - return false; + jsCallBack_.push_back(std::move(callbackRef)); + WLOGFI("JsWindowListener::AddCallbackAndRegister success jsCallBack_ size: %{public}d!", + static_cast(jsCallBack_.size())); + return; +} + +void JsWindowListener::RemoveAllCallback() +{ + std::lock_guard lock(mtx_); + jsCallBack_.clear(); +} + +void JsWindowListener::RemoveCallback(NativeValue* jsListenerObject) +{ + std::lock_guard lock(mtx_); + for (auto iter = jsCallBack_.begin(); iter != jsCallBack_.end();) { + if (jsListenerObject->StrictEquals((*iter)->Get())) { + jsCallBack_.erase(iter); + } else { + iter++; + } } - jsWinodwListenerObjectMap_[type].insert(std::move(callbackRef)); - WLOGFI("JsWindowListener::AddJsListenerObject failed jsWinodwListenerObjectMap_ size: %{public}d!", - static_cast(jsWinodwListenerObjectMap_[type].size())); - return true; + WLOGFI("JsWindowListener::AddCallbackAndRegister success jsCallBack_ size: %{public}d!", + static_cast(jsCallBack_.size())); + return; } -void JsWindowListener::RemoveJsListenerObject(std::string type, NativeValue* jsListenerObject) +void JsWindowListener::CallJsMethod(const char* methodName, NativeValue* const* argv, size_t argc) { - WLOGFI("JsWindowListener::RemoveJsListenerObject is called"); - std::lock_guard lock(listenerMutex_); - if (jsWinodwListenerObjectMap_.find(type) == jsWinodwListenerObjectMap_.end()) { - WLOGFE("methodName %{public}s not exist!", type.c_str()); + WLOGFI("CallJsMethod methodName = %{public}s", methodName); + if (engine_ == nullptr) { + WLOGFE("engine_ nullptr"); return; } - if (jsListenerObject == nullptr) { - jsWinodwListenerObjectMap_.erase(type); - } else { - for (auto iter = jsWinodwListenerObjectMap_[type].begin(); - iter != jsWinodwListenerObjectMap_[type].end(); iter++) { - if (jsListenerObject->StrictEquals((*iter)->Get())) { - jsWinodwListenerObjectMap_[type].erase(iter); - } + for (auto iter = jsCallBack_.begin(); iter != jsCallBack_.end(); iter++) { + NativeValue* method = (*iter)->Get(); + if (method == nullptr) { + WLOGFE("Failed to get method callback from object"); + continue; } + engine_->CallFunction(engine_->CreateUndefined(), method, argv, argc); } - WLOGFI("JsWindowListener::RemoveJsListenerObject jsWinodwListenerObjectMap_ size: %{public}d!", - static_cast(jsWinodwListenerObjectMap_[type].size())); - WLOGFI("JsWindowListener::RemoveJsListenerObject success!"); } void JsWindowListener::OnSizeChange(Rect rect) { WLOGFI("JsWindowListener::OnSizeChange is called"); + std::lock_guard lock(mtx_); + if (jsCallBack_.empty()) { + WLOGFE("JsWindowListener::OnSizeChange windowSizeChanged not register!"); + return; + } + NativeValue* sizeValue = engine_->CreateObject(); NativeObject* object = ConvertNativeValueTo(sizeValue); if (object == nullptr) { @@ -92,27 +94,24 @@ void JsWindowListener::OnSizeChange(Rect rect) CallJsMethod("windowSizeChange", argv, ArraySize(argv)); } -void JsWindowListener::CallJsMethod(const char* methodName, NativeValue* const* argv, size_t argc) +void JsWindowListener::OnSystemBarPropertyChange(uint64_t displayId, SystemBarProps props) { - WLOGFI("CallJsMethod methodName = %{public}s", methodName); - if (engine_ == nullptr) { - WLOGFE("engine_ nullptr"); + std::lock_guard lock(mtx_); + WLOGFI("JsWindowListener::OnSystemBarPropertyChange is called"); + if (jsCallBack_.empty()) { + WLOGFE("JsWindowListener::OnSystemBarPropertyChange systemUiTintChange not register!"); return; } - std::lock_guard lock(listenerMutex_); - std::string type(methodName); - if (jsWinodwListenerObjectMap_.find(type) == jsWinodwListenerObjectMap_.end()) { - WLOGFE("methodName %{public}s not exist!", methodName); + NativeValue* propertyValue = engine_->CreateObject(); + NativeObject* object = ConvertNativeValueTo(propertyValue); + if (object == nullptr) { + WLOGFE("Failed to convert prop to jsObject"); return; } - for (auto iter = jsWinodwListenerObjectMap_[type].begin(); iter != jsWinodwListenerObjectMap_[type].end(); iter++) { - NativeValue* method = (*iter)->Get(); - if (method == nullptr) { - WLOGFE("Failed to get method callback from object"); - return; - } - engine_->CallFunction(engine_->CreateUndefined(), method, argv, argc); - } + object->SetProperty("displayId", CreateJsValue(*engine_, static_cast(displayId))); + object->SetProperty("regionTint", CreateJsSystemBarRegionTintArrayObject(*engine_, props)); + NativeValue* argv[] = {propertyValue}; + CallJsMethod("systemUiTintChange", argv, ArraySize(argv)); } } // namespace Rosen } // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/napi/window_runtime/js_window_listener.h b/interfaces/kits/napi/window_runtime/js_window_listener.h index 19ba2d834dd2a654aaf2dcdb9d54e2d72f788df7..be1548597d6f82b1f2d32387872aa8debf53ff78 100644 --- a/interfaces/kits/napi/window_runtime/js_window_listener.h +++ b/interfaces/kits/napi/window_runtime/js_window_listener.h @@ -21,22 +21,28 @@ #include #include "native_engine/native_engine.h" #include "native_engine/native_value.h" +#include "refbase.h" #include "window.h" +#include "window_manager.h" +#include "wm_common.h" + namespace OHOS { namespace Rosen { -class JsWindowListener : public IWindowChangeListener { +class JsWindowListener : public IWindowChangeListener, + public ISystemBarChangedListener { public: explicit JsWindowListener(NativeEngine* engine) : engine_(engine) {} virtual ~JsWindowListener() = default; + void AddCallback(NativeValue* jsListenerObject); + void RemoveAllCallback(); + void RemoveCallback(NativeValue* jsListenerObject); + void OnSystemBarPropertyChange(uint64_t displayId, SystemBarProps props) override; void OnSizeChange(Rect rect) override; - bool AddJsListenerObject(std::string type, NativeValue* jsListenerObject); - void RemoveJsListenerObject(std::string type, NativeValue* jsListenerObject); private: void CallJsMethod(const char* methodName, NativeValue* const* argv = nullptr, size_t argc = 0); - bool IsCallbackExists(std::string type, NativeValue* jsListenerObject); NativeEngine* engine_ = nullptr; - std::map>> jsWinodwListenerObjectMap_; - std::mutex listenerMutex_; + std::mutex mtx_; + std::vector> jsCallBack_; }; } // namespace Rosen } // namespace OHOS diff --git a/interfaces/kits/napi/window_runtime/js_window_manager.cpp b/interfaces/kits/napi/window_runtime/js_window_manager.cpp index f4aaf9a701c594bf7a5fa2a361ed8b21cec5a1ef..fe3c393062d10cf7e548f6e1eaf24514cb4d9104 100644 --- a/interfaces/kits/napi/window_runtime/js_window_manager.cpp +++ b/interfaces/kits/napi/window_runtime/js_window_manager.cpp @@ -15,11 +15,13 @@ #include "js_window_manager.h" #include "js_runtime_utils.h" #include "js_window.h" +#include "js_window_listener.h" #include "js_window_utils.h" #include "native_engine/native_reference.h" +#include "window_manager.h" #include "window_manager_hilog.h" #include "window_option.h" - +#include "singleton_container.h" namespace OHOS { namespace Rosen { using namespace AbilityRuntime; @@ -29,7 +31,9 @@ namespace { class JsWindowManager { public: - JsWindowManager() = default; + explicit JsWindowManager(NativeEngine* engine) { + } + ~JsWindowManager() = default; static void Finalizer(NativeEngine* engine, void* data, void* hint) @@ -50,6 +54,18 @@ public: return (me != nullptr) ? me->OnFindWindow(*engine, *info) : nullptr; } + static NativeValue* RegisterWindowManagerCallback(NativeEngine* engine, NativeCallbackInfo* info) + { + JsWindowManager* me = CheckParamsAndGetThis(engine, info); + return (me != nullptr) ? me->OnRegisterWindowMangerCallback(*engine, *info) : nullptr; + } + + static NativeValue* UnregisterWindowMangerCallback(NativeEngine* engine, NativeCallbackInfo* info) + { + JsWindowManager* me = CheckParamsAndGetThis(engine, info); + return (me != nullptr) ? me->OnUnregisterWindowManagerCallback(*engine, *info) : nullptr; + } + private: std::weak_ptr context_; bool GetNativeContext(NativeValue* nativeContext) @@ -66,6 +82,9 @@ private: return true; } + std::map, sptr>> jsCbMap_; + std::mutex mtx_; + NativeValue* OnCreateWindow(NativeEngine& engine, NativeCallbackInfo& info) { WLOGFI("JsOnCreateWindow is called"); @@ -135,7 +154,7 @@ private: WLOGFI("JsWindowManager::OnFindWindow success"); } else { task.Reject(engine, CreateJsError(engine, - static_cast(WMError::WM_ERROR_NULLPTR), "JsWindow::OnFindWindow failed.")); + static_cast(WMError::WM_ERROR_NULLPTR), "JsWindowManager::OnFindWindow failed.")); } }; @@ -148,6 +167,142 @@ private: engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result)); return result; } + + bool IfCallbackRegistered(std::string type, NativeValue* jsListenerObject) + { + if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) { + WLOGFI("JsWindowManager::IfCallbackRegistered methodName %{public}s not registertd!", type.c_str()); + return false; + } + + for (auto iter = jsCbMap_[type].begin(); iter != jsCbMap_[type].end(); iter++) { + if (jsListenerObject->StrictEquals(iter->first->Get())) { + WLOGFE("JsWindowManager::IfCallbackRegistered callback already registered!"); + return true; + } + } + return false; + } + + void RegisterWmListenerWithType(NativeEngine& engine, std::string type, NativeValue* value) + { + // should do type check + if (IfCallbackRegistered(type, value)) { + WLOGFE("JsWindowManager::RegisterWmListenerWithType callback already registered!"); + return; + } + std::unique_ptr callbackRef; + callbackRef.reset(engine.CreateReference(value, 1)); + sptr windowManagerListener = new JsWindowListener(&engine); + if (type.compare("systemUiTintChange") == 0) { + sptr thisListener(windowManagerListener); + SingletonContainer::Get().RegisterSystemBarChangedListener(thisListener); + WLOGFI("JsWindowManager::RegisterWmListenerWithType systemUiTintChange success"); + } else { + WLOGFE("JsWindowManager::RegisterWmListenerWithType failed method: %{public}s not support!", + type.c_str()); + return; + } + windowManagerListener->AddCallback(value); + jsCbMap_[type][std::move(callbackRef)] = windowManagerListener; + return; + } + + void UnregisterAllWmListenerWithType(std::string type) + { + if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) { + WLOGFI("JsWindowManager::UnregisterAllWmListenerWithType methodName %{public}s not registerted!", + type.c_str()); + return; + } + for (auto it = jsCbMap_[type].begin(); it != jsCbMap_[type].end();) { + it->second->RemoveAllCallback(); + if (type.compare("systemUiTintChange") == 0) { + sptr thisListener(it->second); + SingletonContainer::Get().UnregisterSystemBarChangedListener(thisListener); + WLOGFI("JsWindowManager::UnregisterAllWmListenerWithType systemUiTintChange success"); + } + jsCbMap_[type].erase(it++); + } + jsCbMap_.erase(type); + return; + } + + void UnregisterWmListenerWithType(std::string type, NativeValue* value) + { + if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) { + WLOGFI("JsWindowManager::UnregisterWmListenerWithType methodName %{public}s not registerted!", + type.c_str()); + return; + } + for (auto it = jsCbMap_[type].begin(); it != jsCbMap_[type].end();) { + if (value->StrictEquals(it->first->Get())) { + it->second->RemoveCallback(value); + if (type.compare("systemUiTintChange") == 0) { + sptr thisListener(it->second); + SingletonContainer::Get().UnregisterSystemBarChangedListener(thisListener); + WLOGFI("JsWindowManager::UnregisterWmListenerWithType systemUiTintChange success"); + } + jsCbMap_[type].erase(it++); + break; + } else { + it++; + } + } + // one type with multi jscallback, erase type when there is no callback in one type + if (jsCbMap_[type].empty()) { + jsCbMap_.erase(type); + } + return; + } + + NativeValue* OnRegisterWindowMangerCallback(NativeEngine& engine, NativeCallbackInfo& info) + { + WLOGFI("JsWindowManager::OnRegisterWindowMangerCallback is called"); + if (info.argc != ARGC_TWO) { + WLOGFE("Params not match"); + return engine.CreateUndefined(); + } + std::string cbType; + if (!ConvertFromJsValue(engine, info.argv[0], cbType)) { + WLOGFE("Failed to convert parameter to callbackType"); + return engine.CreateUndefined(); + } + NativeValue* value = info.argv[1]; + if (!value->IsCallable()) { + WLOGFI("JsWindowManager::OnRegisterWindowMangerCallback info->argv[1] is not callable"); + return engine.CreateUndefined(); + } + std::lock_guard lock(mtx_); + RegisterWmListenerWithType(engine, cbType, value); + return engine.CreateUndefined(); + } + + NativeValue* OnUnregisterWindowManagerCallback(NativeEngine& engine, NativeCallbackInfo& info) + { + WLOGFI("JsWindowManager::OnUnregisterWindowCallback is called"); + if (info.argc == 0) { + WLOGFE("Params not match"); + return engine.CreateUndefined(); + } + std::string cbType; + if (!ConvertFromJsValue(engine, info.argv[0], cbType)) { + WLOGFE("Failed to convert parameter to callbackType"); + return engine.CreateUndefined(); + } + std::lock_guard lock(mtx_); + if (info.argc == 1) { + UnregisterAllWmListenerWithType(cbType); + } else { + NativeValue* value = info.argv[1]; + if (!value->IsCallable()) { + WLOGFI("JsWindowManager::OnUnregisterWindowManagerCallback info->argv[1] is not callable"); + return engine.CreateUndefined(); + } + UnregisterWmListenerWithType(cbType, value); + } + return engine.CreateUndefined(); + } }; NativeValue* JsWindowManagerInit(NativeEngine* engine, NativeValue* exportObj) @@ -165,12 +320,13 @@ NativeValue* JsWindowManagerInit(NativeEngine* engine, NativeValue* exportObj) return nullptr; } - std::unique_ptr jsWinManager = std::make_unique(); + std::unique_ptr jsWinManager = std::make_unique(engine); object->SetNativePointer(jsWinManager.release(), JsWindowManager::Finalizer, nullptr); BindNativeFunction(*engine, *object, "create", JsWindowManager::CreateWindow); BindNativeFunction(*engine, *object, "find", JsWindowManager::FindWindow); - + BindNativeFunction(*engine, *object, "on", JsWindowManager::RegisterWindowManagerCallback); + BindNativeFunction(*engine, *object, "off", JsWindowManager::UnregisterWindowMangerCallback); return engine->CreateUndefined(); } } // namespace Rosen diff --git a/interfaces/kits/napi/window_runtime/js_window_utils.cpp b/interfaces/kits/napi/window_runtime/js_window_utils.cpp index 0dfe19d8a7b7785d5d38de763cc7d905c40af76e..60f97e0ca6dd0141debf2fc18afb460011d84d40 100644 --- a/interfaces/kits/napi/window_runtime/js_window_utils.cpp +++ b/interfaces/kits/napi/window_runtime/js_window_utils.cpp @@ -13,6 +13,9 @@ * limitations under the License. */ #include "js_window_utils.h" +#include +#include +#include #include "js_runtime_utils.h" #include "window_manager_hilog.h" namespace OHOS { @@ -22,13 +25,13 @@ namespace { constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0, "JsWindowUtils"}; } -static NativeValue* GetRectAndConvertToJsValue(NativeEngine& engine, const Rect& rect) +static NativeValue* GetRectAndConvertToJsValue(NativeEngine& engine, const Rect rect) { NativeValue* objValue = engine.CreateObject(); NativeObject* object = ConvertNativeValueTo(objValue); if (object == nullptr) { WLOGFE("Failed to convert rect to jsObject"); - return engine.CreateUndefined(); + return nullptr; } object->SetProperty("left", CreateJsValue(engine, rect.posX_)); object->SetProperty("top", CreateJsValue(engine, rect.posY_)); @@ -56,5 +59,170 @@ NativeValue* CreateJsWindowPropertiesObject(NativeEngine& engine, sptr& object->SetProperty("type", CreateJsValue(engine, window->GetType())); return objValue; } +static std::string GetHexColor(uint32_t color) +{ + std::stringstream ioss; + std::string temp; + ioss << std::setiosflags(std::ios::uppercase) << std::hex << color; + ioss >> temp; + int count = RGBA_LENGTH - temp.length(); + std::string tmpColor(count, '0'); + tmpColor += temp; + std::string finalColor("#"); + finalColor += tmpColor; + return finalColor; +} + +static NativeValue* CreateJsSystemBarRegionTintObject(NativeEngine& engine, + WindowType type, const SystemBarProperty& prop) +{ + WLOGFI("JsWindow::CreateJsSystemBarRegionTintObject is called"); + + NativeValue* objValue = engine.CreateObject(); + NativeObject* object = ConvertNativeValueTo(objValue); + if (object == nullptr) { + WLOGFE("Failed to convert SystemBarProperty to jsObject"); + return nullptr; + } + object->SetProperty("type", CreateJsValue(engine, static_cast(type))); + object->SetProperty("isEnable", CreateJsValue(engine, prop.enable_)); + std::string bkgColor = GetHexColor(prop.backgroundColor_); + WLOGFI("JsWindow::CreateJsSystemBarRegionTintObject backgroundColir: %{public}s", bkgColor.c_str()); + object->SetProperty("backgroundColor", CreateJsValue(engine, bkgColor)); + std::string contentColor = GetHexColor(prop.contentColor_); + WLOGFI("JsWindow::CreateJsSystemBarRegionTintObject contentColor: %{public}s", contentColor.c_str()); + object->SetProperty("contentColor", CreateJsValue(engine, contentColor)); + Rect rect = {0, 0, 0, 0}; // to fix on next version + object->SetProperty("region", GetRectAndConvertToJsValue(engine, rect)); + return objValue; +} + +NativeValue* CreateJsSystemBarRegionTintArrayObject(NativeEngine& engine, + const SystemBarProps& props) +{ + WLOGFI("JsWindow::CreateJsSystemBarRegionTintArrayObject is called"); + if (props.empty()) { + return nullptr; + } + NativeValue* objValue = engine.CreateArray(props.size()); + NativeArray* array = ConvertNativeValueTo(objValue); + if (array == nullptr) { + WLOGFE("Failed to convert SystemBarPropertys to jsArrayObject"); + return nullptr; + } + uint32_t index = 0; + for (size_t i = 0; i < props.size(); i++) { + array->SetElement(index++, CreateJsSystemBarRegionTintObject(engine, props[i].first, props[i].second)); + } + return objValue; +} + +bool GetSystemBarStatus(std::map& systemBarProperties, + NativeEngine& engine, NativeCallbackInfo& info, sptr& window) +{ + NativeArray* nativeArray = ConvertNativeValueTo(info.argv[0]); + if (nativeArray == nullptr) { + WLOGFE("Failed to convert parameter to SystemBarArray"); + return false; + } + uint32_t size = nativeArray->GetLength(); + auto statusProperty = window->GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_STATUS_BAR); + auto navProperty = window->GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_NAVIGATION_BAR); + statusProperty.enable_ = false; + navProperty.enable_ = false; + systemBarProperties[WindowType::WINDOW_TYPE_STATUS_BAR] = statusProperty; + systemBarProperties[WindowType::WINDOW_TYPE_NAVIGATION_BAR] = navProperty; + for (uint32_t i = 0; i < size; i++) { + std::string name; + if (!ConvertFromJsValue(engine, nativeArray->GetElement(i), name)) { + WLOGFE("Failed to convert parameter to SystemBarName"); + return false; + } + if (name.compare("status") == 0) { + systemBarProperties[WindowType::WINDOW_TYPE_STATUS_BAR].enable_ = true; + } else if (name.compare("navigation") == 0) { + systemBarProperties[WindowType::WINDOW_TYPE_NAVIGATION_BAR].enable_ = true; + } + } + return true; +} + +static uint32_t GetColorFromJs(NativeEngine& engine, NativeObject* jsObject, + const char* name, uint32_t defaultColor) +{ + NativeValue* jsColor = jsObject->GetProperty(name); + if (jsColor->TypeOf() != NATIVE_UNDEFINED) { + std::string colorStr; + if (!ConvertFromJsValue(engine, jsColor, colorStr)) { + WLOGFE("Failed to convert parameter to color"); + return defaultColor; + } + std::regex pattern("^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$"); + if (!std::regex_match(colorStr, pattern)) { + WLOGFE("invalid color input"); + return defaultColor; + } + WLOGFI("origin color: %{public}s", colorStr.c_str()); + if (colorStr.length() == RGB_LENGTH) { + colorStr += "FF"; // RGB + A + } + std::string color = colorStr.substr(1); + std::stringstream ss; + uint32_t hexColor; + ss << std::hex << color; + ss >> hexColor; + WLOGFI("color: %{public}s, Final Color is %{public}x", color.c_str(), hexColor); + return hexColor; + } + return defaultColor; +} + +bool SetSystemBarPropertiesFromJs(NativeEngine& engine, NativeObject* jsObject, + std::map& properties, sptr& window) +{ + auto statusProperty = window->GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_STATUS_BAR); + auto navProperty = window->GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_NAVIGATION_BAR); + properties[WindowType::WINDOW_TYPE_STATUS_BAR] = statusProperty; + properties[WindowType::WINDOW_TYPE_NAVIGATION_BAR] = navProperty; + properties[WindowType::WINDOW_TYPE_STATUS_BAR].backgroundColor_ = GetColorFromJs(engine, + jsObject, "statusBarColor", statusProperty.backgroundColor_); + properties[WindowType::WINDOW_TYPE_NAVIGATION_BAR].backgroundColor_ = GetColorFromJs(engine, + jsObject, "navigationBarColor", navProperty.backgroundColor_); + NativeValue* jsStatusContentColor = jsObject->GetProperty("statusBarContenColor"); + NativeValue* jsStatusIcon = jsObject->GetProperty("isStatusBarLightIcon"); + if (jsStatusContentColor->TypeOf() != NATIVE_UNDEFINED) { + properties[WindowType::WINDOW_TYPE_STATUS_BAR].contentColor_ = GetColorFromJs(engine, + jsObject, "statusBarContenColor", statusProperty.contentColor_); + } else if (jsStatusIcon->TypeOf() != NATIVE_UNDEFINED) { + bool isStatusBarLightIcon; + if (!ConvertFromJsValue(engine, jsStatusIcon, isStatusBarLightIcon)) { + WLOGFE("Failed to convert parameter to isStatusBarLightIcon"); + return false; + } + if (isStatusBarLightIcon) { + properties[WindowType::WINDOW_TYPE_STATUS_BAR].contentColor_ = SYSTEM_COLOR_WHITE; + } else { + properties[WindowType::WINDOW_TYPE_STATUS_BAR].contentColor_ = SYSTEM_COLOR_BLACK; + } + } + NativeValue* jsNavigationContentColor = jsObject->GetProperty("navigationBarContenColor"); + NativeValue* jsNavigationIcon = jsObject->GetProperty("isNavigationBarLightIcon"); + if (jsNavigationContentColor->TypeOf() != NATIVE_UNDEFINED) { + properties[WindowType::WINDOW_TYPE_NAVIGATION_BAR].contentColor_ = GetColorFromJs(engine, + jsObject, "navigationBarContenColor", navProperty.contentColor_); + } else if (jsNavigationIcon->TypeOf() != NATIVE_UNDEFINED) { + bool isNavigationBarLightIcon; + if (!ConvertFromJsValue(engine, jsNavigationIcon, isNavigationBarLightIcon)) { + WLOGFE("Failed to convert parameter to isNavigationBarLightIcon"); + return false; + } + if (isNavigationBarLightIcon) { + properties[WindowType::WINDOW_TYPE_NAVIGATION_BAR].contentColor_ = SYSTEM_COLOR_WHITE; + } else { + properties[WindowType::WINDOW_TYPE_NAVIGATION_BAR].contentColor_ = SYSTEM_COLOR_BLACK; + } + } + return true; +} } // namespace Rosen } // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/napi/window_runtime/js_window_utils.h b/interfaces/kits/napi/window_runtime/js_window_utils.h index 5d209d739fcfa29c0facba7373232b09b6eec1c4..d5f357c9b973055816c7999a9311f0308abcc71a 100644 --- a/interfaces/kits/napi/window_runtime/js_window_utils.h +++ b/interfaces/kits/napi/window_runtime/js_window_utils.h @@ -29,9 +29,17 @@ namespace { constexpr int32_t INDEX_ONE = 1; constexpr int32_t INDEX_TWO = 2; constexpr int32_t INDEX_THREE = 3; + constexpr int32_t RGB_LENGTH = 7; + constexpr int32_t RGBA_LENGTH = 8; } NativeValue* CreateJsWindowPropertiesObject(NativeEngine& engine, sptr& window); + bool SetSystemBarPropertiesFromJs(NativeEngine& engine, NativeObject* jsObject, + std::map& properties, sptr& window); + bool GetSystemBarStatus(std::map& systemBarProperties, + NativeEngine& engine, NativeCallbackInfo& info, sptr& window); + NativeValue* CreateJsSystemBarRegionTintArrayObject(NativeEngine& engine, + const SystemBarProps& props); } } #endif \ No newline at end of file diff --git a/wm/test/systemtest/window_immersive_test.cpp b/wm/test/systemtest/window_immersive_test.cpp index 4865ad6c602090bd9d4ca816e16ca8599cc6b9af..d4ed9f190a04e3818375537bc72b60ed4d477548 100644 --- a/wm/test/systemtest/window_immersive_test.cpp +++ b/wm/test/systemtest/window_immersive_test.cpp @@ -51,7 +51,7 @@ using utils = WindowTestUtils; class TestSystemBarChangedListener : public ISystemBarChangedListener { public: SystemBarProps props_; - void OnSystemBarPropertyChange(uint64_t displayId, const SystemBarProps& props) override; + void OnSystemBarPropertyChange(uint64_t displayId, SystemBarProps props) override; }; class WindowImmersiveTest : public testing::Test { @@ -111,7 +111,7 @@ bool WindowImmersiveTest::SystemBarPropsEqualsTo(const SystemBarProps& expect) return true; } -void TestSystemBarChangedListener::OnSystemBarPropertyChange(uint64_t displayId, const SystemBarProps& props) +void TestSystemBarChangedListener::OnSystemBarPropertyChange(uint64_t displayId, SystemBarProps props) { printf("TestSystemBarChangedListener Display ID: %llu\n", displayId); props_ = props;