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 2669adf115f40240d1f8bfd0266c2445f7a9b3e0262Yifan Hong // If -c is provided, check it. 2679adf115f40240d1f8bfd0266c2445f7a9b3e0262Yifan Hong bool checkDualFile(const HalManifest& manifest, const CompatibilityMatrix& matrix) { 2689adf115f40240d1f8bfd0266c2445f7a9b3e0262Yifan Hong if (getBooleanFlag("PRODUCT_ENFORCE_VINTF_MANIFEST")) { 2699adf115f40240d1f8bfd0266c2445f7a9b3e0262Yifan Hong std::string error; 2709adf115f40240d1f8bfd0266c2445f7a9b3e0262Yifan Hong if (!manifest.checkCompatibility(matrix, &error)) { 2719adf115f40240d1f8bfd0266c2445f7a9b3e0262Yifan Hong std::cerr << "Not compatible: " << error << std::endl; 2729adf115f40240d1f8bfd0266c2445f7a9b3e0262Yifan Hong return false; 2739adf115f40240d1f8bfd0266c2445f7a9b3e0262Yifan Hong } 2749adf115f40240d1f8bfd0266c2445f7a9b3e0262Yifan Hong } 2759adf115f40240d1f8bfd0266c2445f7a9b3e0262Yifan Hong 2769adf115f40240d1f8bfd0266c2445f7a9b3e0262Yifan Hong // Check HALs in device manifest that are not in framework matrix. 2779adf115f40240d1f8bfd0266c2445f7a9b3e0262Yifan Hong if (getBooleanFlag("VINTF_ENFORCE_NO_UNUSED_HALS")) { 2789adf115f40240d1f8bfd0266c2445f7a9b3e0262Yifan Hong auto unused = manifest.checkUnusedHals(matrix); 2799adf115f40240d1f8bfd0266c2445f7a9b3e0262Yifan Hong if (!unused.empty()) { 2809adf115f40240d1f8bfd0266c2445f7a9b3e0262Yifan Hong std::cerr << "Error: The following instances are in the device manifest but " 2819adf115f40240d1f8bfd0266c2445f7a9b3e0262Yifan Hong << "not specified in framework compatibility matrix: " << std::endl 2829adf115f40240d1f8bfd0266c2445f7a9b3e0262Yifan Hong << " " << android::base::Join(unused, "\n ") << std::endl 2839adf115f40240d1f8bfd0266c2445f7a9b3e0262Yifan Hong << "Suggested fix:" << std::endl 2849adf115f40240d1f8bfd0266c2445f7a9b3e0262Yifan Hong << "1. Check for any typos in device manifest or framework compatibility " 2859adf115f40240d1f8bfd0266c2445f7a9b3e0262Yifan Hong << "matrices with FCM version >= " << matrix.level() << "." << std::endl 2869adf115f40240d1f8bfd0266c2445f7a9b3e0262Yifan Hong << "2. Add them to any framework compatibility matrix with FCM " 2879adf115f40240d1f8bfd0266c2445f7a9b3e0262Yifan Hong << "version >= " << matrix.level() << " where applicable." << std::endl 2889adf115f40240d1f8bfd0266c2445f7a9b3e0262Yifan Hong << "3. Add them to DEVICE_FRAMEWORK_COMPATIBILITY_MATRIX_FILE." 2899adf115f40240d1f8bfd0266c2445f7a9b3e0262Yifan Hong << std::endl; 2909adf115f40240d1f8bfd0266c2445f7a9b3e0262Yifan Hong 2919adf115f40240d1f8bfd0266c2445f7a9b3e0262Yifan Hong return false; 2929adf115f40240d1f8bfd0266c2445f7a9b3e0262Yifan Hong } 2939adf115f40240d1f8bfd0266c2445f7a9b3e0262Yifan Hong } 2949adf115f40240d1f8bfd0266c2445f7a9b3e0262Yifan Hong return true; 2959adf115f40240d1f8bfd0266c2445f7a9b3e0262Yifan Hong } 2969adf115f40240d1f8bfd0266c2445f7a9b3e0262Yifan Hong 297dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong template <typename S> 298ffcaf994fe9956e976d4c525038f39fa08e76e8aYifan Hong using Schemas = std::vector<Named<S>>; 299dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong using HalManifests = Schemas<HalManifest>; 300dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong using CompatibilityMatrices = Schemas<CompatibilityMatrix>; 301dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 302dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong bool assembleHalManifest(HalManifests* halManifests) { 3034650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong std::string error; 304ffcaf994fe9956e976d4c525038f39fa08e76e8aYifan Hong HalManifest* halManifest = &halManifests->front().object; 305dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong for (auto it = halManifests->begin() + 1; it != halManifests->end(); ++it) { 306ffcaf994fe9956e976d4c525038f39fa08e76e8aYifan Hong const std::string& path = it->name; 307ffcaf994fe9956e976d4c525038f39fa08e76e8aYifan Hong HalManifest& halToAdd = it->object; 308dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 309dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong if (halToAdd.level() != Level::UNSPECIFIED) { 310dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong if (halManifest->level() == Level::UNSPECIFIED) { 311dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong halManifest->mLevel = halToAdd.level(); 312dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } else if (halManifest->level() != halToAdd.level()) { 313dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong std::cerr << "Inconsistent FCM Version in HAL manifests:" << std::endl 314ffcaf994fe9956e976d4c525038f39fa08e76e8aYifan Hong << " File '" << halManifests->front().name << "' has level " 315dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << halManifest->level() << std::endl 316dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << " File '" << path << "' has level " << halToAdd.level() 317dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << std::endl; 318dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return false; 319dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 320dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 321dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 322ea25dd45961fc0b23ae9ba602c6d090590aa8241Yifan Hong if (!halManifest->addAllHals(&halToAdd, &error)) { 323dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong std::cerr << "File \"" << path << "\" cannot be added: conflict on HAL \"" << error 324dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << "\" with an existing HAL. See <hal> with the same name " 325dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << "in previously parsed files or previously declared in this file." 326dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << std::endl; 327dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return false; 328dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 329dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 3304d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 3319aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong if (halManifest->mType == SchemaType::DEVICE) { 3329aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong if (!getFlag("BOARD_SEPOLICY_VERS", &halManifest->device.mSepolicyVersion)) { 3339aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong return false; 3344d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong } 335dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong if (!setDeviceFcmVersion(halManifest)) { 336dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return false; 337dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 3389aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong } 3394d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 340feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong if (halManifest->mType == SchemaType::FRAMEWORK) { 341a28729e759ec4041d8c53d365b690b0782ea8b03Yifan Hong for (auto&& v : getEnvList("PROVIDED_VNDK_VERSIONS")) { 342a28729e759ec4041d8c53d365b690b0782ea8b03Yifan Hong halManifest->framework.mVendorNdks.emplace_back(std::move(v)); 343a28729e759ec4041d8c53d365b690b0782ea8b03Yifan Hong } 344a28729e759ec4041d8c53d365b690b0782ea8b03Yifan Hong 3458b8492bcc42b79d1a95b02808dfbb654e2e31690Yifan Hong for (auto&& v : getEnvList("PLATFORM_SYSTEMSDK_VERSIONS")) { 346a28729e759ec4041d8c53d365b690b0782ea8b03Yifan Hong halManifest->framework.mSystemSdk.mVersions.emplace(std::move(v)); 347feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong } 348feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong } 349feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong 3509aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong if (mOutputMatrix) { 3519aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong CompatibilityMatrix generatedMatrix = halManifest->generateCompatibleMatrix(); 3529aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong if (!halManifest->checkCompatibility(generatedMatrix, &error)) { 3539aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong std::cerr << "FATAL ERROR: cannot generate a compatible matrix: " << error 3549aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong << std::endl; 355a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong } 3569aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong out() << "<!-- \n" 3579aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong " Autogenerated skeleton compatibility matrix. \n" 3589aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong " Use with caution. Modify it to suit your needs.\n" 3599aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong " All HALs are set to optional.\n" 3609aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong " Many entries other than HALs are zero-filled and\n" 3619aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong " require human attention. \n" 3629aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong "-->\n" 363a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong << gCompatibilityMatrixConverter(generatedMatrix, mSerializeFlags); 3649aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong } else { 365a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong out() << gHalManifestConverter(*halManifest, mSerializeFlags); 3669aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong } 3679aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong out().flush(); 3689aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong 3698302cea08dea5238cbc4d2637ff90319480971aeYifan Hong if (mCheckFile != nullptr) { 3709aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong CompatibilityMatrix checkMatrix; 371947570619d88bc6b9ca87f567943987f70a3905aYifan Hong if (!gCompatibilityMatrixConverter(&checkMatrix, read(*mCheckFile), &error)) { 372947570619d88bc6b9ca87f567943987f70a3905aYifan Hong std::cerr << "Cannot parse check file as a compatibility matrix: " << error 373947570619d88bc6b9ca87f567943987f70a3905aYifan Hong << std::endl; 3749aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong return false; 3754650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong } 3769adf115f40240d1f8bfd0266c2445f7a9b3e0262Yifan Hong if (!checkDualFile(*halManifest, checkMatrix)) { 3779aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong return false; 3789aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong } 3799aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong } 3804650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong 3819aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong return true; 3829aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong } 3839aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong 384e88e16721117aaf97548bebbffd6c8ea81b681efYifan Hong bool assembleFrameworkCompatibilityMatrixKernels(CompatibilityMatrix* matrix) { 3858302cea08dea5238cbc4d2637ff90319480971aeYifan Hong for (auto& pair : mKernels) { 3869a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong std::vector<ConditionedConfig> conditionedConfigs; 3878302cea08dea5238cbc4d2637ff90319480971aeYifan Hong if (!parseFilesForKernelConfigs(&pair.second, &conditionedConfigs)) { 388e88e16721117aaf97548bebbffd6c8ea81b681efYifan Hong return false; 389e88e16721117aaf97548bebbffd6c8ea81b681efYifan Hong } 3909a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong for (ConditionedConfig& conditionedConfig : conditionedConfigs) { 391fb9e8b655e67031c156687eeb4e561c976d04015Yifan Hong MatrixKernel kernel(KernelVersion{pair.first}, std::move(conditionedConfig.second)); 392079ec2492c275b9041584f2f07605982682c559cYifan Hong if (conditionedConfig.first != nullptr) 393079ec2492c275b9041584f2f07605982682c559cYifan Hong kernel.mConditions.push_back(std::move(*conditionedConfig.first)); 394079ec2492c275b9041584f2f07605982682c559cYifan Hong matrix->framework.mKernels.push_back(std::move(kernel)); 3959a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong } 396e88e16721117aaf97548bebbffd6c8ea81b681efYifan Hong } 397e88e16721117aaf97548bebbffd6c8ea81b681efYifan Hong return true; 398e88e16721117aaf97548bebbffd6c8ea81b681efYifan Hong } 399e88e16721117aaf97548bebbffd6c8ea81b681efYifan Hong 400dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong bool setDeviceFcmVersion(HalManifest* manifest) { 4019295851019e7f8c4ecec7fa07ca5c9d7f0278ffeYifan Hong // Not needed for generating empty manifest for DEVICE_FRAMEWORK_COMPATIBILITY_MATRIX_FILE. 40273fad5fa12f0a5ca49ff1b8047a46599b7574e17Yifan Hong if (getBooleanFlag("VINTF_IGNORE_TARGET_FCM_VERSION")) { 4039295851019e7f8c4ecec7fa07ca5c9d7f0278ffeYifan Hong return true; 4049295851019e7f8c4ecec7fa07ca5c9d7f0278ffeYifan Hong } 4059295851019e7f8c4ecec7fa07ca5c9d7f0278ffeYifan Hong 406dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong size_t shippingApiLevel = getIntegerFlag("PRODUCT_SHIPPING_API_LEVEL"); 407dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 408dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong if (manifest->level() != Level::UNSPECIFIED) { 409dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return true; 410dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 411dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong if (!getBooleanFlag("PRODUCT_ENFORCE_VINTF_MANIFEST")) { 412dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong manifest->mLevel = Level::LEGACY; 413dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return true; 414dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 415dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong // TODO(b/70628538): Do not infer from Shipping API level. 416dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong if (shippingApiLevel) { 417dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong std::cerr << "Warning: Shipping FCM Version is inferred from Shipping API level. " 418dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << "Declare Shipping FCM Version in device manifest directly." << std::endl; 419afae198ce40f51b116c2540ca87f9157c3a56ea4Yifan Hong manifest->mLevel = details::convertFromApiLevel(shippingApiLevel); 420dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong if (manifest->mLevel == Level::UNSPECIFIED) { 421dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong std::cerr << "Error: Shipping FCM Version cannot be inferred from Shipping API " 422dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << "level " << shippingApiLevel << "." 423dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << "Declare Shipping FCM Version in device manifest directly." 424dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << std::endl; 425dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return false; 426dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 427dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return true; 428dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 429dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong // TODO(b/69638851): should be an error if Shipping API level is not defined. 430dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong // For now, just leave it empty; when framework compatibility matrix is built, 431dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong // lowest FCM Version is assumed. 432dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong std::cerr << "Warning: Shipping FCM Version cannot be inferred, because:" << std::endl 433dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << " (1) It is not explicitly declared in device manifest;" << std::endl 434dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << " (2) PRODUCT_ENFORCE_VINTF_MANIFEST is set to true;" << std::endl 435dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << " (3) PRODUCT_SHIPPING_API_LEVEL is undefined." << std::endl 436dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << "Assuming 'unspecified' Shipping FCM Version. " << std::endl 437dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << "To remove this warning, define 'level' attribute in device manifest." 438dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << std::endl; 439dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return true; 440dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 4419aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong 442dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong Level getLowestFcmVersion(const CompatibilityMatrices& matrices) { 443dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong Level ret = Level::UNSPECIFIED; 444dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong for (const auto& e : matrices) { 445ffcaf994fe9956e976d4c525038f39fa08e76e8aYifan Hong if (ret == Level::UNSPECIFIED || ret > e.object.level()) { 446ffcaf994fe9956e976d4c525038f39fa08e76e8aYifan Hong ret = e.object.level(); 447dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 448dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 449dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return ret; 450dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 451dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 452dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong bool assembleCompatibilityMatrix(CompatibilityMatrices* matrices) { 453dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong std::string error; 454dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong CompatibilityMatrix* matrix = nullptr; 455dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong std::unique_ptr<HalManifest> checkManifest; 456ffcaf994fe9956e976d4c525038f39fa08e76e8aYifan Hong if (matrices->front().object.mType == SchemaType::DEVICE) { 457ffcaf994fe9956e976d4c525038f39fa08e76e8aYifan Hong matrix = &matrices->front().object; 458feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong 459feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong auto vndkVersion = base::Trim(getEnv("REQUIRED_VNDK_VERSION")); 460feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong if (!vndkVersion.empty()) { 461feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong auto& valueInMatrix = matrix->device.mVendorNdk; 462feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong if (!valueInMatrix.version().empty() && valueInMatrix.version() != vndkVersion) { 463feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong std::cerr << "Hard-coded <vendor-ndk> version in device compatibility matrix (" 464feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong << matrices->front().name << "), '" << valueInMatrix.version() 465feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong << "', does not match value inferred " 466feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong << "from BOARD_VNDK_VERSION '" << vndkVersion << "'" << std::endl; 467feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong return false; 468feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong } 469feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong valueInMatrix = VendorNdk{std::move(vndkVersion)}; 470feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong } 471a28729e759ec4041d8c53d365b690b0782ea8b03Yifan Hong 472a28729e759ec4041d8c53d365b690b0782ea8b03Yifan Hong for (auto&& v : getEnvList("BOARD_SYSTEMSDK_VERSIONS")) { 473a28729e759ec4041d8c53d365b690b0782ea8b03Yifan Hong matrix->device.mSystemSdk.mVersions.emplace(std::move(v)); 474a28729e759ec4041d8c53d365b690b0782ea8b03Yifan Hong } 475dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 476dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 477ffcaf994fe9956e976d4c525038f39fa08e76e8aYifan Hong if (matrices->front().object.mType == SchemaType::FRAMEWORK) { 478dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong Level deviceLevel = Level::UNSPECIFIED; 4798302cea08dea5238cbc4d2637ff90319480971aeYifan Hong if (mCheckFile != nullptr) { 480dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong checkManifest = std::make_unique<HalManifest>(); 481947570619d88bc6b9ca87f567943987f70a3905aYifan Hong if (!gHalManifestConverter(checkManifest.get(), read(*mCheckFile), &error)) { 482947570619d88bc6b9ca87f567943987f70a3905aYifan Hong std::cerr << "Cannot parse check file as a HAL manifest: " << error 483947570619d88bc6b9ca87f567943987f70a3905aYifan Hong << std::endl; 484dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return false; 485dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 486dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong deviceLevel = checkManifest->level(); 487dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 488dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 489dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong if (deviceLevel == Level::UNSPECIFIED) { 490dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong // For GSI build, legacy devices that do not have a HAL manifest, 491dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong // and devices in development, merge all compatibility matrices. 492dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong deviceLevel = getLowestFcmVersion(*matrices); 493dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 494dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 4959295851019e7f8c4ecec7fa07ca5c9d7f0278ffeYifan Hong matrix = CompatibilityMatrix::combine(deviceLevel, matrices, &error); 4969295851019e7f8c4ecec7fa07ca5c9d7f0278ffeYifan Hong if (matrix == nullptr) { 4979295851019e7f8c4ecec7fa07ca5c9d7f0278ffeYifan Hong std::cerr << error << std::endl; 4989295851019e7f8c4ecec7fa07ca5c9d7f0278ffeYifan Hong return false; 499dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 500dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 501e88e16721117aaf97548bebbffd6c8ea81b681efYifan Hong if (!assembleFrameworkCompatibilityMatrixKernels(matrix)) { 502e88e16721117aaf97548bebbffd6c8ea81b681efYifan Hong return false; 50379efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong } 504e88e16721117aaf97548bebbffd6c8ea81b681efYifan Hong 505321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong // Add PLATFORM_SEPOLICY_* to sepolicy.sepolicy-version. Remove dupes. 506321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong std::set<Version> sepolicyVersions; 507321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong auto sepolicyVersionStrings = getEnvList("PLATFORM_SEPOLICY_COMPAT_VERSIONS"); 508321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong auto currentSepolicyVersionString = getEnv("PLATFORM_SEPOLICY_VERSION"); 509321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong if (!currentSepolicyVersionString.empty()) { 510321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong sepolicyVersionStrings.push_back(currentSepolicyVersionString); 511321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong } 512321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong for (auto&& s : sepolicyVersionStrings) { 513321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong Version v; 514321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong if (!parse(s, &v)) { 515321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong std::cerr << "Error: unknown sepolicy version '" << s << "' specified by " 516321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong << (s == currentSepolicyVersionString 517321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong ? "PLATFORM_SEPOLICY_VERSION" 518321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong : "PLATFORM_SEPOLICY_COMPAT_VERSIONS") 519321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong << "."; 520321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong return false; 521321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong } 522321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong sepolicyVersions.insert(v); 523321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong } 524321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong for (auto&& v : sepolicyVersions) { 525321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong matrix->framework.mSepolicy.mSepolicyVersionRanges.emplace_back(v.majorVer, 526321ee222deb2c2419461dac7cfeca1686c68b34dYifan Hong v.minorVer); 5277f6c00c77c755f4efef49e5371058470a461193fYifan Hong } 528f4135016f2c735ac1bf3c50730bb66aa2b8e385fYifan Hong 529f7e8b1bc78ce6a2981ebd4b1a3031b8a0fe3c726Yifan Hong getFlagIfUnset("POLICYVERS", &matrix->framework.mSepolicy.mKernelSepolicyVersion, 530f7e8b1bc78ce6a2981ebd4b1a3031b8a0fe3c726Yifan Hong deviceLevel == Level::UNSPECIFIED /* log */); 531f7e8b1bc78ce6a2981ebd4b1a3031b8a0fe3c726Yifan Hong getFlagIfUnset("FRAMEWORK_VBMETA_VERSION", &matrix->framework.mAvbMetaVersion, 532f7e8b1bc78ce6a2981ebd4b1a3031b8a0fe3c726Yifan Hong deviceLevel == Level::UNSPECIFIED /* log */); 533dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 534dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong out() << "<!--" << std::endl; 535dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong out() << " Input:" << std::endl; 536ddae77eaca3f1a79398033c8a53ce2d57875a27bYifan Hong for (const auto& e : *matrices) { 537ffcaf994fe9956e976d4c525038f39fa08e76e8aYifan Hong if (!e.name.empty()) { 5384f67f3bf621fa4162e07bd7d015b81e915ad4d44Yifan Hong out() << " " << base::Basename(e.name) << std::endl; 539ddae77eaca3f1a79398033c8a53ce2d57875a27bYifan Hong } 540dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 541dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong out() << "-->" << std::endl; 542a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong } 543a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong out() << gCompatibilityMatrixConverter(*matrix, mSerializeFlags); 5449aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong out().flush(); 545a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong 5469adf115f40240d1f8bfd0266c2445f7a9b3e0262Yifan Hong if (checkManifest != nullptr && !checkDualFile(*checkManifest, *matrix)) { 547dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return false; 5489aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong } 5499aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong 5509aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong return true; 5519aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong } 5529aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong 553bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong enum AssembleStatus { SUCCESS, FAIL_AND_EXIT, TRY_NEXT }; 554bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong template <typename Schema, typename AssembleFunc> 555bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong AssembleStatus tryAssemble(const XmlConverter<Schema>& converter, const std::string& schemaName, 556947570619d88bc6b9ca87f567943987f70a3905aYifan Hong AssembleFunc assemble, std::string* error) { 557dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong Schemas<Schema> schemas; 558bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong Schema schema; 559947570619d88bc6b9ca87f567943987f70a3905aYifan Hong if (!converter(&schema, read(mInFiles.front().stream()), error)) { 560bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong return TRY_NEXT; 561bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong } 562bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong auto firstType = schema.type(); 563aa219f5a7792ebff4db38c60f8f08f9ab44b2586Yifan Hong schemas.emplace_back(mInFiles.front().name(), std::move(schema)); 564dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 565bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong for (auto it = mInFiles.begin() + 1; it != mInFiles.end(); ++it) { 566bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong Schema additionalSchema; 567aa219f5a7792ebff4db38c60f8f08f9ab44b2586Yifan Hong const std::string& fileName = it->name(); 568947570619d88bc6b9ca87f567943987f70a3905aYifan Hong if (!converter(&additionalSchema, read(it->stream()), error)) { 569dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong std::cerr << "File \"" << fileName << "\" is not a valid " << firstType << " " 570dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << schemaName << " (but the first file is a valid " << firstType << " " 571947570619d88bc6b9ca87f567943987f70a3905aYifan Hong << schemaName << "). Error: " << *error << std::endl; 572bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong return FAIL_AND_EXIT; 573bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong } 574bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong if (additionalSchema.type() != firstType) { 575dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong std::cerr << "File \"" << fileName << "\" is a " << additionalSchema.type() << " " 576dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << schemaName << " (but a " << firstType << " " << schemaName 577dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << " is expected)." << std::endl; 578eb14e3013ea11b3d47d40fa860f16345c607fef6Yifan Hong return FAIL_AND_EXIT; 579eb14e3013ea11b3d47d40fa860f16345c607fef6Yifan Hong } 580dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 581dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong schemas.emplace_back(fileName, std::move(additionalSchema)); 582bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong } 583dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return assemble(&schemas) ? SUCCESS : FAIL_AND_EXIT; 584bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong } 585bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong 5868302cea08dea5238cbc4d2637ff90319480971aeYifan Hong bool assemble() override { 587bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong using std::placeholders::_1; 588bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong if (mInFiles.empty()) { 5899aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong std::cerr << "Missing input file." << std::endl; 5909aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong return false; 5919aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong } 5929aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong 593947570619d88bc6b9ca87f567943987f70a3905aYifan Hong std::string manifestError; 594bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong auto status = tryAssemble(gHalManifestConverter, "manifest", 595947570619d88bc6b9ca87f567943987f70a3905aYifan Hong std::bind(&AssembleVintfImpl::assembleHalManifest, this, _1), 596947570619d88bc6b9ca87f567943987f70a3905aYifan Hong &manifestError); 597bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong if (status == SUCCESS) return true; 598bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong if (status == FAIL_AND_EXIT) return false; 5999aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong 600bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong resetInFiles(); 6014650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong 602947570619d88bc6b9ca87f567943987f70a3905aYifan Hong std::string matrixError; 603bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong status = tryAssemble(gCompatibilityMatrixConverter, "compatibility matrix", 604947570619d88bc6b9ca87f567943987f70a3905aYifan Hong std::bind(&AssembleVintfImpl::assembleCompatibilityMatrix, this, _1), 605947570619d88bc6b9ca87f567943987f70a3905aYifan Hong &matrixError); 606bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong if (status == SUCCESS) return true; 607bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong if (status == FAIL_AND_EXIT) return false; 6084d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 609959ee1bf8b922980542f72ce9ad1929fc7d8b55cYifan Hong std::cerr << "Input file has unknown format." << std::endl 610947570619d88bc6b9ca87f567943987f70a3905aYifan Hong << "Error when attempting to convert to manifest: " << manifestError << std::endl 611947570619d88bc6b9ca87f567943987f70a3905aYifan Hong << "Error when attempting to convert to compatibility matrix: " << matrixError 612947570619d88bc6b9ca87f567943987f70a3905aYifan Hong << std::endl; 613959ee1bf8b922980542f72ce9ad1929fc7d8b55cYifan Hong return false; 6144d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong } 6159aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong 6168302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::ostream& setOutputStream(Ostream&& out) override { 6178302cea08dea5238cbc4d2637ff90319480971aeYifan Hong mOutRef = std::move(out); 6188302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return *mOutRef; 6199aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong } 6209aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong 6218302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::istream& addInputStream(const std::string& name, Istream&& in) override { 6228302cea08dea5238cbc4d2637ff90319480971aeYifan Hong auto it = mInFiles.emplace(mInFiles.end(), name, std::move(in)); 6238302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return it->stream(); 6248302cea08dea5238cbc4d2637ff90319480971aeYifan Hong } 6258302cea08dea5238cbc4d2637ff90319480971aeYifan Hong 6268302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::istream& setCheckInputStream(Istream&& in) override { 6278302cea08dea5238cbc4d2637ff90319480971aeYifan Hong mCheckFile = std::move(in); 6288302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return *mCheckFile; 6299aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong } 6309aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong 631fb9e8b655e67031c156687eeb4e561c976d04015Yifan Hong bool hasKernelVersion(const KernelVersion& kernelVer) const override { 6328302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return mKernels.find(kernelVer) != mKernels.end(); 6338302cea08dea5238cbc4d2637ff90319480971aeYifan Hong } 6348302cea08dea5238cbc4d2637ff90319480971aeYifan Hong 635fb9e8b655e67031c156687eeb4e561c976d04015Yifan Hong std::istream& addKernelConfigInputStream(const KernelVersion& kernelVer, 636fb9e8b655e67031c156687eeb4e561c976d04015Yifan Hong const std::string& name, Istream&& in) override { 6378302cea08dea5238cbc4d2637ff90319480971aeYifan Hong auto&& kernel = mKernels[kernelVer]; 6388302cea08dea5238cbc4d2637ff90319480971aeYifan Hong auto it = kernel.emplace(kernel.end(), name, std::move(in)); 6398302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return it->stream(); 6409aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong } 6419aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong 642bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong void resetInFiles() { 643bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong for (auto& inFile : mInFiles) { 644aa219f5a7792ebff4db38c60f8f08f9ab44b2586Yifan Hong inFile.stream().clear(); 645aa219f5a7792ebff4db38c60f8f08f9ab44b2586Yifan Hong inFile.stream().seekg(0); 646bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong } 647bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong } 648bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong 6498302cea08dea5238cbc4d2637ff90319480971aeYifan Hong void setOutputMatrix() override { mOutputMatrix = true; } 6509aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong 6518302cea08dea5238cbc4d2637ff90319480971aeYifan Hong bool setHalsOnly() override { 652a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong if (mSerializeFlags) return false; 653a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong mSerializeFlags |= SerializeFlag::HALS_ONLY; 654a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong return true; 655a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong } 656a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong 6578302cea08dea5238cbc4d2637ff90319480971aeYifan Hong bool setNoHals() override { 658a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong if (mSerializeFlags) return false; 659a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong mSerializeFlags |= SerializeFlag::NO_HALS; 660a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong return true; 661a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong } 662a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong 6639aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong private: 664aa219f5a7792ebff4db38c60f8f08f9ab44b2586Yifan Hong std::vector<NamedIstream> mInFiles; 6658302cea08dea5238cbc4d2637ff90319480971aeYifan Hong Ostream mOutRef; 6668302cea08dea5238cbc4d2637ff90319480971aeYifan Hong Istream mCheckFile; 6679aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong bool mOutputMatrix = false; 668a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong SerializeFlags mSerializeFlags = SerializeFlag::EVERYTHING; 669fb9e8b655e67031c156687eeb4e561c976d04015Yifan Hong std::map<KernelVersion, std::vector<NamedIstream>> mKernels; 6708302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::map<std::string, std::string> mFakeEnv; 6714d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong}; 6724d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 6738302cea08dea5238cbc4d2637ff90319480971aeYifan Hongbool AssembleVintf::openOutFile(const std::string& path) { 6748302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return static_cast<std::ofstream&>(setOutputStream(std::make_unique<std::ofstream>(path))) 6758302cea08dea5238cbc4d2637ff90319480971aeYifan Hong .is_open(); 6764d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong} 6774d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 6788302cea08dea5238cbc4d2637ff90319480971aeYifan Hongbool AssembleVintf::openInFile(const std::string& path) { 6798302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return static_cast<std::ifstream&>(addInputStream(path, std::make_unique<std::ifstream>(path))) 6808302cea08dea5238cbc4d2637ff90319480971aeYifan Hong .is_open(); 6818302cea08dea5238cbc4d2637ff90319480971aeYifan Hong} 682a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong 6838302cea08dea5238cbc4d2637ff90319480971aeYifan Hongbool AssembleVintf::openCheckFile(const std::string& path) { 6848302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return static_cast<std::ifstream&>(setCheckInputStream(std::make_unique<std::ifstream>(path))) 6858302cea08dea5238cbc4d2637ff90319480971aeYifan Hong .is_open(); 6868302cea08dea5238cbc4d2637ff90319480971aeYifan Hong} 687a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong 6888302cea08dea5238cbc4d2637ff90319480971aeYifan Hongbool AssembleVintf::addKernel(const std::string& kernelArg) { 689b83e56bbf1b2aba92f69f63d1e434be512193b5bYifan Hong auto tokens = base::Split(kernelArg, ":"); 6908302cea08dea5238cbc4d2637ff90319480971aeYifan Hong if (tokens.size() <= 1) { 6918302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::cerr << "Unrecognized --kernel option '" << kernelArg << "'" << std::endl; 6928302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return false; 6938302cea08dea5238cbc4d2637ff90319480971aeYifan Hong } 694fb9e8b655e67031c156687eeb4e561c976d04015Yifan Hong KernelVersion kernelVer; 6958302cea08dea5238cbc4d2637ff90319480971aeYifan Hong if (!parse(tokens.front(), &kernelVer)) { 6968302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::cerr << "Unrecognized kernel version '" << tokens.front() << "'" << std::endl; 6978302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return false; 6988302cea08dea5238cbc4d2637ff90319480971aeYifan Hong } 6998302cea08dea5238cbc4d2637ff90319480971aeYifan Hong if (hasKernelVersion(kernelVer)) { 7008302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::cerr << "Multiple --kernel for " << kernelVer << " is specified." << std::endl; 7018302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return false; 7028302cea08dea5238cbc4d2637ff90319480971aeYifan Hong } 7038302cea08dea5238cbc4d2637ff90319480971aeYifan Hong for (auto it = tokens.begin() + 1; it != tokens.end(); ++it) { 7048302cea08dea5238cbc4d2637ff90319480971aeYifan Hong bool opened = 7058302cea08dea5238cbc4d2637ff90319480971aeYifan Hong static_cast<std::ifstream&>( 7068302cea08dea5238cbc4d2637ff90319480971aeYifan Hong addKernelConfigInputStream(kernelVer, *it, std::make_unique<std::ifstream>(*it))) 7078302cea08dea5238cbc4d2637ff90319480971aeYifan Hong .is_open(); 7088302cea08dea5238cbc4d2637ff90319480971aeYifan Hong if (!opened) { 7098302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::cerr << "Cannot open file '" << *it << "'." << std::endl; 7108302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return false; 7114d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong } 7124d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong } 7138302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return true; 7148302cea08dea5238cbc4d2637ff90319480971aeYifan Hong} 7154d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 7168302cea08dea5238cbc4d2637ff90319480971aeYifan Hongstd::unique_ptr<AssembleVintf> AssembleVintf::newInstance() { 7178302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return std::make_unique<AssembleVintfImpl>(); 7184d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong} 7198302cea08dea5238cbc4d2637ff90319480971aeYifan Hong 7208302cea08dea5238cbc4d2637ff90319480971aeYifan Hong} // namespace vintf 7218302cea08dea5238cbc4d2637ff90319480971aeYifan Hong} // namespace android 722