背景:
上一篇文章已经带大家学习了aosp15的编译和运行,在体验aosp15的相关功能时候发现了自由窗口的一个问题:
发现自由窗口根本没有入口进行打开,这里只可以看到分屏相关。
正常要开放自由窗口需要把相关的settings值放开
adb shell settings put global enable_freeform_support 1
但是这里已经设置为了1,打开多任务可以看到显示依然是只有分屏,没有自由窗口。
问题源码分析:
在packages/apps/Launcher3/quickstep/src/com/android/quickstep/TaskShortcutFactory.java中有控制这个自由窗口的选项,具体代码如下:
TaskShortcutFactory FREE_FORM = new TaskShortcutFactory() {
@Override
public List<SystemShortcut> getShortcuts(RecentsViewContainer container,
TaskContainer taskContainer) {
final Task task = taskContainer.getTask();
if (!task.isDockable) {
android.util.Log.i("lsm666","!task.isDockable");
return null;
}
if (!isAvailable(container)) {
android.util.Log.i("lsm666","!isAvailable(container)");
return null;
}
return Collections.singletonList(new FreeformSystemShortcut(
R.drawable.ic_caption_desktop_button_foreground,
R.string.recent_task_option_freeform, container, taskContainer,
LAUNCHER_SYSTEM_SHORTCUT_FREE_FORM_TAP));
}
这里最后只要可以通过getShortcuts走到底部的Collections.singletonList那就说明可以显示出来,所以这里显示不出来肯定是没有走到底部这个Collections.singletonList,说明是在前面的两个if返回了null,具体哪里返回了?那得加打印进行追踪,打印后发现是如下代码不满足
if (!isAvailable(container)) {
android.util.Log.i("lsm666","!isAvailable(container)");
return null;
}
这里详细看看isAvailable方法:
private boolean isAvailable(RecentsViewContainer container) {
return Settings.Global.getInt(
container.asContext().getContentResolver(),
Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0
&& !enableDesktopWindowingMode();
}
可以看到这里条件只有2个:
1.settings值是否为1,就是上面说的enable_freeform_support这个
2.enableDesktopWindowingMode方法返回为false,即要求不允许桌面模式才可以开放自由窗口
这里明显就第2个条件不满足,那么来看看这里的enableDesktopWindowingMode方法的具体判断是啥。
遗憾发现enableDesktopWindowingMode根本没办法跳转,找不到源码
这里可以临时修改方案:
屏蔽掉这个判断,但还是要考虑分析看看有没有可以设置prop方式能成功就最好。
分析看看他的import
发现是在com.android.window这个包下,那么继续寻找一下看看这个路径是啥情况?
可以发现这里flags目录,居然没有一个java文件,全是一些aconfig文件,找到了一个相关的配置
猜测这里很可能是编译期间把aconfig转化成了java。
分析aconfig对应的java代码在哪?
这里因为看最后代码中还是使用的enableDesktopWindowingMode,即一个java方法,所以这里需要对这块进行寻找到它的java代码,一般这个需要去out生成代码目录查看,这里直接去grep看看情况如下:
在out/soong/.intermediates/frameworks目录进行grep “enableDesktopWindowingMode” ./ -rn
可以看到没有搜索到任何的java代码有这个enableDesktopWindowingMode方法。
但是看到末尾一个有相关的jar包com.android.window.flags.window-aconfig-java.jar里面有匹配到enableDesktopWindowingMode。
find -name com.android.window.flags.window-aconfig-java.jar
./base/com.android.window.flags.window-aconfig-java/android_common/javac/com.android.window.flags.window-aconfig-java.jar
./base/com.android.window.flags.window-aconfig-java/android_common/turbine-combined/com.android.window.flags.window-aconfig-java.jar
./base/com.android.window.flags.window-aconfig-java/android_common/turbine/com.android.window.flags.window-aconfig-java.jar
这里寻找到了3个一样名字jar,这里注意一般要使用体积大的可以反编译出源码具体的实现,其他小的反编译没有实现。
这里选着第一个路径如下:
out/soong/.intermediates/frameworks/base/com.android.window.flags.window-aconfig-java/android_common/javac/com.android.window.flags.window-aconfig-java.jar
反编译jar查看源码
先看看Flags这个类
这里来看看FEATURE_FLAGS的具体实现:
哈哈,到这里大家是不是终于看到熟悉的Properties了,你是不是和马哥一样认为这里其实就是普通的prop,如果这样认为其实就是完全错误的哈,具体这里Properties是啥,这个就有需要了解新版本上使用的类似config机制。这个部分就太长了,后需要在考虑给vip学员们专门开一个文章吧。
更多framework请关注“千里马学框架”