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