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-util/FQName.h>
21 #include <hidl/metadata.h>
22 #include <vintf/VintfObject.h>
23
24 using namespace android;
25
26 // clang-format off
27 static const std::set<std::string> kKnownMissingHidl = {
28 "android.frameworks.cameraservice.device@2.1",
29 "android.frameworks.displayservice@1.0", // deprecated, see b/141930622
30 "android.frameworks.schedulerservice@1.0", // deprecated, see b/37226359
31 "android.frameworks.vr.composer@1.0",
32 "android.frameworks.vr.composer@2.0",
33 "android.frameworks.automotive.display@1.0",
34 "android.frameworks.stats@1.0", // converted to AIDL, see b/177667419
35 "android.hardware.audio@2.0",
36 "android.hardware.audio@4.0",
37 "android.hardware.audio@5.0",
38 "android.hardware.audio@6.0",
39 "android.hardware.audio.effect@2.0",
40 "android.hardware.audio.effect@4.0",
41 "android.hardware.audio.effect@5.0",
42 "android.hardware.audio.effect@6.0",
43 "android.hardware.automotive.audiocontrol@1.0",
44 "android.hardware.automotive.audiocontrol@2.0",
45 "android.hardware.automotive.can@1.0",
46 "android.hardware.automotive.evs@1.1",
47 "android.hardware.automotive.sv@1.0",
48 "android.hardware.automotive.vehicle@2.0",
49 "android.hardware.biometrics.fingerprint@2.3",
50 "android.hardware.bluetooth.a2dp@1.0",
51 "android.hardware.bluetooth.audio@2.1", // converted to AIDL, see b/203490261
52 "android.hardware.broadcastradio@1.1",
53 "android.hardware.broadcastradio@2.0",
54 "android.hardware.camera.provider@2.7", // Camera converted to AIDL, b/196432585
55 "android.hardware.cas.native@1.0",
56 "android.hardware.configstore@1.1", // deprecated, see b/149050985, b/149050733
57 "android.hardware.contexthub@1.2",
58 "android.hardware.drm@1.4", // converted to AIDL, b/200055138
59 "android.hardware.fastboot@1.1",
60 "android.hardware.dumpstate@1.1", // deprecated, see b/205760700
61 "android.hardware.gnss@1.1", // GNSS converted to AIDL, b/206670536
62 "android.hardware.gnss@2.1", // GNSS converted to AIDL, b/206670536
63 "android.hardware.gnss.measurement_corrections@1.1", // is sub-interface of gnss
64 "android.hardware.gnss.visibility_control@1.0",
65 "android.hardware.graphics.allocator@2.0",
66 "android.hardware.graphics.allocator@3.0",
67 "android.hardware.graphics.allocator@4.0", // converted to AIDL, see b/205761012
68 "android.hardware.graphics.bufferqueue@1.0",
69 "android.hardware.graphics.bufferqueue@2.0",
70 "android.hardware.graphics.composer@2.4", // converted to AIDL, see b/193240715
71 "android.hardware.graphics.mapper@2.1",
72 "android.hardware.graphics.mapper@3.0",
73 "android.hardware.health.storage@1.0", // converted to AIDL, see b/177470478
74 "android.hardware.health@2.1", // converted to AIDL, see b/177269435
75 "android.hardware.input.classifier@1.0", // converted to AIDL, see b/205761620
76 "android.hardware.ir@1.0", // converted to AIDL, see b/205000342
77 "android.hardware.keymaster@3.0",
78 "android.hardware.keymaster@4.1", // Replaced by KeyMint
79 "android.hardware.light@2.0",
80 "android.hardware.media.bufferpool@1.0",
81 "android.hardware.media.bufferpool@2.0",
82 "android.hardware.memtrack@1.0",
83 "android.hardware.nfc@1.2",
84 "android.hardware.oemlock@1.0",
85 "android.hardware.power@1.3",
86 "android.hardware.power.stats@1.0",
87 "android.hardware.radio@1.6", // converted to AIDL
88 "android.hardware.radio.config@1.3", // converted to AIDL
89 "android.hardware.radio.deprecated@1.0",
90 "android.hardware.renderscript@1.0",
91 "android.hardware.soundtrigger@2.3",
92 "android.hardware.secure_element@1.2",
93 "android.hardware.sensors@1.0",
94 "android.hardware.sensors@2.1",
95 "android.hardware.tetheroffload.config@1.0",
96 "android.hardware.tetheroffload.control@1.1", // see b/170699770
97 "android.hardware.thermal@1.1",
98 "android.hardware.tv.cec@1.1",
99 "android.hardware.tv.input@1.0",
100 "android.hardware.tv.tuner@1.1",
101 "android.hardware.usb@1.3", // migrated to AIDL see b/200993386
102 "android.hardware.usb.gadget@1.2",
103 "android.hardware.vibrator@1.3",
104 "android.hardware.vr@1.0",
105 "android.hardware.weaver@1.0",
106 "android.hardware.wifi.hostapd@1.3",
107 "android.hardware.wifi.supplicant@1.4",
108 "android.hardware.wifi.offload@1.0",
109 "android.hidl.base@1.0",
110 "android.hidl.memory.token@1.0",
111 "android.system.suspend@1.0", // Converted to AIDL (see b/170260236)
112 };
113 // clang-format on
114
115 struct VersionedAidlPackage {
116 std::string name;
117 size_t version;
operator <VersionedAidlPackage118 bool operator<(const VersionedAidlPackage& rhs) const {
119 return (name < rhs.name || (name == rhs.name && version < rhs.version));
120 }
121 };
122
123 static const std::set<VersionedAidlPackage> kKnownMissingAidl = {
124 // Cuttlefish Identity Credential HAL implementation is currently
125 // stuck at version 3 while RKP support is being added. Will be
126 // updated soon.
127 {"android.hardware.identity.", 4},
128
129 // types-only packages, which never expect a default implementation
130 {"android.hardware.audio.common.", 1},
131 {"android.hardware.biometrics.common.", 1},
132 {"android.hardware.biometrics.common.", 2},
133 {"android.hardware.common.", 1},
134 {"android.hardware.common.", 2},
135 {"android.hardware.common.fmq.", 1},
136
137 {"android.hardware.graphics.common.", 1},
138 {"android.hardware.graphics.common.", 2},
139 {"android.hardware.graphics.common.", 3},
140 {"android.hardware.input.common.", 1},
141
142 // android.hardware.camera.device is an interface returned by
143 // android.hardware.camera.provider.
144 // android.hardware.camera.common and android.hardware.camera.metadata are
145 // types used by android.hardware.camera.provider and
146 // android.hardware.camera.device.
147 {"android.hardware.camera.common.", 1},
148 {"android.hardware.camera.device.", 1},
149 {"android.hardware.camera.metadata.", 1},
150
151 // No implementations on cuttlefish for omapi aidl hal
152 {"android.se.omapi.", 1},
153
154 // These KeyMaster types are in an AIDL types-only HAL because they're used
155 // by the Identity Credential AIDL HAL. Remove this when fully porting
156 // KeyMaster to AIDL.
157 {"android.hardware.keymaster.", 1},
158 {"android.hardware.keymaster.", 2},
159 {"android.hardware.keymaster.", 3},
160
161 // Sound trigger doesn't have a default implementation.
162 {"android.hardware.soundtrigger3.", 1},
163 {"android.media.soundtrigger.", 1},
164 {"android.media.audio.common.", 1},
165
166 // These types are only used in Automotive.
167 {"android.automotive.computepipe.registry.", 1},
168 {"android.automotive.computepipe.runner.", 1},
169 {"android.automotive.watchdog.", 2},
170 {"android.automotive.watchdog.", 3},
171 {"android.frameworks.automotive.display.", 1},
172 {"android.frameworks.automotive.powerpolicy.", 1},
173 {"android.frameworks.automotive.powerpolicy.internal.", 1},
174 {"android.frameworks.automotive.telemetry.", 1},
175 {"android.hardware.automotive.audiocontrol.", 1},
176 {"android.hardware.automotive.audiocontrol.", 2},
177 {"android.hardware.automotive.evs.", 1},
178 {"android.hardware.automotive.occupant_awareness.", 1},
179 {"android.hardware.automotive.vehicle.", 1},
180
181 // These types are only used in TV.
182 {"android.hardware.tv.tuner.", 1},
183
184 // types-only packages, which never expect a default implementation
185 {"android.hardware.radio.", 1},
186
187 // types-only packages, which never expect a default implementation
188 {"android.hardware.uwb.fira_android.", 1},
189 };
190
191 static const std::set<VersionedAidlPackage> kComingSoonAidl = {
192 };
193
194 // AOSP packages which are never considered
isHidlPackageConsidered(const FQName & name)195 static bool isHidlPackageConsidered(const FQName& name) {
196 static std::vector<std::string> gAospExclude = {
197 // packages not implemented now that we never expect to be implemented
198 "android.hardware.tests",
199 // packages not registered with hwservicemanager, usually sub-interfaces
200 "android.hardware.camera.device",
201 };
202 for (const std::string& package : gAospExclude) {
203 if (name.inPackage(package)) {
204 return false;
205 }
206 }
207 return true;
208 }
209
isAospHidlInterface(const FQName & name)210 static bool isAospHidlInterface(const FQName& name) {
211 static const std::vector<std::string> kAospPackages = {
212 "android.hidl",
213 "android.hardware",
214 "android.frameworks",
215 "android.system",
216 };
217 for (const std::string& package : kAospPackages) {
218 if (name.inPackage(package)) {
219 return true;
220 }
221 }
222 return false;
223 }
224
allTreeHidlInterfaces()225 static std::set<FQName> allTreeHidlInterfaces() {
226 std::set<FQName> ret;
227 for (const auto& iface : HidlInterfaceMetadata::all()) {
228 FQName f;
229 CHECK(f.setTo(iface.name)) << iface.name;
230 ret.insert(f);
231 }
232 return ret;
233 }
234
allHidlManifestInterfaces()235 static std::set<FQName> allHidlManifestInterfaces() {
236 std::set<FQName> ret;
237 auto setInserter = [&](const vintf::ManifestInstance& i) -> bool {
238 if (i.format() != vintf::HalFormat::HIDL) {
239 return true; // continue
240 }
241 ret.insert(i.getFqInstance().getFqName());
242 return true; // continue
243 };
244 vintf::VintfObject::GetDeviceHalManifest()->forEachInstance(setInserter);
245 vintf::VintfObject::GetFrameworkHalManifest()->forEachInstance(setInserter);
246 return ret;
247 }
248
isAospAidlInterface(const std::string & name)249 static bool isAospAidlInterface(const std::string& name) {
250 return base::StartsWith(name, "android.") &&
251 !base::StartsWith(name, "android.hardware.tests.") &&
252 !base::StartsWith(name, "android.aidl.tests");
253 }
254
allAidlManifestInterfaces()255 static std::set<VersionedAidlPackage> allAidlManifestInterfaces() {
256 std::set<VersionedAidlPackage> ret;
257 auto setInserter = [&](const vintf::ManifestInstance& i) -> bool {
258 if (i.format() != vintf::HalFormat::AIDL) {
259 return true; // continue
260 }
261 ret.insert({i.package() + "." + i.interface(), i.version().minorVer});
262 return true; // continue
263 };
264 vintf::VintfObject::GetDeviceHalManifest()->forEachInstance(setInserter);
265 vintf::VintfObject::GetFrameworkHalManifest()->forEachInstance(setInserter);
266 return ret;
267 }
268
TEST(Hal,AllHidlInterfacesAreInAosp)269 TEST(Hal, AllHidlInterfacesAreInAosp) {
270 for (const FQName& name : allHidlManifestInterfaces()) {
271 EXPECT_TRUE(isAospHidlInterface(name))
272 << "This device should only have AOSP interfaces, not: "
273 << name.string();
274 }
275 }
276
TEST(Hal,HidlInterfacesImplemented)277 TEST(Hal, HidlInterfacesImplemented) {
278 // instances -> major version -> minor versions
279 std::map<std::string, std::map<size_t, std::set<size_t>>> unimplemented;
280
281 for (const FQName& f : allTreeHidlInterfaces()) {
282 if (!isAospHidlInterface(f)) continue;
283 if (!isHidlPackageConsidered(f)) continue;
284
285 unimplemented[f.package()][f.getPackageMajorVersion()].insert(
286 f.getPackageMinorVersion());
287 }
288
289 // we'll be removing items from this which we know are missing
290 // in order to be left with those elements which we thought we
291 // knew were missing but are actually present
292 std::set<std::string> thoughtMissing = kKnownMissingHidl;
293
294 for (const FQName& f : allHidlManifestInterfaces()) {
295 if (thoughtMissing.erase(f.getPackageAndVersion().string()) > 0) {
296 ADD_FAILURE() << "Instance in missing list, but available: "
297 << f.string();
298 }
299
300 std::set<size_t>& minors =
301 unimplemented[f.package()][f.getPackageMajorVersion()];
302 size_t minor = f.getPackageMinorVersion();
303
304 auto it = minors.find(minor);
305 if (it == minors.end()) continue;
306
307 // if 1.2 is implemented, also considere 1.0, 1.1 implemented
308 minors.erase(minors.begin(), std::next(it));
309 }
310
311 for (const auto& [package, minorsPerMajor] : unimplemented) {
312 for (const auto& [major, minors] : minorsPerMajor) {
313 if (minors.empty()) continue;
314
315 size_t maxMinor = *minors.rbegin();
316
317 FQName missing;
318 ASSERT_TRUE(missing.setTo(package, major, maxMinor));
319
320 if (thoughtMissing.erase(missing.string()) > 0) continue;
321
322 ADD_FAILURE() << "Missing implementation from " << missing.string();
323 }
324 }
325
326 for (const std::string& missing : thoughtMissing) {
327 ADD_FAILURE() << "Instance in missing list and cannot find it anywhere: "
328 << missing << " (multiple versions in missing list?)";
329 }
330 }
331
TEST(Hal,AllAidlInterfacesAreInAosp)332 TEST(Hal, AllAidlInterfacesAreInAosp) {
333 for (const auto& package : allAidlManifestInterfaces()) {
334 EXPECT_TRUE(isAospAidlInterface(package.name))
335 << "This device should only have AOSP interfaces, not: "
336 << package.name;
337 }
338 }
339
340 // android.hardware.foo.IFoo -> android.hardware.foo.
getAidlPackage(const std::string & aidlType)341 std::string getAidlPackage(const std::string& aidlType) {
342 size_t lastDot = aidlType.rfind('.');
343 CHECK(lastDot != std::string::npos);
344 return aidlType.substr(0, lastDot + 1);
345 }
346
347 struct AidlPackageCheck {
348 bool hasRegistration;
349 bool knownMissing;
350 };
351
TEST(Hal,AidlInterfacesImplemented)352 TEST(Hal, AidlInterfacesImplemented) {
353 std::set<VersionedAidlPackage> manifest = allAidlManifestInterfaces();
354 std::set<VersionedAidlPackage> thoughtMissing = kKnownMissingAidl;
355 std::set<VersionedAidlPackage> comingSoon = kComingSoonAidl;
356
357 for (const auto& treePackage : AidlInterfaceMetadata::all()) {
358 ASSERT_FALSE(treePackage.types.empty()) << treePackage.name;
359 if (std::none_of(treePackage.types.begin(), treePackage.types.end(),
360 isAospAidlInterface))
361 continue;
362 if (treePackage.stability != "vintf") continue;
363
364 // expect versions from 1 to latest version. If the package has development
365 // the latest version is the latest known version + 1. Each of these need
366 // to be checked for registration and knownMissing.
367 std::map<size_t, AidlPackageCheck> expectedVersions;
368 for (const auto version : treePackage.versions) {
369 expectedVersions[version] = {false, false};
370 }
371 if (treePackage.has_development) {
372 size_t version =
373 treePackage.versions.empty() ? 1 : *treePackage.versions.rbegin() + 1;
374 expectedVersions[version] = {false, false};
375 }
376
377 // Check all types and versions defined by the package for registration.
378 // The package version is considered registered if any of those types are
379 // present in the manifest with the same version.
380 // The package version is considered known missing if it is found in
381 // thoughtMissing.
382 bool latestRegistered = false;
383 for (const std::string& type : treePackage.types) {
384 for (auto& [version, check] : expectedVersions) {
385 if (manifest.erase({type, version}) > 0) {
386 if (version == expectedVersions.rbegin()->first) {
387 latestRegistered = true;
388 }
389 check.hasRegistration = true;
390 }
391 if (thoughtMissing.erase({getAidlPackage(type), version}) > 0)
392 check.knownMissing = true;
393 }
394 }
395
396 if (!latestRegistered && !expectedVersions.rbegin()->second.knownMissing) {
397 ADD_FAILURE() << "The latest version ("
398 << expectedVersions.rbegin()->first
399 << ") of the package is not implemented: "
400 << treePackage.name
401 << " which declares the following types:\n "
402 << base::Join(treePackage.types, "\n ");
403 }
404
405 for (const auto& [version, check] : expectedVersions) {
406 if (check.knownMissing) {
407 if (check.hasRegistration) {
408 ADD_FAILURE() << "Package in missing list, but available: "
409 << treePackage.name << " V" << version
410 << " which declares the following types:\n "
411 << base::Join(treePackage.types, "\n ");
412 }
413
414 continue;
415 }
416 }
417 }
418
419 for (const auto& package : thoughtMissing) {
420 // TODO: b/194806512 : Remove after Wifi hostapd AIDL interface lands on aosp
421 if (comingSoon.erase(package) == 0) {
422 ADD_FAILURE() << "Interface in missing list and cannot find it anywhere: "
423 << package.name << " V" << package.version;
424 }
425 }
426
427 for (const auto& package : manifest) {
428 ADD_FAILURE() << "Can't find manifest entry in tree: " << package.name
429 << " version: " << package.version;
430 }
431 }
432