android Init进程新特性(截止android 8)

这一节主要补充,在现在android 8上和之前比的新特性(仅仅是自己新发现,不清楚哪个版本加入或者是以前自己没发现)。

1. init.rc中加入了对vendor下面手机厂商自己的rc文件,这样不用重新编译bootimage,只要push自己rc文件到vendor/etc/init/hw。而且自己的rc文件完全独立原生的rc文件

import /vendor/etc/init/hw/init.${ro.hardware}.rc

2. import各个进程下面的rc文件,system/etc/init下面的各个进程的rc文件

这些rc文件是在什么时候加入到init进程进行解析的,是在处理mount_all的时候调用了import_late的时候将/system/etc/init下面的rc文件加入到init进程进行解析了。

static void import_late(const std::vector<std::string>& args, size_t start_index, size_t end_index) {
    Parser& parser = Parser::GetInstance();
    if (end_index <= start_index) {
        // Fallbacks for partitions on which early mount isn't enabled.
        if (!parser.is_system_etc_init_loaded()) {
            parser.ParseConfig("/system/etc/init");
            parser.set_is_system_etc_init_loaded(true);
        }
        if (!parser.is_vendor_etc_init_loaded()) {
            parser.ParseConfig("/vendor/etc/init");
            parser.set_is_vendor_etc_init_loaded(true);
        }
        if (!parser.is_odm_etc_init_loaded()) {
            parser.ParseConfig("/odm/etc/init");
            parser.set_is_odm_etc_init_loaded(true);
        }
    } else {
        for (size_t i = start_index; i < end_index; ++i) {
            parser.ParseConfig(args[i]);
        }
    }

顺便提下,mount_all还会调用queue_fs_event函数,这里面会根据是否加密来push不同的trigger,我们正常的开机流程就是在nonencrypted这个trigger中,这里面就会class_start main等。

static int queue_fs_event(int code) {
    int ret = code;

    if (code == FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION) {
        ActionManager::GetInstance().QueueEventTrigger("encrypt");
    } else if (code == FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED) {
        property_set("ro.crypto.state", "encrypted");
        property_set("ro.crypto.type", "block");
        ActionManager::GetInstance().QueueEventTrigger("defaultcrypto");
    } else if (code == FS_MGR_MNTALL_DEV_NOT_ENCRYPTED) {
        property_set("ro.crypto.state", "unencrypted");
        ActionManager::GetInstance().QueueEventTrigger("nonencrypted");
    } else if (code == FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) {
        property_set("ro.crypto.state", "unsupported");
        ActionManager::GetInstance().QueueEventTrigger("nonencrypted");
    } else if (code == FS_MGR_MNTALL_DEV_NEEDS_RECOVERY) {
        /* Setup a wipe via recovery, and reboot into recovery */
        PLOG(ERROR) << "fs_mgr_mount_all suggested recovery, so wiping data via recovery.";
        const std::vector<std::string> options = {"--wipe_data", "--reason=fs_mgr_mount_all" };
        reboot_into_recovery(options);
        return 0;
        /* If reboot worked, there is no return. */
    } else if (code == FS_MGR_MNTALL_DEV_FILE_ENCRYPTED) {
        if (e4crypt_install_keyring()) {
            return -1;
        }
        property_set("ro.crypto.state", "encrypted");
        property_set("ro.crypto.type", "file");

        // Although encrypted, we have device key, so we do not need to
        // do anything different from the nonencrypted case.
        ActionManager::GetInstance().QueueEventTrigger("nonencrypted");
    } else if (code == FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED) {
        if (e4crypt_install_keyring()) {
            return -1;
        }
        property_set("ro.crypto.state", "encrypted");
        property_set("ro.crypto.type", "file");

        // defaultcrypto detects file/block encryption. init flow is same for each.
        ActionManager::GetInstance().QueueEventTrigger("defaultcrypto");
    } else if (code == FS_MGR_MNTALL_DEV_NEEDS_METADATA_ENCRYPTION) {
        if (e4crypt_install_keyring()) {
            return -1;
        }
        property_set("ro.crypto.type", "file");

        // encrypt detects file/block encryption. init flow is same for each.
        ActionManager::GetInstance().QueueEventTrigger("encrypt");
    } else if (code > 0) {
        PLOG(ERROR) << "fs_mgr_mount_all returned unexpected error " << code;
    }
    /* else ... < 0: error */

    return ret;
}

3. 各个进程的状态,init启动的进程会设置进程的状态,这个可能一直都有(可能自己没发现)。init启动或者停止某个service最后都会NotifyStateChange函数来改变状态,这个函数会设置init.svc.name(name代表这个service的名字)这个属性当前进程的状态,当是running还会设置ro.boottime.name(name代表这个service的名字)的时间,当然是ro属性,所以也就是第一次启动进程的时间。

void Service::NotifyStateChange(const std::string& new_state) const {
    if ((flags_ & SVC_TEMPORARY) != 0) {
        // Services created by 'exec' are temporary and don't have properties tracking their state.
        return;
    }

    std::string prop_name = "init.svc." + name_;
    property_set(prop_name, new_state);

    if (new_state == "running") {
        uint64_t start_ns = time_started_.time_since_epoch().count();
        property_set("ro.boottime." + name_, std::to_string(start_ns));
    }
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值