首页 > 其他分享 >Android 12 addWindow过程分析

Android 12 addWindow过程分析

时间:2023-06-12 19:11:26浏览次数:49  
标签:12 ViewRootImpl Session DisplayContent addWindow client new Android

1 背景

分析过Window层级结构之后,以addWindow为切入点看一下系统是怎么使用的。而且addWindow也是系统非常重要的一个环节,无论是Activity(PhoneWindow)还是各种系统窗口,都会走到这里。

addView举例:

frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
line 137

2 时序分析

2.1 client端(WMS之前)

WindowManager.addView()
	WindowManagerImpl.addView()
		WindowManagerGlobal.addView()
			WindowManagerGlobal.getWindowSession()
				WindowManagerService.openSession()
					new Session()
			new ViewRootImpl()
				ViewRootImpl.setView()
					Session.addToDisplayAsUser()
  1. 如果没有创建过Session(Aidl是IWindowSession,每个进程一个),则向WMS申请创建一个Session
  2. 然后在ViewRootImpl中调用Session的 addToDisplayAsUser方法。

2.2 WMS端

Session.addToDisplayAsUser()
	WindowManagerService.addWindow()
		WindowManagerService.getDisplayContentOrCreate()	 // 1
			RootWindowContainer.getWindowToken(IBinder binder)
			WindowToken.getDisplayContent()  or  RootWindowContainer.getDisplayContentOrCreate()
		new WindowToken()		// 并且设置DisplayContent(setDisplayContent())
		new WindowState()
		WindowState.attach()
			Session.windowAddedLocked()
				new SurfaceSession()
					new SurfaceComposerClient()		// jni
		WindowToken.addWindow()
			WindowToken.createSurfaceControl()
				WindowContainer.createSurfaceControl()
					WindowToken.makeSurface()
						WindowContainer.makeSurface()
							DisplayContent.makeChildSurface()
					setInitialSurfaceControlProperties()
				WindowContainer.setInitialSurfaceControlProperties()		// SurfaceControl.Builder.build()
					WindowContainer.setSurfaceControl()
					WindowContainer.updateSurfacePositionNonOrganized
		WindowManagerService.updateFocusedWindowLocked()
			RootWindowContainer.updateFocusedWindowLocked()
  1. 找到添加Window的DisplayContent
  2. 先后创建WindowToken(令牌)和WindowState(实际对象)
  3. 调用WindowState.attach()方法,内部会创建SurfaceSession,native层对应创建SurfaceComposerClient
  4. 调用WindowToken.addWindow()方法,内部创建SurfaceControl,native层对应创建SurfaceControl

注释:

  1. 如果app在哪一个DisplayContent添加了Window,就返回哪一个DisplayContent。TODO DisplayContent的mTokenMap的管理。

3 token的传递

这里分析一下Server端怎么区分不同的client。

3.1 client创建自己的token

// ViewRootImpl.java
public final WindowManager.LayoutParams mWindowAttributes = new WindowManager.LayoutParams();

token是IBinder类型的。

以StatusBar的添加为例,ViewRootImpl中的mWindowAttributes的token就是addView的时候new的。

3.2 server中怎么使用client的token

WMS在addWindow的时候会通过token找到一个DisplayContent对象:

// 1 WMS.addWindow()中
final DisplayContent displayContent = getDisplayContentOrCreate(displayId, attrs.token);

这个寻找DisplayContent的过程如上图。

4 Session和IWindow接口

这里分析一下WMS.addWindow函数的前两个入参:

// WMS
public int addWindow(Session session, IWindow client, LayoutParams attrs, int viewVisibility,
            int displayId, int requestUserId, InsetsState requestedVisibility,
            InputChannel outInputChannel, InsetsState outInsetsState,
            InsetsSourceControl[] outActiveControls)
  • 第一个入参 Session 和client对应,一个client对应一个Session
  • 第二个入参IWindow client和client的IWindow的实现W类对应,WMS用client唯一标识一个WindowState

简单概括:addWindow时,Session负责client和Server间的通信,而IWindow参数是WindowState在client的代理。

看一下IWindow是怎么实现和初始化对象的。

// ViewRootImpl.java

final W mWindow;

public ViewRootImpl(@UiContext Context context, Display display, IWindowSession session,
        boolean useSfChoreographer) {
    mWindow = new W(this);
}

static class W extends IWindow.Stub {
    
    private final IWindowSession mWindowSession;
    
    W(ViewRootImpl viewAncestor) {
        ...
        mWindowSession = viewAncestor.mWindowSession;
    }
}

// ViewRootImpl.setView()方法中,mWindow最为参数请求Session去addWindow。
res = mWindowSession.addToDisplayAsUser(mWindow, mWindowAttributes,
                            getHostVisibility(), mDisplay.getDisplayId(), userId,
                            mInsetsController.getRequestedVisibility(), inputChannel, mTempInsets,
                            mTempControls);

标签:12,ViewRootImpl,Session,DisplayContent,addWindow,client,new,Android
From: https://www.cnblogs.com/yulisuo/p/17475885.html

相关文章

  • LonLife-ACM 1129 - 喵哈哈村的战斗魔法师丶坏坏い月
    原题链接1129-喵哈哈村的战斗魔法师丶坏坏い月TimeLimit:3s MemoryLimit:256MByteSolved:85DESCRIPTION坏坏い月是月大叔的ID,他是一个掌握者772002种魔法的物理系战士,最擅长的技能就是搞事。今天他又要开始搞事了。nn个数,你需要实现一下操作:lrv,在[l,r]......
  • 51nod-1280 前缀后缀集合
    原题链接1280 前缀后缀集合题目来源: Codility基准时间限制:1 秒空间限制:131072 KB分值: 40 难度:4级算法题 收藏 关注一个数组包含N个正整数,其中有些是重复的。一个前缀后缀集是满足这样条件的下标对(P,S),0<=P,S......
  • Android自动化随机测试工具-Monkey测试心得
    心得一Monkey测试Android应用,尤其是在测试长时间的稳定性和健壮性时,切勿盲目的使用--throttle参数。我们的测试思路应该是:第一次,我们尽量先不使用--throttle参数,执行事件计数少点,比如300或500。执行完后,记录下所需要的时间。接下来,我们使用第一次的Monkey命令,加......
  • 6/12 闲话
    今日推歌:神っぽいな/ピノキオピー歌词今天除了T1都不会,打完暴力分就开始发呆T1:考场上一眼原,虽然之前没做过,但是很快就搞出来了设\(f_i\)为目前有\(i\)张邮票,要买到\(n\)张邮票的期望次数,写一个逆推套路式子:\[f_i=\frac{n-i}{n}(f_{i+1}+1)+\frac{i}{n}(f_i+1)......
  • 【230612-2】三角形ABC中,角A=60度,AB=2,BC=根号6,AD是角A的平分线。求:AD=?(23年全国高考
    【题目】三角形ABC中,角A=60度,AB=2,BC=根号6,AD是角A的平分线。求:AD=?(23年全国高考甲卷理科,16,5)......
  • Android Handler 详解
    概述为了避免多个线程同时更新UI,导致不可预知的错误;所以现今几乎所有的GUI框架都只允许在主线程修改UI;因此这些框架都选择了消息驱动编程模型;消息驱动编程模型有以下几个组件:消息队列:存储待处理的消息分发器:将不同事件分发到不同的业务逻辑单元消息通道:分发器和处理器......
  • Jmeter:"An error occurred: Can't connect to X11 window server using 'lacalhost:12
    做各种不同项目的性能测试,都需要在项目本地压测服务器配置jmeter,需要时还要调出jmeter图形化界面来调试jmeter脚本。标题中的问题遇过多次,这次做个记录。1.启动jmeter报错在配置好jmeter环境变量的linux系统执行jmeter命令,报错如下:[root@localhost~]#jmeter=====......
  • kanzi的android程序修改包名和应用程序名字
    1、修改进程名: 2、修改应用程序名字: 3、修改系统调度ID 通知权限 ......
  • 012 数据库学习笔记--自定义函数
    自定义函数:根据自己的需要,自定义一些函数分类:标量函数、内嵌表值函数、多声明表值函数标量函数:对单一值的操作,返回单一值;包含beginend创建的时候,指定了函数所有体,调用时也必须指定函数所有者调用时,如果函数中指定了默认值,调用的时候,可使用默认值default代替在语法上r......
  • scrcpy——Android投屏神器(使用教程)
    scrcpy简介简单地来说,scrcpy就是通过adb调试的方式来将手机屏幕投到电脑上,并可以通过电脑控制您的Android设备。它可以通过USB连接,也可以通过Wifi连接(类似于隔空投屏),而且不需要任何root权限,不需要在手机里安装任何程序。scrcpy同时适用于GNU/Linux,Windows和macOS。它的一些特......