installd守护进程

本文详细介绍了Android系统中installd守护进程的启动过程,从init进程解析rc文件开始,到installd.cpp的主函数执行,再到InstalldNativeService的Binder服务发布。installd主要负责应用的安装和卸载,其初始化过程中涉及目录设置、文件系统版本检查和升级路径处理。此外,还提到了Installer.java如何连接installd服务。
摘要由CSDN通过智能技术生成

installd守护进程

android11-release
PackageManagerServie 服务负责应用的安装、卸载等相关工作,而真正干活的还是 installd。

installd 启动

Android系统启动 查看 init 进程system/core/init/init.cpp中SecondStageMain,最终在 LoadBootScripts 解析 rc 文件,其中解析 installd.rc,调用到installd.cpp主函数。InstalldNativeService::start()将该服务发布到 native 层的 ServiceManager 中。

frameworks/native/cmds/installd/installd.rc
service installd /system/bin/installd
    class main
frameworks/native/cmds/installd/installd.cpp
namespace android {
namespace installd {
//... ...
static int installd_main(const int argc ATTRIBUTE_UNUSED, char *argv[]) {
    //... ...
    if ((ret = InstalldNativeService::start()) != android::OK) {
        SLOGE("Unable to start InstalldNativeService: %d", ret);
        exit(1);
    }
    //... ...
    return 0;
}

}  // namespace installd
}  // namespace android

int main(const int argc, char *argv[]) {
    return android::installd::installd_main(argc, argv);
}

InstalldNativeService

frameworks/native/cmds/installd/InstalldNativeService.h
frameworks/native/cmds/installd/InstalldNativeService.cpp

InstalldNativeService 继承 BinderService(Binder通信,之前socket),BinderService::publish() 将"installd"服务添加到ServiceManager中
在这里插入图片描述

status_t InstalldNativeService::start() {
    IPCThreadState::self()->disableBackgroundScheduling(true);
    status_t ret = BinderService<InstalldNativeService>::publish();
    if (ret != android::OK) {
        return ret;
    }
    sp<ProcessState> ps(ProcessState::self());
    ps->startThreadPool();
    ps->giveThreadPoolName();
    sAppDataIsolationEnabled = android::base::GetBoolProperty(
            kAppDataIsolationEnabledProperty, true);
    return android::OK;
}
frameworks/native/libs/binder/include/binder/BinderService.h

在这里插入图片描述

Installer.java 连接 “installd” 服务

SystemServer 中 startBootstrapServices 启动 Installer 连接 “installd” 服务
在这里插入图片描述
在这里插入图片描述

installd_main 其他函数

回到 installd 查看其他函数

initialize_globals()

在这里插入图片描述

frameworks/native/cmds/installd/globals.h
frameworks/native/cmds/installd/globals.cpp

获取相关目录:/data//system/data/app//data/app-private//data/app-ephemeral//data/app-lib//data/app-lib//mnt/asec/data/media//mnt/expand//data/misc/profiles/data/app-staging//system/app//system/app-private//vendor/app//oem/app/

bool init_globals_from_data_and_root(const char* data, const char* root) {
    // Get the android data directory.
    android_data_dir = ensure_trailing_slash(data);

    // Get the android root directory.
    android_root_dir = ensure_trailing_slash(root);

    // Get the android app directory.
    android_app_dir = android_data_dir + APP_SUBDIR;

    // Get the android protected app directory.
    android_app_private_dir = android_data_dir + PRIVATE_APP_SUBDIR;

    // Get the android ephemeral app directory.
    android_app_ephemeral_dir = android_data_dir + EPHEMERAL_APP_SUBDIR;

    // Get the android app native library directory.
    android_app_lib_dir = android_data_dir + APP_LIB_SUBDIR;

    // Get the sd-card ASEC mount point.
    android_asec_dir = ensure_trailing_slash(getenv(ASEC_MOUNTPOINT_ENV_NAME));

    // Get the android media directory.
    android_media_dir = android_data_dir + MEDIA_SUBDIR;

    // Get the android external app directory.
    android_mnt_expand_dir = "/mnt/expand/";

    // Get the android profiles directory.
    android_profiles_dir = android_data_dir + PROFILES_SUBDIR;

    // Get the android session staging directory.
    android_staging_dir = android_data_dir + STAGING_SUBDIR;

    // Take note of the system and vendor directories.
    android_system_dirs.clear();
    android_system_dirs.push_back(android_root_dir + APP_SUBDIR);
    android_system_dirs.push_back(android_root_dir + PRIV_APP_SUBDIR);
    android_system_dirs.push_back("/vendor/app/");
    android_system_dirs.push_back("/oem/app/");

    return true;
}

initialize_directories()

  • 读取当前文件系统版本
  • 处理升级路径
static int initialize_directories() {
    int res = -1;

    // Read current filesystem layout version to handle upgrade paths
    char version_path[PATH_MAX];
    snprintf(version_path, PATH_MAX, "%smisc/installd/layout_version", android_data_dir.c_str());

    int oldVersion;
    if (fs_read_atomic_int(version_path, &oldVersion) == -1) {
        oldVersion = 0;
    }
    int version = oldVersion;

    if (version < 2) {
        SLOGD("Assuming that device has multi-user storage layout; upgrade no longer supported");
        version = 2;
    }

    if (ensure_config_user_dirs(0) == -1) {
        SLOGE("Failed to setup misc for user 0");
        goto fail;
    }

    if (version == 2) {
        SLOGD("Upgrading to /data/misc/user directories");

        char misc_dir[PATH_MAX];
        snprintf(misc_dir, PATH_MAX, "%smisc", android_data_dir.c_str());

        char keychain_added_dir[PATH_MAX];
        snprintf(keychain_added_dir, PATH_MAX, "%s/keychain/cacerts-added", misc_dir);

        char keychain_removed_dir[PATH_MAX];
        snprintf(keychain_removed_dir, PATH_MAX, "%s/keychain/cacerts-removed", misc_dir);

        DIR *dir;
        struct dirent *dirent;
        dir = opendir("/data/user");
        if (dir != nullptr) {
            while ((dirent = readdir(dir))) {
                const char *name = dirent->d_name;

                // skip "." and ".."
                if (name[0] == '.') {
                    if (name[1] == 0) continue;
                    if ((name[1] == '.') && (name[2] == 0)) continue;
                }

                uint32_t user_id = std::stoi(name);

                // /data/misc/user/<user_id>
                if (ensure_config_user_dirs(user_id) == -1) {
                    goto fail;
                }

                char misc_added_dir[PATH_MAX];
                snprintf(misc_added_dir, PATH_MAX, "%s/user/%s/cacerts-added", misc_dir, name);

                char misc_removed_dir[PATH_MAX];
                snprintf(misc_removed_dir, PATH_MAX, "%s/user/%s/cacerts-removed", misc_dir, name);

                uid_t uid = multiuser_get_uid(user_id, AID_SYSTEM);
                gid_t gid = uid;
                if (access(keychain_added_dir, F_OK) == 0) {
                    if (copy_dir_files(keychain_added_dir, misc_added_dir, uid, gid) != 0) {
                        SLOGE("Some files failed to copy");
                    }
                }
                if (access(keychain_removed_dir, F_OK) == 0) {
                    if (copy_dir_files(keychain_removed_dir, misc_removed_dir, uid, gid) != 0) {
                        SLOGE("Some files failed to copy");
                    }
                }
            }
            closedir(dir);

            if (access(keychain_added_dir, F_OK) == 0) {
                delete_dir_contents(keychain_added_dir, 1, nullptr);
            }
            if (access(keychain_removed_dir, F_OK) == 0) {
                delete_dir_contents(keychain_removed_dir, 1, nullptr);
            }
        }

        version = 3;
    }

    // Persist layout version if changed
    if (version != oldVersion) {
        if (fs_write_atomic_int(version_path, version) == -1) {
            SLOGE("Failed to save version to %s: %s", version_path, strerror(errno));
            goto fail;
        }
    }

    // Success!
    res = 0;

fail:
    return res;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xhBruce

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值