AssembleVintf.cpp revision 947570619d88bc6b9ca87f567943987f70a3905a
14d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong/* 24d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong * Copyright (C) 2017 The Android Open Source Project 34d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong * 44d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong * Licensed under the Apache License, Version 2.0 (the "License"); 54d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong * you may not use this file except in compliance with the License. 64d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong * You may obtain a copy of the License at 74d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong * 84d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong * http://www.apache.org/licenses/LICENSE-2.0 94d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong * 104d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong * Unless required by applicable law or agreed to in writing, software 114d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong * distributed under the License is distributed on an "AS IS" BASIS, 124d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong * See the License for the specific language governing permissions and 144d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong * limitations under the License. 154d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong */ 164d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 174d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong#include <stdlib.h> 184d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong#include <unistd.h> 194d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 204d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong#include <fstream> 214d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong#include <iostream> 224d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong#include <sstream> 234d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong#include <string> 248302cea08dea5238cbc4d2637ff90319480971aeYifan Hong#include <unordered_map> 254d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 269a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong#include <android-base/file.h> 27dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong#include <android-base/parseint.h> 28b83e56bbf1b2aba92f69f63d1e434be512193b5bYifan Hong#include <android-base/strings.h> 299a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong 308302cea08dea5238cbc4d2637ff90319480971aeYifan Hong#include <vintf/AssembleVintf.h> 3179efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong#include <vintf/KernelConfigParser.h> 324d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong#include <vintf/parse_string.h> 334d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong#include <vintf/parse_xml.h> 348302cea08dea5238cbc4d2637ff90319480971aeYifan Hong#include "utils.h" 354d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 3679efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong#define BUFFER_SIZE sysconf(_SC_PAGESIZE) 3779efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong 384d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hongnamespace android { 394d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hongnamespace vintf { 404d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 419a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hongstatic const std::string gConfigPrefix = "android-base-"; 429a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hongstatic const std::string gConfigSuffix = ".cfg"; 439a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hongstatic const std::string gBaseConfig = "android-base.cfg"; 449a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong 45aa219f5a7792ebff4db38c60f8f08f9ab44b2586Yifan Hong// An input stream with a name. 46aa219f5a7792ebff4db38c60f8f08f9ab44b2586Yifan Hong// The input stream may be an actual file, or a stringstream for testing. 47aa219f5a7792ebff4db38c60f8f08f9ab44b2586Yifan Hong// It takes ownership on the istream. 48aa219f5a7792ebff4db38c60f8f08f9ab44b2586Yifan Hongclass NamedIstream { 49aa219f5a7792ebff4db38c60f8f08f9ab44b2586Yifan Hong public: 50aa219f5a7792ebff4db38c60f8f08f9ab44b2586Yifan Hong NamedIstream(const std::string& name, std::unique_ptr<std::istream>&& stream) 51aa219f5a7792ebff4db38c60f8f08f9ab44b2586Yifan Hong : mName(name), mStream(std::move(stream)) {} 52aa219f5a7792ebff4db38c60f8f08f9ab44b2586Yifan Hong const std::string& name() const { return mName; } 53aa219f5a7792ebff4db38c60f8f08f9ab44b2586Yifan Hong std::istream& stream() { return *mStream; } 54aa219f5a7792ebff4db38c60f8f08f9ab44b2586Yifan Hong 55aa219f5a7792ebff4db38c60f8f08f9ab44b2586Yifan Hong private: 56aa219f5a7792ebff4db38c60f8f08f9ab44b2586Yifan Hong std::string mName; 57aa219f5a7792ebff4db38c60f8f08f9ab44b2586Yifan Hong std::unique_ptr<std::istream> mStream; 58aa219f5a7792ebff4db38c60f8f08f9ab44b2586Yifan Hong}; 59aa219f5a7792ebff4db38c60f8f08f9ab44b2586Yifan Hong 604d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong/** 614d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong * Slurps the device manifest file and add build time flag to it. 624d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong */ 638302cea08dea5238cbc4d2637ff90319480971aeYifan Hongclass AssembleVintfImpl : public AssembleVintf { 649a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong using Condition = std::unique_ptr<KernelConfig>; 659a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong using ConditionedConfig = std::pair<Condition, std::vector<KernelConfig> /* configs */>; 669a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong 679a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong public: 688302cea08dea5238cbc4d2637ff90319480971aeYifan Hong void setFakeEnv(const std::string& key, const std::string& value) { mFakeEnv[key] = value; } 698302cea08dea5238cbc4d2637ff90319480971aeYifan Hong 708302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::string getEnv(const std::string& key) const { 718302cea08dea5238cbc4d2637ff90319480971aeYifan Hong auto it = mFakeEnv.find(key); 728302cea08dea5238cbc4d2637ff90319480971aeYifan Hong if (it != mFakeEnv.end()) { 738302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return it->second; 748302cea08dea5238cbc4d2637ff90319480971aeYifan Hong } 758302cea08dea5238cbc4d2637ff90319480971aeYifan Hong const char* envValue = getenv(key.c_str()); 768302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return envValue != nullptr ? std::string(envValue) : std::string(); 778302cea08dea5238cbc4d2637ff90319480971aeYifan Hong } 788302cea08dea5238cbc4d2637ff90319480971aeYifan Hong 79a28729e759ec4041d8c53d365b690b0782ea8b03Yifan Hong // Get environment variable and split with space. 80a28729e759ec4041d8c53d365b690b0782ea8b03Yifan Hong std::vector<std::string> getEnvList(const std::string& key) const { 81a28729e759ec4041d8c53d365b690b0782ea8b03Yifan Hong std::vector<std::string> ret; 82a28729e759ec4041d8c53d365b690b0782ea8b03Yifan Hong for (auto&& v : base::Split(getEnv(key), " ")) { 83a28729e759ec4041d8c53d365b690b0782ea8b03Yifan Hong v = base::Trim(v); 84a28729e759ec4041d8c53d365b690b0782ea8b03Yifan Hong if (!v.empty()) { 85a28729e759ec4041d8c53d365b690b0782ea8b03Yifan Hong ret.push_back(v); 86a28729e759ec4041d8c53d365b690b0782ea8b03Yifan Hong } 87a28729e759ec4041d8c53d365b690b0782ea8b03Yifan Hong } 88a28729e759ec4041d8c53d365b690b0782ea8b03Yifan Hong return ret; 89a28729e759ec4041d8c53d365b690b0782ea8b03Yifan Hong } 90a28729e759ec4041d8c53d365b690b0782ea8b03Yifan Hong 918302cea08dea5238cbc4d2637ff90319480971aeYifan Hong template <typename T> 928302cea08dea5238cbc4d2637ff90319480971aeYifan Hong bool getFlag(const std::string& key, T* value) const { 938302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::string envValue = getEnv(key); 948302cea08dea5238cbc4d2637ff90319480971aeYifan Hong if (envValue.empty()) { 958302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::cerr << "Warning: " << key << " is missing, defaulted to " << (*value) << "." 96488e16a67311194f0fb9aa4a33219af170e6316bYifan Hong << std::endl; 97488e16a67311194f0fb9aa4a33219af170e6316bYifan Hong return true; 984d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong } 994d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 1004d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong if (!parse(envValue, value)) { 1014d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong std::cerr << "Cannot parse " << envValue << "." << std::endl; 1024d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong return false; 1034d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong } 1044d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong return true; 1054d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong } 1064d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 107eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong /** 1080f7f728a862537162ff034af7064ac183cf13617Yifan Hong * Set *out to environment variable only if *out is a dummy value (i.e. default constructed). 1090f7f728a862537162ff034af7064ac183cf13617Yifan Hong * Return true if *out is set to environment variable, otherwise false. 110eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong */ 111eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong template <typename T> 112f7e8b1bc78ce6a2981ebd4b1a3031b8a0fe3c726Yifan Hong bool getFlagIfUnset(const std::string& envKey, T* out, bool log = true) const { 113eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong bool hasExistingValue = !(*out == T{}); 114eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong 115eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong bool hasEnvValue = false; 116eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong T envValue; 1178302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::string envStrValue = getEnv(envKey); 1188302cea08dea5238cbc4d2637ff90319480971aeYifan Hong if (!envStrValue.empty()) { 1198302cea08dea5238cbc4d2637ff90319480971aeYifan Hong if (!parse(envStrValue, &envValue)) { 120f7e8b1bc78ce6a2981ebd4b1a3031b8a0fe3c726Yifan Hong if (log) { 121f7e8b1bc78ce6a2981ebd4b1a3031b8a0fe3c726Yifan Hong std::cerr << "Cannot parse " << envValue << "." << std::endl; 122f7e8b1bc78ce6a2981ebd4b1a3031b8a0fe3c726Yifan Hong } 123eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong return false; 124eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong } 125eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong hasEnvValue = true; 126eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong } 127eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong 128eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong if (hasExistingValue) { 129f7e8b1bc78ce6a2981ebd4b1a3031b8a0fe3c726Yifan Hong if (hasEnvValue && log) { 130eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong std::cerr << "Warning: cannot override existing value " << *out << " with " 131eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong << envKey << " (which is " << envValue << ")." << std::endl; 132eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong } 133eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong return false; 134eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong } 135eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong if (!hasEnvValue) { 136f7e8b1bc78ce6a2981ebd4b1a3031b8a0fe3c726Yifan Hong if (log) { 137f7e8b1bc78ce6a2981ebd4b1a3031b8a0fe3c726Yifan Hong std::cerr << "Warning: " << envKey << " is not specified. Default to " << T{} << "." 138f7e8b1bc78ce6a2981ebd4b1a3031b8a0fe3c726Yifan Hong << std::endl; 139f7e8b1bc78ce6a2981ebd4b1a3031b8a0fe3c726Yifan Hong } 140eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong return false; 141eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong } 142eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong *out = envValue; 143eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong return true; 144eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong } 145eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong 1468302cea08dea5238cbc4d2637ff90319480971aeYifan Hong bool getBooleanFlag(const std::string& key) const { return getEnv(key) == std::string("true"); } 147dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 1488302cea08dea5238cbc4d2637ff90319480971aeYifan Hong size_t getIntegerFlag(const std::string& key, size_t defaultValue = 0) const { 1498302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::string envValue = getEnv(key); 150dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong if (envValue.empty()) { 151dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return defaultValue; 152dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 153dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong size_t value; 154dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong if (!base::ParseUint(envValue, &value)) { 155dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong std::cerr << "Error: " << key << " must be a number." << std::endl; 156dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return defaultValue; 157dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 158dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return value; 159dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 160dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 1614650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong static std::string read(std::basic_istream<char>& is) { 1624650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong std::stringstream ss; 1634650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong ss << is.rdbuf(); 1644650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong return ss.str(); 1654650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong } 1664650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong 1679a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong static bool isCommonConfig(const std::string& path) { 1689a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong return ::android::base::Basename(path) == gBaseConfig; 1699a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong } 1709a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong 171079ec2492c275b9041584f2f07605982682c559cYifan Hong // nullptr on any error, otherwise the condition. 172079ec2492c275b9041584f2f07605982682c559cYifan Hong static Condition generateCondition(const std::string& path) { 173079ec2492c275b9041584f2f07605982682c559cYifan Hong std::string fname = ::android::base::Basename(path); 174079ec2492c275b9041584f2f07605982682c559cYifan Hong if (fname.size() <= gConfigPrefix.size() + gConfigSuffix.size() || 175079ec2492c275b9041584f2f07605982682c559cYifan Hong !std::equal(gConfigPrefix.begin(), gConfigPrefix.end(), fname.begin()) || 176079ec2492c275b9041584f2f07605982682c559cYifan Hong !std::equal(gConfigSuffix.rbegin(), gConfigSuffix.rend(), fname.rbegin())) { 177079ec2492c275b9041584f2f07605982682c559cYifan Hong return nullptr; 178079ec2492c275b9041584f2f07605982682c559cYifan Hong } 179079ec2492c275b9041584f2f07605982682c559cYifan Hong 180079ec2492c275b9041584f2f07605982682c559cYifan Hong std::string sub = fname.substr(gConfigPrefix.size(), 181079ec2492c275b9041584f2f07605982682c559cYifan Hong fname.size() - gConfigPrefix.size() - gConfigSuffix.size()); 182079ec2492c275b9041584f2f07605982682c559cYifan Hong if (sub.empty()) { 183079ec2492c275b9041584f2f07605982682c559cYifan Hong return nullptr; // should not happen 184079ec2492c275b9041584f2f07605982682c559cYifan Hong } 185079ec2492c275b9041584f2f07605982682c559cYifan Hong for (size_t i = 0; i < sub.size(); ++i) { 186079ec2492c275b9041584f2f07605982682c559cYifan Hong if (sub[i] == '-') { 187079ec2492c275b9041584f2f07605982682c559cYifan Hong sub[i] = '_'; 188079ec2492c275b9041584f2f07605982682c559cYifan Hong continue; 189079ec2492c275b9041584f2f07605982682c559cYifan Hong } 190079ec2492c275b9041584f2f07605982682c559cYifan Hong if (isalnum(sub[i])) { 191079ec2492c275b9041584f2f07605982682c559cYifan Hong sub[i] = toupper(sub[i]); 192079ec2492c275b9041584f2f07605982682c559cYifan Hong continue; 193079ec2492c275b9041584f2f07605982682c559cYifan Hong } 194079ec2492c275b9041584f2f07605982682c559cYifan Hong std::cerr << "'" << fname << "' (in " << path 195079ec2492c275b9041584f2f07605982682c559cYifan Hong << ") is not a valid kernel config file name. Must match regex: " 196079ec2492c275b9041584f2f07605982682c559cYifan Hong << "android-base(-[0-9a-zA-Z-]+)?\\.cfg" << std::endl; 197079ec2492c275b9041584f2f07605982682c559cYifan Hong return nullptr; 198079ec2492c275b9041584f2f07605982682c559cYifan Hong } 199079ec2492c275b9041584f2f07605982682c559cYifan Hong sub.insert(0, "CONFIG_"); 200079ec2492c275b9041584f2f07605982682c559cYifan Hong return std::make_unique<KernelConfig>(std::move(sub), Tristate::YES); 201079ec2492c275b9041584f2f07605982682c559cYifan Hong } 202079ec2492c275b9041584f2f07605982682c559cYifan Hong 2038302cea08dea5238cbc4d2637ff90319480971aeYifan Hong static bool parseFileForKernelConfigs(std::basic_istream<char>& stream, 2048302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::vector<KernelConfig>* out) { 20502e94004a6d35d20af7df1ea9c66c5b65e4bd9c6Yifan Hong KernelConfigParser parser(true /* processComments */, true /* relaxedFormat */); 2068302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::string content = read(stream); 20779efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong status_t err = parser.process(content.c_str(), content.size()); 20879efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong if (err != OK) { 209ae53a0e6d3f605cc124009cb0172f152f69417a4Yifan Hong std::cerr << parser.error(); 21079efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong return false; 21179efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong } 21279efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong err = parser.finish(); 21379efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong if (err != OK) { 214ae53a0e6d3f605cc124009cb0172f152f69417a4Yifan Hong std::cerr << parser.error(); 21579efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong return false; 21679efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong } 21779efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong 21879efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong for (auto& configPair : parser.configs()) { 21979efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong out->push_back({}); 22079efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong KernelConfig& config = out->back(); 22179efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong config.first = std::move(configPair.first); 22279efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong if (!parseKernelConfigTypedValue(configPair.second, &config.second)) { 22379efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong std::cerr << "Unknown value type for key = '" << config.first << "', value = '" 22479efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong << configPair.second << "'\n"; 22579efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong return false; 22679efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong } 22779efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong } 22879efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong return true; 22979efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong } 23079efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong 2318302cea08dea5238cbc4d2637ff90319480971aeYifan Hong static bool parseFilesForKernelConfigs(std::vector<NamedIstream>* streams, 2329a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong std::vector<ConditionedConfig>* out) { 2339a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong out->clear(); 2349a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong ConditionedConfig commonConfig; 2359a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong bool foundCommonConfig = false; 2360bef86826065d9cfdad3139ea186a98524cf2eddSteve Muckle bool ret = true; 2378302cea08dea5238cbc4d2637ff90319480971aeYifan Hong 2388302cea08dea5238cbc4d2637ff90319480971aeYifan Hong for (auto& namedStream : *streams) { 2398302cea08dea5238cbc4d2637ff90319480971aeYifan Hong if (isCommonConfig(namedStream.name())) { 2408302cea08dea5238cbc4d2637ff90319480971aeYifan Hong ret &= parseFileForKernelConfigs(namedStream.stream(), &commonConfig.second); 2419a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong foundCommonConfig = true; 2429a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong } else { 2438302cea08dea5238cbc4d2637ff90319480971aeYifan Hong Condition condition = generateCondition(namedStream.name()); 244079ec2492c275b9041584f2f07605982682c559cYifan Hong ret &= (condition != nullptr); 245079ec2492c275b9041584f2f07605982682c559cYifan Hong 2469a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong std::vector<KernelConfig> kernelConfigs; 2478302cea08dea5238cbc4d2637ff90319480971aeYifan Hong if ((ret &= parseFileForKernelConfigs(namedStream.stream(), &kernelConfigs))) 248079ec2492c275b9041584f2f07605982682c559cYifan Hong out->emplace_back(std::move(condition), std::move(kernelConfigs)); 2499a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong } 2500bef86826065d9cfdad3139ea186a98524cf2eddSteve Muckle } 2519a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong 2529a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong if (!foundCommonConfig) { 2538302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::cerr << "No android-base.cfg is found in these paths:" << std::endl; 2548302cea08dea5238cbc4d2637ff90319480971aeYifan Hong for (auto& namedStream : *streams) { 2558302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::cerr << " " << namedStream.name() << std::endl; 2568302cea08dea5238cbc4d2637ff90319480971aeYifan Hong } 2579a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong } 2589a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong ret &= foundCommonConfig; 2599a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong // first element is always common configs (no conditions). 2609a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong out->insert(out->begin(), std::move(commonConfig)); 2610bef86826065d9cfdad3139ea186a98524cf2eddSteve Muckle return ret; 2620bef86826065d9cfdad3139ea186a98524cf2eddSteve Muckle } 2630bef86826065d9cfdad3139ea186a98524cf2eddSteve Muckle 2648302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::basic_ostream<char>& out() const { return mOutRef == nullptr ? std::cout : *mOutRef; } 2659aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong 266dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong template <typename S> 267ffcaf994fe9956e976d4c525038f39fa08e76e8aYifan Hong using Schemas = std::vector<Named<S>>; 268dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong using HalManifests = Schemas<HalManifest>; 269dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong using CompatibilityMatrices = Schemas<CompatibilityMatrix>; 270dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 271dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong bool assembleHalManifest(HalManifests* halManifests) { 2724650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong std::string error; 273ffcaf994fe9956e976d4c525038f39fa08e76e8aYifan Hong HalManifest* halManifest = &halManifests->front().object; 274dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong for (auto it = halManifests->begin() + 1; it != halManifests->end(); ++it) { 275ffcaf994fe9956e976d4c525038f39fa08e76e8aYifan Hong const std::string& path = it->name; 276ffcaf994fe9956e976d4c525038f39fa08e76e8aYifan Hong HalManifest& halToAdd = it->object; 277dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 278dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong if (halToAdd.level() != Level::UNSPECIFIED) { 279dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong if (halManifest->level() == Level::UNSPECIFIED) { 280dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong halManifest->mLevel = halToAdd.level(); 281dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } else if (halManifest->level() != halToAdd.level()) { 282dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong std::cerr << "Inconsistent FCM Version in HAL manifests:" << std::endl 283ffcaf994fe9956e976d4c525038f39fa08e76e8aYifan Hong << " File '" << halManifests->front().name << "' has level " 284dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << halManifest->level() << std::endl 285dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << " File '" << path << "' has level " << halToAdd.level() 286dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << std::endl; 287dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return false; 288dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 289dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 290dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 291ea25dd45961fc0b23ae9ba602c6d090590aa8241Yifan Hong if (!halManifest->addAllHals(&halToAdd, &error)) { 292dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong std::cerr << "File \"" << path << "\" cannot be added: conflict on HAL \"" << error 293dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << "\" with an existing HAL. See <hal> with the same name " 294dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << "in previously parsed files or previously declared in this file." 295dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << std::endl; 296dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return false; 297dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 298dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 2994d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 3009aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong if (halManifest->mType == SchemaType::DEVICE) { 3019aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong if (!getFlag("BOARD_SEPOLICY_VERS", &halManifest->device.mSepolicyVersion)) { 3029aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong return false; 3034d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong } 304dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong if (!setDeviceFcmVersion(halManifest)) { 305dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return false; 306dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 3079aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong } 3084d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 309feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong if (halManifest->mType == SchemaType::FRAMEWORK) { 310a28729e759ec4041d8c53d365b690b0782ea8b03Yifan Hong for (auto&& v : getEnvList("PROVIDED_VNDK_VERSIONS")) { 311a28729e759ec4041d8c53d365b690b0782ea8b03Yifan Hong halManifest->framework.mVendorNdks.emplace_back(std::move(v)); 312a28729e759ec4041d8c53d365b690b0782ea8b03Yifan Hong } 313a28729e759ec4041d8c53d365b690b0782ea8b03Yifan Hong 3148b8492bcc42b79d1a95b02808dfbb654e2e31690Yifan Hong for (auto&& v : getEnvList("PLATFORM_SYSTEMSDK_VERSIONS")) { 315a28729e759ec4041d8c53d365b690b0782ea8b03Yifan Hong halManifest->framework.mSystemSdk.mVersions.emplace(std::move(v)); 316feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong } 317feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong } 318feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong 3199aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong if (mOutputMatrix) { 3209aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong CompatibilityMatrix generatedMatrix = halManifest->generateCompatibleMatrix(); 3219aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong if (!halManifest->checkCompatibility(generatedMatrix, &error)) { 3229aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong std::cerr << "FATAL ERROR: cannot generate a compatible matrix: " << error 3239aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong << std::endl; 324a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong } 3259aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong out() << "<!-- \n" 3269aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong " Autogenerated skeleton compatibility matrix. \n" 3279aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong " Use with caution. Modify it to suit your needs.\n" 3289aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong " All HALs are set to optional.\n" 3299aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong " Many entries other than HALs are zero-filled and\n" 3309aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong " require human attention. \n" 3319aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong "-->\n" 332a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong << gCompatibilityMatrixConverter(generatedMatrix, mSerializeFlags); 3339aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong } else { 334a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong out() << gHalManifestConverter(*halManifest, mSerializeFlags); 3359aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong } 3369aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong out().flush(); 3379aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong 3388302cea08dea5238cbc4d2637ff90319480971aeYifan Hong if (mCheckFile != nullptr) { 3399aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong CompatibilityMatrix checkMatrix; 340947570619d88bc6b9ca87f567943987f70a3905aYifan Hong if (!gCompatibilityMatrixConverter(&checkMatrix, read(*mCheckFile), &error)) { 341947570619d88bc6b9ca87f567943987f70a3905aYifan Hong std::cerr << "Cannot parse check file as a compatibility matrix: " << error 342947570619d88bc6b9ca87f567943987f70a3905aYifan Hong << std::endl; 3439aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong return false; 3444650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong } 3459aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong if (!halManifest->checkCompatibility(checkMatrix, &error)) { 3469aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong std::cerr << "Not compatible: " << error << std::endl; 3479aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong return false; 3489aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong } 3499aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong } 3504650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong 3519aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong return true; 3529aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong } 3539aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong 354e88e16721117aaf97548bebbffd6c8ea81b681efYifan Hong bool assembleFrameworkCompatibilityMatrixKernels(CompatibilityMatrix* matrix) { 3558302cea08dea5238cbc4d2637ff90319480971aeYifan Hong for (auto& pair : mKernels) { 3569a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong std::vector<ConditionedConfig> conditionedConfigs; 3578302cea08dea5238cbc4d2637ff90319480971aeYifan Hong if (!parseFilesForKernelConfigs(&pair.second, &conditionedConfigs)) { 358e88e16721117aaf97548bebbffd6c8ea81b681efYifan Hong return false; 359e88e16721117aaf97548bebbffd6c8ea81b681efYifan Hong } 3609a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong for (ConditionedConfig& conditionedConfig : conditionedConfigs) { 361fb9e8b655e67031c156687eeb4e561c976d04015Yifan Hong MatrixKernel kernel(KernelVersion{pair.first}, std::move(conditionedConfig.second)); 362079ec2492c275b9041584f2f07605982682c559cYifan Hong if (conditionedConfig.first != nullptr) 363079ec2492c275b9041584f2f07605982682c559cYifan Hong kernel.mConditions.push_back(std::move(*conditionedConfig.first)); 364079ec2492c275b9041584f2f07605982682c559cYifan Hong matrix->framework.mKernels.push_back(std::move(kernel)); 3659a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong } 366e88e16721117aaf97548bebbffd6c8ea81b681efYifan Hong } 367e88e16721117aaf97548bebbffd6c8ea81b681efYifan Hong return true; 368e88e16721117aaf97548bebbffd6c8ea81b681efYifan Hong } 369e88e16721117aaf97548bebbffd6c8ea81b681efYifan Hong 370dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong bool setDeviceFcmVersion(HalManifest* manifest) { 371dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong size_t shippingApiLevel = getIntegerFlag("PRODUCT_SHIPPING_API_LEVEL"); 372dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 373dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong if (manifest->level() != Level::UNSPECIFIED) { 374dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return true; 375dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 376dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong if (!getBooleanFlag("PRODUCT_ENFORCE_VINTF_MANIFEST")) { 377dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong manifest->mLevel = Level::LEGACY; 378dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return true; 379dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 380dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong // TODO(b/70628538): Do not infer from Shipping API level. 381dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong if (shippingApiLevel) { 382dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong std::cerr << "Warning: Shipping FCM Version is inferred from Shipping API level. " 383dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << "Declare Shipping FCM Version in device manifest directly." << std::endl; 384afae198ce40f51b116c2540ca87f9157c3a56ea4Yifan Hong manifest->mLevel = details::convertFromApiLevel(shippingApiLevel); 385dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong if (manifest->mLevel == Level::UNSPECIFIED) { 386dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong std::cerr << "Error: Shipping FCM Version cannot be inferred from Shipping API " 387dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << "level " << shippingApiLevel << "." 388dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << "Declare Shipping FCM Version in device manifest directly." 389dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << std::endl; 390dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return false; 391dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 392dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return true; 393dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 394dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong // TODO(b/69638851): should be an error if Shipping API level is not defined. 395dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong // For now, just leave it empty; when framework compatibility matrix is built, 396dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong // lowest FCM Version is assumed. 397dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong std::cerr << "Warning: Shipping FCM Version cannot be inferred, because:" << std::endl 398dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << " (1) It is not explicitly declared in device manifest;" << std::endl 399dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << " (2) PRODUCT_ENFORCE_VINTF_MANIFEST is set to true;" << std::endl 400dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << " (3) PRODUCT_SHIPPING_API_LEVEL is undefined." << std::endl 401dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << "Assuming 'unspecified' Shipping FCM Version. " << std::endl 402dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << "To remove this warning, define 'level' attribute in device manifest." 403dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << std::endl; 404dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return true; 405dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 4069aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong 407dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong Level getLowestFcmVersion(const CompatibilityMatrices& matrices) { 408dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong Level ret = Level::UNSPECIFIED; 409dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong for (const auto& e : matrices) { 410ffcaf994fe9956e976d4c525038f39fa08e76e8aYifan Hong if (ret == Level::UNSPECIFIED || ret > e.object.level()) { 411ffcaf994fe9956e976d4c525038f39fa08e76e8aYifan Hong ret = e.object.level(); 412dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 413dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 414dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return ret; 415dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 416dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 417dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong bool assembleCompatibilityMatrix(CompatibilityMatrices* matrices) { 418dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong std::string error; 419dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong CompatibilityMatrix* matrix = nullptr; 420dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong std::unique_ptr<HalManifest> checkManifest; 421ffcaf994fe9956e976d4c525038f39fa08e76e8aYifan Hong if (matrices->front().object.mType == SchemaType::DEVICE) { 422ffcaf994fe9956e976d4c525038f39fa08e76e8aYifan Hong matrix = &matrices->front().object; 423feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong 424feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong auto vndkVersion = base::Trim(getEnv("REQUIRED_VNDK_VERSION")); 425feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong if (!vndkVersion.empty()) { 426feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong auto& valueInMatrix = matrix->device.mVendorNdk; 427feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong if (!valueInMatrix.version().empty() && valueInMatrix.version() != vndkVersion) { 428feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong std::cerr << "Hard-coded <vendor-ndk> version in device compatibility matrix (" 429feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong << matrices->front().name << "), '" << valueInMatrix.version() 430feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong << "', does not match value inferred " 431feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong << "from BOARD_VNDK_VERSION '" << vndkVersion << "'" << std::endl; 432feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong return false; 433feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong } 434feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong valueInMatrix = VendorNdk{std::move(vndkVersion)}; 435feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong } 436a28729e759ec4041d8c53d365b690b0782ea8b03Yifan Hong 437a28729e759ec4041d8c53d365b690b0782ea8b03Yifan Hong for (auto&& v : getEnvList("BOARD_SYSTEMSDK_VERSIONS")) { 438a28729e759ec4041d8c53d365b690b0782ea8b03Yifan Hong matrix->device.mSystemSdk.mVersions.emplace(std::move(v)); 439a28729e759ec4041d8c53d365b690b0782ea8b03Yifan Hong } 440dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 441dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 442ffcaf994fe9956e976d4c525038f39fa08e76e8aYifan Hong if (matrices->front().object.mType == SchemaType::FRAMEWORK) { 443dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong Level deviceLevel = Level::UNSPECIFIED; 4448302cea08dea5238cbc4d2637ff90319480971aeYifan Hong if (mCheckFile != nullptr) { 445dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong checkManifest = std::make_unique<HalManifest>(); 446947570619d88bc6b9ca87f567943987f70a3905aYifan Hong if (!gHalManifestConverter(checkManifest.get(), read(*mCheckFile), &error)) { 447947570619d88bc6b9ca87f567943987f70a3905aYifan Hong std::cerr << "Cannot parse check file as a HAL manifest: " << error 448947570619d88bc6b9ca87f567943987f70a3905aYifan Hong << std::endl; 449dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return false; 450dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 451dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong deviceLevel = checkManifest->level(); 452dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 453dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 454dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong if (deviceLevel == Level::UNSPECIFIED) { 455dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong // For GSI build, legacy devices that do not have a HAL manifest, 456dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong // and devices in development, merge all compatibility matrices. 457dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong deviceLevel = getLowestFcmVersion(*matrices); 458dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 459dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 460ddae77eaca3f1a79398033c8a53ce2d57875a27bYifan Hong if (deviceLevel == Level::UNSPECIFIED) { 461ddae77eaca3f1a79398033c8a53ce2d57875a27bYifan Hong // building empty.xml 462ffcaf994fe9956e976d4c525038f39fa08e76e8aYifan Hong matrix = &matrices->front().object; 463ddae77eaca3f1a79398033c8a53ce2d57875a27bYifan Hong } else { 464ddae77eaca3f1a79398033c8a53ce2d57875a27bYifan Hong matrix = CompatibilityMatrix::combine(deviceLevel, matrices, &error); 465ddae77eaca3f1a79398033c8a53ce2d57875a27bYifan Hong if (matrix == nullptr) { 466ddae77eaca3f1a79398033c8a53ce2d57875a27bYifan Hong std::cerr << error << std::endl; 467dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return false; 468dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 469dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 470dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 471e88e16721117aaf97548bebbffd6c8ea81b681efYifan Hong if (!assembleFrameworkCompatibilityMatrixKernels(matrix)) { 472e88e16721117aaf97548bebbffd6c8ea81b681efYifan Hong return false; 47379efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong } 474e88e16721117aaf97548bebbffd6c8ea81b681efYifan Hong 475321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong // Add PLATFORM_SEPOLICY_* to sepolicy.sepolicy-version. Remove dupes. 476321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong std::set<Version> sepolicyVersions; 477321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong auto sepolicyVersionStrings = getEnvList("PLATFORM_SEPOLICY_COMPAT_VERSIONS"); 478321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong auto currentSepolicyVersionString = getEnv("PLATFORM_SEPOLICY_VERSION"); 479321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong if (!currentSepolicyVersionString.empty()) { 480321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong sepolicyVersionStrings.push_back(currentSepolicyVersionString); 481321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong } 482321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong for (auto&& s : sepolicyVersionStrings) { 483321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong Version v; 484321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong if (!parse(s, &v)) { 485321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong std::cerr << "Error: unknown sepolicy version '" << s << "' specified by " 486321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong << (s == currentSepolicyVersionString 487321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong ? "PLATFORM_SEPOLICY_VERSION" 488321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong : "PLATFORM_SEPOLICY_COMPAT_VERSIONS") 489321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong << "."; 490321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong return false; 491321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong } 492321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong sepolicyVersions.insert(v); 493321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong } 494321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong for (auto&& v : sepolicyVersions) { 495321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong matrix->framework.mSepolicy.mSepolicyVersionRanges.emplace_back(v.majorVer, 496321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong v.minorVer); 4977f6c00c77c755f4efef49e5371058470a461193fYifan Hong } 498f4135016f2c735ac1bf3c50730bb66aa2b8e385fYifan Hong 499f7e8b1bc78ce6a2981ebd4b1a3031b8a0fe3c726Yifan Hong getFlagIfUnset("POLICYVERS", &matrix->framework.mSepolicy.mKernelSepolicyVersion, 500f7e8b1bc78ce6a2981ebd4b1a3031b8a0fe3c726Yifan Hong deviceLevel == Level::UNSPECIFIED /* log */); 501f7e8b1bc78ce6a2981ebd4b1a3031b8a0fe3c726Yifan Hong getFlagIfUnset("FRAMEWORK_VBMETA_VERSION", &matrix->framework.mAvbMetaVersion, 502f7e8b1bc78ce6a2981ebd4b1a3031b8a0fe3c726Yifan Hong deviceLevel == Level::UNSPECIFIED /* log */); 503dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 504dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong out() << "<!--" << std::endl; 505dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong out() << " Input:" << std::endl; 506ddae77eaca3f1a79398033c8a53ce2d57875a27bYifan Hong for (const auto& e : *matrices) { 507ffcaf994fe9956e976d4c525038f39fa08e76e8aYifan Hong if (!e.name.empty()) { 5084f67f3bf621fa4162e07bd7d015b81e915ad4d44Yifan Hong out() << " " << base::Basename(e.name) << std::endl; 509ddae77eaca3f1a79398033c8a53ce2d57875a27bYifan Hong } 510dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 511dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong out() << "-->" << std::endl; 512a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong } 513a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong out() << gCompatibilityMatrixConverter(*matrix, mSerializeFlags); 5149aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong out().flush(); 515a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong 516dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong if (checkManifest != nullptr && getBooleanFlag("PRODUCT_ENFORCE_VINTF_MANIFEST") && 517dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong !checkManifest->checkCompatibility(*matrix, &error)) { 518dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong std::cerr << "Not compatible: " << error << std::endl; 519dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return false; 5209aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong } 5219aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong 5229aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong return true; 5239aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong } 5249aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong 525bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong enum AssembleStatus { SUCCESS, FAIL_AND_EXIT, TRY_NEXT }; 526bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong template <typename Schema, typename AssembleFunc> 527bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong AssembleStatus tryAssemble(const XmlConverter<Schema>& converter, const std::string& schemaName, 528947570619d88bc6b9ca87f567943987f70a3905aYifan Hong AssembleFunc assemble, std::string* error) { 529dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong Schemas<Schema> schemas; 530bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong Schema schema; 531947570619d88bc6b9ca87f567943987f70a3905aYifan Hong if (!converter(&schema, read(mInFiles.front().stream()), error)) { 532bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong return TRY_NEXT; 533bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong } 534bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong auto firstType = schema.type(); 535aa219f5a7792ebff4db38c60f8f08f9ab44b2586Yifan Hong schemas.emplace_back(mInFiles.front().name(), std::move(schema)); 536dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 537bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong for (auto it = mInFiles.begin() + 1; it != mInFiles.end(); ++it) { 538bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong Schema additionalSchema; 539aa219f5a7792ebff4db38c60f8f08f9ab44b2586Yifan Hong const std::string& fileName = it->name(); 540947570619d88bc6b9ca87f567943987f70a3905aYifan Hong if (!converter(&additionalSchema, read(it->stream()), error)) { 541dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong std::cerr << "File \"" << fileName << "\" is not a valid " << firstType << " " 542dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << schemaName << " (but the first file is a valid " << firstType << " " 543947570619d88bc6b9ca87f567943987f70a3905aYifan Hong << schemaName << "). Error: " << *error << std::endl; 544bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong return FAIL_AND_EXIT; 545bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong } 546bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong if (additionalSchema.type() != firstType) { 547dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong std::cerr << "File \"" << fileName << "\" is a " << additionalSchema.type() << " " 548dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << schemaName << " (but a " << firstType << " " << schemaName 549dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << " is expected)." << std::endl; 550eb14e3013ea11b3d47d40fa860f16345c607fef6Yifan Hong return FAIL_AND_EXIT; 551eb14e3013ea11b3d47d40fa860f16345c607fef6Yifan Hong } 552dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 553dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong schemas.emplace_back(fileName, std::move(additionalSchema)); 554bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong } 555dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return assemble(&schemas) ? SUCCESS : FAIL_AND_EXIT; 556bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong } 557bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong 5588302cea08dea5238cbc4d2637ff90319480971aeYifan Hong bool assemble() override { 559bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong using std::placeholders::_1; 560bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong if (mInFiles.empty()) { 5619aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong std::cerr << "Missing input file." << std::endl; 5629aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong return false; 5639aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong } 5649aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong 565947570619d88bc6b9ca87f567943987f70a3905aYifan Hong std::string manifestError; 566bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong auto status = tryAssemble(gHalManifestConverter, "manifest", 567947570619d88bc6b9ca87f567943987f70a3905aYifan Hong std::bind(&AssembleVintfImpl::assembleHalManifest, this, _1), 568947570619d88bc6b9ca87f567943987f70a3905aYifan Hong &manifestError); 569bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong if (status == SUCCESS) return true; 570bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong if (status == FAIL_AND_EXIT) return false; 5719aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong 572bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong resetInFiles(); 5734650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong 574947570619d88bc6b9ca87f567943987f70a3905aYifan Hong std::string matrixError; 575bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong status = tryAssemble(gCompatibilityMatrixConverter, "compatibility matrix", 576947570619d88bc6b9ca87f567943987f70a3905aYifan Hong std::bind(&AssembleVintfImpl::assembleCompatibilityMatrix, this, _1), 577947570619d88bc6b9ca87f567943987f70a3905aYifan Hong &matrixError); 578bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong if (status == SUCCESS) return true; 579bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong if (status == FAIL_AND_EXIT) return false; 5804d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 581959ee1bf8b922980542f72ce9ad1929fc7d8b55cYifan Hong std::cerr << "Input file has unknown format." << std::endl 582947570619d88bc6b9ca87f567943987f70a3905aYifan Hong << "Error when attempting to convert to manifest: " << manifestError << std::endl 583947570619d88bc6b9ca87f567943987f70a3905aYifan Hong << "Error when attempting to convert to compatibility matrix: " << matrixError 584947570619d88bc6b9ca87f567943987f70a3905aYifan Hong << std::endl; 585959ee1bf8b922980542f72ce9ad1929fc7d8b55cYifan Hong return false; 5864d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong } 5879aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong 5888302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::ostream& setOutputStream(Ostream&& out) override { 5898302cea08dea5238cbc4d2637ff90319480971aeYifan Hong mOutRef = std::move(out); 5908302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return *mOutRef; 5919aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong } 5929aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong 5938302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::istream& addInputStream(const std::string& name, Istream&& in) override { 5948302cea08dea5238cbc4d2637ff90319480971aeYifan Hong auto it = mInFiles.emplace(mInFiles.end(), name, std::move(in)); 5958302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return it->stream(); 5968302cea08dea5238cbc4d2637ff90319480971aeYifan Hong } 5978302cea08dea5238cbc4d2637ff90319480971aeYifan Hong 5988302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::istream& setCheckInputStream(Istream&& in) override { 5998302cea08dea5238cbc4d2637ff90319480971aeYifan Hong mCheckFile = std::move(in); 6008302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return *mCheckFile; 6019aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong } 6029aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong 603fb9e8b655e67031c156687eeb4e561c976d04015Yifan Hong bool hasKernelVersion(const KernelVersion& kernelVer) const override { 6048302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return mKernels.find(kernelVer) != mKernels.end(); 6058302cea08dea5238cbc4d2637ff90319480971aeYifan Hong } 6068302cea08dea5238cbc4d2637ff90319480971aeYifan Hong 607fb9e8b655e67031c156687eeb4e561c976d04015Yifan Hong std::istream& addKernelConfigInputStream(const KernelVersion& kernelVer, 608fb9e8b655e67031c156687eeb4e561c976d04015Yifan Hong const std::string& name, Istream&& in) override { 6098302cea08dea5238cbc4d2637ff90319480971aeYifan Hong auto&& kernel = mKernels[kernelVer]; 6108302cea08dea5238cbc4d2637ff90319480971aeYifan Hong auto it = kernel.emplace(kernel.end(), name, std::move(in)); 6118302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return it->stream(); 6129aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong } 6139aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong 614bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong void resetInFiles() { 615bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong for (auto& inFile : mInFiles) { 616aa219f5a7792ebff4db38c60f8f08f9ab44b2586Yifan Hong inFile.stream().clear(); 617aa219f5a7792ebff4db38c60f8f08f9ab44b2586Yifan Hong inFile.stream().seekg(0); 618bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong } 619bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong } 620bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong 6218302cea08dea5238cbc4d2637ff90319480971aeYifan Hong void setOutputMatrix() override { mOutputMatrix = true; } 6229aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong 6238302cea08dea5238cbc4d2637ff90319480971aeYifan Hong bool setHalsOnly() override { 624a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong if (mSerializeFlags) return false; 625a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong mSerializeFlags |= SerializeFlag::HALS_ONLY; 626a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong return true; 627a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong } 628a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong 6298302cea08dea5238cbc4d2637ff90319480971aeYifan Hong bool setNoHals() override { 630a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong if (mSerializeFlags) return false; 631a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong mSerializeFlags |= SerializeFlag::NO_HALS; 632a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong return true; 633a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong } 634a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong 6359aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong private: 636aa219f5a7792ebff4db38c60f8f08f9ab44b2586Yifan Hong std::vector<NamedIstream> mInFiles; 6378302cea08dea5238cbc4d2637ff90319480971aeYifan Hong Ostream mOutRef; 6388302cea08dea5238cbc4d2637ff90319480971aeYifan Hong Istream mCheckFile; 6399aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong bool mOutputMatrix = false; 640a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong SerializeFlags mSerializeFlags = SerializeFlag::EVERYTHING; 641fb9e8b655e67031c156687eeb4e561c976d04015Yifan Hong std::map<KernelVersion, std::vector<NamedIstream>> mKernels; 6428302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::map<std::string, std::string> mFakeEnv; 6434d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong}; 6444d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 6458302cea08dea5238cbc4d2637ff90319480971aeYifan Hongbool AssembleVintf::openOutFile(const std::string& path) { 6468302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return static_cast<std::ofstream&>(setOutputStream(std::make_unique<std::ofstream>(path))) 6478302cea08dea5238cbc4d2637ff90319480971aeYifan Hong .is_open(); 6484d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong} 6494d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 6508302cea08dea5238cbc4d2637ff90319480971aeYifan Hongbool AssembleVintf::openInFile(const std::string& path) { 6518302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return static_cast<std::ifstream&>(addInputStream(path, std::make_unique<std::ifstream>(path))) 6528302cea08dea5238cbc4d2637ff90319480971aeYifan Hong .is_open(); 6538302cea08dea5238cbc4d2637ff90319480971aeYifan Hong} 654a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong 6558302cea08dea5238cbc4d2637ff90319480971aeYifan Hongbool AssembleVintf::openCheckFile(const std::string& path) { 6568302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return static_cast<std::ifstream&>(setCheckInputStream(std::make_unique<std::ifstream>(path))) 6578302cea08dea5238cbc4d2637ff90319480971aeYifan Hong .is_open(); 6588302cea08dea5238cbc4d2637ff90319480971aeYifan Hong} 659a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong 6608302cea08dea5238cbc4d2637ff90319480971aeYifan Hongbool AssembleVintf::addKernel(const std::string& kernelArg) { 661b83e56bbf1b2aba92f69f63d1e434be512193b5bYifan Hong auto tokens = base::Split(kernelArg, ":"); 6628302cea08dea5238cbc4d2637ff90319480971aeYifan Hong if (tokens.size() <= 1) { 6638302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::cerr << "Unrecognized --kernel option '" << kernelArg << "'" << std::endl; 6648302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return false; 6658302cea08dea5238cbc4d2637ff90319480971aeYifan Hong } 666fb9e8b655e67031c156687eeb4e561c976d04015Yifan Hong KernelVersion kernelVer; 6678302cea08dea5238cbc4d2637ff90319480971aeYifan Hong if (!parse(tokens.front(), &kernelVer)) { 6688302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::cerr << "Unrecognized kernel version '" << tokens.front() << "'" << std::endl; 6698302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return false; 6708302cea08dea5238cbc4d2637ff90319480971aeYifan Hong } 6718302cea08dea5238cbc4d2637ff90319480971aeYifan Hong if (hasKernelVersion(kernelVer)) { 6728302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::cerr << "Multiple --kernel for " << kernelVer << " is specified." << std::endl; 6738302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return false; 6748302cea08dea5238cbc4d2637ff90319480971aeYifan Hong } 6758302cea08dea5238cbc4d2637ff90319480971aeYifan Hong for (auto it = tokens.begin() + 1; it != tokens.end(); ++it) { 6768302cea08dea5238cbc4d2637ff90319480971aeYifan Hong bool opened = 6778302cea08dea5238cbc4d2637ff90319480971aeYifan Hong static_cast<std::ifstream&>( 6788302cea08dea5238cbc4d2637ff90319480971aeYifan Hong addKernelConfigInputStream(kernelVer, *it, std::make_unique<std::ifstream>(*it))) 6798302cea08dea5238cbc4d2637ff90319480971aeYifan Hong .is_open(); 6808302cea08dea5238cbc4d2637ff90319480971aeYifan Hong if (!opened) { 6818302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::cerr << "Cannot open file '" << *it << "'." << std::endl; 6828302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return false; 6834d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong } 6844d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong } 6858302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return true; 6868302cea08dea5238cbc4d2637ff90319480971aeYifan Hong} 6874d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 6888302cea08dea5238cbc4d2637ff90319480971aeYifan Hongstd::unique_ptr<AssembleVintf> AssembleVintf::newInstance() { 6898302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return std::make_unique<AssembleVintfImpl>(); 6904d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong} 6918302cea08dea5238cbc4d2637ff90319480971aeYifan Hong 6928302cea08dea5238cbc4d2637ff90319480971aeYifan Hong} // namespace vintf 6938302cea08dea5238cbc4d2637ff90319480971aeYifan Hong} // namespace android 694