恢复出厂如何保留自定义属性值

@恢复出厂如何保留自定义属性值

最近有个指令切换型号功能,每次恢复出厂设置之后必在重启一次才可以生效

【方案】
bwrite是可执行文件(out\target\product\xxxx\system\xbin\bwrite),bwrite写persist.sys.xxx=yyy键值对到文件/cache/recovery/last_bird.prop和data/last_bird.prop,开机时将/cache/recovery/last_bird.prop载入内存,应用可通过 SystemProperties.getxxx 获取其中键值对;对于无法使用system property的地方,直接读取文件data/last_bird.prop 获得键值。(/cache/recovery/last_xxx文件恢复出厂设置不会被删除,但是一般应用没有权限读这个文件,所有有个data/last_bird.prop的备份)

开机load last_bird.prop:
system\core\init\property_service.cpp
load_properties_from_file("/cache/recovery/last_bird.prop", NULL); ----------这句话的作用是可以将cache/recovery/last_bird.prop中所有内容当作类似build.prop里当作属性值来获取

修改两个last_bird.prop文件权限

device/sprd/scx35l/sp9832a_5m_volte_bird/rootdir/root/init.sp9832a_5m_volte_bird.rc 添加

on early-boot

chmod 0644 /cache/recovery/last_bird.prop
chmod 0644 /data/last_bird.prop

最重要的是bwrite这个可执行文件----详细如下附件,通过这个创建,修改/cache/recovery/last_bird.prop和data/last_bird.prop

packages/apps/Settings/bwrite/bwrite.c

else if(argv[i][0] == ‘m’) {
memset(value, 0, sizeof(value));

for(k = 0, pspace = argv[i]; k < strlen(argv[i]); k++, pspace++) {
if(*pspace == ‘@’) *pspace = ’ ';
}
// sprintf(value, “ro.bird.model=%s\n persist.sys.bird.model=%s\n”, pvalue);
sprintf(value, “persist.sys.bird.model=%s\n”, pvalue);
strcat(writeContent, value);
}

…/data/upload/1/201905/0916573204631dl6.c

在device/sprd/scx35l/common/rootdir/root/init.sc8830_ieb.rc注册bwrite服务

service bwrite /system/xbin/bwrite
user root
group root
oneshot

声明bwrite权限:

device/sprd/scx35l/common/sepolicy/bwrite.te

type bwrite, domain;
type bwrite_exec, exec_type, file_type;

STOPSHIP: Permissive is not allowed. CTS violation!

init_daemon_domain(bwrite)
net_domain(bwrite)
allow bwrite system_data_file:dir rw_dir_perms;
allow bwrite system_data_file:dir create_dir_perms;
allow bwrite system_data_file:file { write create open ioctl };
allow bwrite system_data_file:file rw_file_perms;
allow bwrite system_data_file:file create_file_perms;
allow bwrite last_bird_prop:file { read write create open getattr setattr };
allow bwrite self:capability { fsetid dac_override };
allow bwrite shell_exec:file {execute execute_no_trans read open };
allow bwrite system_file:file execute_no_trans;
allow bwrite cache_file:dir { write create add_name };
allow bwrite cache_file:file { write create open setattr };

绑定执行档类型:

device/sprd/scx35l/common/sepolicy/file_contexts

/system/xbin/bwrite u:object_r:bwrite_exec:s0
/cache/recovery/last_bird.prop u:object_r:cache_recovery_file:s0

声明last_bird_prop(bwrite.te里面用了)

device/sprd/scx35l/common/sepolicy/file.te

type last_bird_prop, file_type, data_file_type;

在recovery中给last_bird_prop赋予权限:

device/sprd/scx35l/common/sepolicy/recovery.te

allow recovery last_bird_prop:file {open read write getattr};

从neverallow中去掉bwrite:
external/sepolicy/domain.te

neverallow {
domain

-bwrite
} system_data_file:file no_w_file_perms;

在java 中是如何调用bwrite,以型号为例

在packages/apps/Settings/bird/src/com/bird/settings/BirdModelActivity.java

切换之后发送广播

Intent intent = new Intent(“bird.intent.receiver.model_new”);
intent.putExtra(“model”, model);
mContext.sendBroadcast(intent);
在frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java 中处理广播做如下操作

String command = “bwrite:bird_write_prop” + " " + BIRD_PROP_PATH + " " + param;
Log.i(TAG, “command:” + command);
SystemProperties.set(“ctl.start”, command); ---------启动bwrite服务修改persist.sys.bird.model的值

最终设置下型号和第三方获取型号是从frameworks/base/core/java/android/os/Build.java中获取

public static final String realMODEL = getString(“ro.product.model”);
public static String MODEL = SystemProperties.get(“persist.sys.bird.model”, realMODEL); -----------获取修改后的值

关键点:

1.是需要一个将属性值保存在恢复出厂不被删除的文件,我们这里是cache/recovery/last_bird.prop

2.可以get到属性值,如过get不到可读取data/last_bird.prop文件(这就有可能牵扯到恢复出厂刚开机还没来得及生成此文件,Bug就是由此引起,还有一种方按,写个shell脚本在init.rc中就加载拷贝,可参考网址:https://blog.csdn.net/yang_gaolei/article/details/78864429 ------init.rc 执行shell脚本 ---- 制作一初始化配置文件)

注意:调试过程中很容易遇到avc,等selinux权限相关

比如这行warning log:
avc: denied { write } for name=“last_bird.prop” dev=“mmcblk0p23” ino=23 scontext=u:r:bwrite:s0 tcontext=u:object_r:system_data_file:s0 tclass=file permissive=1
那么我们就得出最后的规则是在bwrite.te中添加:
allow bwrite system_data_file:file { write };

在手机关机或者开启过程中可短暂获取log的命令:adb shell dmesg >1.txt 查询内核缓冲区信息 -------可以看到一些init 的信息

指令切换型号–相机拍照详情型号未改变

原因读取的是ro.product.model 的值,目前两种方案:

1.找到bdA/qiku/vendor/sprd/modules/libcamera/oem2v0/src/cmr_setting.c

这个路径下的文件,修改下

//bird modify by zss

property_get(“persist.sys.bird.model”, property, EXIF_DEF_MODEL);
//property_get(“ro.product.model”, property, EXIF_DEF_MODEL);

  1. 比较彻底的一种,所有获取ro.product.model的值都转换成获取persist.sys.bird.model
    bdA/qiku/system/core/libcutils/properties.c

int property_get(const char *key, char *value, const char *default_value)
{
int len;
// bird modify by zss begin
ALOGV(“old key=%s\n”,key );
char oldmodel[]= “ro.product.model”;
char newmodel[] = “persist.sys.bird.model”;
if(0 == strncmp(oldmodel,key,strlen(oldmodel))){
key = newmodel;
}
ALOGV(“new key=%s\n”,key );
//property_get(“ro.product.model”, property, EXIF_DEF_MODEL);
// bird modify by zss end

len = __system_property_get(key, value);
if(len > 0) {
    return len;
}
if(default_value) {
    len = strlen(default_value);
    if (len >= PROPERTY_VALUE_MAX) {
        len = PROPERTY_VALUE_MAX - 1;
    }
    memcpy(value, default_value, len);
    value[len] = '\0';
}
return len;

}

你可能感兴趣的:(Android)