* Copyright (c) 2024 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_manager_impl.h"
#include "ability.h"
#include "ability_context.h"
#include "accesstoken_kit.h"
#include "bundle_constants.h"
#include "display_manager.h"
#include "ipc_skeleton.h"
#include "singleton_container.h"
#include "window_helper.h"
#include "window_impl.h"
#include "window_manager.h"
#include "window_manager_hilog.h"
#include "window_utils.h"
namespace OHOS {
namespace Rosen {
using namespace AbilityRuntime;
bool CheckCallingPermission(std::string permission)
{
TLOGD(WmsLogTag::WMS_SUB, "Permission: %{public}s", permission.c_str());
if (!permission.empty() &&
Security::AccessToken::AccessTokenKit::VerifyAccessToken(IPCSkeleton::GetCallingTokenID(), permission)
!= AppExecFwk::Constants::PERMISSION_GRANTED) {
TLOGE(WmsLogTag::WMS_SUB, "Permission %{public}s is not granted", permission.c_str());
return false;
}
return true;
}
static int32_t CreateNewSystemWindow(OHOS::AbilityRuntime::Context* ctx,
sptr<WindowOption> windowOption, int64_t* windowId)
{
if (windowOption == nullptr) {
TLOGE(WmsLogTag::WMS_SUB, "New window option failed");
return static_cast<int32_t>(WmErrorCode::WM_ERROR_SYSTEM_ABNORMALLY);
}
if (ctx == nullptr) {
TLOGE(WmsLogTag::WMS_SUB, "Context is nullptr");
return static_cast<int32_t>(WmErrorCode::WM_ERROR_CONTEXT_ABNORMALLY);
}
auto sctx = ctx->shared_from_this();
auto context = std::weak_ptr<AbilityRuntime::Context>(sctx);
if (windowOption->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT ||
windowOption->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT_CAMERA) {
auto abilityContext = Context::ConvertTo<AbilityRuntime::AbilityContext>(context.lock());
if (abilityContext != nullptr) {
if (!CheckCallingPermission("ohos.permission.SYSTEM_FLOAT_WINDOW")) {
TLOGE(WmsLogTag::WMS_SUB, "TYPE_FLOAT CheckCallingPermission failed");
return static_cast<int32_t>(WmErrorCode::WM_ERROR_NO_PERMISSION);
}
}
}
WMError wmError = WMError::WM_OK;
sptr<Window> window = Window::Create(windowOption->GetWindowName(), windowOption, context.lock(), wmError);
WmErrorCode wmErrorCode = WM_JS_TO_ERROR_CODE_MAP.at(wmError);
if (window != nullptr && wmErrorCode == WmErrorCode::WM_OK) {
auto instance = CreateCjWindowObject(window);
if (!instance) {
return static_cast<int32_t>(WMError::WM_ERROR_NO_MEM);
}
*windowId = instance->GetID();
}
return static_cast<int32_t>(wmErrorCode);
}
int32_t WindowManagerImpl::CreateWindow(WindowParameters window)
{
WindowOption option;
option.SetWindowName(window.name);
if (window.winType >= static_cast<uint32_t>(ApiWindowType::TYPE_BASE) &&
window.winType < static_cast<uint32_t>(ApiWindowType::TYPE_END)) {
option.SetWindowType(CJ_TO_NATIVE_WINDOW_TYPE_MAP.at(static_cast<ApiWindowType>(window.winType)));
} else {
option.SetWindowType(static_cast<WindowType>(window.winType));
}
if (window.displayId < 0 ||
SingletonContainer::Get<DisplayManager>().GetDisplayById(static_cast<uint64_t>(window.displayId)) == nullptr) {
TLOGE(WmsLogTag::WMS_SUB, "Failed to parse config");
return static_cast<int32_t>(WmErrorCode::WM_ERROR_INVALID_PARAM);
}
option.SetDisplayId(window.displayId);
option.SetParentId(window.parentId);
sptr<WindowOption> windowOption = new(std::nothrow) WindowOption(option);
if (WindowHelper::IsSystemWindow(option.GetWindowType())) {
TLOGI(WmsLogTag::WMS_SUB, "CreateNewSystemWindow");
return CreateNewSystemWindow(window.context, windowOption, window.windowId);
}
return static_cast<int32_t>(WmErrorCode::WM_ERROR_INVALID_PARAM);
}
int32_t WindowManagerImpl::SetWindowLayoutMode(uint32_t mode)
{
WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(
SingletonContainer::Get<WindowManager>().SetWindowLayoutMode(WindowLayoutMode(mode)));
return static_cast<int32_t>(ret);
}
int32_t WindowManagerImpl::MinimizeAll(int64_t displayId, int32_t excludeWindowId)
{
if (displayId < 0 ||
SingletonContainer::Get<DisplayManager>().GetDisplayById(static_cast<uint64_t>(displayId)) == nullptr) {
return static_cast<int32_t>(WmErrorCode::WM_ERROR_INVALID_PARAM);
}
WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(
SingletonContainer::Get<WindowManager>().MinimizeAllAppWindows(
static_cast<uint64_t>(displayId), static_cast<int32_t>(excludeWindowId)));
return static_cast<int32_t>(ret);
}
int32_t WindowManagerImpl::FindWindow(std::string name, int64_t& windowId)
{
sptr<CJWindowImpl> windowImpl = FindCjWindowObject(name);
if (windowImpl != nullptr) {
windowId = windowImpl->GetID();
return WINDOW_SUCCESS;
} else {
sptr<Window> window = Window::Find(name);
if (window == nullptr) {
return static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY);
} else {
sptr<CJWindowImpl> newWindow = CreateCjWindowObject(window);
if (newWindow == nullptr) {
return static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY);
}
windowId = newWindow->GetID();
return WINDOW_SUCCESS;
}
}
}
int32_t WindowManagerImpl::GetLastWindow(OHOS::AbilityRuntime::Context* ctx, int64_t& id)
{
sptr<Window> window = nullptr;
if (ctx == nullptr) {
TLOGE(WmsLogTag::WMS_HIERARCHY, "[WindowManager]Stage mode without context");
return static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY);
}
auto sctx = ctx->shared_from_this();
auto context = std::weak_ptr<AbilityRuntime::Context>(sctx);
if (sctx == nullptr) {
TLOGE(WmsLogTag::WMS_HIERARCHY, "[WindowManager]Stage mode without context");
return static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY);
}
window = Window::GetTopWindowWithContext(context.lock());
if (window == nullptr) {
TLOGE(WmsLogTag::WMS_HIERARCHY, "[WindowManager]Get top window failed");
return static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY);
}
return FindWindow(window->GetWindowName(), id);
}
int32_t WindowManagerImpl::ShiftAppWindowFocus(int32_t sourceWindowId,
int32_t targetWindowId)
{
WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(
SingletonContainer::Get<WindowManager>().ShiftAppWindowFocus(sourceWindowId, targetWindowId));
if (ret != WmErrorCode::WM_OK) {
TLOGE(WmsLogTag::WMS_FOCUS, "Shift application window focus failed");
}
return static_cast<int32_t>(ret);
}
}
}