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 setRequireFrozen(bool requireFrozen); 46 47 void setDepFile(const std::string& depFile); 48 49 const std::string& getOwner() const; 50 void setOwner(const std::string& owner); 51 52 // adds path only if it doesn't exist 53 status_t addPackagePath(const std::string& root, const std::string& path, std::string* error); 54 // adds path if it hasn't already been added 55 void addDefaultPackagePath(const std::string& root, const std::string& path); 56 57 enum class Location { 58 STANDARD_OUT, 59 DIRECT, // mOutputPath + file name 60 PACKAGE_ROOT, // e.x. mRootPath + /nfc/1.0/Android.bp 61 GEN_OUTPUT, // e.x. mOutputPath + /android/hardware/foo/1.0/*.cpp 62 GEN_SANITIZED, // e.x. mOutputPath + /android/hardware/foo/V1_0/*.cpp 63 }; 64 65 status_t getFilepath(const FQName& fqName, Location location, const std::string& fileName, 66 std::string* path) const; 67 68 Formatter getFormatter(const FQName& fqName, Location location, 69 const std::string& fileName) const; 70 71 // must be called before file access 72 void onFileAccess(const std::string& path, const std::string& mode) const; 73 74 status_t writeDepFile(const std::string& forFile) const; 75 76 enum class Enforce { 77 FULL, // default 78 NO_HASH, // only for use with -Lhash 79 NONE, // only for use during enforcement 80 }; 81 82 // Attempts to parse the interface/types referred to by fqName. 83 // Parsing an interface also parses the associated package's types.hal 84 // file if it exists. 85 // If "parsedASTs" is non-NULL, successfully parsed ASTs are inserted 86 // into the set. 87 // If !enforce, enforceRestrictionsOnPackage won't be run. 88 AST* parse(const FQName& fqName, std::set<AST*>* parsedASTs = nullptr, 89 Enforce enforcement = Enforce::FULL) const; 90 91 // Same as parse, but it distinguishes between "missing file" and "could not parse AST" 92 // return OK, out *ast: 93 // 0xdeadbeef -> successfully parsed 94 // nullptr -> file not present 95 // return !OK 96 // could not parse AST and file exists 97 status_t parseOptional(const FQName& fqName, AST** ast, std::set<AST*>* parsedASTs = nullptr, 98 Enforce enforcement = Enforce::FULL) const; 99 100 // Given package-root paths of ["hardware/interfaces", 101 // "vendor/<something>/interfaces"], package roots of 102 // ["android.hardware", "vendor.<something>.hardware"], and a 103 // FQName of "android.hardware.nfc@1.0::INfc, then getPackagePath() 104 // will return "hardware/interfaces/nfc/1.0" (if sanitized = false) 105 // or "hardware/interfaces/nfc/V1_0" (if sanitized = true). 106 status_t getPackagePath(const FQName& fqName, bool relative, bool sanitized, 107 std::string* path) const; 108 109 // Given package roots of ["android.hardware", 110 // "vendor.<something>.hardware"] and a FQName of 111 // "android.hardware.nfc@1.0::INfc, then getPackageRoot() will 112 // return "android.hardware". 113 status_t getPackageRoot(const FQName& fqName, std::string* root) const; 114 115 status_t getPackageInterfaceFiles( 116 const FQName &package, 117 std::vector<std::string> *fileNames) const; 118 119 // Returns true if the package points to a directory that exists 120 status_t packageExists(const FQName& package, bool* result) const; 121 122 status_t appendPackageInterfacesToVector( 123 const FQName &package, 124 std::vector<FQName> *packageInterfaces) const; 125 126 status_t isTypesOnlyPackage(const FQName& package, bool* result) const; 127 128 // Returns types which are imported/defined but not referenced in code 129 status_t addUnreferencedTypes(const std::vector<FQName>& packageInterfaces, 130 std::set<FQName>* unreferencedDefinitions, 131 std::set<FQName>* unreferencedImports) const; 132 133 // Enforce a set of restrictions on a set of packages. These include: 134 // - minor version upgrades 135 // "packages" contains names like "android.hardware.nfc@1.1". 136 // - hashing restrictions 137 status_t enforceRestrictionsOnPackage(const FQName& fqName, 138 Enforce enforcement = Enforce::FULL) const; 139 140 // opt is the option that was parsed 141 // optarg contains the argument provided to opt 142 // - optarg == NULL if opt is not expecting an argument 143 using HandleArg = std::function<void(int opt, char* optarg)>; 144 145 // options is the same format as optstring for getopt 146 void parseOptions(int argc, char** argv, const std::string& options, 147 const HandleArg& handleArg); 148 149 static void emitOptionsUsageString(Formatter& out); 150 static void emitOptionsDetailString(Formatter& out); 151 152 // Returns path relative to mRootPath 153 std::string makeRelative(const std::string& filename) const; 154 155 private: 156 static bool MakeParentHierarchy(const std::string &path); 157 158 enum class HashStatus { 159 ERROR, 160 UNFROZEN, 161 FROZEN, 162 CHANGED, // frozen but changed 163 }; 164 HashStatus checkHash(const FQName& fqName) const; 165 status_t getUnfrozenDependencies(const FQName& fqName, std::set<FQName>* result) const; 166 167 // indicates that packages in "android.hardware" will be looked up in hardware/interfaces 168 struct PackageRoot { 169 std::string path; // e.x. hardware/interfaces 170 FQName root; // e.x. android.hardware@0.0 171 }; 172 173 // nullptr if it doesn't exist 174 const PackageRoot* findPackageRoot(const FQName& fqName) const; 175 176 // Given package-root paths of ["hardware/interfaces", 177 // "vendor/<something>/interfaces"], package roots of 178 // ["android.hardware", "vendor.<something>.hardware"], and a 179 // FQName of "android.hardware.nfc@1.0::INfc, then getPackageRootPath() 180 // will return "hardware/interfaces". 181 status_t getPackageRootPath(const FQName& fqName, std::string* path) const; 182 183 // Given an FQName of "android.hardware.nfc@1.0::INfc", return 184 // "android/hardware/". 185 status_t convertPackageRootToPath(const FQName& fqName, std::string* path) const; 186 187 std::vector<PackageRoot> mPackageRoots; 188 std::string mRootPath; // root of android source tree (to locate package roots) 189 std::string mOutputPath; // root of output directory 190 std::string mDepFile; // location to write depfile 191 192 // hidl-gen options 193 bool mVerbose = false; 194 bool mRequireFrozen = false; 195 std::string mOwner; 196 197 // cache to parse(). 198 mutable std::map<FQName, AST *> mCache; 199 200 // cache to enforceRestrictionsOnPackage(). 201 mutable std::set<FQName> mPackagesEnforced; 202 203 mutable std::set<std::string> mReadFiles; 204 205 // Returns the given path if it is absolute, otherwise it returns 206 // the path relative to mRootPath 207 std::string makeAbsolute(const std::string& string) const; 208 209 // Rules of enforceRestrictionsOnPackage are listed below. 210 status_t enforceMinorVersionUprevs(const FQName& fqName, Enforce enforcement) const; 211 status_t enforceHashes(const FQName &fqName) const; 212 213 DISALLOW_COPY_AND_ASSIGN(Coordinator); 214 }; 215 216 } // namespace android 217 218 #endif // COORDINATOR_H_ 219