* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "window_extension_session_impl.h"
#include <bool_wrapper.h>
#include <float_wrapper.h>
#include <hitrace_meter.h>
#include <int_wrapper.h>
#include <long_wrapper.h>
#include <ipc_types.h>
#include <parameters.h>
#include <string_wrapper.h>
#include <transaction/rs_interfaces.h>
#include <transaction/rs_transaction.h>
#ifdef IMF_ENABLE
#include <input_method_controller.h>
#endif
#include "configuration.h"
#include "display_info.h"
#include "input_transfer_station.h"
#include "perform_reporter.h"
#include "rs_adapter.h"
#include "session_permission.h"
#include "singleton_container.h"
#include "sys_cap_util.h"
#include "ui_extension/provider_data_handler.h"
#include "window_adapter.h"
#include "window_helper.h"
#include "window_manager_hilog.h"
#include "wm_common.h"
#include "session_helper.h"
namespace OHOS {
namespace Rosen {
namespace {
constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowExtensionSessionImpl"};
#ifdef IMF_ENABLE
constexpr int64_t DISPATCH_KEY_EVENT_TIMEOUT_TIME_MS = 1000;
#endif
constexpr int32_t UIEXTENTION_ROTATION_ANIMATION_TIME = 400;
constexpr const char* TRANSPARENT_BACKGROUND_COLOR_HEX = "#00000000";
constexpr uint64_t INVALID_NODE_ID = 0;
}
#define CHECK_HOST_SESSION_RETURN_IF_NULL(hostSession) \
do { \
if ((hostSession) == nullptr) { \
TLOGE(WmsLogTag::DEFAULT, "hostSession is null"); \
return; \
} \
} while (false)
#define CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, ret) \
do { \
if ((hostSession) == nullptr) { \
TLOGE(WmsLogTag::DEFAULT, "hostSession is null"); \
return ret; \
} \
} while (false)
WindowExtensionSessionImpl::WindowExtensionSessionImpl(
const sptr<WindowOption>& option) : WindowSessionImpl(option, nullptr)
{
if (property_->GetUIExtensionUsage() == UIExtensionUsage::MODAL ||
SessionHelper::IsSecureUIExtension(property_->GetUIExtensionUsage())) {
startModalExtensionTimeStamp_ = option->GetStartModalExtensionTimeStamp();
extensionWindowFlags_.hideNonSecureWindowsFlag = true;
}
if ((isDensityFollowHost_ = option->GetIsDensityFollowHost())) {
hostDensityValue_ = option->GetDensity();
}
TLOGNI(WmsLogTag::WMS_UIEXT, "Uiext usage=%{public}u, timeStamp=%{public}" PRId64,
property_->GetUIExtensionUsage(), startModalExtensionTimeStamp_);
dataHandler_ = std::make_shared<Extension::ProviderDataHandler>();
RegisterDataConsumer();
}
WindowExtensionSessionImpl::~WindowExtensionSessionImpl()
{
WLOGFI("[WMSCom] %{public}d, %{public}s", GetPersistentId(), GetWindowName().c_str());
}
static float GetFloatParam(const std::string& key, const AAFwk::WantParams& configParam,
float defaultValue = 1.0f)
{
if (AAFwk::IFloat* so = AAFwk::IFloat::Query(configParam.GetParam(key))) {
defaultValue = AAFwk::Float::Unbox(so);
}
return defaultValue;
}
std::shared_ptr<IDataHandler> WindowExtensionSessionImpl::GetExtensionDataHandler() const
{
return dataHandler_;
}
WMError WindowExtensionSessionImpl::Create(const std::shared_ptr<AbilityRuntime::Context>& context,
const sptr<Rosen::ISession>& iSession, const std::string& identityToken, bool isModuleAbilityHookEnd,
bool isBlockSubwindow)
{
TLOGD(WmsLogTag::WMS_LIFE, "Called.");
if (!context || !iSession) {
TLOGE(WmsLogTag::WMS_LIFE, "context is nullptr: %{public}u or sessionToken is nullptr: %{public}u",
context == nullptr, iSession == nullptr);
return WMError::WM_ERROR_NULLPTR;
}
if (vsyncStation_ == nullptr || !vsyncStation_->IsVsyncReceiverCreated()) {
return WMError::WM_ERROR_NULLPTR;
}
SetDefaultDisplayIdIfNeed();
hostSession_ = iSession;
dataHandler_->SetEventHandler(handler_);
dataHandler_->SetRemoteProxyObject(iSession->AsObject());
context_ = context;
if (context_) {
abilityToken_ = context_->GetToken();
}
TLOGI(WmsLogTag::WMS_UIEXT, "IsConstrainedModal: %{public}d", property_->IsConstrainedModal());
AddExtensionWindowStageToSCB(property_->IsConstrainedModal());
WMError ret = Connect();
if (ret != WMError::WM_OK) {
TLOGE(WmsLogTag::WMS_LIFE, "name:%{public}s %{public}d connect fail. ret:%{public}d",
property_->GetWindowName().c_str(), GetPersistentId(), ret);
return ret;
}
MakeSubOrDialogWindowDragableAndMoveble();
{
std::unique_lock<std::shared_mutex> lock(windowExtensionSessionMutex_);
GetWindowExtensionSessionSet().insert(this);
}
auto usage = property_->GetUIExtensionUsage();
if ((usage == UIExtensionUsage::MODAL) || SessionHelper::IsSecureUIExtension(usage)) {
InputTransferStation::GetInstance().AddInputWindow(this);
}
state_ = WindowState::STATE_CREATED;
isUIExtensionAbilityProcess_ = true;
property_->SetIsUIExtensionAbilityProcess(true);
isBlockSubwindow_ = isBlockSubwindow;
UpdateDefaultStatusBarColor();
TLOGI(WmsLogTag::WMS_LIFE, "Created name:%{public}s %{public}d success.",
property_->GetWindowName().c_str(), GetPersistentId());
AddSetUIContentTimeoutCheck();
RecordWindowLifecycleChange("create");
return WMError::WM_OK;
}
void WindowExtensionSessionImpl::AddExtensionWindowStageToSCB(bool isConstrainedModal)
{
if (!abilityToken_) {
TLOGE(WmsLogTag::WMS_UIEXT, "token is nullptr");
return;
}
if (nodeId_ == INVALID_NODE_ID) {
TLOGE(WmsLogTag::WMS_UIEXT, "nodeId_ is invalid");
return;
}
SingletonContainer::Get<WindowAdapter>().AddExtensionWindowStageToSCB(sptr<ISessionStage>(this), abilityToken_,
nodeId_, startModalExtensionTimeStamp_, isConstrainedModal);
}
void WindowExtensionSessionImpl::RemoveExtensionWindowStageFromSCB(bool isConstrainedModal)
{
if (!abilityToken_) {
TLOGE(WmsLogTag::WMS_UIEXT, "token is nullptr");
return;
}
SingletonContainer::Get<WindowAdapter>().RemoveExtensionWindowStageFromSCB(sptr<ISessionStage>(this),
abilityToken_, isConstrainedModal);
}
void WindowExtensionSessionImpl::UpdateConfiguration(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
{
if (auto uiContent = GetUIContentSharedPtr()) {
TLOGI(WmsLogTag::WMS_ATTRIBUTE, "notify ace extension win=%{public}u, display=%{public}" PRIu64,
GetWindowId(), GetDisplayId());
uiContent->UpdateConfiguration(configuration);
} else {
TLOGE(WmsLogTag::WMS_ATTRIBUTE, "uiContent null, ext win=%{public}u, display=%{public}" PRIu64,
GetWindowId(), GetDisplayId());
}
UpdateDefaultStatusBarColor();
}
void WindowExtensionSessionImpl::UpdateConfigurationForSpecified(
const std::shared_ptr<AppExecFwk::Configuration>& configuration,
const std::shared_ptr<Global::Resource::ResourceManager>& resourceManager)
{
if (auto uiContent = GetUIContentSharedPtr()) {
TLOGI(WmsLogTag::WMS_ATTRIBUTE, "notify ace extension win=%{public}u, display=%{public}" PRIu64,
GetWindowId(), GetDisplayId());
uiContent->UpdateConfiguration(configuration, resourceManager);
} else {
TLOGE(WmsLogTag::WMS_ATTRIBUTE, "uiContent null, ext win=%{public}u, display=%{public}" PRIu64,
GetWindowId(), GetDisplayId());
}
if (configuration != nullptr) {
TLOGI(WmsLogTag::WMS_IMMS, "extension win=%{public}u, colorMode=%{public}s, display=%{public}" PRIu64,
GetWindowId(), specifiedColorMode_.c_str(), GetDisplayId());
specifiedColorMode_ = configuration->GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE);
UpdateDefaultStatusBarColor();
}
}
void WindowExtensionSessionImpl::UpdateConfigurationForAll(
const std::shared_ptr<AppExecFwk::Configuration>& configuration,
const std::vector<std::shared_ptr<AbilityRuntime::Context>>& ignoreWindowContexts)
{
std::unordered_set<std::shared_ptr<AbilityRuntime::Context>> ignoreWindowCtxSet(
ignoreWindowContexts.begin(), ignoreWindowContexts.end());
std::unique_lock<std::shared_mutex> lock(windowExtensionSessionMutex_);
TLOGD(WmsLogTag::WMS_ATTRIBUTE, "extension map size: %{public}u",
static_cast<uint32_t>(GetWindowExtensionSessionSet().size()));
for (const auto& window : GetWindowExtensionSessionSet()) {
if (window == nullptr) {
TLOGE(WmsLogTag::WMS_ATTRIBUTE, "extension window is null");
continue;
}
if (ignoreWindowCtxSet.count(window->GetContext()) == 0) {
TLOGD(WmsLogTag::WMS_ATTRIBUTE, "extension win=%{public}u, display=%{public}" PRIu64,
window->GetWindowId(), window->GetDisplayId());
window->UpdateConfiguration(configuration);
} else {
TLOGI(WmsLogTag::WMS_ATTRIBUTE, "skip extension win=%{public}u, display=%{public}" PRIu64,
window->GetWindowId(), window->GetDisplayId());
}
}
}
void WindowExtensionSessionImpl::UpdateConfigurationSync(
const std::shared_ptr<AppExecFwk::Configuration>& configuration)
{
if (auto uiContent = GetUIContentSharedPtr()) {
TLOGI(WmsLogTag::WMS_ATTRIBUTE, "notify ace extension win=%{public}u, display=%{public}" PRIu64,
GetWindowId(), GetDisplayId());
uiContent->UpdateConfigurationSyncForAll(configuration);
} else {
TLOGE(WmsLogTag::WMS_ATTRIBUTE, "uiContent null, ext win=%{public}u, display=%{public}" PRIu64,
GetWindowId(), GetDisplayId());
}
}
void WindowExtensionSessionImpl::UpdateConfigurationSyncForAll(
const std::shared_ptr<AppExecFwk::Configuration>& configuration)
{
std::unique_lock<std::shared_mutex> lock(windowExtensionSessionMutex_);
TLOGD(WmsLogTag::WMS_ATTRIBUTE, "extension map size: %{public}u",
static_cast<uint32_t>(GetWindowExtensionSessionSet().size()));
for (const auto& window : GetWindowExtensionSessionSet()) {
if (window == nullptr) {
TLOGE(WmsLogTag::WMS_ATTRIBUTE, "extension window is null");
continue;
}
TLOGD(WmsLogTag::WMS_ATTRIBUTE, "extension win=%{public}u, display=%{public}" PRIu64,
window->GetWindowId(), window->GetDisplayId());
window->UpdateConfigurationSync(configuration);
}
}
void WindowExtensionSessionImpl::UpdateDefaultStatusBarColor()
{
if (!property_->GetIsAtomicService()) {
TLOGD(WmsLogTag::WMS_IMMS, "win %{public}u no support", GetPersistentId());
return;
}
uint32_t contentColor = 0;
auto ret = UpdateStatusBarColorByColorMode(contentColor);
if (ret != WMError::WM_OK) {
TLOGD(WmsLogTag::WMS_IMMS, "win %{public}u no need update", GetPersistentId());
return;
}
TLOGI(WmsLogTag::WMS_IMMS, "win %{public}u, contentColor %{public}x", GetPersistentId(), contentColor);
SetStatusBarColorForExtensionInner(contentColor);
}
WMError WindowExtensionSessionImpl::Destroy(bool needNotifyServer, bool needClearListener, uint32_t reason,
bool isFromInnerkits)
{
TLOGI(WmsLogTag::WMS_LIFE, "id:%{public}d Destroy, state:%{public}u, needNotifyServer:%{public}d, "
"needClearListener:%{public}d, isFromInnerkits:%{public}d",
GetPersistentId(), state_, needNotifyServer, needClearListener, isFromInnerkits);
auto usage = property_->GetUIExtensionUsage();
if ((usage == UIExtensionUsage::MODAL) || SessionHelper::IsSecureUIExtension(usage)) {
InputTransferStation::GetInstance().RemoveInputWindow(GetPersistentId());
}
if (IsWindowSessionInvalid()) {
TLOGE(WmsLogTag::WMS_LIFE, "session is invalid");
return WMError::WM_ERROR_INVALID_WINDOW;
}
if (auto hostSession = GetHostSession()) {
TLOGI(WmsLogTag::WMS_LIFE, "Disconnect with host session, id: %{public}d.", GetPersistentId());
hostSession->Disconnect();
}
NotifyBeforeDestroy(GetWindowName());
if (needClearListener) {
ClearListenersById(GetPersistentId());
}
{
std::lock_guard<std::recursive_mutex> lock(mutex_);
state_ = WindowState::STATE_DESTROYED;
requestState_ = WindowState::STATE_DESTROYED;
}
DestroySubWindow();
{
TLOGI(WmsLogTag::WMS_LIFE, "Reset state, id: %{public}d.", GetPersistentId());
std::lock_guard<std::mutex> lock(hostSessionMutex_);
hostSession_ = nullptr;
}
{
std::unique_lock<std::shared_mutex> lock(windowExtensionSessionMutex_);
GetWindowExtensionSessionSet().erase(this);
}
AAFwk::Want want;
auto ret = SendExtensionMessageToHost(
static_cast<uint32_t>(Extension::Businesscode::UNREGISTER_HOST_WINDOW_RECT_CHANGE_LISTENER), want);
if (ret != WMError::WM_OK) {
TLOGE(WmsLogTag::WMS_UIEXT, "Send unregister host window rect change listener message failed, errCode: "
"%{public}d", ret);
}
TLOGI(WmsLogTag::WMS_LIFE, "Erase in set, id: %{public}d.", GetPersistentId());
if (context_) {
context_.reset();
}
ClearVsyncStation();
SetUIContentComplete();
SetUIExtensionDestroyComplete();
RemoveExtensionWindowStageFromSCB(property_->IsConstrainedModal());
dataHandler_->SetRemoteProxyObject(nullptr);
TLOGI(WmsLogTag::WMS_LIFE, "Destroyed success, id: %{public}d.", GetPersistentId());
RecordWindowLifecycleChange("destroy");
return WMError::WM_OK;
}
WMError WindowExtensionSessionImpl::MoveTo(int32_t x, int32_t y,
bool isMoveToGlobal, MoveConfiguration moveConfiguration)
{
TLOGD(WmsLogTag::WMS_UIEXT, "Id:%{public}d xy %{public}d %{public}d isMoveToGlobal %{public}d "
"moveConfiguration %{public}s", property_->GetPersistentId(), x, y, isMoveToGlobal,
moveConfiguration.ToString().c_str());
if (IsWindowSessionInvalid()) {
WLOGFE("Window session invalid.");
return WMError::WM_ERROR_INVALID_WINDOW;
}
const auto& rect = property_->GetWindowRect();
WSRect wsRect = { x, y, rect.width_, rect.height_ };
WSError error = UpdateRect(wsRect, SizeChangeReason::MOVE);
return static_cast<WMError>(error);
}
WMError WindowExtensionSessionImpl::Resize(uint32_t width, uint32_t height)
{
WLOGFD("Id:%{public}d wh %{public}u %{public}u", property_->GetPersistentId(), width, height);
if (IsWindowSessionInvalid()) {
WLOGFE("Window session invalid.");
return WMError::WM_ERROR_INVALID_WINDOW;
}
const auto& rect = property_->GetWindowRect();
WSRect wsRect = { rect.posX_, rect.posY_, width, height };
WSError error = UpdateRect(wsRect, SizeChangeReason::RESIZE);
return static_cast<WMError>(error);
}
WMError WindowExtensionSessionImpl::TransferAbilityResult(uint32_t resultCode, const AAFwk::Want& want)
{
TLOGI(WmsLogTag::WMS_UIEXT, "id: %{public}d", GetPersistentId());
if (IsWindowSessionInvalid()) {
WLOGFE("Window invalid.");
return WMError::WM_ERROR_REPEAT_OPERATION;
}
auto hostSession = GetHostSession();
CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
return static_cast<WMError>(hostSession->TransferAbilityResult(resultCode, want));
}
WMError WindowExtensionSessionImpl::TransferExtensionData(const AAFwk::WantParams& wantParams)
{
TLOGD(WmsLogTag::WMS_UIEXT, "id: %{public}d", GetPersistentId());
if (IsWindowSessionInvalid()) {
WLOGFE("Window invalid.");
return WMError::WM_ERROR_REPEAT_OPERATION;
}
auto hostSession = GetHostSession();
CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
auto ret = hostSession->TransferExtensionData(wantParams);
if (ret == ERR_NONE) {
return WMError::WM_OK;
}
if (context_ != nullptr) {
std::ostringstream oss;
oss << "TransferExtensionData from provider to host failed" << ",";
oss << " provider bundleName: " << context_->GetBundleName() << ",";
oss << " provider windowName: " << property_->GetWindowName() << ",";
oss << " errorCode: " << static_cast<int32_t>(ret) << ";";
int32_t res = WindowInfoReporter::GetInstance().ReportUIExtensionException(
static_cast<int32_t>(WindowDFXHelperType::WINDOW_UIEXTENSION_TRANSFER_DATA_FAIL),
getpid(), GetPersistentId(), oss.str()
);
if (res != 0) {
TLOGE(WmsLogTag::WMS_UIEXT, "ReportUIExtensionException message failed, res: %{public}d", res);
}
}
return WMError::WM_ERROR_IPC_FAILED;
}
void WindowExtensionSessionImpl::RegisterTransferComponentDataListener(const NotifyTransferComponentDataFunc& func)
{
if (IsWindowSessionInvalid()) {
WLOGFE("Window invalid.");
return;
}
notifyTransferComponentDataFunc_ = std::move(func);
auto hostSession = GetHostSession();
CHECK_HOST_SESSION_RETURN_IF_NULL(hostSession);
hostSession->NotifyAsyncOn();
}
WSError WindowExtensionSessionImpl::NotifyTransferComponentData(const AAFwk::WantParams& wantParams)
{
TLOGD(WmsLogTag::WMS_UIEXT, "id: %{public}d", GetPersistentId());
if (notifyTransferComponentDataFunc_) {
notifyTransferComponentDataFunc_(wantParams);
}
return WSError::WS_OK;
}
WSErrorCode WindowExtensionSessionImpl::NotifyTransferComponentDataSync(
const AAFwk::WantParams& wantParams, AAFwk::WantParams& reWantParams)
{
TLOGI(WmsLogTag::WMS_UIEXT, "id: %{public}d", GetPersistentId());
if (notifyTransferComponentDataForResultFunc_) {
reWantParams = notifyTransferComponentDataForResultFunc_(wantParams);
return WSErrorCode::WS_OK;
}
return WSErrorCode::WS_ERROR_NOT_REGISTER_SYNC_CALLBACK;
}
void WindowExtensionSessionImpl::RegisterTransferComponentDataForResultListener(
const NotifyTransferComponentDataForResultFunc& func)
{
if (IsWindowSessionInvalid()) {
WLOGFE("session invalid.");
return;
}
notifyTransferComponentDataForResultFunc_ = std::move(func);
auto hostSession = GetHostSession();
CHECK_HOST_SESSION_RETURN_IF_NULL(hostSession);
hostSession->NotifySyncOn();
}
WMError WindowExtensionSessionImpl::RegisterHostWindowRectChangeListener(
const sptr<IWindowRectChangeListener>& listener)
{
AAFwk::Want dataToSend;
auto ret = SendExtensionMessageToHost(
static_cast<uint32_t>(Extension::Businesscode::REGISTER_HOST_WINDOW_RECT_CHANGE_LISTENER), dataToSend);
if (ret != WMError::WM_OK) {
return ret;
}
{
std::lock_guard<std::mutex> lockListener(hostWindowRectChangeListenerMutex_);
ret = RegisterListener(hostWindowRectChangeListener_, listener);
}
return ret;
}
WMError WindowExtensionSessionImpl::UnregisterHostWindowRectChangeListener(
const sptr<IWindowRectChangeListener>& listener)
{
WMError ret = WMError::WM_OK;
bool isHostWindowRectChangeListenerEmpty = false;
size_t hostWindowRectChangeListenerSize = 0;
{
std::lock_guard<std::mutex> lockListener(hostWindowRectChangeListenerMutex_);
ret = UnregisterListener(hostWindowRectChangeListener_, listener);
if (ret != WMError::WM_OK) {
return ret;
}
isHostWindowRectChangeListenerEmpty = hostWindowRectChangeListener_.empty();
hostWindowRectChangeListenerSize = hostWindowRectChangeListener_.size();
}
if (!isHostWindowRectChangeListenerEmpty || !rectChangeUIExtListenerIds_.empty()) {
TLOGI(WmsLogTag::WMS_UIEXT, "No need to send message to host to unregister, size of "
"hostWindowRectChangeListener_: %{public}zu, size of rectChangeUIExtListenerIds_: %{public}zu",
hostWindowRectChangeListenerSize, rectChangeUIExtListenerIds_.size());
return ret;
}
AAFwk::Want dataToSend;
ret = SendExtensionMessageToHost(
static_cast<uint32_t>(Extension::Businesscode::UNREGISTER_HOST_WINDOW_RECT_CHANGE_LISTENER), dataToSend);
return ret;
}
WMError WindowExtensionSessionImpl::RegisterRectChangeInGlobalDisplayListener(
const sptr<IRectChangeInGlobalDisplayListener>& listener, bool useHookedSize)
{
AAFwk::Want dataToSend;
auto ret = SendExtensionMessageToHost(
static_cast<uint32_t>(Extension::Businesscode::REGISTER_HOST_RECT_CHANGE_IN_GLOBAL_DISPLAY_LISTENER),
dataToSend);
if (ret != WMError::WM_OK) {
return ret;
}
{
std::lock_guard<std::mutex> lockListener(hostRectChangeInGlobalDisplayListenerMutex_);
ret = RegisterListener(hostRectChangeInGlobalDisplayListenerList_, listener);
}
return ret;
}
WMError WindowExtensionSessionImpl::UnregisterRectChangeInGlobalDisplayListener(
const sptr<IRectChangeInGlobalDisplayListener>& listener)
{
WMError ret = WMError::WM_OK;
bool needNotifyHost = false;
{
std::lock_guard<std::mutex> lockListener(hostRectChangeInGlobalDisplayListenerMutex_);
ret = UnregisterListener(hostRectChangeInGlobalDisplayListenerList_, listener);
if (ret != WMError::WM_OK) {
return ret;
}
needNotifyHost = hostRectChangeInGlobalDisplayListenerList_.empty() &&
rectChangeInGlobalDisplayUIExtListenerIds_.empty();
}
if (needNotifyHost) {
AAFwk::Want dataToSend;
ret = SendExtensionMessageToHost(
static_cast<uint32_t>(Extension::Businesscode::UNREGISTER_HOST_RECT_CHANGE_IN_GLOBAL_DISPLAY_LISTENER),
dataToSend);
}
TLOGI(WmsLogTag::WMS_UIEXT, "No need to send message to host to unregister, size of "
"listener: %{public}zu, size of rectChangeInGlobalDisplayUIExtListenerIds_: %{public}zu",
hostRectChangeInGlobalDisplayListenerList_.size(), rectChangeInGlobalDisplayUIExtListenerIds_.size());
return ret;
}
WMError WindowExtensionSessionImpl::RegisterKeyboardDidShowListener(const sptr<IKeyboardDidShowListener>& listener)
{
TLOGD(WmsLogTag::WMS_KEYBOARD, "in");
AAFwk::Want want;
auto ret = SendExtensionMessageToHost(
static_cast<uint32_t>(Extension::Businesscode::REGISTER_KEYBOARD_DID_SHOW_LISTENER), want);
if (ret != WMError::WM_OK) {
TLOGE(WmsLogTag::WMS_UIEXT, "Send register listener message failed, errCode: %{public}d", ret);
return ret;
}
std::lock_guard<std::mutex> lockListener(keyboardDidShowListenerMutex_);
ret = RegisterListener(keyboardDidShowListenerList_, listener);
return ret;
}
WMError WindowExtensionSessionImpl::UnregisterKeyboardDidShowListener(const sptr<IKeyboardDidShowListener>& listener)
{
TLOGD(WmsLogTag::WMS_KEYBOARD, "in");
WMError ret = WMError::WM_OK;
bool needNotifyHost = false;
{
std::lock_guard<std::mutex> lockListener(keyboardDidShowListenerMutex_);
ret = UnregisterListener(keyboardDidShowListenerList_, listener);
if (ret != WMError::WM_OK) {
return ret;
}
needNotifyHost = keyboardDidShowListenerList_.empty() && keyboardDidShowUIExtListeners_.empty();
}
if (needNotifyHost) {
AAFwk::Want want;
ret = SendExtensionMessageToHost(
static_cast<uint32_t>(Extension::Businesscode::UNREGISTER_KEYBOARD_DID_SHOW_LISTENER), want);
}
return ret;
}
WMError WindowExtensionSessionImpl::RegisterKeyboardDidHideListener(const sptr<IKeyboardDidHideListener>& listener)
{
TLOGD(WmsLogTag::WMS_KEYBOARD, "in");
AAFwk::Want want;
auto ret = SendExtensionMessageToHost(
static_cast<uint32_t>(Extension::Businesscode::REGISTER_KEYBOARD_DID_HIDE_LISTENER), want);
if (ret != WMError::WM_OK) {
TLOGE(WmsLogTag::WMS_UIEXT, "Send register listener message failed, errCode: %{public}d", ret);
return ret;
}
std::lock_guard<std::mutex> lockListener(keyboardDidHideListenerMutex_);
ret = RegisterListener(keyboardDidHideListenerList_, listener);
return ret;
}
WMError WindowExtensionSessionImpl::UnregisterKeyboardDidHideListener(const sptr<IKeyboardDidHideListener>& listener)
{
TLOGD(WmsLogTag::WMS_KEYBOARD, "in");
WMError ret = WMError::WM_OK;
bool needNotifyHost = false;
{
std::lock_guard<std::mutex> lockListener(keyboardDidHideListenerMutex_);
ret = UnregisterListener(keyboardDidHideListenerList_, listener);
if (ret != WMError::WM_OK) {
return ret;
}
needNotifyHost = keyboardDidHideListenerList_.empty() && keyboardDidHideUIExtListeners_.empty();
}
if (needNotifyHost) {
AAFwk::Want want;
ret = SendExtensionMessageToHost(
static_cast<uint32_t>(Extension::Businesscode::UNREGISTER_KEYBOARD_DID_HIDE_LISTENER), want);
}
return ret;
}
WMError WindowExtensionSessionImpl::RegisterTouchOutsideListener(const sptr<ITouchOutsideListener>& listener)
{
TLOGD(WmsLogTag::WMS_UIEXT, "in");
WMError ret = WMError::WM_OK;
auto persistentId = GetPersistentId();
{
std::lock_guard<std::mutex> lockListener(touchOutsideListenerMutex_);
ret = RegisterListener(touchOutsideListeners_[persistentId], listener);
if (ret != WMError::WM_OK) {
return ret;
}
}
AAFwk::Want want;
ret = SendExtensionMessageToHost(
static_cast<uint32_t>(Extension::Businesscode::REGISTER_TOUCH_OUTSIDE_LISTENER), want);
if (ret != WMError::WM_OK) {
TLOGE(WmsLogTag::WMS_UIEXT, "Send register listener message failed, errCode: %{public}d", ret);
return ret;
}
return ret;
}
WMError WindowExtensionSessionImpl::UnregisterTouchOutsideListener(const sptr<ITouchOutsideListener>& listener)
{
TLOGD(WmsLogTag::WMS_UIEXT, "in");
WMError ret = WMError::WM_OK;
bool needNotifyHost = false;
auto persistentId = GetPersistentId();
{
std::lock_guard<std::mutex> lockListener(touchOutsideListenerMutex_);
ret = UnregisterListener(touchOutsideListeners_[persistentId], listener);
if (ret != WMError::WM_OK) {
return ret;
}
needNotifyHost = touchOutsideListeners_[persistentId].empty() && touchOutsideUIExtListenerIds_.empty();
}
if (needNotifyHost) {
AAFwk::Want want;
ret = SendExtensionMessageToHost(
static_cast<uint32_t>(Extension::Businesscode::UNREGISTER_TOUCH_OUTSIDE_LISTENER), want);
}
return ret;
}
void WindowExtensionSessionImpl::TriggerBindModalUIExtension()
{
TLOGI(WmsLogTag::WMS_UIEXT, "id: %{public}d", GetPersistentId());
auto hostSession = GetHostSession();
CHECK_HOST_SESSION_RETURN_IF_NULL(hostSession);
hostSession->TriggerBindModalUIExtension();
}
WMError WindowExtensionSessionImpl::SetPrivacyMode(bool isPrivacyMode)
{
TLOGI(WmsLogTag::WMS_UIEXT, "Id: %{public}u, isPrivacyMode: %{public}u", GetPersistentId(),
isPrivacyMode);
if (surfaceNode_ == nullptr) {
TLOGE(WmsLogTag::WMS_UIEXT, "surfaceNode is nullptr");
return WMError::WM_ERROR_NULLPTR;
}
surfaceNode_->SetSecurityLayer(isPrivacyMode);
RSTransactionAdapter::FlushImplicitTransaction(surfaceNode_);
if (state_ != WindowState::STATE_SHOWN) {
extensionWindowFlags_.privacyModeFlag = isPrivacyMode;
return WMError::WM_OK;
}
if (isPrivacyMode == extensionWindowFlags_.privacyModeFlag) {
return WMError::WM_OK;
}
auto updateFlags = extensionWindowFlags_;
updateFlags.privacyModeFlag = isPrivacyMode;
ExtensionWindowFlags actions(0);
actions.privacyModeFlag = true;
auto ret = UpdateExtWindowFlags(updateFlags, actions);
if (ret == WMError::WM_OK) {
extensionWindowFlags_ = updateFlags;
}
return ret;
}
WMError WindowExtensionSessionImpl::HidePrivacyContentForHost(bool needHide)
{
auto persistentId = GetPersistentId();
std::stringstream ss;
ss << "ID: " << persistentId << ", needHide: " << needHide;
if (surfaceNode_ == nullptr) {
TLOGI(WmsLogTag::WMS_UIEXT, "surfaceNode is null, %{public}s", ss.str().c_str());
return WMError::WM_ERROR_NULLPTR;
}
auto errCode = surfaceNode_->SetHidePrivacyContent(needHide);
TLOGI(WmsLogTag::WMS_UIEXT, "Notify Render Service client finished, %{public}s, err: %{public}u", ss.str().c_str(),
errCode);
if (errCode == RSInterfaceErrorCode::NONSYSTEM_CALLING) {
return WMError::WM_ERROR_NOT_SYSTEM_APP;
} else if (errCode != RSInterfaceErrorCode::NO_ERROR) {
return WMError::WM_ERROR_SYSTEM_ABNORMALLY;
}
return WMError::WM_OK;
}
bool WindowExtensionSessionImpl::IsComponentFocused() const
{
if (IsWindowSessionInvalid() || focusState_ == std::nullopt) {
TLOGE(WmsLogTag::WMS_FOCUS, "Session is invalid");
return false;
}
TLOGD(WmsLogTag::WMS_FOCUS, "window id=%{public}d, isFocused=%{public}d",
GetPersistentId(), static_cast<int32_t>(focusState_.value()));
return focusState_.value();
}
void WindowExtensionSessionImpl::NotifyFocusStateEvent(bool focusState)
{
if (auto uiContent = GetUIContentSharedPtr()) {
focusState ? uiContent->Focus() : uiContent->UnFocus();
}
if (focusState) {
NotifyWindowAfterFocused();
} else {
NotifyWindowAfterUnfocused();
}
focusState_ = focusState;
if (focusState_ != std::nullopt) {
TLOGI(WmsLogTag::WMS_FOCUS, "[%{public}d,%{public}d]",
GetPersistentId(), static_cast<int32_t>(focusState_.value()));
}
}
void WindowExtensionSessionImpl::NotifyFocusActiveEvent(bool isFocusActive)
{
if (auto uiContent = GetUIContentSharedPtr()) {
uiContent->SetIsFocusActive(isFocusActive);
}
}
void WindowExtensionSessionImpl::NotifyBackpressedEvent(bool& isConsumed)
{
if (auto uiContent = GetUIContentSharedPtr()) {
WLOGFD("Transfer backpressed event to uiContent");
isConsumed = uiContent->ProcessBackPressed();
}
WLOGFD("Backpressed event is consumed %{public}d", isConsumed);
}
void WindowExtensionSessionImpl::InputMethodKeyEventResultCallback(const std::shared_ptr<MMI::KeyEvent>& keyEvent,
bool consumed, std::shared_ptr<std::promise<bool>> isConsumedPromise, std::shared_ptr<bool> isTimeout)
{
if (keyEvent == nullptr) {
WLOGFW("keyEvent is null, consumed:%{public}" PRId32, consumed);
if (isConsumedPromise != nullptr) {
isConsumedPromise->set_value(consumed);
}
return;
}
auto id = keyEvent->GetId();
if (isConsumedPromise == nullptr || isTimeout == nullptr) {
WLOGFW("Shared point isConsumedPromise or isTimeout is null, id:%{public}" PRId32, id);
keyEvent->MarkProcessed();
return;
}
if (*isTimeout) {
WLOGFW("DispatchKeyEvent timeout id:%{public}" PRId32, id);
keyEvent->MarkProcessed();
return;
}
if (consumed) {
isConsumedPromise->set_value(consumed);
WLOGD("Input method has processed key event, id:%{public}" PRId32, id);
return;
}
bool isConsumed = false;
DispatchKeyEventCallback(const_cast<std::shared_ptr<MMI::KeyEvent>&>(keyEvent), isConsumed);
isConsumedPromise->set_value(isConsumed);
}
void WindowExtensionSessionImpl::NotifyKeyEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent, bool& isConsumed,
bool notifyInputMethod)
{
if (keyEvent == nullptr) {
WLOGFE("keyEvent is nullptr");
return;
}
if (property_->GetUIExtensionUsage() == UIExtensionUsage::PREVIEW_EMBEDDED) {
TLOGD(WmsLogTag::WMS_EVENT, "Preview uiext does not handle event, eid:%{public}d", keyEvent->GetId());
return;
}
#ifdef IMF_ENABLE
bool isKeyboardEvent = IsKeyboardEvent(keyEvent);
if (isKeyboardEvent && notifyInputMethod) {
WLOGD("Async dispatch keyEvent to input method, id:%{public}" PRId32, keyEvent->GetId());
auto isConsumedPromise = std::make_shared<std::promise<bool>>();
auto isConsumedFuture = isConsumedPromise->get_future().share();
auto isTimeout = std::make_shared<bool>(false);
auto ret = MiscServices::InputMethodController::GetInstance()->DispatchKeyEvent(keyEvent,
[weakThis = wptr(this), isConsumedPromise, isTimeout](const std::shared_ptr<MMI::KeyEvent>& keyEvent,
bool consumed) {
auto window = weakThis.promote();
if (window == nullptr) {
TLOGNE(WmsLogTag::WMS_UIEXT, "window is nullptr");
return;
}
window->InputMethodKeyEventResultCallback(keyEvent, consumed, isConsumedPromise, isTimeout);
});
if (ret != 0) {
WLOGFW("DispatchKeyEvent failed, ret:%{public}" PRId32 ", id:%{public}" PRId32, ret, keyEvent->GetId());
DispatchKeyEventCallback(keyEvent, isConsumed);
return;
}
if (isConsumedFuture.wait_for(std::chrono::milliseconds(DISPATCH_KEY_EVENT_TIMEOUT_TIME_MS)) ==
std::future_status::timeout) {
*isTimeout = true;
isConsumed = true;
WLOGFE("DispatchKeyEvent timeout, id:%{public}" PRId32, keyEvent->GetId());
} else {
isConsumed = isConsumedFuture.get();
}
WLOGFD("Input Method DispatchKeyEvent isConsumed:%{public}" PRId32, isConsumed);
return;
}
#endif
DispatchKeyEventCallback(keyEvent, isConsumed);
}
void WindowExtensionSessionImpl::ArkUIFrameworkSupport()
{
uint32_t version = 0;
if ((context_ != nullptr) && (context_->GetApplicationInfo() != nullptr)) {
version = context_->GetApplicationInfo()->apiCompatibleVersion;
}
if (version < 10) {
SetLayoutFullScreenByApiVersion(isIgnoreSafeArea_);
if (!isSystembarPropertiesSet_) {
SetSystemBarProperty(WindowType::WINDOW_TYPE_STATUS_BAR, SystemBarProperty());
}
} else if (isIgnoreSafeAreaNeedNotify_) {
SetLayoutFullScreenByApiVersion(isIgnoreSafeArea_);
}
}
std::unique_ptr<Ace::UIContent> WindowExtensionSessionImpl::CreateUIContent(AppExecFwk::Ability* ability, void* env,
EnvironmentType envType)
{
if (envType == EnvironmentType::ANI) {
return ability != nullptr ? Ace::UIContent::Create(ability) :
Ace::UIContent::CreateWithAniEnv(GetContext().get(), reinterpret_cast<ani_env*>(env));
} else {
return ability != nullptr ? Ace::UIContent::Create(ability) :
Ace::UIContent::Create(GetContext().get(), reinterpret_cast<NativeEngine*>(env));
}
}
WMError WindowExtensionSessionImpl::NapiSetUIContent(const std::string& contentInfo, napi_env env, napi_value storage,
BackupAndRestoreType type, sptr<IRemoteObject> token, AppExecFwk::Ability* ability)
{
return SetUIContentInner(contentInfo, env, storage, token, ability, false, EnvironmentType::NAPI);
}
WMError WindowExtensionSessionImpl::AniSetUIContent(const std::string& contentInfo, ani_env* env, ani_object storage,
BackupAndRestoreType type, sptr<IRemoteObject> token, AppExecFwk::Ability* ability)
{
return SetUIContentInner(contentInfo, env, storage, token, ability, false, EnvironmentType::ANI);
}
WMError WindowExtensionSessionImpl::NapiSetUIContentByName(const std::string& contentName, napi_env env,
napi_value storage, BackupAndRestoreType type, sptr<IRemoteObject> token, AppExecFwk::Ability* ability)
{
TLOGI(WmsLogTag::WMS_UIEXT, "name: %{public}s", contentName.c_str());
return SetUIContentInner(contentName, env, storage, token, ability, true, EnvironmentType::NAPI);
}
WMError WindowExtensionSessionImpl::AniSetUIContentByName(const std::string& contentName, ani_env* env,
ani_object storage, BackupAndRestoreType type, sptr<IRemoteObject> token, AppExecFwk::Ability* ability)
{
TLOGI(WmsLogTag::WMS_UIEXT, "name: %{public}s", contentName.c_str());
return SetUIContentInner(contentName, env, storage, token, ability, true, EnvironmentType::ANI);
}
WMError WindowExtensionSessionImpl::SetUIContentInner(const std::string& contentInfo, void* env, void* storage,
sptr<IRemoteObject> token, AppExecFwk::Ability* ability, bool initByName, EnvironmentType envType)
{
WLOGFD("%{public}s state:%{public}u", contentInfo.c_str(), state_);
if (auto uiContent = GetUIContentSharedPtr()) {
uiContent->Destroy();
}
{
std::unique_ptr<Ace::UIContent> uiContent = CreateUIContent(ability, static_cast<void*>(env), envType);
if (uiContent == nullptr) {
WLOGFE("failed, id: %{public}d", GetPersistentId());
return WMError::WM_ERROR_NULLPTR;
}
uiContent->SetParentToken(token);
auto usage = property_->GetUIExtensionUsage();
if (usage == UIExtensionUsage::CONSTRAINED_EMBEDDED) {
uiContent->SetUIContentType(Ace::UIContentType::SECURITY_UI_EXTENSION);
} else if (usage == UIExtensionUsage::EMBEDDED) {
uiContent->SetUIContentType(Ace::UIContentType::UI_EXTENSION);
} else if (usage == UIExtensionUsage::MODAL) {
uiContent->SetUIContentType(Ace::UIContentType::MODAL_UI_EXTENSION);
} else if (usage == UIExtensionUsage::PREVIEW_EMBEDDED) {
uiContent->SetUIContentType(Ace::UIContentType::PREVIEW_UI_EXTENSION);
}
uiContent->SetHostParams(extensionConfig_);
if (initByName) {
if (envType == EnvironmentType::ANI) {
uiContent->InitializeByNameWithAniStorage(this, contentInfo, static_cast<ani_object>(storage),
property_->GetParentId());
} else {
uiContent->InitializeByName(this, contentInfo, static_cast<napi_value>(storage),
property_->GetParentId());
}
} else {
if (envType == EnvironmentType::ANI) {
uiContent->InitializeWithAniStorage(this, contentInfo, static_cast<ani_object>(storage),
property_->GetParentId());
} else {
uiContent->Initialize(this, contentInfo, static_cast<napi_value>(storage), property_->GetParentId());
}
}
std::unique_lock<std::shared_mutex> lock(uiContentMutex_);
uiContent_ = std::move(uiContent);
}
SetUIContentComplete();
NotifyModalUIExtensionMayBeCovered(true);
SetLayoutFullScreen(immersiveModeEnabled_);
UpdateAccessibilityTreeInfo();
std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
if (uiContent == nullptr) {
TLOGE(WmsLogTag::DEFAULT, "uiContent is nullptr.");
return WMError::WM_ERROR_NULLPTR;
}
if (focusState_ != std::nullopt) {
focusState_.value() ? uiContent->Focus() : uiContent->UnFocus();
}
ArkUIFrameworkSupport();
UpdateDecorEnable(true);
if (state_ == WindowState::STATE_SHOWN) {
uiContent->Foreground();
UpdateTitleButtonVisibility();
}
UpdateViewportConfig(GetRect(), WindowSizeChangeReason::UNDEFINED);
if (transparentUIExtensionFlag_) {
TLOGI(WmsLogTag::WMS_UIEXT, "set background to transparent, id:%{public}d", GetPersistentId());
SetBackgroundColor(TRANSPARENT_BACKGROUND_COLOR_HEX);
}
WLOGFD("notify uiContent window size change end");
return WMError::WM_OK;
}
WSError WindowExtensionSessionImpl::UpdateRect(const WSRect& rect, SizeChangeReason reason,
const SceneAnimationConfig& config, const std::map<AvoidAreaType, AvoidArea>& avoidAreas)
{
auto wmReason = static_cast<WindowSizeChangeReason>(reason);
Rect wmRect = {rect.posX_, rect.posY_, rect.width_, rect.height_};
auto preRect = GetRect();
if (rect.width_ == static_cast<int>(preRect.width_) && rect.height_ == static_cast<int>(preRect.height_)) {
WLOGFD("EQ [%{public}d, %{public}d, reason: %{public}d]", rect.width_,
rect.height_, static_cast<int>(reason));
} else {
WLOGFI("[%{public}d, %{public}d, reason: %{public}d]", rect.width_,
rect.height_, static_cast<int>(reason));
}
property_->SetWindowRect(wmRect);
if (property_->GetUIExtensionUsage() == UIExtensionUsage::MODAL) {
if (!abilityToken_) {
TLOGE(WmsLogTag::WMS_UIEXT, "token is nullptr");
return WSError::WS_ERROR_NULLPTR;
}
SingletonContainer::Get<WindowAdapter>().UpdateModalExtensionRect(abilityToken_, wmRect);
}
if (wmReason == WindowSizeChangeReason::ROTATION || wmReason == WindowSizeChangeReason::SNAPSHOT_ROTATION) {
const std::shared_ptr<RSTransaction>& rsTransaction = config.rsTransaction_;
UpdateRectForRotation(wmRect, preRect, wmReason, rsTransaction, avoidAreas);
} else if (handler_ != nullptr) {
UpdateRectForOtherReason(wmRect, wmReason, avoidAreas);
} else {
NotifySizeChange(wmRect, wmReason);
UpdateViewportConfig(wmRect, wmReason, nullptr, nullptr, avoidAreas);
}
return WSError::WS_OK;
}
void WindowExtensionSessionImpl::UpdateRectForRotation(const Rect& wmRect, const Rect& preRect,
WindowSizeChangeReason wmReason, const std::shared_ptr<RSTransaction>& rsTransaction,
const std::map<AvoidAreaType, AvoidArea>& avoidAreas)
{
if (!handler_) {
return;
}
auto task = [weak = wptr(this), wmReason, wmRect, preRect, rsTransaction, avoidAreas]() mutable {
HITRACE_METER_NAME(HITRACE_TAG_WINDOW_MANAGER, "WindowExtensionSessionImpl::UpdateRectForRotation");
auto window = weak.promote();
if (!window) {
return;
}
int32_t duration = UIEXTENTION_ROTATION_ANIMATION_TIME;
bool needSync = false;
if (rsTransaction && rsTransaction->GetSyncId() > 0) {
auto SyncTransactionPid = static_cast<int32_t>(rsTransaction->GetSyncId() >> 32);
if (rsTransaction->IsOpenSyncTransaction() || SyncTransactionPid != rsTransaction->GetParentPid()) {
needSync = true;
}
}
auto rsUIContext = window->GetRSUIContext();
if (needSync) {
window->UpdateRotateDuration(wmReason, duration, rsTransaction);
RSTransactionAdapter::FlushImplicitTransaction(rsUIContext);
RSAdapterUtil::SetRSTransactionHandler(rsTransaction, rsUIContext);
rsTransaction->Begin();
}
window->rotationAnimationCount_++;
auto rotationAnimationCallBackExecuted = std::make_shared<std::atomic_bool>(false);
auto handler = window->handler_;
RSAnimationTimingProtocol protocol;
protocol.SetDuration(duration);
auto curve = RSAnimationTimingCurve::CreateCubicCurve(0.2, 0.0, 0.2, 1.0);
RSNode::OpenImplicitAnimation(rsUIContext, protocol, curve, [weak, rotationAnimationCallBackExecuted]() {
auto window = weak.promote();
if (!window) {
return;
}
rotationAnimationCallBackExecuted->store(true);
window->rotationAnimationCount_--;
if (window->rotationAnimationCount_ == 0) {
window->NotifyRotationAnimationEnd();
}
});
window->StartRotationAnimationTimeoutTask(handler, rotationAnimationCallBackExecuted);
if (wmRect != preRect) {
window->NotifySizeChange(wmRect, wmReason);
}
window->UpdateViewportConfig(wmRect, wmReason, rsTransaction, nullptr, avoidAreas);
RSNode::CloseImplicitAnimation(rsUIContext);
if (needSync) {
rsTransaction->Commit();
} else {
RSTransactionAdapter::FlushImplicitTransaction(rsUIContext);
}
};
handler_->PostTask(task, "WMS_WindowExtensionSessionImpl_UpdateRectForRotation");
}
void WindowExtensionSessionImpl::UpdateRotateDuration(WindowSizeChangeReason& reason, int32_t& duration,
const std::shared_ptr<RSTransaction>& rsTransaction)
{
if (reason == WindowSizeChangeReason::SNAPSHOT_ROTATION) {
duration = rsTransaction->GetDuration();
reason = WindowSizeChangeReason::ROTATION;
} else {
duration = rsTransaction->GetDuration() ? rsTransaction->GetDuration() : duration;
}
}
void WindowExtensionSessionImpl::UpdateRectForOtherReason(const Rect& wmRect, WindowSizeChangeReason wmReason,
const std::map<AvoidAreaType, AvoidArea>& avoidAreas)
{
auto task = [weak = wptr(this), wmReason, wmRect, avoidAreas] {
auto window = weak.promote();
if (!window) {
TLOGE(WmsLogTag::WMS_LAYOUT, "window is null, updateViewPortConfig failed");
return;
}
window->NotifySizeChange(wmRect, wmReason);
window->UpdateViewportConfig(wmRect, wmReason, nullptr, nullptr, avoidAreas);
};
if (handler_) {
handler_->PostTask(task, "WMS_WindowExtensionSessionImpl_UpdateRectForOtherReason");
}
}
WMError WindowExtensionSessionImpl::GetSystemViewportConfig(SessionViewportConfig& config)
{
config.displayId_ = property_->GetDisplayId();
auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(config.displayId_);
if (display == nullptr) {
TLOGE(WmsLogTag::WMS_UIEXT, "display is null!");
return WMError::WM_ERROR_NULLPTR;
}
auto displayInfo = display->GetDisplayInfo();
if (displayInfo == nullptr) {
TLOGE(WmsLogTag::WMS_UIEXT, "displayInfo is null");
return WMError::WM_ERROR_NULLPTR;
}
config.density_ = GetDefaultDensity(displayInfo);
auto rotation = ONE_FOURTH_FULL_CIRCLE_DEGREE * static_cast<uint32_t>(displayInfo->GetOriginRotation());
auto deviceRotation = static_cast<uint32_t>(displayInfo->GetDefaultDeviceRotationOffset());
config.transform_ = (rotation + deviceRotation) % FULL_CIRCLE_DEGREE;
config.orientation_ = static_cast<int32_t>(displayInfo->GetDisplayOrientation());
return WMError::WM_OK;
}
void WindowExtensionSessionImpl::UpdateSystemViewportConfig()
{
if (!handler_) {
TLOGE(WmsLogTag::WMS_UIEXT, "handler_ is null");
return;
}
auto task = [weak = wptr(this)]() {
auto window = weak.promote();
if (!window) {
return;
}
if (window->isDensityCustomized_) {
TLOGNI(WmsLogTag::WMS_UIEXT, "UpdateSystemViewportConfig: Density is customized");
return;
}
if (window->isDensityFollowHost_) {
TLOGNW(WmsLogTag::WMS_UIEXT, "UpdateSystemViewportConfig: Density is follow host");
return;
}
SessionViewportConfig config;
if (window->GetSystemViewportConfig(config) != WMError::WM_OK) {
TLOGNE(WmsLogTag::WMS_UIEXT, "UpdateSystemViewportConfig: Get system viewportConfig failed");
return;
}
if (!MathHelper::NearZero(window->lastDensity_ - config.density_)) {
TLOGNI(WmsLogTag::WMS_UIEXT, "UpdateSystemViewportConfig: System density is changed");
window->UpdateSessionViewportConfig(config);
}
};
handler_->PostTask(task, "UpdateSystemViewportConfig");
}
WSError WindowExtensionSessionImpl::UpdateSessionViewportConfig(const SessionViewportConfig& config)
{
if (config.isDensityFollowHost_ && std::islessequal(config.density_, 0.0f)) {
TLOGE(WmsLogTag::WMS_UIEXT, "invalid density_: %{public}f", config.density_);
return WSError::WS_ERROR_INVALID_PARAM;
}
if (!handler_) {
TLOGE(WmsLogTag::WMS_UIEXT, "handler_ is null");
return WSError::WS_ERROR_NULLPTR;
}
auto task = [weak = wptr(this), config]() {
auto window = weak.promote();
if (!window) {
return;
}
auto viewportConfig = config;
window->UpdateExtensionDensity(viewportConfig);
TLOGNI(WmsLogTag::WMS_UIEXT, "UpdateSessionViewportConfig: Id:%{public}d, isDensityFollowHost_:%{public}d, "
"displayId:%{public}" PRIu64", density:%{public}f, lastDensity:%{public}f, orientation:%{public}d, "
"lastOrientation:%{public}d, isDensityCustomized:%{public}d",
window->GetPersistentId(), viewportConfig.isDensityFollowHost_, viewportConfig.displayId_,
viewportConfig.density_, window->lastDensity_, viewportConfig.orientation_, window->lastOrientation_,
window->isDensityCustomized_);
window->NotifyDisplayInfoChange(viewportConfig);
window->property_->SetDisplayId(viewportConfig.displayId_);
auto ret = window->UpdateSessionViewportConfigInner(viewportConfig);
if (ret == WSError::WS_OK) {
window->lastDensity_ = viewportConfig.density_;
window->lastOrientation_ = viewportConfig.orientation_;
window->lastDisplayId_ = viewportConfig.displayId_;
window->lastTransform_ = viewportConfig.transform_;
}
};
handler_->PostTask(task, "UpdateSessionViewportConfig");
return WSError::WS_OK;
}
WMError WindowExtensionSessionImpl::SetUIExtCustomDensity(const float density)
{
if (std::islessequal(density, 0.0f)) {
TLOGE(WmsLogTag::WMS_UIEXT, "Invalid density_: %{public}f", density);
return WMError::WM_ERROR_INVALID_PARAM;
}
if (!handler_) {
TLOGE(WmsLogTag::WMS_UIEXT, "handler_ is null");
return WMError::WM_ERROR_SYSTEM_ABNORMALLY;
}
auto task = [weak = wptr(this), density]() {
auto window = weak.promote();
if (!window) {
TLOGNE(WmsLogTag::WMS_UIEXT, "window is null");
return;
}
TLOGNI(WmsLogTag::WMS_UIEXT, "Customize density:%{public}f", density);
window->customizedDensity_ = density;
window->isDensityCustomized_ = true;
SessionViewportConfig config;
config.isDensityFollowHost_ = false;
config.density_ = density;
config.orientation_ = window->lastOrientation_;
config.displayId_ = window->lastDisplayId_;
config.transform_ = window->lastTransform_;
window->UpdateSessionViewportConfig(config);
};
handler_->PostTask(task, "SetUIExtCustomDensity");
return WMError::WM_OK;
}
void WindowExtensionSessionImpl::UpdateExtensionDensity(SessionViewportConfig& config)
{
TLOGD(WmsLogTag::WMS_UIEXT, "isFollowHost:%{public}d, densityValue:%{public}f,isDensityCustomized_:%{public}d, "
"customizedDensity:%{public}f", config.isDensityFollowHost_, config.density_, isDensityCustomized_,
customizedDensity_);
if (isDensityCustomized_) {
if (config.isDensityFollowHost_) {
hostDensityValue_ = config.density_;
}
config.density_ = customizedDensity_;
return;
}
isDensityFollowHost_ = config.isDensityFollowHost_;
if (config.isDensityFollowHost_) {
hostDensityValue_ = config.density_;
return;
}
auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(config.displayId_);
if (display == nullptr) {
TLOGE(WmsLogTag::WMS_UIEXT, "display is null!");
return;
}
auto displayInfo = display->GetDisplayInfo();
if (displayInfo == nullptr) {
TLOGE(WmsLogTag::WMS_UIEXT, "displayInfo is null");
return;
}
config.density_ = GetDefaultDensity(displayInfo);
}
void WindowExtensionSessionImpl::NotifyDisplayInfoChange(const SessionViewportConfig& config)
{
auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(config.displayId_);
if (display != nullptr) {
auto displayInfo = display->GetDisplayInfo();
if (displayInfo != nullptr && !MathHelper::NearZero(lastSystemDensity_ - displayInfo->GetVirtualPixelRatio())) {
auto density = displayInfo->GetVirtualPixelRatio();
lastSystemDensity_ = density;
NotifySystemDensityChange(density);
}
}
if (context_ == nullptr) {
TLOGE(WmsLogTag::WMS_UIEXT, "get token of window:%{public}d failed because of context is null.",
GetPersistentId());
return;
}
auto token = context_->GetToken();
if (token == nullptr) {
TLOGE(WmsLogTag::WMS_UIEXT, "get token of window:%{public}d failed.", GetPersistentId());
return;
}
if (config.displayId_ != lastDisplayId_) {
NotifyDisplayIdChange(config.displayId_);
}
SingletonContainer::Get<WindowManager>().NotifyDisplayInfoChange(
token, config.displayId_, config.density_, static_cast<DisplayOrientation>(config.orientation_));
}
WSError WindowExtensionSessionImpl::UpdateSessionViewportConfigInner(const SessionViewportConfig& config)
{
if (NearEqual(lastDensity_, config.density_) && lastOrientation_ == config.orientation_ &&
lastDisplayId_ == config.displayId_) {
TLOGI(WmsLogTag::WMS_UIEXT, "No parameters have changed, no need to update");
return WSError::WS_DO_NOTHING;
}
Ace::ViewportConfig viewportConfig;
auto rect = GetRect();
viewportConfig.SetSize(rect.width_, rect.height_);
viewportConfig.SetPosition(rect.posX_, rect.posY_);
viewportConfig.SetDensity(config.density_);
viewportConfig.SetOrientation(config.orientation_);
viewportConfig.SetTransformHint(config.transform_);
viewportConfig.SetDisplayId(config.displayId_);
std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
if (uiContent == nullptr) {
TLOGW(WmsLogTag::WMS_UIEXT, "uiContent is null!");
return WSError::WS_ERROR_NULLPTR;
}
float oldDensity = virtualPixelRatio_;
virtualPixelRatio_ = config.density_;
if (!NearEqual(oldDensity, config.density_)) {
NotifyWindowDensityChange(config.density_);
}
uiContent->UpdateViewportConfig(viewportConfig, WindowSizeChangeReason::UNDEFINED, nullptr, lastAvoidAreaMap_);
return WSError::WS_OK;
}
WSError WindowExtensionSessionImpl::NotifyAccessibilityHoverEvent(float pointX, float pointY, int32_t sourceType,
int32_t eventType, int64_t timeMs)
{
std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
if (uiContent == nullptr) {
WLOGFE("error, no uiContent");
return WSError::WS_ERROR_NO_UI_CONTENT_ERROR;
}
uiContent->HandleAccessibilityHoverEvent(pointX, pointY, sourceType, eventType, timeMs);
return WSError::WS_OK;
}
WMError WindowExtensionSessionImpl::TransferAccessibilityEvent(const Accessibility::AccessibilityEventInfo& info,
int64_t uiExtensionIdLevel)
{
if (IsWindowSessionInvalid()) {
WLOGFE("Window session invalid.");
return WMError::WM_ERROR_INVALID_WINDOW;
}
auto hostSession = GetHostSession();
CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
return static_cast<WMError>(hostSession->TransferAccessibilityEvent(info, uiExtensionIdLevel));
}
void WindowExtensionSessionImpl::NotifySessionForeground(uint32_t reason, bool withAnimation)
{
}
void WindowExtensionSessionImpl::NotifySessionBackground(uint32_t reason, bool withAnimation, bool isFromInnerkits)
{
}
void WindowExtensionSessionImpl::NotifyOccupiedAreaChangeInfo(sptr<OccupiedAreaChangeInfo> info,
const std::shared_ptr<RSTransaction>& rsTransaction,
const Rect& callingSessionRect, const std::map<AvoidAreaType, AvoidArea>& avoidAreas)
{
if (handler_ == nullptr) {
TLOGE(WmsLogTag::WMS_KEYBOARD, "handler is nullptr");
return;
}
auto task = [weak = wptr(this), info, rsTransaction, callingSessionRect, avoidAreas]() {
if (info != nullptr) {
TLOGNI(WmsLogTag::WMS_KEYBOARD, "TextFieldPosY: %{public}f, KeyBoardHeight: %{public}d",
info->textFieldPositionY_, info->rect_.height_);
}
auto window = weak.promote();
if (window == nullptr) {
TLOGNE(WmsLogTag::WMS_KEYBOARD, "window is nullptr, notify occupied area info failed");
return;
}
window->NotifyOccupiedAreaChange(info);
window->occupiedAreaInfo_ = info;
window->UpdateViewportConfig(
window->GetRect(), WindowSizeChangeReason::OCCUPIED_AREA_CHANGE, rsTransaction, nullptr, avoidAreas);
};
handler_->PostTask(task, "WMS_WindowExtensionSessionImpl_NotifyOccupiedAreaChangeInfo");
}
WMError WindowExtensionSessionImpl::RegisterOccupiedAreaChangeListener(
const sptr<IOccupiedAreaChangeListener>& listener)
{
std::lock_guard<std::mutex> lockListener(occupiedAreaChangeListenerMutex_);
return RegisterListener(occupiedAreaChangeListenerList_, listener);
}
WMError WindowExtensionSessionImpl::UnregisterOccupiedAreaChangeListener(
const sptr<IOccupiedAreaChangeListener>& listener)
{
std::lock_guard<std::mutex> lockListener(occupiedAreaChangeListenerMutex_);
return UnregisterListener(occupiedAreaChangeListenerList_, listener);
}
WMError WindowExtensionSessionImpl::GetAvoidAreaByType(AvoidAreaType type, AvoidArea& avoidArea,
const Rect& rect, int32_t apiVersion)
{
uint32_t currentApiVersion = GetTargetAPIVersionByApplicationInfo();
apiVersion = (apiVersion == API_VERSION_INVALID) ? static_cast<int32_t>(currentApiVersion) : apiVersion;
if (!IsFloatNavigationAvoidAreaEnabled(type)) {
TLOGI(WmsLogTag::WMS_IMMS, "win %{public}u type not supported", GetWindowId());
return WMError::WM_DO_NOTHING;
}
auto hostSession = GetHostSession();
CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
WSRect sessionRect = { rect.posX_, rect.posY_, rect.width_, rect.height_ };
avoidArea = hostSession->GetAvoidAreaByType(type, sessionRect, apiVersion);
TLOGI(WmsLogTag::WMS_IMMS, "win %{public}d type %{public}d api %{public}d area %{public}s",
GetPersistentId(), type, apiVersion, avoidArea.ToString().c_str());
return WMError::WM_OK;
}
WMError WindowExtensionSessionImpl::RegisterAvoidAreaChangeListener(const sptr<IAvoidAreaChangedListener>& listener)
{
return RegisterExtensionAvoidAreaChangeListener(listener);
}
WMError WindowExtensionSessionImpl::UnregisterAvoidAreaChangeListener(const sptr<IAvoidAreaChangedListener>& listener)
{
return UnregisterExtensionAvoidAreaChangeListener(listener);
}
WMError WindowExtensionSessionImpl::Show(uint32_t reason, bool withAnimation, bool withFocus,
int32_t requestId, int32_t scbRequestId)
{
return Show(reason, withAnimation, withFocus, false, requestId, scbRequestId);
}
WMError WindowExtensionSessionImpl::Show(uint32_t reason, bool withAnimation, bool withFocus, bool waitAttach,
int32_t requestId, int32_t scbRequestId)
{
CheckAndAddExtWindowFlags();
UpdateSystemViewportConfig();
WMError ret = WindowSessionImpl::Show(reason, withAnimation, withFocus, waitAttach, requestId, scbRequestId);
if (ret == WMError::WM_OK) {
RecordWindowLifecycleChange("show");
}
return ret;
}
WMError WindowExtensionSessionImpl::Hide(uint32_t reason, bool withAnimation, bool isFromInnerkits)
{
return Hide(reason, withAnimation, isFromInnerkits, false);
}
WMError WindowExtensionSessionImpl::Hide(uint32_t reason, bool withAnimation, bool isFromInnerkits, bool waitDetach)
{
TLOGI(WmsLogTag::WMS_LIFE, "id:%{public}d Hide, reason:%{public}u, state:%{public}u",
GetPersistentId(), reason, state_);
if (IsWindowSessionInvalid()) {
WLOGFE("session invalid");
return WMError::WM_ERROR_INVALID_WINDOW;
}
auto hostSession = GetHostSession();
CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
CheckAndRemoveExtWindowFlags();
if (state_ == WindowState::STATE_HIDDEN || state_ == WindowState::STATE_CREATED) {
TLOGD(WmsLogTag::WMS_LIFE, "already hidden [name:%{public}s, id:%{public}d, type: %{public}u]",
property_->GetWindowName().c_str(), GetPersistentId(), property_->GetWindowType());
NotifyBackgroundFailed(WMError::WM_DO_NOTHING);
return WMError::WM_OK;
}
WSError ret = hostSession->Background();
WMError res = static_cast<WMError>(ret);
if (res == WMError::WM_OK) {
StateChangeOption option(GetPersistentId(), WindowState::STATE_HIDDEN, reason, withAnimation, false, false,
isFromInnerkits, waitDetach);
UpdateSubWindowStateWithOptions(option);
state_ = WindowState::STATE_HIDDEN;
requestState_ = WindowState::STATE_HIDDEN;
NotifyAfterBackground();
RecordWindowLifecycleChange("hide");
} else {
TLOGD(WmsLogTag::WMS_LIFE, "window extension session Hide to Background error");
}
return WMError::WM_OK;
}
WSError WindowExtensionSessionImpl::NotifyDensityFollowHost(bool isFollowHost, float densityValue)
{
TLOGI(WmsLogTag::WMS_UIEXT, "isFollowHost:%{public}d densityValue:%{public}f", isFollowHost, densityValue);
if (!isFollowHost && !isDensityFollowHost_) {
TLOGI(WmsLogTag::WMS_UIEXT, "isFollowHost is false and not change");
return WSError::WS_OK;
}
if (isFollowHost) {
if (std::islessequal(densityValue, 0.0f)) {
TLOGE(WmsLogTag::WMS_UIEXT, "densityValue is invalid");
return WSError::WS_ERROR_INVALID_PARAM;
}
if (hostDensityValue_ != std::nullopt &&
std::abs(hostDensityValue_->load() - densityValue) < std::numeric_limits<float>::epsilon()) {
TLOGI(WmsLogTag::WMS_UIEXT, "densityValue not change");
return WSError::WS_OK;
}
hostDensityValue_ = densityValue;
}
isDensityFollowHost_ = isFollowHost;
UpdateViewportConfig(GetRect(), WindowSizeChangeReason::UNDEFINED);
return WSError::WS_OK;
}
float WindowExtensionSessionImpl::GetVirtualPixelRatio(const sptr<DisplayInfo>& displayInfo)
{
if (isDensityCustomized_) {
return customizedDensity_;
}
if (isDensityFollowHost_ && hostDensityValue_ != std::nullopt) {
return hostDensityValue_->load();
}
return GetDefaultDensity(displayInfo);
}
float WindowExtensionSessionImpl::GetDefaultDensity(const sptr<DisplayInfo>& displayInfo)
{
if (IsAdaptToSimulationScale()) {
TLOGD(WmsLogTag::WMS_COMPAT, "id:%{public}d scale mode", GetPersistentId());
return COMPACT_SIMULATION_SCALE_DPI;
}
float vpr = 1.0f;
if (displayInfo == nullptr) {
TLOGE(WmsLogTag::WMS_UIEXT, "displayInfo is nullptr");
return vpr;
}
return displayInfo->GetVirtualPixelRatio();
}
WMError WindowExtensionSessionImpl::CheckHideNonSecureWindowsPermission(bool shouldHide)
{
if ((property_->GetUIExtensionUsage() == UIExtensionUsage::MODAL ||
SessionHelper::IsSecureUIExtension(property_->GetUIExtensionUsage())) && !shouldHide) {
if (!SessionPermission::VerifyCallingPermission("ohos.permission.ALLOW_SHOW_NON_SECURE_WINDOWS")) {
extensionWindowFlags_.hideNonSecureWindowsFlag = true;
TLOGE(WmsLogTag::WMS_UIEXT, "Permission denied in %{public}s UIExtension.",
property_->GetUIExtensionUsage() == UIExtensionUsage::MODAL ? "modal" : "constrained embedded");
return WMError::WM_ERROR_INVALID_OPERATION;
}
if (modalUIExtensionMayBeCovered_) {
ReportModalUIExtensionMayBeCovered(modalUIExtensionSelfLoadContent_);
}
}
return WMError::WM_OK;
}
WMError WindowExtensionSessionImpl::HideNonSecureWindows(bool shouldHide)
{
TLOGI(WmsLogTag::WMS_UIEXT, "Id: %{public}u, shouldHide: %{public}u", GetPersistentId(), shouldHide);
WMError checkRet = CheckHideNonSecureWindowsPermission(shouldHide);
if (checkRet != WMError::WM_OK) {
return checkRet;
}
if (state_ != WindowState::STATE_SHOWN) {
extensionWindowFlags_.hideNonSecureWindowsFlag = shouldHide;
return WMError::WM_OK;
}
if (shouldHide == extensionWindowFlags_.hideNonSecureWindowsFlag) {
return WMError::WM_OK;
}
auto updateFlags = extensionWindowFlags_;
updateFlags.hideNonSecureWindowsFlag = shouldHide;
ExtensionWindowFlags actions(0);
actions.hideNonSecureWindowsFlag = true;
auto ret = UpdateExtWindowFlags(updateFlags, actions);
if (ret == WMError::WM_OK) {
extensionWindowFlags_ = updateFlags;
}
return ret;
}
WMError WindowExtensionSessionImpl::SetWaterMarkFlag(bool isEnable)
{
TLOGI(WmsLogTag::WMS_UIEXT, "Id: %{public}u, isEnable: %{public}u", GetPersistentId(), isEnable);
if (state_ != WindowState::STATE_SHOWN) {
extensionWindowFlags_.waterMarkFlag = isEnable;
return WMError::WM_OK;
}
if (isEnable == extensionWindowFlags_.waterMarkFlag) {
return WMError::WM_OK;
}
auto updateFlags = extensionWindowFlags_;
updateFlags.waterMarkFlag = isEnable;
ExtensionWindowFlags actions(0);
actions.waterMarkFlag = true;
auto ret = UpdateExtWindowFlags(updateFlags, actions);
if (ret == WMError::WM_OK) {
extensionWindowFlags_ = updateFlags;
}
return ret;
}
void WindowExtensionSessionImpl::CheckAndAddExtWindowFlags()
{
if (extensionWindowFlags_.bitData != 0) {
UpdateExtWindowFlags(extensionWindowFlags_, extensionWindowFlags_);
}
}
void WindowExtensionSessionImpl::CheckAndRemoveExtWindowFlags()
{
if (extensionWindowFlags_.bitData != 0) {
UpdateExtWindowFlags(ExtensionWindowFlags(), extensionWindowFlags_);
}
}
WSError WindowExtensionSessionImpl::NotifyAccessibilityChildTreeRegister(
uint32_t windowId, int32_t treeId, int64_t accessibilityId)
{
if (!handler_) {
return WSError::WS_ERROR_INTERNAL_ERROR;
}
auto uiContentSharedPtr = GetUIContentSharedPtr();
if (uiContentSharedPtr == nullptr) {
accessibilityChildTreeInfo_ = {
.windowId = windowId,
.treeId = treeId,
.accessibilityId = accessibilityId
};
TLOGD(WmsLogTag::WMS_UIEXT, "uiContent is null, save the accessibility child tree info.");
return WSError::WS_OK;
}
handler_->PostTask([uiContent = uiContentSharedPtr, windowId, treeId, accessibilityId]() {
if (uiContent == nullptr) {
TLOGNE(WmsLogTag::WMS_UIEXT, "NotifyAccessibilityChildTreeRegister error, no uiContent");
return;
}
TLOGND(WmsLogTag::WMS_UIEXT,
"NotifyAccessibilityChildTreeRegister: %{public}d %{public}" PRId64, treeId, accessibilityId);
uiContent->RegisterAccessibilityChildTree(windowId, treeId, accessibilityId);
});
return WSError::WS_OK;
}
WSError WindowExtensionSessionImpl::NotifyAccessibilityChildTreeUnregister()
{
if (!handler_) {
return WSError::WS_ERROR_INTERNAL_ERROR;
}
handler_->PostTask([uiContent = GetUIContentSharedPtr()]() {
if (uiContent == nullptr) {
TLOGNE(WmsLogTag::WMS_UIEXT, "NotifyAccessibilityChildTreeUnregister error, no uiContent");
return;
}
uiContent->DeregisterAccessibilityChildTree();
});
return WSError::WS_OK;
}
WSError WindowExtensionSessionImpl::NotifyAccessibilityDumpChildInfo(
const std::vector<std::string>& params, std::vector<std::string>& info)
{
if (!handler_) {
return WSError::WS_ERROR_INTERNAL_ERROR;
}
handler_->PostSyncTask([uiContent = GetUIContentSharedPtr(), params, &info]() {
if (uiContent == nullptr) {
TLOGNE(WmsLogTag::WMS_UIEXT, "NotifyAccessibilityDumpChildInfo error, no uiContent");
return;
}
uiContent->AccessibilityDumpChildInfo(params, info);
});
return WSError::WS_OK;
}
void WindowExtensionSessionImpl::UpdateAccessibilityTreeInfo()
{
if (accessibilityChildTreeInfo_ == std::nullopt) {
return;
}
std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
if (uiContent == nullptr) {
return;
}
uiContent->RegisterAccessibilityChildTree(accessibilityChildTreeInfo_->windowId,
accessibilityChildTreeInfo_->treeId, accessibilityChildTreeInfo_->accessibilityId);
accessibilityChildTreeInfo_.reset();
}
WMError WindowExtensionSessionImpl::UpdateExtWindowFlags(const ExtensionWindowFlags& flags,
const ExtensionWindowFlags& actions)
{
if (IsWindowSessionInvalid()) {
TLOGI(WmsLogTag::WMS_UIEXT, "session is invalid");
return WMError::WM_ERROR_INVALID_WINDOW;
}
if (!abilityToken_) {
TLOGE(WmsLogTag::WMS_UIEXT, "token is nullptr");
return WMError::WM_ERROR_NULLPTR;
}
return SingletonContainer::Get<WindowAdapter>().UpdateExtWindowFlags(abilityToken_, flags.bitData, actions.bitData);
}
Rect WindowExtensionSessionImpl::GetHostWindowRect(int32_t hostWindowId)
{
return GetHostWindowRect(hostWindowId, false);
}
Rect WindowExtensionSessionImpl::GetHostWindowRect(int32_t hostWindowId, bool useHookedSize)
{
Rect rect;
if (hostWindowId != property_->GetParentId()) {
TLOGE(WmsLogTag::WMS_UIEXT, "hostWindowId is invalid");
return rect;
}
SingletonContainer::Get<WindowAdapter>().GetHostWindowRect(hostWindowId, rect, useHookedSize);
return rect;
}
WMError WindowExtensionSessionImpl::GetGlobalScaledRect(Rect& globalScaledRect, bool useHookedSize)
{
return SingletonContainer::Get<WindowAdapter>().GetHostGlobalScaledRect(
property_->GetParentId(), globalScaledRect, useHookedSize);
}
WMError WindowExtensionSessionImpl::GetGestureBackEnabled(bool& enable) const
{
enable = hostGestureBackEnabled_;
return WMError::WM_OK;
}
WMError WindowExtensionSessionImpl::SetGestureBackEnabled(bool enable)
{
AAFwk::WantParams want;
want.SetParam(Extension::ATOMICSERVICE_KEY_FUNCTION, AAFwk::String::Box("setGestureBackEnabled"));
want.SetParam(Extension::ATOMICSERVICE_KEY_PARAM_ENABLE, AAFwk::Boolean::Box(enable));
if (TransferExtensionData(want) != WMError::WM_OK) {
TLOGE(WmsLogTag::WMS_UIEXT, "send failed");
return WMError::WM_ERROR_IPC_FAILED;
}
return WMError::WM_OK;
}
WMError WindowExtensionSessionImpl::SetLayoutFullScreen(bool status)
{
TLOGI(WmsLogTag::WMS_IMMS, "win [%{public}u %{public}s] status %{public}d",
GetWindowId(), GetWindowName().c_str(), static_cast<int32_t>(status));
if (IsWindowSessionInvalid()) {
return WMError::WM_ERROR_INVALID_WINDOW;
}
if (auto hostSession = GetHostSession()) {
hostSession->OnLayoutFullScreenChange(status);
}
property_->SetIsLayoutFullScreen(status);
isIgnoreSafeArea_ = status;
isIgnoreSafeAreaNeedNotify_ = true;
immersiveModeEnabled_ = status;
if (auto uiContent = GetUIContentSharedPtr()) {
uiContent->SetIgnoreViewSafeArea(status);
}
return WMError::WM_OK;
}
WMError WindowExtensionSessionImpl::UpdateSystemBarProperties(
const std::unordered_map<WindowType, SystemBarProperty>& systemBarProperties,
const std::unordered_map<WindowType, SystemBarPropertyFlag>& systemBarPropertyFlags)
{
AAFwk::WantParams want;
want.SetParam(Extension::ATOMICSERVICE_KEY_FUNCTION, AAFwk::String::Box("setWindowSystemBarEnable"));
want.SetParam(Extension::ATOMICSERVICE_KEY_PARAM_STATUS,
AAFwk::Boolean::Box(systemBarProperties.at(WindowType::WINDOW_TYPE_STATUS_BAR).enable_));
want.SetParam(Extension::ATOMICSERVICE_KEY_PARAM_NAVIGATION,
AAFwk::Boolean::Box(systemBarProperties.at(WindowType::WINDOW_TYPE_NAVIGATION_BAR).enable_));
if (TransferExtensionData(want) != WMError::WM_OK) {
TLOGE(WmsLogTag::WMS_UIEXT, "send failed");
return WMError::WM_ERROR_IPC_FAILED;
}
return WMError::WM_OK;
}
WMError WindowExtensionSessionImpl::UpdateHostSpecificSystemBarEnabled(const std::string& name, bool enable,
bool enableAnimation)
{
AAFwk::WantParams want;
want.SetParam(Extension::ATOMICSERVICE_KEY_FUNCTION, AAFwk::String::Box("setSpecificSystemBarEnabled"));
want.SetParam(Extension::ATOMICSERVICE_KEY_PARAM_NAME, AAFwk::String::Box(name));
want.SetParam(Extension::ATOMICSERVICE_KEY_PARAM_ENABLE, AAFwk::Boolean::Box(enable));
want.SetParam(Extension::ATOMICSERVICE_KEY_PARAM_ENABLEANIMATION, AAFwk::Boolean::Box(enableAnimation));
if (TransferExtensionData(want) != WMError::WM_OK) {
TLOGE(WmsLogTag::WMS_UIEXT, "send failed");
return WMError::WM_ERROR_IPC_FAILED;
}
return WMError::WM_OK;
}
bool WindowExtensionSessionImpl::GetImmersiveModeEnabledState() const
{
return immersiveModeEnabled_;
}
WMError WindowExtensionSessionImpl::SetImmersiveModeEnabledState(bool enable)
{
return SetLayoutFullScreen(enable);
}
WMError WindowExtensionSessionImpl::ExtensionSetKeepScreenOn(bool keepScreenOn)
{
AAFwk::WantParams want;
want.SetParam(Extension::ATOMICSERVICE_KEY_FUNCTION, AAFwk::String::Box("setWindowKeepScreenOn"));
want.SetParam(Extension::ATOMICSERVICE_KEY_PARAM_ISKEEPSCREENON, AAFwk::Boolean::Box(keepScreenOn));
if (TransferExtensionData(want) != WMError::WM_OK) {
TLOGE(WmsLogTag::WMS_UIEXT, "send failed");
return WMError::WM_ERROR_IPC_FAILED;
}
return WMError::WM_OK;
}
WMError WindowExtensionSessionImpl::ExtensionSetBrightness(float brightness)
{
AAFwk::WantParams want;
want.SetParam(Extension::ATOMICSERVICE_KEY_FUNCTION, AAFwk::String::Box("setWindowBrightness"));
want.SetParam(Extension::ATOMICSERVICE_KEY_PARAM_BRIGHTNESS, AAFwk::Float::Box(brightness));
if (TransferExtensionData(want) != WMError::WM_OK) {
TLOGE(WmsLogTag::WMS_UIEXT, "send failed");
return WMError::WM_ERROR_IPC_FAILED;
}
return WMError::WM_OK;
}
WMError WindowExtensionSessionImpl::GetWindowStateSnapshot(std::string& winStateSnapshotJsonStr)
{
auto persistentId = GetPersistentId();
nlohmann::json winStateSnapshotJson = {
{"isPcMode", system::GetBoolParameter("persist.sceneboard.ispcmode", false)},
};
winStateSnapshotJsonStr = winStateSnapshotJson.dump();
auto hostWinId = property_->GetParentId();
auto errCode = SingletonContainer::Get<WindowAdapter>().GetWindowStateSnapshot(hostWinId,
winStateSnapshotJsonStr);
if (errCode != WMError::WM_OK) {
TLOGE(WmsLogTag::WMS_ATTRIBUTE, "ipc failed: winId=%{public}d, hostWinId=%{public}d, retCode=%{public}d",
persistentId, hostWinId, static_cast<int32_t>(errCode));
return WMError::WM_ERROR_SYSTEM_ABNORMALLY;
}
TLOGD(WmsLogTag::WMS_ATTRIBUTE, "ext winId=%{public}d, hostWinId=%{public}d, winStateSnapshot=%{public}s",
persistentId, hostWinId, winStateSnapshotJsonStr.c_str());
return WMError::WM_OK;
}
WMError WindowExtensionSessionImpl::SetStatusBarColorForExtension(uint32_t color)
{
TLOGI(WmsLogTag::WMS_UIEXT, "id=%{public}d", GetPersistentId());
WMError ret = SetStatusBarColorForExtensionInner(color);
if (ret == WMError::WM_OK) {
systemBarSettingFlag_ = SystemBarSettingFlag::COLOR_SETTING;
}
return ret;
}
WMError WindowExtensionSessionImpl::SetStatusBarColorForExtensionInner(uint32_t color)
{
TLOGD(WmsLogTag::WMS_UIEXT, "id=%{public}d", GetPersistentId());
AAFwk::WantParams want;
want.SetParam(Extension::ATOMICSERVICE_KEY_FUNCTION, AAFwk::String::Box("setStatusBarColor"));
want.SetParam(Extension::ATOMICSERVICE_KEY_PARAM_COLOR_NUMERIC, AAFwk::Long::Box(color));
if (TransferExtensionData(want) != WMError::WM_OK) {
TLOGE(WmsLogTag::WMS_UIEXT, "send failed");
return WMError::WM_ERROR_IPC_FAILED;
}
return WMError::WM_OK;
}
bool WindowExtensionSessionImpl::IsBlockSubwindow() const
{
return isBlockSubwindow_;
}
void WindowExtensionSessionImpl::ConsumePointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
{
if (pointerEvent == nullptr) {
TLOGE(WmsLogTag::WMS_EVENT, "PointerEvent is nullptr, windowId: %{public}d", GetWindowId());
return;
}
if (property_->GetUIExtensionUsage() == UIExtensionUsage::PREVIEW_EMBEDDED) {
TLOGD(WmsLogTag::WMS_EVENT, "Preview uiext does not handle event, eid:%{public}d", pointerEvent->GetId());
return;
}
if (hostSession_ == nullptr) {
TLOGE(WmsLogTag::WMS_EVENT, "hostSession is nullptr, windowId: %{public}d", GetWindowId());
pointerEvent->MarkProcessed();
return;
}
MMI::PointerEvent::PointerItem pointerItem;
if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
TLOGW(WmsLogTag::WMS_EVENT, "invalid pointerEvent, windowId: %{public}d", GetWindowId());
pointerEvent->MarkProcessed();
return;
}
auto action = pointerEvent->GetPointerAction();
bool isPointDown = (action == MMI::PointerEvent::POINTER_ACTION_DOWN ||
action == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN);
if ((property_->GetUIExtensionUsage() == UIExtensionUsage::MODAL) && isPointDown) {
if (!abilityToken_) {
TLOGE(WmsLogTag::WMS_UIEXT, "token is nullptr");
return;
}
SingletonContainer::Get<WindowAdapter>().ProcessModalExtensionPointDown(abilityToken_,
pointerItem.GetDisplayX(), pointerItem.GetDisplayY());
}
if (action != MMI::PointerEvent::POINTER_ACTION_MOVE) {
TLOGI(WmsLogTag::WMS_EVENT, "eid:%{public}d,wid:%{public}u,"
"pointId:%{public}d,sourceType:%{public}d", pointerEvent->GetId(), GetWindowId(),
pointerEvent->GetPointerId(), pointerEvent->GetSourceType());
}
NotifyPointerEvent(pointerEvent);
}
void WindowExtensionSessionImpl::NotifyPointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
{
if (pointerEvent == nullptr) {
TLOGE(WmsLogTag::WMS_EVENT, "pointerEvent is nullptr, windowId: %{public}d", GetWindowId());
return;
}
WindowSessionImpl::NotifyPointerEvent(pointerEvent);
if (!IsWindowDelayRaiseEnabled()) {
return;
}
std::shared_ptr<MMI::PointerEvent> pointerEventBackup;
if (pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN) {
pointerEventBackup = std::make_shared<MMI::PointerEvent>(*pointerEvent);
} else {
pointerEventBackup = pointerEvent;
}
auto uiContent = GetUIContentSharedPtr();
if (uiContent == nullptr) {
TLOGE(WmsLogTag::WMS_UIEXT, "uiContent is null!");
return;
}
uiContent->ProcessPointerEvent(pointerEvent,
[weakThis = wptr(this), pointerEventBackup](bool isHitTargetDraggable) mutable {
auto window = weakThis.promote();
if (window == nullptr) {
TLOGNE(WmsLogTag::WMS_UIEXT, "window is null!");
return;
}
window->ProcessPointerEventWithHostWindowDelayRaise(pointerEventBackup, isHitTargetDraggable);
});
}
void WindowExtensionSessionImpl::ProcessPointerEventWithHostWindowDelayRaise(
const std::shared_ptr<MMI::PointerEvent>& pointerEvent, bool isHitTargetDraggable) const
{
if (pointerEvent == nullptr) {
TLOGE(WmsLogTag::WMS_EVENT, "pointerEvent is nullptr, windowId: %{public}d", GetWindowId());
return;
}
const int32_t action = pointerEvent->GetPointerAction();
bool isPointerButtonDown = (action == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN);
bool isPointerUp = (action == MMI::PointerEvent::POINTER_ACTION_BUTTON_UP ||
action == MMI::PointerEvent::POINTER_ACTION_PULL_UP);
if (!isPointerButtonDown && !isPointerUp) {
return;
}
bool needNotifyHostWindowToRaise = isPointerUp || !isHitTargetDraggable;
if (needNotifyHostWindowToRaise) {
auto businessCode = Extension::Businesscode::NOTIFY_HOST_WINDOW_TO_RAISE;
AAFwk::Want dataToSend;
if (SendExtensionMessageToHost(static_cast<uint32_t>(businessCode), dataToSend) != WMError::WM_OK) {
return;
}
TLOGI(WmsLogTag::WMS_UIEXT, "Notify host window to raise, id: %{public}d, isHitTargetDraggable: %{public}d, "
"isPointerUp: %{public}d", GetPersistentId(), isHitTargetDraggable, isPointerUp);
return;
}
TLOGI(WmsLogTag::WMS_UIEXT, "No need to notify host window to raise, id: %{public}d, isHitTargetDraggable: "
"%{public}d, isPointerUp: %{public}d", GetPersistentId(), isHitTargetDraggable, isPointerUp);
}
bool WindowExtensionSessionImpl::PreNotifyKeyEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent)
{
if (keyEvent == nullptr) {
TLOGE(WmsLogTag::WMS_EVENT, "keyEvent is nullptr");
return false;
}
if (property_->GetUIExtensionUsage() == UIExtensionUsage::PREVIEW_EMBEDDED) {
TLOGD(WmsLogTag::WMS_EVENT, "Preview uiext does not handle event, eid:%{public}d", keyEvent->GetId());
return false;
}
RefreshNoInteractionTimeoutMonitor();
if (property_->GetUIExtensionUsage() == UIExtensionUsage::CONSTRAINED_EMBEDDED) {
if (focusState_ == std::nullopt) {
TLOGW(WmsLogTag::WMS_EVENT, "focusState is null");
keyEvent->MarkProcessed();
return true;
}
if (!focusState_.value()) {
keyEvent->MarkProcessed();
return true;
}
TLOGI(WmsLogTag::WMS_EVENT, "eid:%{public}d wid:%{public}d",
keyEvent->GetId(), keyEvent->GetAgentWindowId());
}
if (auto uiContent = GetUIContentSharedPtr()) {
TLOGD(WmsLogTag::WMS_EVENT, "Start to process keyEvent, id: %{public}d", keyEvent->GetId());
return uiContent->ProcessKeyEvent(keyEvent, true);
}
return false;
}
bool WindowExtensionSessionImpl::GetFreeMultiWindowModeEnabledState()
{
bool enable = false;
SingletonContainer::Get<WindowAdapter>().GetFreeMultiWindowEnableState(enable);
TLOGI(WmsLogTag::WMS_MULTI_WINDOW, "enable=%{public}u", enable);
return enable;
}
void WindowExtensionSessionImpl::NotifyExtensionTimeout(int32_t errorCode)
{
auto hostSession = GetHostSession();
CHECK_HOST_SESSION_RETURN_IF_NULL(hostSession);
hostSession->NotifyExtensionTimeout(errorCode);
}
int32_t WindowExtensionSessionImpl::GetRealParentId() const
{
return property_->GetRealParentId();
}
int32_t WindowExtensionSessionImpl::GetHostWindowId() const
{
return property_->GetParentId();
}
WindowType WindowExtensionSessionImpl::GetParentWindowType() const
{
return property_->GetParentWindowType();
}
WMError WindowExtensionSessionImpl::GetWindowPropertyInfo(WindowPropertyInfo& windowPropertyInfo, bool useHookedSize)
{
if (IsWindowSessionInvalid()) {
TLOGE(WmsLogTag::WMS_UIEXT, "window session is invalid");
return WMError::WM_ERROR_INVALID_WINDOW;
}
windowPropertyInfo.windowRect = GetRect();
windowPropertyInfo.type = GetType();
windowPropertyInfo.isLayoutFullScreen = IsLayoutFullScreen();
windowPropertyInfo.isFullScreen = IsFullScreen();
windowPropertyInfo.isTouchable = GetTouchable();
windowPropertyInfo.isFocusable = GetFocusable();
windowPropertyInfo.name = GetWindowName();
windowPropertyInfo.isPrivacyMode = IsPrivacyMode();
windowPropertyInfo.isKeepScreenOn = IsKeepScreenOn();
windowPropertyInfo.brightness = GetBrightness();
windowPropertyInfo.isTransparent = IsTransparent();
windowPropertyInfo.id = GetWindowId();
TLOGD(WmsLogTag::WMS_UIEXT, "winId=%{public}u", GetWindowId());
return WMError::WM_OK;
}
void WindowExtensionSessionImpl::NotifyModalUIExtensionMayBeCovered(bool byLoadContent)
{
if (property_->GetUIExtensionUsage() != UIExtensionUsage::MODAL &&
!SessionHelper::IsSecureUIExtension(property_->GetUIExtensionUsage())) {
return;
}
modalUIExtensionMayBeCovered_ = true;
if (byLoadContent) {
modalUIExtensionSelfLoadContent_ = true;
}
if (extensionWindowFlags_.hideNonSecureWindowsFlag) {
return;
}
ReportModalUIExtensionMayBeCovered(byLoadContent);
}
void WindowExtensionSessionImpl::ReportModalUIExtensionMayBeCovered(bool byLoadContent) const
{
TLOGW(WmsLogTag::WMS_UIEXT, "Id=%{public}d", GetPersistentId());
std::ostringstream oss;
oss << "Modal UIExtension may be covered uid: " << getuid();
oss << ", windowName: " << property_->GetWindowName();
if (context_) {
oss << ", bundleName: " << context_->GetBundleName();
}
auto type = byLoadContent ? WindowDFXHelperType::WINDOW_MODAL_UIEXTENSION_UICONTENT_CHECK :
WindowDFXHelperType::WINDOW_MODAL_UIEXTENSION_SUBWINDOW_CHECK;
SingletonContainer::Get<WindowInfoReporter>().ReportWindowException(static_cast<int32_t>(type), getpid(),
oss.str());
}
void WindowExtensionSessionImpl::NotifyExtensionEventAsync(uint32_t notifyEvent)
{
TLOGD(WmsLogTag::WMS_UIEXT, "notifyEvent:%{public}d", notifyEvent);
if (IsWindowSessionInvalid()) {
TLOGE(WmsLogTag::WMS_UIEXT, "Window session invalid.");
return;
}
auto hostSession = GetHostSession();
CHECK_HOST_SESSION_RETURN_IF_NULL(hostSession);
hostSession->NotifyExtensionEventAsync(notifyEvent);
}
WSError WindowExtensionSessionImpl::NotifyDumpInfo(const std::vector<std::string>& params,
std::vector<std::string>& info)
{
TLOGI(WmsLogTag::WMS_UIEXT, "persistentId: %{public}d", GetPersistentId());
auto uiContentSharedPtr = GetUIContentSharedPtr();
if (uiContentSharedPtr == nullptr) {
TLOGE(WmsLogTag::WMS_UIEXT, "uiContent is nullptr");
return WSError::WS_ERROR_NULLPTR;
}
uiContentSharedPtr->DumpInfo(params, info);
if (!SessionPermission::IsBetaVersion()) {
TLOGW(WmsLogTag::WMS_UIEXT, "is not beta version, persistentId: %{public}d", GetPersistentId());
info.clear();
}
return WSError::WS_OK;
}
WSError WindowExtensionSessionImpl::SetUIExtensionTransparent()
{
TLOGI(WmsLogTag::WMS_UIEXT, "in");
if (!SessionPermission::IsSystemCalling()) {
TLOGE(WmsLogTag::WMS_UIEXT, "permission denied!");
return WSError::WS_ERROR_NOT_SYSTEM_APP;
}
transparentUIExtensionFlag_ = true;
if (auto uiContent = GetUIContentSharedPtr()) {
TLOGI(WmsLogTag::WMS_UIEXT, "set background to transparent, id:%{public}d", GetPersistentId());
SetBackgroundColor(TRANSPARENT_BACKGROUND_COLOR_HEX);
}
return WSError::WS_OK;
}
bool WindowExtensionSessionImpl::IsPcWindow() const
{
bool isPcWindow = false;
WMError ret = SingletonContainer::Get<WindowAdapter>().IsPcWindow(isPcWindow);
if (ret != WMError::WM_OK) {
TLOGE(WmsLogTag::WMS_UIEXT, "can't find isPcWindow, err: %{public}u",
static_cast<uint32_t>(ret));
}
return isPcWindow;
}
bool WindowExtensionSessionImpl::IsPcOrPadFreeMultiWindowMode() const
{
bool isPcOrPadFreeMultiWindowMode = false;
WMError ret = SingletonContainer::Get<WindowAdapter>().IsPcOrPadFreeMultiWindowMode(isPcOrPadFreeMultiWindowMode);
if (ret != WMError::WM_OK) {
TLOGE(WmsLogTag::WMS_UIEXT, "cant't find isPcOrPadFreeMultiWindowMode, err: %{public}u",
static_cast<uint32_t>(ret));
}
return isPcOrPadFreeMultiWindowMode;
}
WSError WindowExtensionSessionImpl::SendExtensionData(MessageParcel& data, MessageParcel& reply,
[[maybe_unused]] MessageOption& option)
{
TLOGD(WmsLogTag::WMS_UIEXT, "id=%{public}d", GetPersistentId());
dataHandler_->NotifyDataConsumer(data, reply);
return WSError::WS_OK;
}
WindowMode WindowExtensionSessionImpl::GetWindowMode() const
{
return property_->GetWindowMode();
}
WindowMode WindowExtensionSessionImpl::GetWindowModeCompat() const
{
return property_->GetWindowModeCompat();
}
void WindowExtensionSessionImpl::UpdateExtensionConfig(const std::shared_ptr<AAFwk::Want>& want)
{
if (want == nullptr) {
TLOGE(WmsLogTag::WMS_UIEXT, "null want ptr");
return;
}
const auto& configParam = want->GetParams().GetWantParams(Extension::UIEXTENSION_CONFIG_FIELD);
auto state = configParam.GetIntParam(Extension::CROSS_AXIS_FIELD, 0);
if (IsValidCrossState(state)) {
crossAxisState_ = static_cast<CrossAxisState>(state);
}
auto waterfallModeValue = configParam.GetIntParam(Extension::WATERFALL_MODE_FIELD, 0);
isFullScreenWaterfallMode_.store(static_cast<bool>(waterfallModeValue));
isValidWaterfallMode_.store(true);
hostGestureBackEnabled_ = static_cast<bool>(configParam.GetIntParam(Extension::GESTURE_BACK_ENABLED, 1));
auto isHostWindowDelayRaiseEnabled = configParam.GetIntParam(Extension::HOST_WINDOW_DELAY_RAISE_STATE_FIELD, 0);
property_->SetWindowDelayRaiseEnabled(static_cast<bool>(isHostWindowDelayRaiseEnabled));
extensionConfig_ = AAFwk::WantParams(configParam);
if (auto uiContent = GetUIContentSharedPtr()) {
uiContent->SetHostParams(extensionConfig_);
}
want->RemoveParam(Extension::UIEXTENSION_CONFIG_FIELD);
auto rootHostWindowType =
static_cast<WindowType>(configParam.GetIntParam(Extension::ROOT_HOST_WINDOW_TYPE_FIELD, 0));
SetRootHostWindowType(rootHostWindowType);
SetCompatInfo(configParam);
auto hostWindowStatus = static_cast<WindowStatus>(configParam.GetIntParam(Extension::HOST_WINDOW_STATUS_FIELD,
static_cast<int32_t>(WindowStatus::WINDOW_STATUS_UNDEFINED)));
hostWindowStatus_ = hostWindowStatus;
TLOGI(WmsLogTag::WMS_ATTRIBUTE, "CrossAxisState: %{public}d, waterfall: %{public}d, "
"rootHostWindowType: %{public}u, isHostWindowDelayRaiseEnabled: %{public}d, "
"hostWindowStatus: %{public}u, winId: %{public}u",
state, isFullScreenWaterfallMode_.load(), rootHostWindowType,
isHostWindowDelayRaiseEnabled, hostWindowStatus, GetWindowId());
}
WMError WindowExtensionSessionImpl::SendExtensionMessageToHost(uint32_t code, const AAFwk::Want& data) const
{
auto dataHandler = GetExtensionDataHandler();
if (dataHandler == nullptr) {
TLOGE(WmsLogTag::WMS_UIEXT, "dataHandler_ is nullptr!");
return WMError::WM_ERROR_INVALID_PARAM;
}
auto sendResult = dataHandler->SendDataAsync(SubSystemId::ARKUI_UIEXT, code, data);
if (sendResult == DataHandlerErr::OK) {
return WMError::WM_OK;
}
TLOGE(WmsLogTag::WMS_UIEXT, "SendDataAsync failed, businessCode: %{public}u, errCode: %{public}u", code,
sendResult);
return WMError::WM_ERROR_IPC_FAILED;
}
WMError WindowExtensionSessionImpl::OnExtensionMessage(uint32_t code, int32_t persistentId, const AAFwk::Want& data)
{
switch (code) {
case static_cast<uint32_t>(Extension::Businesscode::NOTIFY_HOST_WINDOW_TO_RAISE): {
return HandleHostWindowRaise(code, persistentId, data);
}
case static_cast<uint32_t>(Extension::Businesscode::REGISTER_HOST_WINDOW_RECT_CHANGE_LISTENER): {
return HandleRegisterHostWindowRectChangeListener(code, persistentId, data);
}
case static_cast<uint32_t>(Extension::Businesscode::UNREGISTER_HOST_WINDOW_RECT_CHANGE_LISTENER): {
return HandleUnregisterHostWindowRectChangeListener(code, persistentId, data);
}
case static_cast<uint32_t>(Extension::Businesscode::REGISTER_KEYBOARD_DID_SHOW_LISTENER): {
return HandleUIExtRegisterKeyboardDidShowListener(code, persistentId, data);
}
case static_cast<uint32_t>(Extension::Businesscode::UNREGISTER_KEYBOARD_DID_SHOW_LISTENER): {
return HandleUIExtUnregisterKeyboardDidShowListener(code, persistentId, data);
}
case static_cast<uint32_t>(Extension::Businesscode::REGISTER_KEYBOARD_DID_HIDE_LISTENER): {
return HandleUIExtRegisterKeyboardDidHideListener(code, persistentId, data);
}
case static_cast<uint32_t>(Extension::Businesscode::UNREGISTER_KEYBOARD_DID_HIDE_LISTENER): {
return HandleUIExtUnregisterKeyboardDidHideListener(code, persistentId, data);
}
case static_cast<uint32_t>(Extension::Businesscode::REGISTER_HOST_RECT_CHANGE_IN_GLOBAL_DISPLAY_LISTENER): {
return HandleRegisterHostRectChangeInGlobalDisplayListener(code, persistentId, data);
}
case static_cast<uint32_t>(Extension::Businesscode::UNREGISTER_HOST_RECT_CHANGE_IN_GLOBAL_DISPLAY_LISTENER): {
return HandleUnregisterHostRectChangeInGlobalDisplayListener(code, persistentId, data);
}
case static_cast<uint32_t>(Extension::Businesscode::REGISTER_TOUCH_OUTSIDE_LISTENER): {
return HandleUIExtRegisterTouchOutsideListener(code, persistentId, data);
}
case static_cast<uint32_t>(Extension::Businesscode::UNREGISTER_TOUCH_OUTSIDE_LISTENER): {
return HandleUIExtUnregisterTouchOutsideListener(code, persistentId, data);
}
default: {
TLOGI(WmsLogTag::WMS_UIEXT, "Message was not processed, businessCode: %{public}u", code);
break;
}
}
return WMError::WM_OK;
}
WMError WindowExtensionSessionImpl::HandleHostWindowRaise(uint32_t code, int32_t persistentId, const AAFwk::Want& data)
{
TLOGI(WmsLogTag::WMS_UIEXT, "businessCode: %{public}u", code);
return SendExtensionMessageToHost(code, data);
}
WMError WindowExtensionSessionImpl::HandleRegisterHostWindowRectChangeListener(uint32_t code, int32_t persistentId,
const AAFwk::Want& data)
{
TLOGD(WmsLogTag::WMS_UIEXT, "businessCode: %{public}u", code);
auto ret = SendExtensionMessageToHost(code, data);
if (ret != WMError::WM_OK) {
return ret;
}
{
std::lock_guard<std::mutex> lockListener(hostWindowRectChangeListenerMutex_);
rectChangeUIExtListenerIds_.emplace(persistentId);
}
return WMError::WM_OK;
}
WMError WindowExtensionSessionImpl::HandleUnregisterHostWindowRectChangeListener(uint32_t code, int32_t persistentId,
const AAFwk::Want& data)
{
TLOGD(WmsLogTag::WMS_UIEXT, "businessCode: %{public}u", code);
bool isHostWindowRectChangeListenerEmpty = false;
size_t hostWindowRectChangeListenerSize = 0;
{
std::lock_guard<std::mutex> lockListener(hostWindowRectChangeListenerMutex_);
rectChangeUIExtListenerIds_.erase(persistentId);
isHostWindowRectChangeListenerEmpty = hostWindowRectChangeListener_.empty();
hostWindowRectChangeListenerSize = hostWindowRectChangeListener_.size();
}
if (!isHostWindowRectChangeListenerEmpty || !rectChangeUIExtListenerIds_.empty()) {
TLOGI(WmsLogTag::WMS_UIEXT, "No need to send message to host to unregister, size of "
"hostWindowRectChangeListener_: %{public}zu, size of rectChangeUIExtListenerIds_: %{public}zu",
hostWindowRectChangeListenerSize, rectChangeUIExtListenerIds_.size());
return WMError::WM_OK;
}
return SendExtensionMessageToHost(code, data);
}
WMError WindowExtensionSessionImpl::HandleRegisterHostRectChangeInGlobalDisplayListener(uint32_t code,
int32_t persistentId, const AAFwk::Want& data)
{
TLOGD(WmsLogTag::WMS_UIEXT, "businessCode: %{public}u", code);
auto ret = SendExtensionMessageToHost(code, data);
if (ret != WMError::WM_OK) {
return ret;
}
{
std::lock_guard<std::mutex> lockListener(hostRectChangeInGlobalDisplayListenerMutex_);
rectChangeInGlobalDisplayUIExtListenerIds_.emplace(persistentId);
}
return WMError::WM_OK;
}
WMError WindowExtensionSessionImpl::HandleUnregisterHostRectChangeInGlobalDisplayListener(uint32_t code,
int32_t persistentId, const AAFwk::Want& data)
{
TLOGD(WmsLogTag::WMS_UIEXT, "businessCode: %{public}u", code);
bool needNotifyHost = false;
{
std::lock_guard<std::mutex> lockListener(hostRectChangeInGlobalDisplayListenerMutex_);
rectChangeInGlobalDisplayUIExtListenerIds_.erase(persistentId);
needNotifyHost = hostRectChangeInGlobalDisplayListenerList_.empty() &&
rectChangeInGlobalDisplayUIExtListenerIds_.empty();
}
if (needNotifyHost) {
return SendExtensionMessageToHost(code, data);
}
TLOGI(WmsLogTag::WMS_UIEXT, "No need to send message to host to unregister, size of "
"listener: %{public}zu, size of rectChangeUIExtListenerIds_: %{public}zu",
hostRectChangeInGlobalDisplayListenerList_.size(), rectChangeInGlobalDisplayUIExtListenerIds_.size());
return WMError::WM_OK;
}
WMError WindowExtensionSessionImpl::HandleUIExtRegisterTouchOutsideListener(uint32_t code,
int32_t persistentId, const AAFwk::Want& data)
{
TLOGD(WmsLogTag::WMS_UIEXT, "businessCode: %{public}u", code);
auto ret = SendExtensionMessageToHost(code, data);
if (ret != WMError::WM_OK) {
return ret;
}
{
std::lock_guard<std::mutex> lockListener(touchOutsideListenerMutex_);
touchOutsideUIExtListenerIds_.emplace(persistentId);
}
return WMError::WM_OK;
}
WMError WindowExtensionSessionImpl::HandleUIExtUnregisterTouchOutsideListener(uint32_t code,
int32_t persistentId, const AAFwk::Want& data)
{
TLOGD(WmsLogTag::WMS_UIEXT, "businessCode: %{public}u", code);
bool needNotifyHost = false;
{
std::lock_guard<std::mutex> lockListener(touchOutsideListenerMutex_);
touchOutsideUIExtListenerIds_.erase(persistentId);
needNotifyHost = touchOutsideListeners_[persistentId].empty() && touchOutsideUIExtListenerIds_.empty();
}
if (needNotifyHost) {
return SendExtensionMessageToHost(code, data);
}
TLOGI(WmsLogTag::WMS_UIEXT, "No need to send message to host to unregister, size of "
"listener: %{public}zu, size of touchOutsideUIExtListenerIds_: %{public}zu",
touchOutsideListeners_[persistentId].size(), touchOutsideUIExtListenerIds_.size());
return WMError::WM_OK;
}
WMError WindowExtensionSessionImpl::SetWindowMode(WindowMode mode)
{
property_->SetWindowMode(mode);
if (auto uiContet = GetUIContentSharedPtr()) {
uiContet->NotifyWindowMode(mode);
}
TLOGNI(WmsLogTag::WMS_UIEXT, "windowMode:%{public}u", GetWindowMode());
return WMError::WM_OK;
}
WMError WindowExtensionSessionImpl::OnCrossAxisStateChange(AAFwk::Want&& data, std::optional<AAFwk::Want>& reply)
{
auto state = data.GetIntParam(Extension::CROSS_AXIS_FIELD, 0);
if (state == static_cast<int32_t>(GetCrossAxisState())) {
return WMError::WM_OK;
}
if (!IsValidCrossState(state)) {
TLOGE(WmsLogTag::WMS_UIEXT, "invalid CrossAxisState:%{public}d", state);
return WMError::WM_ERROR_INVALID_PARAM;
}
crossAxisState_ = static_cast<CrossAxisState>(state);
if (auto uiContent = GetUIContentSharedPtr()) {
uiContent->SendUIExtProprty(static_cast<uint32_t>(Extension::Businesscode::SYNC_CROSS_AXIS_STATE),
data, static_cast<uint8_t>(SubSystemId::WM_UIEXT));
}
TLOGI(WmsLogTag::WMS_UIEXT, "CrossAxisState:%{public}d", state);
auto windowCrossAxisListeners = GetListeners<IWindowCrossAxisListener>();
for (const auto& listener : windowCrossAxisListeners) {
if (listener != nullptr) {
listener->OnCrossAxisChange(static_cast<CrossAxisState>(state));
}
}
return WMError::WM_OK;
}
CrossAxisState WindowExtensionSessionImpl::GetCrossAxisState()
{
return crossAxisState_.load();
}
WMError WindowExtensionSessionImpl::OnWaterfallModeChange(AAFwk::Want&& data, std::optional<AAFwk::Want>& reply)
{
bool isWaterfallMode = data.GetBoolParam(Extension::WATERFALL_MODE_FIELD, false);
if (isWaterfallMode == isFullScreenWaterfallMode_) {
return WMError::WM_OK;
}
TLOGI(WmsLogTag::WMS_ATTRIBUTE, "prev: %{public}d, curr: %{public}d, winId: %{public}u",
isFullScreenWaterfallMode_.load(), isWaterfallMode, GetWindowId());
isFullScreenWaterfallMode_.store(isWaterfallMode);
isValidWaterfallMode_.store(true);
if (auto uiContent = GetUIContentSharedPtr()) {
TLOGI(WmsLogTag::WMS_ATTRIBUTE, "send uiext winId: %{public}u", GetWindowId());
uiContent->SendUIExtProprty(static_cast<uint32_t>(Extension::Businesscode::SYNC_HOST_WATERFALL_MODE),
data, static_cast<uint8_t>(SubSystemId::WM_UIEXT));
}
auto waterfallModeChangeListeners = GetWaterfallModeChangeListeners();
for (const auto& listener : waterfallModeChangeListeners) {
if (listener != nullptr) {
listener->OnWaterfallModeChange(isWaterfallMode);
}
}
return WMError::WM_OK;
}
WMError WindowExtensionSessionImpl::OnResyncExtensionConfig(AAFwk::Want&& data, std::optional<AAFwk::Want>& reply)
{
const auto& configParam = data.GetParams().GetWantParams(Extension::UIEXTENSION_CONFIG_FIELD);
AAFwk::Want axisWant;
axisWant.SetParam(Extension::CROSS_AXIS_FIELD,
static_cast<int32_t>(configParam.GetIntParam(Extension::CROSS_AXIS_FIELD, 0)));
OnCrossAxisStateChange(std::move(axisWant), reply);
AAFwk::Want waterfallWant;
waterfallWant.SetParam(Extension::WATERFALL_MODE_FIELD,
static_cast<bool>(configParam.GetIntParam(Extension::WATERFALL_MODE_FIELD, 0)));
OnWaterfallModeChange(std::move(waterfallWant), reply);
AAFwk::Want windowDelayRaiseWant;
windowDelayRaiseWant.SetParam(Extension::HOST_WINDOW_DELAY_RAISE_STATE_FIELD,
static_cast<bool>(configParam.GetIntParam(Extension::HOST_WINDOW_DELAY_RAISE_STATE_FIELD, 0)));
OnHostWindowDelayRaiseStateChange(std::move(windowDelayRaiseWant), reply);
AAFwk::Want compatWant;
compatWant.SetParam(Extension::COMPAT_IS_SIMULATION_SCALE_FIELD,
static_cast<bool>(configParam.GetIntParam(Extension::COMPAT_IS_SIMULATION_SCALE_FIELD, 0)));
compatWant.SetParam(Extension::COMPAT_IS_PROPORTION_SCALE_FIELD,
static_cast<bool>(configParam.GetIntParam(Extension::COMPAT_IS_PROPORTION_SCALE_FIELD, 0)));
compatWant.SetParam(Extension::COMPAT_SCALE_X_FIELD, GetFloatParam(Extension::COMPAT_SCALE_X_FIELD, configParam));
compatWant.SetParam(Extension::COMPAT_SCALE_Y_FIELD, GetFloatParam(Extension::COMPAT_SCALE_Y_FIELD, configParam));
OnHostWindowCompatInfoChange(std::move(compatWant), reply);
AAFwk::Want windowStatusWant;
windowStatusWant.SetParam(Extension::HOST_WINDOW_STATUS_FIELD,
configParam.GetIntParam(Extension::HOST_WINDOW_STATUS_FIELD,
static_cast<int32_t>(WindowStatus::WINDOW_STATUS_UNDEFINED)));
OnHostWindowStatusChange(std::move(windowStatusWant), reply);
return WMError::WM_OK;
}
WMError WindowExtensionSessionImpl::OnGestureBackEnabledChange(AAFwk::Want&& data, std::optional<AAFwk::Want>& reply)
{
auto enable = data.GetBoolParam(Extension::GESTURE_BACK_ENABLED, true);
if (enable == hostGestureBackEnabled_) {
return WMError::WM_OK;
}
TLOGI(WmsLogTag::WMS_UIEXT, "gestureBackEnabled:%{public}d", enable);
hostGestureBackEnabled_ = enable;
if (auto uiContent = GetUIContentSharedPtr()) {
uiContent->SendUIExtProprty(static_cast<uint32_t>(Extension::Businesscode::SYNC_HOST_GESTURE_BACK_ENABLED),
data, static_cast<uint8_t>(SubSystemId::WM_UIEXT));
}
return WMError::WM_OK;
}
WMError WindowExtensionSessionImpl::OnHostWindowDelayRaiseStateChange(AAFwk::Want&& data,
std::optional<AAFwk::Want>& reply)
{
bool isHostWindowDelayRaiseEnabled = data.GetBoolParam(Extension::HOST_WINDOW_DELAY_RAISE_STATE_FIELD, false);
if (isHostWindowDelayRaiseEnabled == IsWindowDelayRaiseEnabled()) {
return WMError::WM_OK;
}
property_->SetWindowDelayRaiseEnabled(isHostWindowDelayRaiseEnabled);
if (auto uiContent = GetUIContentSharedPtr()) {
uiContent->SendUIExtProprty(static_cast<uint32_t>(Extension::Businesscode::SYNC_HOST_WINDOW_DELAY_RAISE_STATE),
data, static_cast<uint8_t>(SubSystemId::WM_UIEXT));
}
TLOGI(WmsLogTag::WMS_UIEXT, "isHostWindowDelayRaiseEnabled: %{public}d", isHostWindowDelayRaiseEnabled);
return WMError::WM_OK;
}
WMError WindowExtensionSessionImpl::OnHostWindowRectChange(AAFwk::Want&& data, std::optional<AAFwk::Want>& reply)
{
auto rectX = data.GetIntParam(Extension::RECT_X, 0);
auto rectY = data.GetIntParam(Extension::RECT_Y, 0);
auto rectWidth = data.GetIntParam(Extension::RECT_WIDTH, 0);
auto rectHeight = data.GetIntParam(Extension::RECT_HEIGHT, 0);
auto reason = static_cast<WindowSizeChangeReason>(data.GetIntParam(Extension::RECT_CHANGE_REASON, 0));
Rect rect {rectX, rectY, rectWidth, rectHeight};
TLOGI(WmsLogTag::WMS_UIEXT, "Host window rect change: %{public}s, reason: %{public}u",
rect.ToString().c_str(), reason);
{
std::lock_guard<std::mutex> lockListener(hostWindowRectChangeListenerMutex_);
for (const auto& listener : hostWindowRectChangeListener_) {
if (listener != nullptr) {
listener->OnRectChange(rect, reason);
}
}
}
auto uiContent = GetUIContentSharedPtr();
if (!rectChangeUIExtListenerIds_.empty() && uiContent != nullptr) {
uiContent->SendUIExtProprtyByPersistentId(
static_cast<uint32_t>(Extension::Businesscode::NOTIFY_HOST_WINDOW_RECT_CHANGE), data,
rectChangeUIExtListenerIds_, static_cast<uint8_t>(SubSystemId::WM_UIEXT));
}
return WMError::WM_OK;
}
WMError WindowExtensionSessionImpl::OnHostRectChangeInGlobalDisplay(AAFwk::Want&& data,
std::optional<AAFwk::Want>& reply)
{
auto rectX = data.GetIntParam(Extension::RECT_X, 0);
auto rectY = data.GetIntParam(Extension::RECT_Y, 0);
auto rectWidth = data.GetIntParam(Extension::RECT_WIDTH, 0);
auto rectHeight = data.GetIntParam(Extension::RECT_HEIGHT, 0);
auto reason = static_cast<WindowSizeChangeReason>(data.GetIntParam(Extension::RECT_CHANGE_REASON, 0));
Rect rect {rectX, rectY, rectWidth, rectHeight};
TLOGI(WmsLogTag::WMS_UIEXT, "Host rect change in global display: %{public}s, reason: %{public}u",
rect.ToString().c_str(), reason);
std::lock_guard<std::mutex> lockListener(hostRectChangeInGlobalDisplayListenerMutex_);
for (const auto& listener : hostRectChangeInGlobalDisplayListenerList_) {
if (listener != nullptr) {
listener->OnRectChangeInGlobalDisplay(rect, reason);
}
}
auto uiContent = GetUIContentSharedPtr();
if (!rectChangeInGlobalDisplayUIExtListenerIds_.empty() && uiContent != nullptr) {
uiContent->SendUIExtProprtyByPersistentId(
static_cast<uint32_t>(Extension::Businesscode::NOTIFY_HOST_RECT_CHANGE_IN_GLOBAL_DISPLAY), data,
rectChangeInGlobalDisplayUIExtListenerIds_, static_cast<uint8_t>(SubSystemId::WM_UIEXT));
}
return WMError::WM_OK;
}
WMError WindowExtensionSessionImpl::OnRecover(AAFwk::Want&& data, std::optional<AAFwk::Want>& reply)
{
TLOGI(WmsLogTag::WMS_UIEXT, "id: %{public}d", GetPersistentId());
AddExtensionWindowStageToSCB(property_->IsConstrainedModal());
CheckAndAddExtWindowFlags();
if (property_->GetUIExtensionUsage() == UIExtensionUsage::MODAL && abilityToken_) {
WindowAdapter::GetInstance().UpdateModalExtensionRect(abilityToken_, property_->GetWindowRect());
}
if (auto uiContent = GetUIContentSharedPtr()) {
uiContent->SendUIExtProprty(static_cast<uint32_t>(Extension::Businesscode::RECOVER_EXTENSION), data,
static_cast<uint8_t>(SubSystemId::WM_UIEXT));
}
return WMError::WM_OK;
}
WMError WindowExtensionSessionImpl::OnScreenshot(AAFwk::Want&& data, std::optional<AAFwk::Want>& reply)
{
TLOGD(WmsLogTag::WMS_UIEXT, "in");
NotifyScreenshot();
return WMError::WM_OK;
}
WMError WindowExtensionSessionImpl::OnExtensionSecureLimitChange(AAFwk::Want&& data, std::optional<AAFwk::Want>& reply)
{
bool limit = data.GetBoolParam(Extension::EXTENSION_SECURE_LIMIT_CHANGE, false);
TLOGD(WmsLogTag::WMS_UIEXT, "limit: %{public}d", limit);
NotifyExtensionSecureLimitChange(limit);
return WMError::WM_OK;
}
WMError WindowExtensionSessionImpl::OnKeyboardDidShow(AAFwk::Want&& data, std::optional<AAFwk::Want>& reply)
{
TLOGD(WmsLogTag::WMS_UIEXT, "in");
KeyboardPanelInfo info;
ReadKeyboardInfoFromWant(data, info);
NotifyKeyboardDidShow(info);
return WMError::WM_OK;
}
WMError WindowExtensionSessionImpl::OnKeyboardDidHide(AAFwk::Want&& data, std::optional<AAFwk::Want>& reply)
{
TLOGD(WmsLogTag::WMS_UIEXT, "in");
KeyboardPanelInfo info;
ReadKeyboardInfoFromWant(data, info);
NotifyKeyboardDidHide(info);
return WMError::WM_OK;
}
void WindowExtensionSessionImpl::RegisterConsumer(Extension::Businesscode code,
const std::function<WMError(AAFwk::Want&& data, std::optional<AAFwk::Want>& reply)>& func)
{
auto consumer = [func](SubSystemId id, uint32_t customId, AAFwk::Want&& data,
std::optional<AAFwk::Want>& reply) {
return static_cast<int32_t>(func(std::move(data), reply));
};
dataConsumers_.emplace(static_cast<uint32_t>(code), std::move(consumer));
}
void WindowExtensionSessionImpl::RegisterDataConsumer()
{
auto windowModeConsumer = [this](SubSystemId id, uint32_t customId, AAFwk::Want&& data,
std::optional<AAFwk::Want>& reply) -> int32_t {
auto windowMode = data.GetIntParam(Extension::WINDOW_MODE_FIELD, 0);
if (windowMode < static_cast<int32_t>(WindowMode::WINDOW_MODE_UNDEFINED) ||
windowMode > static_cast<int32_t>(WindowMode::END)) {
TLOGNE(WmsLogTag::WMS_UIEXT, "invalid window mode, windowMode:%{public}d", windowMode);
return static_cast<int32_t>(DataHandlerErr::INVALID_PARAMETER);
}
static_cast<void>(SetWindowMode(static_cast<WindowMode>(windowMode)));
return static_cast<int32_t>(DataHandlerErr::OK);
};
dataConsumers_.emplace(static_cast<uint32_t>(Extension::Businesscode::SYNC_HOST_WINDOW_MODE),
std::move(windowModeConsumer));
RegisterConsumer(Extension::Businesscode::SYNC_CROSS_AXIS_STATE,
std::bind(&WindowExtensionSessionImpl::OnCrossAxisStateChange,
this, std::placeholders::_1, std::placeholders::_2));
RegisterConsumer(Extension::Businesscode::SYNC_HOST_WATERFALL_MODE,
std::bind(&WindowExtensionSessionImpl::OnWaterfallModeChange,
this, std::placeholders::_1, std::placeholders::_2));
RegisterConsumer(Extension::Businesscode::SYNC_WANT_PARAMS,
std::bind(&WindowExtensionSessionImpl::OnResyncExtensionConfig,
this, std::placeholders::_1, std::placeholders::_2));
RegisterConsumer(Extension::Businesscode::SYNC_HOST_GESTURE_BACK_ENABLED,
std::bind(&WindowExtensionSessionImpl::OnGestureBackEnabledChange,
this, std::placeholders::_1, std::placeholders::_2));
RegisterConsumer(Extension::Businesscode::SYNC_COMPAT_INFO,
std::bind(&WindowExtensionSessionImpl::OnHostWindowCompatInfoChange,
this, std::placeholders::_1, std::placeholders::_2));
RegisterConsumer(Extension::Businesscode::SYNC_HOST_WINDOW_DELAY_RAISE_STATE,
std::bind(&WindowExtensionSessionImpl::OnHostWindowDelayRaiseStateChange,
this, std::placeholders::_1, std::placeholders::_2));
RegisterConsumer(Extension::Businesscode::NOTIFY_HOST_WINDOW_RECT_CHANGE,
std::bind(&WindowExtensionSessionImpl::OnHostWindowRectChange,
this, std::placeholders::_1, std::placeholders::_2));
RegisterConsumer(Extension::Businesscode::NOTIFY_SCREENSHOT,
std::bind(&WindowExtensionSessionImpl::OnScreenshot,
this, std::placeholders::_1, std::placeholders::_2));
RegisterConsumer(Extension::Businesscode::NOTIFY_EXTENSION_SECURE_LIMIT_CHANGE,
std::bind(&WindowExtensionSessionImpl::OnExtensionSecureLimitChange,
this, std::placeholders::_1, std::placeholders::_2));
RegisterConsumer(Extension::Businesscode::NOTIFY_KEYBOARD_DID_SHOW,
std::bind(&WindowExtensionSessionImpl::OnKeyboardDidShow,
this, std::placeholders::_1, std::placeholders::_2));
RegisterConsumer(Extension::Businesscode::NOTIFY_KEYBOARD_DID_HIDE,
std::bind(&WindowExtensionSessionImpl::OnKeyboardDidHide,
this, std::placeholders::_1, std::placeholders::_2));
RegisterConsumer(Extension::Businesscode::SYNC_HOST_STATUS_BAR_CONTENT_COLOR,
std::bind(&WindowExtensionSessionImpl::OnHostStatusBarContentColorChange,
this, std::placeholders::_1, std::placeholders::_2));
RegisterConsumer(Extension::Businesscode::NOTIFY_HOST_RECT_CHANGE_IN_GLOBAL_DISPLAY,
std::bind(&WindowExtensionSessionImpl::OnHostRectChangeInGlobalDisplay,
this, std::placeholders::_1, std::placeholders::_2));
RegisterConsumer(Extension::Businesscode::RECOVER_EXTENSION,
std::bind(&WindowExtensionSessionImpl::OnRecover,
this, std::placeholders::_1, std::placeholders::_2));
RegisterConsumer(Extension::Businesscode::SYNC_HOST_WINDOW_STATUS,
std::bind(&WindowExtensionSessionImpl::OnHostWindowStatusChange,
this, std::placeholders::_1, std::placeholders::_2));
RegisterConsumer(Extension::Businesscode::NOTIFY_TOUCH_OUTSIDE,
std::bind(&WindowExtensionSessionImpl::OnTouchOutside,
this, std::placeholders::_1, std::placeholders::_2));
auto consumersEntry = [weakThis = wptr(this)](SubSystemId id, uint32_t customId, AAFwk::Want&& data,
std::optional<AAFwk::Want>& reply) -> int32_t {
auto window = weakThis.promote();
if (window == nullptr) {
TLOGNE(WmsLogTag::WMS_UIEXT, "window is nullptr");
return static_cast<int32_t>(DataHandlerErr::NULL_PTR);
}
auto itr = window->dataConsumers_.find(customId);
if (itr == window->dataConsumers_.end()) {
TLOGNE(WmsLogTag::WMS_UIEXT, "no consumer for %{public}u", customId);
return static_cast<int32_t>(DataHandlerErr::NO_CONSUME_CALLBACK);
}
const auto& func = itr->second;
if (!func) {
TLOGNE(WmsLogTag::WMS_UIEXT, "not callable for %{public}u", customId);
return static_cast<int32_t>(DataHandlerErr::INVALID_CALLBACK);
}
auto ret = func(id, customId, std::move(data), reply);
TLOGND(WmsLogTag::WMS_UIEXT, "customId:%{public}u, ret:%{public}d", customId, ret);
return static_cast<int32_t>(DataHandlerErr::OK);
};
dataHandler_->RegisterDataConsumer(SubSystemId::WM_UIEXT, std::move(consumersEntry));
}
WMError WindowExtensionSessionImpl::UseImplicitAnimation(bool useImplicit)
{
TLOGI(WmsLogTag::WMS_UIEXT, "WindowId: %{public}u", GetWindowId());
SingletonContainer::Get<WindowAdapter>().UseImplicitAnimation(property_->GetParentId(), useImplicit);
return WMError::WM_OK;
}
WMError WindowExtensionSessionImpl::SetCompatInfo(const AAFwk::WantParams& configParam)
{
bool isAdaptToSimulationScale =
static_cast<bool>(configParam.GetIntParam(Extension::COMPAT_IS_SIMULATION_SCALE_FIELD, 0));
bool isAdaptToProportionalScale =
static_cast<bool>(configParam.GetIntParam(Extension::COMPAT_IS_PROPORTION_SCALE_FIELD, 0));
auto compatibleModeProperty = property_->GetCompatibleModeProperty();
if (compatibleModeProperty == nullptr) {
if (!isAdaptToSimulationScale && !isAdaptToProportionalScale) {
TLOGD(WmsLogTag::WMS_COMPAT, "id:%{public}d not scale mode", GetPersistentId());
return WMError::WM_DO_NOTHING;
}
compatibleModeProperty = sptr<CompatibleModeProperty>::MakeSptr();
property_->SetCompatibleModeProperty(compatibleModeProperty);
}
compatibleModeProperty->SetIsAdaptToSimulationScale(isAdaptToSimulationScale);
compatibleModeProperty->SetIsAdaptToProportionalScale(isAdaptToProportionalScale);
{
std::lock_guard<std::mutex> lockListener(compatScaleListenerMutex_);
compatScaleX_ = GetFloatParam(Extension::COMPAT_SCALE_X_FIELD, configParam);
compatScaleY_ = GetFloatParam(Extension::COMPAT_SCALE_Y_FIELD, configParam);
TLOGI(WmsLogTag::WMS_COMPAT, "id:%{public}d compatScaleX:%{public}f compatScaleY:%{public}f",
GetPersistentId(), compatScaleX_, compatScaleY_);
}
return WMError::WM_OK;
}
WMError WindowExtensionSessionImpl::OnHostWindowCompatInfoChange(AAFwk::Want&& data,
std::optional<AAFwk::Want>& reply)
{
bool isAdaptToSimulationScale = data.GetBoolParam(Extension::COMPAT_IS_SIMULATION_SCALE_FIELD, false);
bool isAdaptToProportionalScale = data.GetBoolParam(Extension::COMPAT_IS_PROPORTION_SCALE_FIELD, false);
auto compatibleModeProperty = property_->GetCompatibleModeProperty();
if (compatibleModeProperty == nullptr) {
if (!isAdaptToSimulationScale && !isAdaptToProportionalScale) {
TLOGD(WmsLogTag::WMS_COMPAT, "id:%{public}d not scale mode", GetPersistentId());
return WMError::WM_DO_NOTHING;
}
compatibleModeProperty = sptr<CompatibleModeProperty>::MakeSptr();
property_->SetCompatibleModeProperty(compatibleModeProperty);
}
compatibleModeProperty->SetIsAdaptToSimulationScale(isAdaptToSimulationScale);
compatibleModeProperty->SetIsAdaptToProportionalScale(isAdaptToProportionalScale);
{
std::lock_guard<std::mutex> lockListener(compatScaleListenerMutex_);
compatScaleX_ = data.GetFloatParam(Extension::COMPAT_SCALE_X_FIELD, 1.0f);
compatScaleY_ = data.GetFloatParam(Extension::COMPAT_SCALE_Y_FIELD, 1.0f);
TLOGI(WmsLogTag::WMS_COMPAT, "id:%{public}d compatScaleX:%{public}f compatScaleY:%{public}f",
GetPersistentId(), compatScaleX_, compatScaleY_);
}
if (auto uiContent = GetUIContentSharedPtr()) {
TLOGD(WmsLogTag::WMS_COMPAT, "send uiext winId: %{public}u", GetWindowId());
uiContent->SendUIExtProprty(static_cast<uint32_t>(Extension::Businesscode::SYNC_COMPAT_INFO),
data, static_cast<uint8_t>(SubSystemId::WM_UIEXT));
}
return WMError::WM_OK;
}
void WindowExtensionSessionImpl::NotifyKeyboardDidShow(const KeyboardPanelInfo& keyboardPanelInfo)
{
std::lock_guard<std::mutex> lockListener(keyboardDidShowListenerMutex_);
for (const auto& listener : keyboardDidShowListenerList_) {
if (listener != nullptr) {
listener->OnKeyboardDidShow(keyboardPanelInfo);
}
}
if (auto uiContent = GetUIContentSharedPtr()) {
AAFwk::Want want;
WriteKeyboardInfoToWant(want, keyboardPanelInfo);
uiContent->SendUIExtProprtyByPersistentId(
static_cast<uint32_t>(Extension::Businesscode::NOTIFY_KEYBOARD_DID_SHOW), want,
keyboardDidShowUIExtListenerIds_, static_cast<uint8_t>(SubSystemId::WM_UIEXT));
}
}
void WindowExtensionSessionImpl::NotifyKeyboardDidHide(const KeyboardPanelInfo& keyboardPanelInfo)
{
std::lock_guard<std::mutex> lockListener(keyboardDidHideListenerMutex_);
for (const auto& listener : keyboardDidHideListenerList_) {
if (listener != nullptr) {
listener->OnKeyboardDidHide(keyboardPanelInfo);
}
}
if (auto uiContent = GetUIContentSharedPtr()) {
AAFwk::Want want;
WriteKeyboardInfoToWant(want, keyboardPanelInfo);
uiContent->SendUIExtProprtyByPersistentId(
static_cast<uint32_t>(Extension::Businesscode::NOTIFY_KEYBOARD_DID_HIDE), want,
keyboardDidHideUIExtListenerIds_, static_cast<uint8_t>(SubSystemId::WM_UIEXT));
}
}
WMError WindowExtensionSessionImpl::OnHostStatusBarContentColorChange(AAFwk::Want&& data,
std::optional<AAFwk::Want>& reply)
{
auto contentColor = static_cast<uint32_t>(data.GetIntParam(Extension::HOST_STATUS_BAR_CONTENT_COLOR, 0));
TLOGI(WmsLogTag::WMS_UIEXT, "contentColor: %{public}u", contentColor);
hostStatusBarContentColor_ = contentColor;
return WMError::WM_OK;
}
uint32_t WindowExtensionSessionImpl::GetHostStatusBarContentColor() const
{
return hostStatusBarContentColor_;
}
WMError WindowExtensionSessionImpl::OnHostWindowStatusChange(AAFwk::Want&& data,
std::optional<AAFwk::Want>& reply)
{
if (!property_->GetIsAtomicService()) {
TLOGD(WmsLogTag::WMS_UIEXT, "win %{public}u no support", GetPersistentId());
return WMError::WM_OK;
}
auto windowStatus = static_cast<WindowStatus>(data.GetIntParam(Extension::HOST_WINDOW_STATUS_FIELD,
static_cast<int32_t>(WindowStatus::WINDOW_STATUS_UNDEFINED)));
if (windowStatus == hostWindowStatus_) {
TLOGD(WmsLogTag::WMS_UIEXT, "windowStatus not changed");
return WMError::WM_OK;
}
hostWindowStatus_ = windowStatus;
TLOGI(WmsLogTag::WMS_UIEXT, "hostWindowStatus: %{public}u", windowStatus);
auto windowStatusChangeListeners = GetListeners<IWindowStatusChangeListener>();
for (const auto& listener : windowStatusChangeListeners) {
if (listener != nullptr) {
listener->OnWindowStatusChange(hostWindowStatus_);
}
}
return WMError::WM_OK;
}
WMError WindowExtensionSessionImpl::GetWindowStatus(WindowStatus& windowStatus)
{
windowStatus = hostWindowStatus_;
TLOGD(WmsLogTag::WMS_UIEXT, "windowStatus: %{public}u", windowStatus);
return WMError::WM_OK;
}
void WindowExtensionSessionImpl::NotifyOccupiedAreaChange(sptr<OccupiedAreaChangeInfo> info)
{
std::lock_guard<std::mutex> lockListener(occupiedAreaChangeListenerMutex_);
for (auto& listener : occupiedAreaChangeListenerList_) {
if (listener != nullptr) {
listener->OnSizeChange(info);
}
}
}
WMError WindowExtensionSessionImpl::OnTouchOutside(AAFwk::Want&& data, std::optional<AAFwk::Want>& reply)
{
TLOGD(WmsLogTag::WMS_UIEXT, "in");
auto persistentId = GetPersistentId();
for (const auto& listener : touchOutsideListeners_[persistentId]) {
if (listener != nullptr) {
listener->OnTouchOutside();
}
}
NotifyUIExtTouchOutside();
return WMError::WM_OK;
}
}
}