diff --git a/Android.bp b/Android.bp index 7e41f22..1240efc 100644 --- a/Android.bp +++ b/Android.bp @@ -239,7 +239,10 @@ cc_binary { cc_binary { name: "vold_prepare_subdirs", - defaults: ["vold_default_flags"], + defaults: [ + "vold_default_flags", + "libapexservice-deps", + ], srcs: [ "vold_prepare_subdirs.cpp", diff --git a/vold_prepare_subdirs.cpp b/vold_prepare_subdirs.cpp index 60e82f5..e41e994 100644 --- a/vold_prepare_subdirs.cpp +++ b/vold_prepare_subdirs.cpp @@ -30,7 +30,11 @@ #include #include +#include #include +#include +#include +#include #include #include @@ -141,24 +145,35 @@ static bool rmrf_contents(const std::string& path) { } } +static android::base::Result> get_apex_list() { + auto sm = android::defaultServiceManager(); + auto binder = sm->waitForService(android::String16("apexservice")); + if (binder == nullptr) { + return android::base::Error() << "Failed to get apexservice"; + } + auto service = android::interface_cast(binder); + std::vector list; + auto status = service->getActivePackages(&list); + if (!status.isOk()) { + return android::base::Error() << status.exceptionMessage().c_str(); + } + std::vector names; + names.reserve(list.size()); + for (const auto& apex_info : list) { + names.push_back(apex_info.moduleName); + } + return names; +} + static bool prepare_apex_subdirs(struct selabel_handle* sehandle, const std::string& path) { if (!prepare_dir(sehandle, 0711, 0, 0, path + "/apexdata")) return false; - auto dirp = std::unique_ptr(opendir("/apex"), closedir); - if (!dirp) { - PLOG(ERROR) << "Unable to open apex directory"; + auto apex_list = get_apex_list(); + if (!apex_list.ok()) { + LOG(ERROR) << apex_list.error(); return false; } - struct dirent* entry; - while ((entry = readdir(dirp.get())) != nullptr) { - if (entry->d_type != DT_DIR) continue; - - const char* name = entry->d_name; - // skip any starting with "." - if (name[0] == '.') continue; - - if (strchr(name, '@') != NULL) continue; - + for (const auto& name : *apex_list) { if (!prepare_dir(sehandle, 0771, AID_ROOT, AID_SYSTEM, path + "/apexdata/" + name)) { return false; }