From 9befb0c3261a336c4df12ceefb295a71b3c7dbf1 Mon Sep 17 00:00:00 2001 From: Jaewoong Jung Date: Sat, 18 Jan 2020 10:33:43 -0800 Subject: [PATCH] Add runtime_resource_overlay. Fixes: 119811120 Test: app_test.go Test: Converted and built IconPackFilledSystemUIOverlay Change-Id: I71841148c25f820ba829f751a201d2c771c8bd20 --- java/aar.go | 3 +- java/androidmk.go | 13 +++++++ java/app.go | 90 +++++++++++++++++++++++++++++++++++++++++++++++ java/app_test.go | 42 ++++++++++++++++++++++ java/sdk.go | 5 +-- 5 files changed, 150 insertions(+), 3 deletions(-) diff --git a/java/aar.go b/java/aar.go index ae064e5b6..1ba65dc75 100644 --- a/java/aar.go +++ b/java/aar.go @@ -15,11 +15,12 @@ package java import ( - "android/soong/android" "fmt" "path/filepath" "strings" + "android/soong/android" + "github.com/google/blueprint" "github.com/google/blueprint/proptools" ) diff --git a/java/androidmk.go b/java/androidmk.go index 04bf15cf4..7c19180e3 100644 --- a/java/androidmk.go +++ b/java/androidmk.go @@ -695,3 +695,16 @@ func androidMkWriteTestData(data android.Paths, entries *android.AndroidMkEntrie } entries.AddStrings("LOCAL_COMPATIBILITY_SUPPORT_FILES", testFiles...) } + +func (r *RuntimeResourceOverlay) AndroidMkEntries() []android.AndroidMkEntries { + return []android.AndroidMkEntries{android.AndroidMkEntries{ + Class: "ETC", + OutputFile: android.OptionalPathForPath(r.outputFile), + Include: "$(BUILD_SYSTEM)/soong_app_prebuilt.mk", + ExtraEntries: []android.AndroidMkExtraEntriesFunc{ + func(entries *android.AndroidMkEntries) { + entries.SetPath("LOCAL_MODULE_PATH", r.installDir.ToMakePath()) + }, + }, + }} +} diff --git a/java/app.go b/java/app.go index e9941f2d2..d253a122e 100755 --- a/java/app.go +++ b/java/app.go @@ -47,6 +47,7 @@ func RegisterAppBuildComponents(ctx android.RegistrationContext) { ctx.RegisterModuleType("override_android_test", OverrideAndroidTestModuleFactory) ctx.RegisterModuleType("android_app_import", AndroidAppImportFactory) ctx.RegisterModuleType("android_test_import", AndroidTestImportFactory) + ctx.RegisterModuleType("runtime_resource_overlay", RuntimeResourceOverlayFactory) } // AndroidManifest.xml merging @@ -1212,6 +1213,95 @@ func AndroidTestImportFactory() android.Module { return module } +type RuntimeResourceOverlay struct { + android.ModuleBase + android.DefaultableModuleBase + aapt + + properties RuntimeResourceOverlayProperties + + outputFile android.Path + installDir android.InstallPath +} + +type RuntimeResourceOverlayProperties struct { + // the name of a certificate in the default certificate directory or an android_app_certificate + // module name in the form ":module". + Certificate *string + + // optional theme name. If specified, the overlay package will be applied + // only when the ro.boot.vendor.overlay.theme system property is set to the same value. + Theme *string + + // if not blank, set to the version of the sdk to compile against. + // Defaults to compiling against the current platform. + Sdk_version *string + + // if not blank, set the minimum version of the sdk that the compiled artifacts will run against. + // Defaults to sdk_version if not set. + Min_sdk_version *string +} + +func (r *RuntimeResourceOverlay) DepsMutator(ctx android.BottomUpMutatorContext) { + sdkDep := decodeSdkDep(ctx, sdkContext(r)) + if sdkDep.hasFrameworkLibs() { + r.aapt.deps(ctx, sdkDep) + } + + cert := android.SrcIsModule(String(r.properties.Certificate)) + if cert != "" { + ctx.AddDependency(ctx.Module(), certificateTag, cert) + } +} + +func (r *RuntimeResourceOverlay) GenerateAndroidBuildActions(ctx android.ModuleContext) { + // Compile and link resources + r.aapt.hasNoCode = true + r.aapt.buildActions(ctx, r) + + // Sign the built package + _, certificates := collectAppDeps(ctx, false) + certificates = processMainCert(r.ModuleBase, String(r.properties.Certificate), certificates, ctx) + signed := android.PathForModuleOut(ctx, "signed", r.Name()+".apk") + SignAppPackage(ctx, signed, r.aapt.exportPackage, certificates) + + r.outputFile = signed + r.installDir = android.PathForModuleInstall(ctx, "overlay", String(r.properties.Theme)) + ctx.InstallFile(r.installDir, r.outputFile.Base(), r.outputFile) +} + +func (r *RuntimeResourceOverlay) sdkVersion() string { + return String(r.properties.Sdk_version) +} + +func (r *RuntimeResourceOverlay) systemModules() string { + return "" +} + +func (r *RuntimeResourceOverlay) minSdkVersion() string { + if r.properties.Min_sdk_version != nil { + return *r.properties.Min_sdk_version + } + return r.sdkVersion() +} + +func (r *RuntimeResourceOverlay) targetSdkVersion() string { + return r.sdkVersion() +} + +// runtime_resource_overlay generates a resource-only apk file that can overlay application and +// system resources at run time. +func RuntimeResourceOverlayFactory() android.Module { + module := &RuntimeResourceOverlay{} + module.AddProperties( + &module.properties, + &module.aaptProperties) + + InitJavaModule(module, android.DeviceSupported) + + return module +} + type UsesLibraryProperties struct { // A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file. Uses_libs []string diff --git a/java/app_test.go b/java/app_test.go index 6f89da410..ce5c8930e 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -2207,3 +2207,45 @@ func checkAapt2LinkFlag(t *testing.T, aapt2Flags, flagName, expectedValue string } } } + +func TestRuntimeResourceOverlay(t *testing.T) { + ctx, config := testJava(t, ` + runtime_resource_overlay { + name: "foo", + certificate: "platform", + product_specific: true, + } + + runtime_resource_overlay { + name: "foo_themed", + certificate: "platform", + product_specific: true, + theme: "faza", + } + `) + + m := ctx.ModuleForTests("foo", "android_common") + + // Check cert signing flag. + signedApk := m.Output("signed/foo.apk") + signingFlag := signedApk.Args["certificates"] + expected := "build/make/target/product/security/platform.x509.pem build/make/target/product/security/platform.pk8" + if expected != signingFlag { + t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected, signingFlag) + } + + // Check device location. + path := android.AndroidMkEntriesForTest(t, config, "", m.Module())[0].EntryMap["LOCAL_MODULE_PATH"] + expectedPath := []string{"/tmp/target/product/test_device/product/overlay"} + if !reflect.DeepEqual(path, expectedPath) { + t.Errorf("Unexpected LOCAL_MODULE_PATH value: %v, expected: %v", path, expectedPath) + } + + // A themed module has a different device location + m = ctx.ModuleForTests("foo_themed", "android_common") + path = android.AndroidMkEntriesForTest(t, config, "", m.Module())[0].EntryMap["LOCAL_MODULE_PATH"] + expectedPath = []string{"/tmp/target/product/test_device/product/overlay/faza"} + if !reflect.DeepEqual(path, expectedPath) { + t.Errorf("Unexpected LOCAL_MODULE_PATH value: %v, expected: %v", path, expectedPath) + } +} diff --git a/java/sdk.go b/java/sdk.go index 66eb284ba..2aa797a02 100644 --- a/java/sdk.go +++ b/java/sdk.go @@ -15,14 +15,15 @@ package java import ( - "android/soong/android" - "android/soong/java/config" "fmt" "path/filepath" "sort" "strconv" "strings" + "android/soong/android" + "android/soong/java/config" + "github.com/google/blueprint/pathtools" )