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

Commit ec0fe177 authored by Paul Duffin's avatar Paul Duffin
Browse files

Avoid hiddenapi ignoring prebuilt with missing dex implementation jar

Previously, when a prebuilt was preferred but did not provide a
suitable boot dex jar both the source and the prebuilt were silently
ignored which meant that the "hiddenapi list" command was not given a
complete set of boot dex jars. That could either lead to incorrect
hiddenapi flags being set or the "hiddenapi list" command failing if it
could not find a class. Debugging the cause of either of those cases
can be very time consuming so this change fails early and makes the
cause very explicit.

Bug: 181267622
Test: m nothing
Change-Id: I6763ddb9ba90ed2e501d0cf7984f6655237e905d
parent 3785673f
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -148,7 +148,18 @@ func (h *hiddenAPI) initHiddenAPI(ctx android.BaseModuleContext, configurationNa
		primary = configurationName == ctx.ModuleName()

		// A source module that has been replaced by a prebuilt can never be the primary module.
		primary = primary && !module.IsReplacedByPrebuilt()
		if module.IsReplacedByPrebuilt() {
			ctx.VisitDirectDepsWithTag(android.PrebuiltDepTag, func(prebuilt android.Module) {
				if h, ok := prebuilt.(hiddenAPIIntf); ok && h.bootDexJar() != nil {
					primary = false
				} else {
					ctx.ModuleErrorf(
						"hiddenapi has determined that the source module %q should be ignored as it has been"+
							" replaced by the prebuilt module %q but unfortunately it does not provide a"+
							" suitable boot dex jar", ctx.ModuleName(), ctx.OtherModuleName(prebuilt))
				}
			})
		}
	}
	h.primary = primary
}
+23 −0
Original line number Diff line number Diff line
@@ -126,6 +126,29 @@ func TestHiddenAPIIndexSingleton(t *testing.T) {
`, indexParams)
}

func TestHiddenAPISingletonWithSourceAndPrebuiltPreferredButNoDex(t *testing.T) {
	config := testConfigWithBootJars(`
		java_library {
			name: "foo",
			srcs: ["a.java"],
			compile_dex: true,
		}

		java_import {
			name: "foo",
			jars: ["a.jar"],
			prefer: true,
		}
	`, []string{"platform:foo"}, nil)

	ctx := testContextWithHiddenAPI(config)

	runWithErrors(t, ctx, config,
		"hiddenapi has determined that the source module \"foo\" should be ignored as it has been"+
			" replaced by the prebuilt module \"prebuilt_foo\" but unfortunately it does not provide a"+
			" suitable boot dex jar")
}

func TestHiddenAPISingletonWithPrebuilt(t *testing.T) {
	ctx, _ := testHiddenAPIBootJars(t, `
		java_import {
+9 −3
Original line number Diff line number Diff line
@@ -114,20 +114,26 @@ func testJavaErrorWithConfig(t *testing.T, pattern string, config android.Config
	pathCtx := android.PathContextForTesting(config)
	dexpreopt.SetTestGlobalConfig(config, dexpreopt.GlobalConfigForTests(pathCtx))

	runWithErrors(t, ctx, config, pattern)

	return ctx, config
}

func runWithErrors(t *testing.T, ctx *android.TestContext, config android.Config, pattern string) {
	ctx.Register()
	_, errs := ctx.ParseBlueprintsFiles("Android.bp")
	if len(errs) > 0 {
		android.FailIfNoMatchingErrors(t, pattern, errs)
		return ctx, config
		return
	}
	_, errs = ctx.PrepareBuildActions(config)
	if len(errs) > 0 {
		android.FailIfNoMatchingErrors(t, pattern, errs)
		return ctx, config
		return
	}

	t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
	return ctx, config
	return
}

func testJavaWithFS(t *testing.T, bp string, fs map[string][]byte) (*android.TestContext, android.Config) {