/* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "libapexutil" #include "apexutil.h" #include #include #include #include #include #include #include using ::android::base::Error; using ::android::base::ReadFileToString; using ::android::base::Result; using ::apex::proto::ApexManifest; namespace { Result ParseApexManifest(const std::string &manifest_path) { std::string content; if (!ReadFileToString(manifest_path, &content)) { return Error() << "Failed to read manifest file: " << manifest_path; } ApexManifest manifest; if (!manifest.ParseFromString(content)) { return Error() << "Can't parse APEX manifest: " << manifest_path; } return manifest; } } // namespace namespace android { namespace apex { std::map GetActivePackages(const std::string &apex_root) { std::unique_ptr dir(opendir(apex_root.c_str()), closedir); if (!dir) { return {}; } std::map apexes; dirent *entry; while ((entry = readdir(dir.get())) != nullptr) { if (entry->d_name[0] == '.') continue; if (entry->d_type != DT_DIR) continue; if (strchr(entry->d_name, '@') != nullptr) continue; if (strcmp(entry->d_name, "sharedlibs") == 0) continue; std::string apex_path = apex_root + "/" + entry->d_name; auto manifest = ParseApexManifest(apex_path + "/apex_manifest.pb"); if (manifest.ok()) { apexes.emplace(std::move(apex_path), std::move(*manifest)); } else { LOG(WARNING) << manifest.error(); } } return apexes; } } // namespace apex } // namespace android