!7869 新增异步接口moveWindowToAsync及resizeAsync

Merge pull request !7869 from 白钰胜/master
This commit is contained in:
openharmony_ci 2024-08-09 02:41:46 +00:00 committed by Gitee
commit 19c227d5ce
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
25 changed files with 1141 additions and 24 deletions

View File

@ -817,6 +817,14 @@ public:
* @return WMError
*/
virtual WMError MoveTo(int32_t x, int32_t y) { return WMError::WM_OK; }
/**
* @brief move the window to (x, y)
*
* @param x
* @param y
* @return WMError
*/
virtual WMError MoveToAsync(int32_t x, int32_t y) { return WMError::WM_ERROR_DEVICE_NOT_SUPPORT; }
/**
* @brief resize the window instance (w,h)
*
@ -825,6 +833,14 @@ public:
* @return WMError
*/
virtual WMError Resize(uint32_t width, uint32_t height) { return WMError::WM_OK; }
/**
* @brief resize the window instance (w,h)
*
* @param width
* @param height
* @return WMError
*/
virtual WMError ResizeAsync(uint32_t width, uint32_t height) { return WMError::WM_ERROR_DEVICE_NOT_SUPPORT; }
/**
* @brief set the window gravity
*

View File

@ -176,6 +176,13 @@ napi_value JsWindow::MoveWindowTo(napi_env env, napi_callback_info info)
return (me != nullptr) ? me->OnMoveWindowTo(env, info) : nullptr;
}
napi_value JsWindow::MoveWindowToAsync(napi_env env, napi_callback_info info)
{
WLOGI("MoveTo");
JsWindow* me = CheckParamsAndGetThis<JsWindow>(env, info);
return (me != nullptr) ? me->OnMoveWindowToAsync(env, info) : nullptr;
}
napi_value JsWindow::Resize(napi_env env, napi_callback_info info)
{
WLOGD("Resize");
@ -190,6 +197,13 @@ napi_value JsWindow::ResizeWindow(napi_env env, napi_callback_info info)
return (me != nullptr) ? me->OnResizeWindow(env, info) : nullptr;
}
napi_value JsWindow::ResizeWindowAsync(napi_env env, napi_callback_info info)
{
WLOGI("Resize");
JsWindow* me = CheckParamsAndGetThis<JsWindow>(env, info);
return (me != nullptr) ? me->OnResizeWindowAsync(env, info) : nullptr;
}
napi_value JsWindow::SetWindowType(napi_env env, napi_callback_info info)
{
WLOGI("SetWindowType");
@ -1381,6 +1395,88 @@ napi_value JsWindow::OnMoveWindowTo(napi_env env, napi_callback_info info)
return result;
}
static void SetMoveWindowToAsyncTask(NapiAsyncTask::ExecuteCallback& execute, NapiAsyncTask::CompleteCallback& complete,
wptr<Window> weakToken, int32_t x, int32_t y, std::shared_ptr<WmErrorCode> errCodePtr)
{
execute = [weakToken, errCodePtr, x, y]() {
if (errCodePtr == nullptr) {
return;
}
if (*errCodePtr != WmErrorCode::WM_OK) {
return;
}
auto spWindow = weakToken.promote();
if (spWindow == nullptr) {
TLOGE(WmsLogTag::WMS_LAYOUT, "window is nullptr");
*errCodePtr = WmErrorCode::WM_ERROR_STATE_ABNORMALLY;
return;
}
*errCodePtr = WM_JS_TO_ERROR_CODE_MAP.at(spWindow->MoveToAsync(x, y));
};
complete = [weakToken, errCodePtr](napi_env env, NapiAsyncTask& task, int32_t status) {
if (errCodePtr == nullptr) {
task.Reject(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
return;
}
if (*errCodePtr == WmErrorCode::WM_ERROR_INVALID_PARAM) {
task.Reject(env, JsErrUtils::CreateJsError(env, *errCodePtr));
TLOGE(WmsLogTag::WMS_LAYOUT, "Get invalid param");
return;
}
auto weakWindow = weakToken.promote();
if (weakWindow == nullptr) {
task.Reject(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
return;
}
if (*errCodePtr == WmErrorCode::WM_OK) {
task.Resolve(env, NapiGetUndefined(env));
} else {
task.Reject(env, JsErrUtils::CreateJsError(env, *errCodePtr, "JsWindow::OnMoveWindowToAsync failed"));
}
TLOGI(WmsLogTag::WMS_LAYOUT, "Window [%{public}u, %{public}s] move end, err = %{public}d",
weakWindow->GetWindowId(), weakWindow->GetWindowName().c_str(), *errCodePtr);
};
}
napi_value JsWindow::OnMoveWindowToAsync(napi_env env, napi_callback_info info)
{
WmErrorCode errCode = WmErrorCode::WM_OK;
size_t argc = 4; // 4: number of arg
napi_value argv[4] = {nullptr};
napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
if (argc < 2) { // 2:minimum param num
WLOGFE("Argc is invalid: %{public}zu", argc);
errCode = WmErrorCode::WM_ERROR_INVALID_PARAM;
}
int32_t x = 0;
if (errCode == WmErrorCode::WM_OK && !ConvertFromJsValue(env, argv[0], x)) {
WLOGFE("Failed to convert parameter to x");
errCode = WmErrorCode::WM_ERROR_INVALID_PARAM;
}
int32_t y = 0;
if (errCode == WmErrorCode::WM_OK && !ConvertFromJsValue(env, argv[1], y)) {
WLOGFE("Failed to convert parameter to y");
errCode = WmErrorCode::WM_ERROR_INVALID_PARAM;
}
if (errCode == WmErrorCode::WM_ERROR_INVALID_PARAM) {
return NapiThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM);
}
wptr<Window> weakToken(windowToken_);
std::shared_ptr<WmErrorCode> errCodePtr = std::make_shared<WmErrorCode>(errCode);
NapiAsyncTask::ExecuteCallback execute;
NapiAsyncTask::CompleteCallback complete;
SetMoveWindowToAsyncTask(execute, complete, weakToken, x, y, errCodePtr);
// 2: params num; 2: index of callback
napi_value lastParam = (argc <= 2) ? nullptr :
((argv[2] != nullptr && GetType(env, argv[2]) == napi_function) ? argv[2] : nullptr);
napi_value result = nullptr;
NapiAsyncTask::Schedule("JsWindow::OnMoveWindowToAsync",
env, CreateAsyncTaskWithLastParam(env, lastParam, std::move(execute), std::move(complete), &result));
return result;
}
napi_value JsWindow::OnResize(napi_env env, napi_callback_info info)
{
WMError errCode = WMError::WM_OK;
@ -1493,6 +1589,93 @@ napi_value JsWindow::OnResizeWindow(napi_env env, napi_callback_info info)
return result;
}
static void SetResizeWindowAsyncTask(NapiAsyncTask::ExecuteCallback& execute, NapiAsyncTask::CompleteCallback& complete,
wptr<Window> weakToken, int32_t width, int32_t height, std::shared_ptr<WmErrorCode> errCodePtr)
{
execute = [weakToken, errCodePtr, width, height]() {
if (errCodePtr == nullptr) {
return;
}
if (*errCodePtr != WmErrorCode::WM_OK) {
return;
}
auto spWindow = weakToken.promote();
if (spWindow == nullptr) {
TLOGE(WmsLogTag::WMS_LAYOUT, "window is nullptr");
*errCodePtr = WmErrorCode::WM_ERROR_STATE_ABNORMALLY;
return;
}
*errCodePtr = WM_JS_TO_ERROR_CODE_MAP.at(
spWindow->ResizeAsync(static_cast<uint32_t>(width), static_cast<uint32_t>(height)));
};
complete = [weakToken, errCodePtr](napi_env env, NapiAsyncTask& task, int32_t status) {
if (errCodePtr == nullptr) {
task.Reject(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
return;
}
if (*errCodePtr == WmErrorCode::WM_ERROR_INVALID_PARAM) {
task.Reject(env, JsErrUtils::CreateJsError(env, *errCodePtr));
TLOGE(WmsLogTag::WMS_LAYOUT, "Get invalid param");
return;
}
auto weakWindow = weakToken.promote();
if (weakWindow == nullptr) {
task.Reject(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
return;
}
if (*errCodePtr == WmErrorCode::WM_OK) {
task.Resolve(env, NapiGetUndefined(env));
} else {
task.Reject(env, JsErrUtils::CreateJsError(env, *errCodePtr, "JsWindow::OnResizeWindowAsync failed"));
}
TLOGI(WmsLogTag::WMS_LAYOUT, "Window [%{public}u, %{public}s] resize end, err = %{public}d",
weakWindow->GetWindowId(), weakWindow->GetWindowName().c_str(), *errCodePtr);
};
}
napi_value JsWindow::OnResizeWindowAsync(napi_env env, napi_callback_info info)
{
WmErrorCode errCode = WmErrorCode::WM_OK;
size_t argc = 4; // 4: number of arg
napi_value argv[4] = {nullptr};
napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
if (argc < 2) { // 2: minimum param num
WLOGFE("Argc is invalid: %{public}zu", argc);
errCode = WmErrorCode::WM_ERROR_INVALID_PARAM;
}
int32_t width = 0;
if (errCode == WmErrorCode::WM_OK && !ConvertFromJsValue(env, argv[0], width)) {
WLOGFE("Failed to convert parameter to width");
errCode = WmErrorCode::WM_ERROR_INVALID_PARAM;
}
int32_t height = 0;
if (errCode == WmErrorCode::WM_OK && !ConvertFromJsValue(env, argv[1], height)) {
WLOGFE("Failed to convert parameter to height");
errCode = WmErrorCode::WM_ERROR_INVALID_PARAM;
}
if (width <= 0 || height <= 0) {
WLOGFE("width or height should greater than 0!");
errCode = WmErrorCode::WM_ERROR_INVALID_PARAM;
}
if (errCode == WmErrorCode::WM_ERROR_INVALID_PARAM) {
return NapiThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM);
}
wptr<Window> weakToken(windowToken_);
std::shared_ptr<WmErrorCode> errCodePtr = std::make_shared<WmErrorCode>(errCode);
NapiAsyncTask::ExecuteCallback execute;
NapiAsyncTask::CompleteCallback complete;
SetResizeWindowAsyncTask(execute, complete, weakToken, width, height, errCodePtr);
// 2: params num; 2: index of callback
napi_value lastParam = (argc <= 2) ? nullptr :
((argv[2] != nullptr && GetType(env, argv[2]) == napi_function) ? argv[2] : nullptr);
napi_value result = nullptr;
NapiAsyncTask::Schedule("JsWindow::OnResizeWindowAsync",
env, CreateAsyncTaskWithLastParam(env, lastParam, std::move(execute), std::move(complete), &result));
return result;
}
napi_value JsWindow::OnSetWindowType(napi_env env, napi_callback_info info)
{
WMError errCode = WMError::WM_OK;
@ -6116,8 +6299,10 @@ void BindFunctions(napi_env env, napi_value object, const char *moduleName)
BindNativeFunction(env, object, "recover", moduleName, JsWindow::Recover);
BindNativeFunction(env, object, "moveTo", moduleName, JsWindow::MoveTo);
BindNativeFunction(env, object, "moveWindowTo", moduleName, JsWindow::MoveWindowTo);
BindNativeFunction(env, object, "moveWindowToAsync", moduleName, JsWindow::MoveWindowToAsync);
BindNativeFunction(env, object, "resetSize", moduleName, JsWindow::Resize);
BindNativeFunction(env, object, "resize", moduleName, JsWindow::ResizeWindow);
BindNativeFunction(env, object, "resizeAsync", moduleName, JsWindow::ResizeWindowAsync);
BindNativeFunction(env, object, "setWindowType", moduleName, JsWindow::SetWindowType);
BindNativeFunction(env, object, "setWindowMode", moduleName, JsWindow::SetWindowMode);
BindNativeFunction(env, object, "getProperties", moduleName, JsWindow::GetProperties);

View File

@ -53,8 +53,10 @@ public:
static napi_value Recover(napi_env env, napi_callback_info info);
static napi_value MoveTo(napi_env env, napi_callback_info info);
static napi_value MoveWindowTo(napi_env env, napi_callback_info info);
static napi_value MoveWindowToAsync(napi_env env, napi_callback_info info);
static napi_value Resize(napi_env env, napi_callback_info info);
static napi_value ResizeWindow(napi_env env, napi_callback_info info);
static napi_value ResizeWindowAsync(napi_env env, napi_callback_info info);
static napi_value SetWindowType(napi_env env, napi_callback_info info);
static napi_value SetWindowMode(napi_env env, napi_callback_info info);
static napi_value GetProperties(napi_env env, napi_callback_info info);
@ -179,8 +181,10 @@ private:
napi_value OnRecover(napi_env env, napi_callback_info info);
napi_value OnMoveTo(napi_env env, napi_callback_info info);
napi_value OnMoveWindowTo(napi_env env, napi_callback_info info);
napi_value OnMoveWindowToAsync(napi_env env, napi_callback_info info);
napi_value OnResize(napi_env env, napi_callback_info info);
napi_value OnResizeWindow(napi_env env, napi_callback_info info);
napi_value OnResizeWindowAsync(napi_env env, napi_callback_info info);
napi_value OnSetWindowType(napi_env env, napi_callback_info info);
napi_value OnSetWindowMode(napi_env env, napi_callback_info info);
napi_value OnGetProperties(napi_env env, napi_callback_info info);

View File

@ -166,7 +166,9 @@ public:
virtual WMError Show(uint32_t reason = 0, bool withAnimation = false) = 0;
virtual WMError Hide(uint32_t reason = 0, bool withAnimation = false, bool isFromInnerkits = true) = 0;
virtual WMError MoveTo(int32_t x, int32_t y) = 0;
virtual WMError MoveToAsync(int32_t x, int32_t y) { return WMError::WM_ERROR_DEVICE_NOT_SUPPORT; }
virtual WMError Resize(uint32_t width, uint32_t height) = 0;
virtual WMError ResizeAsync(uint32_t width, uint32_t height) { return WMError::WM_ERROR_DEVICE_NOT_SUPPORT; }
virtual WMError SetWindowGravity(WindowGravity gravity, uint32_t percent) = 0;
virtual WMError SetKeepScreenOn(bool keepScreenOn) = 0;
virtual bool IsKeepScreenOn() const = 0;

View File

@ -36,6 +36,9 @@ ohos_shared_library("window_scene_common") {
debug = false
}
sources = [
"src/future_callback.cpp",
"src/future_callback_proxy.cpp",
"src/future_callback_stub.cpp",
"src/session_permission.cpp",
"src/task_scheduler.cpp",
"src/window_session_property.cpp",

View File

@ -0,0 +1,35 @@
/*
* 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.
*/
#ifndef OHOS_ROSEN_FUTURE_CALLBACK_H
#define OHOS_ROSEN_FUTURE_CALLBACK_H
#include "future.h"
#include "future_callback_stub.h"
#include "interfaces/include/ws_common.h"
namespace OHOS {
namespace Rosen {
class FutureCallback : public FutureCallbackStub {
public:
WSError OnUpdateSessionRect(const WSRect& rect) override;
virtual WSRect GetResult(long timeOut) override;
virtual void ResetLock() override;
private:
RunnableFuture<WSRect> future_{};
};
} // namespace Rosen
} // namespace OHOS
#endif // OHOS_ROSEN_FUTURE_CALLBACK_H

View File

@ -0,0 +1,40 @@
/*
* 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.
*/
#ifndef OHOS_ROSEN_FUTURE_CALLBACK_INTERFACE_H
#define OHOS_ROSEN_FUTURE_CALLBACK_INTERFACE_H
#include <iremote_broker.h>
#include "future.h"
#include "interfaces/include/ws_common.h"
namespace OHOS {
namespace Rosen {
class IFutureCallback : public IRemoteBroker {
public:
DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.IFutureCallback");
enum class FutureCallbackMessage : uint32_t {
TRANS_ID_UPDATE_SESSION_RECT = 0,
};
virtual WSError OnUpdateSessionRect(const WSRect& rect) = 0;
virtual WSRect GetResult(long timeOut) { return WSRect({0, 0, 0, 0}); }
virtual void ResetLock() {}
};
} // namespace Rosen
} // namespace OHOS
#endif // OHOS_ROSEN_FUTURE_CALLBACK_INTERFACE_H

View File

@ -0,0 +1,38 @@
/*
* 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.
*/
#ifndef OHOS_ROSEN_FUTURE_CALLBACK_PROXY_H
#define OHOS_ROSEN_FUTURE_CALLBACK_PROXY_H
#include "future_callback_interface.h"
#include "interfaces/include/ws_common.h"
#include "iremote_proxy.h"
namespace OHOS {
namespace Rosen {
class FutureCallbackProxy : public IRemoteProxy<IFutureCallback> {
public:
explicit FutureCallbackProxy(const sptr<IRemoteObject>& impl) : IRemoteProxy<IFutureCallback>(impl) {}
~FutureCallbackProxy() {}
WSError OnUpdateSessionRect(const WSRect& rect) override;
private:
static inline BrokerDelegator<FutureCallbackProxy> delegator_;
};
} // namespace Rosen
} // namespace OHOS
#endif // OHOS_ROSEN_FUTURE_CALLBACK_PROXY_H

View File

@ -0,0 +1,40 @@
/*
* 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.
*/
#ifndef OHOS_ROSEN_FUTURE_CALLBACK_STUB_H
#define OHOS_ROSEN_FUTURE_CALLBACK_STUB_H
#include <map>
#include "future_callback_interface.h"
#include "iremote_stub.h"
namespace OHOS {
namespace Rosen {
class FutureCallbackStub : public IRemoteStub<IFutureCallback> {
public:
FutureCallbackStub() = default;
~FutureCallbackStub() = default;
virtual int OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel& reply,
MessageOption& option) override;
private:
int HandleUpdateSessionRect(MessageParcel& data, MessageParcel& reply);
int ProcessRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel& reply, MessageOption& option);
};
} // namespace Rosen
} // namespace OHOS
#endif // OHOS_ROSEN_FUTURE_CALLBACK_STUB_H

View File

@ -20,6 +20,7 @@
#include <string>
#include <unordered_map>
#include <parcel.h>
#include "future_callback_interface.h"
#include "interfaces/include/ws_common.h"
#include "interfaces/include/ws_common_inner.h"
#include "wm_common.h"
@ -42,6 +43,7 @@ public:
void CopyFrom(const sptr<WindowSessionProperty>& property);
void SetWindowName(const std::string& name);
void SetSessionInfo(const SessionInfo& info);
void SetLayoutCallback(const sptr<IFutureCallback>& callback);
void SetRequestRect(const struct Rect& rect);
void SetWindowRect(const struct Rect& rect);
void SetFocusable(bool isFocusable);
@ -100,6 +102,7 @@ public:
bool GetIsNeedUpdateWindowMode() const;
const std::string& GetWindowName() const;
const SessionInfo& GetSessionInfo() const;
sptr<IFutureCallback> GetLayoutCallback() const;
SessionInfo& EditSessionInfo();
Rect GetWindowRect() const;
Rect GetRequestRect() const;
@ -164,6 +167,8 @@ public:
static void UnmarshallingWindowMask(Parcel& parcel, WindowSessionProperty* property);
bool MarshallingSessionInfo(Parcel& parcel) const;
static bool UnmarshallingSessionInfo(Parcel& parcel, WindowSessionProperty* property);
bool MarshallingFutureCallback(Parcel& parcel) const;
static void UnmarshallingFutureCallback(Parcel& parcel, WindowSessionProperty* property);
void SetTextFieldPositionY(double textFieldPositionY);
void SetTextFieldHeight(double textFieldHeight);
@ -235,6 +240,7 @@ private:
void ReadActionUpdateModeSupportInfo(Parcel& parcel);
std::string windowName_;
SessionInfo sessionInfo_;
sptr<IFutureCallback> layoutCallback_ = nullptr;
Rect requestRect_ { 0, 0, 0, 0 }; // window rect requested by the client (without decoration size)
Rect windowRect_ { 0, 0, 0, 0 }; // actual window rect
WindowType type_ { WindowType::WINDOW_TYPE_APP_MAIN_WINDOW }; // type main window

View File

@ -0,0 +1,39 @@
/*
* 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 "common/include/future_callback.h"
#include "window_manager_hilog.h"
namespace OHOS {
namespace Rosen {
WSError FutureCallback::OnUpdateSessionRect(const WSRect& rect)
{
TLOGI(WmsLogTag::WMS_LAYOUT, "rect:%{public}s", rect.ToString().c_str());
future_.SetValue(rect);
return WSError::WS_OK;
}
WSRect FutureCallback::GetResult(long timeOut)
{
return future_.GetResult(timeOut);
}
void FutureCallback::ResetLock()
{
future_.ResetLock({});
}
} // namespace Rosen
} // namespace OHOS

View File

@ -0,0 +1,50 @@
/*
* 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 <ipc_types.h>
#include <message_option.h>
#include <message_parcel.h>
#include "common/include/future_callback_proxy.h"
#include "window_manager_hilog.h"
namespace OHOS {
namespace Rosen {
WSError FutureCallbackProxy::OnUpdateSessionRect(const WSRect& rect)
{
MessageParcel data;
MessageParcel reply;
MessageOption option(MessageOption::TF_ASYNC);
if (!data.WriteInterfaceToken(GetDescriptor())) {
TLOGE(WmsLogTag::WMS_LAYOUT, "WriteInterfaceToken failed");
return WSError::WS_ERROR_IPC_FAILED;
}
if (!(data.WriteInt32(rect.posX_) && data.WriteInt32(rect.posY_) &&
data.WriteUint32(rect.width_) && data.WriteUint32(rect.height_))) {
TLOGE(WmsLogTag::WMS_LAYOUT, "Write WindowRect failed");
return WSError::WS_ERROR_IPC_FAILED;
}
if (Remote()->SendRequest(static_cast<uint32_t>(FutureCallbackMessage::TRANS_ID_UPDATE_SESSION_RECT),
data, reply, option) != ERR_NONE) {
TLOGE(WmsLogTag::WMS_LAYOUT, "SendRequest failed");
return WSError::WS_ERROR_IPC_FAILED;
}
int32_t ret = reply.ReadInt32();
return static_cast<WSError>(ret);
}
} // namespace Rosen
} // namespace OHOS

View File

@ -0,0 +1,52 @@
/*
* 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 "common/include/future_callback_stub.h"
#include "window_manager_hilog.h"
namespace OHOS {
namespace Rosen {
int FutureCallbackStub::OnRemoteRequest(uint32_t code, MessageParcel& data,
MessageParcel& reply, MessageOption& option)
{
TLOGD(WmsLogTag::WMS_LAYOUT, "OnRemoteRequest code is %{public}u", code);
if (data.ReadInterfaceToken() != GetDescriptor()) {
TLOGE(WmsLogTag::WMS_LAYOUT, "InterfaceToken check failed");
return ERR_INVALID_STATE;
}
return ProcessRemoteRequest(code, data, reply, option);
}
int FutureCallbackStub::ProcessRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel& reply,
MessageOption& option)
{
switch (code) {
case static_cast<uint32_t>(FutureCallbackMessage::TRANS_ID_UPDATE_SESSION_RECT):
return HandleUpdateSessionRect(data, reply);
default:
TLOGE(WmsLogTag::WMS_LAYOUT, "Failed to find function handler!");
return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
}
}
int FutureCallbackStub::HandleUpdateSessionRect(MessageParcel& data, MessageParcel& reply)
{
TLOGD(WmsLogTag::WMS_LAYOUT, "UpdateSessionRect!");
WSRect rect = { data.ReadInt32(), data.ReadInt32(), data.ReadUint32(), data.ReadUint32() };
OnUpdateSessionRect(rect);
return ERR_NONE;
}
} // namespace Rosen
} // namespace OHOS

View File

@ -155,6 +155,11 @@ void WindowSessionProperty::SetSessionInfo(const SessionInfo& info)
sessionInfo_ = info;
}
void WindowSessionProperty::SetLayoutCallback(const sptr<IFutureCallback>& callback)
{
layoutCallback_ = callback;
}
void WindowSessionProperty::SetWindowRect(const struct Rect& rect)
{
windowRect_ = rect;
@ -255,6 +260,11 @@ SessionInfo& WindowSessionProperty::EditSessionInfo()
return sessionInfo_;
}
sptr<IFutureCallback> WindowSessionProperty::GetLayoutCallback() const
{
return layoutCallback_;
}
Rect WindowSessionProperty::GetWindowRect() const
{
return windowRect_;
@ -918,6 +928,29 @@ bool WindowSessionProperty::GetIsSupportDragInPcCompatibleMode() const
return isSupportDragInPcCompatibleMode_;
}
bool WindowSessionProperty::MarshallingFutureCallback(Parcel& parcel) const
{
if (layoutCallback_ == nullptr) {
return false;
}
if (!parcel.WriteObject(layoutCallback_->AsObject())) {
return false;
}
return true;
}
void WindowSessionProperty::UnmarshallingFutureCallback(Parcel& parcel, WindowSessionProperty* property)
{
auto readObject = parcel.ReadObject<IRemoteObject>();
sptr<IFutureCallback> callback = nullptr;
if (readObject != nullptr) {
callback = iface_cast<IFutureCallback>(readObject);
}
if (callback != nullptr) {
property->SetLayoutCallback(callback);
}
}
bool WindowSessionProperty::Marshalling(Parcel& parcel) const
{
return parcel.WriteString(windowName_) && parcel.WriteInt32(windowRect_.posX_) &&
@ -956,7 +989,8 @@ bool WindowSessionProperty::Marshalling(Parcel& parcel) const
parcel.WriteBool(compatibleModeInPc_) &&
parcel.WriteBool(isAppSupportPhoneInPc_) &&
parcel.WriteBool(isSupportDragInPcCompatibleMode_) &&
parcel.WriteBool(isPcAppInPad_);
parcel.WriteBool(isPcAppInPad_) &&
MarshallingFutureCallback(parcel);
}
WindowSessionProperty* WindowSessionProperty::Unmarshalling(Parcel& parcel)
@ -1025,6 +1059,7 @@ WindowSessionProperty* WindowSessionProperty::Unmarshalling(Parcel& parcel)
property->SetIsAppSupportPhoneInPc(parcel.ReadBool());
property->SetIsSupportDragInPcCompatibleMode(parcel.ReadBool());
property->SetIsPcAppInPad(parcel.ReadBool());
UnmarshallingFutureCallback(parcel, property);
return property;
}
@ -1072,6 +1107,7 @@ void WindowSessionProperty::CopyFrom(const sptr<WindowSessionProperty>& property
isLayoutFullScreen_ = property->isLayoutFullScreen_;
windowMask_ = property->windowMask_;
isShaped_ = property->isShaped_;
layoutCallback_ = property->layoutCallback_;
}
bool WindowSessionProperty::Write(Parcel& parcel, WSPropertyChangeAction action)

View File

@ -0,0 +1,38 @@
/*
* 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.
*/
#ifndef OHOS_ROSEN_FUTURE_CALLBACK_STUB_MOCKER_H
#define OHOS_ROSEN_FUTURE_CALLBACK_STUB_MOCKER_H
#include <gmock/gmock.h>
#include <ipc_types.h>
#include "common/include/future_callback_stub.h"
namespace OHOS {
namespace Rosen {
class FutureCallbackStubMocker : public FutureCallbackStub {
public:
FutureCallbackStubMocker() {};
~FutureCallbackStubMocker() {};
WSError OnUpdateSessionRect(const WSRect& rect) override { return WSError::WS_OK; }
MOCK_METHOD(int, OnRemoteRequest,
(uint32_t code, MessageParcel& data, MessageParcel& reply, MessageOption& option), (override));
MOCK_METHOD2(HandleUpdateSessionRect, int(MessageParcel& data, MessageParcel& reply));
};
} // namespace Rosen
} // namespace OHOS
#endif // OHOS_ROSEN_FUTURE_CALLBACK_STUB_MOCKER_H

View File

@ -33,6 +33,8 @@ group("unittest") {
":ws_fold_screen_controller_test",
":ws_fold_screen_sensor_manager_test",
":ws_fold_screen_state_machine_test",
":ws_future_callback_proxy_test",
":ws_future_callback_stub_test",
":ws_hidumper_controller_test",
":ws_intention_event_manager_test",
":ws_keyboard_session_test",
@ -1560,6 +1562,32 @@ ohos_unittest("ws_hidumper_controller_test") {
]
}
ohos_unittest("ws_future_callback_proxy_test") {
module_out_path = module_out_path
sources = [ "future_callback_proxy_test.cpp" ]
deps = [ ":ws_unittest_common" ]
external_deps = [
"c_utils:utils",
"hilog:libhilog",
]
}
ohos_unittest("ws_future_callback_stub_test") {
module_out_path = module_out_path
sources = [ "future_callback_stub_test.cpp" ]
deps = [ ":ws_unittest_common" ]
external_deps = [
"c_utils:utils",
"hilog:libhilog",
]
}
ohos_unittest("ws_session_stub_test") {
module_out_path = module_out_path

View File

@ -0,0 +1,68 @@
/*
* 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 <gtest/gtest.h>
#include "future_callback_proxy.h"
#include "iremote_object_mocker.h"
#include "window_session_property.h"
using namespace testing;
using namespace testing::ext;
namespace OHOS {
namespace Rosen {
class FutureCallbackProxyTest : public testing::Test {
public:
static void SetUpTestCase();
static void TearDownTestCase();
void SetUp() override;
void TearDown() override;
};
void FutureCallbackProxyTest::SetUpTestCase()
{
}
void FutureCallbackProxyTest::TearDownTestCase()
{
}
void FutureCallbackProxyTest::SetUp()
{
}
void FutureCallbackProxyTest::TearDown()
{
}
namespace {
/**
* @tc.name: OnUpdateSessionRect
* @tc.desc: normal function
* @tc.type: FUNC
*/
HWTEST_F(FutureCallbackProxyTest, OnUpdateSessionRect, Function | SmallTest | Level2)
{
GTEST_LOG_(INFO) << "FutureCallbackProxyTest: OnUpdateSessionRect start";
sptr<IRemoteObject> iRemoteObjectMocker = new IRemoteObjectMocker();
FutureCallbackProxy* fProxy = new(std::nothrow) FutureCallbackProxy(iRemoteObjectMocker);
WSRect rect{.posX_ = 1, .posY_ = 1, .width_ = 100, .height_ = 100};
WSError res = fProxy->OnUpdateSessionRect(rect);
ASSERT_EQ(res, WSError::WS_OK);
GTEST_LOG_(INFO) << "FutureCallbackProxyTest: OnUpdateSessionRect end";
}
} // namespace
} // namespace Rosen
} // namespace OHOS

View File

@ -0,0 +1,80 @@
/*
* 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 <gtest/gtest.h>
#include "future_callback_stub.h"
#include "mock/mock_future_callback_stub.h"
#include "window_session_property.h"
using namespace testing;
using namespace testing::ext;
namespace OHOS {
namespace Rosen {
class FutureCallbackStubTest : public testing::Test {
public:
static void SetUpTestCase();
static void TearDownTestCase();
void SetUp() override;
void TearDown() override;
private:
sptr<FutureCallbackStub> futureCallback_ = nullptr;
};
void FutureCallbackStubTest::SetUpTestCase()
{
}
void FutureCallbackStubTest::TearDownTestCase()
{
}
void FutureCallbackStubTest::SetUp()
{
futureCallback_ = new (std::nothrow) FutureCallbackStubMocker();
EXPECT_NE(nullptr, futureCallback_);
}
void FutureCallbackStubTest::TearDown()
{
futureCallback_ = nullptr;
}
namespace {
/**
* @tc.name: OnRemoteRequest01
* @tc.desc: sessionStub OnRemoteRequest01
* @tc.type: FUNC
* @tc.require: #I6JLSI
*/
HWTEST_F(FutureCallbackStubTest, OnRemoteRequest01, Function | SmallTest | Level2)
{
uint32_t code = 0;
MessageParcel data;
MessageParcel reply;
MessageOption option = {MessageOption::TF_ASYNC};
auto res = futureCallback_->OnRemoteRequest(code, data, reply, option);
ASSERT_EQ(ERR_NONE, res);
data.WriteInterfaceToken(u"OHOS.IFutureCallback");
res = futureCallback_->OnRemoteRequest(code, data, reply, option);
ASSERT_EQ(ERR_NONE, res);
code = 1;
res = futureCallback_->OnRemoteRequest(code, data, reply, option);
ASSERT_EQ(ERR_NONE, res);
}
} // namespace
} // namespace Rosen
} // namespace OHOS

View File

@ -14,6 +14,7 @@
*/
#include <gtest/gtest.h>
#include "future_callback.h"
#include "window_session_property.h"
using namespace testing;
@ -1028,6 +1029,44 @@ HWTEST_F(WindowSessionPropertyTest, SetIsPcAppInPad, Function | SmallTest | Leve
delete property;
}
/**
* @tc.name: MarshallingFutureCallback
* @tc.desc: MarshallingFutureCallback
* @tc.type: FUNC
*/
HWTEST_F(WindowSessionPropertyTest, MarshallingFutureCallback, Function | SmallTest | Level2)
{
sptr<WindowSessionProperty> property = sptr<WindowSessionProperty>::MakeSptr();
if (property == nullptr) {
return;
}
Parcel parcel = Parcel();
property->SetLayoutCallback(nullptr);
ASSERT_EQ(false, property->MarshallingFutureCallback(parcel));
auto layoutCallback = sptr<FutureCallback>::MakeSptr();
ASSERT_EQ(false, property->MarshallingFutureCallback(parcel));
}
/**
* @tc.name: UnmarshallingFutureCallback
* @tc.desc: UnmarshallingFutureCallback
* @tc.type: FUNC
*/
HWTEST_F(WindowSessionPropertyTest, UnmarshallingFutureCallback, Function | SmallTest | Level2)
{
sptr<WindowSessionProperty> property = sptr<WindowSessionProperty>::MakeSptr();
if (property == nullptr) {
return;
}
Parcel parcel = Parcel();
WindowSessionProperty windowSessionProperty;
windowSessionProperty.UnmarshallingFutureCallback(parcel, property);
auto layoutCallback = sptr<FutureCallback>::MakeSptr();
ASSERT_NE(nullptr, layoutCallback);
parcel.WriteObject(layoutCallback->AsObject());
windowSessionProperty.UnmarshallingFutureCallback(parcel, property);
ASSERT_NE(nullptr, property->GetLayoutCallback());
}
} // namespace
} // namespace Rosen
} // namespace OHOS

View File

@ -67,7 +67,9 @@ public:
WMError Close() override;
WindowMode GetMode() const override;
WMError MoveTo(int32_t x, int32_t y) override;
WMError MoveToAsync(int32_t x, int32_t y) override;
WMError Resize(uint32_t width, uint32_t height) override;
WMError ResizeAsync(uint32_t width, uint32_t height) override;
WmErrorCode RaiseToAppTop() override;
WmErrorCode RaiseAboveTarget(int32_t subWindowId) override;
void PerformBack() override;

View File

@ -29,6 +29,7 @@
#include "singleton_container.h"
#include "common/include/window_session_property.h"
#include "common/include/future_callback.h"
#include "interfaces/include/ws_common.h"
#include "interfaces/include/ws_common_inner.h"
#include "session/container/include/zidl/session_stage_stub.h"
@ -374,6 +375,8 @@ private:
bool CheckIfNeedCommitRsTransaction(WindowSizeChangeReason wmReason);
void UpdateRectForRotation(const Rect& wmRect, const Rect& preRect, WindowSizeChangeReason wmReason,
const std::shared_ptr<RSTransaction>& rsTransaction = nullptr);
void UpdateRectForOtherReason(const Rect& wmRect, const Rect& preRect, WindowSizeChangeReason wmReason,
const std::shared_ptr<RSTransaction>& rsTransaction = nullptr);
void NotifyRotationAnimationEnd();
void SubmitNoInteractionMonitorTask(int32_t eventId, const IWindowNoInteractionListenerSptr& listener);
bool IsUserOrientation(Orientation orientation) const;

View File

@ -24,6 +24,7 @@
#include <application_context.h>
#include "anr_handler.h"
#include "color_parser.h"
#include "common/include/future_callback.h"
#include "display_info.h"
#include "singleton_container.h"
#include "display_manager.h"
@ -88,6 +89,7 @@ union WSColorParam {
namespace {
constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowSceneSessionImpl"};
constexpr int32_t WINDOW_DETACH_TIMEOUT = 300;
constexpr int32_t WINDOW_LAYOUT_TIMEOUT = 30;
const std::string PARAM_DUMP_HELP = "-h";
constexpr float MIN_GRAY_SCALE = 0.0f;
constexpr float MAX_GRAY_SCALE = 1.0f;
@ -1398,6 +1400,56 @@ WMError WindowSceneSessionImpl::MoveTo(int32_t x, int32_t y)
return static_cast<WMError>(ret);
}
WMError WindowSceneSessionImpl::MoveToAsync(int32_t x, int32_t y)
{
TLOGI(WmsLogTag::WMS_LAYOUT, "Id:%{public}d MoveTo %{public}d %{public}d", property_->GetPersistentId(), x, y);
if (IsWindowSessionInvalid()) {
return WMError::WM_ERROR_INVALID_WINDOW;
}
if (property_->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
TLOGW(WmsLogTag::WMS_LAYOUT, "Unsupported operation for pip window");
return WMError::WM_ERROR_INVALID_OPERATION;
}
if (GetMode() != WindowMode::WINDOW_MODE_FLOATING) {
TLOGW(WmsLogTag::WMS_LAYOUT, "FullScreen window could not move, winId:%{public}u", GetWindowId());
return WMError::WM_ERROR_OPER_FULLSCREEN_FAILED;
}
const auto& windowRect = GetRect();
const auto& requestRect = GetRequestRect();
if (WindowHelper::IsSubWindow(GetType())) {
auto mainWindow = FindMainWindowWithContext();
if (mainWindow != nullptr && (mainWindow->GetMode() == WindowMode::WINDOW_MODE_SPLIT_SECONDARY ||
mainWindow->GetMode() == WindowMode::WINDOW_MODE_SPLIT_PRIMARY)) {
if (requestRect.posX_ == x && requestRect.posY_ == y) {
TLOGW(WmsLogTag::WMS_LAYOUT, "Request same position in multiWindow will not update");
return WMError::WM_OK;
}
}
}
Rect newRect = { x, y, requestRect.width_, requestRect.height_ }; // must keep x/y
TLOGI(WmsLogTag::WMS_LAYOUT, "Id:%{public}d, state: %{public}d, type: %{public}d, mode: %{public}d, requestRect: "
"[%{public}d, %{public}d, %{public}d, %{public}d], windowRect: [%{public}d, %{public}d, "
"%{public}d, %{public}d], newRect: [%{public}d, %{public}d, %{public}d, %{public}d]",
property_->GetPersistentId(), state_, GetType(), GetMode(), requestRect.posX_, requestRect.posY_,
requestRect.width_, requestRect.height_, windowRect.posX_, windowRect.posY_,
windowRect.width_, windowRect.height_, newRect.posX_, newRect.posY_,
newRect.width_, newRect.height_);
property_->SetRequestRect(newRect);
WSRect wsRect = { newRect.posX_, newRect.posY_, newRect.width_, newRect.height_ };
auto hostSession = GetHostSession();
CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
auto ret = hostSession->UpdateSessionRect(wsRect, SizeChangeReason::MOVE);
if (state_ == WindowState::STATE_SHOWN && property_) {
sptr<IFutureCallback> layoutCallback = property_->GetLayoutCallback();
if (layoutCallback) {
layoutCallback->ResetLock();
layoutCallback->GetResult(WINDOW_LAYOUT_TIMEOUT);
}
}
return static_cast<WMError>(ret);
}
void WindowSceneSessionImpl::LimitCameraFloatWindowMininumSize(uint32_t& width, uint32_t& height, float& vpr)
{
// Float camera window has a special limit:
@ -1548,6 +1600,57 @@ WMError WindowSceneSessionImpl::Resize(uint32_t width, uint32_t height)
return static_cast<WMError>(ret);
}
WMError WindowSceneSessionImpl::ResizeAsync(uint32_t width, uint32_t height)
{
TLOGI(WmsLogTag::WMS_LAYOUT, "Id:%{public}d resize %{public}u %{public}u",
property_->GetPersistentId(), width, height);
if (IsWindowSessionInvalid()) {
return WMError::WM_ERROR_INVALID_WINDOW;
}
if (property_->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
TLOGW(WmsLogTag::WMS_LAYOUT, "Unsupported operation for pip window");
return WMError::WM_ERROR_INVALID_OPERATION;
}
if (GetMode() != WindowMode::WINDOW_MODE_FLOATING) {
TLOGW(WmsLogTag::WMS_LAYOUT, "Fullscreen window could not resize, winId: %{public}u", GetWindowId());
return WMError::WM_ERROR_OPER_FULLSCREEN_FAILED;
}
LimitWindowSize(width, height);
const auto& windowRect = GetRect();
const auto& requestRect = GetRequestRect();
if (WindowHelper::IsSubWindow(GetType())) {
auto mainWindow = FindMainWindowWithContext();
if (mainWindow != nullptr && (mainWindow->GetMode() == WindowMode::WINDOW_MODE_SPLIT_SECONDARY ||
mainWindow->GetMode() == WindowMode::WINDOW_MODE_SPLIT_PRIMARY)) {
if (width == requestRect.width_ && height == requestRect.height_) {
TLOGW(WmsLogTag::WMS_LAYOUT, "Request same size in multiWindow will not update, return");
return WMError::WM_OK;
}
}
}
Rect newRect = { requestRect.posX_, requestRect.posY_, width, height }; // must keep w/h
TLOGI(WmsLogTag::WMS_LAYOUT, "Id:%{public}d, state: %{public}d, type: %{public}d, mode: %{public}d, requestRect: "
"[%{public}d, %{public}d, %{public}d, %{public}d], windowRect: [%{public}d, %{public}d, "
"%{public}d, %{public}d], newRect: [%{public}d, %{public}d, %{public}d, %{public}d]",
property_->GetPersistentId(), state_, GetType(), GetMode(), requestRect.posX_, requestRect.posY_,
requestRect.width_, requestRect.height_, windowRect.posX_, windowRect.posY_,
windowRect.width_, windowRect.height_, newRect.posX_, newRect.posY_,
newRect.width_, newRect.height_);
property_->SetRequestRect(newRect);
WSRect wsRect = { newRect.posX_, newRect.posY_, newRect.width_, newRect.height_ };
auto hostSession = GetHostSession();
CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
auto ret = hostSession->UpdateSessionRect(wsRect, SizeChangeReason::RESIZE);
if (state_ == WindowState::STATE_SHOWN && property_) {
sptr<IFutureCallback> layoutCallback = property_->GetLayoutCallback();
if (layoutCallback) {
layoutCallback->ResetLock();
layoutCallback->GetResult(WINDOW_LAYOUT_TIMEOUT);
}
}
return static_cast<WMError>(ret);
}
WMError WindowSceneSessionImpl::SetAspectRatio(float ratio)
{
auto hostSession = GetHostSession();

View File

@ -191,6 +191,8 @@ WindowSessionImpl::WindowSessionImpl(const sptr<WindowOption>& option)
isMainHandlerAvailable_ = option->GetMainHandlerAvailable();
isIgnoreSafeArea_ = WindowHelper::IsSubWindow(optionWindowType);
windowOption_ = option;
auto layoutCallback = sptr<FutureCallback>::MakeSptr();
property_->SetLayoutCallback(layoutCallback);
surfaceNode_ = CreateSurfaceNode(property_->GetWindowName(), optionWindowType);
handler_ = std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::GetMainEventRunner());
if (surfaceNode_ != nullptr) {
@ -586,29 +588,8 @@ WSError WindowSessionImpl::UpdateRect(const WSRect& rect, SizeChangeReason reaso
if (handler_ != nullptr && wmReason == WindowSizeChangeReason::ROTATION) {
postTaskDone_ = false;
UpdateRectForRotation(wmRect, preRect, wmReason, rsTransaction);
} else if (handler_ != nullptr) {
auto task = [weak = wptr(this), wmReason, wmRect, preRect, rsTransaction]() mutable {
auto window = weak.promote();
if (!window) {
TLOGE(WmsLogTag::WMS_LAYOUT, "window is null, updateViewPortConfig failed");
return;
}
if (rsTransaction && window->CheckIfNeedCommitRsTransaction(wmReason)) {
RSTransaction::FlushImplicitTransaction();
rsTransaction->Begin();
}
if ((wmRect != preRect) || (wmReason != window->lastSizeChangeReason_) ||
!window->postTaskDone_) {
window->NotifySizeChange(wmRect, wmReason);
window->lastSizeChangeReason_ = wmReason;
}
window->UpdateViewportConfig(wmRect, wmReason, rsTransaction);
if (rsTransaction && window->CheckIfNeedCommitRsTransaction(wmReason)) {
rsTransaction->Commit();
}
window->postTaskDone_ = true;
};
handler_->PostTask(task, "WMS_WindowSessionImpl_UpdateRectForNoRotation");
} else if (handler_ != nullptr && rsTransaction != nullptr && CheckIfNeedCommitRsTransaction(wmReason)) {
UpdateRectForOtherReason(wmRect, preRect, wmReason, rsTransaction);
} else {
if ((wmRect != preRect) || (wmReason != lastSizeChangeReason_) || !postTaskDone_) {
NotifySizeChange(wmRect, wmReason);
@ -617,6 +598,12 @@ WSError WindowSessionImpl::UpdateRect(const WSRect& rect, SizeChangeReason reaso
}
UpdateViewportConfig(wmRect, wmReason, rsTransaction);
}
if (property_) {
sptr<IFutureCallback> layoutCallback = property_->GetLayoutCallback();
if (layoutCallback) {
layoutCallback->OnUpdateSessionRect(rect);
}
}
return WSError::WS_OK;
}
@ -664,6 +651,33 @@ void WindowSessionImpl::UpdateRectForRotation(const Rect& wmRect, const Rect& pr
}, "WMS_WindowSessionImpl_UpdateRectForRotation");
}
void WindowSessionImpl::UpdateRectForOtherReason(const Rect& wmRect, const Rect& preRect,
WindowSizeChangeReason wmReason, const std::shared_ptr<RSTransaction>& rsTransaction)
{
auto task = [weak = wptr(this), wmReason, wmRect, preRect, rsTransaction]() mutable {
auto window = weak.promote();
if (!window) {
TLOGE(WmsLogTag::WMS_LAYOUT, "window is null, updateViewPortConfig failed");
return;
}
if (rsTransaction) {
RSTransaction::FlushImplicitTransaction();
rsTransaction->Begin();
}
if ((wmRect != preRect) || (wmReason != window->lastSizeChangeReason_) ||
!window->postTaskDone_) {
window->NotifySizeChange(wmRect, wmReason);
window->lastSizeChangeReason_ = wmReason;
}
window->UpdateViewportConfig(wmRect, wmReason, rsTransaction);
if (rsTransaction) {
rsTransaction->Commit();
}
window->postTaskDone_ = true;
};
handler_->PostTask(task, "WMS_WindowSessionImpl_UpdateRectForOtherReason");
}
void WindowSessionImpl::NotifyRotationAnimationEnd()
{
std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();

View File

@ -16,6 +16,7 @@
#include <gtest/gtest.h>
#include <parameters.h>
#include "ability_context_impl.h"
#include "common/include/future_callback.h"
#include "display_info.h"
#include "mock_session.h"
#include "mock_uicontent.h"
@ -542,6 +543,160 @@ HWTEST_F(WindowSceneSessionImplTest4, SetSpecificBarProperty, Function | SmallTe
EXPECT_EQ(WMError::WM_ERROR_INVALID_WINDOW, ret);
}
/**
* @tc.name: MoveToAsync01
* @tc.desc: MoveToAsync
* @tc.type: FUNC
*/
HWTEST_F(WindowSceneSessionImplTest4, MoveToAsync01, Function | SmallTest | Level2)
{
sptr<WindowOption> option = new (std::nothrow) WindowOption();
ASSERT_NE(nullptr, option);
option->SetWindowName("MoveToAsync01");
option->SetWindowMode(WindowMode::WINDOW_MODE_FULLSCREEN);
option->SetWindowType(WindowType::WINDOW_TYPE_PIP);
sptr<WindowSceneSessionImpl> window = new (std::nothrow) WindowSceneSessionImpl(option);
ASSERT_NE(nullptr, window);
ASSERT_EQ(WMError::WM_ERROR_INVALID_WINDOW, window->MoveToAsync(10, 10));
window->property_->SetPersistentId(997);
SessionInfo sessionInfo = { "CreateTestBundle", "CreateTestModule", "CreateTestAbility" };
sptr<SessionMocker> session = new (std::nothrow) SessionMocker(sessionInfo);
ASSERT_NE(nullptr, session);
window->hostSession_ = session;
ASSERT_EQ(WMError::WM_ERROR_INVALID_OPERATION, window->MoveToAsync(10, 10));
}
/**
* @tc.name: MoveToAsync02
* @tc.desc: MoveToAsync
* @tc.type: FUNC
*/
HWTEST_F(WindowSceneSessionImplTest4, MoveToAsync02, Function | SmallTest | Level2)
{
sptr<WindowOption> option = new (std::nothrow) WindowOption();
ASSERT_NE(nullptr, option);
option->SetWindowName("MoveToAsync02");
option->SetWindowMode(WindowMode::WINDOW_MODE_FULLSCREEN);
option->SetWindowType(WindowType::WINDOW_TYPE_APP_MAIN_WINDOW);
sptr<WindowSceneSessionImpl> window = new (std::nothrow) WindowSceneSessionImpl(option);
ASSERT_NE(nullptr, window);
window->property_->SetPersistentId(998);
SessionInfo sessionInfo = { "CreateTestBundle", "CreateTestModule", "CreateTestAbility" };
sptr<SessionMocker> session = new (std::nothrow) SessionMocker(sessionInfo);
ASSERT_NE(nullptr, session);
window->hostSession_ = session;
sptr<WindowOption> subOption = new (std::nothrow) WindowOption();
ASSERT_NE(nullptr, subOption);
subOption->SetWindowName("subMoveToAsync02");
subOption->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
subOption->SetWindowType(WindowType::WINDOW_TYPE_APP_SUB_WINDOW);
sptr<WindowSceneSessionImpl> subWindow = new (std::nothrow) WindowSceneSessionImpl(subOption);
ASSERT_NE(nullptr, subWindow);
subWindow->property_->SetPersistentId(999);
SessionInfo subSessionInfo = { "subCreateTestBundle", "subCreateTestModule", "subCreateTestAbility" };
sptr<SessionMocker> subSession = new (std::nothrow) SessionMocker(subSessionInfo);
ASSERT_NE(nullptr, subSession);
subWindow->hostSession_ = subSession;
ASSERT_EQ(WMError::WM_OK, subWindow->MoveToAsync(10, 10));
ASSERT_EQ(WMError::WM_OK, window->Create(abilityContext_, session));
ASSERT_EQ(WMError::WM_OK, subWindow->Create(abilityContext_, subSession));
subWindow->windowSessionMap_.insert(std::make_pair("MoveToAsync02", std::make_pair(998, window)));
ASSERT_EQ(WMError::WM_OK, subWindow->MoveToAsync(10, 10));
window->SetWindowMode(WindowMode::WINDOW_MODE_SPLIT_SECONDARY);
ASSERT_EQ(WMError::WM_OK, subWindow->MoveToAsync(10, 10));
window->SetWindowMode(WindowMode::WINDOW_MODE_SPLIT_PRIMARY);
ASSERT_EQ(WMError::WM_OK, subWindow->MoveToAsync(10, 10));
Rect request = { 100, 100, 100, 100 };
subWindow->property_->SetRequestRect(request);
ASSERT_EQ(WMError::WM_OK, subWindow->MoveToAsync(10, 10));
auto layoutCallback = sptr<FutureCallback>::MakeSptr();
subWindow->property_->SetLayoutCallback(layoutCallback);
window->SetWindowMode(WindowMode::WINDOW_MODE_FULLSCREEN);
subWindow->state_ = WindowState::STATE_HIDDEN;
ASSERT_EQ(WMError::WM_OK, subWindow->MoveToAsync(10, 10));
subWindow->state_ = WindowState::STATE_SHOWN;
ASSERT_EQ(WMError::WM_OK, subWindow->MoveToAsync(10, 10));
}
/**
* @tc.name: ResizeAsync01
* @tc.desc: ResizeAsync
* @tc.type: FUNC
*/
HWTEST_F(WindowSceneSessionImplTest4, ResizeAsync01, Function | SmallTest | Level2)
{
sptr<WindowOption> option = new (std::nothrow) WindowOption();
ASSERT_NE(nullptr, option);
option->SetWindowName("ResizeAsync01");
option->SetWindowMode(WindowMode::WINDOW_MODE_FULLSCREEN);
option->SetWindowType(WindowType::WINDOW_TYPE_PIP);
sptr<WindowSceneSessionImpl> window = new (std::nothrow) WindowSceneSessionImpl(option);
ASSERT_NE(nullptr, window);
ASSERT_EQ(WMError::WM_ERROR_INVALID_WINDOW, window->ResizeAsync(500, 500));
window->property_->SetPersistentId(990);
SessionInfo sessionInfo = { "CreateTestBundle", "CreateTestModule", "CreateTestAbility" };
sptr<SessionMocker> session = new (std::nothrow) SessionMocker(sessionInfo);
ASSERT_NE(nullptr, session);
window->hostSession_ = session;
ASSERT_EQ(WMError::WM_ERROR_INVALID_OPERATION, window->ResizeAsync(500, 500));
}
/**
* @tc.name: ResizeAsync02
* @tc.desc: ResizeAsync
* @tc.type: FUNC
*/
HWTEST_F(WindowSceneSessionImplTest4, ResizeAsync02, Function | SmallTest | Level2)
{
sptr<WindowOption> option = new (std::nothrow) WindowOption();
ASSERT_NE(nullptr, option);
option->SetWindowName("ResizeAsync02");
option->SetWindowMode(WindowMode::WINDOW_MODE_FULLSCREEN);
option->SetWindowType(WindowType::WINDOW_TYPE_APP_MAIN_WINDOW);
sptr<WindowSceneSessionImpl> window = new (std::nothrow) WindowSceneSessionImpl(option);
ASSERT_NE(nullptr, window);
window->property_->SetPersistentId(991);
SessionInfo sessionInfo = { "CreateTestBundle", "CreateTestModule", "CreateTestAbility" };
sptr<SessionMocker> session = new (std::nothrow) SessionMocker(sessionInfo);
ASSERT_NE(nullptr, session);
window->hostSession_ = session;
sptr<WindowOption> subOption = new (std::nothrow) WindowOption();
ASSERT_NE(nullptr, subOption);
subOption->SetWindowName("subResizeAsync02");
subOption->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
subOption->SetWindowType(WindowType::WINDOW_TYPE_APP_SUB_WINDOW);
sptr<WindowSceneSessionImpl> subWindow = new (std::nothrow) WindowSceneSessionImpl(subOption);
ASSERT_NE(nullptr, subWindow);
subWindow->property_->SetPersistentId(992);
SessionInfo subSessionInfo = { "subCreateTestBundle", "subCreateTestModule", "subCreateTestAbility" };
sptr<SessionMocker> subSession = new (std::nothrow) SessionMocker(subSessionInfo);
ASSERT_NE(nullptr, subSession);
subWindow->hostSession_ = subSession;
ASSERT_EQ(WMError::WM_OK, subWindow->ResizeAsync(500, 500));
ASSERT_EQ(WMError::WM_OK, window->Create(abilityContext_, session));
ASSERT_EQ(WMError::WM_OK, subWindow->Create(abilityContext_, subSession));
subWindow->windowSessionMap_.insert(std::make_pair("ResizeAsync02", std::make_pair(998, window)));
ASSERT_EQ(WMError::WM_OK, subWindow->ResizeAsync(500, 500));
window->SetWindowMode(WindowMode::WINDOW_MODE_SPLIT_SECONDARY);
ASSERT_EQ(WMError::WM_OK, subWindow->ResizeAsync(500, 500));
window->SetWindowMode(WindowMode::WINDOW_MODE_SPLIT_PRIMARY);
ASSERT_EQ(WMError::WM_OK, subWindow->ResizeAsync(500, 500));
Rect request = { 100, 100, 600, 600 };
subWindow->property_->SetRequestRect(request);
ASSERT_EQ(WMError::WM_OK, subWindow->ResizeAsync(500, 500));
auto layoutCallback = sptr<FutureCallback>::MakeSptr();
subWindow->property_->SetLayoutCallback(layoutCallback);
window->SetWindowMode(WindowMode::WINDOW_MODE_FULLSCREEN);
subWindow->state_ = WindowState::STATE_HIDDEN;
ASSERT_EQ(WMError::WM_OK, subWindow->ResizeAsync(500, 500));
subWindow->state_ = WindowState::STATE_SHOWN;
ASSERT_EQ(WMError::WM_OK, subWindow->ResizeAsync(500, 500));
}
/**
* @tc.name: NotifyDialogStateChange
* @tc.desc: NotifyDialogStateChange

View File

@ -19,6 +19,7 @@
#include "ability_context_impl.h"
#include "accessibility_event_info.h"
#include "color_parser.h"
#include "common/include/future_callback.h"
#include "mock_session.h"
#include "window_helper.h"
#include "window_session_impl.h"
@ -897,6 +898,46 @@ HWTEST_F(WindowSessionImplTest4, GetTitleButtonVisible01, Function | SmallTest |
ASSERT_EQ(hideSplitButton, true);
}
/**
* @tc.name: UpdateRect03
* @tc.desc: UpdateRect
* @tc.type: FUNC
*/
HWTEST_F(WindowSessionImplTest4, UpdateRect03, Function | SmallTest | Level2)
{
sptr<WindowOption> option = new WindowOption();
option->SetWindowName("WindowSessionCreateCheck");
sptr<WindowSessionImpl> window = new (std::nothrow) WindowSessionImpl(option);
ASSERT_NE(window, nullptr);
WSRect rect;
rect.posX_ = 0;
rect.posY_ = 0;
rect.height_ = 0;
rect.width_ = 0;
Rect rectW; // GetRect().IsUninitializedRect is true
rectW.posX_ = 0;
rectW.posY_ = 0;
rectW.height_ = 0; // rectW - rect > 50
rectW.width_ = 0; // rectW - rect > 50
window->property_->SetWindowRect(rectW);
SizeChangeReason reason = SizeChangeReason::UNDEFINED;
WSError res = window->UpdateRect(rect, reason);
ASSERT_EQ(res, WSError::WS_OK);
rect.height_ = 50;
rect.width_ = 50;
rectW.height_ = 50;
rectW.width_ = 50;
auto layoutCallback = sptr<FutureCallback>::MakeSptr();
window->property_->SetLayoutCallback(layoutCallback);
window->property_->SetWindowRect(rectW);
res = window->UpdateRect(rect, reason);
ASSERT_EQ(res, WSError::WS_OK);
}
/**
* @tc.name: GetTitleButtonVisible02
* @tc.desc: GetTitleButtonVisible