diff --git a/android/config.go b/android/config.go index e0f3a91f9..50e39d7e9 100644 --- a/android/config.go +++ b/android/config.go @@ -1413,6 +1413,14 @@ func (c *deviceConfig) VendorSnapshotModules() map[string]bool { return c.config.productVariables.VendorSnapshotModules } +func (c *deviceConfig) DirectedRecoverySnapshot() bool { + return c.config.productVariables.DirectedRecoverySnapshot +} + +func (c *deviceConfig) RecoverySnapshotModules() map[string]bool { + return c.config.productVariables.RecoverySnapshotModules +} + // The ConfiguredJarList struct provides methods for handling a list of (apex, jar) pairs. // Such lists are used in the build system for things like bootclasspath jars or system server jars. // The apex part is either an apex name, or a special names "platform" or "system_ext". Jar is a diff --git a/android/variable.go b/android/variable.go index 799369d33..e76d68397 100644 --- a/android/variable.go +++ b/android/variable.go @@ -307,6 +307,9 @@ type productVariables struct { DirectedVendorSnapshot bool `json:",omitempty"` VendorSnapshotModules map[string]bool `json:",omitempty"` + DirectedRecoverySnapshot bool `json:",omitempty"` + RecoverySnapshotModules map[string]bool `json:",omitempty"` + BoardVendorSepolicyDirs []string `json:",omitempty"` BoardOdmSepolicyDirs []string `json:",omitempty"` BoardReqdMaskPolicy []string `json:",omitempty"` diff --git a/cc/snapshot_prebuilt.go b/cc/snapshot_prebuilt.go index b82628ccb..62daafde4 100644 --- a/cc/snapshot_prebuilt.go +++ b/cc/snapshot_prebuilt.go @@ -195,8 +195,12 @@ func (recoverySnapshotImage) targetSnapshotVersion(cfg android.DeviceConfig) str } func (recoverySnapshotImage) excludeFromDirectedSnapshot(cfg android.DeviceConfig, name string) bool { - // directed recovery snapshot is not implemented yet - return false + // If we're using full snapshot, not directed snapshot, capture every module + if !cfg.DirectedRecoverySnapshot() { + return false + } + // Else, checks if name is in RECOVERY_SNAPSHOT_MODULES. + return !cfg.RecoverySnapshotModules()[name] } func (recoverySnapshotImage) imageVariantName(cfg android.DeviceConfig) string { diff --git a/cc/vendor_snapshot_test.go b/cc/vendor_snapshot_test.go index 659b6931c..7e283fb89 100644 --- a/cc/vendor_snapshot_test.go +++ b/cc/vendor_snapshot_test.go @@ -1051,3 +1051,85 @@ func TestRecoverySnapshotExclude(t *testing.T) { } } } + +func TestRecoverySnapshotDirected(t *testing.T) { + bp := ` + cc_library_shared { + name: "librecovery", + recovery: true, + nocrt: true, + } + + cc_library_shared { + name: "librecovery_available", + recovery_available: true, + nocrt: true, + } + + genrule { + name: "libfoo_gen", + cmd: "", + out: ["libfoo.so"], + } + + cc_prebuilt_library_shared { + name: "libfoo", + recovery: true, + prefer: true, + srcs: [":libfoo_gen"], + } + + cc_library_shared { + name: "libfoo", + recovery: true, + nocrt: true, + } +` + config := TestConfig(buildDir, android.Android, nil, bp, nil) + config.TestProductVariables.DeviceVndkVersion = StringPtr("current") + config.TestProductVariables.RecoverySnapshotVersion = StringPtr("current") + config.TestProductVariables.Platform_vndk_version = StringPtr("VER") + config.TestProductVariables.DirectedRecoverySnapshot = true + config.TestProductVariables.RecoverySnapshotModules = make(map[string]bool) + config.TestProductVariables.RecoverySnapshotModules["librecovery"] = true + config.TestProductVariables.RecoverySnapshotModules["libfoo"] = true + ctx := testCcWithConfig(t, config) + + // Check recovery snapshot output. + + snapshotDir := "recovery-snapshot" + snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64") + snapshotSingleton := ctx.SingletonForTests("recovery-snapshot") + + var includeJsonFiles []string + + for _, arch := range [][]string{ + []string{"arm64", "armv8-a"}, + } { + archType := arch[0] + archVariant := arch[1] + archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant) + + sharedVariant := fmt.Sprintf("android_recovery_%s_%s_shared", archType, archVariant) + sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared") + + // Included modules + checkSnapshot(t, ctx, snapshotSingleton, "librecovery", "librecovery.so", sharedDir, sharedVariant) + includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "librecovery.so.json")) + // Check that snapshot captures "prefer: true" prebuilt + checkSnapshot(t, ctx, snapshotSingleton, "prebuilt_libfoo", "libfoo.so", sharedDir, sharedVariant) + includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libfoo.so.json")) + + // Excluded modules. Modules not included in the directed recovery snapshot + // are still include as fake modules. + checkSnapshotRule(t, ctx, snapshotSingleton, "librecovery_available", "librecovery_available.so", sharedDir, sharedVariant) + includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "librecovery_available.so.json")) + } + + // Verify that each json file for an included module has a rule. + for _, jsonFile := range includeJsonFiles { + if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil { + t.Errorf("include json file %q not found", jsonFile) + } + } +}