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 
17 #include <aidl/metadata.h>
18 #include <android-base/logging.h>
19 #include <android-base/properties.h>
20 #include <android-base/strings.h>
21 #include <android/content/pm/IPackageManagerNative.h>
22 #include <binder/IServiceManager.h>
23 #include <gtest/gtest.h>
24 #include <hidl-util/FQName.h>
25 #include <hidl/metadata.h>
26 #include <vintf/VintfObject.h>
27 
28 #include <algorithm>
29 #include <cstddef>
30 #include <map>
31 #include <mutex>
32 #include <set>
33 #include <string>
34 #include <vector>
35 
36 #ifdef AIDL_USE_UNFROZEN
37 constexpr bool kAidlUseUnfrozen = true;
38 #else
39 constexpr bool kAidlUseUnfrozen = false;
40 #endif
41 
42 using namespace android;
43 
44 // clang-format off
45 static const std::set<std::string> kKnownMissingHidl = {
46     "[email protected]", // converted to AIDL, see b/170401743
47     "[email protected]",
48     "[email protected]", // converted to AIDL, see b/205764761
49     "[email protected]", // deprecated, see b/141930622
50     "[email protected]", // deprecated, see b/37226359
51     "[email protected]", // deprecated, see b/205764765
52     "[email protected]",
53     "[email protected]",
54     "[email protected]",  // converted to AIDL, see b/177667419
55     "[email protected]", // deprecated, see b/204935495
56     "[email protected]",
57     "[email protected]",
58     "[email protected]",
59     "[email protected]",
60     "[email protected]", // converted to AIDL, see b/264712385
61     "[email protected]",
62     "[email protected]",
63     "[email protected]",
64     "[email protected]",
65     "[email protected]", // converted to AIDL, see b/264712385
66     "[email protected]", // converted to AIDL, see b/182976659
67     "[email protected]",
68     "[email protected]",
69     "[email protected]",  // converted to AIDL, see b/170405615
70     "[email protected]",
71     "[email protected]",
72     "[email protected]",
73     "[email protected]", // converted to AIDL, see b/152416783
74     "[email protected]", // converted to AIDL, see b/168730443
75     "[email protected]",
76     "[email protected]", // converted to AIDL, see b/203490261
77     "[email protected]", // converted to AIDL, see b/205758693
78     "[email protected]", // converted to AIDL, see b/227536004
79     "[email protected]",
80     "[email protected]",
81     "[email protected]", // Camera converted to AIDL, b/196432585
82     "[email protected]", // converted to AIDL, see b/227673974
83     "[email protected]",
84     "[email protected]", // deprecated, see b/149050985, b/149050733
85     "[email protected]", // converted to AIDL, see b/205760172
86     "[email protected]",
87     "[email protected]", // converted to AIDL, b/200055138
88     "[email protected]",
89     "[email protected]", // deprecated, see b/205760700
90     "[email protected]", // converted to AIDL, b/205760843
91     "[email protected]", // GNSS converted to AIDL, b/206670536
92     "[email protected]", // GNSS converted to AIDL, b/206670536
93     "[email protected]", // is sub-interface of gnss
94     "[email protected]",
95     "[email protected]",
96     "[email protected]",
97     "[email protected]", // converted to AIDL, see b/205761012
98     "[email protected]",
99     "[email protected]",
100     "[email protected]", // converted to AIDL, see b/193240715
101     "[email protected]",
102     "[email protected]",
103     "[email protected]", // converted to Stable C, see b/205761028
104     "[email protected]", // converted to AIDL, see b/177470478
105     "[email protected]", // converted to AIDL, see b/177269435
106     "[email protected]", // converted to AIDL, see b/205761620
107     "[email protected]", // converted to AIDL, see b/205000342
108     "[email protected]",
109     "[email protected]", // Replaced by AIDL KeyMint, see b/111446262
110     "[email protected]",
111     "[email protected]",
112     "[email protected]",
113     "[email protected]", // deprecated b/205761766
114     "[email protected]",
115     "[email protected]", // converted to AIDL, see b/161428342
116     "[email protected]",
117     "[email protected]", // converted to AIDL, see b/176107318 b/282160400
118     "[email protected]",
119     "[email protected]",
120     "[email protected]", // converted to AIDL
121     "[email protected]", // converted to AIDL
122     "[email protected]",
123     "[email protected]",
124     "[email protected]",
125     "[email protected]",
126     "[email protected]",
127     "[email protected]",
128     "[email protected]",
129     "[email protected]", // see b/170699770
130     "[email protected]",
131     "[email protected]", // Converted to AIDL (see b/205762943)
132     "[email protected]",
133     "[email protected]",
134     "[email protected]",
135     "[email protected]", // migrated to AIDL see b/200993386
136     "[email protected]",
137     "[email protected]",
138     "[email protected]",
139     "[email protected]",
140     "[email protected]", // Converted to AIDL (see b/205044134)
141     "[email protected]", // Converted to AIDL (see b/194806512)
142     "[email protected]", // Converted to AIDL (see b/196235436)
143     "[email protected]",
144     "[email protected]",
145     "[email protected]", // Deprecated (see b/205764958)
146     "[email protected]", // Converted to AIDL (see b/205764585)
147     "[email protected]", // Converted to AIDL (see b/170260236)
148     "[email protected]", // Converted to AIDL (see b/205764502)
149 };
150 // clang-format on
151 
152 struct VersionedAidlPackage {
153   std::string name;
154   size_t version;
155   int bugNum;
operator <VersionedAidlPackage156   bool operator<(const VersionedAidlPackage& rhs) const {
157     return (name < rhs.name || (name == rhs.name && version < rhs.version));
158   }
159 };
160 
161 static const std::set<std::string> kPhoneOnlyAidl = {
162     "android.hardware.camera.provider",
163 };
164 
165 static const std::set<std::string> kAutomotiveOnlyAidl = {
166     /**
167      * These types are only used in Android Automotive, so don't expect them
168      * on phones.
169      */
170     "android.automotive.watchdog",
171     "android.frameworks.automotive.display",
172     "android.frameworks.automotive.powerpolicy",
173     "android.frameworks.automotive.powerpolicy.internal",
174     "android.frameworks.automotive.telemetry",
175     "android.hardware.automotive.audiocontrol",
176     "android.hardware.automotive.can",
177     "android.hardware.broadcastradio",
178     "android.hardware.automotive.occupant_awareness",
179     "android.hardware.automotive.remoteaccess",
180     "android.hardware.automotive.vehicle",
181     "android.hardware.automotive.ivn",
182     "android.hardware.macsec",
183 };
184 
185 static const std::set<std::string> kTvOnlyAidl = {
186     /**
187      * These types are only used in Android TV, so don't expect them on other
188      * devices.
189      * TODO(b/266868403) This test should run on TV devices to enforce the same
190      * requirements
191      */
192     "android.hardware.tv.hdmi.cec",        "android.hardware.tv.hdmi.earc",
193     "android.hardware.tv.hdmi.connection", "android.hardware.tv.tuner",
194     "android.hardware.tv.input",           "android.hardware.tv.mediaquality",
195 };
196 
197 static const std::set<std::string> kRadioOnlyAidl = {
198     // Not all devices have radio capabilities
199     "android.hardware.radio.config",    "android.hardware.radio.data",
200     "android.hardware.radio.messaging", "android.hardware.radio.modem",
201     "android.hardware.radio.network",   "android.hardware.radio.sap",
202     "android.hardware.radio.sim",       "android.hardware.radio.voice",
203     "android.hardware.radio.ims",       "android.hardware.radio.ims.media",
204     "android.hardware.radio.satellite",
205 
206 };
207 
208 /*
209  * Always missing AIDL packages that are not served on Cuttlefish.
210  * These are typically types-only packages.
211  */
212 static const std::set<std::string> kAlwaysMissingAidl = {
213     // types-only packages, which never expect a default implementation
214     "android.frameworks.cameraservice.common",
215     "android.frameworks.cameraservice.device",
216     "android.hardware.audio.common",
217     "android.hardware.audio.core.sounddose",
218     "android.hardware.biometrics.common",
219     "android.hardware.camera.common",
220     "android.hardware.camera.device",
221     "android.hardware.camera.metadata",
222     "android.hardware.common",
223     "android.hardware.common.fmq",
224     "android.hardware.drm.common",
225     "android.hardware.graphics.common",
226     "android.hardware.input.common",
227     "android.media.audio.common.types",
228     "android.media.audio.eraser.types",
229     "android.hardware.radio",
230     "android.hardware.uwb.fira_android",
231     "android.hardware.wifi.common",
232     "android.hardware.keymaster",
233     "android.hardware.automotive.vehicle.property",
234     // not on Cuttlefish since it's needed only on systems using HIDL audio HAL
235     "android.hardware.audio.sounddose",
236 
237     // android.hardware.media.bufferpool2 is a HAL-less interface.
238     // It could be used for buffer recycling and caching by using the interface.
239     "android.hardware.media.bufferpool2",
240 
241     /**
242      * No implementation on cuttlefish for fastboot AIDL hal because it doesn't
243      * run during normal boot, only in recovery/fastboot mode.
244      */
245     "android.hardware.fastboot",
246     /**
247      * No implementation for usb gadget HAL because cuttlefish doesn't
248      * support usb gadget configfs, and currently there is no
249      * plan to add this support.
250      * Context: (b/130076572, g/android-idl-discuss/c/0SaiY0p-vJw/)
251      */
252     "android.hardware.usb.gadget",
253     // Currently this HAL only implements a feature for protected VMs, and the
254     // reference implementation of this HAL only works with pKVM hypervisor.
255     // TODO(b/360102915): remove this after implementing no-op version of HAL
256     //  for cuttlefish.
257     "android.hardware.virtualization.capabilities.capabilities_service",
258 };
259 
260 /*
261  * These packages should have implementations but currently do not.
262  * These must be accompanied by a bug and expected to be here temporarily.
263  */
264 static const std::vector<VersionedAidlPackage> kKnownMissingAidl = {
265     // Cuttlefish Identity Credential HAL implementation is currently
266     // stuck at version 3 while RKP support is being added. Will be
267     // updated soon.
268     {"android.hardware.identity.", 4, 266869317},
269     {"android.hardware.identity.", 5, 266869317},
270 
271     {"android.se.omapi.", 1, 266870904},
272     {"android.hardware.soundtrigger3.", 3, 266941225},
273     {"android.media.soundtrigger.", 3, 266941225},
274     {"android.hardware.weaver.", 2, 262418065},
275 
276     {"android.automotive.computepipe.registry.", 2, 273549907},
277     {"android.automotive.computepipe.runner.", 2, 273549907},
278     {"android.hardware.automotive.evs.", 2, 274162534},
279     {"android.hardware.security.see.authmgr.", 1, 379940224},
280     {"android.hardware.security.see.storage.", 1, 379940224},
281     {"android.hardware.security.see.hwcrypto.", 1, 379940224},
282     {"android.hardware.security.see.hdcp.", 1, 379940224},
283     {"android.system.vold.", 1, 362567323},
284 };
285 
286 // android.hardware.foo.IFoo -> android.hardware.foo.
getAidlPackage(const std::string & aidlType)287 std::string getAidlPackage(const std::string& aidlType) {
288   size_t lastDot = aidlType.rfind('.');
289   CHECK(lastDot != std::string::npos);
290   return aidlType.substr(0, lastDot + 1);
291 }
292 
isAospAidlInterface(const std::string & name)293 static bool isAospAidlInterface(const std::string& name) {
294   return base::StartsWith(name, "android.") &&
295          !base::StartsWith(name, "android.hardware.tests.") &&
296          !base::StartsWith(name, "android.aidl.tests");
297 }
298 
299 enum class DeviceType {
300   UNKNOWN,
301   AUTOMOTIVE,
302   TV,
303   WATCH,
304   PHONE,
305 };
306 
getDeviceType()307 static DeviceType getDeviceType() {
308   static DeviceType type = DeviceType::UNKNOWN;
309   if (type != DeviceType::UNKNOWN) {
310     return type;
311   }
312 
313   sp<IBinder> binder =
314       defaultServiceManager()->waitForService(String16("package_native"));
315   sp<content::pm::IPackageManagerNative> packageManager =
316       interface_cast<content::pm::IPackageManagerNative>(binder);
317   CHECK(packageManager != nullptr);
318 
319   bool hasFeature = false;
320   // PackageManager.FEATURE_AUTOMOTIVE
321   CHECK(packageManager
322             ->hasSystemFeature(String16("android.hardware.type.automotive"), 0,
323                                &hasFeature)
324             .isOk());
325   if (hasFeature) {
326     return DeviceType::AUTOMOTIVE;
327   }
328 
329   // PackageManager.FEATURE_LEANBACK
330   CHECK(packageManager
331             ->hasSystemFeature(String16("android.software.leanback"), 0,
332                                &hasFeature)
333             .isOk());
334   if (hasFeature) {
335     return DeviceType::TV;
336   }
337 
338   // PackageManager.FEATURE_WATCH
339   CHECK(packageManager
340             ->hasSystemFeature(String16("android.hardware.type.watch"), 0,
341                                &hasFeature)
342             .isOk());
343   if (hasFeature) {
344     return DeviceType::WATCH;
345   }
346 
347   return DeviceType::PHONE;
348 }
349 
isMissingAidl(const std::string & packageName)350 static bool isMissingAidl(const std::string& packageName) {
351   static std::once_flag unionFlag;
352   static std::set<std::string> missingAidl = kAlwaysMissingAidl;
353 
354   std::call_once(unionFlag, [&]() {
355     const DeviceType type = getDeviceType();
356     switch (type) {
357       case DeviceType::AUTOMOTIVE:
358         missingAidl.insert(kPhoneOnlyAidl.begin(), kPhoneOnlyAidl.end());
359         missingAidl.insert(kTvOnlyAidl.begin(), kTvOnlyAidl.end());
360         break;
361       case DeviceType::TV:
362         missingAidl.insert(kAutomotiveOnlyAidl.begin(),
363                            kAutomotiveOnlyAidl.end());
364         missingAidl.insert(kRadioOnlyAidl.begin(), kRadioOnlyAidl.end());
365         break;
366       case DeviceType::WATCH:
367         missingAidl.insert(kAutomotiveOnlyAidl.begin(),
368                            kAutomotiveOnlyAidl.end());
369         missingAidl.insert(kPhoneOnlyAidl.begin(), kPhoneOnlyAidl.end());
370         missingAidl.insert(kTvOnlyAidl.begin(), kTvOnlyAidl.end());
371         break;
372       case DeviceType::PHONE:
373         missingAidl.insert(kAutomotiveOnlyAidl.begin(),
374                            kAutomotiveOnlyAidl.end());
375         missingAidl.insert(kTvOnlyAidl.begin(), kTvOnlyAidl.end());
376         break;
377       case DeviceType::UNKNOWN:
378         CHECK(false) << "getDeviceType return UNKNOWN type.";
379         break;
380     }
381   });
382 
383   return missingAidl.find(packageName) != missingAidl.end();
384 }
385 
allAidlManifestInterfaces()386 static std::vector<VersionedAidlPackage> allAidlManifestInterfaces() {
387   std::vector<VersionedAidlPackage> ret;
388   auto setInserter = [&](const vintf::ManifestInstance& i) -> bool {
389     if (i.format() != vintf::HalFormat::AIDL) {
390       return true;  // continue
391     }
392     ret.push_back({i.package() + "." + i.interface(), i.version().minorVer, 0});
393     return true;  // continue
394   };
395   vintf::VintfObject::GetDeviceHalManifest()->forEachInstance(setInserter);
396   vintf::VintfObject::GetFrameworkHalManifest()->forEachInstance(setInserter);
397   return ret;
398 }
399 
TEST(Hal,AllAidlInterfacesAreInAosp)400 TEST(Hal, AllAidlInterfacesAreInAosp) {
401   if (!kAidlUseUnfrozen) {
402     GTEST_SKIP() << "Not valid in 'next' configuration";
403   }
404   if (getDeviceType() != DeviceType::PHONE) {
405     GTEST_SKIP() << "Test only supports phones right now";
406   }
407   for (const auto& package : allAidlManifestInterfaces()) {
408     EXPECT_TRUE(isAospAidlInterface(package.name))
409         << "This device should only have AOSP interfaces, not: "
410         << package.name;
411   }
412 }
413 
414 struct AidlPackageCheck {
415   bool hasRegistration;
416   bool knownMissing;
417 };
418 
TEST(Hal,AidlInterfacesImplemented)419 TEST(Hal, AidlInterfacesImplemented) {
420   if (!kAidlUseUnfrozen) {
421     GTEST_SKIP() << "Not valid in 'next' configuration";
422   }
423   if (getDeviceType() != DeviceType::PHONE) {
424     GTEST_SKIP() << "Test only supports phones right now";
425   }
426   std::vector<VersionedAidlPackage> manifest = allAidlManifestInterfaces();
427   std::vector<VersionedAidlPackage> thoughtMissing = kKnownMissingAidl;
428 
429   for (const auto& treePackage : AidlInterfaceMetadata::all()) {
430     ASSERT_FALSE(treePackage.types.empty()) << treePackage.name;
431     if (std::none_of(treePackage.types.begin(), treePackage.types.end(),
432                      isAospAidlInterface) ||
433         isMissingAidl(treePackage.name)) {
434       continue;
435     }
436     if (treePackage.stability != "vintf") {
437       continue;
438     }
439 
440     // expect versions from 1 to latest version. If the package has development
441     // the latest version is the latest known version + 1. Each of these need
442     // to be checked for registration and knownMissing.
443     std::map<size_t, AidlPackageCheck> expectedVersions;
444     for (const auto version : treePackage.versions) {
445       expectedVersions[version] = {false, false};
446     }
447     if (treePackage.has_development) {
448       size_t version =
449           treePackage.versions.empty() ? 1 : *treePackage.versions.rbegin() + 1;
450       expectedVersions[version] = {false, false};
451     }
452 
453     // Check all types and versions defined by the package for registration.
454     // The package version is considered registered if any of those types are
455     // present in the manifest with the same version.
456     // The package version is considered known missing if it is found in
457     // thoughtMissing.
458     bool latestRegistered = false;
459     for (const std::string& type : treePackage.types) {
460       for (auto& [version, check] : expectedVersions) {
461         auto it = std::remove_if(
462             manifest.begin(), manifest.end(),
463             [&type, &ver = version](const VersionedAidlPackage& package) {
464               return package.name == type && package.version == ver;
465             });
466         if (it != manifest.end()) {
467           manifest.erase(it, manifest.end());
468           if (version == expectedVersions.rbegin()->first) {
469             latestRegistered = true;
470           }
471           check.hasRegistration = true;
472         }
473         it = std::remove_if(
474             thoughtMissing.begin(), thoughtMissing.end(),
475             [&type, &ver = version](const VersionedAidlPackage& package) {
476               return package.name == getAidlPackage(type) &&
477                      package.version == ver;
478             });
479         if (it != thoughtMissing.end()) {
480           thoughtMissing.erase(it, thoughtMissing.end());
481           check.knownMissing = true;
482         }
483       }
484     }
485 
486     if (!latestRegistered && !expectedVersions.rbegin()->second.knownMissing) {
487       ADD_FAILURE() << "The latest version ("
488                     << expectedVersions.rbegin()->first
489                     << ") of the module is not implemented: "
490                     << treePackage.name
491                     << " which declares the following types:\n    "
492                     << base::Join(treePackage.types, "\n    ");
493     }
494 
495     for (const auto& [version, check] : expectedVersions) {
496       if (check.knownMissing) {
497         if (check.hasRegistration) {
498           ADD_FAILURE() << "Package in missing list, but available: "
499                         << treePackage.name << " V" << version
500                         << " which declares the following types:\n    "
501                         << base::Join(treePackage.types, "\n    ");
502         }
503 
504         continue;
505       }
506     }
507   }
508 
509   for (const auto& package : thoughtMissing) {
510     ADD_FAILURE() << "Interface in missing list and cannot find it anywhere: "
511                   << package.name << " V" << package.version;
512   }
513 
514   for (const auto& package : manifest) {
515     ADD_FAILURE() << "Can't find manifest entry in tree: " << package.name
516                   << " version: " << package.version;
517   }
518 }
519