!1148 截屏监听&窗口截图

Merge pull request !1148 from 韩冰/snapshot
This commit is contained in:
openharmony_ci
2022-07-11 11:31:37 +00:00
committed by Gitee
32 changed files with 373 additions and 82 deletions
@@ -26,7 +26,6 @@
#include "screen.h"
#include "abstract_display.h"
#include "display_change_listener.h"
#include "transaction/rs_interfaces.h"
#include "future.h"
namespace OHOS::Rosen {
@@ -76,36 +75,6 @@ private:
sptr<AbstractScreenController::AbstractScreenCallback> abstractScreenCallback_;
OHOS::Rosen::RSInterfaces& rsInterface_;
DisplayStateChangeListener displayStateChangeListener_;
class ScreenshotCallback : public SurfaceCaptureCallback, public Future<std::shared_ptr<Media::PixelMap>> {
public:
ScreenshotCallback() = default;
~ScreenshotCallback() {};
void OnSurfaceCapture(std::shared_ptr<Media::PixelMap> pixelmap) override
{
FutureCall(pixelmap);
}
protected:
void Call(std::shared_ptr<Media::PixelMap> pixelmap) override
{
if (!flag_) {
flag_ = true;
pixelMap_ = pixelmap;
}
}
bool IsReady() override
{
return flag_;
}
std::shared_ptr<Media::PixelMap> FetchResult() override
{
return pixelMap_;
}
private:
bool flag_ = false;
std::shared_ptr<Media::PixelMap> pixelMap_ = nullptr;
};
};
} // namespace OHOS::Rosen
#endif // FOUNDATION_DMSERVER_ABSTRACT_DISPLAY_CONTROLLER_H
@@ -105,6 +105,7 @@ private:
bool Init();
void NotifyDisplayStateChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type);
void NotifyScreenshot(DisplayId displayId);
ScreenId GetScreenIdByDisplayId(DisplayId displayId) const;
std::shared_ptr<RSDisplayNode> GetRSDisplayNodeByDisplayId(DisplayId displayId) const;
void ConfigureDisplayManagerService();
+4 -2
View File
@@ -22,6 +22,7 @@
#include "display_manager_agent_controller.h"
#include "display_manager_service.h"
#include "screen_group.h"
#include "surface_capture_future.h"
#include "window_manager_hilog.h"
namespace OHOS::Rosen {
@@ -113,10 +114,11 @@ std::shared_ptr<Media::PixelMap> AbstractDisplayController::GetScreenSnapshot(Di
}
ScreenId dmsScreenId = abstractDisplay->GetAbstractScreenId();
std::shared_ptr<RSDisplayNode> displayNode = abstractScreenController_->GetRSDisplayNodeByScreenId(dmsScreenId);
std::lock_guard<std::recursive_mutex> lock(mutex_);
std::shared_ptr<ScreenshotCallback> callback = std::make_shared<ScreenshotCallback>();
std::shared_ptr<SurfaceCaptureFuture> callback = std::make_shared<SurfaceCaptureFuture>();
rsInterface_.TakeSurfaceCapture(displayNode, callback);
std::shared_ptr<Media::PixelMap> screenshot = callback->GetResult(2000); // wait for 2000ms
std::shared_ptr<Media::PixelMap> screenshot = callback->GetResult(2000); // wait for <= 2000ms
if (screenshot == nullptr) {
WLOGFE("Failed to get pixelmap from RS, return nullptr!");
}
+12 -1
View File
@@ -140,6 +140,13 @@ void DisplayManagerService::GetWindowPreferredOrientation(DisplayId displayId, O
}
}
void DisplayManagerService::NotifyScreenshot(DisplayId displayId)
{
if (displayChangeListener_ != nullptr) {
displayChangeListener_->OnScreenshot(displayId);
}
}
sptr<DisplayInfo> DisplayManagerService::GetDefaultDisplayInfo()
{
ScreenId dmsScreenId = abstractScreenController_->GetDefaultAbstractScreenId();
@@ -225,7 +232,11 @@ std::shared_ptr<Media::PixelMap> DisplayManagerService::GetDisplaySnapshot(Displ
HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "dms:GetDisplaySnapshot(%" PRIu64")", displayId);
if (Permission::CheckCallingPermission("ohos.permission.CAPTURE_SCREEN") ||
Permission::IsStartByHdcd()) {
return abstractDisplayController_->GetScreenSnapshot(displayId);
auto res = abstractDisplayController_->GetScreenSnapshot(displayId);
if (res != nullptr) {
NotifyScreenshot(displayId);
}
return res;
}
return nullptr;
}
+9
View File
@@ -18,6 +18,7 @@
#include <refbase.h>
#include <parcel.h>
#include <pixel_map.h>
#include "wm_common.h"
#include "window_option.h"
@@ -140,6 +141,11 @@ public:
virtual void AnimationForHidden() = 0;
};
class IScreenshotListener : virtual public RefBase {
public:
virtual void OnScreenshot() = 0;
};
class Window : public RefBase {
public:
/**
@@ -242,6 +248,8 @@ public:
virtual void RegisterTouchOutsideListener(const sptr<ITouchOutsideListener>& listener) = 0;
virtual void UnregisterTouchOutsideListener(const sptr<ITouchOutsideListener>& listener) = 0;
virtual void RegisterAnimationTransitionController(const sptr<IAnimationTransitionController>& listener) = 0;
virtual void RegisterScreenshotListener(const sptr<IScreenshotListener>& listener) = 0;
virtual void UnregisterScreenshotListener(const sptr<IScreenshotListener>& listener) = 0;
virtual void SetAceAbilityHandler(const sptr<IAceAbilityHandler>& handler) = 0;
virtual WMError SetUIContent(const std::string& contentInfo, NativeEngine* engine,
NativeValue* storage, bool isDistributed = false, AppExecFwk::Ability* ability = nullptr) = 0;
@@ -269,6 +277,7 @@ public:
virtual ColorSpace GetColorSpace() = 0;
virtual void DumpInfo(const std::vector<std::string>& params, std::vector<std::string>& info) = 0;
virtual std::shared_ptr<Media::PixelMap> Snapshot() = 0;
};
}
}
@@ -62,6 +62,7 @@ ohos_shared_library("window_native_kit") {
"bundle_framework:appexecfwk_base",
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
"multimedia_image_standard:image",
"napi:ace_napi",
"utils_base:utils",
]
@@ -15,6 +15,8 @@
import { AsyncCallback, Callback } from './basic' ;
import { Context } from './app/context';
import { ContenStorage } from './@internal/component/ets/stateManagement'
import image from './@ohos.multimedia.image';
/**
* Window manager.
* @syscap SystemCapability.WindowManager.WindowManager.Core
@@ -888,6 +890,22 @@ declare namespace window {
*/
off(type: 'avoidAreaChange', callback?: Callback<{ type: AvoidAreaType, area: AvoidArea }>): void;
/**
* register the callback of screenshotEvent, only the focused window called back
* @param type: 'screenshotEvent'
* @syscap SystemCapability.WindowManager.WindowManager.Core
* @since 9
*/
on(type: 'screenshotEvent', callback: Callback<void>): void;
/**
* unregister the callback of screenshotEvent
* @param type: 'screenshotEvent'
* @syscap SystemCapability.WindowManager.WindowManager.Core
* @since 9
*/
off(type: 'screenshotEvent', callback?: Callback<void>): void;
/**
* Whether the window supports thr wide gamut setting.
* @since 8
@@ -1133,6 +1151,20 @@ declare namespace window {
* @since 9
*/
getTransitionControllerSync(): TransitionController;
/**
* Obtains snapshot of window
* @syscap SystemCapability.WindowManager.WindowManager.Cor
* @since 9
*/
snapshot(callback: AsyncCallback<image.PixelMap>): void;
/**
* Obtains snapshot of window
* @syscap SystemCapability.WindowManager.WindowManager.Co
* @since 9
*/
snapshot(): Promise<image.PixelMap>;
}
/**
* Transition Context
@@ -22,6 +22,9 @@
#include "window_helper.h"
#include "window_manager_hilog.h"
#include "window_option.h"
#include "pixel_map.h"
#include "pixel_map_napi.h"
namespace OHOS {
namespace Rosen {
using namespace AbilityRuntime;
@@ -1726,6 +1729,13 @@ NativeValue* JsWindow::OnDump(NativeEngine& engine, NativeCallbackInfo& info)
return dumpInfoValue;
}
NativeValue* JsWindow::Snapshot(NativeEngine* engine, NativeCallbackInfo* info)
{
WLOGFI("[NAPI]Snapshot");
JsWindow* me = CheckParamsAndGetThis<JsWindow>(engine, info);
return (me != nullptr) ? me->OnSnapshot(*engine, *info) : nullptr;
}
NativeValue* JsWindow::OnSetForbidSplitMove(NativeEngine& engine, NativeCallbackInfo& info)
{
WMError errCode = WMError::WM_OK;
@@ -1769,7 +1779,50 @@ NativeValue* JsWindow::OnSetForbidSplitMove(NativeEngine& engine, NativeCallback
NativeValue* lastParam = (info.argc <= 1) ? nullptr :
(info.argv[1]->TypeOf() == NATIVE_FUNCTION ? info.argv[1] : nullptr);
NativeValue* result = nullptr;
AsyncTask::Schedule("JsWindow::OnDump",
AsyncTask::Schedule("JsWindow::OnSetForbidSplitMove",
engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
return result;
}
NativeValue* JsWindow::OnSnapshot(NativeEngine& engine, NativeCallbackInfo& info)
{
WMError errCode = WMError::WM_OK;
if (info.argc > 1) {
WLOGFE("[NAPI]Argc is invalid: %{public}zu", info.argc);
errCode = WMError::WM_ERROR_INVALID_PARAM;
}
wptr<Window> weakToken(windowToken_);
AsyncTask::CompleteCallback complete =
[weakToken, errCode](NativeEngine& engine, AsyncTask& task, int32_t status) {
auto weakWindow = weakToken.promote();
if (weakWindow == nullptr || errCode != WMError::WM_OK) {
task.Reject(engine, CreateJsError(engine, static_cast<int32_t>(errCode)));
WLOGFE("[NAPI]window is nullptr or get invalid param");
return;
}
std::shared_ptr<Media::PixelMap> pixelMap = weakWindow->Snapshot();
if (pixelMap == nullptr) {
task.Reject(engine, CreateJsError(engine, static_cast<int32_t>(WMError::WM_ERROR_NULLPTR)));
WLOGFE("[NAPI]window snapshot get pixelmap is null");
return;
}
auto nativePixelMap = reinterpret_cast<NativeValue*>(
Media::PixelMapNapi::CreatePixelMap(reinterpret_cast<napi_env>(&engine), pixelMap));
if (nativePixelMap == nullptr) {
WLOGFE("[NAPI]window snapshot get nativePixelMap is null");
}
task.Resolve(engine, nativePixelMap);
WLOGFI("[NAPI]Window [%{public}u, %{public}s] OnSnapshot, WxH=%{public}dx%{public}d",
weakWindow->GetWindowId(), weakWindow->GetWindowName().c_str(),
pixelMap->GetWidth(), pixelMap->GetHeight());
};
NativeValue* lastParam = (info.argc == 0) ? nullptr :
(info.argv[0]->TypeOf() == NATIVE_FUNCTION ? info.argv[0] : nullptr);
NativeValue* result = nullptr;
AsyncTask::Schedule("JsWindow::OnSnapshot",
engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
return result;
}
@@ -2098,6 +2151,7 @@ void BindFunctions(NativeEngine& engine, NativeObject* object)
BindNativeFunction(engine, *object, "setRotateSync", JsWindow::SetRotateSync);
BindNativeFunction(engine, *object, "setTranslateSync", JsWindow::SetTranslateSync);
BindNativeFunction(engine, *object, "getTransitionControllerSync", JsWindow::GetTransitionControllerSync);
BindNativeFunction(engine, *object, "snapshot", JsWindow::Snapshot);
}
} // namespace Rosen
} // namespace OHOS
@@ -70,6 +70,7 @@ public:
static NativeValue* GetColorSpace(NativeEngine* engine, NativeCallbackInfo* info);
static NativeValue* Dump(NativeEngine* engine, NativeCallbackInfo* info);
static NativeValue* SetForbidSplitMove(NativeEngine* engine, NativeCallbackInfo* info);
static NativeValue* Snapshot(NativeEngine* engine, NativeCallbackInfo* info);
// animation config
static NativeValue* SetOpacitySync(NativeEngine* engine, NativeCallbackInfo* info);
@@ -120,6 +121,7 @@ private:
NativeValue* OnDisableWindowDecor(NativeEngine& engine, NativeCallbackInfo& info);
NativeValue* OnDump(NativeEngine& engine, NativeCallbackInfo& info);
NativeValue* OnSetForbidSplitMove(NativeEngine& engine, NativeCallbackInfo& info);
NativeValue* OnSnapshot(NativeEngine& engine, NativeCallbackInfo& info);
// animation Config
NativeValue* OnSetOpacitySync(NativeEngine& engine, NativeCallbackInfo& info);
@@ -210,6 +210,7 @@ void JsWindowListener::OnSizeChange(const sptr<OccupiedAreaChangeInfo>& info)
void JsWindowListener::OnTouchOutside() const
{
WLOGFI("CALLED");
std::unique_ptr<AsyncTask::CompleteCallback> complete = std::make_unique<AsyncTask::CompleteCallback> (
[self = weakRef_] (NativeEngine &engine, AsyncTask &task, int32_t status) {
auto thisListener = self.promote();
@@ -225,7 +226,26 @@ void JsWindowListener::OnTouchOutside() const
std::unique_ptr<AsyncTask::ExecuteCallback> execute = nullptr;
AsyncTask::Schedule("JsWindowListener::OnOutsidePressed",
*engine_, std::make_unique<AsyncTask>(callback, std::move(execute), std::move(complete)));
}
void JsWindowListener::OnScreenshot()
{
WLOGFI("CALLED");
std::unique_ptr<AsyncTask::CompleteCallback> complete = std::make_unique<AsyncTask::CompleteCallback> (
[self = wptr<JsWindowListener>(this)] (NativeEngine &engine, AsyncTask &task, int32_t status) {
auto thisListener = self.promote();
if (thisListener == nullptr) {
WLOGFE("[NAPI]this listener is nullptr");
return;
}
thisListener->CallJsMethod(SCREENSHOT_EVENT_CB.c_str(), nullptr, 0);
}
);
NativeReference* callback = nullptr;
std::unique_ptr<AsyncTask::ExecuteCallback> execute = nullptr;
AsyncTask::Schedule("JsWindowListener::OnScreenshot",
*engine_, std::make_unique<AsyncTask>(callback, std::move(execute), std::move(complete)));
}
} // namespace Rosen
} // namespace OHOS
@@ -38,13 +38,15 @@ const std::string LIFECYCLE_EVENT_CB = "lifeCycleEvent";
const std::string WINDOW_STAGE_EVENT_CB = "windowStageEvent";
const std::string KEYBOARD_HEIGHT_CHANGE_CB = "keyboardHeightChange";
const std::string TOUCH_OUTSIDE_CB = "touchOutside";
const std::string SCREENSHOT_EVENT_CB = "screenshotEvent";
class JsWindowListener : public IWindowChangeListener,
public ISystemBarChangedListener,
public IAvoidAreaChangedListener,
public IWindowLifeCycle,
public IOccupiedAreaChangeListener,
public ITouchOutsideListener {
public ITouchOutsideListener,
public IScreenshotListener {
public:
JsWindowListener(NativeEngine* engine, std::shared_ptr<NativeReference> callback)
: engine_(engine), jsCallBack_(callback), weakRef_(wptr<JsWindowListener> (this)) {}
@@ -59,6 +61,7 @@ public:
void AfterUnfocused() override;
void OnSizeChange(const sptr<OccupiedAreaChangeInfo>& info) override;
void OnTouchOutside() const override;
void OnScreenshot() override;
void CallJsMethod(const char* methodName, NativeValue* const* argv = nullptr, size_t argc = 0);
private:
void LifeCycleCallBack(LifeCycleEventType eventType);
@@ -35,7 +35,8 @@ JsWindowRegisterManager::JsWindowRegisterManager()
{ AVOID_AREA_CHANGE_CB, &JsWindowRegisterManager::ProcessAvoidAreaChangeRegister },
{ LIFECYCLE_EVENT_CB, &JsWindowRegisterManager::ProcessLifeCycleEventRegister },
{ KEYBOARD_HEIGHT_CHANGE_CB, &JsWindowRegisterManager::ProcessOccupiedAreaChangeRegister },
{ TOUCH_OUTSIDE_CB, &JsWindowRegisterManager::ProcessTouchOutsideRegister }
{ TOUCH_OUTSIDE_CB, &JsWindowRegisterManager::ProcessTouchOutsideRegister },
{ SCREENSHOT_EVENT_CB, &JsWindowRegisterManager::ProcessScreenshotRegister }
};
// white register list for window stage
listenerProcess_[CaseType::CASE_STAGE] = {
@@ -160,6 +161,23 @@ bool JsWindowRegisterManager::ProcessTouchOutsideRegister(sptr<JsWindowListener>
return true;
}
bool JsWindowRegisterManager::ProcessScreenshotRegister(sptr<JsWindowListener> listener,
sptr<Window> window, bool isRegister)
{
WLOGFI("called");
if (window == nullptr) {
WLOGFE("%{public}sregister screenshot listener failed. window is null", isRegister? "" : "un");
return false;
}
sptr<IScreenshotListener> thisListener(listener);
if (isRegister) {
window->RegisterScreenshotListener(thisListener);
} else {
window->UnregisterScreenshotListener(thisListener);
}
return true;
}
bool JsWindowRegisterManager::IsCallbackRegistered(std::string type, NativeValue* jsListenerObject)
{
if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) {
@@ -46,6 +46,7 @@ private:
bool ProcessOccupiedAreaChangeRegister(sptr<JsWindowListener> listener, sptr<Window> window, bool isRegister);
bool ProcessSystemBarChangeRegister(sptr<JsWindowListener> listener, sptr<Window> window, bool isRegister);
bool ProcessTouchOutsideRegister(sptr<JsWindowListener> listener, sptr<Window> window, bool isRegister);
bool ProcessScreenshotRegister(sptr<JsWindowListener> listener, sptr<Window> window, bool isRegister);
using Func_t = bool(JsWindowRegisterManager::*)(sptr<JsWindowListener>, sptr<Window> window, bool);
std::map<std::string, std::map<std::shared_ptr<NativeReference>, sptr<JsWindowListener>>> jsCbMap_;
std::mutex mtx_;
+1
View File
@@ -36,6 +36,7 @@ public:
virtual void OnDisplayStateChange(DisplayId defaultDisplayId, sptr<DisplayInfo> info,
const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type) = 0;
virtual void OnGetWindowPreferredOrientation(DisplayId displayId, Orientation &orientation) = 0;
virtual void OnScreenshot(DisplayId displayId) = 0;
};
}
}
+55
View File
@@ -0,0 +1,55 @@
/*
* 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 SURFACE_CAPTURE_FUTURE_H
#define SURFACE_CAPTURE_FUTURE_H
#include "future.h"
#include "pixel_map.h"
#include "transaction/rs_render_service_client.h"
namespace OHOS {
namespace Rosen {
class SurfaceCaptureFuture : public SurfaceCaptureCallback, public Future<std::shared_ptr<Media::PixelMap>> {
public:
SurfaceCaptureFuture() = default;
~SurfaceCaptureFuture() {};
void OnSurfaceCapture(std::shared_ptr<Media::PixelMap> pixelmap) override
{
FutureCall(pixelmap);
}
protected:
void Call(std::shared_ptr<Media::PixelMap> pixelmap) override
{
if (!flag_) {
pixelMap_ = pixelmap;
flag_ = true;
}
}
bool IsReady() override
{
return flag_;
}
std::shared_ptr<Media::PixelMap> FetchResult() override
{
return pixelMap_;
}
private:
bool flag_ = false;
std::shared_ptr<Media::PixelMap> pixelMap_ = nullptr;
};
} // Rosen
} // OHOS
#endif // SURFACE_CAPTURE_FUTURE_H
+1
View File
@@ -83,6 +83,7 @@ ohos_shared_library("libwm") {
"input:libmmi-client",
"inputmethod_native:inputmethod_client",
"ipc:ipc_core",
"multimedia_image_standard:image",
"multimedia_image_standard:image_native",
"napi:ace_napi",
+1
View File
@@ -39,6 +39,7 @@ public:
void UpdateActiveStatus(bool isActive) override;
sptr<WindowProperty> GetWindowProperty() override;
void NotifyTouchOutside() override;
void NotifyScreenshot() override;
void DumpInfo(const std::vector<std::string>& params, std::vector<std::string>& info) override;
private:
sptr<WindowImpl> window_;
+5
View File
@@ -193,6 +193,8 @@ public:
virtual void RegisterTouchOutsideListener(const sptr<ITouchOutsideListener>& listener) override;
virtual void UnregisterTouchOutsideListener(const sptr<ITouchOutsideListener>& listener) override;
virtual void RegisterAnimationTransitionController(const sptr<IAnimationTransitionController>& listener) override;
virtual void RegisterScreenshotListener(const sptr<IScreenshotListener>& listener) override;
virtual void UnregisterScreenshotListener(const sptr<IScreenshotListener>& listener) override;
virtual void SetAceAbilityHandler(const sptr<IAceAbilityHandler>& handler) override;
virtual void SetRequestModeSupportInfo(uint32_t modeSupportInfo) override;
void UpdateRect(const struct Rect& rect, bool decoStatus, WindowSizeChangeReason reason);
@@ -220,6 +222,7 @@ public:
void NotifyModeChange(WindowMode mode);
void NotifyDragEvent(const PointInfo& point, DragEvent event);
void NotifyTouchOutside();
void NotifyScreenshot();
virtual WMError SetUIContent(const std::string& contentInfo, NativeEngine* engine,
NativeValue* storage, bool isdistributed, AppExecFwk::Ability* ability) override;
@@ -239,6 +242,7 @@ public:
virtual ColorSpace GetColorSpace() override;
virtual void DumpInfo(const std::vector<std::string>& params, std::vector<std::string>& info) override;
virtual std::shared_ptr<Media::PixelMap> Snapshot() override;
void PostListenerTask(ListenerTaskCallback &&callback, Priority priority = Priority::LOW,
const std::string taskName = "");
private:
@@ -390,6 +394,7 @@ private:
WindowState state_ { WindowState::STATE_INITIAL };
WindowTag windowTag_;
sptr<IAceAbilityHandler> aceAbilityHandler_;
std::vector<sptr<IScreenshotListener>> screenshotListeners_;
std::vector<sptr<ITouchOutsideListener>> touchOutsideListeners_;
std::vector<sptr<IWindowLifeCycle>> lifecycleListeners_;
std::vector<sptr<IWindowChangeListener>> windowChangeListeners_;
+2
View File
@@ -41,6 +41,7 @@ public:
TRANS_ID_UPDATE_ACTIVE_STATUS,
TRANS_ID_GET_WINDOW_PROPERTY,
TRANS_ID_NOTIFY_OUTSIDE_PRESSED,
TRANS_ID_NOTIFY_SCREEN_SHOT,
TRANS_ID_DUMP_INFO,
};
@@ -56,6 +57,7 @@ public:
virtual void UpdateActiveStatus(bool isActive) = 0;
virtual sptr<WindowProperty> GetWindowProperty() = 0;
virtual void NotifyTouchOutside() = 0;
virtual void NotifyScreenshot() = 0;
virtual void DumpInfo(const std::vector<std::string>& params, std::vector<std::string>& info) = 0;
};
} // namespace Rosen
+1
View File
@@ -40,6 +40,7 @@ public:
void UpdateActiveStatus(bool isActive) override;
sptr<WindowProperty> GetWindowProperty() override;
void NotifyTouchOutside() override;
void NotifyScreenshot() override;
void DumpInfo(const std::vector<std::string>& params, std::vector<std::string>& info) override;
private:
static inline BrokerDelegator<WindowProxy> delegator_;
+10
View File
@@ -137,6 +137,16 @@ void WindowAgent::NotifyTouchOutside()
window_->NotifyTouchOutside();
}
void WindowAgent::NotifyScreenshot()
{
if (window_ == nullptr) {
WLOGFE("notify screenshot failed: window is null.");
return;
}
WLOGFI("called");
window_->NotifyScreenshot();
}
void WindowAgent::DumpInfo(const std::vector<std::string>& params, std::vector<std::string>& info)
{
if (window_ == nullptr) {
+60 -3
View File
@@ -20,11 +20,13 @@
#include <ability_manager_client.h>
#include <hisysevent.h>
#include "ipc_skeleton.h"
#include <ipc_skeleton.h>
#include <transaction/rs_interfaces.h>
#include "color_parser.h"
#include "display_manager.h"
#include "singleton_container.h"
#include "surface_capture_future.h"
#include "window_adapter.h"
#include "window_agent.h"
#include "window_helper.h"
@@ -41,8 +43,8 @@ namespace {
}
const WindowImpl::ColorSpaceConvertMap WindowImpl::colorSpaceConvertMap[] = {
{ ColorSpace::COLOR_SPACE_DEFAULT, COLOR_GAMUT_SRGB },
{ ColorSpace::COLOR_SPACE_WIDE_GAMUT, COLOR_GAMUT_DCI_P3 },
{ ColorSpace::COLOR_SPACE_DEFAULT, ColorGamut::COLOR_GAMUT_SRGB },
{ ColorSpace::COLOR_SPACE_WIDE_GAMUT, ColorGamut::COLOR_GAMUT_DCI_P3 },
};
std::map<std::string, std::pair<uint32_t, sptr<Window>>> WindowImpl::windowMap_;
@@ -546,6 +548,20 @@ ColorSpace WindowImpl::GetColorSpace()
return GetColorSpaceFromSurfaceGamut(surfaceGamut);
}
std::shared_ptr<Media::PixelMap> WindowImpl::Snapshot()
{
WLOGFI("WMS-Clinet Snapshot");
std::shared_ptr<SurfaceCaptureFuture> callback = std::make_shared<SurfaceCaptureFuture>();
RSInterfaces::GetInstance().TakeSurfaceCapture(surfaceNode_, callback);
std::shared_ptr<Media::PixelMap> pixelMap = callback->GetResult(2000); // wait for <= 2000ms
if (pixelMap != nullptr) {
WLOGFI("WMS-Clinet Save WxH = %{public}dx%{public}d", pixelMap->GetWidth(), pixelMap->GetHeight());
} else {
WLOGFE("Failed to get pixelmap, return nullptr!");
}
return pixelMap;
}
void WindowImpl::DumpInfo(const std::vector<std::string>& params, std::vector<std::string>& info)
{
if (params.size() == 1 && params[0] == PARAM_DUMP_HELP) { // 1: params num
@@ -1662,6 +1678,7 @@ void WindowImpl::RegisterTouchOutsideListener(const sptr<ITouchOutsideListener>&
void WindowImpl::UnregisterTouchOutsideListener(const sptr<ITouchOutsideListener>& listener)
{
std::lock_guard<std::recursive_mutex> lock(mutex_);
touchOutsideListeners_.erase(std::remove_if(touchOutsideListeners_.begin(),
touchOutsideListeners_.end(), [listener](sptr<ITouchOutsideListener> registeredListener) {
return registeredListener == listener;
@@ -1677,6 +1694,30 @@ void WindowImpl::RegisterAnimationTransitionController(const sptr<IAnimationTran
animationTranistionController_ = listener;
}
void WindowImpl::RegisterScreenshotListener(const sptr<IScreenshotListener>& listener)
{
if (listener == nullptr) {
WLOGFE("listener is nullptr");
return;
}
std::lock_guard<std::recursive_mutex> lock(mutex_);
if (std::find(screenshotListeners_.begin(), screenshotListeners_.end(), listener) !=
screenshotListeners_.end()) {
WLOGFE("Listener already registered");
return;
}
screenshotListeners_.emplace_back(listener);
}
void WindowImpl::UnregisterScreenshotListener(const sptr<IScreenshotListener>& listener)
{
std::lock_guard<std::recursive_mutex> lock(mutex_);
screenshotListeners_.erase(std::remove_if(screenshotListeners_.begin(),
screenshotListeners_.end(), [listener](sptr<IScreenshotListener> registeredListener) {
return registeredListener == listener;
}), screenshotListeners_.end());
}
void WindowImpl::SetAceAbilityHandler(const sptr<IAceAbilityHandler>& handler)
{
if (handler == nullptr) {
@@ -2347,6 +2388,22 @@ void WindowImpl::UpdateActiveStatus(bool isActive)
}
}
void WindowImpl::NotifyScreenshot()
{
std::vector<sptr<IScreenshotListener>> screenshotListeners;
{
std::lock_guard<std::recursive_mutex> lock(mutex_);
screenshotListeners = screenshotListeners_;
}
PostListenerTask([screenshotListeners]() {
for (auto& screenshotListener : screenshotListeners) {
if (screenshotListener != nullptr) {
screenshotListener->OnScreenshot();
}
}
});
}
void WindowImpl::NotifyTouchOutside()
{
std::vector<sptr<ITouchOutsideListener>> touchOutsideListeners;
+16
View File
@@ -277,6 +277,22 @@ void WindowProxy::NotifyTouchOutside()
}
}
void WindowProxy::NotifyScreenshot()
{
MessageParcel data;
MessageParcel replay;
MessageOption option(MessageOption::TF_ASYNC);
if (!data.WriteInterfaceToken(GetDescriptor())) {
WLOGFE("WriteInterfaceToken failed");
return;
}
if (Remote()->SendRequest(static_cast<uint32_t>(WindowMessage::TRANS_ID_NOTIFY_SCREEN_SHOT),
data, replay, option) != ERR_NONE) {
WLOGFE("SendRequest failed");
}
}
void WindowProxy::DumpInfo(const std::vector<std::string>& params, std::vector<std::string>& info)
{
MessageParcel data;
+4
View File
@@ -99,6 +99,10 @@ int WindowStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParce
NotifyTouchOutside();
break;
}
case WindowMessage::TRANS_ID_NOTIFY_SCREEN_SHOT: {
NotifyScreenshot();
break;
}
case WindowMessage::TRANS_ID_DUMP_INFO: {
std::vector<std::string> params;
if (!data.ReadStringVector(&params)) {
+4 -2
View File
@@ -36,8 +36,10 @@ ohos_fuzztest("WindowFuzzTest") {
"//foundation/windowmanager/wm:libwm",
"//utils/native/base:utils",
]
external_deps = [ "ipc:ipc_core" ]
external_deps = [
"ipc:ipc_core",
"multimedia_image_standard:image",
]
}
###############################################################################
@@ -69,6 +69,7 @@ public:
return nullptr;
}
void NotifyTouchOutside() override {}
void NotifyScreenshot() override {}
void DumpInfo(const std::vector<std::string>& params, std::vector<std::string>& info) override {}
RunnableFuture<AvoidArea> statusBarAvoidAreaFuture_;
RunnableFuture<AvoidArea> keyboardAvoidAreaFuture_;
+3
View File
@@ -63,6 +63,7 @@ public:
void MinimizeWindowsByLauncher(std::vector<uint32_t>& windowIds, bool isAnimated,
sptr<RSIWindowAnimationFinishedCallback>& finishCallback);
Orientation GetWindowPreferredOrientation(DisplayId displayId);
void OnScreenshot(DisplayId displayId);
private:
uint32_t GenWindowId();
void FlushWindowInfo(uint32_t windowId);
@@ -87,6 +88,8 @@ private:
void NotifyTouchOutside(const sptr<WindowNode>& node);
uint32_t GetEmbedNodeId(const std::vector<sptr<WindowNode>>& windowNodes, const sptr<WindowNode>& node);
void NotifyWindowPropertyChanged(const sptr<WindowNode>& node);
WMError GetFocusWindowNode(DisplayId displayId, sptr<WindowNode>& windowNode);
sptr<WindowRoot> windowRoot_;
sptr<InputWindowMonitor> inputWindowMonitor_;
std::atomic<uint32_t> windowId_ { INVALID_WINDOW_ID };
@@ -44,6 +44,7 @@ public:
virtual void OnDisplayStateChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type) override;
virtual void OnGetWindowPreferredOrientation(DisplayId displayId, Orientation &orientation) override;
virtual void OnScreenshot(DisplayId displayId) override;
};
class WindowManagerServiceHandler : public AAFwk::WindowManagerServiceHandlerStub {
@@ -108,6 +109,7 @@ public:
void GetWindowPreferredOrientation(DisplayId displayId, Orientation &orientation);
void OnAccountSwitched() const;
WMError UpdateRsTree(uint32_t windowId, bool isAdd) override;
void OnScreenshot(DisplayId displayId);
protected:
WindowManagerService();
virtual ~WindowManagerService() = default;
@@ -19,8 +19,8 @@
#include <snapshot.h>
#include <transaction/rs_interfaces.h>
#include "future.h"
#include "window_root.h"
#include "snapshot_stub.h"
#include "window_root.h"
#include "window_manager_hilog.h"
namespace OHOS {
@@ -42,35 +42,6 @@ private:
RSInterfaces& rsInterface_;
WMError TakeSnapshot(const std::shared_ptr<RSSurfaceNode>& surfaceNode, AAFwk::Snapshot& snapshot);
class GetSurfaceCapture : public SurfaceCaptureCallback, public Future<std::shared_ptr<Media::PixelMap>> {
public:
GetSurfaceCapture() = default;
~GetSurfaceCapture() {};
void OnSurfaceCapture(std::shared_ptr<Media::PixelMap> pixelmap) override
{
FutureCall(pixelmap);
}
protected:
void Call(std::shared_ptr<Media::PixelMap> pixelmap) override
{
if (!flag_) {
pixelMap_ = pixelmap;
flag_ = true;
}
}
bool IsReady() override
{
return flag_;
}
std::shared_ptr<Media::PixelMap> FetchResult() override
{
return pixelMap_;
}
private:
bool flag_ = false;
std::shared_ptr<Media::PixelMap> pixelMap_ = nullptr;
};
};
}
}
+31 -6
View File
@@ -148,25 +148,35 @@ WMError WindowController::NotifyWindowTransition(sptr<WindowTransitionInfo>& src
return WMError::WM_OK;
}
WMError WindowController::GetFocusWindowInfo(sptr<IRemoteObject>& abilityToken)
WMError WindowController::GetFocusWindowNode(DisplayId displayId, sptr<WindowNode>& windowNode)
{
DisplayId displayId = DisplayManagerServiceInner::GetInstance().GetDefaultDisplayId();
auto windowNodeContainer = windowRoot_->GetOrCreateWindowNodeContainer(displayId);
if (windowNodeContainer == nullptr) {
WLOGFE("windowNodeContainer is null, displayId: %{public}" PRIu64"", displayId);
return WMError::WM_ERROR_NULLPTR;
}
uint32_t focusWindowId = windowNodeContainer->GetFocusWindow();
auto windowNode = windowRoot_->GetWindowNode(focusWindowId);
if (windowNode == nullptr || !windowNode->currentVisibility_) {
WLOGFI("focusWindowId: %{public}u", focusWindowId);
auto thisWindowNode = windowRoot_->GetWindowNode(focusWindowId);
if (thisWindowNode == nullptr || !thisWindowNode->currentVisibility_) {
WLOGFE("focusWindowNode is null or invisible, focusWindowId: %{public}u", focusWindowId);
return WMError::WM_ERROR_INVALID_WINDOW;
}
abilityToken = windowNode->abilityToken_;
WLOGFI("focusWindowId: %{public}u", focusWindowId);
windowNode = thisWindowNode;
return WMError::WM_OK;
}
WMError WindowController::GetFocusWindowInfo(sptr<IRemoteObject>& abilityToken)
{
DisplayId displayId = DisplayManagerServiceInner::GetInstance().GetDefaultDisplayId();
sptr<WindowNode> windowNode;
WMError res = GetFocusWindowNode(displayId, windowNode);
if (res == WMError::WM_OK) {
abilityToken = windowNode->abilityToken_;
}
return res;
}
WMError WindowController::CreateWindow(sptr<IWindow>& window, sptr<WindowProperty>& property,
const std::shared_ptr<RSSurfaceNode>& surfaceNode, uint32_t& windowId, sptr<IRemoteObject> token,
int32_t pid, int32_t uid)
@@ -1049,5 +1059,20 @@ Orientation WindowController::GetWindowPreferredOrientation(DisplayId displayId)
}
return Orientation::UNSPECIFIED;
}
void WindowController::OnScreenshot(DisplayId displayId)
{
sptr<WindowNode> windowNode;
WMError res = GetFocusWindowNode(displayId, windowNode);
if (res != WMError::WM_OK) {
return;
}
auto windowToken = windowNode->GetWindowToken();
if (windowToken == nullptr) {
WLOGFE("notify screenshot failed: window token is null.");
return;
}
windowToken->NotifyScreenshot();
}
} // namespace OHOS
} // namespace Rosen
+12
View File
@@ -548,6 +548,11 @@ void DisplayChangeListener::OnGetWindowPreferredOrientation(DisplayId displayId,
WindowManagerService::GetInstance().GetWindowPreferredOrientation(displayId, orientation);
}
void DisplayChangeListener::OnScreenshot(DisplayId displayId)
{
WindowManagerService::GetInstance().OnScreenshot(displayId);
}
void WindowManagerService::ProcessPointDown(uint32_t windowId, bool isStartDrag)
{
return wmsTaskLooper_->PostTask([this, windowId, isStartDrag]() {
@@ -685,5 +690,12 @@ WMError WindowManagerService::UpdateRsTree(uint32_t windowId, bool isAdd)
return windowRoot_->UpdateRsTree(windowId, isAdd);
}).get();
}
void WindowManagerService::OnScreenshot(DisplayId displayId)
{
wmsTaskLooper_->PostTask([this, displayId]() {
windowController_->OnScreenshot(displayId);
});
}
} // namespace Rosen
} // namespace OHOS
@@ -17,6 +17,7 @@
#include <hitrace_meter.h>
#include "surface_capture_future.h"
#include "window_manager_hilog.h"
#include "wm_common.h"
@@ -33,11 +34,9 @@ void SnapshotController::Init(sptr<WindowRoot>& root)
WMError SnapshotController::TakeSnapshot(const std::shared_ptr<RSSurfaceNode>& surfaceNode, Snapshot& snapshot)
{
std::shared_ptr<GetSurfaceCapture> callback = std::make_shared<GetSurfaceCapture>();
std::shared_ptr<SurfaceCaptureFuture> callback = std::make_shared<SurfaceCaptureFuture>();
rsInterface_.TakeSurfaceCapture(surfaceNode, callback, scaleW, scaleH);
std::shared_ptr<Media::PixelMap> pixelMap = callback->GetResult(2000); // wait for 2000ms
std::shared_ptr<Media::PixelMap> pixelMap = callback->GetResult(2000); // wait for <= 2000ms
if (pixelMap == nullptr) {
WLOGFE("Failed to get pixelmap, return nullptr!");
return WMError::WM_ERROR_NULLPTR;