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

Commit 03cf3181 authored by Cole Faust's avatar Cole Faust Committed by Gerrit Code Review
Browse files

Merge "Expand preprocessed flag to work on android_app_imports"

parents 3e0836e8 2f1da168
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -1461,10 +1461,8 @@ func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, man

// verifyUsesLibrariesAPK checks the <uses-library> tags in the manifest of an APK against the build
// system and returns the path to a copy of the APK.
func (u *usesLibrary) verifyUsesLibrariesAPK(ctx android.ModuleContext, apk android.Path) android.Path {
func (u *usesLibrary) verifyUsesLibrariesAPK(ctx android.ModuleContext, apk android.Path) {
	u.verifyUsesLibraries(ctx, apk, nil) // for APKs manifest_check does not write output file
	outputFile := android.PathForModuleOut(ctx, "verify_uses_libraries", apk.Base())
	return outputFile
}

// For Bazel / bp2build
+54 −17
Original line number Diff line number Diff line
@@ -49,6 +49,17 @@ var (
		CommandDeps: []string{"${config.Zip2ZipCmd}"},
		Description: "Uncompress dex files",
	})

	checkJniAndDexLibsAreUncompressedRule = pctx.AndroidStaticRule("check-jni-and-dex-libs-are-uncompressed", blueprint.RuleParams{
		// grep -v ' stor ' will search for lines that don't have ' stor '. stor means the file is stored uncompressed
		Command: "if (zipinfo $in 'lib/*.so' '*.dex' 2>/dev/null | grep -v ' stor ' >/dev/null) ; then " +
			"echo $in: Contains compressed JNI libraries and/or dex files >&2;" +
			"exit 1; " +
			"else " +
			"touch $out; " +
			"fi",
		Description: "Check for compressed JNI libs or dex files",
	})
)

func RegisterAppImportBuildComponents(ctx android.RegistrationContext) {
@@ -73,8 +84,6 @@ type AndroidAppImport struct {

	usesLibrary usesLibrary

	preprocessed bool

	installPath android.InstallPath

	hideApexVariantFromMake bool
@@ -128,6 +137,13 @@ type AndroidAppImportProperties struct {

	// Optional. Install to a subdirectory of the default install path for the module
	Relative_install_path *string

	// Whether the prebuilt apk can be installed without additional processing. Default is false.
	Preprocessed *bool

	// Whether or not to skip checking the preprocessed apk for proper alignment and uncompressed
	// JNI libs and dex files. Default is false
	Skip_preprocessed_apk_checks *bool
}

func (a *AndroidAppImport) IsInstallable() bool {
@@ -201,7 +217,7 @@ func (a *AndroidAppImport) uncompressEmbeddedJniLibs(
	ctx android.ModuleContext, inputPath android.Path, outputPath android.OutputPath) {
	// Test apps don't need their JNI libraries stored uncompressed. As a matter of fact, messing
	// with them may invalidate pre-existing signature data.
	if ctx.InstallInTestcases() && (Bool(a.properties.Presigned) || a.preprocessed) {
	if ctx.InstallInTestcases() && (Bool(a.properties.Presigned) || Bool(a.properties.Preprocessed)) {
		ctx.Build(pctx, android.BuildParams{
			Rule:   android.Cp,
			Output: outputPath,
@@ -219,7 +235,7 @@ func (a *AndroidAppImport) uncompressEmbeddedJniLibs(

// Returns whether this module should have the dex file stored uncompressed in the APK.
func (a *AndroidAppImport) shouldUncompressDex(ctx android.ModuleContext) bool {
	if ctx.Config().UnbundledBuild() || a.preprocessed {
	if ctx.Config().UnbundledBuild() || proptools.Bool(a.properties.Preprocessed) {
		return false
	}

@@ -297,7 +313,7 @@ func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext
	a.dexpreopter.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)

	if a.usesLibrary.enforceUsesLibraries() {
		srcApk = a.usesLibrary.verifyUsesLibrariesAPK(ctx, srcApk)
		a.usesLibrary.verifyUsesLibrariesAPK(ctx, srcApk)
	}

	a.dexpreopter.dexpreopt(ctx, jnisUncompressed)
@@ -317,8 +333,15 @@ func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext

	// Sign or align the package if package has not been preprocessed

	if a.preprocessed {
		a.outputFile = srcApk
	if proptools.Bool(a.properties.Preprocessed) {
		output := srcApk
		// TODO(b/185811447) Uncomment this after all existing failing apks set skip_preprocessed_apk_checks: true
		//if !proptools.Bool(a.properties.Skip_preprocessed_apk_checks) {
		//	writableOutput := android.PathForModuleOut(ctx, "validated-prebuilt", apkFilename)
		//	a.validatePreprocessedApk(ctx, srcApk, writableOutput)
		//	output = writableOutput
		//}
		a.outputFile = output
		a.certificate = PresignedCertificate
	} else if !Bool(a.properties.Presigned) {
		// If the certificate property is empty at this point, default_dev_cert must be set to true.
@@ -352,6 +375,30 @@ func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext
	// TODO: androidmk converter jni libs
}

func (a *AndroidAppImport) validatePreprocessedApk(ctx android.ModuleContext, srcApk android.Path, dstApk android.WritablePath) {
	alignmentStamp := android.PathForModuleOut(ctx, "validated-prebuilt", "alignment.stamp")
	ctx.Build(pctx, android.BuildParams{
		Rule:   checkZipAlignment,
		Input:  srcApk,
		Output: alignmentStamp,
	})
	compressionStamp := android.PathForModuleOut(ctx, "validated-prebuilt", "compression.stamp")
	ctx.Build(pctx, android.BuildParams{
		Rule:   checkJniAndDexLibsAreUncompressedRule,
		Input:  srcApk,
		Output: compressionStamp,
	})
	ctx.Build(pctx, android.BuildParams{
		Rule:   android.Cp,
		Input:  srcApk,
		Output: dstApk,
		Validations: []android.Path{
			alignmentStamp,
			compressionStamp,
		},
	})
}

func (a *AndroidAppImport) Prebuilt() *android.Prebuilt {
	return &a.prebuilt
}
@@ -487,11 +534,6 @@ func AndroidAppImportFactory() android.Module {
	return module
}

type androidTestImportProperties struct {
	// Whether the prebuilt apk can be installed without additional processing. Default is false.
	Preprocessed *bool
}

type AndroidTestImport struct {
	AndroidAppImport

@@ -508,14 +550,10 @@ type AndroidTestImport struct {
		Per_testcase_directory *bool
	}

	testImportProperties androidTestImportProperties

	data android.Paths
}

func (a *AndroidTestImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	a.preprocessed = Bool(a.testImportProperties.Preprocessed)

	a.generateAndroidBuildActions(ctx)

	a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
@@ -532,7 +570,6 @@ func AndroidTestImportFactory() android.Module {
	module.AddProperties(&module.properties)
	module.AddProperties(&module.dexpreoptProperties)
	module.AddProperties(&module.testProperties)
	module.AddProperties(&module.testImportProperties)
	module.populateAllVariantStructs()
	android.AddLoadHook(module, func(ctx android.LoadHookContext) {
		module.processVariants(ctx)
+24 −0
Original line number Diff line number Diff line
@@ -657,6 +657,30 @@ func TestAndroidTestImport_Preprocessed(t *testing.T) {
	}
}

// TODO(b/185811447) Uncomment this after all existing failing apks set skip_preprocessed_apk_checks: true
//func TestAndroidAppImport_Preprocessed(t *testing.T) {
//	ctx, _ := testJava(t, `
//		android_app_import {
//			name: "foo",
//			apk: "prebuilts/apk/app.apk",
//			presigned: true,
//			preprocessed: true,
//		}
//		`)
//
//	apkName := "foo.apk"
//	variant := ctx.ModuleForTests("foo", "android_common")
//	outputBuildParams := variant.Output("validated-prebuilt/" + apkName).BuildParams
//	if outputBuildParams.Rule.String() != android.Cp.String() {
//		t.Errorf("Unexpected prebuilt android_app_import rule: " + outputBuildParams.Rule.String())
//	}
//
//	// Make sure compression and aligning were validated.
//	if len(outputBuildParams.Validations) != 2 {
//		t.Errorf("Expected compression/alignment validation rules, found %d validations", len(outputBuildParams.Validations))
//	}
//}

func TestAndroidTestImport_UncompressDex(t *testing.T) {
	testCases := []struct {
		name string
+13 −0
Original line number Diff line number Diff line
@@ -246,6 +246,19 @@ var (
			CommandDeps: []string{"${config.ZipAlign}"},
		},
	)

	checkZipAlignment = pctx.AndroidStaticRule("checkzipalign",
		blueprint.RuleParams{
			Command: "if ! ${config.ZipAlign} -c -p 4 $in > /dev/null; then " +
				"echo $in: Improper package alignment >&2; " +
				"exit 1; " +
				"else " +
				"touch $out; " +
				"fi",
			CommandDeps: []string{"${config.ZipAlign}"},
			Description: "Check zip alignment",
		},
	)
)

func init() {