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 <functional>
23 #include <map>
24 #include <set>
25 #include <string>
26 #include <utils/Errors.h>
27 #include <vector>
28 
29 namespace android {
30 
31 struct AST;
32 struct FQName;
33 struct Type;
34 
35 struct Coordinator {
36     Coordinator(
37             const std::vector<std::string> &packageRootPaths,
38             const std::vector<std::string> &packageRoots);
39 
40     ~Coordinator();
41 
42     // Attempts to parse the interface/types referred to by fqName.
43     // Parsing an interface also parses the associated package's types.hal
44     // file if it exists.
45     // If "parsedASTs" is non-NULL, successfully parsed ASTs are inserted
46     // into the set.
47     // If !enforce, enforceRestrictionsOnPackage won't be run.
48     AST *parse(const FQName &fqName, std::set<AST *> *parsedASTs = nullptr,
49             bool enforce = true);
50 
51     // Given package-root paths of ["hardware/interfaces",
52     // "vendor/<something>/interfaces"], package roots of
53     // ["android.hardware", "vendor.<something>.hardware"], and a
54     // FQName of "android.hardware.nfc@1.0::INfc, then getPackagePath()
55     // will return "hardware/interfaces/nfc/1.0" (if sanitized = false)
56     // or "hardware/interfaces/nfc/V1_0" (if sanitized = true).
57 
58     std::string getPackagePath(
59             const FQName &fqName, bool relative = false,
60             bool sanitized = false) const;
61 
62     // Given package roots of ["android.hardware",
63     // "vendor.<something>.hardware"] and a FQName of
64     // "android.hardware.nfc@1.0::INfc, then getPackageRoot() will
65     // return "android.hardware".
66 
67     std::string getPackageRoot(const FQName &fqName) const;
68 
69     // Given package-root paths of ["hardware/interfaces",
70     // "vendor/<something>/interfaces"], package roots of
71     // ["android.hardware", "vendor.<something>.hardware"], and a
72     // FQName of "android.hardware.nfc@1.0::INfc, then getPackageRootPath()
73     // will return "hardware/interfaces".
74 
75     std::string getPackageRootPath(const FQName &fqName) const;
76 
77     // return getPackageRoot + ":" + getPackageRootPath
78     std::string getPackageRootOption(const FQName &fqName) const;
79 
80     // Given an FQName of "android.hardware.nfc@1.0::INfc", return
81     // "android/hardware/".
82     std::string convertPackageRootToPath(const FQName &fqName) const;
83 
84     status_t getPackageInterfaceFiles(
85             const FQName &package,
86             std::vector<std::string> *fileNames) const;
87 
88     status_t appendPackageInterfacesToVector(
89             const FQName &package,
90             std::vector<FQName> *packageInterfaces) const;
91 
92     // Enforce a set of restrictions on a set of packages. These include:
93     //    - minor version upgrades
94     // "packages" contains names like "android.hardware.nfc@1.1".
95     //    - hashing restrictions
96     status_t enforceRestrictionsOnPackage(const FQName &fqName);
97 
98     static bool MakeParentHierarchy(const std::string &path);
99 
100 private:
101     // A list of top-level directories (mPackageRootPaths)
102     // corresponding to a list of package roots (mPackageRoots). For
103     // example, if mPackageRootPaths[0] == "hardware/interfaces" and
104     // mPackageRoots[0] == "android.hardware" this means that all
105     // packages starting with "android.hardware" will be looked up in
106     // "hardware/interfaces".
107     std::vector<std::string> mPackageRootPaths;
108     std::vector<std::string> mPackageRoots;
109 
110     // cache to parse().
111     std::map<FQName, AST *> mCache;
112 
113     // cache to enforceRestrictionsOnPackage().
114     std::set<FQName> mPackagesEnforced;
115 
116     std::vector<std::string>::const_iterator findPackageRoot(
117             const FQName &fqName) const;
118 
119     // Rules of enforceRestrictionsOnPackage are listed below.
120     status_t enforceMinorVersionUprevs(const FQName &fqName);
121     status_t enforceHashes(const FQName &fqName);
122 
123     DISALLOW_COPY_AND_ASSIGN(Coordinator);
124 };
125 
126 }  // namespace android
127 
128 #endif  // COORDINATOR_H_
129