Loading android/util.go +13 −2 Original line number Diff line number Diff line Loading @@ -121,8 +121,19 @@ func InList(s string, list []string) bool { return IndexList(s, list) != -1 } func PrefixInList(s string, list []string) bool { for _, prefix := range list { // Returns true if the given string s is prefixed with any string in the given prefix list. func PrefixInList(s string, prefixList []string) bool { for _, prefix := range prefixList { if strings.HasPrefix(s, prefix) { return true } } return false } // Returns true if any string in the given list has the given prefix. func PrefixedStringInList(list []string, prefix string) bool { for _, s := range list { if strings.HasPrefix(s, prefix) { return true } Loading java/aapt2.go +21 −2 Original line number Diff line number Diff line Loading @@ -147,10 +147,16 @@ var fileListToFileRule = pctx.AndroidStaticRule("fileListToFile", RspfileContent: "$in", }) var mergeAssetsRule = pctx.AndroidStaticRule("mergeAssets", blueprint.RuleParams{ Command: `${config.MergeZipsCmd} ${out} ${in}`, CommandDeps: []string{"${config.MergeZipsCmd}"}, }) func aapt2Link(ctx android.ModuleContext, packageRes, genJar, proguardOptions, rTxt, extraPackages android.WritablePath, flags []string, deps android.Paths, compiledRes, compiledOverlay android.Paths, splitPackages android.WritablePaths) { compiledRes, compiledOverlay, assetPackages android.Paths, splitPackages android.WritablePaths) { genDir := android.PathForModuleGen(ctx, "aapt2", "R") Loading Loading @@ -186,12 +192,25 @@ func aapt2Link(ctx android.ModuleContext, } implicitOutputs := append(splitPackages, proguardOptions, genJar, rTxt, extraPackages) linkOutput := packageRes // AAPT2 ignores assets in overlays. Merge them after linking. if len(assetPackages) > 0 { linkOutput = android.PathForModuleOut(ctx, "aapt2", "package-res.apk") inputZips := append(android.Paths{linkOutput}, assetPackages...) ctx.Build(pctx, android.BuildParams{ Rule: mergeAssetsRule, Inputs: inputZips, Output: packageRes, Description: "merge assets from dependencies", }) } ctx.Build(pctx, android.BuildParams{ Rule: aapt2LinkRule, Description: "aapt2 link", Implicits: deps, Output: packageRes, Output: linkOutput, ImplicitOutputs: implicitOutputs, Args: map[string]string{ "flags": strings.Join(flags, " "), Loading java/aar.go +39 −6 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ type AndroidLibraryDependency interface { ExportedRRODirs() []rroDir ExportedStaticPackages() android.Paths ExportedManifests() android.Paths ExportedAssets() android.OptionalPath } func init() { Loading Loading @@ -93,6 +94,7 @@ type aapt struct { extraAaptPackagesFile android.Path mergedManifestFile android.Path noticeFile android.OptionalPath assetPackage android.OptionalPath isLibrary bool useEmbeddedNativeLibs bool useEmbeddedDex bool Loading Loading @@ -124,6 +126,10 @@ func (a *aapt) ExportedManifests() android.Paths { return a.transitiveManifestPaths } func (a *aapt) ExportedAssets() android.OptionalPath { return a.assetPackage } func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkContext sdkContext, manifestPath android.Path) (compileFlags, linkFlags []string, linkDeps android.Paths, resDirs, overlayDirs []globbedResourceDir, rroDirs []rroDir, resZips android.Paths) { Loading Loading @@ -219,9 +225,15 @@ func (a *aapt) deps(ctx android.BottomUpMutatorContext, sdkDep sdkDep) { } } var extractAssetsRule = pctx.AndroidStaticRule("extractAssets", blueprint.RuleParams{ Command: `${config.Zip2ZipCmd} -i ${in} -o ${out} "assets/**/*"`, CommandDeps: []string{"${config.Zip2ZipCmd}"}, }) func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext sdkContext, extraLinkFlags ...string) { transitiveStaticLibs, transitiveStaticLibManifests, staticRRODirs, libDeps, libFlags, sdkLibraries := transitiveStaticLibs, transitiveStaticLibManifests, staticRRODirs, assetPackages, libDeps, libFlags, sdkLibraries := aaptLibs(ctx, sdkContext) // App manifest file Loading Loading @@ -321,7 +333,20 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext sdkContext, ex } aapt2Link(ctx, packageRes, srcJar, proguardOptionsFile, rTxt, extraPackages, linkFlags, linkDeps, compiledRes, compiledOverlay, splitPackages) linkFlags, linkDeps, compiledRes, compiledOverlay, assetPackages, splitPackages) // Extract assets from the resource package output so that they can be used later in aapt2link // for modules that depend on this one. if android.PrefixedStringInList(linkFlags, "-A ") || len(assetPackages) > 0 { assets := android.PathForModuleOut(ctx, "assets.zip") ctx.Build(pctx, android.BuildParams{ Rule: extractAssetsRule, Input: packageRes, Output: assets, Description: "extract assets from built resource file", }) a.assetPackage = android.OptionalPathForPath(assets) } a.aaptSrcJar = srcJar a.exportPackage = packageRes Loading @@ -335,7 +360,7 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext sdkContext, ex // aaptLibs collects libraries from dependencies and sdk_version and converts them into paths func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext) (transitiveStaticLibs, transitiveStaticLibManifests android.Paths, staticRRODirs []rroDir, deps android.Paths, flags []string, sdkLibraries []string) { staticRRODirs []rroDir, assets, deps android.Paths, flags []string, sdkLibraries []string) { var sharedLibs android.Paths Loading Loading @@ -373,6 +398,9 @@ func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext) (transitiveStati transitiveStaticLibs = append(transitiveStaticLibs, exportPackage) transitiveStaticLibManifests = append(transitiveStaticLibManifests, aarDep.ExportedManifests()...) sdkLibraries = append(sdkLibraries, aarDep.ExportedSdkLibs()...) if aarDep.ExportedAssets().Valid() { assets = append(assets, aarDep.ExportedAssets().Path()) } outer: for _, d := range aarDep.ExportedRRODirs() { Loading Loading @@ -402,7 +430,7 @@ func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext) (transitiveStati transitiveStaticLibManifests = android.FirstUniquePaths(transitiveStaticLibManifests) sdkLibraries = android.FirstUniqueStrings(sdkLibraries) return transitiveStaticLibs, transitiveStaticLibManifests, staticRRODirs, deps, flags, sdkLibraries return transitiveStaticLibs, transitiveStaticLibManifests, staticRRODirs, assets, deps, flags, sdkLibraries } type AndroidLibrary struct { Loading Loading @@ -572,6 +600,11 @@ func (a *AARImport) ExportedManifests() android.Paths { return android.Paths{a.manifest} } // TODO(jungjw): Decide whether we want to implement this. func (a *AARImport) ExportedAssets() android.OptionalPath { return android.OptionalPath{} } func (a *AARImport) Prebuilt() *android.Prebuilt { return &a.prebuilt } Loading Loading @@ -660,7 +693,7 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { linkFlags = append(linkFlags, "--manifest "+a.manifest.String()) linkDeps = append(linkDeps, a.manifest) transitiveStaticLibs, staticLibManifests, staticRRODirs, libDeps, libFlags, sdkLibraries := transitiveStaticLibs, staticLibManifests, staticRRODirs, transitiveAssets, libDeps, libFlags, sdkLibraries := aaptLibs(ctx, sdkContext(a)) _ = staticLibManifests Loading @@ -673,7 +706,7 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { overlayRes := append(android.Paths{flata}, transitiveStaticLibs...) aapt2Link(ctx, a.exportPackage, srcJar, proguardOptionsFile, rTxt, a.extraAaptPackagesFile, linkFlags, linkDeps, nil, overlayRes, nil) linkFlags, linkDeps, nil, overlayRes, transitiveAssets, nil) } var _ Dependency = (*AARImport)(nil) Loading java/app_test.go +101 −0 Original line number Diff line number Diff line Loading @@ -323,6 +323,107 @@ func TestResourceDirs(t *testing.T) { } } func TestLibraryAssets(t *testing.T) { bp := ` android_app { name: "foo", sdk_version: "current", static_libs: ["lib1", "lib2", "lib3"], } android_library { name: "lib1", sdk_version: "current", asset_dirs: ["assets_a"], } android_library { name: "lib2", sdk_version: "current", } android_library { name: "lib3", sdk_version: "current", static_libs: ["lib4"], } android_library { name: "lib4", sdk_version: "current", asset_dirs: ["assets_b"], } ` testCases := []struct { name string assetFlag string assetPackages []string }{ { name: "foo", // lib1 has its own asset. lib3 doesn't have any, but provides lib4's transitively. assetPackages: []string{ buildDir + "/.intermediates/foo/android_common/aapt2/package-res.apk", buildDir + "/.intermediates/lib1/android_common/assets.zip", buildDir + "/.intermediates/lib3/android_common/assets.zip", }, }, { name: "lib1", assetFlag: "-A assets_a", }, { name: "lib2", }, { name: "lib3", assetPackages: []string{ buildDir + "/.intermediates/lib3/android_common/aapt2/package-res.apk", buildDir + "/.intermediates/lib4/android_common/assets.zip", }, }, { name: "lib4", assetFlag: "-A assets_b", }, } ctx := testApp(t, bp) for _, test := range testCases { t.Run(test.name, func(t *testing.T) { m := ctx.ModuleForTests(test.name, "android_common") // Check asset flag in aapt2 link flags var aapt2link android.TestingBuildParams if len(test.assetPackages) > 0 { aapt2link = m.Output("aapt2/package-res.apk") } else { aapt2link = m.Output("package-res.apk") } aapt2Flags := aapt2link.Args["flags"] if test.assetFlag != "" { if !strings.Contains(aapt2Flags, test.assetFlag) { t.Errorf("Can't find asset flag %q in aapt2 link flags %q", test.assetFlag, aapt2Flags) } } else { if strings.Contains(aapt2Flags, " -A ") { t.Errorf("aapt2 link flags %q contain unexpected asset flag", aapt2Flags) } } // Check asset merge rule. if len(test.assetPackages) > 0 { mergeAssets := m.Output("package-res.apk") if !reflect.DeepEqual(test.assetPackages, mergeAssets.Inputs.Strings()) { t.Errorf("Unexpected mergeAssets inputs: %v, expected: %v", mergeAssets.Inputs.Strings(), test.assetPackages) } } }) } } func TestAndroidResources(t *testing.T) { testCases := []struct { name string Loading java/testing.go +2 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,8 @@ func TestConfig(buildDir string, env map[string]string, bp string, fs map[string "api/test-current.txt": nil, "api/test-removed.txt": nil, "framework/aidl/a.aidl": nil, "assets_a/a": nil, "assets_b/b": nil, "prebuilts/ndk/current/sources/cxx-stl/llvm-libc++/libs/arm64-v8a/libc++_shared.so": nil, Loading Loading
android/util.go +13 −2 Original line number Diff line number Diff line Loading @@ -121,8 +121,19 @@ func InList(s string, list []string) bool { return IndexList(s, list) != -1 } func PrefixInList(s string, list []string) bool { for _, prefix := range list { // Returns true if the given string s is prefixed with any string in the given prefix list. func PrefixInList(s string, prefixList []string) bool { for _, prefix := range prefixList { if strings.HasPrefix(s, prefix) { return true } } return false } // Returns true if any string in the given list has the given prefix. func PrefixedStringInList(list []string, prefix string) bool { for _, s := range list { if strings.HasPrefix(s, prefix) { return true } Loading
java/aapt2.go +21 −2 Original line number Diff line number Diff line Loading @@ -147,10 +147,16 @@ var fileListToFileRule = pctx.AndroidStaticRule("fileListToFile", RspfileContent: "$in", }) var mergeAssetsRule = pctx.AndroidStaticRule("mergeAssets", blueprint.RuleParams{ Command: `${config.MergeZipsCmd} ${out} ${in}`, CommandDeps: []string{"${config.MergeZipsCmd}"}, }) func aapt2Link(ctx android.ModuleContext, packageRes, genJar, proguardOptions, rTxt, extraPackages android.WritablePath, flags []string, deps android.Paths, compiledRes, compiledOverlay android.Paths, splitPackages android.WritablePaths) { compiledRes, compiledOverlay, assetPackages android.Paths, splitPackages android.WritablePaths) { genDir := android.PathForModuleGen(ctx, "aapt2", "R") Loading Loading @@ -186,12 +192,25 @@ func aapt2Link(ctx android.ModuleContext, } implicitOutputs := append(splitPackages, proguardOptions, genJar, rTxt, extraPackages) linkOutput := packageRes // AAPT2 ignores assets in overlays. Merge them after linking. if len(assetPackages) > 0 { linkOutput = android.PathForModuleOut(ctx, "aapt2", "package-res.apk") inputZips := append(android.Paths{linkOutput}, assetPackages...) ctx.Build(pctx, android.BuildParams{ Rule: mergeAssetsRule, Inputs: inputZips, Output: packageRes, Description: "merge assets from dependencies", }) } ctx.Build(pctx, android.BuildParams{ Rule: aapt2LinkRule, Description: "aapt2 link", Implicits: deps, Output: packageRes, Output: linkOutput, ImplicitOutputs: implicitOutputs, Args: map[string]string{ "flags": strings.Join(flags, " "), Loading
java/aar.go +39 −6 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ type AndroidLibraryDependency interface { ExportedRRODirs() []rroDir ExportedStaticPackages() android.Paths ExportedManifests() android.Paths ExportedAssets() android.OptionalPath } func init() { Loading Loading @@ -93,6 +94,7 @@ type aapt struct { extraAaptPackagesFile android.Path mergedManifestFile android.Path noticeFile android.OptionalPath assetPackage android.OptionalPath isLibrary bool useEmbeddedNativeLibs bool useEmbeddedDex bool Loading Loading @@ -124,6 +126,10 @@ func (a *aapt) ExportedManifests() android.Paths { return a.transitiveManifestPaths } func (a *aapt) ExportedAssets() android.OptionalPath { return a.assetPackage } func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkContext sdkContext, manifestPath android.Path) (compileFlags, linkFlags []string, linkDeps android.Paths, resDirs, overlayDirs []globbedResourceDir, rroDirs []rroDir, resZips android.Paths) { Loading Loading @@ -219,9 +225,15 @@ func (a *aapt) deps(ctx android.BottomUpMutatorContext, sdkDep sdkDep) { } } var extractAssetsRule = pctx.AndroidStaticRule("extractAssets", blueprint.RuleParams{ Command: `${config.Zip2ZipCmd} -i ${in} -o ${out} "assets/**/*"`, CommandDeps: []string{"${config.Zip2ZipCmd}"}, }) func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext sdkContext, extraLinkFlags ...string) { transitiveStaticLibs, transitiveStaticLibManifests, staticRRODirs, libDeps, libFlags, sdkLibraries := transitiveStaticLibs, transitiveStaticLibManifests, staticRRODirs, assetPackages, libDeps, libFlags, sdkLibraries := aaptLibs(ctx, sdkContext) // App manifest file Loading Loading @@ -321,7 +333,20 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext sdkContext, ex } aapt2Link(ctx, packageRes, srcJar, proguardOptionsFile, rTxt, extraPackages, linkFlags, linkDeps, compiledRes, compiledOverlay, splitPackages) linkFlags, linkDeps, compiledRes, compiledOverlay, assetPackages, splitPackages) // Extract assets from the resource package output so that they can be used later in aapt2link // for modules that depend on this one. if android.PrefixedStringInList(linkFlags, "-A ") || len(assetPackages) > 0 { assets := android.PathForModuleOut(ctx, "assets.zip") ctx.Build(pctx, android.BuildParams{ Rule: extractAssetsRule, Input: packageRes, Output: assets, Description: "extract assets from built resource file", }) a.assetPackage = android.OptionalPathForPath(assets) } a.aaptSrcJar = srcJar a.exportPackage = packageRes Loading @@ -335,7 +360,7 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext sdkContext, ex // aaptLibs collects libraries from dependencies and sdk_version and converts them into paths func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext) (transitiveStaticLibs, transitiveStaticLibManifests android.Paths, staticRRODirs []rroDir, deps android.Paths, flags []string, sdkLibraries []string) { staticRRODirs []rroDir, assets, deps android.Paths, flags []string, sdkLibraries []string) { var sharedLibs android.Paths Loading Loading @@ -373,6 +398,9 @@ func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext) (transitiveStati transitiveStaticLibs = append(transitiveStaticLibs, exportPackage) transitiveStaticLibManifests = append(transitiveStaticLibManifests, aarDep.ExportedManifests()...) sdkLibraries = append(sdkLibraries, aarDep.ExportedSdkLibs()...) if aarDep.ExportedAssets().Valid() { assets = append(assets, aarDep.ExportedAssets().Path()) } outer: for _, d := range aarDep.ExportedRRODirs() { Loading Loading @@ -402,7 +430,7 @@ func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext) (transitiveStati transitiveStaticLibManifests = android.FirstUniquePaths(transitiveStaticLibManifests) sdkLibraries = android.FirstUniqueStrings(sdkLibraries) return transitiveStaticLibs, transitiveStaticLibManifests, staticRRODirs, deps, flags, sdkLibraries return transitiveStaticLibs, transitiveStaticLibManifests, staticRRODirs, assets, deps, flags, sdkLibraries } type AndroidLibrary struct { Loading Loading @@ -572,6 +600,11 @@ func (a *AARImport) ExportedManifests() android.Paths { return android.Paths{a.manifest} } // TODO(jungjw): Decide whether we want to implement this. func (a *AARImport) ExportedAssets() android.OptionalPath { return android.OptionalPath{} } func (a *AARImport) Prebuilt() *android.Prebuilt { return &a.prebuilt } Loading Loading @@ -660,7 +693,7 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { linkFlags = append(linkFlags, "--manifest "+a.manifest.String()) linkDeps = append(linkDeps, a.manifest) transitiveStaticLibs, staticLibManifests, staticRRODirs, libDeps, libFlags, sdkLibraries := transitiveStaticLibs, staticLibManifests, staticRRODirs, transitiveAssets, libDeps, libFlags, sdkLibraries := aaptLibs(ctx, sdkContext(a)) _ = staticLibManifests Loading @@ -673,7 +706,7 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { overlayRes := append(android.Paths{flata}, transitiveStaticLibs...) aapt2Link(ctx, a.exportPackage, srcJar, proguardOptionsFile, rTxt, a.extraAaptPackagesFile, linkFlags, linkDeps, nil, overlayRes, nil) linkFlags, linkDeps, nil, overlayRes, transitiveAssets, nil) } var _ Dependency = (*AARImport)(nil) Loading
java/app_test.go +101 −0 Original line number Diff line number Diff line Loading @@ -323,6 +323,107 @@ func TestResourceDirs(t *testing.T) { } } func TestLibraryAssets(t *testing.T) { bp := ` android_app { name: "foo", sdk_version: "current", static_libs: ["lib1", "lib2", "lib3"], } android_library { name: "lib1", sdk_version: "current", asset_dirs: ["assets_a"], } android_library { name: "lib2", sdk_version: "current", } android_library { name: "lib3", sdk_version: "current", static_libs: ["lib4"], } android_library { name: "lib4", sdk_version: "current", asset_dirs: ["assets_b"], } ` testCases := []struct { name string assetFlag string assetPackages []string }{ { name: "foo", // lib1 has its own asset. lib3 doesn't have any, but provides lib4's transitively. assetPackages: []string{ buildDir + "/.intermediates/foo/android_common/aapt2/package-res.apk", buildDir + "/.intermediates/lib1/android_common/assets.zip", buildDir + "/.intermediates/lib3/android_common/assets.zip", }, }, { name: "lib1", assetFlag: "-A assets_a", }, { name: "lib2", }, { name: "lib3", assetPackages: []string{ buildDir + "/.intermediates/lib3/android_common/aapt2/package-res.apk", buildDir + "/.intermediates/lib4/android_common/assets.zip", }, }, { name: "lib4", assetFlag: "-A assets_b", }, } ctx := testApp(t, bp) for _, test := range testCases { t.Run(test.name, func(t *testing.T) { m := ctx.ModuleForTests(test.name, "android_common") // Check asset flag in aapt2 link flags var aapt2link android.TestingBuildParams if len(test.assetPackages) > 0 { aapt2link = m.Output("aapt2/package-res.apk") } else { aapt2link = m.Output("package-res.apk") } aapt2Flags := aapt2link.Args["flags"] if test.assetFlag != "" { if !strings.Contains(aapt2Flags, test.assetFlag) { t.Errorf("Can't find asset flag %q in aapt2 link flags %q", test.assetFlag, aapt2Flags) } } else { if strings.Contains(aapt2Flags, " -A ") { t.Errorf("aapt2 link flags %q contain unexpected asset flag", aapt2Flags) } } // Check asset merge rule. if len(test.assetPackages) > 0 { mergeAssets := m.Output("package-res.apk") if !reflect.DeepEqual(test.assetPackages, mergeAssets.Inputs.Strings()) { t.Errorf("Unexpected mergeAssets inputs: %v, expected: %v", mergeAssets.Inputs.Strings(), test.assetPackages) } } }) } } func TestAndroidResources(t *testing.T) { testCases := []struct { name string Loading
java/testing.go +2 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,8 @@ func TestConfig(buildDir string, env map[string]string, bp string, fs map[string "api/test-current.txt": nil, "api/test-removed.txt": nil, "framework/aidl/a.aidl": nil, "assets_a/a": nil, "assets_b/b": nil, "prebuilts/ndk/current/sources/cxx-stl/llvm-libc++/libs/arm64-v8a/libc++_shared.so": nil, Loading