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

Commit 94098e88 authored by Jingwen Chen's avatar Jingwen Chen
Browse files

apex mixed builds: use the .capex when required.

The .capex is the compressed apex. Depending on various conditions, the
.capex should be installed, and thus the
apex.go#ProcessBazelQueryResponse should set the .capex as the main apex
output file.

Fixes: 264873511
Test: new unit test with install rules
Test: m com.android.adbd --bazel-mode-staging gives:

$ ls -lah
out/target/product/generic_arm64/system/apex/com.android.adbd.capex
-rw-r----- 1 jingwen primarygroup 3.6M Jan 10 14:44 out/target/product/generic_arm64/system/apex/com.android.adbd.capex

Change-Id: Ic3143cc6999f111428c6adb76760be8ddc4b6344
parent d6dd6a3c
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -1905,9 +1905,15 @@ func (a *apexBundle) ProcessBazelQueryResponse(ctx android.ModuleContext) {
		return
	}
	a.installDir = android.PathForModuleInstall(ctx, "apex")

	// Set the output file to .apex or .capex depending on the compression configuration.
	a.setCompression(ctx)
	if a.isCompressed {
		a.outputApexFile = android.PathForBazelOut(ctx, outputs.SignedCompressedOutput)
	} else {
		a.outputApexFile = android.PathForBazelOut(ctx, outputs.SignedOutput)
	}
	a.outputFile = a.outputApexFile
	a.setCompression(ctx)

	// TODO(b/257829940): These are used by the apex_keys_text singleton; would probably be a clearer
	// interface if these were set in a provider rather than the module itself
+72 −9
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ apex {
				LabelToApexInfo: map[string]cquery.ApexInfo{
					"//:foo": cquery.ApexInfo{
						SignedOutput:           "signed_out.apex",
						SignedCompressedOutput: "signed_out.capex",
						UnsignedOutput:         "unsigned_out.apex",
						BundleKeyInfo:          []string{"public_key", "private_key"},
						ContainerKeyInfo:       []string{"container_cert", "container_private"},
@@ -115,6 +116,68 @@ apex {
	}
}

func TestCompressedApexImageInMixedBuilds(t *testing.T) {
	bp := `
apex_key{
	name: "foo_key",
}
apex {
	name: "foo",
	key: "foo_key",
	updatable: true,
	min_sdk_version: "31",
	file_contexts: ":myapex-file_contexts",
	bazel_module: { label: "//:foo" },
	test_only_force_compression: true, // force compression
}`

	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{
						SignedOutput:           "signed_out.apex",
						SignedCompressedOutput: "signed_out.capex",
						BundleKeyInfo:          []string{"public_key", "private_key"},
						ContainerKeyInfo:       []string{"container_cert", "container_private"},
					},
				},
			}
		}),
	).RunTestWithBp(t, bp)

	m := result.ModuleForTests("foo", "android_common_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__/signed_out.capex", ab.outputFile.String(); w != g {
		t.Errorf("Expected output file to be compressed apex %q, got %q", w, g)
	}

	mkData := android.AndroidMkDataForTest(t, result.TestContext, m)
	var builder strings.Builder
	mkData.Custom(&builder, "foo", "BAZEL_TARGET_", "", mkData)

	data := builder.String()

	expectedAndroidMk := []string{
		"LOCAL_PREBUILT_MODULE_FILE := out/bazel/execroot/__main__/signed_out.capex",

		// Check that the source install file is the capex. The dest is not important.
		"LOCAL_SOONG_INSTALL_PAIRS := out/bazel/execroot/__main__/signed_out.capex:",
	}
	for _, androidMk := range expectedAndroidMk {
		if !strings.Contains(data, androidMk) {
			t.Errorf("Expected %q in androidmk data, but did not find %q", androidMk, data)
		}
	}
}

func TestOverrideApexImageInMixedBuilds(t *testing.T) {
	bp := `
apex_key{
+19 −12
Original line number Diff line number Diff line
@@ -232,8 +232,14 @@ if not info:
  fail("%s did not provide ApexInfo" % id_string)
bundle_key_info = info.bundle_key_info
container_key_info = info.container_key_info

signed_compressed_output = "" # no .capex if the apex is not compressible, cannot be None as it needs to be json encoded.
if info.signed_compressed_output:
    signed_compressed_output = info.signed_compressed_output.path

return json_encode({
    "signed_output": info.signed_output.path,
    "signed_compressed_output": signed_compressed_output,
    "unsigned_output": info.unsigned_output.path,
    "provides_native_libs": [str(lib) for lib in info.provides_native_libs],
    "requires_native_libs": [str(lib) for lib in info.requires_native_libs],
@@ -250,6 +256,7 @@ return json_encode({

type ApexInfo struct {
	SignedOutput           string   `json:"signed_output"`
	SignedCompressedOutput string   `json:"signed_compressed_output"`
	UnsignedOutput         string   `json:"unsigned_output"`
	ProvidesLibs           []string `json:"provides_native_libs"`
	RequiresLibs           []string `json:"requires_native_libs"`