diff options
| -rw-r--r-- | android/allowlists/allowlists.go | 293 | ||||
| -rw-r--r-- | android/bazel.go | 4 | ||||
| -rw-r--r-- | android/bazel_paths.go | 4 | ||||
| -rw-r--r-- | android/deptag.go | 4 | ||||
| -rw-r--r-- | android/license_metadata.go | 2 | ||||
| -rw-r--r-- | android/module.go | 30 | ||||
| -rw-r--r-- | android/override_module.go | 51 | ||||
| -rw-r--r-- | android/packaging_test.go | 4 | ||||
| -rw-r--r-- | apex/apex.go | 22 | ||||
| -rw-r--r-- | apex/apex_test.go | 55 | ||||
| -rw-r--r-- | apex/bp2build_test.go | 278 | ||||
| -rw-r--r-- | cc/androidmk.go | 13 | ||||
| -rw-r--r-- | cc/sdk.go | 6 | ||||
| -rw-r--r-- | cc/sdk_test.go | 92 | ||||
| -rw-r--r-- | cmd/soong_build/main.go | 50 | ||||
| -rwxr-xr-x | java/app.go | 58 | ||||
| -rw-r--r-- | java/app_import.go | 4 | ||||
| -rw-r--r-- | java/app_test.go | 48 | ||||
| -rw-r--r-- | scripts/Android.bp | 17 | ||||
| -rw-r--r-- | scripts/check_boot_jars/package_allowed_list.txt | 1 | ||||
| -rwxr-xr-x | scripts/modify_permissions_allowlist.py | 70 | ||||
| -rwxr-xr-x | scripts/modify_permissions_allowlist_test.py | 76 | ||||
| -rw-r--r-- | sh/sh_binary.go | 14 | ||||
| -rw-r--r-- | ui/build/rbe.go | 2 |
24 files changed, 667 insertions, 531 deletions
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go index 433c06357..67f3132a1 100644 --- a/android/allowlists/allowlists.go +++ b/android/allowlists/allowlists.go @@ -38,7 +38,13 @@ const ( // allows modules to opt-in. Bp2BuildDefaultFalseRecursively - DEFAULT_NINJA_WEIGHT = 1000 + // Modules with build time of more than half a minute should have high priority. + DEFAULT_PRIORITIZED_WEIGHT = 1000 + // Modules with build time of more than a few minute should have higher priority. + HIGH_PRIORITIZED_WEIGHT = 10 * DEFAULT_PRIORITIZED_WEIGHT + // Modules with inputs greater than the threshold should have high priority. + // Adjust this threshold if there are lots of wrong predictions. + INPUT_SIZE_THRESHOLD = 50 ) var ( @@ -59,7 +65,9 @@ var ( "build/bazel": Bp2BuildDefaultTrueRecursively, "build/make/target/product/security": Bp2BuildDefaultTrue, + "build/make/tools/protos": Bp2BuildDefaultTrue, "build/make/tools/releasetools": Bp2BuildDefaultTrue, + "build/make/tools/sbom": Bp2BuildDefaultTrue, "build/make/tools/signapk": Bp2BuildDefaultTrue, "build/make/tools/zipalign": Bp2BuildDefaultTrueRecursively, "build/soong": Bp2BuildDefaultTrue, @@ -449,9 +457,8 @@ var ( "libidmap2_policies", "libSurfaceFlingerProp", // cc mainline modules - "code_coverage.policy", - "code_coverage.policy.other", - "codec2_soft_exports", + + // com.android.media.swcodec "com.android.media.swcodec", "com.android.media.swcodec-androidManifest", "com.android.media.swcodec-ld.config.txt", @@ -459,6 +466,12 @@ var ( "com.android.media.swcodec-mediaswcodec.rc", "com.android.media.swcodec.certificate", "com.android.media.swcodec.key", + "test_com.android.media.swcodec", + + // deps + "code_coverage.policy", + "code_coverage.policy.other", + "codec2_soft_exports", "flatbuffer_headers", "framework-connectivity-protos", "gemmlowp_headers", @@ -1435,6 +1448,9 @@ var ( "MetaDataBaseUnitTest", // depends on libstagefright "AVCUtilsUnitTest", // depends on libstagefright "ColorUtilsTest", // depends on libmediandk + + // python_test_host with test data + "sbom_writers_test", } MixedBuildsDisabledList = []string{ @@ -1562,267 +1578,12 @@ var ( // "libstagefright_flacdec", // "libutils", - // TODO(b/273282046): Make this list customizable to support various targets. - // The list of modules which are expected to spend lots of build time. - // With `--ninja_weight_source=soong`, ninja builds these modules and deps first. - HugeModulesMap = map[string]int{ - "AccountManagementApp": DEFAULT_NINJA_WEIGHT, - "ActivityManagerPerfTestsStubApp1": DEFAULT_NINJA_WEIGHT, - "ActivityManagerPerfTestsStubApp2": DEFAULT_NINJA_WEIGHT, - "ActivityManagerPerfTestsStubApp3": DEFAULT_NINJA_WEIGHT, - "api-stubs-docs-non-updatable": DEFAULT_NINJA_WEIGHT, - "AppCompatibilityTest": DEFAULT_NINJA_WEIGHT, - "AppTransitionTests": DEFAULT_NINJA_WEIGHT, - "art_compiler_tests": DEFAULT_NINJA_WEIGHT, - "art.module.intra.core.api.stubs.source": DEFAULT_NINJA_WEIGHT, - "art.module.public.api.stubs.source": DEFAULT_NINJA_WEIGHT, - "AttestationVerificationTest": DEFAULT_NINJA_WEIGHT, - "BatteryUsageStatsProtoTests": DEFAULT_NINJA_WEIGHT, - "bluetooth_test_gd_unit": DEFAULT_NINJA_WEIGHT, - "Bluetooth": DEFAULT_NINJA_WEIGHT, - "BluetoothInstrumentationTests": DEFAULT_NINJA_WEIGHT, - "Calendar": DEFAULT_NINJA_WEIGHT, - "CalendarProvider": DEFAULT_NINJA_WEIGHT, - "Camera2": DEFAULT_NINJA_WEIGHT, - "CarRotaryControllerUnitTests": DEFAULT_NINJA_WEIGHT, - "CarSettingsForUnitTesting": DEFAULT_NINJA_WEIGHT, - "CarSettingsUnitTests": DEFAULT_NINJA_WEIGHT, - "CarSystemUI-tests": DEFAULT_NINJA_WEIGHT, - "CellBroadcastApp": DEFAULT_NINJA_WEIGHT, - "CellBroadcastLegacyApp": DEFAULT_NINJA_WEIGHT, - "CellBroadcastReceiverOemUnitTests": DEFAULT_NINJA_WEIGHT, - "CellBroadcastServiceModule": DEFAULT_NINJA_WEIGHT, - "CompanionDeviceManager": DEFAULT_NINJA_WEIGHT, - "ConnectivityChecker": DEFAULT_NINJA_WEIGHT, - "Contacts": DEFAULT_NINJA_WEIGHT, - "ContactsProvider": DEFAULT_NINJA_WEIGHT, - "ContentCapturePerfTests": DEFAULT_NINJA_WEIGHT, - "CorePerfTests": DEFAULT_NINJA_WEIGHT, - "crosvm": DEFAULT_NINJA_WEIGHT, - "CtsDomainVerificationDeviceMultiUserTestCases": DEFAULT_NINJA_WEIGHT, - "CtsLogdTestCases": DEFAULT_NINJA_WEIGHT, - "CtsMediaProviderTranscodeTests": DEFAULT_NINJA_WEIGHT, - "CtsRollbackManagerHostTestHelperApp": DEFAULT_NINJA_WEIGHT, - "CtsRollbackManagerHostTestHelperApp2": DEFAULT_NINJA_WEIGHT, - "CtsRootPackageInstallerTestCases": DEFAULT_NINJA_WEIGHT, - "CtsRootRollbackManagerHostTestHelperApp": DEFAULT_NINJA_WEIGHT, - "CtsTranscodeTestAppSupportsHevc": DEFAULT_NINJA_WEIGHT, - "CtsTranscodeTestAppSupportsSlowMotion": DEFAULT_NINJA_WEIGHT, - "CuttlefishDisplayHotplugHelperApp": DEFAULT_NINJA_WEIGHT, - "cvd-host_package": DEFAULT_NINJA_WEIGHT, - "DelegateTestApp": DEFAULT_NINJA_WEIGHT, - "DeskClock": DEFAULT_NINJA_WEIGHT, - "Development": DEFAULT_NINJA_WEIGHT, - "DeviceAdminTestApp": DEFAULT_NINJA_WEIGHT, - "DevicePolicyManagementRoleHolderTestApp": DEFAULT_NINJA_WEIGHT, - "dex2oatd": DEFAULT_NINJA_WEIGHT, - "DocumentsUI": DEFAULT_NINJA_WEIGHT, - "EasterEgg": DEFAULT_NINJA_WEIGHT, - "EffectProxyTest": DEFAULT_NINJA_WEIGHT, - "EmergencyInfo": DEFAULT_NINJA_WEIGHT, - "EmptyTestApp": DEFAULT_NINJA_WEIGHT, - "ExtServices": DEFAULT_NINJA_WEIGHT, - "FacebookAppsScenarioTests": DEFAULT_NINJA_WEIGHT, - "flickerlib-core": DEFAULT_NINJA_WEIGHT, - "flickerlib": DEFAULT_NINJA_WEIGHT, - "FlickerLibTest": DEFAULT_NINJA_WEIGHT, - "FlickerTests": DEFAULT_NINJA_WEIGHT, - "framework-minus-apex": DEFAULT_NINJA_WEIGHT, - "framework-res": DEFAULT_NINJA_WEIGHT, - "FrameworksCoreTests": DEFAULT_NINJA_WEIGHT, - "FrameworksMockingCoreTests": DEFAULT_NINJA_WEIGHT, - "FrameworksMockingServicesTests": DEFAULT_NINJA_WEIGHT, - "FrameworksNetSmokeTests": DEFAULT_NINJA_WEIGHT, - "FrameworksNetTests": DEFAULT_NINJA_WEIGHT, - "FrameworksServicesTests": DEFAULT_NINJA_WEIGHT, - "FrameworksTelephonyTests": DEFAULT_NINJA_WEIGHT, - "FrameworksUiServicesTests": DEFAULT_NINJA_WEIGHT, - "FrameworksVcnTests": DEFAULT_NINJA_WEIGHT, - "Gallery2": DEFAULT_NINJA_WEIGHT, - "GameCoreDevice": DEFAULT_NINJA_WEIGHT, - "GoogleBluetoothInstrumentationTests": DEFAULT_NINJA_WEIGHT, - "guice_munged_srcs": DEFAULT_NINJA_WEIGHT, - "HalfSheetUX": DEFAULT_NINJA_WEIGHT, - "ImePerfTests": DEFAULT_NINJA_WEIGHT, - "imgdiag": DEFAULT_NINJA_WEIGHT, - "ImsServiceEntitlement": DEFAULT_NINJA_WEIGHT, - "ImsServiceEntitlementUnitTests": DEFAULT_NINJA_WEIGHT, - "InputTests": DEFAULT_NINJA_WEIGHT, - "InstallTest": DEFAULT_NINJA_WEIGHT, - "IntentResolver": DEFAULT_NINJA_WEIGHT, - "JankBench": DEFAULT_NINJA_WEIGHT, - "jsilver": DEFAULT_NINJA_WEIGHT, - "KeyChain": DEFAULT_NINJA_WEIGHT, - "KeyChainTests": DEFAULT_NINJA_WEIGHT, - "keystore2": DEFAULT_NINJA_WEIGHT, - "LargeResourcesCompressed": DEFAULT_NINJA_WEIGHT, - "LatinIME": DEFAULT_NINJA_WEIGHT, - "Launcher3QuickStepLib": DEFAULT_NINJA_WEIGHT, - "libaom": DEFAULT_NINJA_WEIGHT, - "libart-broken": DEFAULT_NINJA_WEIGHT, - "libart-compiler": DEFAULT_NINJA_WEIGHT, - "libart-disassembler": DEFAULT_NINJA_WEIGHT, - "libart": DEFAULT_NINJA_WEIGHT, - "libartd": DEFAULT_NINJA_WEIGHT, - "libaudiohal@7.1": DEFAULT_NINJA_WEIGHT, - "libbluetooth_core_rs": DEFAULT_NINJA_WEIGHT, - "libbluetooth_gd_unit_tests": DEFAULT_NINJA_WEIGHT, - "libbluetooth_gd": DEFAULT_NINJA_WEIGHT, - "libbluetooth_rs": DEFAULT_NINJA_WEIGHT, - "libbluetooth-for-tests": DEFAULT_NINJA_WEIGHT, - "libbt_common": DEFAULT_NINJA_WEIGHT, - "libbt_packets_nonapex": DEFAULT_NINJA_WEIGHT, - "libbt_packets": DEFAULT_NINJA_WEIGHT, - "libbt_shim_ffi": DEFAULT_NINJA_WEIGHT, - "libbt_shim": DEFAULT_NINJA_WEIGHT, - "libbt-audio-hal-interface": DEFAULT_NINJA_WEIGHT, - "libbt-bta-core": DEFAULT_NINJA_WEIGHT, - "libbt-bta": DEFAULT_NINJA_WEIGHT, - "libbt-common": DEFAULT_NINJA_WEIGHT, - "libbt-hci": DEFAULT_NINJA_WEIGHT, - "libbt-platform-protos-lite": DEFAULT_NINJA_WEIGHT, - "libbt-protos-lite": DEFAULT_NINJA_WEIGHT, - "libbt-sbc-decoder": DEFAULT_NINJA_WEIGHT, - "libc": DEFAULT_NINJA_WEIGHT, - "libclap": DEFAULT_NINJA_WEIGHT, - "libcodec2_soft_av1dec_gav1": DEFAULT_NINJA_WEIGHT, - "libcompositionengine_test": DEFAULT_NINJA_WEIGHT, - "libdevices": DEFAULT_NINJA_WEIGHT, - "libfrontend_proto": DEFAULT_NINJA_WEIGHT, - "libhwtrust": DEFAULT_NINJA_WEIGHT, - "libjni": DEFAULT_NINJA_WEIGHT, - "libkeystore2": DEFAULT_NINJA_WEIGHT, - "libkmr_ta": DEFAULT_NINJA_WEIGHT, - "liblmp": DEFAULT_NINJA_WEIGHT, - "libopenjdkjvmtid": DEFAULT_NINJA_WEIGHT, - "libprotobuf_deprecated": DEFAULT_NINJA_WEIGHT, - "libprotobuf": DEFAULT_NINJA_WEIGHT, - "libregex": DEFAULT_NINJA_WEIGHT, - "LibStatsPullTests": DEFAULT_NINJA_WEIGHT, - "libstd": DEFAULT_NINJA_WEIGHT, - "libsurfaceflinger_unittest": DEFAULT_NINJA_WEIGHT, - "libsyn": DEFAULT_NINJA_WEIGHT, - "libtokio": DEFAULT_NINJA_WEIGHT, - "libuwb_core": DEFAULT_NINJA_WEIGHT, - "libuwb_uci_jni_rust": DEFAULT_NINJA_WEIGHT, - "libuwb_uci_packets": DEFAULT_NINJA_WEIGHT, - "libvpx": DEFAULT_NINJA_WEIGHT, - "libvulkan_enc": DEFAULT_NINJA_WEIGHT, - "libwebrtc": DEFAULT_NINJA_WEIGHT, - "LiveWallpapersPicker": DEFAULT_NINJA_WEIGHT, - "LockTaskApp": DEFAULT_NINJA_WEIGHT, - "LongevityPlatformLibTests": DEFAULT_NINJA_WEIGHT, - "ManagedProvisioning": DEFAULT_NINJA_WEIGHT, - "ManagedProvisioningTests": DEFAULT_NINJA_WEIGHT, - "MediaProvider": DEFAULT_NINJA_WEIGHT, - "MediaProviderClientTests": DEFAULT_NINJA_WEIGHT, - "MediaProviderLegacy": DEFAULT_NINJA_WEIGHT, - "messaging": DEFAULT_NINJA_WEIGHT, - "metalava": DEFAULT_NINJA_WEIGHT, - "MicrobenchmarkRunnerTests": DEFAULT_NINJA_WEIGHT, - "microdroid_manager": DEFAULT_NINJA_WEIGHT, - "minikin_tests": DEFAULT_NINJA_WEIGHT, - "MLCTestApp": DEFAULT_NINJA_WEIGHT, - "MmsService": DEFAULT_NINJA_WEIGHT, - "MmsServiceTests": DEFAULT_NINJA_WEIGHT, - "module-lib-api-stubs-docs-non-updatable": DEFAULT_NINJA_WEIGHT, - "motion_tool_lib_tests": DEFAULT_NINJA_WEIGHT, - "MtpService": DEFAULT_NINJA_WEIGHT, - "MultiUserTests": DEFAULT_NINJA_WEIGHT, - "NearbyIntegrationUiTests": DEFAULT_NINJA_WEIGHT, - "net_test_bluetooth": DEFAULT_NINJA_WEIGHT, - "net_test_btif": DEFAULT_NINJA_WEIGHT, - "net_test_main_shim": DEFAULT_NINJA_WEIGHT, - "net_test_stack": DEFAULT_NINJA_WEIGHT, - "net-tests-utils": DEFAULT_NINJA_WEIGHT, - "NetworkStackCoverageTests": DEFAULT_NINJA_WEIGHT, - "NetworkStackIntegrationTests": DEFAULT_NINJA_WEIGHT, - "NetworkStackNext": DEFAULT_NINJA_WEIGHT, - "NfcNci": DEFAULT_NINJA_WEIGHT, - "NfcNciUnitTests": DEFAULT_NINJA_WEIGHT, - "NotEmptyTestApp": DEFAULT_NINJA_WEIGHT, - "NotificationFunctionalTests": DEFAULT_NINJA_WEIGHT, - "oatdumpd": DEFAULT_NINJA_WEIGHT, - "OsuLogin": DEFAULT_NINJA_WEIGHT, - "PackageInstaller": DEFAULT_NINJA_WEIGHT, - "PackageManagerComponentOverrideTests": DEFAULT_NINJA_WEIGHT, - "PackageManagerPerfTests": DEFAULT_NINJA_WEIGHT, - "PackageManagerServiceServerTests": DEFAULT_NINJA_WEIGHT, - "PackageManagerServiceUnitTests": DEFAULT_NINJA_WEIGHT, - "PackageWatchdogTest": DEFAULT_NINJA_WEIGHT, - "PandoraServerLib": DEFAULT_NINJA_WEIGHT, - "pdl": DEFAULT_NINJA_WEIGHT, - "perfetto_trace_java_protos": DEFAULT_NINJA_WEIGHT, - "perfetto_trace-full": DEFAULT_NINJA_WEIGHT, - "PermissionController": DEFAULT_NINJA_WEIGHT, - "PermissionControllerMockingTests": DEFAULT_NINJA_WEIGHT, - "PixelAppCompTests": DEFAULT_NINJA_WEIGHT, - "platform-bootclasspath": DEFAULT_NINJA_WEIGHT, - "PlatformCommonScenarioTests": DEFAULT_NINJA_WEIGHT, - "PlatformComposeCoreTests": DEFAULT_NINJA_WEIGHT, - "platformprotoslite": DEFAULT_NINJA_WEIGHT, - "PlatformRuleTests": DEFAULT_NINJA_WEIGHT, - "precompiled_sepolicy-without_apex": DEFAULT_NINJA_WEIGHT, - "PresencePolling": DEFAULT_NINJA_WEIGHT, - "PrintSpooler": DEFAULT_NINJA_WEIGHT, - "QuickSearchBox": DEFAULT_NINJA_WEIGHT, - "RemoteDPCTestApp": DEFAULT_NINJA_WEIGHT, - "RemoteProvisioningServiceTests": DEFAULT_NINJA_WEIGHT, - "RkpdAppUnitTests": DEFAULT_NINJA_WEIGHT, - "Robolectric_shadows_framework": DEFAULT_NINJA_WEIGHT, - "RoleHolderApp": DEFAULT_NINJA_WEIGHT, - "SdkSandbox": DEFAULT_NINJA_WEIGHT, - "service-appsearch": DEFAULT_NINJA_WEIGHT, - "service-connectivity": DEFAULT_NINJA_WEIGHT, - "service-uwb": DEFAULT_NINJA_WEIGHT, - "service-wifi": DEFAULT_NINJA_WEIGHT, - "services-non-updatable-stubs": DEFAULT_NINJA_WEIGHT, - "services": DEFAULT_NINJA_WEIGHT, - "Settings-core": DEFAULT_NINJA_WEIGHT, - "Settings": DEFAULT_NINJA_WEIGHT, - "SettingsIntelligence": DEFAULT_NINJA_WEIGHT, - "SettingsLibTests": DEFAULT_NINJA_WEIGHT, - "SettingsProvider": DEFAULT_NINJA_WEIGHT, - "Shell": DEFAULT_NINJA_WEIGHT, - "SimAppDialog": DEFAULT_NINJA_WEIGHT, - "sl4a": DEFAULT_NINJA_WEIGHT, - "SmsApp": DEFAULT_NINJA_WEIGHT, - "SoundPicker": DEFAULT_NINJA_WEIGHT, - "StagedInstallTest": DEFAULT_NINJA_WEIGHT, - "StatementService": DEFAULT_NINJA_WEIGHT, - "StatsdFrameworkTestApp": DEFAULT_NINJA_WEIGHT, - "StatsdFrameworkTestAppNoPermission": DEFAULT_NINJA_WEIGHT, - "statsdprotolite": DEFAULT_NINJA_WEIGHT, - "Stk": DEFAULT_NINJA_WEIGHT, - "StorageManager": DEFAULT_NINJA_WEIGHT, - "system-api-stubs-docs-non-updatable": DEFAULT_NINJA_WEIGHT, - "SystemUI-core": DEFAULT_NINJA_WEIGHT, - "SystemUI-tests-base": DEFAULT_NINJA_WEIGHT, - "SystemUI-tests": DEFAULT_NINJA_WEIGHT, - "SystemUI": DEFAULT_NINJA_WEIGHT, - "SystemUIComposeFeatures": DEFAULT_NINJA_WEIGHT, - "SystemUIComposeFeaturesTests": DEFAULT_NINJA_WEIGHT, - "SystemUITests": DEFAULT_NINJA_WEIGHT, - "Tag": DEFAULT_NINJA_WEIGHT, - "Telecom": DEFAULT_NINJA_WEIGHT, - "TelecomUnitTests": DEFAULT_NINJA_WEIGHT, - "telephony-common": DEFAULT_NINJA_WEIGHT, - "TelephonyProvider": DEFAULT_NINJA_WEIGHT, - "TeleService": DEFAULT_NINJA_WEIGHT, - "test-api-stubs-docs-non-updatable": DEFAULT_NINJA_WEIGHT, - "TetheringIntegrationTests": DEFAULT_NINJA_WEIGHT, - "TetheringNext": DEFAULT_NINJA_WEIGHT, - "ThemePickerTests": DEFAULT_NINJA_WEIGHT, - "Traceur": DEFAULT_NINJA_WEIGHT, - "UsbManagerTests": DEFAULT_NINJA_WEIGHT, - "UsbTests": DEFAULT_NINJA_WEIGHT, - "virtmgr": DEFAULT_NINJA_WEIGHT, - "WallpaperPicker2TestLib": DEFAULT_NINJA_WEIGHT, - "WallpaperPicker2Tests": DEFAULT_NINJA_WEIGHT, - "WifiDialog": DEFAULT_NINJA_WEIGHT, - "wm-proto-parsers": DEFAULT_NINJA_WEIGHT, - "WMShellFlickerTests": DEFAULT_NINJA_WEIGHT, - "WmTests": DEFAULT_NINJA_WEIGHT, - "wpa_supplicant": DEFAULT_NINJA_WEIGHT, + // The list of module types which are expected to spend lots of build time. + // With `--ninja_weight_source=soong`, ninja builds these module types and deps first. + HugeModuleTypePrefixMap = map[string]int{ + "rust_": HIGH_PRIORITIZED_WEIGHT, + "droidstubs": DEFAULT_PRIORITIZED_WEIGHT, + "art_": DEFAULT_PRIORITIZED_WEIGHT, + "ndk_library": DEFAULT_PRIORITIZED_WEIGHT, } ) diff --git a/android/bazel.go b/android/bazel.go index 58d9d87db..3fe063c51 100644 --- a/android/bazel.go +++ b/android/bazel.go @@ -431,7 +431,7 @@ func (b *BazelModuleBase) shouldConvertWithBp2build(ctx bazelOtherModuleContext, } propValue := b.bazelProperties.Bazel_module.Bp2build_available - packagePath := ctx.OtherModuleDir(module) + packagePath := moduleDirWithPossibleOverride(ctx, module) // Modules in unit tests which are enabled in the allowlist by type or name // trigger this conditional because unit tests run under the "." package path @@ -440,7 +440,7 @@ func (b *BazelModuleBase) shouldConvertWithBp2build(ctx bazelOtherModuleContext, return true } - moduleName := module.Name() + moduleName := moduleNameWithPossibleOverride(ctx, module) allowlist := ctx.Config().Bp2buildPackageConfig moduleNameAllowed := allowlist.moduleAlwaysConvert[moduleName] moduleTypeAllowed := allowlist.moduleTypeAlwaysConvert[ctx.OtherModuleType(module)] diff --git a/android/bazel_paths.go b/android/bazel_paths.go index bad7baf06..ddbdbd49b 100644 --- a/android/bazel_paths.go +++ b/android/bazel_paths.go @@ -453,8 +453,8 @@ func samePackage(label1, label2 string) bool { } func bp2buildModuleLabel(ctx BazelConversionContext, module blueprint.Module) string { - moduleName := ctx.OtherModuleName(module) - moduleDir := ctx.OtherModuleDir(module) + moduleName := moduleNameWithPossibleOverride(ctx, module) + moduleDir := moduleDirWithPossibleOverride(ctx, module) if moduleDir == Bp2BuildTopLevel { moduleDir = "" } diff --git a/android/deptag.go b/android/deptag.go index be5c35c8d..a15443b4a 100644 --- a/android/deptag.go +++ b/android/deptag.go @@ -34,10 +34,10 @@ func (i InstallAlwaysNeededDependencyTag) InstallDepNeeded() bool { var _ InstallNeededDependencyTag = InstallAlwaysNeededDependencyTag{} -// IsInstallDepNeeded returns true if the dependency tag implements the InstallNeededDependencyTag +// IsInstallDepNeededTag returns true if the dependency tag implements the InstallNeededDependencyTag // interface and the InstallDepNeeded returns true, meaning that the installed files of the parent // should depend on the installed files of the child. -func IsInstallDepNeeded(tag blueprint.DependencyTag) bool { +func IsInstallDepNeededTag(tag blueprint.DependencyTag) bool { if i, ok := tag.(InstallNeededDependencyTag); ok { return i.InstallDepNeeded() } diff --git a/android/license_metadata.go b/android/license_metadata.go index 18b63d310..73000a9fa 100644 --- a/android/license_metadata.go +++ b/android/license_metadata.go @@ -74,7 +74,7 @@ func buildLicenseMetadata(ctx ModuleContext, licenseMetadataFile WritablePath) { if ctx.OtherModuleHasProvider(dep, LicenseMetadataProvider) { info := ctx.OtherModuleProvider(dep, LicenseMetadataProvider).(*LicenseMetadataInfo) allDepMetadataFiles = append(allDepMetadataFiles, info.LicenseMetadataPath) - if isContainer || IsInstallDepNeeded(ctx.OtherModuleDependencyTag(dep)) { + if isContainer || isInstallDepNeeded(dep, ctx.OtherModuleDependencyTag(dep)) { allDepMetadataDepSets = append(allDepMetadataDepSets, info.LicenseMetadataDepSet) } diff --git a/android/module.go b/android/module.go index c8670c31a..db602a0aa 100644 --- a/android/module.go +++ b/android/module.go @@ -925,6 +925,12 @@ type commonProperties struct { // and don't create a rule to install the file. SkipInstall bool `blueprint:"mutated"` + // UninstallableApexPlatformVariant is set by MakeUninstallable called by the apex + // mutator. MakeUninstallable also sets HideFromMake. UninstallableApexPlatformVariant + // is used to avoid adding install or packaging dependencies into libraries provided + // by apexes. + UninstallableApexPlatformVariant bool `blueprint:"mutated"` + // Whether the module has been replaced by a prebuilt ReplacedByPrebuilt bool `blueprint:"mutated"` @@ -2009,6 +2015,7 @@ func (m *ModuleBase) IsSkipInstall() bool { // have other side effects, in particular when it adds a NOTICE file target, // which other install targets might depend on. func (m *ModuleBase) MakeUninstallable() { + m.commonProperties.UninstallableApexPlatformVariant = true m.HideFromMake() } @@ -2038,13 +2045,19 @@ func (m *ModuleBase) EffectiveLicenseFiles() Paths { } // computeInstallDeps finds the installed paths of all dependencies that have a dependency -// tag that is annotated as needing installation via the IsInstallDepNeeded method. +// tag that is annotated as needing installation via the isInstallDepNeeded method. func (m *ModuleBase) computeInstallDeps(ctx ModuleContext) ([]*installPathsDepSet, []*packagingSpecsDepSet) { var installDeps []*installPathsDepSet var packagingSpecs []*packagingSpecsDepSet ctx.VisitDirectDeps(func(dep Module) { - if IsInstallDepNeeded(ctx.OtherModuleDependencyTag(dep)) && !dep.IsHideFromMake() && !dep.IsSkipInstall() { - installDeps = append(installDeps, dep.base().installFilesDepSet) + if isInstallDepNeeded(dep, ctx.OtherModuleDependencyTag(dep)) { + // Installation is still handled by Make, so anything hidden from Make is not + // installable. + if !dep.IsHideFromMake() && !dep.IsSkipInstall() { + installDeps = append(installDeps, dep.base().installFilesDepSet) + } + // Add packaging deps even when the dependency is not installed so that uninstallable + // modules can still be packaged. Often the package will be installed instead. packagingSpecs = append(packagingSpecs, dep.base().packagingSpecsDepSet) } }) @@ -2052,6 +2065,17 @@ func (m *ModuleBase) computeInstallDeps(ctx ModuleContext) ([]*installPathsDepSe return installDeps, packagingSpecs } +// isInstallDepNeeded returns true if installing the output files of the current module +// should also install the output files of the given dependency and dependency tag. +func isInstallDepNeeded(dep Module, tag blueprint.DependencyTag) bool { + // Don't add a dependency from the platform to a library provided by an apex. + if dep.base().commonProperties.UninstallableApexPlatformVariant { + return false + } + // Only install modules if the dependency tag is an InstallDepNeeded tag. + return IsInstallDepNeededTag(tag) +} + func (m *ModuleBase) FilesToInstall() InstallPaths { return m.installFiles } diff --git a/android/override_module.go b/android/override_module.go index 86f582b76..9e95c0f10 100644 --- a/android/override_module.go +++ b/android/override_module.go @@ -28,7 +28,6 @@ package android // module based on it. import ( - "fmt" "sort" "sync" @@ -121,7 +120,7 @@ type OverridableModule interface { addOverride(o OverrideModule) getOverrides() []OverrideModule - override(ctx BaseModuleContext, o OverrideModule) + override(ctx BaseModuleContext, m Module, o OverrideModule) GetOverriddenBy() string GetOverriddenByModuleDir() string @@ -192,7 +191,8 @@ func (b *OverridableModuleBase) setOverridesProperty(overridesProperty *[]string } // Overrides a base module with the given OverrideModule. -func (b *OverridableModuleBase) override(ctx BaseModuleContext, o OverrideModule) { +func (b *OverridableModuleBase) override(ctx BaseModuleContext, m Module, o OverrideModule) { + for _, p := range b.overridableProperties { for _, op := range o.getOverridingProperties() { if proptools.TypeEqual(p, op) { @@ -214,6 +214,17 @@ func (b *OverridableModuleBase) override(ctx BaseModuleContext, o OverrideModule } b.overridableModuleProperties.OverriddenBy = o.Name() b.overridableModuleProperties.OverriddenByModuleDir = o.ModuleDir() + + if oBazelable, ok := o.base().module.(Bazelable); ok { + if bBazelable, ok := m.(Bazelable); ok { + oProps := oBazelable.bazelProps() + bProps := bBazelable.bazelProps() + bProps.Bazel_module.Bp2build_available = oProps.Bazel_module.Bp2build_available + bProps.Bazel_module.Label = oProps.Bazel_module.Label + } else { + ctx.ModuleErrorf("Override type cannot be Bazelable if original module type is not Bazelable %v %v.", o.Name(), m.Name()) + } + } } // GetOverriddenBy returns the name of the override module that has overridden this module. @@ -302,7 +313,7 @@ func performOverrideMutator(ctx BottomUpMutatorContext) { // is specified. ctx.AliasVariation(variants[0]) for i, o := range overrides { - mods[i+1].(OverridableModule).override(ctx, o) + mods[i+1].(OverridableModule).override(ctx, mods[i+1], o) if o.getOverriddenByPrebuilt() { // The overriding module itself, too, is overridden by a prebuilt. // Copy the flag and hide it in make @@ -340,34 +351,26 @@ func replaceDepsOnOverridingModuleMutator(ctx BottomUpMutatorContext) { // variant of this OverridableModule, or ctx.ModuleName() if this module is not an OverridableModule // or if this variant is not overridden. func ModuleNameWithPossibleOverride(ctx BazelConversionContext) string { - if overridable, ok := ctx.Module().(OverridableModule); ok { + return moduleNameWithPossibleOverride(ctx, ctx.Module()) +} + +func moduleNameWithPossibleOverride(ctx bazelOtherModuleContext, module blueprint.Module) string { + if overridable, ok := module.(OverridableModule); ok { if o := overridable.GetOverriddenBy(); o != "" { return o } } - return ctx.OtherModuleName(ctx.Module()) + return ctx.OtherModuleName(module) } -// ModuleDirWithPossibleOverride returns the dir of the OverrideModule that overrides the current -// variant of this OverridableModule, or ctx.ModuleName() if this module is not an OverridableModule -// or if this variant is not overridden. -func moduleDirWithPossibleOverride(ctx BazelConversionContext) string { - if overridable, ok := ctx.Module().(OverridableModule); ok { +// moduleDirWithPossibleOverride returns the dir of the OverrideModule that overrides the current +// variant of the given OverridableModule, or ctx.OtherModuleName() if the module is not an +// OverridableModule or if the variant is not overridden. +func moduleDirWithPossibleOverride(ctx bazelOtherModuleContext, module blueprint.Module) string { + if overridable, ok := module.(OverridableModule); ok { if o := overridable.GetOverriddenByModuleDir(); o != "" { return o } } - return ctx.OtherModuleDir(ctx.Module()) -} - -// MaybeBp2buildLabelOfOverridingModule returns the bazel label of the -// overriding module of an OverridableModule (e.g. override_apex label of a base -// apex), or the module's label itself if not overridden. -func MaybeBp2buildLabelOfOverridingModule(ctx BazelConversionContext) string { - moduleName := ModuleNameWithPossibleOverride(ctx) - moduleDir := moduleDirWithPossibleOverride(ctx) - if moduleDir == Bp2BuildTopLevel { - moduleDir = "" - } - return fmt.Sprintf("//%s:%s", moduleDir, moduleName) + return ctx.OtherModuleDir(module) } diff --git a/android/packaging_test.go b/android/packaging_test.go index 91ac1f386..383343723 100644 --- a/android/packaging_test.go +++ b/android/packaging_test.go @@ -373,7 +373,7 @@ func TestPackagingBaseSingleTarget(t *testing.T) { func TestPackagingWithSkipInstallDeps(t *testing.T) { // package -[dep]-> foo -[dep]-> bar -[dep]-> baz - // OK SKIPPED + // Packaging should continue transitively through modules that are not installed. multiTarget := false runPackagingTest(t, multiTarget, ` @@ -396,5 +396,5 @@ func TestPackagingWithSkipInstallDeps(t *testing.T) { name: "package", deps: ["foo"], } - `, []string{"lib64/foo"}) + `, []string{"lib64/foo", "lib64/bar", "lib64/baz"}) } diff --git a/apex/apex.go b/apex/apex.go index 69547c3b7..af9afb1ca 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -1828,6 +1828,7 @@ type androidApp interface { Certificate() java.Certificate BaseModuleName() string LintDepSets() java.LintDepSets + PrivAppAllowlist() android.OptionalPath } var _ androidApp = (*java.AndroidApp)(nil) @@ -1848,7 +1849,7 @@ func sanitizedBuildIdForPath(ctx android.BaseModuleContext) string { return buildId } -func apexFileForAndroidApp(ctx android.BaseModuleContext, aapp androidApp) apexFile { +func apexFilesForAndroidApp(ctx android.BaseModuleContext, aapp androidApp) []apexFile { appDir := "app" if aapp.Privileged() { appDir = "priv-app" @@ -1870,7 +1871,15 @@ func apexFileForAndroidApp(ctx android.BaseModuleContext, aapp androidApp) apexF }); ok { af.overriddenPackageName = app.OverriddenManifestPackageName() } - return af + apexFiles := []apexFile{af} + + if allowlist := aapp.PrivAppAllowlist(); allowlist.Valid() { + dirInApex := filepath.Join("etc", "permissions") + privAppAllowlist := newApexFile(ctx, allowlist.Path(), aapp.BaseModuleName()+"privapp", dirInApex, etc, aapp) + apexFiles = append(apexFiles, privAppAllowlist) + } + + return apexFiles } func apexFileForRuntimeResourceOverlay(ctx android.BaseModuleContext, rro java.RuntimeResourceOverlayModule) apexFile { @@ -1964,9 +1973,6 @@ func (a *apexBundle) QueueBazelCall(ctx android.BaseModuleContext) { // overridden by different override_apex modules (e.g. Google or Go variants), // which is handled by the overrides mutators. func (a *apexBundle) GetBazelLabel(ctx android.BazelConversionPathContext, module blueprint.Module) string { - if _, ok := ctx.Module().(android.OverridableModule); ok { - return android.MaybeBp2buildLabelOfOverridingModule(ctx) - } return a.BazelModuleBase.GetBazelLabel(ctx, a) } @@ -2318,12 +2324,12 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, case androidAppTag: switch ap := child.(type) { case *java.AndroidApp: - vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap)) + vctx.filesInfo = append(vctx.filesInfo, apexFilesForAndroidApp(ctx, ap)...) return true // track transitive dependencies case *java.AndroidAppImport: - vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap)) + vctx.filesInfo = append(vctx.filesInfo, apexFilesForAndroidApp(ctx, ap)...) case *java.AndroidTestHelperApp: - vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap)) + vctx.filesInfo = append(vctx.filesInfo, apexFilesForAndroidApp(ctx, ap)...) case *java.AndroidAppSet: appDir := "app" if ap.Privileged() { diff --git a/apex/apex_test.go b/apex/apex_test.go index 3ba4d8d55..e4b0323e3 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -33,6 +33,7 @@ import ( "android/soong/cc" "android/soong/dexpreopt" prebuilt_etc "android/soong/etc" + "android/soong/filesystem" "android/soong/java" "android/soong/rust" "android/soong/sh" @@ -6045,6 +6046,8 @@ func TestApexWithApps(t *testing.T) { sdk_version: "current", system_modules: "none", privileged: true, + privapp_allowlist: "perms.xml", + package_name: "com.android.AppFooPriv", stl: "none", apex_available: [ "myapex" ], } @@ -6074,6 +6077,7 @@ func TestApexWithApps(t *testing.T) { ensureContains(t, copyCmds, "image.apex/app/AppFoo@TEST.BUILD_ID/AppFoo.apk") ensureContains(t, copyCmds, "image.apex/priv-app/AppFooPriv@TEST.BUILD_ID/AppFooPriv.apk") + ensureContains(t, copyCmds, "image.apex/etc/permissions/privapp_allowlist_com.android.AppFooPriv.xml") appZipRule := ctx.ModuleForTests("AppFoo", "android_common_apex10000").Description("zip jni libs") // JNI libraries are uncompressed @@ -10375,3 +10379,54 @@ func TestStubLibrariesMultipleApexViolation(t *testing.T) { } } } + +func TestFileSystemShouldSkipApexLibraries(t *testing.T) { + context := android.GroupFixturePreparers( + android.PrepareForIntegrationTestWithAndroid, + cc.PrepareForIntegrationTestWithCc, + PrepareForTestWithApexBuildComponents, + prepareForTestWithMyapex, + filesystem.PrepareForTestWithFilesystemBuildComponents, + ) + result := context.RunTestWithBp(t, ` + android_system_image { + name: "myfilesystem", + deps: [ + "libfoo", + ], + linker_config_src: "linker.config.json", + } + + cc_library { + name: "libfoo", + shared_libs: [ + "libbar", + ], + stl: "none", + } + + cc_library { + name: "libbar", + stl: "none", + apex_available: ["myapex"], + } + + apex { + name: "myapex", + native_shared_libs: ["libbar"], + key: "myapex.key", + updatable: false, + } + + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + `) + + inputs := result.ModuleForTests("myfilesystem", "android_common").Output("deps.zip").Implicits + android.AssertStringListDoesNotContain(t, "filesystem should not have libbar", + inputs.Strings(), + "out/soong/.intermediates/libbar/android_arm64_armv8-a_shared/libbar.so") +} diff --git a/apex/bp2build_test.go b/apex/bp2build_test.go index 2a0f6e9e2..b1b6a75e8 100644 --- a/apex/bp2build_test.go +++ b/apex/bp2build_test.go @@ -15,7 +15,10 @@ package apex import ( "android/soong/android" + "android/soong/android/allowlists" "android/soong/bazel/cquery" + "fmt" + "path/filepath" "strings" "testing" ) @@ -326,7 +329,7 @@ apex { } func TestOverrideApexImageInMixedBuilds(t *testing.T) { - bp := ` + originalBp := ` apex_key{ name: "foo_key", } @@ -340,122 +343,203 @@ apex { min_sdk_version: "31", package_name: "pkg_name", file_contexts: ":myapex-file_contexts", - bazel_module: { label: "//:foo" }, -} + %s +}` + overrideBp := ` override_apex { name: "override_foo", key: "override_foo_key", package_name: "override_pkg_name", base: "foo", - bazel_module: { label: "//:override_foo" }, + %s } ` - outputBaseDir := "out/bazel" - result := android.GroupFixturePreparers( - prepareForApexTest, - android.FixtureModifyConfig(func(config android.Config) { - config.BazelContext = android.MockBazelContext{ - OutputBaseDir: outputBaseDir, - LabelToApexInfo: map[string]cquery.ApexInfo{ - "//:foo": cquery.ApexInfo{ - // ApexInfo Starlark provider - SignedOutput: "signed_out.apex", - UnsignedOutput: "unsigned_out.apex", - BundleKeyInfo: []string{"public_key", "private_key"}, - ContainerKeyInfo: []string{"container_cert", "container_private"}, - SymbolsUsedByApex: "foo_using.txt", - JavaSymbolsUsedByApex: "foo_using.xml", - BundleFile: "apex_bundle.zip", - InstalledFiles: "installed-files.txt", - RequiresLibs: []string{"//path/c:c", "//path/d:d"}, - - // unused - PackageName: "pkg_name", - ProvidesLibs: []string{"a", "b"}, - - // ApexMkInfo Starlark provider - MakeModulesToInstall: []string{"c"}, // d deliberately omitted - }, - "//:override_foo": cquery.ApexInfo{ - // ApexInfo Starlark provider - SignedOutput: "override_signed_out.apex", - UnsignedOutput: "override_unsigned_out.apex", - BundleKeyInfo: []string{"override_public_key", "override_private_key"}, - ContainerKeyInfo: []string{"override_container_cert", "override_container_private"}, - SymbolsUsedByApex: "override_foo_using.txt", - JavaSymbolsUsedByApex: "override_foo_using.xml", - BundleFile: "override_apex_bundle.zip", - InstalledFiles: "override_installed-files.txt", - RequiresLibs: []string{"//path/c:c", "//path/d:d"}, - - // unused - PackageName: "override_pkg_name", - ProvidesLibs: []string{"a", "b"}, + originalApexBpDir := "original" + originalApexName := "foo" + overrideApexBpDir := "override" + overrideApexName := "override_foo" + + defaultApexLabel := fmt.Sprintf("//%s:%s", originalApexBpDir, originalApexName) + defaultOverrideApexLabel := fmt.Sprintf("//%s:%s", overrideApexBpDir, overrideApexName) + + testCases := []struct { + desc string + bazelModuleProp string + apexLabel string + overrideBazelModuleProp string + overrideApexLabel string + bp2buildConfiguration android.Bp2BuildConversionAllowlist + }{ + { + desc: "both explicit labels", + bazelModuleProp: `bazel_module: { label: "//:foo" },`, + apexLabel: "//:foo", + overrideBazelModuleProp: `bazel_module: { label: "//:override_foo" },`, + overrideApexLabel: "//:override_foo", + bp2buildConfiguration: android.NewBp2BuildAllowlist(), + }, + { + desc: "both explicitly allowed", + bazelModuleProp: `bazel_module: { bp2build_available: true },`, + apexLabel: defaultApexLabel, + overrideBazelModuleProp: `bazel_module: { bp2build_available: true },`, + overrideApexLabel: defaultOverrideApexLabel, + bp2buildConfiguration: android.NewBp2BuildAllowlist(), + }, + { + desc: "original allowed by dir, override allowed by name", + apexLabel: defaultApexLabel, + overrideApexLabel: defaultOverrideApexLabel, + bp2buildConfiguration: android.NewBp2BuildAllowlist().SetDefaultConfig( + map[string]allowlists.BazelConversionConfigEntry{ + originalApexBpDir: allowlists.Bp2BuildDefaultTrue, + }).SetModuleAlwaysConvertList([]string{ + overrideApexName, + }), + }, + { + desc: "both allowed by name", + apexLabel: defaultApexLabel, + overrideApexLabel: defaultOverrideApexLabel, + bp2buildConfiguration: android.NewBp2BuildAllowlist().SetModuleAlwaysConvertList([]string{ + originalApexName, + overrideApexName, + }), + }, + { + desc: "override allowed by name", + apexLabel: defaultApexLabel, + overrideApexLabel: defaultOverrideApexLabel, + bp2buildConfiguration: android.NewBp2BuildAllowlist().SetModuleAlwaysConvertList([]string{ + overrideApexName, + }), + }, + { + desc: "override allowed by dir", + apexLabel: defaultApexLabel, + overrideApexLabel: defaultOverrideApexLabel, + bp2buildConfiguration: android.NewBp2BuildAllowlist().SetDefaultConfig( + map[string]allowlists.BazelConversionConfigEntry{ + overrideApexBpDir: allowlists.Bp2BuildDefaultTrue, + }).SetModuleAlwaysConvertList([]string{}), + }, + } - // ApexMkInfo Starlark provider - MakeModulesToInstall: []string{"c"}, // d deliberately omitted - }, - }, + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + outputBaseDir := "out/bazel" + result := android.GroupFixturePreparers( + prepareForApexTest, + android.FixtureAddTextFile(filepath.Join(originalApexBpDir, "Android.bp"), fmt.Sprintf(originalBp, tc.bazelModuleProp)), + android.FixtureAddTextFile(filepath.Join(overrideApexBpDir, "Android.bp"), fmt.Sprintf(overrideBp, tc.overrideBazelModuleProp)), + android.FixtureModifyContext(func(ctx *android.TestContext) { + ctx.RegisterBp2BuildConfig(tc.bp2buildConfiguration) + }), + android.FixtureModifyConfig(func(config android.Config) { + config.BazelContext = android.MockBazelContext{ + OutputBaseDir: outputBaseDir, + LabelToApexInfo: map[string]cquery.ApexInfo{ + tc.apexLabel: cquery.ApexInfo{ + // ApexInfo Starlark provider + SignedOutput: "signed_out.apex", + UnsignedOutput: "unsigned_out.apex", + BundleKeyInfo: []string{"public_key", "private_key"}, + ContainerKeyInfo: []string{"container_cert", "container_private"}, + SymbolsUsedByApex: "foo_using.txt", + JavaSymbolsUsedByApex: "foo_using.xml", + BundleFile: "apex_bundle.zip", + InstalledFiles: "installed-files.txt", + RequiresLibs: []string{"//path/c:c", "//path/d:d"}, + + // unused + PackageName: "pkg_name", + ProvidesLibs: []string{"a", "b"}, + + // ApexMkInfo Starlark provider + MakeModulesToInstall: []string{"c"}, // d deliberately omitted + }, + tc.overrideApexLabel: cquery.ApexInfo{ + // ApexInfo Starlark provider + SignedOutput: "override_signed_out.apex", + UnsignedOutput: "override_unsigned_out.apex", + BundleKeyInfo: []string{"override_public_key", "override_private_key"}, + ContainerKeyInfo: []string{"override_container_cert", "override_container_private"}, + SymbolsUsedByApex: "override_foo_using.txt", + JavaSymbolsUsedByApex: "override_foo_using.xml", + BundleFile: "override_apex_bundle.zip", + InstalledFiles: "override_installed-files.txt", + RequiresLibs: []string{"//path/c:c", "//path/d:d"}, + + // unused + PackageName: "override_pkg_name", + ProvidesLibs: []string{"a", "b"}, + + // ApexMkInfo Starlark provider + MakeModulesToInstall: []string{"c"}, // d deliberately omitted + }, + }, + } + }), + ).RunTest(t) + + m := result.ModuleForTests("foo", "android_common_override_foo_foo_image").Module() + ab, ok := m.(*apexBundle) + if !ok { + t.Fatalf("Expected module to be an apexBundle, was not") } - }), - ).RunTestWithBp(t, bp) - m := result.ModuleForTests("foo", "android_common_override_foo_foo_image").Module() - ab, ok := m.(*apexBundle) - if !ok { - t.Fatalf("Expected module to be an apexBundle, was not") - } - - if w, g := "out/bazel/execroot/__main__/override_public_key", ab.publicKeyFile.String(); w != g { - t.Errorf("Expected public key %q, got %q", w, g) - } + if w, g := "out/bazel/execroot/__main__/override_public_key", ab.publicKeyFile.String(); w != g { + t.Errorf("Expected public key %q, got %q", w, g) + } - if w, g := "out/bazel/execroot/__main__/override_private_key", ab.privateKeyFile.String(); w != g { - t.Errorf("Expected private key %q, got %q", w, g) - } + if w, g := "out/bazel/execroot/__main__/override_private_key", ab.privateKeyFile.String(); w != g { + t.Errorf("Expected private key %q, got %q", w, g) + } - if w, g := "out/bazel/execroot/__main__/override_container_cert", ab.containerCertificateFile.String(); w != g { - t.Errorf("Expected public container key %q, got %q", w, g) - } + if w, g := "out/bazel/execroot/__main__/override_container_cert", ab.containerCertificateFile; g != nil && w != g.String() { + t.Errorf("Expected public container key %q, got %q", w, g) + } - if w, g := "out/bazel/execroot/__main__/override_container_private", ab.containerPrivateKeyFile.String(); w != g { - t.Errorf("Expected private container key %q, got %q", w, g) - } + if w, g := "out/bazel/execroot/__main__/override_container_private", ab.containerPrivateKeyFile; g != nil && w != g.String() { + t.Errorf("Expected private container key %q, got %q", w, g) + } - if w, g := "out/bazel/execroot/__main__/override_signed_out.apex", ab.outputFile.String(); w != g { - t.Errorf("Expected output file %q, got %q", w, g) - } + if w, g := "out/bazel/execroot/__main__/override_signed_out.apex", ab.outputFile.String(); w != g { + t.Errorf("Expected output file %q, got %q", w, g) + } - if w, g := "out/bazel/execroot/__main__/override_foo_using.txt", ab.nativeApisUsedByModuleFile.String(); w != g { - t.Errorf("Expected output file %q, got %q", w, g) - } + if w, g := "out/bazel/execroot/__main__/override_foo_using.txt", ab.nativeApisUsedByModuleFile.String(); w != g { + t.Errorf("Expected output file %q, got %q", w, g) + } - if w, g := "out/bazel/execroot/__main__/override_foo_using.xml", ab.javaApisUsedByModuleFile.String(); w != g { - t.Errorf("Expected output file %q, got %q", w, g) - } + if w, g := "out/bazel/execroot/__main__/override_foo_using.xml", ab.javaApisUsedByModuleFile.String(); w != g { + t.Errorf("Expected output file %q, got %q", w, g) + } - if w, g := "out/bazel/execroot/__main__/override_installed-files.txt", ab.installedFilesFile.String(); w != g { - t.Errorf("Expected installed-files.txt %q, got %q", w, g) - } + if w, g := "out/bazel/execroot/__main__/override_installed-files.txt", ab.installedFilesFile.String(); w != g { + t.Errorf("Expected installed-files.txt %q, got %q", w, g) + } - mkData := android.AndroidMkDataForTest(t, result.TestContext, m) - var builder strings.Builder - mkData.Custom(&builder, "override_foo", "BAZEL_TARGET_", "", mkData) + mkData := android.AndroidMkDataForTest(t, result.TestContext, m) + var builder strings.Builder + mkData.Custom(&builder, "override_foo", "BAZEL_TARGET_", "", mkData) - data := builder.String() - if w := "ALL_MODULES.$(my_register_name).BUNDLE := out/bazel/execroot/__main__/override_apex_bundle.zip"; !strings.Contains(data, w) { - t.Errorf("Expected %q in androidmk data, but did not find %q", w, data) - } - if w := "$(call dist-for-goals,checkbuild,out/bazel/execroot/__main__/override_installed-files.txt:override_foo-installed-files.txt)"; !strings.Contains(data, w) { - t.Errorf("Expected %q in androidmk data, but did not find %q", w, data) - } + data := builder.String() + if w := "ALL_MODULES.$(my_register_name).BUNDLE := out/bazel/execroot/__main__/override_apex_bundle.zip"; !strings.Contains(data, w) { + t.Errorf("Expected %q in androidmk data, but did not find %q", w, data) + } + if w := "$(call dist-for-goals,checkbuild,out/bazel/execroot/__main__/override_installed-files.txt:override_foo-installed-files.txt)"; !strings.Contains(data, w) { + t.Errorf("Expected %q in androidmk data, but did not find %q", w, data) + } - // make modules to be installed to system - if len(ab.makeModulesToInstall) != 1 && ab.makeModulesToInstall[0] != "c" { - t.Errorf("Expected makeModulestoInstall slice to only contain 'c', got %q", ab.makeModulesToInstall) - } - if w := "LOCAL_REQUIRED_MODULES := c"; !strings.Contains(data, w) { - t.Errorf("Expected %q in androidmk data, but did not find it in %q", w, data) + // make modules to be installed to system + if len(ab.makeModulesToInstall) != 1 || ab.makeModulesToInstall[0] != "c" { + t.Errorf("Expected makeModulestoInstall slice to only contain 'c', got %q", ab.makeModulesToInstall) + } + if w := "LOCAL_REQUIRED_MODULES := c"; !strings.Contains(data, w) { + t.Errorf("Expected %q in androidmk data, but did not find it in %q", w, data) + } + }) } } diff --git a/cc/androidmk.go b/cc/androidmk.go index 980dd0762..ce35b5c44 100644 --- a/cc/androidmk.go +++ b/cc/androidmk.go @@ -124,17 +124,14 @@ func (c *Module) AndroidMkEntries() []android.AndroidMkEntries { } } } - if c.Properties.IsSdkVariant { + if c.Properties.IsSdkVariant && c.Properties.SdkAndPlatformVariantVisibleToMake { // Make the SDK variant uninstallable so that there are not two rules to install // to the same location. entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true) - - if c.Properties.SdkAndPlatformVariantVisibleToMake { - // Add the unsuffixed name to SOONG_SDK_VARIANT_MODULES so that Make can rewrite - // dependencies to the .sdk suffix when building a module that uses the SDK. - entries.SetString("SOONG_SDK_VARIANT_MODULES", - "$(SOONG_SDK_VARIANT_MODULES) $(patsubst %.sdk,%,$(LOCAL_MODULE))") - } + // Add the unsuffixed name to SOONG_SDK_VARIANT_MODULES so that Make can rewrite + // dependencies to the .sdk suffix when building a module that uses the SDK. + entries.SetString("SOONG_SDK_VARIANT_MODULES", + "$(SOONG_SDK_VARIANT_MODULES) $(patsubst %.sdk,%,$(LOCAL_MODULE))") } }, }, @@ -47,16 +47,16 @@ func sdkMutator(ctx android.BottomUpMutatorContext) { // Mark the SDK variant. modules[1].(*Module).Properties.IsSdkVariant = true - // SDK variant is not supposed to be installed - modules[1].(*Module).Properties.PreventInstall = true if ctx.Config().UnbundledBuildApps() { // For an unbundled apps build, hide the platform variant from Make. modules[0].(*Module).Properties.HideFromMake = true + modules[0].(*Module).Properties.PreventInstall = true } else { // For a platform build, mark the SDK variant so that it gets a ".sdk" suffix when // exposed to Make. modules[1].(*Module).Properties.SdkAndPlatformVariantVisibleToMake = true + modules[1].(*Module).Properties.PreventInstall = true } ctx.AliasVariation("") } else if isCcModule && ccModule.isImportedApiLibrary() { @@ -74,8 +74,8 @@ func sdkMutator(ctx android.BottomUpMutatorContext) { if apiLibrary.hasApexStubs() { // For an unbundled apps build, hide the platform variant from Make. modules[1].(*Module).Properties.HideFromMake = true - modules[1].(*Module).Properties.PreventInstall = true } + modules[1].(*Module).Properties.PreventInstall = true } else { // For a platform build, mark the SDK variant so that it gets a ".sdk" suffix when // exposed to Make. diff --git a/cc/sdk_test.go b/cc/sdk_test.go index 790440cb9..61925e30c 100644 --- a/cc/sdk_test.go +++ b/cc/sdk_test.go @@ -101,95 +101,3 @@ func TestSdkMutator(t *testing.T) { assertDep(t, libsdkNDK, libcxxNDK) assertDep(t, libsdkPlatform, libcxxPlatform) } - -func TestMakeModuleNameForSdkVariant(t *testing.T) { - bp := ` - cc_library { - name: "libfoo", - srcs: ["main_test.cpp"], - sdk_version: "current", - stl: "none", - } - ` - platformVariant := "android_arm64_armv8-a_shared" - sdkVariant := "android_arm64_armv8-a_sdk_shared" - testCases := []struct { - name string - unbundledApps []string - variant string - skipInstall bool // soong skips install - hideFromMake bool // no make entry - makeUninstallable bool // make skips install - makeModuleName string - }{ - { - name: "platform variant in normal builds", - unbundledApps: nil, - variant: platformVariant, - // installable in soong - skipInstall: false, - // visiable in Make as "libfoo" - hideFromMake: false, - makeModuleName: "libfoo", - // installable in Make - makeUninstallable: false, - }, - { - name: "sdk variant in normal builds", - unbundledApps: nil, - variant: sdkVariant, - // soong doesn't install - skipInstall: true, - // visible in Make as "libfoo.sdk" - hideFromMake: false, - makeModuleName: "libfoo.sdk", - // but not installed - makeUninstallable: true, - }, - { - name: "platform variant in unbunded builds", - unbundledApps: []string{"bar"}, - variant: platformVariant, - // installable in soong - skipInstall: false, - // hidden from make - hideFromMake: true, - }, - { - name: "sdk variant in unbunded builds", - unbundledApps: []string{"bar"}, - variant: sdkVariant, - // soong doesn't install - skipInstall: true, - // visible in Make as "libfoo" - hideFromMake: false, - makeModuleName: "libfoo", - // but not installed - makeUninstallable: true, - }, - } - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - fixture := android.GroupFixturePreparers(prepareForCcTest, - android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { - variables.Unbundled_build_apps = tc.unbundledApps - }), - ) - ctx := fixture.RunTestWithBp(t, bp).TestContext - module := ctx.ModuleForTests("libfoo", tc.variant).Module().(*Module) - android.AssertBoolEquals(t, "IsSkipInstall", tc.skipInstall, module.IsSkipInstall()) - android.AssertBoolEquals(t, "HideFromMake", tc.hideFromMake, module.HiddenFromMake()) - if !tc.hideFromMake { - entries := android.AndroidMkEntriesForTest(t, ctx, module)[0] - android.AssertStringEquals(t, "LOCAL_MODULE", - tc.makeModuleName, entries.EntryMap["LOCAL_MODULE"][0]) - actualUninstallable := false - if actual, ok := entries.EntryMap["LOCAL_UNINSTALLABLE_MODULE"]; ok { - actualUninstallable = "true" == actual[0] - } - android.AssertBoolEquals(t, "LOCAL_UNINSTALLABLE_MODULE", - tc.makeUninstallable, actualUninstallable) - } - }) - } -} diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go index c22fd80b9..5de232664 100644 --- a/cmd/soong_build/main.go +++ b/cmd/soong_build/main.go @@ -30,6 +30,7 @@ import ( "android/soong/shared" "android/soong/ui/metrics/bp2build_metrics_proto" + "github.com/google/blueprint" "github.com/google/blueprint/bootstrap" "github.com/google/blueprint/deptools" "github.com/google/blueprint/metrics" @@ -256,18 +257,47 @@ func apiBuildFileExcludes(ctx *android.Context) []string { } func writeNinjaHint(ctx *android.Context) error { - wantModules := make([]string, len(allowlists.HugeModulesMap)) - i := 0 - for k := range allowlists.HugeModulesMap { - wantModules[i] = k - i += 1 + ctx.BeginEvent("ninja_hint") + defer ctx.EndEvent("ninja_hint") + // The current predictor focuses on reducing false negatives. + // If there are too many false positives (e.g., most modules are marked as positive), + // real long-running jobs cannot run early. + // Therefore, the model should be adjusted in this case. + // The model should also be adjusted if there are critical false negatives. + predicate := func(j *blueprint.JsonModule) (prioritized bool, weight int) { + prioritized = false + weight = 0 + for prefix, w := range allowlists.HugeModuleTypePrefixMap { + if strings.HasPrefix(j.Type, prefix) { + prioritized = true + weight = w + return + } + } + dep_count := len(j.Deps) + src_count := 0 + for _, a := range j.Module["Actions"].([]blueprint.JSONAction) { + src_count += len(a.Inputs) + } + input_size := dep_count + src_count + + // Current threshold is an arbitrary value which only consider recall rather than accuracy. + if input_size > allowlists.INPUT_SIZE_THRESHOLD { + prioritized = true + weight += ((input_size) / allowlists.INPUT_SIZE_THRESHOLD) * allowlists.DEFAULT_PRIORITIZED_WEIGHT + + // To prevent some modules from having too large a priority value. + if weight > allowlists.HIGH_PRIORITIZED_WEIGHT { + weight = allowlists.HIGH_PRIORITIZED_WEIGHT + } + } + return } - outputsMap := ctx.Context.GetOutputsFromModuleNames(wantModules) + + outputsMap := ctx.Context.GetWeightedOutputsFromPredicate(predicate) var outputBuilder strings.Builder - for k, v := range allowlists.HugeModulesMap { - for _, output := range outputsMap[k] { - outputBuilder.WriteString(fmt.Sprintf("%s,%d\n", output, v)) - } + for output, weight := range outputsMap { + outputBuilder.WriteString(fmt.Sprintf("%s,%d\n", output, weight)) } weightListFile := filepath.Join(topDir, ctx.Config().OutDir(), ".ninja_weight_list") diff --git a/java/app.go b/java/app.go index 7bb8cdbd7..da9c6f343 100755 --- a/java/app.go +++ b/java/app.go @@ -33,8 +33,17 @@ import ( func init() { RegisterAppBuildComponents(android.InitRegistrationContext) + pctx.HostBinToolVariable("ModifyAllowlistCmd", "modify_permissions_allowlist") } +var ( + modifyAllowlist = pctx.AndroidStaticRule("modifyAllowlist", + blueprint.RuleParams{ + Command: "${ModifyAllowlistCmd} $in $packageName $out", + CommandDeps: []string{"${ModifyAllowlistCmd}"}, + }, "packageName") +) + func RegisterAppBuildComponents(ctx android.RegistrationContext) { ctx.RegisterModuleType("android_app", AndroidAppFactory) ctx.RegisterModuleType("android_test", AndroidTestFactory) @@ -115,6 +124,9 @@ type appProperties struct { // Prefer using other specific properties if build behaviour must be changed; avoid using this // flag for anything but neverallow rules (unless the behaviour change is invisible to owners). Updatable *bool + + // Specifies the file that contains the allowlist for this app. + Privapp_allowlist *string `android:"path"` } // android_app properties that can be overridden by override_android_app @@ -179,6 +191,8 @@ type AndroidApp struct { android.ApexBundleDepsInfo javaApiUsedByOutputFile android.ModuleOutPath + + privAppAllowlist android.OptionalPath } func (a *AndroidApp) IsInstallable() bool { @@ -205,6 +219,10 @@ func (a *AndroidApp) JniCoverageOutputs() android.Paths { return a.jniCoverageOutputs } +func (a *AndroidApp) PrivAppAllowlist() android.OptionalPath { + return a.privAppAllowlist +} + var _ AndroidLibraryDependency = (*AndroidApp)(nil) type Certificate struct { @@ -269,6 +287,10 @@ func (a *AndroidApp) OverridablePropertiesDepsMutator(ctx android.BottomUpMutato ctx.AddDependency(ctx.Module(), certificateTag, cert) } + if a.appProperties.Privapp_allowlist != nil && !Bool(a.appProperties.Privileged) { + ctx.PropertyErrorf("privapp_allowlist", "privileged must be set in order to use privapp_allowlist") + } + for _, cert := range a.appProperties.Additional_certificates { cert = android.SrcIsModule(cert) if cert != "" { @@ -598,6 +620,27 @@ func (a *AndroidApp) InstallApkName() string { return a.installApkName } +func (a *AndroidApp) createPrivappAllowlist(ctx android.ModuleContext) *android.OutputPath { + if a.appProperties.Privapp_allowlist == nil { + return nil + } + if a.overridableAppProperties.Package_name == nil { + ctx.PropertyErrorf("privapp_allowlist", "package_name must be set to use privapp_allowlist") + } + packageName := *a.overridableAppProperties.Package_name + fileName := "privapp_allowlist_" + packageName + ".xml" + outPath := android.PathForModuleOut(ctx, fileName).OutputPath + ctx.Build(pctx, android.BuildParams{ + Rule: modifyAllowlist, + Input: android.PathForModuleSrc(ctx, *a.appProperties.Privapp_allowlist), + Output: outPath, + Args: map[string]string{ + "packageName": packageName, + }, + }) + return &outPath +} + func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { var apkDeps android.Paths @@ -733,18 +776,27 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { BuildBundleModule(ctx, bundleFile, a.exportPackage, jniJarFile, dexJarFile) a.bundleFile = bundleFile + allowlist := a.createPrivappAllowlist(ctx) + if allowlist != nil { + a.privAppAllowlist = android.OptionalPathForPath(allowlist) + } + apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) // Install the app package. - if (Bool(a.Module.properties.Installable) || ctx.Host()) && apexInfo.IsForPlatform() && - !a.appProperties.PreventInstall { - + shouldInstallAppPackage := (Bool(a.Module.properties.Installable) || ctx.Host()) && apexInfo.IsForPlatform() && !a.appProperties.PreventInstall + if shouldInstallAppPackage { var extraInstalledPaths android.Paths for _, extra := range a.extraOutputFiles { installed := ctx.InstallFile(a.installDir, extra.Base(), extra) extraInstalledPaths = append(extraInstalledPaths, installed) } ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile, extraInstalledPaths...) + + if a.privAppAllowlist.Valid() { + installPath := android.PathForModuleInstall(ctx, "etc", "permissions") + ctx.InstallFile(installPath, a.privAppAllowlist.Path().Base(), a.privAppAllowlist.Path()) + } } a.buildAppDependencyInfo(ctx) diff --git a/java/app_import.go b/java/app_import.go index bfd67679e..52ae0247a 100644 --- a/java/app_import.go +++ b/java/app_import.go @@ -423,6 +423,10 @@ func (a *AndroidAppImport) ProvenanceMetaDataFile() android.OutputPath { return a.provenanceMetaDataFile } +func (a *AndroidAppImport) PrivAppAllowlist() android.OptionalPath { + return android.OptionalPath{} +} + var dpiVariantGroupType reflect.Type var archVariantGroupType reflect.Type var supportedDpis = []string{"ldpi", "mdpi", "hdpi", "xhdpi", "xxhdpi", "xxxhdpi"} diff --git a/java/app_test.go b/java/app_test.go index 7e97b0fb1..daff94ca9 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -3539,3 +3539,51 @@ func TestTargetSdkVersionMtsTests(t *testing.T) { android.AssertStringDoesContain(t, testCase.desc, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected) } } + +func TestPrivappAllowlist(t *testing.T) { + testJavaError(t, "privileged must be set in order to use privapp_allowlist", ` + android_app { + name: "foo", + srcs: ["a.java"], + privapp_allowlist: "perms.xml", + } + `) + + result := PrepareForTestWithJavaDefaultModules.RunTestWithBp( + t, + ` + android_app { + name: "foo", + srcs: ["a.java"], + privapp_allowlist: "perms.xml", + privileged: true, + package_name: "com.android.foo", + sdk_version: "current", + } + override_android_app { + name: "bar", + base: "foo", + package_name: "com.google.android.foo", + } + `, + ) + app := result.ModuleForTests("foo", "android_common") + overrideApp := result.ModuleForTests("foo", "android_common_bar") + + // verify that privapp allowlist is created + app.Output("out/soong/.intermediates/foo/android_common/privapp_allowlist_com.android.foo.xml") + overrideApp.Output("out/soong/.intermediates/foo/android_common_bar/privapp_allowlist_com.google.android.foo.xml") + expectedAllowlist := "perms.xml" + actualAllowlist := app.Rule("modifyAllowlist").Input.String() + if expectedAllowlist != actualAllowlist { + t.Errorf("expected allowlist to be %q; got %q", expectedAllowlist, actualAllowlist) + } + overrideActualAllowlist := overrideApp.Rule("modifyAllowlist").Input.String() + if expectedAllowlist != overrideActualAllowlist { + t.Errorf("expected override allowlist to be %q; got %q", expectedAllowlist, overrideActualAllowlist) + } + + // verify that permissions are copied to device + app.Output("out/soong/target/product/test_device/system/etc/permissions/privapp_allowlist_com.android.foo.xml") + overrideApp.Output("out/soong/target/product/test_device/system/etc/permissions/privapp_allowlist_com.google.android.foo.xml") +} diff --git a/scripts/Android.bp b/scripts/Android.bp index 9367ff06a..97f6ab424 100644 --- a/scripts/Android.bp +++ b/scripts/Android.bp @@ -237,3 +237,20 @@ sh_binary_host { name: "jars-to-module-info-java", src: "jars-to-module-info-java.sh", } + +python_binary_host { + name: "modify_permissions_allowlist", + main: "modify_permissions_allowlist.py", + srcs: [ + "modify_permissions_allowlist.py", + ], +} + +python_test_host { + name: "modify_permissions_allowlist_test", + main: "modify_permissions_allowlist_test.py", + srcs: [ + "modify_permissions_allowlist_test.py", + "modify_permissions_allowlist.py", + ], +} diff --git a/scripts/check_boot_jars/package_allowed_list.txt b/scripts/check_boot_jars/package_allowed_list.txt index 869fd3f83..dad2b47d9 100644 --- a/scripts/check_boot_jars/package_allowed_list.txt +++ b/scripts/check_boot_jars/package_allowed_list.txt @@ -72,6 +72,7 @@ javax\.xml\.transform\.stream javax\.xml\.validation javax\.xml\.xpath jdk\.internal +jdk\.internal\.access jdk\.internal\.math jdk\.internal\.misc jdk\.internal\.ref diff --git a/scripts/modify_permissions_allowlist.py b/scripts/modify_permissions_allowlist.py new file mode 100755 index 000000000..38ec7ec86 --- /dev/null +++ b/scripts/modify_permissions_allowlist.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python +# +# Copyright (C) 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +"""A tool for modifying privileged permission allowlists.""" + +from __future__ import print_function + +import argparse +import sys +from xml.dom import minidom + + +class InvalidRootNodeException(Exception): + pass + + +class InvalidNumberOfPrivappPermissionChildren(Exception): + pass + + +def modify_allowlist(allowlist_dom, package_name): + if allowlist_dom.documentElement.tagName != 'permissions': + raise InvalidRootNodeException + nodes = allowlist_dom.getElementsByTagName('privapp-permissions') + if nodes.length != 1: + raise InvalidNumberOfPrivappPermissionChildren + privapp_permissions = nodes[0] + privapp_permissions.setAttribute('package', package_name) + + +def parse_args(): + """Parse commandline arguments.""" + + parser = argparse.ArgumentParser() + parser.add_argument('input', help='input allowlist template file') + parser.add_argument( + 'package_name', help='package name to use in the allowlist' + ) + parser.add_argument('output', help='output allowlist file') + + return parser.parse_args() + + +def main(): + try: + args = parse_args() + doc = minidom.parse(args.input) + modify_allowlist(doc, args.package_name) + with open(args.output, 'w') as output_file: + doc.writexml(output_file, encoding='utf-8') + except Exception as err: + print('error: ' + str(err), file=sys.stderr) + sys.exit(-1) + + +if __name__ == '__main__': + main() diff --git a/scripts/modify_permissions_allowlist_test.py b/scripts/modify_permissions_allowlist_test.py new file mode 100755 index 000000000..ee8b12cc8 --- /dev/null +++ b/scripts/modify_permissions_allowlist_test.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python +# +# Copyright (C) 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +"""Unit tests for modify_permissions_allowlist.py.""" + +from __future__ import print_function + +import unittest + +from xml.dom import minidom + +from modify_permissions_allowlist import InvalidRootNodeException, InvalidNumberOfPrivappPermissionChildren, modify_allowlist + + +class ModifyPermissionsAllowlistTest(unittest.TestCase): + + def test_invalid_root(self): + xml_data = '<foo></foo>' + xml_dom = minidom.parseString(xml_data) + self.assertRaises(InvalidRootNodeException, modify_allowlist, xml_dom, 'x') + + def test_no_packages(self): + xml_data = '<permissions></permissions>' + xml_dom = minidom.parseString(xml_data) + self.assertRaises( + InvalidNumberOfPrivappPermissionChildren, modify_allowlist, xml_dom, 'x' + ) + + def test_multiple_packages(self): + xml_data = ( + '<permissions>' + ' <privapp-permissions package="foo.bar"></privapp-permissions>' + ' <privapp-permissions package="bar.baz"></privapp-permissions>' + '</permissions>' + ) + xml_dom = minidom.parseString(xml_data) + self.assertRaises( + InvalidNumberOfPrivappPermissionChildren, modify_allowlist, xml_dom, 'x' + ) + + def test_modify_package_name(self): + xml_data = ( + '<permissions>' + ' <privapp-permissions package="foo.bar">' + ' <permission name="myperm1"/>' + ' </privapp-permissions>' + '</permissions>' + ) + xml_dom = minidom.parseString(xml_data) + modify_allowlist(xml_dom, 'bar.baz') + expected_data = ( + '<?xml version="1.0" ?>' + '<permissions>' + ' <privapp-permissions package="bar.baz">' + ' <permission name="myperm1"/>' + ' </privapp-permissions>' + '</permissions>' + ) + self.assertEqual(expected_data, xml_dom.toxml()) + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/sh/sh_binary.go b/sh/sh_binary.go index c921ca68a..d2eede65d 100644 --- a/sh/sh_binary.go +++ b/sh/sh_binary.go @@ -474,16 +474,18 @@ func (s *ShTest) AndroidMkEntries() []android.AndroidMkEntries { }} } -func InitShBinaryModule(s *ShBinary) { +func initShBinaryModule(s *ShBinary, useBazel bool) { s.AddProperties(&s.properties) - android.InitBazelModule(s) + if useBazel { + android.InitBazelModule(s) + } } // sh_binary is for a shell script or batch file to be installed as an // executable binary to <partition>/bin. func ShBinaryFactory() android.Module { module := &ShBinary{} - InitShBinaryModule(module) + initShBinaryModule(module, true) android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibFirst) return module } @@ -492,7 +494,7 @@ func ShBinaryFactory() android.Module { // to $(HOST_OUT)/bin. func ShBinaryHostFactory() android.Module { module := &ShBinary{} - InitShBinaryModule(module) + initShBinaryModule(module, true) android.InitAndroidArchModule(module, android.HostSupported, android.MultilibFirst) return module } @@ -500,7 +502,7 @@ func ShBinaryHostFactory() android.Module { // sh_test defines a shell script based test module. func ShTestFactory() android.Module { module := &ShTest{} - InitShBinaryModule(&module.ShBinary) + initShBinaryModule(&module.ShBinary, false) module.AddProperties(&module.testProperties) android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibFirst) @@ -510,7 +512,7 @@ func ShTestFactory() android.Module { // sh_test_host defines a shell script based test module that runs on a host. func ShTestHostFactory() android.Module { module := &ShTest{} - InitShBinaryModule(&module.ShBinary) + initShBinaryModule(&module.ShBinary, false) module.AddProperties(&module.testProperties) // Default sh_test_host to unit_tests = true if module.testProperties.Test_options.Unit_test == nil { diff --git a/ui/build/rbe.go b/ui/build/rbe.go index 6479925dd..3b9d301f5 100644 --- a/ui/build/rbe.go +++ b/ui/build/rbe.go @@ -183,8 +183,6 @@ func DumpRBEMetrics(ctx Context, config Config, filename string) { return } - ctx.Status.Status("Dumping rbe metrics...") - outputDir := config.rbeProxyLogsDir() if outputDir == "" { ctx.Fatal("RBE output dir variable not defined. Aborting metrics dumping.") |