【Android WMS】从应用图像获取来认识WindowState
创始人
2025-05-30 10:56:46
0

为了能够更动感的去学习WMS窗口概念,这里我们从应用的图像画面获取来认识WindowState,作为WMS学习的一个突破口,现在暂时记住下面这句话,

  1. WindowState是WMS中的一个对象,保存了APP窗口相关信息。

保存了窗口相关信息?图像信息也包含么?答案是包含了的,我们可以从WindowState里获取到应用的GrahpicBuffer,进而保存期图像画面。(使用SurfaceControl相关方法)

在【Android】使用SurfaceControl.captureLayers获取应用图像Layer试验 里面

试验了调用WallPaperControll的方法Bitmap screenshotWallpaperLocked()方法来保存WapllPaper图像,

这个方法里通过SurfaceControl.captureLayers调用,传入wallpaperWindowState.getSurfaceControl().getHandle(),得到了相应的GraphicBuffer,

SurfaceControl.captureLayers( wallpaperWindowState.getSurfaceControl().getHandle(), bounds, 1 /* frameScale */);

695    /**
696     * Take a screenshot of the wallpaper if it's visible.
697     *
698     * @return Bitmap of the wallpaper
699     */
700    Bitmap screenshotWallpaperLocked() {
701        if (!mService.mPolicy.isScreenOn()) {
702            if (DEBUG_SCREENSHOT) {
703                Slog.i(TAG_WM, "Attempted to take screenshot while display was off.");
704            }
705            return null;
706        }
707
708        final WindowState wallpaperWindowState = getTopVisibleWallpaper();
709        if (wallpaperWindowState == null) {
710            if (DEBUG_SCREENSHOT) {
711                Slog.i(TAG_WM, "No visible wallpaper to screenshot");
712            }
713            return null;
714        }
715
716        final Rect bounds = wallpaperWindowState.getBounds();
717        bounds.offsetTo(0, 0);
718
719        GraphicBuffer wallpaperBuffer = SurfaceControl.captureLayers(
720                wallpaperWindowState.getSurfaceControl().getHandle(), bounds, 1 /* frameScale */);
721
722        if (wallpaperBuffer == null) {
723            Slog.w(TAG_WM, "Failed to screenshot wallpaper");
724            return null;
725        }
726        return Bitmap.createHardwareBitmap(wallpaperBuffer);
727    }

这里给了我们启发,WindowState.getSurfaceControl()方法可以获取到应用SurfaceControl相关内容,进而获取到应用图像。

命令dumpsys window windows可以查看到WIndowState的信息,如

WINDOW MANAGER WINDOWS (dumpsys window windows)Window #0 Window{bb28569 u0 ScreenDecorOverlayBottom}:mDisplayId=0 rootTaskId=1 mSession=Session{d35f7c7 3452:u0a10142} mClient=android.os.BinderProxy@1b679d8mOwnerUid=10142 showForAllUsers=true package=com.android.systemui appop=NONEmAttrs={(0,0)(fillxwrap) gr=BOTTOM CENTER_VERTICAL sim={adjust=pan} layoutInDisplayCutoutMode=always ty=NAVIGATION_BAR_PANEL fmt=TRANSLUCENTfl=NOT_FOCUSABLE NOT_TOUCHABLE NOT_TOUCH_MODAL LAYOUT_IN_SCREEN SPLIT_TOUCH FLAG_SLIPPERYpfl=SHOW_FOR_ALL_USERS NO_MOVE_ANIMATION IS_ROUNDED_CORNERS_OVERLAY COLOR_SPACE_AGNOSTIC USE_BLAST FIT_INSETS_CONTROLLED TRUSTED_OVERLAYvsysui=LAYOUT_STABLEbhv=DEFAULT}Requested w=1080 h=66 mLayoutSeq=125

一个比较朴素的试验,可以在WindowState的dump方法里,添加SurfaceControl.captureLayers方法,获取到相应的GraphicBuffer,再仿照 Bitmap screenshotWallpaperLocked()里的处理,调用

Bitmap.createHardwareBitmap方法,转换为Bitmap对象,再调用Bitmap的compress方法,就可以保存图像了。

3305    void dump(PrintWriter pw, String prefix, boolean dumpAll) {
3306        final TaskStack stack = getStack();
3307        pw.print(prefix); pw.print("mDisplayId="); pw.print(getDisplayId());
3308                if (stack != null) {
3309                    pw.print(" stackId="); pw.print(stack.mStackId);
3310                }
3311                pw.print(" mSession="); pw.print(mSession);
3312                pw.print(" mClient="); pw.println(mClient.asBinder());
3313        pw.print(prefix); pw.print("mOwnerUid="); pw.print(mOwnerUid);
3314                pw.print(" mShowToOwnerOnly="); pw.print(mShowToOwnerOnly);
3315                pw.print(" package="); pw.print(mAttrs.packageName);
3316                pw.print(" appop="); pw.println(AppOpsManager.opToName(mAppOp));
3317        pw.print(prefix); pw.print("mAttrs="); pw.println(mAttrs.toString(prefix));
3318        pw.print(prefix); pw.print("Requested w="); pw.print(mRequestedWidth);
3319                pw.print(" h="); pw.print(mRequestedHeight);

这个就很直观的展现了WindowState和应用surface相关联系。也说明,WMS有能力获取到应用图像。

WMS在创建窗口的时候创建WIndowState,并且告诉SurfaceFlinger去创建Surface对象,提供给App去绘图。

Surface联系如下:

参考资料:

https://blog.csdn.net/yangwen123/article/details/80674965?spm=1001.2014.3001.5502

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...
【Ctfer训练计划】——(三... 作者名:Demo不是emo  主页面链接:主页传送门 创作初心ÿ...