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