Suffix the build ID to the dirname of APK-in-APEX files.
This fixes an issue with package manager's cache invalidation. Test: CI Bug: 226559955 Bug: 224589412 Change-Id: I8af49d51ff99cf8184d0e4d1136fff1cdb29c23e Merged-In: I8af49d51ff99cf8184d0e4d1136fff1cdb29c23e
This commit is contained in:
committed by
Andrei-Valentin Onea
parent
9345773428
commit
11cca671ac
31
apex/apex.go
31
apex/apex.go
@@ -19,6 +19,7 @@ package apex
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -1537,13 +1538,33 @@ type androidApp interface {
|
|||||||
var _ androidApp = (*java.AndroidApp)(nil)
|
var _ androidApp = (*java.AndroidApp)(nil)
|
||||||
var _ androidApp = (*java.AndroidAppImport)(nil)
|
var _ androidApp = (*java.AndroidAppImport)(nil)
|
||||||
|
|
||||||
|
func sanitizedBuildIdForPath(ctx android.BaseModuleContext) string {
|
||||||
|
buildId := ctx.Config().BuildId()
|
||||||
|
|
||||||
|
// The build ID is used as a suffix for a filename, so ensure that
|
||||||
|
// the set of characters being used are sanitized.
|
||||||
|
// - any word character: [a-zA-Z0-9_]
|
||||||
|
// - dots: .
|
||||||
|
// - dashes: -
|
||||||
|
validRegex := regexp.MustCompile(`^[\w\.\-\_]+$`)
|
||||||
|
if !validRegex.MatchString(buildId) {
|
||||||
|
ctx.ModuleErrorf("Unable to use build id %s as filename suffix, valid characters are [a-z A-Z 0-9 _ . -].", buildId)
|
||||||
|
}
|
||||||
|
return buildId
|
||||||
|
}
|
||||||
|
|
||||||
func apexFileForAndroidApp(ctx android.BaseModuleContext, aapp androidApp) apexFile {
|
func apexFileForAndroidApp(ctx android.BaseModuleContext, aapp androidApp) apexFile {
|
||||||
appDir := "app"
|
appDir := "app"
|
||||||
if aapp.Privileged() {
|
if aapp.Privileged() {
|
||||||
appDir = "priv-app"
|
appDir = "priv-app"
|
||||||
}
|
}
|
||||||
dirInApex := filepath.Join(appDir, aapp.InstallApkName())
|
|
||||||
|
// TODO(b/224589412, b/226559955): Ensure that the subdirname is suffixed
|
||||||
|
// so that PackageManager correctly invalidates the existing installed apk
|
||||||
|
// in favour of the new APK-in-APEX. See bugs for more information.
|
||||||
|
dirInApex := filepath.Join(appDir, aapp.InstallApkName()+"@"+sanitizedBuildIdForPath(ctx))
|
||||||
fileToCopy := aapp.OutputFile()
|
fileToCopy := aapp.OutputFile()
|
||||||
|
|
||||||
af := newApexFile(ctx, fileToCopy, aapp.BaseModuleName(), dirInApex, app, aapp)
|
af := newApexFile(ctx, fileToCopy, aapp.BaseModuleName(), dirInApex, app, aapp)
|
||||||
af.jacocoReportClassesFile = aapp.JacocoReportClassesFile()
|
af.jacocoReportClassesFile = aapp.JacocoReportClassesFile()
|
||||||
af.lintDepSets = aapp.LintDepSets()
|
af.lintDepSets = aapp.LintDepSets()
|
||||||
@@ -1756,8 +1777,12 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
if ap.Privileged() {
|
if ap.Privileged() {
|
||||||
appDir = "priv-app"
|
appDir = "priv-app"
|
||||||
}
|
}
|
||||||
af := newApexFile(ctx, ap.OutputFile(), ap.BaseModuleName(),
|
// TODO(b/224589412, b/226559955): Ensure that the dirname is
|
||||||
filepath.Join(appDir, ap.BaseModuleName()), appSet, ap)
|
// suffixed so that PackageManager correctly invalidates the
|
||||||
|
// existing installed apk in favour of the new APK-in-APEX.
|
||||||
|
// See bugs for more information.
|
||||||
|
appDirName := filepath.Join(appDir, ap.BaseModuleName()+"@"+sanitizedBuildIdForPath(ctx))
|
||||||
|
af := newApexFile(ctx, ap.OutputFile(), ap.BaseModuleName(), appDirName, appSet, ap)
|
||||||
af.certificate = java.PresignedCertificate
|
af.certificate = java.PresignedCertificate
|
||||||
filesInfo = append(filesInfo, af)
|
filesInfo = append(filesInfo, af)
|
||||||
} else {
|
} else {
|
||||||
|
@@ -217,6 +217,7 @@ var prepareForApexTest = android.GroupFixturePreparers(
|
|||||||
variables.Platform_sdk_final = proptools.BoolPtr(false)
|
variables.Platform_sdk_final = proptools.BoolPtr(false)
|
||||||
variables.Platform_version_active_codenames = []string{"Q"}
|
variables.Platform_version_active_codenames = []string{"Q"}
|
||||||
variables.Platform_vndk_version = proptools.StringPtr("29")
|
variables.Platform_vndk_version = proptools.StringPtr("29")
|
||||||
|
variables.BuildId = proptools.StringPtr("TEST.BUILD_ID")
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -686,7 +687,7 @@ func TestDefaults(t *testing.T) {
|
|||||||
"etc/myetc",
|
"etc/myetc",
|
||||||
"javalib/myjar.jar",
|
"javalib/myjar.jar",
|
||||||
"lib64/mylib.so",
|
"lib64/mylib.so",
|
||||||
"app/AppFoo/AppFoo.apk",
|
"app/AppFoo@TEST.BUILD_ID/AppFoo.apk",
|
||||||
"overlay/blue/rro.apk",
|
"overlay/blue/rro.apk",
|
||||||
"etc/bpf/bpf.o",
|
"etc/bpf/bpf.o",
|
||||||
"etc/bpf/bpf2.o",
|
"etc/bpf/bpf2.o",
|
||||||
@@ -5124,8 +5125,8 @@ func TestApexWithApps(t *testing.T) {
|
|||||||
apexRule := module.Rule("apexRule")
|
apexRule := module.Rule("apexRule")
|
||||||
copyCmds := apexRule.Args["copy_commands"]
|
copyCmds := apexRule.Args["copy_commands"]
|
||||||
|
|
||||||
ensureContains(t, copyCmds, "image.apex/app/AppFoo/AppFoo.apk")
|
ensureContains(t, copyCmds, "image.apex/app/AppFoo@TEST.BUILD_ID/AppFoo.apk")
|
||||||
ensureContains(t, copyCmds, "image.apex/priv-app/AppFooPriv/AppFooPriv.apk")
|
ensureContains(t, copyCmds, "image.apex/priv-app/AppFooPriv@TEST.BUILD_ID/AppFooPriv.apk")
|
||||||
|
|
||||||
appZipRule := ctx.ModuleForTests("AppFoo", "android_common_apex10000").Description("zip jni libs")
|
appZipRule := ctx.ModuleForTests("AppFoo", "android_common_apex10000").Description("zip jni libs")
|
||||||
// JNI libraries are uncompressed
|
// JNI libraries are uncompressed
|
||||||
@@ -5142,6 +5143,36 @@ func TestApexWithApps(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestApexWithAppImportBuildId(t *testing.T) {
|
||||||
|
invalidBuildIds := []string{"../", "a b", "a/b", "a/b/../c", "/a"}
|
||||||
|
for _, id := range invalidBuildIds {
|
||||||
|
message := fmt.Sprintf("Unable to use build id %s as filename suffix", id)
|
||||||
|
fixture := android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
|
||||||
|
variables.BuildId = proptools.StringPtr(id)
|
||||||
|
})
|
||||||
|
testApexError(t, message, `apex {
|
||||||
|
name: "myapex",
|
||||||
|
key: "myapex.key",
|
||||||
|
apps: ["AppFooPrebuilt"],
|
||||||
|
updatable: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
apex_key {
|
||||||
|
name: "myapex.key",
|
||||||
|
public_key: "testkey.avbpubkey",
|
||||||
|
private_key: "testkey.pem",
|
||||||
|
}
|
||||||
|
|
||||||
|
android_app_import {
|
||||||
|
name: "AppFooPrebuilt",
|
||||||
|
apk: "PrebuiltAppFoo.apk",
|
||||||
|
presigned: true,
|
||||||
|
apex_available: ["myapex"],
|
||||||
|
}
|
||||||
|
`, fixture)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestApexWithAppImports(t *testing.T) {
|
func TestApexWithAppImports(t *testing.T) {
|
||||||
ctx := testApex(t, `
|
ctx := testApex(t, `
|
||||||
apex {
|
apex {
|
||||||
@@ -5187,8 +5218,8 @@ func TestApexWithAppImports(t *testing.T) {
|
|||||||
apexRule := module.Rule("apexRule")
|
apexRule := module.Rule("apexRule")
|
||||||
copyCmds := apexRule.Args["copy_commands"]
|
copyCmds := apexRule.Args["copy_commands"]
|
||||||
|
|
||||||
ensureContains(t, copyCmds, "image.apex/app/AppFooPrebuilt/AppFooPrebuilt.apk")
|
ensureContains(t, copyCmds, "image.apex/app/AppFooPrebuilt@TEST.BUILD_ID/AppFooPrebuilt.apk")
|
||||||
ensureContains(t, copyCmds, "image.apex/priv-app/AppFooPrivPrebuilt/AwesomePrebuiltAppFooPriv.apk")
|
ensureContains(t, copyCmds, "image.apex/priv-app/AppFooPrivPrebuilt@TEST.BUILD_ID/AwesomePrebuiltAppFooPriv.apk")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestApexWithAppImportsPrefer(t *testing.T) {
|
func TestApexWithAppImportsPrefer(t *testing.T) {
|
||||||
@@ -5229,7 +5260,7 @@ func TestApexWithAppImportsPrefer(t *testing.T) {
|
|||||||
}))
|
}))
|
||||||
|
|
||||||
ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
|
ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
|
||||||
"app/AppFoo/AppFooPrebuilt.apk",
|
"app/AppFoo@TEST.BUILD_ID/AppFooPrebuilt.apk",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5262,7 +5293,7 @@ func TestApexWithTestHelperApp(t *testing.T) {
|
|||||||
apexRule := module.Rule("apexRule")
|
apexRule := module.Rule("apexRule")
|
||||||
copyCmds := apexRule.Args["copy_commands"]
|
copyCmds := apexRule.Args["copy_commands"]
|
||||||
|
|
||||||
ensureContains(t, copyCmds, "image.apex/app/TesterHelpAppFoo/TesterHelpAppFoo.apk")
|
ensureContains(t, copyCmds, "image.apex/app/TesterHelpAppFoo@TEST.BUILD_ID/TesterHelpAppFoo.apk")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestApexPropertiesShouldBeDefaultable(t *testing.T) {
|
func TestApexPropertiesShouldBeDefaultable(t *testing.T) {
|
||||||
@@ -5609,8 +5640,8 @@ func TestOverrideApex(t *testing.T) {
|
|||||||
apexRule := module.Rule("apexRule")
|
apexRule := module.Rule("apexRule")
|
||||||
copyCmds := apexRule.Args["copy_commands"]
|
copyCmds := apexRule.Args["copy_commands"]
|
||||||
|
|
||||||
ensureNotContains(t, copyCmds, "image.apex/app/app/app.apk")
|
ensureNotContains(t, copyCmds, "image.apex/app/app@TEST.BUILD_ID/app.apk")
|
||||||
ensureContains(t, copyCmds, "image.apex/app/override_app/override_app.apk")
|
ensureContains(t, copyCmds, "image.apex/app/override_app@TEST.BUILD_ID/override_app.apk")
|
||||||
|
|
||||||
apexBundle := module.Module().(*apexBundle)
|
apexBundle := module.Module().(*apexBundle)
|
||||||
name := apexBundle.Name()
|
name := apexBundle.Name()
|
||||||
@@ -6349,7 +6380,7 @@ func TestAppBundle(t *testing.T) {
|
|||||||
content := bundleConfigRule.Args["content"]
|
content := bundleConfigRule.Args["content"]
|
||||||
|
|
||||||
ensureContains(t, content, `"compression":{"uncompressed_glob":["apex_payload.img","apex_manifest.*"]}`)
|
ensureContains(t, content, `"compression":{"uncompressed_glob":["apex_payload.img","apex_manifest.*"]}`)
|
||||||
ensureContains(t, content, `"apex_config":{"apex_embedded_apk_config":[{"package_name":"com.android.foo","path":"app/AppFoo/AppFoo.apk"}]}`)
|
ensureContains(t, content, `"apex_config":{"apex_embedded_apk_config":[{"package_name":"com.android.foo","path":"app/AppFoo@TEST.BUILD_ID/AppFoo.apk"}]}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAppSetBundle(t *testing.T) {
|
func TestAppSetBundle(t *testing.T) {
|
||||||
@@ -6380,9 +6411,9 @@ func TestAppSetBundle(t *testing.T) {
|
|||||||
if len(copyCmds) != 3 {
|
if len(copyCmds) != 3 {
|
||||||
t.Fatalf("Expected 3 commands, got %d in:\n%s", len(copyCmds), s)
|
t.Fatalf("Expected 3 commands, got %d in:\n%s", len(copyCmds), s)
|
||||||
}
|
}
|
||||||
ensureMatches(t, copyCmds[0], "^rm -rf .*/app/AppSet$")
|
ensureMatches(t, copyCmds[0], "^rm -rf .*/app/AppSet@TEST.BUILD_ID$")
|
||||||
ensureMatches(t, copyCmds[1], "^mkdir -p .*/app/AppSet$")
|
ensureMatches(t, copyCmds[1], "^mkdir -p .*/app/AppSet@TEST.BUILD_ID$")
|
||||||
ensureMatches(t, copyCmds[2], "^unzip .*-d .*/app/AppSet .*/AppSet.zip$")
|
ensureMatches(t, copyCmds[2], "^unzip .*-d .*/app/AppSet@TEST.BUILD_ID .*/AppSet.zip$")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAppSetBundlePrebuilt(t *testing.T) {
|
func TestAppSetBundlePrebuilt(t *testing.T) {
|
||||||
|
Reference in New Issue
Block a user