/* * Copyright 2023 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. */ #include "widevine_apex_info.h" #include #include #include "apex_manifest_minimal.pb.h" using android::base::ConsumePrefix; using android::base::ErrnoError; using android::base::Error; using android::base::GetExecutablePath; using android::base::ReadFileToString; using android::base::Result; using apex::proto::ApexManifest; namespace widevine::apex { namespace { Result GetApexNameFromPath(const std::string& path) { std::string_view sv{path}; if (!ConsumePrefix(&sv, "/apex/")) { return Error() << "Not found an apex name: " << path; } return std::string{sv.substr(0, sv.find('/'))}; } Result ParseApexManifest(const std::string& manifest_path) { std::string content; if (!ReadFileToString(manifest_path, &content)) { return ErrnoError() << "Failed to read manifest file: " << manifest_path; } ApexManifest manifest; if (!manifest.ParseFromString(content)) { return Error() << "Can't parse APEX manifest: " << manifest_path; } return manifest; } } Result GetApexInfo() { auto exe_path = GetExecutablePath(); auto apex_name = GetApexNameFromPath(exe_path); if (!apex_name.ok()) { return apex_name.error(); } auto manifest_path = fmt::format("/apex/{}/apex_manifest.pb", *apex_name); auto apex_manifest = ParseApexManifest(manifest_path); if (!apex_manifest.ok()) { return apex_manifest.error(); } return ApexInfo { apex_manifest->name(), apex_manifest->version(), }; } } // namespace widevine::apex