Android16 EDLA CtsWindowManagerDeviceActivity存在fail方法testStartActivityWithLaunchBounds

一、前言

EDLA Window相关的报错一般是: frameworks/base/services/core/java/com/android/server/wm 改动导致;

也有可能是server目录下的am、pm、input、inputmethod 代码修改导致;

暂时不是很会分析窗口的问题,这里记录一下遇到的报错,后续方便快速分析解决。

本文分析的是CtsWindowManagerDeviceActivity项的其中一个Failed。

二、CtsWindowManagerDeviceActivity项的Failed解决

刚开始是六个Failed项:

在这里插入图片描述

上面这几个报错都是在 frameworks/base/services/core/java/com/android/server/wm 改动的地方添加了cts测试判断;

还有就是取消自定义默认显示的悬浮框;

后续重新测试,出现了另外一个Failed:

报错方法 testStartActivityWithLaunchBounds

在这里插入图片描述

报错的项名称(类名、方法名):

android.server.wm.activity.StartActivityTests#testStartActivityWithLaunchBounds

看报错内容主要是

预期的视图是1920 * 2160的,但是实际是3840 * 2160;

这个我也不知咋说。最后是回退代码发现哪里导致的。

是修改了多视窗导致的,但是不是framework的代码,

是一个配置文件修改导致,但是如果修改framework某个地方的代码应该也会出现。

2、导致报错的修改:

release/build/release/aconfig/bp2a/com.android.window.flags/fix_layout_existing_task_flag_values.textproto

flag_value {
  package: "com.android.window.flags"
  name: "fix_layout_existing_task"
  state: ENABLED // 修改成 state: DISABLED 导致Failed
  permission: READ_ONLY
}

内容:state: ENABLED 修改成 state: DISABLED 导致。如果要解决这个Failed可以回退这个修改。

这也是为啥我回退了framework的代码,还是存在该项Failed的原因,有些情况是修改配置属性导致Failed 的。

该代码修改的问题是: 【多视窗】在侧边栏多视窗应用列表打开WPS,小窗出来后会变小 。

这个属性对应什么代码?

3、后续分析

fix_layout_existing_task_flag_values.textproto 的 state 属性是对应:fixLayoutExistingTask()

com.android.window.flags.Flags.fixLayoutExistingTask()

具体如何分析出来的,不太清楚,是修改多视窗视图同事叶工分析的。

Flags类应该是编译生成的。有点类似蓝牙的那个prop属性。代码看不到实现,仔细研究可以看到属性的和应方法。

在系统源码 grep -nr com.android.window.flags 会有非常多代码,但是 grep -nr fixLayoutExistingTask 只有三个地方有:

release/frameworks/base/services# grep -nr fixLayoutExistingTask
core/java/com/android/server/wm/DesktopModeLaunchParamsModifier.java:97: //这个一般没用
	if (com.android.window.flags.Flags.fixLayoutExistingTask()

core/java/com/android/server/wm/ActivityStarter.java:3147:        
	if (com.android.window.flags.Flags.fixLayoutExistingTask()) {

core/java/com/android/server/wm/Task.java:6260:        
	if (com.android.window.flags.Flags.fixLayoutExistingTask()) {

fixLayoutExistingTask() 方法默认是true的,但是目前系统功能需要是false;

EDLA测试需要跑原生的代码流程,否则测试会出现Failed;

修改方法就是测试cts的时候,fixLayoutExistingTask() 的条件判断的时候为true,否则为false;

4、兼容功能和Failed项的修改

ActivityStarter.java 和 Task.java都要修改,这里举例 Task.java 的修改:

class ActivityStarter {
    private void setTargetRootTaskIfNeeded(ActivityRecord intentActivity) {
        //EDLA test 添加了cts属性判断,默认为false,测试的时候cts属性设置为true,
        boolean isinstallCts = SystemProperties.getBoolean("persist.skg.isinstall.cts", false);
        if (com.android.window.flags.Flags.fixLayoutExistingTask() && isinstallCts) {
            // Layout the task to ensure the Task is in correct bounds.
            mSupervisor.getLaunchParamsController().layoutTask(intentTask,
                    mStartActivity.info.windowLayout, mStartActivity, mSourceRecord, mOptions);
        }
        ...
    }
    ....
}

上面虽然未修改 fixLayoutExistingTask() 方法的返回值,但是默认是为true的,

所以只要添加一个判断属性值,即可控制这个方法的流程。

Cts测试的时候:fixLayoutExistingTask() 的整个条件判断的时候为true,否则为false;

所以如果framework里面Java修改 fixLayoutExistingTask() 的判断逻辑或者跳过该方法的判断也会造成Failed。

CtsWindowManagerDeviceActivity项的Failed:
android.server.wm.activity.StartActivityTests#testStartActivityWithLaunchBounds

三、其他

1、小结

(1)window相关的Failed项一般是framework的修改导致;
(2)上面 testStartActivityWithLaunchBounds 方法的Failed,可能是配置文件的修改,也可能是framework的修改;
(3)如果代码其他地方修改干扰到了多视窗视图的大小也会导致该项Failed。

2、cts代码分析

cts的报错理论上都是在系统源码里面能看到测试过程的代码的;

报错信息:

CtsWindowManagerDeviceActivity项的Failed:
android.server.wm.activity.StartActivityTests#testStartActivityWithLaunchBounds

#号,前面就是包名类名,后面就是方法名。

在系统源码release/cts 目录下,grep -nr testStartActivityWithLaunchBounds 可以找到测试方法。

下面是测试方法的代码:

release\cts\tests\framework\base\windowmanager\src\android\server\wm\activity\StartActivityTests.java

    /**
     * Test the activity launched with ActivityOptions#setLaunchBounds should be launched with the
     * requested bounds.
     */
    @Test
    @ApiTest(apis = {"android.app.ActivityOptions#setLaunchBounds"})
    @RequiresFlagsEnabled(com.android.window.flags.Flags.FLAG_FIX_LAYOUT_EXISTING_TASK)
    public void testStartActivityWithLaunchBounds() {
        assumeTrue("Device doesn't support pip or freeform", supportsPip() || supportsFreeform());


        // Launch the Activity again to bring up the existing instance with different bounds.
        final Rect newBounds;
        if (bounds.width() > bounds.height()) {
            newBounds = new Rect(bounds.left, bounds.top, bounds.right / 2, bounds.bottom);
        } else {
            newBounds = new Rect(bounds.left, bounds.top, bounds.right, bounds.bottom / 2);
        }

        final ActivityOptions options = ActivityOptions.makeBasic();
        options.setLaunchBounds(newBounds);
        options.setLaunchWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
        final Intent intent =
                new Intent()
                        .addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_SINGLE_TOP)
                        .setComponent(TEST_ACTIVITY);
        mContext.startActivity(intent, options.toBundle());
        waitAndAssertResumedActivity(TEST_ACTIVITY);

        // Ensure the bounds are updated. 报错的堆栈行数:432,是下面这行
        assertEquals(
                "Activity bounds should be updated.",
                newBounds,
                mWmState.getActivity(TEST_ACTIVITY).getBounds());

        // Start home
        launchHomeActivity();

        // Launch the Activity again with different bounds, which adds a new Activity instance
        // and removes the existing Activity instance (FLAG_ACTIVITY_CLEAR_TASK).
        newBounds.right -= 1;
        newBounds.bottom -= 1;
        options.setLaunchBounds(newBounds);
        intent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)
                .setComponent(TEST_ACTIVITY);
        mContext.startActivity(intent, options.toBundle());
        waitAndAssertResumedActivity(TEST_ACTIVITY);

        // Ensure the bounds are updated.
        assertEquals(
                "Activity bounds should be updated.",
                newBounds,
                mWmState.getActivity(TEST_ACTIVITY).getBounds());
    }
...

newBounds 不符合多窗口规则 导致预言失败,所以导致Failed。

具体是如何分析的这个暂时不太会。
估计需要深入了解AMS,对View 的创建、更新过程,内容太对,需要自行研究。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐