android13(T) 通过烧写客制分区(customer)实现替换默认壁纸

为了减少系统打包次数,主流厂家做法都会新增一个分区,用于客制一些常规需求。

通过烧写工具或者 fastboot 指令单独烧写替换资源及配置,这里提供一个直接将文件夹打包成 img 脚本

执行此脚本需要 root 权限

#!/bin/bash -x
IMG_SIZE=409600
rm customer.img
dd if=/dev/zero of=customer.img bs=1024 count=$IMG_SIZE
mkfs.ext4 -F customer.img
rm -rf t
mkdir t
sudo mount customer.img t
sudo cp customer/* t/ -r
sudo chmod 666 -R ./t
sudo chmod 777 -R ./t/bin
sudo find ./t -type d | while read line; do
  sudo chmod 777 $line
done
sudo umount t
rm -rf t
e2fsck -f customer.img
resize2fs -M customer.img

接下来进入正题

建议先看下壁纸服务启动流程,可以参考如下资料

设置壁纸流程分析
Android 12系统源码_系统壁纸(一)WallpaperManagerService的启动流程
Android壁纸服务WallpaperManagerService

以下是测试的几种方式

方式一、在 java 层修改

通过 WallpaperManager api 就可以成功修改默认壁纸,同时需要增加 权限

为了便利和时效性考虑,在 SystemUI 中增加核心代码进行尝试

	try {
    
    
		java.io.FileInputStream inputStream = new java.io.FileInputStream(new java.io.File("/customer/wallpaper/default.png"));
		android.app.WallpaperManager.getInstance(mContext).setStream(inputStream);
		Log.i("PowerUI","set oemwallpaper success");
	} catch (Exception e) {
    
    
		e.printStackTrace();
	}

验证结果,在收到开机广播后调用上面的 java 代码进行设置,SystemUI 进程会挂掉重启然后壁纸可成功设置

原因应该是这时候壁纸相关的服务还没完全启动,这种方式不推荐

方式二、在 sh 中修改

用户手动设置的壁纸,其实原理就是在 /data/system/users/0/wallpaper 下

所以通过 cp 指令将壁纸文件直接复制到固定目录即可,wallpaper.sh 脚本如下

因为 data/system 目录需要 root 权限才可范围,所以选择在 init.rc 中加载 wallpaper.sh 自动执行

如下脚本的大概意思,先判断壁纸文件夹是否存在,存在则继续创建用户设置壁纸文件夹

#!/system/bin/sh

PICTURES_DIR=/data/media/0/Pictures
WALLPAPER_OEM_DIR=/customer/wallpaper
DEFAULT_WALLPAPER_OEM=$WALLPAPER_OEM_DIR/default.png
SYS_DEFAULT_WALLPAPER=/data/system/users/0/wallpaper

if [ ! -e $WALLPAPER_OEM_DIR ]
then
  exit 0
fi

function mkdirIfNotExist() {
    
    
  local path=$1
  if [ ! -e $path ]
  then
    mkdirIfNotExist $(dirname $path)
    mkdir $path
	chmod 777 $path
  fi
}

mkdirIfNotExist $PICTURES_DIR
mkdirIfNotExist $(dirname $SYS_DEFAULT_WALLPAPER)

for i in `find $WALLPAPER_OEM_DIR -name "*.png"`
do
  if [ ! -e $PICTURES_DIR/$(basename $i) ]
  then
    cp $i $PICTURES_DIR
  fi
done

if [ -e $DEFAULT_WALLPAPER_OEM ]
then
  if [ ! -e $SYS_DEFAULT_WALLPAPER ]
  then
    cp $DEFAULT_WALLPAPER_OEM $SYS_DEFAULT_WALLPAPER
	chmod 666 $SYS_DEFAULT_WALLPAPER
  fi
fi

验证结果,烧写 customer.img 开机启动时执行脚本,这时创建完壁纸信息,但默认壁纸加载流程已经结束

需要再重启一次设备才能看到客制默认壁纸,这种方式不推荐

方式三、修改 prop 值配置客制壁纸路径

String PROP_WALLPAPER = “ro.config.wallpaper”;

将 ro.config.wallpaper=/customer/wallpaper/default.png 配置一下即可

要修改 ro 开头 prop 属性值需要去除 property_service.cpp 中限制

默认壁纸加载顺序

1、用户自己设置的壁纸,也就是 /data/system/users/0/wallpaper

2、ro.config.wallpaper 对应壁纸是否存在

3、framework 目录下默认 default_wallpaper

frameworks\base\core\java\android\app\WallpaperManager.java

 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    public static InputStream openDefaultWallpaper(Context context, @SetWallpaperFlags int which) {
    
    
        final String whichProp;
        final int defaultResId;
        if (which == FLAG_LOCK) {
    
    
            /* Factory-default lock wallpapers are not yet supported
            whichProp = PROP_LOCK_WALLPAPER;
            defaultResId = com.android.internal.R.drawable.default_lock_wallpaper;
            */
            return null;
        } else {
    
    
            whichProp = PROP_WALLPAPER;
            defaultResId = com.android.internal.R.drawable.default_wallpaper;
        }
        final String path = SystemProperties.get(whichProp);
        final InputStream wallpaperInputStream = getWallpaperInputStream(path);
        if (wallpaperInputStream != null) {
    
    
            return wallpaperInputStream;
        }
        final String cmfPath = getCmfWallpaperPath();
        final InputStream cmfWallpaperInputStream = getWallpaperInputStream(cmfPath);
        if (cmfWallpaperInputStream != null) {
    
    
            return cmfWallpaperInputStream;
        }
        try {
    
    
            return context.getResources().openRawResource(defaultResId);
        } catch (NotFoundException e) {
    
    
            // no default defined for this device; this is not a failure
        }
        return null;
    }

验证结果,当 ro.config.wallpaper 对应壁纸存在时,开机显示客制壁纸,推荐此种灵活方式

猜你喜欢

转载自blog.csdn.net/u012932409/article/details/130991495