Coordinator.cpp revision 62709d73d7f260fae0a475f8d4d30eb3665e8168
11aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber/* 21aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * Copyright (C) 2016 The Android Open Source Project 31aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * 41aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 51aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * you may not use this file except in compliance with the License. 61aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * You may obtain a copy of the License at 71aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * 81aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 91aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * 101aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * Unless required by applicable law or agreed to in writing, software 111aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 121aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * See the License for the specific language governing permissions and 141aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * limitations under the License. 151aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber */ 161aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber 175345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber#include "Coordinator.h" 185345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 195345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber#include "AST.h" 205345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 215e8bcfad6dbb7b85fcd75ae64c569fd6efafb5b8Iliyan Malchev#include <algorithm> 225345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber#include <android-base/logging.h> 235715fedbd05231bf845e3a120c83b931b7f53aa3Steven Moreland#include <hidl-util/StringHelper.h> 24dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber#include <iterator> 25a72e0d2be173cebf62f728b9d215808bd862f219Iliyan Malchev#include <dirent.h> 26d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber#include <sys/stat.h> 275345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 280d0f9a2e0195a8609f1939c35bd8907253b68249Andreas Huberextern android::status_t parseFile(android::AST *ast); 295345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 305345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Hubernamespace android { 315345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 32dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas HuberCoordinator::Coordinator( 33dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber const std::vector<std::string> &packageRootPaths, 34dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber const std::vector<std::string> &packageRoots) 35dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber : mPackageRootPaths(packageRootPaths), 36dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber mPackageRoots(packageRoots) { 37dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber // empty 38dc981333b38f47f416b9b810dc80e5cf2d7ac68aAndreas Huber} 39dc981333b38f47f416b9b810dc80e5cf2d7ac68aAndreas Huber 40dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas HuberCoordinator::~Coordinator() { 41dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber // empty 42dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber} 435345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 4439fa71827738f6c1340e4523946fe9bf704eef3aAndreas HuberAST *Coordinator::parse(const FQName &fqName, std::set<AST *> *parsedASTs) { 4568f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber CHECK(fqName.isFullyQualified()); 4668f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber 47d537ab02e1707597d70665fd8c75ca1ec9f57326Steven Moreland auto it = mCache.find(fqName); 48d537ab02e1707597d70665fd8c75ca1ec9f57326Steven Moreland if (it != mCache.end()) { 49d537ab02e1707597d70665fd8c75ca1ec9f57326Steven Moreland AST *ast = (*it).second; 505345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 5139fa71827738f6c1340e4523946fe9bf704eef3aAndreas Huber if (ast != nullptr && parsedASTs != nullptr) { 5239fa71827738f6c1340e4523946fe9bf704eef3aAndreas Huber parsedASTs->insert(ast); 5339fa71827738f6c1340e4523946fe9bf704eef3aAndreas Huber } 5439fa71827738f6c1340e4523946fe9bf704eef3aAndreas Huber 555345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber return ast; 565345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber } 575345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 5868f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber // Add this to the cache immediately, so we can discover circular imports. 59d537ab02e1707597d70665fd8c75ca1ec9f57326Steven Moreland mCache[fqName] = nullptr; 6039fa71827738f6c1340e4523946fe9bf704eef3aAndreas Huber 6139fa71827738f6c1340e4523946fe9bf704eef3aAndreas Huber AST *typesAST = nullptr; 6268f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber 6368f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber if (fqName.name() != "types") { 6468f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber // Any interface file implicitly imports its package's types.hal. 65fece6ecab34d69d38f57419d2500017a7136083eYifan Hong FQName typesName = fqName.getTypesForPackage(); 6639fa71827738f6c1340e4523946fe9bf704eef3aAndreas Huber typesAST = parse(typesName, parsedASTs); 6768f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber 6868f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber // fall through. 6968f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber } 7068f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber 71dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber std::string path = getPackagePath(fqName); 72dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber 7368f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber path.append(fqName.name()); 7468f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber path.append(".hal"); 755345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 760d0f9a2e0195a8609f1939c35bd8907253b68249Andreas Huber AST *ast = new AST(this, path); 7739fa71827738f6c1340e4523946fe9bf704eef3aAndreas Huber 7839fa71827738f6c1340e4523946fe9bf704eef3aAndreas Huber if (typesAST != NULL) { 7939fa71827738f6c1340e4523946fe9bf704eef3aAndreas Huber // If types.hal for this AST's package existed, make it's defined 8039fa71827738f6c1340e4523946fe9bf704eef3aAndreas Huber // types available to the (about to be parsed) AST right away. 8139fa71827738f6c1340e4523946fe9bf704eef3aAndreas Huber ast->addImportedAST(typesAST); 8239fa71827738f6c1340e4523946fe9bf704eef3aAndreas Huber } 8339fa71827738f6c1340e4523946fe9bf704eef3aAndreas Huber 840d0f9a2e0195a8609f1939c35bd8907253b68249Andreas Huber status_t err = parseFile(ast); 8568f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber 8668f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber if (err != OK) { 876e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber // LOG(ERROR) << "parsing '" << path << "' FAILED."; 886e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber 8968f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber delete ast; 9039fa71827738f6c1340e4523946fe9bf704eef3aAndreas Huber ast = nullptr; 915345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 9239fa71827738f6c1340e4523946fe9bf704eef3aAndreas Huber return nullptr; 9368f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber } 9468f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber 95a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber if (ast->package().package() != fqName.package() 96a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber || ast->package().version() != fqName.version()) { 9770a59e1dc3dcf32f791d2dd7966111d4adf32ecaAndreas Huber fprintf(stderr, 9870a59e1dc3dcf32f791d2dd7966111d4adf32ecaAndreas Huber "ERROR: File at '%s' does not match expected package and/or " 990d0f9a2e0195a8609f1939c35bd8907253b68249Andreas Huber "version.\n", 10070a59e1dc3dcf32f791d2dd7966111d4adf32ecaAndreas Huber path.c_str()); 101a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber 102a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber err = UNKNOWN_ERROR; 103a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber } else { 104a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber std::string ifaceName; 105a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber if (ast->isInterface(&ifaceName)) { 106a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber if (fqName.name() == "types") { 10770a59e1dc3dcf32f791d2dd7966111d4adf32ecaAndreas Huber fprintf(stderr, 10870a59e1dc3dcf32f791d2dd7966111d4adf32ecaAndreas Huber "ERROR: File at '%s' declares an interface '%s' " 1090d0f9a2e0195a8609f1939c35bd8907253b68249Andreas Huber "instead of the expected types common to the package.\n", 11070a59e1dc3dcf32f791d2dd7966111d4adf32ecaAndreas Huber path.c_str(), 11170a59e1dc3dcf32f791d2dd7966111d4adf32ecaAndreas Huber ifaceName.c_str()); 112a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber 113a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber err = UNKNOWN_ERROR; 114a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber } else if (ifaceName != fqName.name()) { 11570a59e1dc3dcf32f791d2dd7966111d4adf32ecaAndreas Huber fprintf(stderr, 11670a59e1dc3dcf32f791d2dd7966111d4adf32ecaAndreas Huber "ERROR: File at '%s' does not declare interface type " 1170d0f9a2e0195a8609f1939c35bd8907253b68249Andreas Huber "'%s'.\n", 11870a59e1dc3dcf32f791d2dd7966111d4adf32ecaAndreas Huber path.c_str(), 11970a59e1dc3dcf32f791d2dd7966111d4adf32ecaAndreas Huber fqName.name().c_str()); 120a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber 121a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber err = UNKNOWN_ERROR; 122a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber } 123a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber } else if (fqName.name() != "types") { 12470a59e1dc3dcf32f791d2dd7966111d4adf32ecaAndreas Huber fprintf(stderr, 12570a59e1dc3dcf32f791d2dd7966111d4adf32ecaAndreas Huber "ERROR: File at '%s' declares types rather than the " 1260d0f9a2e0195a8609f1939c35bd8907253b68249Andreas Huber "expected interface type '%s'.\n", 12770a59e1dc3dcf32f791d2dd7966111d4adf32ecaAndreas Huber path.c_str(), 12870a59e1dc3dcf32f791d2dd7966111d4adf32ecaAndreas Huber fqName.name().c_str()); 129a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber 130a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber err = UNKNOWN_ERROR; 1317c5ddfb41a806a7bf71581952d06b637a7670cf7Andreas Huber } else if (ast->containsInterfaces()) { 1327c5ddfb41a806a7bf71581952d06b637a7670cf7Andreas Huber fprintf(stderr, 1337c5ddfb41a806a7bf71581952d06b637a7670cf7Andreas Huber "ERROR: types.hal file at '%s' declares at least one " 1347c5ddfb41a806a7bf71581952d06b637a7670cf7Andreas Huber "interface type.\n", 1357c5ddfb41a806a7bf71581952d06b637a7670cf7Andreas Huber path.c_str()); 1367c5ddfb41a806a7bf71581952d06b637a7670cf7Andreas Huber 1377c5ddfb41a806a7bf71581952d06b637a7670cf7Andreas Huber err = UNKNOWN_ERROR; 138a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber } 139a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber } 140a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber 141a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber if (err != OK) { 142a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber delete ast; 14339fa71827738f6c1340e4523946fe9bf704eef3aAndreas Huber ast = nullptr; 144a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber 14539fa71827738f6c1340e4523946fe9bf704eef3aAndreas Huber return nullptr; 146a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber } 147a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber 14839fa71827738f6c1340e4523946fe9bf704eef3aAndreas Huber if (parsedASTs != nullptr) { parsedASTs->insert(ast); } 14939fa71827738f6c1340e4523946fe9bf704eef3aAndreas Huber 150d537ab02e1707597d70665fd8c75ca1ec9f57326Steven Moreland mCache[fqName] = ast; 1515345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 1525345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber return ast; 1535345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber} 1545345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 155dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huberstd::vector<std::string>::const_iterator 156dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas HuberCoordinator::findPackageRoot(const FQName &fqName) const { 1575345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber CHECK(!fqName.package().empty()); 1585345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber CHECK(!fqName.version().empty()); 1595345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 160dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber // Find the right package prefix and path for this FQName. For 161dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber // example, if FQName is "android.hardware.nfc@1.0::INfc", and the 162dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber // prefix:root is set to [ "android.hardware:hardware/interfaces", 163dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber // "vendor.qcom.hardware:vendor/qcom"], then we will identify the 164dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber // prefix "android.hardware" and the package root 165dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber // "hardware/interfaces". 166dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber 167dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber auto it = mPackageRoots.begin(); 16862709d73d7f260fae0a475f8d4d30eb3665e8168Steven Moreland auto ret = mPackageRoots.end(); 169dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber for (; it != mPackageRoots.end(); it++) { 17062709d73d7f260fae0a475f8d4d30eb3665e8168Steven Moreland if (!fqName.inPackage(*it)) { 17162709d73d7f260fae0a475f8d4d30eb3665e8168Steven Moreland continue; 172dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber } 17362709d73d7f260fae0a475f8d4d30eb3665e8168Steven Moreland 17462709d73d7f260fae0a475f8d4d30eb3665e8168Steven Moreland CHECK(ret == mPackageRoots.end()) 17562709d73d7f260fae0a475f8d4d30eb3665e8168Steven Moreland << "Multiple package roots found for " << fqName.string() 17662709d73d7f260fae0a475f8d4d30eb3665e8168Steven Moreland << " (" << *it << " and " << *ret << ")"; 17762709d73d7f260fae0a475f8d4d30eb3665e8168Steven Moreland 17862709d73d7f260fae0a475f8d4d30eb3665e8168Steven Moreland ret = it; 179dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber } 18062709d73d7f260fae0a475f8d4d30eb3665e8168Steven Moreland CHECK(ret != mPackageRoots.end()) 181401cd16db8a421aaf91338024cea9208549ef67eAndreas Huber << "Unable to find package root for " << fqName.string(); 182dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber 18362709d73d7f260fae0a475f8d4d30eb3665e8168Steven Moreland return ret; 184dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber} 185dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber 186dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huberstd::string Coordinator::getPackageRoot(const FQName &fqName) const { 187dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber auto it = findPackageRoot(fqName); 188dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber auto prefix = *it; 189dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber return prefix; 190dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber} 191dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber 1925bb14024064a51a044e51c14466e5b2ae8352505Iliyan Malchevstd::string Coordinator::getPackageRootPath(const FQName &fqName) const { 1935bb14024064a51a044e51c14466e5b2ae8352505Iliyan Malchev auto it = findPackageRoot(fqName); 1945bb14024064a51a044e51c14466e5b2ae8352505Iliyan Malchev auto root = mPackageRootPaths[std::distance(mPackageRoots.begin(), it)]; 1955bb14024064a51a044e51c14466e5b2ae8352505Iliyan Malchev return root; 1965bb14024064a51a044e51c14466e5b2ae8352505Iliyan Malchev} 1975bb14024064a51a044e51c14466e5b2ae8352505Iliyan Malchev 198c89340422f53046bfe24ff3e529161f9194120f8Yifan Hongstd::string Coordinator::getPackageRootOption(const FQName &fqName) const { 199c89340422f53046bfe24ff3e529161f9194120f8Yifan Hong return getPackageRoot(fqName) + ":" + getPackageRootPath(fqName); 200c89340422f53046bfe24ff3e529161f9194120f8Yifan Hong} 201c89340422f53046bfe24ff3e529161f9194120f8Yifan Hong 202dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huberstd::string Coordinator::getPackagePath( 20397288acdcff66df30cc443c65ddb815e8d0cfeaaYifan Hong const FQName &fqName, bool relative, bool sanitized) const { 204dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber 205dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber auto it = findPackageRoot(fqName); 206dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber auto prefix = *it; 207dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber auto root = mPackageRootPaths[std::distance(mPackageRoots.begin(), it)]; 208dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber 209dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber // Make sure the prefix ends on a '.' and the root path on a '/' 210dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber if ((*--prefix.end()) != '.') { 211dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber prefix += '.'; 212dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber } 213dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber 214dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber if ((*--root.end()) != '/') { 215dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber root += '/'; 216dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber } 217dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber 218dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber // Given FQName of "android.hardware.nfc@1.0::IFoo" and a prefix 219dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber // "android.hardware.", the suffix is "nfc@1.0::IFoo". 220dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber const std::string packageSuffix = fqName.package().substr(prefix.length()); 2215345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 222881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber std::string packagePath; 223881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber if (!relative) { 224dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber packagePath = root; 225881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber } 2265345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 2275345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber size_t startPos = 0; 2285345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber size_t dotPos; 2295345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber while ((dotPos = packageSuffix.find('.', startPos)) != std::string::npos) { 2305345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber packagePath.append(packageSuffix.substr(startPos, dotPos - startPos)); 2315345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber packagePath.append("/"); 2325345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 2335345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber startPos = dotPos + 1; 2345345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber } 2355345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber CHECK_LT(startPos + 1, packageSuffix.length()); 2365345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber packagePath.append(packageSuffix.substr(startPos)); 2375345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber packagePath.append("/"); 2385345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 23997288acdcff66df30cc443c65ddb815e8d0cfeaaYifan Hong packagePath.append(sanitized ? fqName.sanitizedVersion() : fqName.version()); 2405345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber packagePath.append("/"); 2415345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 2425345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber return packagePath; 2435345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber} 2445345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 245d2943e11533697b97aa5330f05fc144493748c0bAndreas Huberstatus_t Coordinator::getPackageInterfaceFiles( 246d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber const FQName &package, 247d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber std::vector<std::string> *fileNames) const { 248d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber fileNames->clear(); 2496cb08cf9f021a01d9d2b1eaec6729aac6ae70708Andreas Huber 250d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber const std::string packagePath = getPackagePath(package); 251d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 252d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber DIR *dir = opendir(packagePath.c_str()); 253d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 254d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber if (dir == NULL) { 255261370ae8d57b78b01e4168abcf54d506f946f24Steven Moreland LOG(ERROR) << "Could not open package path: " << packagePath; 256d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber return -errno; 257d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber } 258d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 259d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber struct dirent *ent; 260d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber while ((ent = readdir(dir)) != NULL) { 261d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber if (ent->d_type != DT_REG) { 2626cb08cf9f021a01d9d2b1eaec6729aac6ae70708Andreas Huber continue; 2636cb08cf9f021a01d9d2b1eaec6729aac6ae70708Andreas Huber } 2646cb08cf9f021a01d9d2b1eaec6729aac6ae70708Andreas Huber 265d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber const auto suffix = ".hal"; 266d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber const auto suffix_len = std::strlen(suffix); 267d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber const auto d_namelen = strlen(ent->d_name); 268e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber 269d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber if (d_namelen < suffix_len 270d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber || strcmp(ent->d_name + d_namelen - suffix_len, suffix)) { 271d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber continue; 272e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber } 273d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 274d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber fileNames->push_back(std::string(ent->d_name, d_namelen - suffix_len)); 275e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber } 276e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber 277d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber closedir(dir); 278d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber dir = NULL; 279d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 2805e8bcfad6dbb7b85fcd75ae64c569fd6efafb5b8Iliyan Malchev std::sort(fileNames->begin(), fileNames->end(), 2815e8bcfad6dbb7b85fcd75ae64c569fd6efafb5b8Iliyan Malchev [](const std::string& lhs, const std::string& rhs) -> bool { 2825e8bcfad6dbb7b85fcd75ae64c569fd6efafb5b8Iliyan Malchev if (lhs == "types") { 2835e8bcfad6dbb7b85fcd75ae64c569fd6efafb5b8Iliyan Malchev return true; 2845e8bcfad6dbb7b85fcd75ae64c569fd6efafb5b8Iliyan Malchev } 2855e8bcfad6dbb7b85fcd75ae64c569fd6efafb5b8Iliyan Malchev if (rhs == "types") { 2865e8bcfad6dbb7b85fcd75ae64c569fd6efafb5b8Iliyan Malchev return false; 2875e8bcfad6dbb7b85fcd75ae64c569fd6efafb5b8Iliyan Malchev } 2885e8bcfad6dbb7b85fcd75ae64c569fd6efafb5b8Iliyan Malchev return lhs < rhs; 2895e8bcfad6dbb7b85fcd75ae64c569fd6efafb5b8Iliyan Malchev }); 2905e8bcfad6dbb7b85fcd75ae64c569fd6efafb5b8Iliyan Malchev 291e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber return OK; 292e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber} 293e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber 294aa1868371f36507ff8f6337ec0e6bb02b2620981Steven Morelandstatus_t Coordinator::appendPackageInterfacesToVector( 295d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber const FQName &package, 296d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber std::vector<FQName> *packageInterfaces) const { 297d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber packageInterfaces->clear(); 298d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 299d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber std::vector<std::string> fileNames; 300d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber status_t err = getPackageInterfaceFiles(package, &fileNames); 301d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 302d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber if (err != OK) { 303d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber return err; 304d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber } 305d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 306d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber for (const auto &fileName : fileNames) { 307d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber FQName subFQName( 30890ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong package.package() + package.atVersion() + "::" + fileName); 309d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 310d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber if (!subFQName.isValid()) { 311d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber LOG(WARNING) 312d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber << "Whole-package import encountered invalid filename '" 313d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber << fileName 314d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber << "' in package " 315d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber << package.package() 31690ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong << package.atVersion(); 317d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 318d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber continue; 319d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber } 320d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 321d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber packageInterfaces->push_back(subFQName); 322d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber } 323d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 324d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber return OK; 325d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber} 326d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 327d2943e11533697b97aa5330f05fc144493748c0bAndreas Huberstd::string Coordinator::convertPackageRootToPath(const FQName &fqName) const { 328d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber std::string packageRoot = getPackageRoot(fqName); 329d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 330d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber if (*(packageRoot.end()--) != '.') { 331d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber packageRoot += '.'; 332d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber } 333d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 334d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber std::replace(packageRoot.begin(), packageRoot.end(), '.', '/'); 335d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 336d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber return packageRoot; // now converted to a path 337d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber} 338d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 339d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber// static 340d2943e11533697b97aa5330f05fc144493748c0bAndreas Huberbool Coordinator::MakeParentHierarchy(const std::string &path) { 341d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber static const mode_t kMode = 0755; 342d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 343d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber size_t start = 1; // Ignore leading '/' 344d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber size_t slashPos; 345d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber while ((slashPos = path.find("/", start)) != std::string::npos) { 346d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber std::string partial = path.substr(0, slashPos); 347d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 348d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber struct stat st; 349d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber if (stat(partial.c_str(), &st) < 0) { 350d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber if (errno != ENOENT) { 351d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber return false; 352d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber } 353d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 354d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber int res = mkdir(partial.c_str(), kMode); 355d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber if (res < 0) { 356d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber return false; 357d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber } 358d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber } else if (!S_ISDIR(st.st_mode)) { 359d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber return false; 360d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber } 361d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 362d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber start = slashPos + 1; 363d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber } 364d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 365d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber return true; 366d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber} 367d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber 3685345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber} // namespace android 3695345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 370