1 /*
2  * Copyright (C) 2019 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 #include <aidl/metadata.h>
17 #include <android-base/logging.h>
18 #include <android-base/strings.h>
19 #include <gtest/gtest.h>
20 #include <hidl/metadata.h>
21 #include <hidl-util/FQName.h>
22 #include <vintf/VintfObject.h>
23 
24 using namespace android;
25 
26 static const std::set<std::string> kKnownMissingHidl = {
27     "[email protected]",
28     "[email protected]",
29     "[email protected]",
30     "[email protected]",
31     "[email protected]",
32     "[email protected]",
33     "[email protected]",
34     "[email protected]",
35     "[email protected]",
36     "[email protected]",
37     "[email protected]",
38     "[email protected]",
39     "[email protected]",
40     "[email protected]",
41     "[email protected]",
42     "[email protected]",
43     "[email protected]",
44     "[email protected]",
45     "[email protected]",
46     "[email protected]",
47     "[email protected]",
48     "[email protected]",
49     "[email protected]",
50     "[email protected]",
51     "[email protected]",
52     "[email protected]", // deprecated, see b/149050985, b/149050733
53     "[email protected]",
54     "[email protected]", // is sub-interface of gnss
55     "[email protected]",
56     "[email protected]",
57     "[email protected]",
58     "[email protected]",
59     "[email protected]",
60     "[email protected]",
61     "[email protected]",
62     "[email protected]",
63     "[email protected]",
64     "[email protected]",
65     "[email protected]",
66     "[email protected]",
67     "[email protected]",
68     "[email protected]",
69     "[email protected]",
70     "[email protected]",
71     "[email protected]",
72     "[email protected]",
73     "[email protected]",
74     "[email protected]",
75     "[email protected]",
76     "[email protected]",
77     "[email protected]",
78     "[email protected]",
79     "[email protected]",
80     "[email protected]",
81     "[email protected]",
82     "[email protected]",
83     "[email protected]",
84     "[email protected]",
85     "[email protected]",
86     "[email protected]",
87     "[email protected]",
88     "[email protected]",
89     "[email protected]",
90     "[email protected]",
91     "[email protected]",
92     "[email protected]",
93     "[email protected]",
94     "[email protected]",
95     "[email protected]",
96     "[email protected]",
97 };
98 
99 static const std::set<std::string> kKnownMissingAidl = {
100     // types-only packages, which never expect a default implementation
101     "android.hardware.common.NativeHandle",
102     "android.hardware.graphics.common.ExtendableType",
103 
104     // These KeyMaster types are in an AIDL types-only HAL because they're used
105     // by the Identity Credential AIDL HAL. Remove this when fully porting
106     // KeyMaster to AIDL.
107     "android.hardware.keymaster.HardwareAuthToken",
108     "android.hardware.keymaster.HardwareAuthenticatorType",
109     "android.hardware.keymaster.Timestamp",
110 };
111 
112 // AOSP packages which are never considered
isHidlPackageWhitelist(const FQName & name)113 static bool isHidlPackageWhitelist(const FQName& name) {
114     static std::vector<std::string> gAospExclude = {
115         // packages not implemented now that we never expect to be implemented
116         "android.hardware.tests",
117         // packages not registered with hwservicemanager, usually sub-interfaces
118         "android.hardware.camera.device",
119     };
120     for (const std::string& package : gAospExclude) {
121         if (name.inPackage(package)) {
122             return true;
123         }
124     }
125     return false;
126 }
127 
isAospHidlInterface(const FQName & name)128 static bool isAospHidlInterface(const FQName& name) {
129     static const std::vector<std::string> kAospPackages = {
130         "android.hidl",
131         "android.hardware",
132         "android.frameworks",
133         "android.system",
134     };
135     for (const std::string& package : kAospPackages) {
136         if (name.inPackage(package)) {
137             return true;
138         }
139     }
140     return false;
141 }
142 
allTreeHidlInterfaces()143 static std::set<FQName> allTreeHidlInterfaces() {
144     std::set<FQName> ret;
145     for (const auto& iface : HidlInterfaceMetadata::all()) {
146         FQName f;
147         CHECK(f.setTo(iface.name)) << iface.name;
148         ret.insert(f);
149     }
150     return ret;
151 }
152 
allHidlManifestInterfaces()153 static std::set<FQName> allHidlManifestInterfaces() {
154     std::set<FQName> ret;
155     auto setInserter = [&] (const vintf::ManifestInstance& i) -> bool {
156         if (i.format() != vintf::HalFormat::HIDL) {
157             return true;  // continue
158         }
159         ret.insert(i.getFqInstance().getFqName());
160         return true;  // continue
161     };
162     vintf::VintfObject::GetDeviceHalManifest()->forEachInstance(setInserter);
163     vintf::VintfObject::GetFrameworkHalManifest()->forEachInstance(setInserter);
164     return ret;
165 }
166 
isAospAidlInterface(const std::string & name)167 static bool isAospAidlInterface(const std::string& name) {
168     return base::StartsWith(name, "android.") &&
169         !base::StartsWith(name, "android.automotive.") &&
170         !base::StartsWith(name, "android.hardware.automotive.") &&
171         !base::StartsWith(name, "android.hardware.tests.");
172 }
173 
allAidlManifestInterfaces()174 static std::set<std::string> allAidlManifestInterfaces() {
175     std::set<std::string> ret;
176     auto setInserter = [&] (const vintf::ManifestInstance& i) -> bool {
177         if (i.format() != vintf::HalFormat::AIDL) {
178             return true;  // continue
179         }
180         ret.insert(i.package() + "." + i.interface());
181         return true;  // continue
182     };
183     vintf::VintfObject::GetDeviceHalManifest()->forEachInstance(setInserter);
184     vintf::VintfObject::GetFrameworkHalManifest()->forEachInstance(setInserter);
185     return ret;
186 }
187 
TEST(Hal,AllHidlInterfacesAreInAosp)188 TEST(Hal, AllHidlInterfacesAreInAosp) {
189     for (const FQName& name : allHidlManifestInterfaces()) {
190         EXPECT_TRUE(isAospHidlInterface(name)) << name.string();
191     }
192 }
193 
TEST(Hal,HidlInterfacesImplemented)194 TEST(Hal, HidlInterfacesImplemented) {
195     // instances -> major version -> minor versions
196     std::map<std::string, std::map<size_t, std::set<size_t>>> unimplemented;
197 
198     for (const FQName& f : allTreeHidlInterfaces()) {
199         if (!isAospHidlInterface(f)) continue;
200         if (isHidlPackageWhitelist(f)) continue;
201 
202         unimplemented[f.package()][f.getPackageMajorVersion()].insert(f.getPackageMinorVersion());
203     }
204 
205     // we'll be removing items from this which we know are missing
206     // in order to be left with those elements which we thought we
207     // knew were missing but are actually present
208     std::set<std::string> thoughtMissing = kKnownMissingHidl;
209 
210     for (const FQName& f : allHidlManifestInterfaces()) {
211         if (thoughtMissing.erase(f.getPackageAndVersion().string()) > 0) {
212              std::cout << "[ WARNING  ] Instance in missing list, but available: "
213                        << f.string() << std::endl;
214         }
215 
216         std::set<size_t>& minors = unimplemented[f.package()][f.getPackageMajorVersion()];
217         size_t minor = f.getPackageMinorVersion();
218 
219         auto it = minors.find(minor);
220         if (it == minors.end()) continue;
221 
222         // if 1.2 is implemented, also considere 1.0, 1.1 implemented
223         minors.erase(minors.begin(), std::next(it));
224     }
225 
226     for (const auto& [package, minorsPerMajor] : unimplemented) {
227         for (const auto& [major, minors] : minorsPerMajor) {
228             if (minors.empty()) continue;
229 
230             size_t maxMinor = *minors.rbegin();
231 
232             FQName missing;
233             ASSERT_TRUE(missing.setTo(package, major, maxMinor));
234 
235             if (thoughtMissing.erase(missing.string()) > 0) continue;
236 
237             ADD_FAILURE() << "Missing implementation from " << missing.string();
238         }
239     }
240 
241     for (const std::string& missing : thoughtMissing) {
242         std::cout << "[ WARNING  ] Instance in missing list and cannot find it anywhere: "
243                   << missing << std::endl;
244     }
245 }
246 
TEST(Hal,AllAidlInterfacesAreInAosp)247 TEST(Hal, AllAidlInterfacesAreInAosp) {
248     for (const std::string& name : allAidlManifestInterfaces()) {
249         EXPECT_TRUE(isAospAidlInterface(name)) << name;
250     }
251 }
252 
TEST(Hal,AidlInterfacesImplemented)253 TEST(Hal, AidlInterfacesImplemented) {
254     std::set<std::string> manifest = allAidlManifestInterfaces();
255     std::set<std::string> thoughtMissing = kKnownMissingAidl;
256 
257     for (const auto& iface : AidlInterfaceMetadata::all()) {
258         ASSERT_FALSE(iface.types.empty()) << iface.name;  // sanity
259         if (std::none_of(iface.types.begin(), iface.types.end(), isAospAidlInterface)) continue;
260         if (iface.stability != "vintf") continue;
261 
262         bool hasRegistration = false;
263         bool knownMissing = false;
264         for (const std::string& type : iface.types) {
265             if (manifest.erase(type) > 0) hasRegistration = true;
266             if (thoughtMissing.erase(type) > 0) knownMissing = true;
267         }
268 
269         if (knownMissing) {
270             if (hasRegistration) {
271                 std::cout << "[ WARNING  ] Interface in missing list, but available: " << iface.name
272                           << " which declares the following types:\n    "
273                           << base::Join(iface.types, "\n    ") << std::endl;
274             }
275 
276             continue;
277         }
278 
279         EXPECT_TRUE(hasRegistration) << iface.name << " which declares the following types:\n    "
280             << base::Join(iface.types, "\n    ") << std::endl;
281     }
282 
283     for (const std::string& iface : thoughtMissing) {
284         std::cout << "[ WARNING  ] Interface in manifest list and cannot find it anywhere: "
285                   << iface << std::endl;
286     }
287 
288     for (const std::string& iface : manifest) {
289         std::cout << "[ WARNING  ] Can't find manifest entry in tree: " << iface << std::endl;
290     }
291 }
292