summaryrefslogtreecommitdiff
path: root/libs/libapexutil/apexutil.cpp
diff options
context:
space:
mode:
authorJooyung Han <jooyung@google.com>2020-01-07 16:41:55 +0900
committerJooyung Han <jooyung@google.com>2020-01-07 16:54:54 +0900
commit221eadd5fc87b2aa994566c44f9deff1445425c2 (patch)
treea341df845d190cbee6fae92d26b345bdd0c31d05 /libs/libapexutil/apexutil.cpp
parent4a30691e89d057be9b65fcf3b5a0a46bf19250ef (diff)
Add libapexutil static library
This provides a helper function to get active APEX packages by scanning /apex directory. Even though this feature is already provided by ApexService::getActivePackages(), but some processes (e.g. linkerconfig) which can't rely on IPC may use this library. Bug: 144659031 Test: atest --host libapexutil_tests Change-Id: I92c69637e0599c1db05a323aaabb4c30ca135f8f
Diffstat (limited to 'libs/libapexutil/apexutil.cpp')
-rw-r--r--libs/libapexutil/apexutil.cpp82
1 files changed, 82 insertions, 0 deletions
diff --git a/libs/libapexutil/apexutil.cpp b/libs/libapexutil/apexutil.cpp
new file mode 100644
index 0000000..948bd86
--- /dev/null
+++ b/libs/libapexutil/apexutil.cpp
@@ -0,0 +1,82 @@
+/*
+ * 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 <dirent.h>
+
+#include <memory>
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/result.h>
+#include <apex_manifest.pb.h>
+
+using ::android::base::Error;
+using ::android::base::ReadFileToString;
+using ::android::base::Result;
+using ::apex::proto::ApexManifest;
+
+namespace {
+
+Result<ApexManifest> 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<std::string, ApexManifest>
+GetActivePackages(const std::string &apex_root) {
+ std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(apex_root.c_str()),
+ closedir);
+ if (!dir) {
+ return {};
+ }
+
+ std::map<std::string, ApexManifest> 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;
+ std::string apex_path = apex_root + "/" + entry->d_name;
+ auto manifest = ParseApexManifest(apex_path + "/apex_manifest.pb");
+ if (manifest) {
+ apexes.emplace(std::move(apex_path), std::move(*manifest));
+ } else {
+ LOG(WARNING) << manifest.error();
+ }
+ }
+ return apexes;
+}
+
+} // namespace apex
+} // namespace android \ No newline at end of file