• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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