AssembleVintf.cpp revision fb9e8b655e67031c156687eeb4e561c976d04015
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 /** 108eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong * Set *out to environment variable if *out is not a dummy value (i.e. default constructed). 109eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong */ 110eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong template <typename T> 111f7e8b1bc78ce6a2981ebd4b1a3031b8a0fe3c726Yifan Hong bool getFlagIfUnset(const std::string& envKey, T* out, bool log = true) const { 112eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong bool hasExistingValue = !(*out == T{}); 113eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong 114eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong bool hasEnvValue = false; 115eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong T envValue; 1168302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::string envStrValue = getEnv(envKey); 1178302cea08dea5238cbc4d2637ff90319480971aeYifan Hong if (!envStrValue.empty()) { 1188302cea08dea5238cbc4d2637ff90319480971aeYifan Hong if (!parse(envStrValue, &envValue)) { 119f7e8b1bc78ce6a2981ebd4b1a3031b8a0fe3c726Yifan Hong if (log) { 120f7e8b1bc78ce6a2981ebd4b1a3031b8a0fe3c726Yifan Hong std::cerr << "Cannot parse " << envValue << "." << std::endl; 121f7e8b1bc78ce6a2981ebd4b1a3031b8a0fe3c726Yifan Hong } 122eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong return false; 123eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong } 124eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong hasEnvValue = true; 125eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong } 126eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong 127eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong if (hasExistingValue) { 128f7e8b1bc78ce6a2981ebd4b1a3031b8a0fe3c726Yifan Hong if (hasEnvValue && log) { 129eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong std::cerr << "Warning: cannot override existing value " << *out << " with " 130eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong << envKey << " (which is " << envValue << ")." << std::endl; 131eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong } 132eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong return false; 133eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong } 134eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong if (!hasEnvValue) { 135f7e8b1bc78ce6a2981ebd4b1a3031b8a0fe3c726Yifan Hong if (log) { 136f7e8b1bc78ce6a2981ebd4b1a3031b8a0fe3c726Yifan Hong std::cerr << "Warning: " << envKey << " is not specified. Default to " << T{} << "." 137f7e8b1bc78ce6a2981ebd4b1a3031b8a0fe3c726Yifan Hong << std::endl; 138f7e8b1bc78ce6a2981ebd4b1a3031b8a0fe3c726Yifan Hong } 139eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong return false; 140eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong } 141eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong *out = envValue; 142eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong return true; 143eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong } 144eff04664c85090494c60a2bf95cc23b0b24ae21cYifan Hong 1458302cea08dea5238cbc4d2637ff90319480971aeYifan Hong bool getBooleanFlag(const std::string& key) const { return getEnv(key) == std::string("true"); } 146dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 1478302cea08dea5238cbc4d2637ff90319480971aeYifan Hong size_t getIntegerFlag(const std::string& key, size_t defaultValue = 0) const { 1488302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::string envValue = getEnv(key); 149dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong if (envValue.empty()) { 150dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return defaultValue; 151dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 152dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong size_t value; 153dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong if (!base::ParseUint(envValue, &value)) { 154dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong std::cerr << "Error: " << key << " must be a number." << std::endl; 155dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return defaultValue; 156dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 157dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return value; 158dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 159dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 1604650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong static std::string read(std::basic_istream<char>& is) { 1614650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong std::stringstream ss; 1624650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong ss << is.rdbuf(); 1634650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong return ss.str(); 1644650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong } 1654650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong 1669a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong static bool isCommonConfig(const std::string& path) { 1679a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong return ::android::base::Basename(path) == gBaseConfig; 1689a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong } 1699a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong 170079ec2492c275b9041584f2f07605982682c559cYifan Hong // nullptr on any error, otherwise the condition. 171079ec2492c275b9041584f2f07605982682c559cYifan Hong static Condition generateCondition(const std::string& path) { 172079ec2492c275b9041584f2f07605982682c559cYifan Hong std::string fname = ::android::base::Basename(path); 173079ec2492c275b9041584f2f07605982682c559cYifan Hong if (fname.size() <= gConfigPrefix.size() + gConfigSuffix.size() || 174079ec2492c275b9041584f2f07605982682c559cYifan Hong !std::equal(gConfigPrefix.begin(), gConfigPrefix.end(), fname.begin()) || 175079ec2492c275b9041584f2f07605982682c559cYifan Hong !std::equal(gConfigSuffix.rbegin(), gConfigSuffix.rend(), fname.rbegin())) { 176079ec2492c275b9041584f2f07605982682c559cYifan Hong return nullptr; 177079ec2492c275b9041584f2f07605982682c559cYifan Hong } 178079ec2492c275b9041584f2f07605982682c559cYifan Hong 179079ec2492c275b9041584f2f07605982682c559cYifan Hong std::string sub = fname.substr(gConfigPrefix.size(), 180079ec2492c275b9041584f2f07605982682c559cYifan Hong fname.size() - gConfigPrefix.size() - gConfigSuffix.size()); 181079ec2492c275b9041584f2f07605982682c559cYifan Hong if (sub.empty()) { 182079ec2492c275b9041584f2f07605982682c559cYifan Hong return nullptr; // should not happen 183079ec2492c275b9041584f2f07605982682c559cYifan Hong } 184079ec2492c275b9041584f2f07605982682c559cYifan Hong for (size_t i = 0; i < sub.size(); ++i) { 185079ec2492c275b9041584f2f07605982682c559cYifan Hong if (sub[i] == '-') { 186079ec2492c275b9041584f2f07605982682c559cYifan Hong sub[i] = '_'; 187079ec2492c275b9041584f2f07605982682c559cYifan Hong continue; 188079ec2492c275b9041584f2f07605982682c559cYifan Hong } 189079ec2492c275b9041584f2f07605982682c559cYifan Hong if (isalnum(sub[i])) { 190079ec2492c275b9041584f2f07605982682c559cYifan Hong sub[i] = toupper(sub[i]); 191079ec2492c275b9041584f2f07605982682c559cYifan Hong continue; 192079ec2492c275b9041584f2f07605982682c559cYifan Hong } 193079ec2492c275b9041584f2f07605982682c559cYifan Hong std::cerr << "'" << fname << "' (in " << path 194079ec2492c275b9041584f2f07605982682c559cYifan Hong << ") is not a valid kernel config file name. Must match regex: " 195079ec2492c275b9041584f2f07605982682c559cYifan Hong << "android-base(-[0-9a-zA-Z-]+)?\\.cfg" << std::endl; 196079ec2492c275b9041584f2f07605982682c559cYifan Hong return nullptr; 197079ec2492c275b9041584f2f07605982682c559cYifan Hong } 198079ec2492c275b9041584f2f07605982682c559cYifan Hong sub.insert(0, "CONFIG_"); 199079ec2492c275b9041584f2f07605982682c559cYifan Hong return std::make_unique<KernelConfig>(std::move(sub), Tristate::YES); 200079ec2492c275b9041584f2f07605982682c559cYifan Hong } 201079ec2492c275b9041584f2f07605982682c559cYifan Hong 2028302cea08dea5238cbc4d2637ff90319480971aeYifan Hong static bool parseFileForKernelConfigs(std::basic_istream<char>& stream, 2038302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::vector<KernelConfig>* out) { 20402e94004a6d35d20af7df1ea9c66c5b65e4bd9c6Yifan Hong KernelConfigParser parser(true /* processComments */, true /* relaxedFormat */); 2058302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::string content = read(stream); 20679efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong status_t err = parser.process(content.c_str(), content.size()); 20779efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong if (err != OK) { 208ae53a0e6d3f605cc124009cb0172f152f69417a4Yifan Hong std::cerr << parser.error(); 20979efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong return false; 21079efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong } 21179efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong err = parser.finish(); 21279efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong if (err != OK) { 213ae53a0e6d3f605cc124009cb0172f152f69417a4Yifan Hong std::cerr << parser.error(); 21479efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong return false; 21579efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong } 21679efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong 21779efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong for (auto& configPair : parser.configs()) { 21879efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong out->push_back({}); 21979efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong KernelConfig& config = out->back(); 22079efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong config.first = std::move(configPair.first); 22179efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong if (!parseKernelConfigTypedValue(configPair.second, &config.second)) { 22279efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong std::cerr << "Unknown value type for key = '" << config.first << "', value = '" 22379efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong << configPair.second << "'\n"; 22479efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong return false; 22579efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong } 22679efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong } 22779efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong return true; 22879efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong } 22979efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong 2308302cea08dea5238cbc4d2637ff90319480971aeYifan Hong static bool parseFilesForKernelConfigs(std::vector<NamedIstream>* streams, 2319a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong std::vector<ConditionedConfig>* out) { 2329a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong out->clear(); 2339a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong ConditionedConfig commonConfig; 2349a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong bool foundCommonConfig = false; 2350bef86826065d9cfdad3139ea186a98524cf2eddSteve Muckle bool ret = true; 2368302cea08dea5238cbc4d2637ff90319480971aeYifan Hong 2378302cea08dea5238cbc4d2637ff90319480971aeYifan Hong for (auto& namedStream : *streams) { 2388302cea08dea5238cbc4d2637ff90319480971aeYifan Hong if (isCommonConfig(namedStream.name())) { 2398302cea08dea5238cbc4d2637ff90319480971aeYifan Hong ret &= parseFileForKernelConfigs(namedStream.stream(), &commonConfig.second); 2409a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong foundCommonConfig = true; 2419a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong } else { 2428302cea08dea5238cbc4d2637ff90319480971aeYifan Hong Condition condition = generateCondition(namedStream.name()); 243079ec2492c275b9041584f2f07605982682c559cYifan Hong ret &= (condition != nullptr); 244079ec2492c275b9041584f2f07605982682c559cYifan Hong 2459a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong std::vector<KernelConfig> kernelConfigs; 2468302cea08dea5238cbc4d2637ff90319480971aeYifan Hong if ((ret &= parseFileForKernelConfigs(namedStream.stream(), &kernelConfigs))) 247079ec2492c275b9041584f2f07605982682c559cYifan Hong out->emplace_back(std::move(condition), std::move(kernelConfigs)); 2489a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong } 2490bef86826065d9cfdad3139ea186a98524cf2eddSteve Muckle } 2509a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong 2519a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong if (!foundCommonConfig) { 2528302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::cerr << "No android-base.cfg is found in these paths:" << std::endl; 2538302cea08dea5238cbc4d2637ff90319480971aeYifan Hong for (auto& namedStream : *streams) { 2548302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::cerr << " " << namedStream.name() << std::endl; 2558302cea08dea5238cbc4d2637ff90319480971aeYifan Hong } 2569a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong } 2579a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong ret &= foundCommonConfig; 2589a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong // first element is always common configs (no conditions). 2599a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong out->insert(out->begin(), std::move(commonConfig)); 2600bef86826065d9cfdad3139ea186a98524cf2eddSteve Muckle return ret; 2610bef86826065d9cfdad3139ea186a98524cf2eddSteve Muckle } 2620bef86826065d9cfdad3139ea186a98524cf2eddSteve Muckle 2638302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::basic_ostream<char>& out() const { return mOutRef == nullptr ? std::cout : *mOutRef; } 2649aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong 265dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong template <typename S> 266ffcaf994fe9956e976d4c525038f39fa08e76e8aYifan Hong using Schemas = std::vector<Named<S>>; 267dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong using HalManifests = Schemas<HalManifest>; 268dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong using CompatibilityMatrices = Schemas<CompatibilityMatrix>; 269dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 270dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong bool assembleHalManifest(HalManifests* halManifests) { 2714650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong std::string error; 272ffcaf994fe9956e976d4c525038f39fa08e76e8aYifan Hong HalManifest* halManifest = &halManifests->front().object; 273dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong for (auto it = halManifests->begin() + 1; it != halManifests->end(); ++it) { 274ffcaf994fe9956e976d4c525038f39fa08e76e8aYifan Hong const std::string& path = it->name; 275ffcaf994fe9956e976d4c525038f39fa08e76e8aYifan Hong HalManifest& halToAdd = it->object; 276dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 277dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong if (halToAdd.level() != Level::UNSPECIFIED) { 278dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong if (halManifest->level() == Level::UNSPECIFIED) { 279dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong halManifest->mLevel = halToAdd.level(); 280dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } else if (halManifest->level() != halToAdd.level()) { 281dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong std::cerr << "Inconsistent FCM Version in HAL manifests:" << std::endl 282ffcaf994fe9956e976d4c525038f39fa08e76e8aYifan Hong << " File '" << halManifests->front().name << "' has level " 283dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << halManifest->level() << std::endl 284dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << " File '" << path << "' has level " << halToAdd.level() 285dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << std::endl; 286dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return false; 287dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 288dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 289dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 290ea25dd45961fc0b23ae9ba602c6d090590aa8241Yifan Hong if (!halManifest->addAllHals(&halToAdd, &error)) { 291dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong std::cerr << "File \"" << path << "\" cannot be added: conflict on HAL \"" << error 292dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << "\" with an existing HAL. See <hal> with the same name " 293dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << "in previously parsed files or previously declared in this file." 294dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << std::endl; 295dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return false; 296dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 297dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 2984d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 2999aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong if (halManifest->mType == SchemaType::DEVICE) { 3009aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong if (!getFlag("BOARD_SEPOLICY_VERS", &halManifest->device.mSepolicyVersion)) { 3019aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong return false; 3024d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong } 303dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong if (!setDeviceFcmVersion(halManifest)) { 304dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return false; 305dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 3069aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong } 3074d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 308feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong if (halManifest->mType == SchemaType::FRAMEWORK) { 309a28729e759ec4041d8c53d365b690b0782ea8b03Yifan Hong for (auto&& v : getEnvList("PROVIDED_VNDK_VERSIONS")) { 310a28729e759ec4041d8c53d365b690b0782ea8b03Yifan Hong halManifest->framework.mVendorNdks.emplace_back(std::move(v)); 311a28729e759ec4041d8c53d365b690b0782ea8b03Yifan Hong } 312a28729e759ec4041d8c53d365b690b0782ea8b03Yifan Hong 3138b8492bcc42b79d1a95b02808dfbb654e2e31690Yifan Hong for (auto&& v : getEnvList("PLATFORM_SYSTEMSDK_VERSIONS")) { 314a28729e759ec4041d8c53d365b690b0782ea8b03Yifan Hong halManifest->framework.mSystemSdk.mVersions.emplace(std::move(v)); 315feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong } 316feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong } 317feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong 3189aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong if (mOutputMatrix) { 3199aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong CompatibilityMatrix generatedMatrix = halManifest->generateCompatibleMatrix(); 3209aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong if (!halManifest->checkCompatibility(generatedMatrix, &error)) { 3219aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong std::cerr << "FATAL ERROR: cannot generate a compatible matrix: " << error 3229aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong << std::endl; 323a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong } 3249aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong out() << "<!-- \n" 3259aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong " Autogenerated skeleton compatibility matrix. \n" 3269aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong " Use with caution. Modify it to suit your needs.\n" 3279aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong " All HALs are set to optional.\n" 3289aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong " Many entries other than HALs are zero-filled and\n" 3299aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong " require human attention. \n" 3309aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong "-->\n" 331a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong << gCompatibilityMatrixConverter(generatedMatrix, mSerializeFlags); 3329aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong } else { 333a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong out() << gHalManifestConverter(*halManifest, mSerializeFlags); 3349aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong } 3359aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong out().flush(); 3369aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong 3378302cea08dea5238cbc4d2637ff90319480971aeYifan Hong if (mCheckFile != nullptr) { 3389aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong CompatibilityMatrix checkMatrix; 3398302cea08dea5238cbc4d2637ff90319480971aeYifan Hong if (!gCompatibilityMatrixConverter(&checkMatrix, read(*mCheckFile))) { 3409aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong std::cerr << "Cannot parse check file as a compatibility matrix: " 3419aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong << gCompatibilityMatrixConverter.lastError() << std::endl; 3429aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong return false; 3434650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong } 3449aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong if (!halManifest->checkCompatibility(checkMatrix, &error)) { 3459aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong std::cerr << "Not compatible: " << error << std::endl; 3469aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong return false; 3479aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong } 3489aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong } 3494650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong 3509aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong return true; 3519aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong } 3529aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong 353e88e16721117aaf97548bebbffd6c8ea81b681efYifan Hong bool assembleFrameworkCompatibilityMatrixKernels(CompatibilityMatrix* matrix) { 3548302cea08dea5238cbc4d2637ff90319480971aeYifan Hong for (auto& pair : mKernels) { 3559a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong std::vector<ConditionedConfig> conditionedConfigs; 3568302cea08dea5238cbc4d2637ff90319480971aeYifan Hong if (!parseFilesForKernelConfigs(&pair.second, &conditionedConfigs)) { 357e88e16721117aaf97548bebbffd6c8ea81b681efYifan Hong return false; 358e88e16721117aaf97548bebbffd6c8ea81b681efYifan Hong } 3599a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong for (ConditionedConfig& conditionedConfig : conditionedConfigs) { 360fb9e8b655e67031c156687eeb4e561c976d04015Yifan Hong MatrixKernel kernel(KernelVersion{pair.first}, std::move(conditionedConfig.second)); 361079ec2492c275b9041584f2f07605982682c559cYifan Hong if (conditionedConfig.first != nullptr) 362079ec2492c275b9041584f2f07605982682c559cYifan Hong kernel.mConditions.push_back(std::move(*conditionedConfig.first)); 363079ec2492c275b9041584f2f07605982682c559cYifan Hong matrix->framework.mKernels.push_back(std::move(kernel)); 3649a8b1a7cec9f39953001a2f113cb976ae73eb211Yifan Hong } 365e88e16721117aaf97548bebbffd6c8ea81b681efYifan Hong } 366e88e16721117aaf97548bebbffd6c8ea81b681efYifan Hong return true; 367e88e16721117aaf97548bebbffd6c8ea81b681efYifan Hong } 368e88e16721117aaf97548bebbffd6c8ea81b681efYifan Hong 369dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong bool setDeviceFcmVersion(HalManifest* manifest) { 370dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong size_t shippingApiLevel = getIntegerFlag("PRODUCT_SHIPPING_API_LEVEL"); 371dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 372dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong if (manifest->level() != Level::UNSPECIFIED) { 373dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return true; 374dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 375dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong if (!getBooleanFlag("PRODUCT_ENFORCE_VINTF_MANIFEST")) { 376dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong manifest->mLevel = Level::LEGACY; 377dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return true; 378dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 379dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong // TODO(b/70628538): Do not infer from Shipping API level. 380dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong if (shippingApiLevel) { 381dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong std::cerr << "Warning: Shipping FCM Version is inferred from Shipping API level. " 382dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << "Declare Shipping FCM Version in device manifest directly." << std::endl; 383afae198ce40f51b116c2540ca87f9157c3a56ea4Yifan Hong manifest->mLevel = details::convertFromApiLevel(shippingApiLevel); 384dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong if (manifest->mLevel == Level::UNSPECIFIED) { 385dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong std::cerr << "Error: Shipping FCM Version cannot be inferred from Shipping API " 386dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << "level " << shippingApiLevel << "." 387dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << "Declare Shipping FCM Version in device manifest directly." 388dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << std::endl; 389dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return false; 390dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 391dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return true; 392dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 393dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong // TODO(b/69638851): should be an error if Shipping API level is not defined. 394dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong // For now, just leave it empty; when framework compatibility matrix is built, 395dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong // lowest FCM Version is assumed. 396dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong std::cerr << "Warning: Shipping FCM Version cannot be inferred, because:" << std::endl 397dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << " (1) It is not explicitly declared in device manifest;" << std::endl 398dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << " (2) PRODUCT_ENFORCE_VINTF_MANIFEST is set to true;" << std::endl 399dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << " (3) PRODUCT_SHIPPING_API_LEVEL is undefined." << std::endl 400dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << "Assuming 'unspecified' Shipping FCM Version. " << std::endl 401dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << "To remove this warning, define 'level' attribute in device manifest." 402dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << std::endl; 403dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return true; 404dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 4059aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong 406dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong Level getLowestFcmVersion(const CompatibilityMatrices& matrices) { 407dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong Level ret = Level::UNSPECIFIED; 408dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong for (const auto& e : matrices) { 409ffcaf994fe9956e976d4c525038f39fa08e76e8aYifan Hong if (ret == Level::UNSPECIFIED || ret > e.object.level()) { 410ffcaf994fe9956e976d4c525038f39fa08e76e8aYifan Hong ret = e.object.level(); 411dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 412dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 413dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return ret; 414dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 415dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 416dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong bool assembleCompatibilityMatrix(CompatibilityMatrices* matrices) { 417dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong std::string error; 418dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong CompatibilityMatrix* matrix = nullptr; 419dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong std::unique_ptr<HalManifest> checkManifest; 420ffcaf994fe9956e976d4c525038f39fa08e76e8aYifan Hong if (matrices->front().object.mType == SchemaType::DEVICE) { 421ffcaf994fe9956e976d4c525038f39fa08e76e8aYifan Hong matrix = &matrices->front().object; 422feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong 423feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong auto vndkVersion = base::Trim(getEnv("REQUIRED_VNDK_VERSION")); 424feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong if (!vndkVersion.empty()) { 425feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong auto& valueInMatrix = matrix->device.mVendorNdk; 426feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong if (!valueInMatrix.version().empty() && valueInMatrix.version() != vndkVersion) { 427feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong std::cerr << "Hard-coded <vendor-ndk> version in device compatibility matrix (" 428feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong << matrices->front().name << "), '" << valueInMatrix.version() 429feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong << "', does not match value inferred " 430feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong << "from BOARD_VNDK_VERSION '" << vndkVersion << "'" << std::endl; 431feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong return false; 432feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong } 433feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong valueInMatrix = VendorNdk{std::move(vndkVersion)}; 434feb454ebc29f29ca7f5241130fac243e769436e2Yifan Hong } 435a28729e759ec4041d8c53d365b690b0782ea8b03Yifan Hong 436a28729e759ec4041d8c53d365b690b0782ea8b03Yifan Hong for (auto&& v : getEnvList("BOARD_SYSTEMSDK_VERSIONS")) { 437a28729e759ec4041d8c53d365b690b0782ea8b03Yifan Hong matrix->device.mSystemSdk.mVersions.emplace(std::move(v)); 438a28729e759ec4041d8c53d365b690b0782ea8b03Yifan Hong } 439dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 440dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 441ffcaf994fe9956e976d4c525038f39fa08e76e8aYifan Hong if (matrices->front().object.mType == SchemaType::FRAMEWORK) { 442dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong Level deviceLevel = Level::UNSPECIFIED; 4438302cea08dea5238cbc4d2637ff90319480971aeYifan Hong if (mCheckFile != nullptr) { 444dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong checkManifest = std::make_unique<HalManifest>(); 4458302cea08dea5238cbc4d2637ff90319480971aeYifan Hong if (!gHalManifestConverter(checkManifest.get(), read(*mCheckFile))) { 446dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong std::cerr << "Cannot parse check file as a HAL manifest: " 447dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << gHalManifestConverter.lastError() << std::endl; 448dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return false; 449dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 450dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong deviceLevel = checkManifest->level(); 451dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 452dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 453dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong if (deviceLevel == Level::UNSPECIFIED) { 454dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong // For GSI build, legacy devices that do not have a HAL manifest, 455dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong // and devices in development, merge all compatibility matrices. 456dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong deviceLevel = getLowestFcmVersion(*matrices); 457dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 458dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 459ddae77eaca3f1a79398033c8a53ce2d57875a27bYifan Hong if (deviceLevel == Level::UNSPECIFIED) { 460ddae77eaca3f1a79398033c8a53ce2d57875a27bYifan Hong // building empty.xml 461ffcaf994fe9956e976d4c525038f39fa08e76e8aYifan Hong matrix = &matrices->front().object; 462ddae77eaca3f1a79398033c8a53ce2d57875a27bYifan Hong } else { 463ddae77eaca3f1a79398033c8a53ce2d57875a27bYifan Hong matrix = CompatibilityMatrix::combine(deviceLevel, matrices, &error); 464ddae77eaca3f1a79398033c8a53ce2d57875a27bYifan Hong if (matrix == nullptr) { 465ddae77eaca3f1a79398033c8a53ce2d57875a27bYifan Hong std::cerr << error << std::endl; 466dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return false; 467dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 468dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 469dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 470e88e16721117aaf97548bebbffd6c8ea81b681efYifan Hong if (!assembleFrameworkCompatibilityMatrixKernels(matrix)) { 471e88e16721117aaf97548bebbffd6c8ea81b681efYifan Hong return false; 47279efa8a35e677cb8ac79041737e2700b0e50de15Yifan Hong } 473e88e16721117aaf97548bebbffd6c8ea81b681efYifan Hong 474f4135016f2c735ac1bf3c50730bb66aa2b8e385fYifan Hong // set sepolicy.sepolicy-version to BOARD_SEPOLICY_VERS when none is specified. 475f4135016f2c735ac1bf3c50730bb66aa2b8e385fYifan Hong std::vector<VersionRange>* sepolicyVrs = 476f4135016f2c735ac1bf3c50730bb66aa2b8e385fYifan Hong &matrix->framework.mSepolicy.mSepolicyVersionRanges; 477f4135016f2c735ac1bf3c50730bb66aa2b8e385fYifan Hong VersionRange sepolicyVr; 478f4135016f2c735ac1bf3c50730bb66aa2b8e385fYifan Hong if (!sepolicyVrs->empty()) sepolicyVr = sepolicyVrs->front(); 479f7e8b1bc78ce6a2981ebd4b1a3031b8a0fe3c726Yifan Hong if (getFlagIfUnset("BOARD_SEPOLICY_VERS", &sepolicyVr, 480f7e8b1bc78ce6a2981ebd4b1a3031b8a0fe3c726Yifan Hong deviceLevel == Level::UNSPECIFIED /* log */)) { 481f4135016f2c735ac1bf3c50730bb66aa2b8e385fYifan Hong *sepolicyVrs = {{sepolicyVr}}; 4827f6c00c77c755f4efef49e5371058470a461193fYifan Hong } 483f4135016f2c735ac1bf3c50730bb66aa2b8e385fYifan Hong 484f7e8b1bc78ce6a2981ebd4b1a3031b8a0fe3c726Yifan Hong getFlagIfUnset("POLICYVERS", &matrix->framework.mSepolicy.mKernelSepolicyVersion, 485f7e8b1bc78ce6a2981ebd4b1a3031b8a0fe3c726Yifan Hong deviceLevel == Level::UNSPECIFIED /* log */); 486f7e8b1bc78ce6a2981ebd4b1a3031b8a0fe3c726Yifan Hong getFlagIfUnset("FRAMEWORK_VBMETA_VERSION", &matrix->framework.mAvbMetaVersion, 487f7e8b1bc78ce6a2981ebd4b1a3031b8a0fe3c726Yifan Hong deviceLevel == Level::UNSPECIFIED /* log */); 488dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 489dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong out() << "<!--" << std::endl; 490dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong out() << " Input:" << std::endl; 491ddae77eaca3f1a79398033c8a53ce2d57875a27bYifan Hong for (const auto& e : *matrices) { 492ffcaf994fe9956e976d4c525038f39fa08e76e8aYifan Hong if (!e.name.empty()) { 4934f67f3bf621fa4162e07bd7d015b81e915ad4d44Yifan Hong out() << " " << base::Basename(e.name) << std::endl; 494ddae77eaca3f1a79398033c8a53ce2d57875a27bYifan Hong } 495dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong } 496dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong out() << "-->" << std::endl; 497a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong } 498a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong out() << gCompatibilityMatrixConverter(*matrix, mSerializeFlags); 4999aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong out().flush(); 500a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong 501dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong if (checkManifest != nullptr && getBooleanFlag("PRODUCT_ENFORCE_VINTF_MANIFEST") && 502dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong !checkManifest->checkCompatibility(*matrix, &error)) { 503dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong std::cerr << "Not compatible: " << error << std::endl; 504dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return false; 5059aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong } 5069aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong 5079aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong return true; 5089aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong } 5099aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong 510bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong enum AssembleStatus { SUCCESS, FAIL_AND_EXIT, TRY_NEXT }; 511bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong template <typename Schema, typename AssembleFunc> 512bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong AssembleStatus tryAssemble(const XmlConverter<Schema>& converter, const std::string& schemaName, 513bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong AssembleFunc assemble) { 514dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong Schemas<Schema> schemas; 515bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong Schema schema; 516aa219f5a7792ebff4db38c60f8f08f9ab44b2586Yifan Hong if (!converter(&schema, read(mInFiles.front().stream()))) { 517bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong return TRY_NEXT; 518bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong } 519bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong auto firstType = schema.type(); 520aa219f5a7792ebff4db38c60f8f08f9ab44b2586Yifan Hong schemas.emplace_back(mInFiles.front().name(), std::move(schema)); 521dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 522bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong for (auto it = mInFiles.begin() + 1; it != mInFiles.end(); ++it) { 523bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong Schema additionalSchema; 524aa219f5a7792ebff4db38c60f8f08f9ab44b2586Yifan Hong const std::string& fileName = it->name(); 525aa219f5a7792ebff4db38c60f8f08f9ab44b2586Yifan Hong if (!converter(&additionalSchema, read(it->stream()))) { 526dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong std::cerr << "File \"" << fileName << "\" is not a valid " << firstType << " " 527dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << schemaName << " (but the first file is a valid " << firstType << " " 528dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << schemaName << "). Error: " << converter.lastError() << std::endl; 529bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong return FAIL_AND_EXIT; 530bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong } 531bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong if (additionalSchema.type() != firstType) { 532dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong std::cerr << "File \"" << fileName << "\" is a " << additionalSchema.type() << " " 533dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << schemaName << " (but a " << firstType << " " << schemaName 534dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong << " is expected)." << std::endl; 535eb14e3013ea11b3d47d40fa860f16345c607fef6Yifan Hong return FAIL_AND_EXIT; 536eb14e3013ea11b3d47d40fa860f16345c607fef6Yifan Hong } 537dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong 538dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong schemas.emplace_back(fileName, std::move(additionalSchema)); 539bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong } 540dbe9db35fe506f6547d33b44ec5e20b70bf343c2Yifan Hong return assemble(&schemas) ? SUCCESS : FAIL_AND_EXIT; 541bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong } 542bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong 5438302cea08dea5238cbc4d2637ff90319480971aeYifan Hong bool assemble() override { 544bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong using std::placeholders::_1; 545bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong if (mInFiles.empty()) { 5469aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong std::cerr << "Missing input file." << std::endl; 5479aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong return false; 5489aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong } 5499aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong 550bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong auto status = tryAssemble(gHalManifestConverter, "manifest", 5518302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::bind(&AssembleVintfImpl::assembleHalManifest, this, _1)); 552bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong if (status == SUCCESS) return true; 553bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong if (status == FAIL_AND_EXIT) return false; 5549aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong 555bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong resetInFiles(); 5564650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong 557bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong status = tryAssemble(gCompatibilityMatrixConverter, "compatibility matrix", 5588302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::bind(&AssembleVintfImpl::assembleCompatibilityMatrix, this, _1)); 559bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong if (status == SUCCESS) return true; 560bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong if (status == FAIL_AND_EXIT) return false; 5614d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 562959ee1bf8b922980542f72ce9ad1929fc7d8b55cYifan Hong std::cerr << "Input file has unknown format." << std::endl 563959ee1bf8b922980542f72ce9ad1929fc7d8b55cYifan Hong << "Error when attempting to convert to manifest: " 564959ee1bf8b922980542f72ce9ad1929fc7d8b55cYifan Hong << gHalManifestConverter.lastError() << std::endl 565959ee1bf8b922980542f72ce9ad1929fc7d8b55cYifan Hong << "Error when attempting to convert to compatibility matrix: " 566959ee1bf8b922980542f72ce9ad1929fc7d8b55cYifan Hong << gCompatibilityMatrixConverter.lastError() << std::endl; 567959ee1bf8b922980542f72ce9ad1929fc7d8b55cYifan Hong return false; 5684d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong } 5699aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong 5708302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::ostream& setOutputStream(Ostream&& out) override { 5718302cea08dea5238cbc4d2637ff90319480971aeYifan Hong mOutRef = std::move(out); 5728302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return *mOutRef; 5739aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong } 5749aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong 5758302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::istream& addInputStream(const std::string& name, Istream&& in) override { 5768302cea08dea5238cbc4d2637ff90319480971aeYifan Hong auto it = mInFiles.emplace(mInFiles.end(), name, std::move(in)); 5778302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return it->stream(); 5788302cea08dea5238cbc4d2637ff90319480971aeYifan Hong } 5798302cea08dea5238cbc4d2637ff90319480971aeYifan Hong 5808302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::istream& setCheckInputStream(Istream&& in) override { 5818302cea08dea5238cbc4d2637ff90319480971aeYifan Hong mCheckFile = std::move(in); 5828302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return *mCheckFile; 5839aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong } 5849aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong 585fb9e8b655e67031c156687eeb4e561c976d04015Yifan Hong bool hasKernelVersion(const KernelVersion& kernelVer) const override { 5868302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return mKernels.find(kernelVer) != mKernels.end(); 5878302cea08dea5238cbc4d2637ff90319480971aeYifan Hong } 5888302cea08dea5238cbc4d2637ff90319480971aeYifan Hong 589fb9e8b655e67031c156687eeb4e561c976d04015Yifan Hong std::istream& addKernelConfigInputStream(const KernelVersion& kernelVer, 590fb9e8b655e67031c156687eeb4e561c976d04015Yifan Hong const std::string& name, Istream&& in) override { 5918302cea08dea5238cbc4d2637ff90319480971aeYifan Hong auto&& kernel = mKernels[kernelVer]; 5928302cea08dea5238cbc4d2637ff90319480971aeYifan Hong auto it = kernel.emplace(kernel.end(), name, std::move(in)); 5938302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return it->stream(); 5949aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong } 5959aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong 596bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong void resetInFiles() { 597bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong for (auto& inFile : mInFiles) { 598aa219f5a7792ebff4db38c60f8f08f9ab44b2586Yifan Hong inFile.stream().clear(); 599aa219f5a7792ebff4db38c60f8f08f9ab44b2586Yifan Hong inFile.stream().seekg(0); 600bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong } 601bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong } 602bfb3c1dc59144dd784d1d81af3ce81c97ea2e45aYifan Hong 6038302cea08dea5238cbc4d2637ff90319480971aeYifan Hong void setOutputMatrix() override { mOutputMatrix = true; } 6049aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong 6058302cea08dea5238cbc4d2637ff90319480971aeYifan Hong bool setHalsOnly() override { 606a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong if (mSerializeFlags) return false; 607a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong mSerializeFlags |= SerializeFlag::HALS_ONLY; 608a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong return true; 609a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong } 610a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong 6118302cea08dea5238cbc4d2637ff90319480971aeYifan Hong bool setNoHals() override { 612a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong if (mSerializeFlags) return false; 613a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong mSerializeFlags |= SerializeFlag::NO_HALS; 614a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong return true; 615a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong } 616a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong 6179aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong private: 618aa219f5a7792ebff4db38c60f8f08f9ab44b2586Yifan Hong std::vector<NamedIstream> mInFiles; 6198302cea08dea5238cbc4d2637ff90319480971aeYifan Hong Ostream mOutRef; 6208302cea08dea5238cbc4d2637ff90319480971aeYifan Hong Istream mCheckFile; 6219aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong bool mOutputMatrix = false; 622a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong SerializeFlags mSerializeFlags = SerializeFlag::EVERYTHING; 623fb9e8b655e67031c156687eeb4e561c976d04015Yifan Hong std::map<KernelVersion, std::vector<NamedIstream>> mKernels; 6248302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::map<std::string, std::string> mFakeEnv; 6254d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong}; 6264d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 6278302cea08dea5238cbc4d2637ff90319480971aeYifan Hongbool AssembleVintf::openOutFile(const std::string& path) { 6288302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return static_cast<std::ofstream&>(setOutputStream(std::make_unique<std::ofstream>(path))) 6298302cea08dea5238cbc4d2637ff90319480971aeYifan Hong .is_open(); 6304d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong} 6314d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 6328302cea08dea5238cbc4d2637ff90319480971aeYifan Hongbool AssembleVintf::openInFile(const std::string& path) { 6338302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return static_cast<std::ifstream&>(addInputStream(path, std::make_unique<std::ifstream>(path))) 6348302cea08dea5238cbc4d2637ff90319480971aeYifan Hong .is_open(); 6358302cea08dea5238cbc4d2637ff90319480971aeYifan Hong} 636a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong 6378302cea08dea5238cbc4d2637ff90319480971aeYifan Hongbool AssembleVintf::openCheckFile(const std::string& path) { 6388302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return static_cast<std::ifstream&>(setCheckInputStream(std::make_unique<std::ifstream>(path))) 6398302cea08dea5238cbc4d2637ff90319480971aeYifan Hong .is_open(); 6408302cea08dea5238cbc4d2637ff90319480971aeYifan Hong} 641a2635c418cdc039d582a50fa91f8dbaa85ce7b02Yifan Hong 6428302cea08dea5238cbc4d2637ff90319480971aeYifan Hongbool AssembleVintf::addKernel(const std::string& kernelArg) { 643b83e56bbf1b2aba92f69f63d1e434be512193b5bYifan Hong auto tokens = base::Split(kernelArg, ":"); 6448302cea08dea5238cbc4d2637ff90319480971aeYifan Hong if (tokens.size() <= 1) { 6458302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::cerr << "Unrecognized --kernel option '" << kernelArg << "'" << std::endl; 6468302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return false; 6478302cea08dea5238cbc4d2637ff90319480971aeYifan Hong } 648fb9e8b655e67031c156687eeb4e561c976d04015Yifan Hong KernelVersion kernelVer; 6498302cea08dea5238cbc4d2637ff90319480971aeYifan Hong if (!parse(tokens.front(), &kernelVer)) { 6508302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::cerr << "Unrecognized kernel version '" << tokens.front() << "'" << std::endl; 6518302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return false; 6528302cea08dea5238cbc4d2637ff90319480971aeYifan Hong } 6538302cea08dea5238cbc4d2637ff90319480971aeYifan Hong if (hasKernelVersion(kernelVer)) { 6548302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::cerr << "Multiple --kernel for " << kernelVer << " is specified." << std::endl; 6558302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return false; 6568302cea08dea5238cbc4d2637ff90319480971aeYifan Hong } 6578302cea08dea5238cbc4d2637ff90319480971aeYifan Hong for (auto it = tokens.begin() + 1; it != tokens.end(); ++it) { 6588302cea08dea5238cbc4d2637ff90319480971aeYifan Hong bool opened = 6598302cea08dea5238cbc4d2637ff90319480971aeYifan Hong static_cast<std::ifstream&>( 6608302cea08dea5238cbc4d2637ff90319480971aeYifan Hong addKernelConfigInputStream(kernelVer, *it, std::make_unique<std::ifstream>(*it))) 6618302cea08dea5238cbc4d2637ff90319480971aeYifan Hong .is_open(); 6628302cea08dea5238cbc4d2637ff90319480971aeYifan Hong if (!opened) { 6638302cea08dea5238cbc4d2637ff90319480971aeYifan Hong std::cerr << "Cannot open file '" << *it << "'." << std::endl; 6648302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return false; 6654d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong } 6664d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong } 6678302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return true; 6688302cea08dea5238cbc4d2637ff90319480971aeYifan Hong} 6694d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 6708302cea08dea5238cbc4d2637ff90319480971aeYifan Hongstd::unique_ptr<AssembleVintf> AssembleVintf::newInstance() { 6718302cea08dea5238cbc4d2637ff90319480971aeYifan Hong return std::make_unique<AssembleVintfImpl>(); 6724d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong} 6738302cea08dea5238cbc4d2637ff90319480971aeYifan Hong 6748302cea08dea5238cbc4d2637ff90319480971aeYifan Hong} // namespace vintf 6758302cea08dea5238cbc4d2637ff90319480971aeYifan Hong} // namespace android 676