1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef COORDINATOR_H_ 18 19 #define COORDINATOR_H_ 20 21 #include <android-base/macros.h> 22 #include <hidl-util/FQName.h> 23 #include <hidl-util/Formatter.h> 24 #include <utils/Errors.h> 25 #include <map> 26 #include <set> 27 #include <string> 28 #include <vector> 29 30 namespace android { 31 32 struct AST; 33 struct Type; 34 35 struct Coordinator { CoordinatorCoordinator36 Coordinator() {}; 37 38 const std::string& getRootPath() const; 39 void setRootPath(const std::string &rootPath); 40 void setOutputPath(const std::string& outputPath); 41 42 void setVerbose(bool value); 43 bool isVerbose() const; 44 45 void setDepFile(const std::string& depFile); 46 47 const std::string& getOwner() const; 48 void setOwner(const std::string& owner); 49 50 // adds path only if it doesn't exist 51 status_t addPackagePath(const std::string& root, const std::string& path, std::string* error); 52 // adds path if it hasn't already been added 53 void addDefaultPackagePath(const std::string& root, const std::string& path); 54 55 enum class Location { 56 STANDARD_OUT, 57 DIRECT, // mOutputPath + file name 58 PACKAGE_ROOT, // e.x. mRootPath + /nfc/1.0/Android.bp 59 GEN_OUTPUT, // e.x. mOutputPath + /android/hardware/foo/1.0/*.cpp 60 GEN_SANITIZED, // e.x. mOutputPath + /android/hardware/foo/V1_0/*.cpp 61 }; 62 63 status_t getFilepath(const FQName& fqName, Location location, const std::string& fileName, 64 std::string* path) const; 65 66 Formatter getFormatter(const FQName& fqName, Location location, 67 const std::string& fileName) const; 68 69 // must be called before file access 70 void onFileAccess(const std::string& path, const std::string& mode) const; 71 72 status_t writeDepFile(const std::string& forFile) const; 73 74 enum class Enforce { 75 FULL, // default 76 NO_HASH, // only for use with -Lhash 77 NONE, // only for use during enforcement 78 }; 79 80 // Attempts to parse the interface/types referred to by fqName. 81 // Parsing an interface also parses the associated package's types.hal 82 // file if it exists. 83 // If "parsedASTs" is non-NULL, successfully parsed ASTs are inserted 84 // into the set. 85 // If !enforce, enforceRestrictionsOnPackage won't be run. 86 AST* parse(const FQName& fqName, std::set<AST*>* parsedASTs = nullptr, 87 Enforce enforcement = Enforce::FULL) const; 88 89 // Same as parse, but it distinguishes between "missing file" and "could not parse AST" 90 // return OK, out *ast: 91 // 0xdeadbeef -> successfully parsed 92 // nullptr -> file not present 93 // return !OK 94 // could not parse AST and file exists 95 status_t parseOptional(const FQName& fqName, AST** ast, std::set<AST*>* parsedASTs = nullptr, 96 Enforce enforcement = Enforce::FULL) const; 97 98 // Given package-root paths of ["hardware/interfaces", 99 // "vendor/<something>/interfaces"], package roots of 100 // ["android.hardware", "vendor.<something>.hardware"], and a 101 // FQName of "android.hardware.nfc@1.0::INfc, then getPackagePath() 102 // will return "hardware/interfaces/nfc/1.0" (if sanitized = false) 103 // or "hardware/interfaces/nfc/V1_0" (if sanitized = true). 104 status_t getPackagePath(const FQName& fqName, bool relative, bool sanitized, 105 std::string* path) const; 106 107 // Given package roots of ["android.hardware", 108 // "vendor.<something>.hardware"] and a FQName of 109 // "android.hardware.nfc@1.0::INfc, then getPackageRoot() will 110 // return "android.hardware". 111 status_t getPackageRoot(const FQName& fqName, std::string* root) const; 112 113 status_t getPackageInterfaceFiles( 114 const FQName &package, 115 std::vector<std::string> *fileNames) const; 116 117 // Returns true if the package points to a directory that exists 118 status_t packageExists(const FQName& package, bool* result) const; 119 120 status_t appendPackageInterfacesToVector( 121 const FQName &package, 122 std::vector<FQName> *packageInterfaces) const; 123 124 status_t isTypesOnlyPackage(const FQName& package, bool* result) const; 125 126 // Returns types which are imported/defined but not referenced in code 127 status_t addUnreferencedTypes(const std::vector<FQName>& packageInterfaces, 128 std::set<FQName>* unreferencedDefinitions, 129 std::set<FQName>* unreferencedImports) const; 130 131 // Enforce a set of restrictions on a set of packages. These include: 132 // - minor version upgrades 133 // "packages" contains names like "android.hardware.nfc@1.1". 134 // - hashing restrictions 135 status_t enforceRestrictionsOnPackage(const FQName& fqName, 136 Enforce enforcement = Enforce::FULL) const; 137 138 // opt is the option that was parsed 139 // optarg contains the argument provided to opt 140 // - optarg == NULL if opt is not expecting an argument 141 using HandleArg = std::function<void(int opt, char* optarg)>; 142 143 // options is the same format as optstring for getopt 144 void parseOptions(int argc, char** argv, const std::string& options, 145 const HandleArg& handleArg); 146 147 static void emitOptionsUsageString(Formatter& out); 148 static void emitOptionsDetailString(Formatter& out); 149 150 // Returns path relative to mRootPath 151 std::string makeRelative(const std::string& filename) const; 152 153 private: 154 static bool MakeParentHierarchy(const std::string &path); 155 156 enum class HashStatus { 157 ERROR, 158 UNFROZEN, 159 FROZEN, 160 CHANGED, // frozen but changed 161 }; 162 HashStatus checkHash(const FQName& fqName) const; 163 status_t getUnfrozenDependencies(const FQName& fqName, std::set<FQName>* result) const; 164 165 // indicates that packages in "android.hardware" will be looked up in hardware/interfaces 166 struct PackageRoot { 167 std::string path; // e.x. hardware/interfaces 168 FQName root; // e.x. android.hardware@0.0 169 }; 170 171 // nullptr if it doesn't exist 172 const PackageRoot* findPackageRoot(const FQName& fqName) const; 173 174 // Given package-root paths of ["hardware/interfaces", 175 // "vendor/<something>/interfaces"], package roots of 176 // ["android.hardware", "vendor.<something>.hardware"], and a 177 // FQName of "android.hardware.nfc@1.0::INfc, then getPackageRootPath() 178 // will return "hardware/interfaces". 179 status_t getPackageRootPath(const FQName& fqName, std::string* path) const; 180 181 // Given an FQName of "android.hardware.nfc@1.0::INfc", return 182 // "android/hardware/". 183 status_t convertPackageRootToPath(const FQName& fqName, std::string* path) const; 184 185 std::vector<PackageRoot> mPackageRoots; 186 std::string mRootPath; // root of android source tree (to locate package roots) 187 std::string mOutputPath; // root of output directory 188 std::string mDepFile; // location to write depfile 189 190 // hidl-gen options 191 bool mVerbose = false; 192 std::string mOwner; 193 194 // cache to parse(). 195 mutable std::map<FQName, AST *> mCache; 196 197 // cache to enforceRestrictionsOnPackage(). 198 mutable std::set<FQName> mPackagesEnforced; 199 200 mutable std::set<std::string> mReadFiles; 201 202 // Returns the given path if it is absolute, otherwise it returns 203 // the path relative to mRootPath 204 std::string makeAbsolute(const std::string& string) const; 205 206 // Rules of enforceRestrictionsOnPackage are listed below. 207 status_t enforceMinorVersionUprevs(const FQName& fqName, Enforce enforcement) const; 208 status_t enforceHashes(const FQName &fqName) const; 209 210 DISALLOW_COPY_AND_ASSIGN(Coordinator); 211 }; 212 213 } // namespace android 214 215 #endif // COORDINATOR_H_ 216