当前位置: 首页 > article >正文

【问题分析】CtsWindowManagerDeviceAnimations【Android15】

在这里插入图片描述

1 case逻辑分析

CtsWindowManagerDeviceAnimations.testRightEdgeExtensionWorksDuringActivityTransition报错:

java.lang.AssertionError: No screenshot of the activity transition passed the assertions :: ColorCheckResult{isFailure=true, firstWrongPixel=Point(450, 1263), expectedColor=Color(1.0, 0.0, 0.0, 1.0, sRGB IEC61966-2.1), actualColor=Color(0.0, 0.0, 0.0, 0.0, sRGB IEC61966-2.1)},

根据case的内容大概理解一下这个case的测试逻辑:

在这里插入图片描述

启动一个名为EdgeExtensionActivity的Activity,这个Activity重写了动画,当播放动画时,EdgeExtensionActivity在X轴方向上被缩放到50%,并且边缘像素延伸到屏幕右边。

因为这个播放动画的Activity是一半蓝,一半红的,我们预期前25%的像素列是蓝色的(来自Activity),然后剩下的75%的像素列是红色的(25%来自Activity,50%来自edge extenstion)。

然后在动画过程中截图,做个对比:

左边是我们的机器有问题,可以看到压缩后左半屏右边的红色边缘是没有延伸到右半屏的。

右边是pixel没问题,可以看到压缩后左半屏右边的红色像素延伸到了右半屏。

在这里插入图片描述

再看报错内容:

在这里插入图片描述

预期在Point(450, 1263)位置的像素颜色应该是:

Color(1.0, 0.0, 0.0, 1.0, sRGB IEC61966-2.1),即红色。

但是实际上是:

Color(0.0, 0.0, 0.0, 0.0, sRGB IEC61966-2.1),即黑色。

所以case fail。

2 本地Demo模拟CTS case

这个问题刚拿到后没有什么头绪,而且没有搞懂这个动画是怎么实现的,先看下能否本地写一个Demo模拟一下case逻辑。

继续梳理case的逻辑,这个case的核心逻辑为,创建一个名为EdgeExtensionActivity的Activity,这个Activity是一半蓝色,一半红色:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent">
    <View android:background="#0000ff" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1"/>
    <View android:background="#ff0000" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1"/>
</LinearLayout>

就像这样:

在这里插入图片描述

然后这个Activity在onResume中调用overridePendingTransition重写了enter动画和exit动画:

    @Override
    protected void onResume() {
        super.onResume();
        mPendingEnterRes = R.anim.edge_extension_right;
        mPendingExitRes = R.anim.alpha_0;
        overridePendingTransition(mPendingEnterRes, mPendingExitRes);
    }

这里我们只关注enter动画,动画样式为自定义的R.anim.edge_extension_right:

在这里插入图片描述

这个动画样式我在aosp中没找到,反编译了CTS的CtsWindowManagerDeviceAnimations.apk后得到:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false">
    <alpha android:interpolator="@android:interpolator/linear" android:duration="5000" android:fillBefore="true" android:fillAfter="true" android:startOffset="0" android:fromAlpha="1" android:toAlpha="1" android:fillEnabled="true"/>
    <scale android:interpolator="@android:interpolator/linear" android:duration="5000" android:startOffset="0" android:fromXScale="0.5" android:toXScale="0.5" android:fromYScale="1" android:toYScale="1"/>
    <extend android:interpolator="@android:interpolator/linear" android:duration="5000" android:startOffset="0" android:fromExtendLeft="0" android:fromExtendTop="0" android:fromExtendRight="100%" android:fromExtendBottom="0" android:toExtendLeft="0" android:toExtendTop="0" android:toExtendRight="100%" android:toExtendBottom="0"/>
</set>

定义了三种动画:

1)、alpha:前后没有变化。

2)、scale:动画开始的时候X轴方向上缩放到0.5,并且这个缩放比例不变,一直保持到动画结束。

3)、extend,有8个特定的描述该类型动画的属性:

  • fromExtendLeft和toExtendLeft。
  • fromExtendTop和toExtendTop。
  • fromExtendRight和toExtendRight。
  • fromExtendBottom和toExtendBottom。

并且设置了fromExtendRight和toExtendRight都是100%,这个属性暂时还不清楚是如何作用。

因为pixel上是正常的,因此在Demo上做了一些修改后,看到:

在这里插入图片描述

进行对比,依稀对extend类型的动画有了一点理解,即将Activity的边缘像素延伸到屏幕的边缘。

再进行一下实验,将整个过程中将X和Y轴方向上都缩放0.5,然后fromExtendRight和fromExtendBottom设置为10%,toExtendRight和toExtendBottom设置为100%,看下是什么效果:

在这里插入图片描述

的确是把Activity的边缘像素延伸到屏幕的边缘的感觉。

再把这个Demo装到我们的机器,发现5s的动画过程中一直都是以下状态:

在这里插入图片描述

只看到了scale的动画效果,但是没有extend的动画效果。

这么一对比,看起来似乎是我们的机器,extend这个类型的动画压根就没有生效。

3 ExtendAnimation分析

在aosp中搜索fromExtendRight等关键字,看到使用的地方在ExtendAnimation:

在这里插入图片描述

在ExtendAnimation的构造方法中被解析,而ExtendAnimation创建的地方在AnimationUtils.createAnimationFromXml:

在这里插入图片描述

也很好理解,如果动画的标签是extend,那么创建ExtendAnimation类型的动画。

再看fromExtendRight和mToRightValue这些属性被解析出来后,都用在什么地方,搜索了一下代码,只有一处,在ExtendAnimation.initialize:

在这里插入图片描述

调用堆栈为:

在这里插入图片描述

用来初始化ExtendAnimation的两个Insets类型的成员变量mFromInsets和mToInsets。

而成员变量mFromInsets和mToInsets使用的地方主要是在ExtendAnimation.applyTransformation和ExtendAnimation.hasExtension:

在这里插入图片描述

applyTransformation这个方法很熟悉了,Animation的子类通过实现这个方法,来计算动画过程中特定时间点下的动画要应用的transformation。

看下调用堆栈为:

在这里插入图片描述

看到关键点在TransitionAnimationHelper.edgeExtendWindow:

在这里插入图片描述

这里看下edgeBounds和extensionRect的值,我的屏幕是720 * 1612,基于我们设置的extend动画参数:

    <extend android:interpolator="@android:interpolator/linear" android:duration="5000" android:startOffset="0" android:fromExtendLeft="0" android:fromExtendTop="0" android:fromExtendRight="10%" android:fromExtendBottom="0" android:toExtendLeft="0" android:toExtendTop="0" android:toExtendRight="100%" android:toExtendBottom="0"/>

得到edgeBounds=Rect(719, 0 - 720, 1612), extensionRect=Rect(0, 0 - 720, 1612)

再看TransitionAnimationHelper.createExtensionSurface方法:

在这里插入图片描述

大致可以理解一下,将整个屏幕截图,然后截取edgeBounds对应的区域,然后从起始位置开始,一直拓展到extensionRect区域。

回到我们的问题,既然ExtendAnimation没有生效,那么大概率是这里的edgeBuffer返回了null,后续继续在SurfaceFlinger.captureLayers打印log,果然,在SurfaceFlinger的这里返回了:

在这里插入图片描述

发现截图的进程对应的App没有声明该权限,android.permission.CAPTURE_BLACKOUT_CONTENT,所以截图失败。

看了下我们的SystemUI,是没有声明这个权限的,反编译pixel的SystemUIGoogle,发现:

在这里插入图片描述

pixel的SystemUI(据SystemUI的同事说pixel的SystemUI不是aosp的那个SystemUI)是添加了这个权限的,所以pixel的SystemUI可以截图,并且后续正常运行ExtendAnimation。

另外一提aosp的SystemUI,即“ /frameworks/base/packages/SystemUI/AndroidManifest.xml”也是没有声明这个权限的,这不是google挖坑吗?只给自己pixel的SystemUI添加这个权限?

最后再用winscope看下画红色的是什么玩意:

在这里插入图片描述

“Right Edge Extension”下的一个名为“bbq-wrapper”的Layer。


http://www.kler.cn/a/283706.html

相关文章:

  • 深入探索:Scrapy深度爬取策略与实践
  • 多进程/线程并发服务器
  • 密码学的基本原理
  • 【插件】多断言 插件pytest-assume
  • 大语言模型:解锁自然语言处理的无限可能
  • Fastapi使用MongoDB作为数据库
  • SpringBoot中@SchedulerLock注解实现定时任务中分布式锁的使用
  • CTFhub通关攻略-SSRF篇【1-5关】
  • windows安装Docker的步骤
  • 内联函数与动态内存分配
  • URP custompasscustom render objects
  • c++多线程交替输出
  • 启动盘如何复原
  • 【一文详解】内外网文件摆渡系统,解决网间数据安全传输问题
  • 【Python进阶(十二)】——自然语言处理
  • 《华为云 AI:开启智能未来的钥匙》
  • zsh 的补全系统
  • 数字芯片设计验证经验分享(第三部分):将ASIC IP核移植到FPGA上——如何确保性能与时序以完成充满挑战的任务!
  • 【FRP 内网穿透】
  • 【问题分析】SetupWizard退出动画卡住【Android15】
  • 【零知识证明】Groth16
  • GAMES202——作业3 Screen Space Ray Tracing
  • 创建型设计模式-构建器(builder)模式-python实现
  • 35. 交错动画 导航列表项的悬停和聚焦效果
  • Linux下UDP编程
  • InternVL 多模态模型部署微调实践