mirror of
https://github.com/openharmony/windowmanager.git
synced 2026-07-19 17:08:11 -04:00
@@ -65,6 +65,7 @@ public:
|
||||
virtual bool SetDisplayState(DisplayState state);
|
||||
virtual DisplayState GetDisplayState(DisplayId displayId);
|
||||
virtual void NotifyDisplayEvent(DisplayEvent event);
|
||||
virtual bool SetFreeze(std::vector<DisplayId> displayIds, bool isFreeze);
|
||||
virtual sptr<DisplayInfo> GetDisplayInfo(DisplayId displayId);
|
||||
private:
|
||||
static inline SingletonDelegator<DisplayManagerAdapter> delegator;
|
||||
|
||||
@@ -627,4 +627,24 @@ void DisplayManager::NotifyDisplayEvent(DisplayEvent event)
|
||||
WLOGFI("DisplayEvent:%{public}u", event);
|
||||
SingletonContainer::Get<DisplayManagerAdapter>().NotifyDisplayEvent(event);
|
||||
}
|
||||
|
||||
bool DisplayManager::Freeze(std::vector<DisplayId> displayIds)
|
||||
{
|
||||
WLOGFD("freeze display");
|
||||
if (displayIds.size() == 0) {
|
||||
WLOGFE("freeze display fail, num of display is 0");
|
||||
return false;
|
||||
}
|
||||
return SingletonContainer::Get<DisplayManagerAdapter>().SetFreeze(displayIds, true);
|
||||
}
|
||||
|
||||
bool DisplayManager::Unfreeze(std::vector<DisplayId> displayIds)
|
||||
{
|
||||
WLOGFD("unfreeze display");
|
||||
if (displayIds.size() == 0) {
|
||||
WLOGFE("unfreeze display fail, num of display is 0");
|
||||
return false;
|
||||
}
|
||||
return SingletonContainer::Get<DisplayManagerAdapter>().SetFreeze(displayIds, false);
|
||||
}
|
||||
} // namespace OHOS::Rosen
|
||||
@@ -202,6 +202,12 @@ void DisplayManagerAdapter::NotifyDisplayEvent(DisplayEvent event)
|
||||
displayManagerServiceProxy_->NotifyDisplayEvent(event);
|
||||
}
|
||||
|
||||
bool DisplayManagerAdapter::SetFreeze(std::vector<DisplayId> displayIds, bool isFreeze)
|
||||
{
|
||||
INIT_PROXY_CHECK_RETURN(false);
|
||||
return displayManagerServiceProxy_->SetFreeze(displayIds, isFreeze);
|
||||
}
|
||||
|
||||
bool BaseAdapter::InitDMSProxy()
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(mutex_);
|
||||
|
||||
@@ -22,6 +22,11 @@
|
||||
#include "display_info.h"
|
||||
|
||||
namespace OHOS::Rosen {
|
||||
enum class FreezeFlag : uint32_t {
|
||||
FREEZING,
|
||||
UNFREEZING,
|
||||
};
|
||||
|
||||
class AbstractDisplay : public RefBase {
|
||||
public:
|
||||
constexpr static int32_t DEFAULT_WIDTH = 720;
|
||||
@@ -45,6 +50,8 @@ public:
|
||||
bool BindAbstractScreen(ScreenId dmsScreenId);
|
||||
bool BindAbstractScreen(sptr<AbstractScreen> abstractDisplay);
|
||||
sptr<DisplayInfo> ConvertToDisplayInfo() const;
|
||||
Rotation GetRotation() const;
|
||||
FreezeFlag GetFreezeFlag() const;
|
||||
|
||||
void SetId(DisplayId displayId);
|
||||
void SetWidth(int32_t width);
|
||||
@@ -53,7 +60,7 @@ public:
|
||||
void SetVirtualPixelRatio(float virtualPixelRatio);
|
||||
void SetOrientation(Orientation orientation);
|
||||
bool RequestRotation(Rotation rotation);
|
||||
Rotation GetRotation();
|
||||
void SetFreezeFlag(FreezeFlag);
|
||||
|
||||
private:
|
||||
DisplayId id_ { DISPLAY_ID_INVALID };
|
||||
@@ -64,6 +71,7 @@ private:
|
||||
float virtualPixelRatio_ { 1.0 };
|
||||
Rotation rotation_ { Rotation::ROTATION_0 };
|
||||
Orientation orientation_ { Orientation::UNSPECIFIED };
|
||||
FreezeFlag freezeFlag_ { FreezeFlag::UNFREEZING };
|
||||
};
|
||||
} // namespace OHOS::Rosen
|
||||
#endif // FOUNDATION_DMSERVER_ABSTRACT_DISPLAY_H
|
||||
@@ -44,6 +44,7 @@ public:
|
||||
sptr<AbstractDisplay> GetAbstractDisplayByScreen(ScreenId screenId) const;
|
||||
std::vector<DisplayId> GetAllDisplayIds() const;
|
||||
void AddDisplayForExpandScreen(sptr<AbstractScreen> absScreen);
|
||||
void SetFreeze(std::vector<DisplayId> displayIds, bool isFreeze);
|
||||
|
||||
private:
|
||||
void OnAbstractScreenConnect(sptr<AbstractScreen> absScreen);
|
||||
|
||||
@@ -48,6 +48,7 @@ public:
|
||||
TRANS_ID_GET_DISPLAY_STATE,
|
||||
TRANS_ID_GET_ALL_DISPLAYIDS,
|
||||
TRANS_ID_NOTIFY_DISPLAY_EVENT,
|
||||
TRANS_ID_SET_FREEZE_EVENT,
|
||||
TRANS_ID_SCREEN_BASE = 1000,
|
||||
TRANS_ID_CREATE_VIRTUAL_SCREEN = TRANS_ID_SCREEN_BASE,
|
||||
TRANS_ID_DESTROY_VIRTUAL_SCREEN,
|
||||
@@ -101,6 +102,7 @@ public:
|
||||
virtual DisplayState GetDisplayState(DisplayId displayId) = 0;
|
||||
virtual std::vector<DisplayId> GetAllDisplayIds() = 0;
|
||||
virtual void NotifyDisplayEvent(DisplayEvent event) = 0;
|
||||
virtual bool SetFreeze(std::vector<DisplayId> displayIds, bool isFreeze) = 0;
|
||||
virtual sptr<ScreenInfo> GetScreenInfoById(ScreenId screenId) = 0;
|
||||
virtual sptr<ScreenGroupInfo> GetScreenGroupInfoById(ScreenId screenId) = 0;
|
||||
virtual std::vector<sptr<ScreenInfo>> GetAllScreenInfos() = 0;
|
||||
|
||||
@@ -62,6 +62,7 @@ public:
|
||||
std::vector<DisplayId> GetAllDisplayIds() override;
|
||||
DisplayState GetDisplayState(DisplayId displayId) override;
|
||||
void NotifyDisplayEvent(DisplayEvent event) override;
|
||||
bool SetFreeze(std::vector<DisplayId> displayIds, bool isFreeze) override;
|
||||
ScreenId MakeMirror(ScreenId mainScreenId, std::vector<ScreenId> mirrorScreenId) override;
|
||||
sptr<ScreenInfo> GetScreenInfoById(ScreenId screenId) override;
|
||||
sptr<ScreenGroupInfo> GetScreenGroupInfoById(ScreenId screenId) override;
|
||||
|
||||
@@ -79,6 +79,7 @@ public:
|
||||
|
||||
DisplayState GetDisplayState(DisplayId displayId) override;
|
||||
void NotifyDisplayEvent(DisplayEvent event) override;
|
||||
bool SetFreeze(std::vector<DisplayId> displayIds, bool isFreeze) override;
|
||||
|
||||
sptr<AbstractDisplay> GetAbstractDisplay(DisplayId displayId);
|
||||
sptr<AbstractScreenController> GetAbstractScreenController();
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
#define FOUNDATION_DMSERVER_DISPLAY_MANAGER_SERVICE_INNER_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <pixel_map.h>
|
||||
#include <system_ability.h>
|
||||
|
||||
#include "abstract_display.h"
|
||||
@@ -37,6 +39,7 @@ public:
|
||||
ScreenId GetRSScreenId(DisplayId displayId) const;
|
||||
const sptr<ScreenInfo> GetScreenInfoByDisplayId(DisplayId displayId) const;
|
||||
const sptr<SupportedScreenModes> GetScreenModesByDisplayId(DisplayId displayId);
|
||||
std::shared_ptr<Media::PixelMap> GetDisplaySnapshot(DisplayId);
|
||||
void UpdateRSTree(DisplayId displayId, std::shared_ptr<RSSurfaceNode>& surfaceNode, bool isAdd);
|
||||
void RegisterDisplayChangeListener(sptr<IDisplayChangeListener> listener);
|
||||
};
|
||||
|
||||
@@ -114,11 +114,21 @@ bool AbstractDisplay::RequestRotation(Rotation rotation)
|
||||
return true;
|
||||
}
|
||||
|
||||
Rotation AbstractDisplay::GetRotation()
|
||||
Rotation AbstractDisplay::GetRotation() const
|
||||
{
|
||||
return rotation_;
|
||||
}
|
||||
|
||||
void AbstractDisplay::SetFreezeFlag(FreezeFlag freezeFlag)
|
||||
{
|
||||
freezeFlag_ = freezeFlag;
|
||||
}
|
||||
|
||||
FreezeFlag AbstractDisplay::GetFreezeFlag() const
|
||||
{
|
||||
return freezeFlag_;
|
||||
}
|
||||
|
||||
bool AbstractDisplay::BindAbstractScreen(ScreenId dmsScreenId)
|
||||
{
|
||||
sptr<AbstractScreenController> screenController
|
||||
|
||||
@@ -55,7 +55,7 @@ void AbstractDisplayController::Init(sptr<AbstractScreenController> abstractScre
|
||||
abstractScreenController_->ScreenConnectionInDisplayInit(abstractScreenCallback_);
|
||||
abstractScreenController->RegisterAbstractScreenCallback(abstractScreenCallback_);
|
||||
|
||||
// TODO: Active the code after "rsDisplayNode_->SetScreenId(rsScreenId)" is provided.
|
||||
// Active the code after "rsDisplayNode_->SetScreenId(rsScreenId)" is provided.
|
||||
/*std::lock_guard<std::recursive_mutex> lock(mutex_);
|
||||
if (dummyDisplay_ == nullptr) {
|
||||
sptr<AbstractDisplay> display = new AbstractDisplay(this, displayCount_.fetch_add(1), SCREEN_ID_INVALID,
|
||||
@@ -423,4 +423,42 @@ void AbstractDisplayController::AddDisplayForExpandScreen(sptr<AbstractScreen> a
|
||||
absScreen->dmsId_);
|
||||
AddScreenToExpandLocked(absScreen);
|
||||
}
|
||||
|
||||
|
||||
void AbstractDisplayController::SetFreeze(std::vector<DisplayId> displayIds, bool toFreeze)
|
||||
{
|
||||
WM_SCOPED_TRACE("dms:SetAllFreeze");
|
||||
DisplayStateChangeType type = toFreeze ? DisplayStateChangeType::FREEZE : DisplayStateChangeType::UNFREEZE;
|
||||
DisplayChangeEvent event
|
||||
= toFreeze ? DisplayChangeEvent::DISPLAY_FREEZED : DisplayChangeEvent::DISPLAY_UNFREEZED;
|
||||
for (DisplayId displayId : displayIds) {
|
||||
sptr<AbstractDisplay> abstractDisplay;
|
||||
WM_SCOPED_TRACE("dms:SetFreeze(%" PRIu64")", displayId);
|
||||
{
|
||||
WLOGI("setfreeze display %{public}" PRIu64"", displayId);
|
||||
std::lock_guard<std::recursive_mutex> lock(mutex_);
|
||||
auto iter = abstractDisplayMap_.find(displayId);
|
||||
if (iter == abstractDisplayMap_.end()) {
|
||||
WLOGI("setfreeze fail, cannot get display %{public}" PRIu64"", displayId);
|
||||
continue;
|
||||
}
|
||||
abstractDisplay = iter->second;
|
||||
FreezeFlag curFlag = abstractDisplay->GetFreezeFlag();
|
||||
if ((toFreeze && (curFlag == FreezeFlag::FREEZING))
|
||||
|| (!toFreeze && (curFlag == FreezeFlag::UNFREEZING))) {
|
||||
WLOGI("setfreeze fail, display %{public}" PRIu64" freezeflag is %{public}u",
|
||||
displayId, curFlag);
|
||||
continue;
|
||||
}
|
||||
FreezeFlag flag = toFreeze ? FreezeFlag::FREEZING : FreezeFlag::UNFREEZING;
|
||||
abstractDisplay->SetFreezeFlag(flag);
|
||||
}
|
||||
|
||||
// Notify freeze event to WMS
|
||||
DisplayManagerService::GetInstance().NotifyDisplayStateChange(displayId, type);
|
||||
// Notify freeze event to DisplayManager
|
||||
sptr<DisplayInfo> displayInfo = abstractDisplay->ConvertToDisplayInfo();
|
||||
DisplayManagerAgentController::GetInstance().OnDisplayChange(displayInfo, event);
|
||||
}
|
||||
}
|
||||
} // namespace OHOS::Rosen
|
||||
@@ -686,6 +686,31 @@ void DisplayManagerProxy::NotifyDisplayEvent(DisplayEvent event)
|
||||
}
|
||||
}
|
||||
|
||||
bool DisplayManagerProxy::SetFreeze(std::vector<DisplayId> displayIds, bool isFreeze)
|
||||
{
|
||||
MessageParcel data;
|
||||
MessageParcel reply;
|
||||
MessageOption option;
|
||||
if (!data.WriteInterfaceToken(GetDescriptor())) {
|
||||
WLOGFE("WriteInterfaceToken failed");
|
||||
return false;
|
||||
}
|
||||
if (!data.WriteUInt64Vector(displayIds)) {
|
||||
WLOGFE("set freeze fail: write displayId failed.");
|
||||
return false;
|
||||
}
|
||||
if (!data.WriteBool(isFreeze)) {
|
||||
WLOGFE("set freeze fail: write freeze flag failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Remote()->SendRequest(TRANS_ID_SET_FREEZE_EVENT, data, reply, option) != ERR_NONE) {
|
||||
WLOGFE("SendRequest failed");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
ScreenId DisplayManagerProxy::MakeMirror(ScreenId mainScreenId, std::vector<ScreenId> mirrorScreenId)
|
||||
{
|
||||
sptr<IRemoteObject> remote = Remote();
|
||||
|
||||
@@ -345,6 +345,11 @@ void DisplayManagerService::NotifyDisplayEvent(DisplayEvent event)
|
||||
displayPowerController_->NotifyDisplayEvent(event);
|
||||
}
|
||||
|
||||
bool DisplayManagerService::SetFreeze(std::vector<DisplayId> displayIds, bool isFreeze)
|
||||
{
|
||||
abstractDisplayController_->SetFreeze(displayIds, isFreeze);
|
||||
return true;
|
||||
}
|
||||
|
||||
std::shared_ptr<RSDisplayNode> DisplayManagerService::GetRSDisplayNodeByDisplayId(DisplayId displayId) const
|
||||
{
|
||||
|
||||
@@ -110,6 +110,11 @@ const sptr<SupportedScreenModes> DisplayManagerServiceInner::GetScreenModesByDis
|
||||
return abstractScreen->GetActiveScreenMode();
|
||||
}
|
||||
|
||||
std::shared_ptr<Media::PixelMap> DisplayManagerServiceInner::GetDisplaySnapshot(DisplayId displayId)
|
||||
{
|
||||
return DisplayManagerService::GetInstance().abstractDisplayController_->GetScreenSnapshot(displayId);
|
||||
}
|
||||
|
||||
void DisplayManagerServiceInner::RegisterDisplayChangeListener(sptr<IDisplayChangeListener> listener)
|
||||
{
|
||||
DisplayManagerService::GetInstance().RegisterDisplayChangeListener(listener);
|
||||
|
||||
@@ -166,6 +166,12 @@ int32_t DisplayManagerStub::OnRemoteRequest(uint32_t code, MessageParcel &data,
|
||||
NotifyDisplayEvent(event);
|
||||
break;
|
||||
}
|
||||
case TRANS_ID_SET_FREEZE_EVENT: {
|
||||
std::vector<DisplayId> ids;
|
||||
data.ReadUInt64Vector(&ids);
|
||||
SetFreeze(ids, data.ReadBool());
|
||||
break;
|
||||
}
|
||||
case TRANS_ID_SCREEN_MAKE_MIRROR: {
|
||||
ScreenId mainScreenId = static_cast<ScreenId>(data.ReadUint64());
|
||||
std::vector<ScreenId> mirrorScreenId;
|
||||
|
||||
@@ -60,6 +60,8 @@ public:
|
||||
bool SetScreenBrightness(uint64_t screenId, uint32_t level);
|
||||
uint32_t GetScreenBrightness(uint64_t screenId) const;
|
||||
void NotifyDisplayEvent(DisplayEvent event);
|
||||
bool Freeze(std::vector<DisplayId> displayIds);
|
||||
bool Unfreeze(std::vector<DisplayId> displayIds);
|
||||
constexpr static int32_t MAX_RESOLUTION_SIZE_SCREENSHOT = 3840; // max resolution, 4K
|
||||
|
||||
private:
|
||||
|
||||
@@ -121,6 +121,8 @@ enum class Orientation : uint32_t {
|
||||
enum class DisplayChangeEvent : uint32_t {
|
||||
UPDATE_ORIENTATION,
|
||||
DISPLAY_SIZE_CHANGED,
|
||||
DISPLAY_FREEZED,
|
||||
DISPLAY_UNFREEZED,
|
||||
UNKNOWN,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ enum class WindowType : uint32_t {
|
||||
WINDOW_TYPE_LAUNCHER_RECENT,
|
||||
WINDOW_TYPE_LAUNCHER_DOCK,
|
||||
WINDOW_TYPE_BOOT_ANIMATION,
|
||||
WINDOW_TYPE_FREEZE_DISPLAY,
|
||||
ABOVE_APP_SYSTEM_WINDOW_END,
|
||||
|
||||
SYSTEM_WINDOW_END = ABOVE_APP_SYSTEM_WINDOW_END,
|
||||
|
||||
@@ -25,7 +25,9 @@ enum class DisplayStateChangeType : uint32_t {
|
||||
BEFORE_UNLOCK,
|
||||
UPDATE_ROTATION,
|
||||
SIZE_CHANGE,
|
||||
DESTROY
|
||||
DESTROY,
|
||||
FREEZE,
|
||||
UNFREEZE,
|
||||
};
|
||||
class IDisplayChangeListener : public RefBase {
|
||||
public:
|
||||
|
||||
@@ -48,6 +48,7 @@ ohos_shared_library("libwms") {
|
||||
"../wm/src/zidl/window_manager_agent_proxy.cpp",
|
||||
"src/avoid_area_controller.cpp",
|
||||
"src/drag_controller.cpp",
|
||||
"src/freeze_controller.cpp",
|
||||
"src/input_window_monitor.cpp",
|
||||
"src/window_controller.cpp",
|
||||
"src/window_inner_manager.cpp",
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2022-2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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_FREEZE_CONTROLLER_H
|
||||
#define OHOS_ROSEN_FREEZE_CONTROLLER_H
|
||||
|
||||
#include <refbase.h>
|
||||
|
||||
#include <include/core/SkBitmap.h>
|
||||
#include <pixel_map.h>
|
||||
#ifdef ACE_ENABLE_GL
|
||||
#include <render_context/render_context.h>
|
||||
#endif
|
||||
#include <transaction/rs_transaction.h>
|
||||
#include <ui/rs_surface_extractor.h>
|
||||
|
||||
#include "display.h"
|
||||
#include "window.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Rosen {
|
||||
class FreezeController : public RefBase {
|
||||
public:
|
||||
FreezeController() {};
|
||||
~FreezeController() = default;
|
||||
|
||||
bool FreezeDisplay(DisplayId displayId);
|
||||
bool UnfreezeDisplay(DisplayId displayId);
|
||||
|
||||
private:
|
||||
sptr<Window> CreateCoverWindow(DisplayId displayId);
|
||||
SkImageInfo MakeSkImageInfoFromPixelMap(std::shared_ptr<Media::PixelMap>& pixmap);
|
||||
bool DrawSkImage(std::shared_ptr<RSSurface>& rsSurface,
|
||||
uint32_t width, uint32_t height, std::shared_ptr<Media::PixelMap> pixelMap);
|
||||
|
||||
std::map<DisplayId, sptr<Window>> coverWindowMap_;
|
||||
#ifdef ACE_ENABLE_GL
|
||||
RenderContext* rc_ = nullptr;
|
||||
#endif
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif // OHOS_ROSEN_FREEZE_CONTROLLER_H
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <system_ability.h>
|
||||
#include "display_change_listener.h"
|
||||
#include "drag_controller.h"
|
||||
#include "freeze_controller.h"
|
||||
#include "singleton_delegator.h"
|
||||
#include "wm_single_instance.h"
|
||||
#include "window_controller.h"
|
||||
@@ -91,6 +92,7 @@ private:
|
||||
sptr<InputWindowMonitor> inputWindowMonitor_;
|
||||
sptr<SnapshotController> snapshotController_;
|
||||
sptr<DragController> dragController_;
|
||||
sptr<FreezeController> freezeDisplayController_;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,6 +60,7 @@ private:
|
||||
{ WindowType::WINDOW_TYPE_DRAGGING_EFFECT, 115 },
|
||||
{ WindowType::WINDOW_TYPE_POINTER, 116 },
|
||||
{ WindowType::WINDOW_TYPE_BOOT_ANIMATION, 117 },
|
||||
{ WindowType::WINDOW_TYPE_FREEZE_DISPLAY, 118 },
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright (c) 2022-2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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 "freeze_controller.h"
|
||||
|
||||
#include <securec.h>
|
||||
|
||||
#include <include/codec/SkCodec.h>
|
||||
#include <include/core/SkCanvas.h>
|
||||
#include <include/core/SkImage.h>
|
||||
|
||||
#include "display_manager_service_inner.h"
|
||||
#include "window_manager_hilog.h"
|
||||
#include "window_option.h"
|
||||
#include "wm_common.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Rosen {
|
||||
namespace {
|
||||
constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "FreezeController"};
|
||||
}
|
||||
|
||||
bool FreezeController::FreezeDisplay(DisplayId displayId)
|
||||
{
|
||||
sptr<Window> window = CreateCoverWindow(displayId);
|
||||
if (window == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
WMError res = window->Show();
|
||||
if (res != WMError::WM_OK) {
|
||||
WLOGFE("Show window failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef ACE_ENABLE_GL
|
||||
WLOGFI("Draw cover window on gpu");
|
||||
// init render context
|
||||
static bool hasInitRC = false;
|
||||
if (!hasInitRC) {
|
||||
rc_ = RenderContextFactory::GetInstance().CreateEngine();
|
||||
if (rc_ != nullptr) {
|
||||
rc_->InitializeEglContext();
|
||||
hasInitRC = true;
|
||||
} else {
|
||||
WLOGFE("InitilizeEglContext failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
std::shared_ptr<RSSurfaceNode> surfaceNode = window->GetSurfaceNode();
|
||||
if (surfaceNode == nullptr) {
|
||||
WLOGFE("RSSurfaceNode is null");
|
||||
return false;
|
||||
}
|
||||
Rect winRect = window->GetRect();
|
||||
WLOGFI("freeze window rect, x : %{public}d, y : %{public}d, width: %{public}u, height: %{public}u",
|
||||
winRect.posX_, winRect.posY_, winRect.width_, winRect.height_);
|
||||
|
||||
std::shared_ptr<RSSurface> rsSurface = RSSurfaceExtractor::ExtractRSSurface(surfaceNode);
|
||||
if (rsSurface == nullptr) {
|
||||
WLOGFE("RSSurface is null");
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef ACE_ENABLE_GL
|
||||
rsSurface->SetRenderContext(rc_);
|
||||
#endif
|
||||
|
||||
std::shared_ptr<Media::PixelMap> pixelMap = DisplayManagerServiceInner::GetInstance().GetDisplaySnapshot(displayId);
|
||||
if (pixelMap == nullptr) {
|
||||
WLOGE("freeze display fail, pixel map is null. display %{public}" PRIu64"", displayId);
|
||||
return false;
|
||||
}
|
||||
return DrawSkImage(rsSurface, winRect.width_, winRect.height_, pixelMap);
|
||||
}
|
||||
|
||||
bool FreezeController::UnfreezeDisplay(DisplayId displayId)
|
||||
{
|
||||
auto iter = coverWindowMap_.find(displayId);
|
||||
if (iter == coverWindowMap_.end()) {
|
||||
WLOGW("unfreeze fail, no cover window. display %{public}" PRIu64"", displayId);
|
||||
return false;
|
||||
}
|
||||
sptr<Window> window = iter->second;
|
||||
if (window == nullptr) {
|
||||
WLOGW("unfreeze fail, window is null. display %{public}" PRIu64"", displayId);
|
||||
return false;
|
||||
}
|
||||
return WMError::WM_OK == window->Destroy();
|
||||
}
|
||||
|
||||
sptr<Window> FreezeController::CreateCoverWindow(DisplayId displayId)
|
||||
{
|
||||
sptr<WindowOption> option = new WindowOption();
|
||||
option->SetWindowType(WindowType::WINDOW_TYPE_FREEZE_DISPLAY);
|
||||
option->SetFocusable(false);
|
||||
option->RemoveWindowFlag(WindowFlag::WINDOW_FLAG_NEED_AVOID);
|
||||
option->SetDisplayId(displayId);
|
||||
sptr<Window> window = Window::Create("freeze" + std::to_string(displayId), option);
|
||||
if (window == nullptr) {
|
||||
WLOGFE("cover window is null");
|
||||
return nullptr;
|
||||
}
|
||||
coverWindowMap_[displayId] = window;
|
||||
return window;
|
||||
}
|
||||
|
||||
bool FreezeController::DrawSkImage(std::shared_ptr<RSSurface>& rsSurface,
|
||||
uint32_t width, uint32_t height, std::shared_ptr<Media::PixelMap> pixelmap)
|
||||
{
|
||||
// Get canvas
|
||||
WLOGFD("start to draw bitmap");
|
||||
std::unique_ptr<RSSurfaceFrame> frame = rsSurface->RequestFrame(width, height);
|
||||
if (frame == nullptr) {
|
||||
WLOGFE("fail to request frame");
|
||||
return false;
|
||||
}
|
||||
auto canvas = frame->GetCanvas();
|
||||
if (canvas == nullptr) {
|
||||
WLOGFE("fail to get canvas");
|
||||
return false;
|
||||
}
|
||||
canvas->clear(SK_ColorTRANSPARENT);
|
||||
|
||||
// Create SkPixmap from PixelMap
|
||||
auto imageInfo = MakeSkImageInfoFromPixelMap(pixelmap);
|
||||
SkPixmap imagePixmap(imageInfo, reinterpret_cast<const void*>(pixelmap->GetPixels()), pixelmap->GetRowBytes());
|
||||
|
||||
// Create SkImage from SkPixmap
|
||||
sk_sp<SkImage> skImage = SkImage::MakeFromRaster(imagePixmap, nullptr, nullptr);
|
||||
if (!skImage) {
|
||||
WLOGFE("sk image is null");
|
||||
return false;
|
||||
}
|
||||
|
||||
SkPaint paint;
|
||||
sk_sp<SkColorSpace> colorSpace = skImage->refColorSpace();
|
||||
#ifdef USE_SYSTEM_SKIA
|
||||
paint.setColor4f(paint.getColor4f(), colorSpace.get());
|
||||
#else
|
||||
paint.setColor(paint.getColor4f(), colorSpace.get());
|
||||
#endif
|
||||
auto skSrcRect = SkRect::MakeXYWH(0, 0, pixelmap->GetWidth(), pixelmap->GetHeight());
|
||||
auto skDstRect = SkRect::MakeXYWH(0, 0, width, height);
|
||||
canvas->drawImageRect(skImage, skSrcRect, skDstRect, &paint);
|
||||
frame->SetDamageRegion(0, 0, width, height);
|
||||
if (!rsSurface->FlushFrame(frame)) {
|
||||
WLOGFE("fail to flush frame");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
SkImageInfo FreezeController::MakeSkImageInfoFromPixelMap(std::shared_ptr<Media::PixelMap>& pixmap)
|
||||
{
|
||||
SkColorType colorType = kN32_SkColorType;
|
||||
SkAlphaType alphaType = SkAlphaType::kOpaque_SkAlphaType;
|
||||
sk_sp<SkColorSpace> colorSpace = SkColorSpace::MakeSRGB();
|
||||
return SkImageInfo::Make(pixmap->GetWidth(), pixmap->GetHeight(), colorType, alphaType, colorSpace);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -48,6 +48,7 @@ WindowManagerService::WindowManagerService() : SystemAbility(WINDOW_MANAGER_SERV
|
||||
windowController_ = new WindowController(windowRoot_, inputWindowMonitor_);
|
||||
snapshotController_ = new SnapshotController(windowRoot_);
|
||||
dragController_ = new DragController(windowRoot_);
|
||||
freezeDisplayController_ = new FreezeController();
|
||||
}
|
||||
|
||||
void WindowManagerService::OnStart()
|
||||
@@ -274,8 +275,14 @@ void WindowManagerService::OnWindowEvent(Event event, uint32_t windowId)
|
||||
void WindowManagerService::NotifyDisplayStateChange(DisplayId id, DisplayStateChangeType type)
|
||||
{
|
||||
WM_SCOPED_TRACE("wms:NotifyDisplayStateChange(%u)", type);
|
||||
std::lock_guard<std::recursive_mutex> lock(mutex_);
|
||||
return windowController_->NotifyDisplayStateChange(id, type);
|
||||
if (type == DisplayStateChangeType::FREEZE) {
|
||||
freezeDisplayController_->FreezeDisplay(id);
|
||||
} else if (type == DisplayStateChangeType::UNFREEZE) {
|
||||
freezeDisplayController_->UnfreezeDisplay(id);
|
||||
} else {
|
||||
std::lock_guard<std::recursive_mutex> lock(mutex_);
|
||||
return windowController_->NotifyDisplayStateChange(id, type);
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayChangeListener::OnDisplayStateChange(DisplayId id, DisplayStateChangeType type)
|
||||
|
||||
Reference in New Issue
Block a user