安卓车载多屏互动副屏底部有黑线条NavigationBar分析

背景:

在学习了马哥的wms和多屏互动课程后,大家普遍都可以跟着做出如下图效果的多屏互动:

其实初略来看这个成果已经完成一个多屏互动项目大部分功能,但是其实还是有一些bug的存在,今天我们就来分析一下多屏互动相关的bug补充哈。

副屏Activity底部有黑线条分析

虚拟屏幕下下面的所有Activity在底部都会显示一个黑线条,具体如图展示:

明显第二屏幕的底部黑线看起来很诡异,下面这个黑线条其实是我们不需要的,这里就需要分析一下为啥会有这个黑线条

分析思路:

dumpsys SurfaceFlinger分析

在最后合成部分查看副屏display的图层

明显看到了Activity上面还有一个NavigationBar2这个图层,那么接下来其实就好办了,找到这个NavigationBar2窗口添加地方

看看NavigationBar2这个图层对应窗口是谁创建的

bash 复制代码
Window #0 Window{5819104 u0 NavigationBar2}:
    mDisplayId=2 rootTaskId=1140 mSession=Session{4e45c83 740:u0a10109} mClient=android.os.BinderProxy@e1cd996
    mOwnerUid=10109 showForAllUsers=true package=com.android.systemui appop=NONE
    mAttrs={(0,0)(fillx168) gr=BOTTOM CENTER_VERTICAL sim={adjust=pan} layoutInDisplayCutoutMode=always ty=NAVIGATION_BAR fmt=TRANSLUCENT
      fl=NOT_FOCUSABLE NOT_TOUCH_MODAL WATCH_OUTSIDE_TOUCH SPLIT_TOUCH FLAG_SLIPPERY
      pfl=LAYOUT_SIZE_EXTENDED_BY_CUTOUT COLOR_SPACE_AGNOSTIC USE_BLAST FIT_INSETS_CONTROLLED TRUSTED_OVERLAY
      bhv=DEFAULT

明显看到是package=com.android.systemui创建,那么接下来怎么找对应的NavigationBar2的窗口创建呢?

这里马哥老粉丝学员肯定会想到是不是可以打堆栈呢?

这里确实是可以的,因为一般NavigationBar2属于窗口最后肯定是需要执行下面这一部分WindowManager.addView的代码

具体堆栈就不贴了,属于学员们自己要学会的基本功。

最后其实是新屏幕创建准备好了以后会通知systemui下面代码

这里再看看createNavigationBar

这里核心关键可以看到有一个拦截是否要创建NavigationBar,来看看shouldCreateNavBarAndTaskBar方法

cpp 复制代码
 private boolean shouldCreateNavBarAndTaskBar(Context context, int displayId) {
        final IWindowManager wms = WindowManagerGlobal.getWindowManagerService();
				//主屏幕调用是setting值
        if (displayId == mDisplayTracker.getDefaultDisplayId() &&
                LineageSettings.System.getIntForUser(context.getContentResolver(),
                        LineageSettings.System.FORCE_SHOW_NAVBAR, 0,
                        UserHandle.USER_CURRENT) == 1) {
            return true;
        }
        //非主屏幕就调用wms的hasNavigationBar接口
        try {
            return wms.hasNavigationBar(displayId);
        } catch (RemoteException e) {
            // Cannot get wms, just return false with warning message.
            Log.w(TAG, "Cannot get WindowManager.");
            return false;
        }
    }

下面来看看wms的hasNavigationBar接口:

cpp 复制代码
    public boolean hasNavigationBar(int displayId) {
        synchronized (mGlobalLock) {
            final DisplayContent dc = mRoot.getDisplayContent(displayId);
            if (dc == null) {
                return false;
            }
            return dc.getDisplayPolicy().hasNavigationBar();
        }
    }

这里看看hasNavigationBar方法

就是靠两个标志位来的主要我们来看看mHasNavigationBar,mForceNavbar看了是不满足的

对于副屏主要就是靠mDisplayContent.supportsSystemDecorations()来决定:

可以看到这里的条件还是比较严格的,这里大部分和我们的display创建参数有关系

1、受信任display

2、有设置FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS

(当然也还有其他settings也可以控制,大家可以一一确定,默认一般setting为false)

那么我们dumpsys display确认一下

确实看到创建副屏满足上面条件,到此整个副屏显示一条黑线就清楚,本质就是显示了一个NavigationBar盖在上面,为啥显示NavigationBar是因为副屏创建时候有相关的FLAG让显示及是相关的Trust屏幕

如何修改

原因知道了,那么修改就简单多了,可以直接修改FLAG也好,或者直接暴力修改让所有副屏都不显示NavigationBar也可以,这里其实建议大家可以自己根据副屏的其他特性判断,自己根据情况细分,这里只是为了演示就直接修改成不显示:

修改后看看效果:

明显可以看到副屏已经没有了那个小黑条,即不在副屏创建NavigationBar。

具体详情试看方式:

投屏专题部分:
https://mp.weixin.qq.com/s/IGm6VHMiAOPejC_H3N_SNg

更多framework详细代码和资料参考如下链接

hal+perfetto+surfaceflinger
https://mp.weixin.qq.com/s/LbVLnu1udqExHVKxd74ILg

其他课程七件套专题:

点击这里
https://mp.weixin.qq.com/s/Qv8zjgQ0CkalKmvi8tMGaw

视频试看:
https://www.bilibili.com/video/BV1wc41117L4/

更多framework假威风耗:androidframework007

相关推荐
openinstall全渠道统计2 小时前
免填邀请码工具:赋能六大核心场景,重构App增长新模型
android·ios·harmonyos
双鱼大猫3 小时前
一句话说透Android里面的ServiceManager的注册服务
android
双鱼大猫3 小时前
一句话说透Android里面的查找服务
android
双鱼大猫3 小时前
一句话说透Android里面的SystemServer进程的作用
android
双鱼大猫3 小时前
一句话说透Android里面的View的绘制流程和实现原理
android
双鱼大猫4 小时前
一句话说透Android里面的Window的内部机制
android
双鱼大猫4 小时前
一句话说透Android里面的为什么要设计Window?
android
双鱼大猫4 小时前
一句话说透Android里面的主线程创建时机,frameworks层面分析
android
苏金标5 小时前
android 快速定位当前页面
android
雾里看山8 小时前
【MySQL】内置函数
android·数据库·mysql