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