缅文字体CTS问题

缅文字体CTS问题

背景

   缅甸有官方字体和民间字体,为了通过CTS必须将系统缅文默认字体设置为官方字体,但用户习惯使用民间字体。

需求

   将官方字体和民间字体都预制到固件中,通过监听系统是否处于CTS测试状态,来实现两者字体的动态切换,若没跑CTS系统缅文默认字体为民间样式,若跑CTS则系统缅文默认字体切换为官方样式。

实现方法

   在开始实现这个需求时,可以先看下这篇文章,了解下Android字体加载原理安卓字体加载原理

1. 内置缅甸民间字体

   安卓原生默认支持缅文官方字体,所以只需再内置缅文民间字体即可。

   1. 在frameworks/base/data/fonts/fonts.xml中添加字体节点

<family lang="my">
    <font weight="400" style="normal">ZawgyiOne.ttf</font>
</family>

注要将该节点添加在官方字体之前,原因在上述文章中有描述,如下

<family lang="und-Beng" variant="compact">
    <font weight="400" style="normal">NotoSansBengaliUI-Regular.ttf</font>
    <font weight="700" style="normal">NotoSansBengaliUI-Bold.ttf</font>
</family>
<family lang="my">
    <font weight="400" style="normal">ZawgyiOne.ttf</font>
</family>
<family lang="und-Mymr" variant="elegant">
    <font weight="400" style="normal">NotoSansMyanmar-Regular.ttf</font>
    <font weight="700" style="normal">NotoSansMyanmar-Bold.ttf</font>
</family>
<family  lang="und-Mymr" variant="compact">
    <font weight="400" style="normal">NotoSansMyanmarUI-Regular.ttf</font>
    <font weight="700" style="normal">NotoSansMyanmarUI-Bold.ttf</font>
</family>

    2. 在frameworks/base/data/fonts/fonts.mk的最后加入新加的字体文件

PRODUCT_PACKAGES := \
    DroidSansFallback.ttf \
    DroidSansMono.ttf \
    AndroidClock.ttf \
    DINPro-Black.otf \
    DINPro-Bold.otf \
    DINPro-Light.otf \
    DINPro-Medium.otf \
    DINPro-Regular.otf \
    ZawgyiOne.ttf

    3. 在frameworks/base/data/fonts/Android.mk的font_src_files最后加入新加的字体文件

font_src_files := \
    AndroidClock.ttf \
    ZawgyiOne.ttf

    4. 将下载的字体放入frameworks/base/data/fonts下

   通过以上步骤就可以内置缅文民间字体。

2. 配置更改

   为了让缅文官方字体和民间字体能够进行切换,需准备好官方字体的配置文件和民间字体的配置文件,做如下工作。

   1. 准备字体配置文件

   Android默认的字体配置文件为fonts.xml,里面配置了各个字体的信息,在上面添加民间字体时,我们在缅文官方字体节点前添加了民间字体的描述节点。

   复制一份fonts.xml,命名为fonts_cts.xml(名字可以自定义),并将民间字体节点移动到官方字体节点底下,如下。

<family lang="und-Beng" variant="compact">
    <font weight="400" style="normal">NotoSansBengaliUI-Regular.ttf</font>
    <font weight="700" style="normal">NotoSansBengaliUI-Bold.ttf</font>
</family>
<family lang="und-Mymr" variant="elegant">
    <font weight="400" style="normal">NotoSansMyanmar-Regular.ttf</font>
    <font weight="700" style="normal">NotoSansMyanmar-Bold.ttf</font>
</family>
<family  lang="und-Mymr" variant="compact">
    <font weight="400" style="normal">NotoSansMyanmarUI-Regular.ttf</font>
    <font weight="700" style="normal">NotoSansMyanmarUI-Bold.ttf</font>
</family>
<family lang="my">
    <font weight="400" style="normal">ZawgyiOne.ttf</font>
</family>

   2. 在frameworks/base/data/fonts/fonts.mk中添加配置文件代码

PRODUCT_COPY_FILES := \
    frameworks/base/data/fonts/fonts.xml:$(TARGET_COPY_OUT_SYSTEM)/etc/fonts.xml \
    frameworks/base/data/fonts/fonts_cts.xml:$(TARGET_COPY_OUT_SYSTEM)/etc/fonts_cts.xml \

3. 添加CTS监听器

   为了动态的切换字体的样式,需要监听系统的状态,判断系统是否处于CTS测试过程,然后根据系统的当前状态设置全局属性值。

   这里可以在系统的全局属性中添加属性,并设置初始值。

SHELL.whether cts is running
PRODUCT_PROPERTY_OVERRIDES += \
  persist.sys.cts_Myanmar_state=false //false表示默认民间字体,true表示默认官方字体

   然后可以通过编写CTS状态监听广播,规定一旦有CTS开始跑时,就设置该属性为true,并不重置。


private BroadcastReceiver mPackageReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        final String action = intent.getAction();
        final String packageName = intent.getData().getSchemeSpecificPart();
        final int uid = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_OWNER);
        final int tmpUidCount = sUidpackage.get(uid);
        if (DEBUG) Slog.d(TAG, "onReceive packageName = " + packageName + ",uid=" + uid);
        if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
            if (isCtsPackages(packageName) && isCtsSignatures(getSignatures(packageName, uid))) {
                sUidpackage.put(uid, tmpUidCount + 1);
                if (!mIsCtsRunning) {
                    SystemProperties.set("persist.sys.cts_Myanmar_state", "true");
                    mIsCtsRunning = true;
                }
            }
        } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
            if (isCtsPackages(packageName)) {
                if (tmpUidCount == 1) {
                    sUidpackage.delete(uid);
                } else if (tmpUidCount > 1) {
                    sUidpackage.put(uid, tmpUidCount - 1);
                }
                if (mIsCtsRunning && sUidpackage.size() == 0) {
                    mIsCtsRunning = false;
                }
            }
        }
    }
};

4. 修改字体加载逻辑

   修改frameworks/base/graphics/java/android/graphics/Typeface.java文件下的代码,其中最主要的是init()函数。

static final String FONTS_CONFIG = "fonts.xml";
static final String FONTS_CTS_CONFIG = "fonts_cts.xml";

private static void init() {
    // Load font config and initialize Minikin state
    File systemFontConfigLocation = getSystemFontConfigLocation();
    boolean isCTSRunning = SystemProperties.getBoolean("persist.sys.cts_Myanmar_state", false);
    File configFilename;
    if (isCTSRunning){
        configFilename = new File(systemFontConfigLocation, FONTS_CTS_CONFIG);
    }else {
        configFilename = new File(systemFontConfigLocation, FONTS_CONFIG);
    }
    // @}

    ...

}

   从代码上可以看出,当字体加载时,会去判断系统是否处于CTS状态,如果处于CTS状态,就会加载官方字体的逻辑(fonts_cts.xml),如果不处于CTS状态,就会加载民间字体的逻辑(fonts.xml)。

注,Android在说明init()函数时,备注该函数只会在系统启动时调用,也就是如果系统不重启,该函数是不会重新调用的。因此当系统检测到CTS测试,并值全局属性为CTS状态后,需要让系统重启,字体的加载逻辑才会走缅文的官方字体逻辑。而经过我们多轮测试验证,CTS过程中,在缅文用例测试之前,会有整机重启的时机,因此这套方案是可行的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值