installd进程流程分析

installd服务启动 【installd进程流程分析】在systemserver中installer服务作为一个重要服务在:startBootstrapServices中启动:

// Wait for installd to finish starting up so that it has a chance to // create critical directories such as /data/user with the appropriate // permissions.We need this to complete before we initialize other services. traceBeginAndSlog("StartInstaller"); Installer installer = mSystemServiceManager.startService(Installer.class); traceEnd();

installer代码较为简洁,主要为一些创建、删除应用目录、创建、删除odex文件,创建、删除oat文件、计算app大小、迁移app等功能:
private void connect() { 获取installd守护进程的binder IBinder binder = ServiceManager.getService("installd"); if (binder != null) { try { binder.linkToDeath(new DeathRecipient() { @Override public void binderDied() { Slog.w(TAG, "installd died; reconnecting"); connect(); } }, 0); } catch (RemoteException e) { binder = null; } }if (binder != null) { 获取installd服务的代理 mInstalld = IInstalld.Stub.asInterface(binder); try { invalidateMounts(); } catch (InstallerException ignored) { } } else { Slog.w(TAG, "installd not found; trying again"); BackgroundThread.getHandler().postDelayed(() -> { connect(); }, DateUtils.SECOND_IN_MILLIS); } }

举例:清除应用数据目录:
public long createAppData(String uuid, String packageName, int userId, int flags, int appId, String seInfo, int targetSdkVersion) throws InstallerException { if (!checkBeforeRemote()) return -1; try { 调用installd守护进程完成真正工作 return mInstalld.createAppData(uuid, packageName, userId, flags, appId, seInfo, targetSdkVersion); } catch (Exception e) { throw InstallerException.from(e); } }

\frameworks\native\cmds\installd\Android.bp编译文件中:
cc_binary { name: "installd", defaults: ["installd_defaults"], srcs: ["installd.cpp"],static_libs: ["libdiskusage"],init_rc: ["installd.rc"], }

installd.cpp中主函数如下:
int main(const int argc, char *argv[]) { return android::installd::installd_main(argc, argv); }static int installd_main(const int argc ATTRIBUTE_UNUSED, char *argv[]) { int ret; int selinux_enabled = (is_selinux_enabled() > 0); setenv("ANDROID_LOG_TAGS", "*:v", 1); android::base::InitLogging(argv); SLOGI("installd firing up"); union selinux_callback cb; cb.func_log = log_callback; selinux_set_callback(SELINUX_CB_LOG, cb); 初始化android全局路径,data,app,protected app,ephemeral app,app native library,sd-card ASEC mount point,media,external app,profiles,system and vendor directories. if (!initialize_globals()) { SLOGE("Could not initialize globals; exiting.\n"); exit(1); } 初始化路径 if (initialize_directories() < 0) { SLOGE("Could not create directories; exiting.\n"); exit(1); }if (selinux_enabled && selinux_status_open(true) < 0) { SLOGE("Could not open selinux status; exiting.\n"); exit(1); } 启动InstalldNativeService if ((ret = InstalldNativeService::start()) != android::OK) { SLOGE("Unable to start InstalldNativeService: %d", ret); exit(1); }IPCThreadState::self()->joinThreadPool(); LOG(INFO) << "installd shutting down"; return 0; }

InstalldNativeService:
start中将该服务发布到了native层的servicemanager中:
status_t InstalldNativeService::start() { IPCThreadState::self()->disableBackgroundScheduling(true); 将InstalldNativeService服务发布到native层的ServiceManager中 status_t ret = BinderService::publish(); if (ret != android::OK) { return ret; } sp ps(ProcessState::self()); ps->startThreadPool(); ps->giveThreadPoolName(); return android::OK; }

查看InstalldNativeService.h定义如下:
class InstalldNativeService : public BinderService, public os::BnInstalld {

BinderService.cpp:
static status_t publish(bool allowIsolated = false) { sp sm(defaultServiceManager()); 将服务加入到ServiceManager中 return sm->addService( String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated); }

所有的install.java中定义功能最终都是通过binder调用了native层的查看InstalldNativeService来实现,如:
binder::Status InstalldNativeService::clearAppProfiles(const std::string& packageName) { ENFORCE_UID(AID_SYSTEM); CHECK_ARGUMENT_PACKAGE_NAME(packageName); std::lock_guard lock(mLock); binder::Status res = ok(); if (!clear_primary_reference_profile(packageName)) { res = error("Failed to clear reference profile for " + packageName); } if (!clear_primary_current_profiles(packageName)) { res = error("Failed to clear current profiles for " + packageName); } return res; }binder::Status InstalldNativeService::clearAppData(const std::unique_ptr& uuid, const std::string& packageName, int32_t userId, int32_t flags, int64_t ceDataInode) { ENFORCE_UID(AID_SYSTEM); CHECK_ARGUMENT_UUID(uuid); CHECK_ARGUMENT_PACKAGE_NAME(packageName); std::lock_guard lock(mLock); const char* uuid_ = uuid ? uuid->c_str() : nullptr; const char* pkgname = packageName.c_str(); binder::Status res = ok(); if (flags & FLAG_STORAGE_CE) { auto path = create_data_user_ce_package_path(uuid_, userId, pkgname, ceDataInode); if (flags & FLAG_CLEAR_CACHE_ONLY) { path = read_path_inode(path, "cache", kXattrInodeCache); } else if (flags & FLAG_CLEAR_CODE_CACHE_ONLY) { path = read_path_inode(path, "code_cache", kXattrInodeCodeCache); } if (access(path.c_str(), F_OK) == 0) { if (delete_dir_contents(path) != 0) { res = error("Failed to delete contents of " + path); } } } if (flags & FLAG_STORAGE_DE) { std::string suffix = ""; bool only_cache = false; if (flags & FLAG_CLEAR_CACHE_ONLY) { suffix = CACHE_DIR_POSTFIX; only_cache = true; } else if (flags & FLAG_CLEAR_CODE_CACHE_ONLY) { suffix = CODE_CACHE_DIR_POSTFIX; only_cache = true; }auto path = create_data_user_de_package_path(uuid_, userId, pkgname) + suffix; if (access(path.c_str(), F_OK) == 0) { if (delete_dir_contents(path) != 0) { res = error("Failed to delete contents of " + path); } } if (!only_cache) { if (!clear_primary_current_profile(packageName, userId)) { res = error("Failed to clear current profile for " + packageName); } } } return res; }

    推荐阅读