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