installd守护进程

Posted xhBruce

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了installd守护进程相关的知识,希望对你有一定的参考价值。

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;
}

以上是关于installd守护进程的主要内容,如果未能解决你的问题,请参考以下文章

守护进程守护进程创建代码实现获取系统时间

20. Gradle编译其他应用代码流程(七) - 守护进程编译

守护线程与守护进程

DBUS 代码在放置在守护进程中时崩溃,但在没有守护进程代码的独立独立 main() 函数中运行良好

python基础-守护进程守护线程守护非守护并行

守护进程