Android13-EDLA 预装使用GoogleWallpaper并打开壁纸Themed icon 功能(M56 - Monochrome App icon)

问题描述

Android13-EDLA 项目中,按照认证需求,需要验证 M56 - Monochrome App icon ,具体需求如下图,可通过 Wallpaper & Style 打开/关闭 Themed Icon功能。测试发现Wallpaper & Style中没有此项设置,无法开关 Themed Icon功能 。

请添加图片描述

原因分析:

因为项目中使用的是原生的壁纸(com.android.wallpaper),一开始怀疑是原生的壁纸没有Theme icon的功能设置,需要预置Google Wallpaper。

解决方案:

  • 预置Google Wallpaper
1. partner_gms/apps/ 目录下添加GoogleWallpaper 目录

在这里插入图片描述
GoogleWallpaper.apk 可自行官网下载,Android.mk 内容如下

###############################################################################
# GoogleWallpaper
LOCAL_PATH := $(my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := GoogleWallpaper
LOCAL_MODULE_OWNER := google
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
#LOCAL_PRIVILEGED_MODULE := true
LOCAL_CERTIFICATE := platform
LOCAL_SYSTEM_EXT_MODULE := true
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_USES_LIBRARIES := org.apache.http.legacy
LOCAL_OPTIONAL_USES_LIBRARIES := androidx.window.extensions androidx.window.sidecar
#LOCAL_OVERRIDES_PACKAGES :=
#LOCAL_REQUIRED_MODULES :=
include $(BUILD_PREBUILT)

LOCAL_SYSTEM_EXT_MODULE := true 预置到 system_ext 下,若没有设置此项,默认编译生成的apk会在system 分区。在system分区时需要额外添加权限白名单,不然会崩溃报错。

2. vendor/partner_gms/products/gms.mk 添加 DeskClockGoogle,添加后编包时才会编译DeskClockGoogle。
 PRODUCT_PACKAGES += \
   DeskClockGoogle \
3. 预置应用后还需要修改Launcher3 和Setting 的配置。
  • /device/xxx/common/products/tablet/overlay/packages/apps/Launcher3/res/values/config.xml
-- <string name="wallpaper_picker_package" translatable="false">com.android.wallpaper</string>
++ <string name="wallpaper_picker_package" translatable="false">com.google.android.apps.wallpaper</string>

将wallpaper_picker_package 配置成 com.google.android.apps.wallpaper。
Launcher3默认的配置文件位置在 packages/apps/Launcher3/res/values/config.xml ,因为存在overlay类,所以需要修改overlay类 才起作用。

  • device/xxx/common/products/tablet/overlay/packages/apps/Settings/res/values/config.xml

-- <string name="config_wallpaper_picker_package" translatable="false">com.android.wallpaper</string>
++ <string name="config_wallpaper_picker_package" translatable="false">com.google.android.apps.wallpaper</string>

将config_wallpaper_picker_package 设置为 com.google.android.apps.wallpaper,跟前面一起,需要修改overlay 类才起作用

4. 编译大包升级系统后,检查 Wallpaper & Style 界面是否是Google Wallpaper 的。

进入 Wallpaper & Style 界面 (Launcher3 或者Setting 进入), 串口执行指令: dumpsys window | grep “mCurrentFocus”
在这里插入图片描述现在是 com.google.android.apps.wallpaper 则说明替换成功。

5. 替换成GoogleWallpaper 后发现,Wallpaper & Style 中 不显示 Wallpaper colors 。如下图所示,红框部分不显示。

在这里插入图片描述

查阅官方文档发现,GoogleWallpaper 显示 Wallpaper colors 需要满足两个条件。

  1. frameworks/base/packages/SystemUI/res/values/flags.xml 中的 flag_monet 必须设置为true。
  2. 必须安装 com.google.android.apps.customization.pixel 。
    在这里插入图片描述
6.预置 com.google.android.apps.customization.pixel

预置方法跟 GoogleWallpaper 一致,参考修改即可。
在这里插入图片描述
Android.mk

###############################################################################
# GoogleWallpaper
LOCAL_PATH := $(my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := CustomizationPixel
LOCAL_MODULE_OWNER := google
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
#LOCAL_PRIVILEGED_MODULE := true
LOCAL_CERTIFICATE := platform
LOCAL_SYSTEM_EXT_MODULE := true
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
#LOCAL_USES_LIBRARIES := org.apache.http.legacy
#LOCAL_OPTIONAL_USES_LIBRARIES := androidx.window.extensions androidx.window.sidecar
#LOCAL_OVERRIDES_PACKAGES :=
#LOCAL_REQUIRED_MODULES :=
include $(BUILD_PREBUILT)

vendor/partner_gms/products/gms.mk 添加 CustomizationPixel

 PRODUCT_PACKAGES += \
   CustomizationPixel\

整编大包后验证有效。

7. Theam icon 不显示的问题。

由于预置的GoogleWallpaper无源码,且没有相关的文档,我们可以从Android版wallpaper分析,ThemePicker(com.android.wallpaper)。

1. 从Theam icon 字符入手,ThemePicker 中检索 Theam icon.

Theam icon —>themed_icon_title(string.xml )–>themed_icon_section_view.xml(layout)—>ThemedIconSectionView.java -->ThemedIconSectionController.java

2. ThemedIconSectionController.java 中定义了 isAvailable方法,按字面意思就是获取 Themed Icon 是否可用。
...
 @Override
    public boolean isAvailable(@Nullable Context context) {
        return context != null && mThemedIconOptionsProvider.isThemedIconAvailable();
    }
...
3. ThemedIconSwitchProvider.java
...
 /** Returns {@code true} if themed icon feature is available. 如果themed icon 功能可用返回true  */
    public boolean isThemedIconAvailable() {
        return mThemedIconUtils.isThemedIconAvailable();
    }
 ...
4. ThemedIconUtils.java (重点类)
 private ProviderInfo mProviderInfo;

    public ThemedIconUtils(Context context, String authorityMetaKey) {
        mContext = context;
        Intent homeIntent = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME);
        ResolveInfo resolveInfo = mContext.getPackageManager().resolveActivity(homeIntent,
                PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_META_DATA);

        if (resolveInfo != null && resolveInfo.activityInfo.metaData != null) {
            mProviderAuthority = resolveInfo.activityInfo.metaData.getString(authorityMetaKey);
        } else {
            mProviderAuthority = null;
        }
        mProviderInfo = TextUtils.isEmpty(mProviderAuthority) ? null :
                mContext.getPackageManager().resolveContentProvider(mProviderAuthority, 0);
        if (mProviderInfo != null && !TextUtils.isEmpty(mProviderInfo.readPermission)) {
            if (mContext.checkSelfPermission(mProviderInfo.readPermission)
                    != PackageManager.PERMISSION_GRANTED) {
                mProviderInfo = null;
            }
        }
    }

 ...

    /**
     * Returns if themed icon is available.
     *
     * @return true if themed icon feature is available, false otherwise.
     */
    boolean isThemedIconAvailable() {
        return mProviderInfo != null;
    }
 ...

Themed Icon 功能是否可用是 通过判断mProviderInfo是否为空,而 mProviderInfo 是在 ThemedIconUtils 构造方法中创建。在构造函数中获取满足 CATEGORY_HOME 、MATCH_DEFAULT_ONLY 、GET_META_DATA 的 的Activity组件(resolveInfo );并获取key为authorityMetaKey的值。

ThemedIconSwitchProvider.java

...
 /** Returns the {@link ThemedIconSwitchProvider} instance. */
    public static ThemedIconSwitchProvider getInstance(Context context) {
        if (sThemedIconSwitchProvider == null) {
            Context appContext = context.getApplicationContext();
            sThemedIconSwitchProvider = new ThemedIconSwitchProvider(
                    appContext.getContentResolver(),
                    new ThemedIconUtils(appContext,
                            appContext.getString(R.string.themed_icon_metadata_key)),
                    (CustomizationPreferences) InjectorProvider.getInjector()
                            .getPreferences(appContext));
        }
        return sThemedIconSwitchProvider;
    }
...

string.xml

 <!--Name of metadata in the main launcher Activity which values contains the authority
    corresponding to a ContentProvider in launcher to query or change themed icon option  -->
<string name="themed_icon_metadata_key" translatable="false">com.android.launcher3.themedicon.option</string>
6. 也就是说,Themed Icon 功能是否支持,由满足 CATEGORY_HOME 、MATCH_DEFAULT_ONLY 、GET_META_DATA 的 的Activity组件, 是否定义的了 key值为 com.android.launcher3.themedicon.option 的 metaData 标签。而满足这个要求的Activity就是Launcher3 的Home Activity 。满足要求的有两个Activity。
  • packages/apps/Launcher3/AndroidManifest.xml 的 com.android.launcher3.Launcher
  <activity
            android:name="com.android.launcher3.Launcher"
            android:launchMode="singleTask"
            android:clearTaskOnLaunch="true"
            android:stateNotNeeded="true"
            android:windowSoftInputMode="adjustPan"
            android:screenOrientation="unspecified"
            android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize"
            android:resizeableActivity="true"
            android:resumeWhilePausing="true"
            android:taskAffinity=""
            android:exported="true"
            android:enabled="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <action android:name="android.intent.action.SHOW_WORK_APPS" />
                <category android:name="android.intent.category.HOME" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.MONKEY"/>
                <category android:name="android.intent.category.LAUNCHER_APP" />
            </intent-filter>
            <meta-data
                android:name="com.android.launcher3.grid.control"
                android:value="${packageName}.grid_control" />
   ++       <meta-data
   ++          android:name="com.android.launcher3.themedicon.option"
   ++          android:value="${packageName}.grid_control" />
        </activity>
  • packages/apps/Launcher3/quickstep/AndroidManifest-launcher.xml 的 com.android.launcher3.uioverrides.QuickstepLauncher
  <activity
            android:name="com.android.launcher3.uioverrides.QuickstepLauncher"
            android:launchMode="singleTask"
            android:clearTaskOnLaunch="true"
            android:stateNotNeeded="true"
            android:windowSoftInputMode="adjustPan"
            android:screenOrientation="unspecified"
            android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize"
            android:resizeableActivity="true"
            android:resumeWhilePausing="true"
            android:taskAffinity=""
            android:exported="true"
            android:enabled="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <action android:name="android.intent.action.SHOW_WORK_APPS" />
                <category android:name="android.intent.category.HOME" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.MONKEY"/>
                <category android:name="android.intent.category.LAUNCHER_APP" />
            </intent-filter>
            <meta-data
                android:name="com.android.launcher3.grid.control"
                android:value="${packageName}.grid_control" />
++         <meta-data
++              android:name="com.android.launcher3.themedicon.option"
++              android:value="${packageName}.grid_control" />
        </activity>

编译验证发现Theme Icon 正常显示,且功能正常。

总结

-其实Theme icon不显示问题跟Google Wallpaper 无关,应该在 Launcher3 的HomeActivity 配置 meta-data 即可,
感兴趣的可以自行验证测试,如有纰漏或分析错误,欢迎指出。

参考

在 aosp 中启用 Material You design

  • 22
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值