1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <optional> 18 #include <set> 19 20 #include <android-base/logging.h> 21 #include <gflags/gflags.h> 22 #include <hidl-util/FqInstance.h> 23 #include <vintf/FileSystem.h> 24 #include <vintf/parse_string.h> 25 #include <vintf/parse_xml.h> 26 27 namespace android { 28 namespace vintf { 29 30 namespace { 31 32 template <typename T> 33 std::optional<T> readObject(const std::string& path, const XmlConverter<T>& converter) { 34 std::string xml; 35 std::string error; 36 status_t err = details::FileSystemImpl().fetch(path, &xml, &error); 37 if (err != OK) { 38 LOG(ERROR) << "Cannot read '" << path << "': " << error; 39 return std::nullopt; 40 } 41 auto ret = std::make_optional<T>(); 42 if (!converter(&ret.value(), xml, &error)) { 43 LOG(ERROR) << "Cannot parse '" << path << "': " << error; 44 return std::nullopt; 45 } 46 return ret; 47 } 48 49 std::optional<std::set<std::string>> getInterfaces(const CompatibilityMatrix& mat) { 50 auto set = std::make_optional<std::set<std::string>>(); 51 mat.forEachInstance([&set](const auto& matrixInstance) { 52 for (auto minorVer = matrixInstance.versionRange().minMinor; 53 minorVer >= matrixInstance.versionRange().minMinor && 54 minorVer <= matrixInstance.versionRange().maxMinor; 55 ++minorVer) { 56 Version version{matrixInstance.versionRange().majorVer, minorVer}; 57 set->insert(matrixInstance.interfaceDescription(version)); 58 } 59 return true; // continue 60 }); 61 return set; 62 } 63 64 } // namespace 65 66 } // namespace vintf 67 } // namespace android 68 69 DEFINE_string(input, "", "Input compatibility matrix file"); 70 static bool ValidateInput(const char* /* flagname */, const std::string& value) { 71 return !value.empty(); 72 } 73 DEFINE_validator(input, &ValidateInput); 74 75 DEFINE_bool(level, false, "Write level (FCM version) of the compatibility matrix."); 76 DEFINE_bool(interfaces, false, "Write strings like \"[email protected]::IFoo\"."); 77 78 int main(int argc, char** argv) { 79 using namespace android::vintf; 80 81 gflags::ParseCommandLineFlags(&argc, &argv, true /* remove flags */); 82 83 auto mat = readObject(FLAGS_input, gCompatibilityMatrixConverter); 84 if (!mat) { 85 return 1; 86 } 87 88 bool written = false; 89 90 if (FLAGS_level) { 91 if (mat->level() == Level::UNSPECIFIED) { 92 LOG(WARNING) << "FCM version is unspecified."; 93 } 94 std::cout << mat->level() << std::endl; 95 96 written = true; 97 } 98 99 if (FLAGS_interfaces) { 100 auto pvs = getInterfaces(*mat); 101 if (!pvs) { 102 return 1; 103 } 104 if (pvs->empty()) { 105 LOG(WARNING) << "No package and versions are found."; 106 } 107 108 for (const auto& pv : *pvs) { 109 std::cout << pv << std::endl; 110 } 111 112 written = true; 113 } 114 115 if (!written) { 116 LOG(ERROR) << "No output format is set."; 117 return 1; 118 } 119 120 return 0; 121 } 122