AssembleVintf.cpp revision a59d2567783cad6f675d2fc1f2fcce4bce3e34e3
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 <unordered_map> 234d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong#include <sstream> 244d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong#include <string> 254d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 264d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong#include <vintf/parse_string.h> 274d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong#include <vintf/parse_xml.h> 284d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 294d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hongnamespace android { 304d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hongnamespace vintf { 314d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 324d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong/** 334d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong * Slurps the device manifest file and add build time flag to it. 344d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong */ 354d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hongclass AssembleVintf { 364d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hongpublic: 374d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong template<typename T> 384d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong static bool getFlag(const std::string& key, T* value) { 394d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong const char *envValue = getenv(key.c_str()); 404d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong if (envValue == NULL) { 414d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong std::cerr << "Required " << key << " flag." << std::endl; 424d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong return false; 434d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong } 444d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 454d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong if (!parse(envValue, value)) { 464d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong std::cerr << "Cannot parse " << envValue << "." << std::endl; 474d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong return false; 484d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong } 494d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong return true; 504d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong } 514d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 52a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong static bool assemble(std::basic_istream<char>& inFile, 53a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong std::basic_ostream<char>& outFile, 54a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong bool isMatrix) { 554d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong std::stringstream ss; 564d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong ss << inFile.rdbuf(); 574d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong std::string fileContent = ss.str(); 584d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 594d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong HalManifest halManifest; 604d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong if (!gHalManifestConverter(&halManifest, fileContent)) { 614d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong std::cerr << "Illformed HAL manifest: " << gHalManifestConverter.lastError() 624d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong << std::endl; 634d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong return false; 644d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong } 654d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 664d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong if (halManifest.mType == SchemaType::DEVICE) { 674d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong if (!getFlag("BOARD_SEPOLICY_VERS", &halManifest.device.mSepolicyVersion)) { 684d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong return false; 694d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong } 704d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong } 714d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 72a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong if (isMatrix) { 73a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong CompatibilityMatrix mat = halManifest.generateCompatibleMatrix(); 74a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong std::string error; 75a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong if (!halManifest.checkCompatibility(mat, &error)) { 76a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong std::cerr << "FATAL ERROR: cannot generate a compatible matrix: " 77a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong << error << std::endl; 78a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong } 79a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong outFile << "<!-- \n" 80a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong " Autogenerated skeleton compatibility matrix. \n" 81a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong " Use with caution. Modify it to suit your needs.\n" 82a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong " All HALs are set to optional.\n" 83a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong " Many entries other than HALs are zero-filled and\n" 84a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong " require human attention. \n" 85a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong "-->\n" 86a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong << gCompatibilityMatrixConverter(mat); 87a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong } else { 88a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong outFile << gHalManifestConverter(halManifest); 89a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong } 90a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong 914d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong outFile.flush(); 924d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 934d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong return true; 944d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong } 954d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong}; 964d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 974d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong} // namespace vintf 984d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong} // namespace android 994d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 1004d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hongvoid help() { 1014d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong std::cerr << 1024d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong "assemble_vintf -h\n" 1034d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong " Display this help text.\n" 104a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong "assemble_vintf -i <input file> [-o <output file>] [-m]\n" 1054d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong " Fill in build-time flags into the given manifest.\n" 106a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong " If no designated output file, write to stdout.\n" 107a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong " If -m is set, a compatible compatibility matrix is\n" 108a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong " generated instead.\n"; 1094d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong} 1104d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 1114d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hongint main(int argc, char **argv) { 1124d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong std::ifstream inFile; 1134d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong std::ofstream outFile; 1144d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong std::ostream* outFileRef = &std::cout; 115a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong bool isMatrix = false; 1164d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong int res; 117a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong while((res = getopt(argc, argv, "hi:o:m")) >= 0) { 1184d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong switch (res) { 1194d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong case 'i': { 1204d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong inFile.open(optarg); 1214d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong if (!inFile.is_open()) { 1224d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong std::cerr << "Failed to open " << optarg << std::endl; 1234d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong return 1; 1244d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong } 1254d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong } break; 1264d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 1274d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong case 'o': { 1284d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong outFile.open(optarg); 1294d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong if (!outFile.is_open()) { 1304d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong std::cerr << "Failed to open " << optarg << std::endl; 1314d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong return 1; 1324d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong } 1334d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong outFileRef = &outFile; 1344d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong } break; 1354d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 136a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong case 'm': { 137a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong isMatrix = true; 138a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong } break; 139a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong 1404d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong case 'h': 1414d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong default: { 1424d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong help(); 1434d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong return 1; 1444d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong } break; 1454d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong } 1464d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong } 1474d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 1484d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong if (!inFile.is_open()) { 1494d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong std::cerr << "Missing input file" << std::endl; 1504d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong help(); 1514d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong return 1; 1524d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong } 1534d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 154a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong return ::android::vintf::AssembleVintf::assemble(inFile, *outFileRef, isMatrix) 1554d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong ? 0 : 1; 1564d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong} 1574d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong 158