Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eec1b3fe authored by Jooyung Han's avatar Jooyung Han
Browse files

Remove "flattened" apexes

Now soong doesn't build "flattened" apexes.

Bug: 279835185
Test: m nothing (soong tests)
Test: m && launch_cvd (cuttlefish)
Change-Id: Id3c540ece1a15cecacc185da9aa17285edd2f493
parent be24d273
Loading
Loading
Loading
Loading
+0 −4
Original line number Diff line number Diff line
@@ -1645,10 +1645,6 @@ func (c *config) AmlAbis() bool {
	return Bool(c.productVariables.Aml_abis)
}

func (c *config) FlattenApex() bool {
	return Bool(c.productVariables.Flatten_apex)
}

func (c *config) ForceApexSymlinkOptimization() bool {
	return Bool(c.productVariables.ForceApexSymlinkOptimization)
}
+0 −5
Original line number Diff line number Diff line
@@ -175,10 +175,6 @@ type variableProperties struct {
			Whole_static_libs []string `android:"arch_variant"`
		} `android:"arch_variant"`

		Flatten_apex struct {
			Enabled *bool
		}

		Native_coverage struct {
			Src          *string  `android:"arch_variant"`
			Srcs         []string `android:"arch_variant"`
@@ -397,7 +393,6 @@ type productVariables struct {
	Ndk_abis *bool `json:",omitempty"`

	TrimmedApex                  *bool `json:",omitempty"`
	Flatten_apex                 *bool `json:",omitempty"`
	ForceApexSymlinkOptimization *bool `json:",omitempty"`
	CompressedApex               *bool `json:",omitempty"`
	Aml_abis                     *bool `json:",omitempty"`
+56 −116
Original line number Diff line number Diff line
@@ -85,16 +85,12 @@ func (a *apexBundle) androidMkForFiles(w io.Writer, apexBundleName, moduleDir st
	// conflicts between two apexes with the same apexName.

	moduleNames := []string{}
	apexType := a.properties.ApexType
	// To avoid creating duplicate build rules, run this function only when primaryApexType is true
	// to install symbol files in $(PRODUCT_OUT}/apex.
	// And if apexType is flattened, run this function to install files in $(PRODUCT_OUT}/system/apex.
	if !a.primaryApexType && apexType != flattenedApex {
	if !a.primaryApexType {
		return moduleNames
	}

	seenDataOutPaths := make(map[string]bool)

	for _, fi := range a.filesInfo {
		linkToSystemLib := a.linkToSystemLib && fi.transitiveDep && fi.availableToPlatform()
		moduleName := a.fullModuleName(apexBundleName, linkToSystemLib, &fi)
@@ -131,33 +127,13 @@ func (a *apexBundle) androidMkForFiles(w io.Writer, apexBundleName, moduleDir st
		}
		// /apex/<apexBundleName>/{lib|framework|...}
		pathForSymbol := filepath.Join("$(PRODUCT_OUT)", "apex", apexBundleName, fi.installDir)
		var modulePath string
		if apexType == flattenedApex {
			// /system/apex/<apexBundleName>/{lib|framework|...}
			modulePath = filepath.Join(a.installDir.String(), apexBundleName, fi.installDir)
			fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", modulePath)
			if a.primaryApexType {
				fmt.Fprintln(w, "LOCAL_SOONG_SYMBOL_PATH :=", pathForSymbol)
			}
			android.AndroidMkEmitAssignList(w, "LOCAL_MODULE_SYMLINKS", fi.symlinks)
			newDataPaths := []android.DataPath{}
			for _, path := range fi.dataPaths {
				dataOutPath := modulePath + ":" + path.SrcPath.Rel()
				if ok := seenDataOutPaths[dataOutPath]; !ok {
					newDataPaths = append(newDataPaths, path)
					seenDataOutPaths[dataOutPath] = true
				}
			}
			android.AndroidMkEmitAssignList(w, "LOCAL_TEST_DATA", android.AndroidMkDataPaths(newDataPaths))
		} else {
			modulePath = pathForSymbol
		modulePath := pathForSymbol
		fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", modulePath)

		// For non-flattend APEXes, the merged notice file is attached to the APEX itself.
		// We don't need to have notice file for the individual modules in it. Otherwise,
		// we will have duplicated notice entries.
		fmt.Fprintln(w, "LOCAL_NO_NOTICE_FILE := true")
		}
		fmt.Fprintln(w, "LOCAL_SOONG_INSTALLED_MODULE :=", filepath.Join(modulePath, fi.stem()))
		fmt.Fprintln(w, "LOCAL_SOONG_INSTALL_PAIRS :=", fi.builtFile.String()+":"+filepath.Join(modulePath, fi.stem()))
		fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", fi.builtFile.String())
@@ -257,31 +233,6 @@ func (a *apexBundle) androidMkForFiles(w io.Writer, apexBundleName, moduleDir st
			fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_cc_rust_prebuilt.mk")
		default:
			fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", fi.stem())
			if fi.builtFile == a.manifestPbOut && apexType == flattenedApex {
				if a.primaryApexType {
					// To install companion files (init_rc, vintf_fragments)
					// Copy some common properties of apexBundle to apex_manifest
					commonProperties := []string{
						"LOCAL_FULL_INIT_RC", "LOCAL_FULL_VINTF_FRAGMENTS",
					}
					for _, name := range commonProperties {
						if value, ok := apexAndroidMkData.Entries.EntryMap[name]; ok {
							android.AndroidMkEmitAssignList(w, name, value)
						}
					}

					// Make apex_manifest.pb module for this APEX to override all other
					// modules in the APEXes being overridden by this APEX
					var patterns []string
					for _, o := range a.overridableProperties.Overrides {
						patterns = append(patterns, "%."+o+a.suffix)
					}
					android.AndroidMkEmitAssignList(w, "LOCAL_OVERRIDES_MODULES", patterns)
				}

				// File_contexts of flattened APEXes should be merged into file_contexts.bin
				fmt.Fprintln(w, "LOCAL_FILE_CONTEXTS :=", a.fileContexts)
			}
			fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
		}

@@ -320,16 +271,6 @@ func (a *apexBundle) androidMkForType() android.AndroidMkData {
				moduleNames = a.androidMkForFiles(w, name, moduleDir, data)
			}

			if apexType == flattenedApex {
				// Only image APEXes can be flattened.
				fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)  # apex.apexBundle.flat")
				fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
				fmt.Fprintln(w, "LOCAL_MODULE :=", name+a.suffix)
				data.Entries.WriteLicenseVariables(w)
				a.writeRequiredModules(w, moduleNames)
				fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)")

			} else {
			fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)  # apex.apexBundle")
			fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
			fmt.Fprintln(w, "LOCAL_MODULE :=", name+a.suffix)
@@ -386,7 +327,6 @@ func (a *apexBundle) androidMkForType() android.AndroidMkData {
			distCoverageFiles(w, "ndk_apis_usedby_apex", a.nativeApisUsedByModuleFile.String())
			distCoverageFiles(w, "ndk_apis_backedby_apex", a.nativeApisBackedByModuleFile.String())
			distCoverageFiles(w, "java_apis_used_by_apex", a.javaApisUsedByModuleFile.String())
			}
		}}
}

+16 −78
Original line number Diff line number Diff line
@@ -79,7 +79,7 @@ func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) {
	ctx.BottomUp("mark_platform_availability", markPlatformAvailability).Parallel()
	ctx.BottomUp("apex", apexMutator).Parallel()
	ctx.BottomUp("apex_directly_in_any", apexDirectlyInAnyMutator).Parallel()
	ctx.BottomUp("apex_flattened", apexFlattenedMutator).Parallel()
	ctx.BottomUp("apex_packaging", apexPackagingMutator).Parallel()
	ctx.BottomUp("apex_dcla_deps", apexDCLADepsMutator).Parallel()
	// Register after apex_info mutator so that it can use ApexVariationName
	ctx.TopDown("apex_strict_updatability_lint", apexStrictUpdatibilityLintMutator).Parallel()
@@ -216,9 +216,7 @@ type apexBundleProperties struct {

	HideFromMake bool `blueprint:"mutated"`

	// Internal package method for this APEX. When payload_type is image, this can be either
	// imageApex or flattenedApex depending on Config.FlattenApex(). When payload_type is zip,
	// this becomes zipApex.
	// Internal package method for this APEX.
	ApexType apexPackaging `blueprint:"mutated"`

	// Name that dependencies can specify in their apex_available properties to refer to this module.
@@ -427,7 +425,7 @@ type apexBundle struct {
	// one gets installed to the device.
	primaryApexType bool

	// Suffix of module name in Android.mk ".flattened", ".apex", ".zipapex", or ""
	// Suffix of module name in Android.mk ".apex", ".zipapex", or ""
	suffix string

	// File system type of apex_payload.img
@@ -535,8 +533,7 @@ var (
// apexFile represents a file in an APEX bundle. This is created during the first half of
// GenerateAndroidBuildActions by traversing the dependencies of the APEX. Then in the second half
// of the function, this is used to create commands that copies the files into a staging directory,
// where they are packaged into the APEX file. This struct is also used for creating Make modules
// for each of the files in case when the APEX is flattened.
// where they are packaged into the APEX file.
type apexFile struct {
	// buildFile is put in the installDir inside the APEX.
	builtFile  android.Path
@@ -1367,12 +1364,8 @@ const (
	// zipApex is a packaging method where contents are directly included in the zip container.
	// This is used for host-side testing - because the contents are easily accessible by
	// unzipping the container.
	// TODO(b/279835185) deprecate zipApex
	zipApex

	// flattendApex is a packaging method where contents are not included in the APEX file, but
	// installed to /apex/<apexname> directory on the device. This packaging method is used for
	// old devices where the filesystem-based APEX file can't be supported.
	flattenedApex
)

const (
@@ -1380,12 +1373,10 @@ const (
	imageApexSuffix  = ".apex"
	imageCapexSuffix = ".capex"
	zipApexSuffix    = ".zipapex"
	flattenedSuffix  = ".flattened"

	// variant names each of which is for a packaging method
	imageApexType = "image"
	zipApexType   = "zip"
	flattenedApexType = "flattened"

	ext4FsType  = "ext4"
	f2fsFsType  = "f2fs"
@@ -1415,9 +1406,8 @@ func (a apexPackaging) name() string {
	}
}

// apexFlattenedMutator creates one or more variations each of which is for a packaging method.
// TODO(jiyong): give a better name to this mutator
func apexFlattenedMutator(mctx android.BottomUpMutatorContext) {
// apexPackagingMutator creates one or more variations each of which is for a packaging method.
func apexPackagingMutator(mctx android.BottomUpMutatorContext) {
	if !mctx.Module().Enabled() {
		return
	}
@@ -1425,19 +1415,11 @@ func apexFlattenedMutator(mctx android.BottomUpMutatorContext) {
		var variants []string
		switch proptools.StringDefault(ab.properties.Payload_type, "image") {
		case "image":
			// This is the normal case. Note that both image and flattend APEXes are
			// created. The image type is installed to the system partition, while the
			// flattened APEX is (optionally) installed to the system_ext partition.
			// This is mostly for GSI which has to support wide range of devices. If GSI
			// is installed on a newer (APEX-capable) device, the image APEX in the
			// system will be used. However, if the same GSI is installed on an old
			// device which can't support image APEX, the flattened APEX in the
			// system_ext partion (which still is part of GSI) is used instead.
			variants = append(variants, imageApexType, flattenedApexType)
			variants = append(variants, imageApexType)
		case "zip":
			variants = append(variants, zipApexType)
		case "both":
			variants = append(variants, imageApexType, zipApexType, flattenedApexType)
			variants = append(variants, imageApexType, zipApexType)
		default:
			mctx.PropertyErrorf("payload_type", "%q is not one of \"image\", \"zip\", or \"both\".", *ab.properties.Payload_type)
			return
@@ -1451,18 +1433,12 @@ func apexFlattenedMutator(mctx android.BottomUpMutatorContext) {
				modules[i].(*apexBundle).properties.ApexType = imageApex
			case zipApexType:
				modules[i].(*apexBundle).properties.ApexType = zipApex
			case flattenedApexType:
				modules[i].(*apexBundle).properties.ApexType = flattenedApex
				// See the comment above for why system_ext.
				if !mctx.Config().FlattenApex() && ab.Platform() {
					modules[i].(*apexBundle).MakeAsSystemExt()
				}
			}
		}
	} else if _, ok := mctx.Module().(*OverrideApex); ok {
		// payload_type is forcibly overridden to "image"
		// TODO(jiyong): is this the right decision?
		mctx.CreateVariations(imageApexType, flattenedApexType)
		mctx.CreateVariations(imageApexType)
	}
}

@@ -1497,9 +1473,6 @@ func (a *apexBundle) OutputFiles(tag string) (android.Paths, error) {
var _ multitree.Exportable = (*apexBundle)(nil)

func (a *apexBundle) Exportable() bool {
	if a.properties.ApexType == flattenedApex {
		return false
	}
	return true
}

@@ -2143,15 +2116,10 @@ func (a *apexBundle) setPayloadFsType(ctx android.ModuleContext) {

func (a *apexBundle) setApexTypeAndSuffix(ctx android.ModuleContext) {
	// Set suffix and primaryApexType depending on the ApexType
	buildFlattenedAsDefault := ctx.Config().FlattenApex()
	switch a.properties.ApexType {
	case imageApex:
		if buildFlattenedAsDefault {
			a.suffix = imageApexSuffix
		} else {
		a.suffix = ""
		a.primaryApexType = true
		}
	case zipApex:
		if proptools.String(a.properties.Payload_type) == "zip" {
			a.suffix = ""
@@ -2159,17 +2127,10 @@ func (a *apexBundle) setApexTypeAndSuffix(ctx android.ModuleContext) {
		} else {
			a.suffix = zipApexSuffix
		}
	case flattenedApex:
		if buildFlattenedAsDefault {
			a.suffix = ""
			a.primaryApexType = true
		} else {
			a.suffix = flattenedSuffix
		}
	}
}

func (a apexBundle) isCompressable() bool {
func (a *apexBundle) isCompressable() bool {
	return proptools.BoolDefault(a.overridableProperties.Compressible, false) && !a.testApex
}

@@ -2668,32 +2629,9 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	////////////////////////////////////////////////////////////////////////////////////////////
	// 4) generate the build rules to create the APEX. This is done in builder.go.
	a.buildManifest(ctx, vctx.provideNativeLibs, vctx.requireNativeLibs)
	if a.properties.ApexType == flattenedApex {
		a.buildFlattenedApex(ctx)
	} else {
		a.buildUnflattenedApex(ctx)
	}
	a.buildApex(ctx)
	a.buildApexDependencyInfo(ctx)
	a.buildLintReports(ctx)

	// Append meta-files to the filesInfo list so that they are reflected in Android.mk as well.
	if a.installable() {
		// For flattened APEX, make sure that APEX manifest and apex_pubkey are also copied
		// along with other ordinary files. (Note that this is done by apexer for
		// non-flattened APEXes)
		a.filesInfo = append(a.filesInfo, newApexFile(ctx, a.manifestPbOut, "apex_manifest.pb", ".", etc, nil))

		// Place the public key as apex_pubkey. This is also done by apexer for
		// non-flattened APEXes case.
		// TODO(jiyong): Why do we need this CP rule?
		copiedPubkey := android.PathForModuleOut(ctx, "apex_pubkey")
		ctx.Build(pctx, android.BuildParams{
			Rule:   android.Cp,
			Input:  a.publicKeyFile,
			Output: copiedPubkey,
		})
		a.filesInfo = append(a.filesInfo, newApexFile(ctx, copiedPubkey, "apex_pubkey", ".", etc, nil))
	}
}

// apexBootclasspathFragmentFiles returns the list of apexFile structures defining the files that
+17 −43
Original line number Diff line number Diff line
@@ -3206,7 +3206,7 @@ func TestAndroidMk_VendorApexRequired(t *testing.T) {
	var builder strings.Builder
	data.Custom(&builder, name, prefix, "", data)
	androidMk := builder.String()
	ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := libc++.vendor.myapex:64 mylib.vendor.myapex:64 apex_manifest.pb.myapex apex_pubkey.myapex libc.vendor libm.vendor libdl.vendor\n")
	ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := libc++.vendor.myapex:64 mylib.vendor.myapex:64 libc.vendor libm.vendor libdl.vendor\n")
}

func TestAndroidMkWritesCommonProperties(t *testing.T) {
@@ -4934,17 +4934,17 @@ func TestApexWithShBinary(t *testing.T) {

func TestApexInVariousPartition(t *testing.T) {
	testcases := []struct {
		propName, parition, flattenedPartition string
		propName, partition string
	}{
		{"", "system", "system_ext"},
		{"product_specific: true", "product", "product"},
		{"soc_specific: true", "vendor", "vendor"},
		{"proprietary: true", "vendor", "vendor"},
		{"vendor: true", "vendor", "vendor"},
		{"system_ext_specific: true", "system_ext", "system_ext"},
		{"", "system"},
		{"product_specific: true", "product"},
		{"soc_specific: true", "vendor"},
		{"proprietary: true", "vendor"},
		{"vendor: true", "vendor"},
		{"system_ext_specific: true", "system_ext"},
	}
	for _, tc := range testcases {
		t.Run(tc.propName+":"+tc.parition, func(t *testing.T) {
		t.Run(tc.propName+":"+tc.partition, func(t *testing.T) {
			ctx := testApex(t, `
				apex {
					name: "myapex",
@@ -4961,18 +4961,11 @@ func TestApexInVariousPartition(t *testing.T) {
			`)

			apex := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
			expected := "out/soong/target/product/test_device/" + tc.parition + "/apex"
			expected := "out/soong/target/product/test_device/" + tc.partition + "/apex"
			actual := apex.installDir.RelativeToTop().String()
			if actual != expected {
				t.Errorf("wrong install path. expected %q. actual %q", expected, actual)
			}

			flattened := ctx.ModuleForTests("myapex", "android_common_myapex_flattened").Module().(*apexBundle)
			expected = "out/soong/target/product/test_device/" + tc.flattenedPartition + "/apex"
			actual = flattened.installDir.RelativeToTop().String()
			if actual != expected {
				t.Errorf("wrong install path. expected %q. actual %q", expected, actual)
			}
		})
	}
}
@@ -6110,16 +6103,7 @@ func TestApexWithTests(t *testing.T) {
	ensureContains(t, androidMk, "LOCAL_MODULE := mytest1.myapex\n")
	ensureContains(t, androidMk, "LOCAL_MODULE := mytest2.myapex\n")
	ensureContains(t, androidMk, "LOCAL_MODULE := mytest3.myapex\n")
	ensureContains(t, androidMk, "LOCAL_MODULE := apex_manifest.pb.myapex\n")
	ensureContains(t, androidMk, "LOCAL_MODULE := apex_pubkey.myapex\n")
	ensureContains(t, androidMk, "LOCAL_MODULE := myapex\n")

	flatBundle := ctx.ModuleForTests("myapex", "android_common_myapex_flattened").Module().(*apexBundle)
	data = android.AndroidMkDataForTest(t, ctx, flatBundle)
	data.Custom(&builder, name, prefix, "", data)
	flatAndroidMk := builder.String()
	ensureContainsOnce(t, flatAndroidMk, "LOCAL_TEST_DATA := :baz :bar/baz\n")
	ensureContainsOnce(t, flatAndroidMk, "LOCAL_TEST_DATA := :testdata/baz\n")
}

func TestErrorsIfDepsAreNotEnabled(t *testing.T) {
@@ -7169,13 +7153,11 @@ func TestOverrideApex(t *testing.T) {
	androidMk := builder.String()
	ensureContains(t, androidMk, "LOCAL_MODULE := override_app.override_myapex")
	ensureContains(t, androidMk, "LOCAL_MODULE := overrideBpf.o.override_myapex")
	ensureContains(t, androidMk, "LOCAL_MODULE := apex_manifest.pb.override_myapex")
	ensureContains(t, androidMk, "LOCAL_MODULE_STEM := override_myapex.apex")
	ensureContains(t, androidMk, "LOCAL_OVERRIDES_MODULES := unknownapex myapex")
	ensureNotContains(t, androidMk, "LOCAL_MODULE := app.myapex")
	ensureNotContains(t, androidMk, "LOCAL_MODULE := bpf.myapex")
	ensureNotContains(t, androidMk, "LOCAL_MODULE := override_app.myapex")
	ensureNotContains(t, androidMk, "LOCAL_MODULE := apex_manifest.pb.myapex")
	ensureNotContains(t, androidMk, "LOCAL_MODULE_STEM := myapex.apex")
}

@@ -7758,7 +7740,7 @@ func TestCarryRequiredModuleNames(t *testing.T) {
	var builder strings.Builder
	data.Custom(&builder, name, prefix, "", data)
	androidMk := builder.String()
	ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := mylib.myapex:64 apex_manifest.pb.myapex apex_pubkey.myapex a b\n")
	ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := mylib.myapex:64 a b\n")
	ensureContains(t, androidMk, "LOCAL_HOST_REQUIRED_MODULES := c d\n")
	ensureContains(t, androidMk, "LOCAL_TARGET_REQUIRED_MODULES := e f\n")
}
@@ -7966,7 +7948,7 @@ func TestSymlinksFromApexToSystemRequiredModuleNames(t *testing.T) {
	ensureNotContains(t, androidMk, "LOCAL_MODULE := prebuilt_myotherlib.myapex\n")
	ensureNotContains(t, androidMk, "LOCAL_MODULE := myotherlib.myapex\n")
	// `myapex` should have `myotherlib` in its required line, not `prebuilt_myotherlib`
	ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := mylib.myapex:64 myotherlib:64 apex_manifest.pb.myapex apex_pubkey.myapex\n")
	ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := mylib.myapex:64 myotherlib:64\n")
}

func TestApexWithJniLibs(t *testing.T) {
@@ -9295,7 +9277,7 @@ func TestApexKeysTxt(t *testing.T) {

	apexKeysText := ctx.SingletonForTests("apex_keys_text")
	content := apexKeysText.MaybeDescription("apexkeys.txt").BuildParams.Args["content"]
	ensureContains(t, content, `name="myapex.apex" public_key="vendor/foo/devkeys/testkey.avbpubkey" private_key="vendor/foo/devkeys/testkey.pem" container_certificate="vendor/foo/devkeys/test.x509.pem" container_private_key="vendor/foo/devkeys/test.pk8" partition="system_ext" sign_tool="sign_myapex"`)
	ensureContains(t, content, `name="myapex.apex" public_key="vendor/foo/devkeys/testkey.avbpubkey" private_key="vendor/foo/devkeys/testkey.pem" container_certificate="vendor/foo/devkeys/test.x509.pem" container_private_key="vendor/foo/devkeys/test.pk8" partition="system" sign_tool="sign_myapex"`)
}

func TestApexKeysTxtOverrides(t *testing.T) {
@@ -9518,7 +9500,7 @@ func TestPreferredPrebuiltSharedLibDep(t *testing.T) {

	// The make level dependency needs to be on otherlib - prebuilt_otherlib isn't
	// a thing there.
	ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := libc++:64 mylib.myapex:64 apex_manifest.pb.myapex apex_pubkey.myapex otherlib\n")
	ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := libc++:64 mylib.myapex:64 otherlib\n")
}

func TestExcludeDependency(t *testing.T) {
@@ -9912,7 +9894,7 @@ func TestAndroidMk_DexpreoptBuiltInstalledForApex(t *testing.T) {
	var builder strings.Builder
	data.Custom(&builder, apexBundle.BaseModuleName(), "TARGET_", "", data)
	androidMk := builder.String()
	ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := foo.myapex apex_manifest.pb.myapex apex_pubkey.myapex foo-dexpreopt-arm64-apex@myapex@javalib@foo.jar@classes.odex foo-dexpreopt-arm64-apex@myapex@javalib@foo.jar@classes.vdex\n")
	ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := foo.myapex foo-dexpreopt-arm64-apex@myapex@javalib@foo.jar@classes.odex foo-dexpreopt-arm64-apex@myapex@javalib@foo.jar@classes.vdex\n")
}

func TestAndroidMk_DexpreoptBuiltInstalledForApex_Prebuilt(t *testing.T) {
@@ -9988,7 +9970,7 @@ func TestAndroidMk_RequiredModules(t *testing.T) {
	var builder strings.Builder
	data.Custom(&builder, apexBundle.BaseModuleName(), "TARGET_", "", data)
	androidMk := builder.String()
	ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := foo.myapex apex_manifest.pb.myapex apex_pubkey.myapex otherapex")
	ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := foo.myapex otherapex")
}

func TestAndroidMk_RequiredDeps(t *testing.T) {
@@ -10012,15 +9994,7 @@ func TestAndroidMk_RequiredDeps(t *testing.T) {
	var builder strings.Builder
	data.Custom(&builder, bundle.BaseModuleName(), "TARGET_", "", data)
	androidMk := builder.String()
	ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := apex_manifest.pb.myapex apex_pubkey.myapex foo\n")

	flattenedBundle := ctx.ModuleForTests("myapex", "android_common_myapex_flattened").Module().(*apexBundle)
	flattenedBundle.makeModulesToInstall = append(flattenedBundle.makeModulesToInstall, "foo")
	flattenedData := android.AndroidMkDataForTest(t, ctx, flattenedBundle)
	var flattenedBuilder strings.Builder
	flattenedData.Custom(&flattenedBuilder, flattenedBundle.BaseModuleName(), "TARGET_", "", flattenedData)
	flattenedAndroidMk := flattenedBuilder.String()
	ensureContains(t, flattenedAndroidMk, "LOCAL_REQUIRED_MODULES := apex_manifest.pb.myapex.flattened apex_pubkey.myapex.flattened foo\n")
	ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := foo\n")
}

func TestApexOutputFileProducer(t *testing.T) {
Loading