diff --git a/android/test_asserts.go b/android/test_asserts.go index 4143f150d..5cc7e4ac0 100644 --- a/android/test_asserts.go +++ b/android/test_asserts.go @@ -17,6 +17,7 @@ package android import ( "fmt" "reflect" + "regexp" "strings" "testing" ) @@ -137,6 +138,20 @@ func AssertStringContainsEquals(t *testing.T, message string, s string, substrin } } +// AssertStringMatches checks if the string matches the given regular expression. If it does not match, +// then an error is reported with the supplied message including a reason for why it failed. +func AssertStringMatches(t *testing.T, message, s, expectedRex string) { + t.Helper() + ok, err := regexp.MatchString(expectedRex, s) + if err != nil { + t.Fatalf("regexp failure trying to match %s against `%s` expression: %s", s, expectedRex, err) + return + } + if !ok { + t.Errorf("%s does not match regular expression %s", s, expectedRex) + } +} + // AssertStringListContains checks if the list of strings contains the expected string. If it does // not then it reports an error prefixed with the supplied message and including a reason for why it // failed. diff --git a/apex/apex.go b/apex/apex.go index 1c794639c..f49492e84 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -1871,14 +1871,17 @@ func apexFilesForAndroidApp(ctx android.BaseModuleContext, aapp androidApp) []ap }); ok { af.overriddenPackageName = app.OverriddenManifestPackageName() } - apexFiles := []apexFile{af} + + apexFiles := []apexFile{} if allowlist := aapp.PrivAppAllowlist(); allowlist.Valid() { dirInApex := filepath.Join("etc", "permissions") - privAppAllowlist := newApexFile(ctx, allowlist.Path(), aapp.BaseModuleName()+"privapp", dirInApex, etc, aapp) + privAppAllowlist := newApexFile(ctx, allowlist.Path(), aapp.BaseModuleName()+"_privapp", dirInApex, etc, aapp) apexFiles = append(apexFiles, privAppAllowlist) } + apexFiles = append(apexFiles, af) + return apexFiles } diff --git a/apex/apex_test.go b/apex/apex_test.go index 2dad22b06..38e24e844 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -6305,6 +6305,18 @@ func TestApexWithApps(t *testing.T) { // ... and not directly inside the APEX ensureNotContains(t, copyCmds, "image.apex/lib64/"+jni+".so") } + + apexBundle := module.Module().(*apexBundle) + data := android.AndroidMkDataForTest(t, ctx, apexBundle) + var builder strings.Builder + data.Custom(&builder, apexBundle.Name(), "TARGET_", "", data) + androidMk := builder.String() + ensureContains(t, androidMk, "LOCAL_MODULE := AppFooPriv.myapex") + ensureContains(t, androidMk, "LOCAL_MODULE := AppFoo.myapex") + ensureMatches(t, androidMk, "LOCAL_SOONG_INSTALLED_MODULE := \\S+AppFooPriv.apk") + ensureMatches(t, androidMk, "LOCAL_SOONG_INSTALLED_MODULE := \\S+AppFoo.apk") + ensureMatches(t, androidMk, "LOCAL_SOONG_INSTALL_PAIRS := \\S+AppFooPriv.apk") + ensureContains(t, androidMk, "LOCAL_SOONG_INSTALL_PAIRS := privapp_allowlist_com.android.AppFooPriv.xml:$(PRODUCT_OUT)/apex/myapex/etc/permissions/privapp_allowlist_com.android.AppFooPriv.xml") } func TestApexWithAppImportBuildId(t *testing.T) { diff --git a/java/app.go b/java/app.go index d0bde6f22..561ce1d17 100755 --- a/java/app.go +++ b/java/app.go @@ -613,7 +613,6 @@ func processMainCert(m android.ModuleBase, certPropValue string, certificates [] } } - return mainCertificate, certificates } @@ -795,17 +794,17 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { // Install the app package. shouldInstallAppPackage := (Bool(a.Module.properties.Installable) || ctx.Host()) && apexInfo.IsForPlatform() && !a.appProperties.PreventInstall if shouldInstallAppPackage { + if a.privAppAllowlist.Valid() { + installPath := android.PathForModuleInstall(ctx, "etc", "permissions") + ctx.InstallFile(installPath, a.privAppAllowlist.Path().Base(), a.privAppAllowlist.Path()) + } + var extraInstalledPaths android.Paths for _, extra := range a.extraOutputFiles { installed := ctx.InstallFile(a.installDir, extra.Base(), extra) extraInstalledPaths = append(extraInstalledPaths, installed) } ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile, extraInstalledPaths...) - - if a.privAppAllowlist.Valid() { - installPath := android.PathForModuleInstall(ctx, "etc", "permissions") - ctx.InstallFile(installPath, a.privAppAllowlist.Path().Base(), a.privAppAllowlist.Path()) - } } a.buildAppDependencyInfo(ctx) diff --git a/java/app_test.go b/java/app_test.go index 4b78c48a5..9293da48e 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -3589,3 +3589,82 @@ func TestPrivappAllowlist(t *testing.T) { app.Output("out/soong/target/product/test_device/system/etc/permissions/privapp_allowlist_com.android.foo.xml") overrideApp.Output("out/soong/target/product/test_device/system/etc/permissions/privapp_allowlist_com.google.android.foo.xml") } + +func TestPrivappAllowlistAndroidMk(t *testing.T) { + result := android.GroupFixturePreparers( + PrepareForTestWithJavaDefaultModules, + android.PrepareForTestWithAndroidMk, + ).RunTestWithBp( + t, + ` + android_app { + name: "foo", + srcs: ["a.java"], + privapp_allowlist: "privapp_allowlist_com.android.foo.xml", + privileged: true, + sdk_version: "current", + } + override_android_app { + name: "bar", + base: "foo", + package_name: "com.google.android.foo", + } + `, + ) + baseApp := result.ModuleForTests("foo", "android_common") + overrideApp := result.ModuleForTests("foo", "android_common_bar") + + baseAndroidApp := baseApp.Module().(*AndroidApp) + baseEntries := android.AndroidMkEntriesForTest(t, result.TestContext, baseAndroidApp)[0] + android.AssertStringMatches( + t, + "androidmk has incorrect LOCAL_SOONG_INSTALLED_MODULE; expected to find foo.apk", + baseEntries.EntryMap["LOCAL_SOONG_INSTALLED_MODULE"][0], + "\\S+foo.apk", + ) + android.AssertStringMatches( + t, + "androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include foo.apk", + baseEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0], + "\\S+foo.apk", + ) + android.AssertStringMatches( + t, + "androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include app", + baseEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0], + "\\S+foo.apk:\\S+/target/product/test_device/system/priv-app/foo/foo.apk", + ) + android.AssertStringMatches( + t, + "androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include privapp_allowlist", + baseEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0], + "privapp_allowlist_com.android.foo.xml:\\S+/target/product/test_device/system/etc/permissions/privapp_allowlist_com.android.foo.xml", + ) + + overrideAndroidApp := overrideApp.Module().(*AndroidApp) + overrideEntries := android.AndroidMkEntriesForTest(t, result.TestContext, overrideAndroidApp)[0] + android.AssertStringMatches( + t, + "androidmk has incorrect LOCAL_SOONG_INSTALLED_MODULE; expected to find bar.apk", + overrideEntries.EntryMap["LOCAL_SOONG_INSTALLED_MODULE"][0], + "\\S+bar.apk", + ) + android.AssertStringMatches( + t, + "androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include bar.apk", + overrideEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0], + "\\S+bar.apk", + ) + android.AssertStringMatches( + t, + "androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include app", + overrideEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0], + "\\S+bar.apk:\\S+/target/product/test_device/system/priv-app/bar/bar.apk", + ) + android.AssertStringMatches( + t, + "androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include privapp_allowlist", + overrideEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0], + "\\S+soong/.intermediates/foo/android_common_bar/privapp_allowlist_com.google.android.foo.xml:\\S+/target/product/test_device/system/etc/permissions/privapp_allowlist_com.google.android.foo.xml", + ) +}