|  | // Copyright 2021 Google Inc. All rights reserved. | 
|  | // | 
|  | // Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | // you may not use this file except in compliance with the License. | 
|  | // You may obtain a copy of the License at | 
|  | // | 
|  | //     http://www.apache.org/licenses/LICENSE-2.0 | 
|  | // | 
|  | // Unless required by applicable law or agreed to in writing, software | 
|  | // distributed under the License is distributed on an "AS IS" BASIS, | 
|  | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | // See the License for the specific language governing permissions and | 
|  | // limitations under the License. | 
|  |  | 
|  | package bp2build | 
|  |  | 
|  | import ( | 
|  | "android/soong/android" | 
|  | "android/soong/cc" | 
|  | "android/soong/java" | 
|  |  | 
|  | "testing" | 
|  | ) | 
|  |  | 
|  | func runAndroidAppTestCase(t *testing.T, tc Bp2buildTestCase) { | 
|  | t.Helper() | 
|  | RunBp2BuildTestCase(t, registerAndroidAppModuleTypes, tc) | 
|  | } | 
|  |  | 
|  | func registerAndroidAppModuleTypes(ctx android.RegistrationContext) { | 
|  | ctx.RegisterModuleType("filegroup", android.FileGroupFactory) | 
|  | ctx.RegisterModuleType("java_library", java.LibraryFactory) | 
|  | ctx.RegisterModuleType("cc_library_shared", cc.LibrarySharedFactory) | 
|  | } | 
|  |  | 
|  | func TestMinimalAndroidApp(t *testing.T) { | 
|  | runAndroidAppTestCase(t, Bp2buildTestCase{ | 
|  | Description:                "Android app - simple example", | 
|  | ModuleTypeUnderTest:        "android_app", | 
|  | ModuleTypeUnderTestFactory: java.AndroidAppFactory, | 
|  | Filesystem: map[string]string{ | 
|  | "app.java":            "", | 
|  | "res/res.png":         "", | 
|  | "AndroidManifest.xml": "", | 
|  | "assets/asset.png":    "", | 
|  | }, | 
|  | Blueprint: ` | 
|  | android_app { | 
|  | name: "TestApp", | 
|  | srcs: ["app.java"], | 
|  | sdk_version: "current", | 
|  | optimize: { | 
|  | shrink: true, | 
|  | optimize: true, | 
|  | obfuscate: true, | 
|  | }, | 
|  | } | 
|  | `, | 
|  | ExpectedBazelTargets: []string{ | 
|  | MakeBazelTarget("android_binary", "TestApp", AttrNameToString{ | 
|  | "srcs":           `["app.java"]`, | 
|  | "manifest":       `"AndroidManifest.xml"`, | 
|  | "resource_files": `["res/res.png"]`, | 
|  | "sdk_version":    `"current"`, | 
|  | "assets":         `["assets/asset.png"]`, | 
|  | "assets_dir":     `"assets"`, | 
|  | }), | 
|  | }}) | 
|  | } | 
|  |  | 
|  | func TestAndroidAppAllSupportedFields(t *testing.T) { | 
|  | runAndroidAppTestCase(t, Bp2buildTestCase{ | 
|  | Description:                "Android app - all supported fields", | 
|  | ModuleTypeUnderTest:        "android_app", | 
|  | ModuleTypeUnderTestFactory: java.AndroidAppFactory, | 
|  | Filesystem: map[string]string{ | 
|  | "app.java":                     "", | 
|  | "resa/res.png":                 "", | 
|  | "resb/res.png":                 "", | 
|  | "manifest/AndroidManifest.xml": "", | 
|  | "assets_/asset.png":            "", | 
|  | }, | 
|  | StubbedBuildDefinitions: []string{"static_lib_dep", "jni_lib"}, | 
|  | Blueprint: simpleModule("android_app", "static_lib_dep") + | 
|  | simpleModule("cc_library_shared", "jni_lib") + ` | 
|  | android_app { | 
|  | name: "TestApp", | 
|  | srcs: ["app.java"], | 
|  | sdk_version: "current", | 
|  | package_name: "com.google", | 
|  | resource_dirs: ["resa", "resb"], | 
|  | manifest: "manifest/AndroidManifest.xml", | 
|  | static_libs: ["static_lib_dep"], | 
|  | java_version: "7", | 
|  | certificate: "foocert", | 
|  | required: ["static_lib_dep"], | 
|  | asset_dirs: ["assets_"], | 
|  | optimize: { | 
|  | enabled: true, | 
|  | optimize: false, | 
|  | proguard_flags_files: ["proguard.flags"], | 
|  | shrink: false, | 
|  | obfuscate: false, | 
|  | ignore_warnings: true, | 
|  | }, | 
|  | jni_libs: ["jni_lib"], | 
|  | } | 
|  | `, | 
|  | ExpectedBazelTargets: []string{ | 
|  | MakeBazelTarget("android_binary", "TestApp", AttrNameToString{ | 
|  | "srcs":     `["app.java"]`, | 
|  | "manifest": `"manifest/AndroidManifest.xml"`, | 
|  | "resource_files": `[ | 
|  | "resa/res.png", | 
|  | "resb/res.png", | 
|  | ]`, | 
|  | "assets":         `["assets_/asset.png"]`, | 
|  | "assets_dir":     `"assets_"`, | 
|  | "custom_package": `"com.google"`, | 
|  | "deps": `[ | 
|  | ":static_lib_dep", | 
|  | ":jni_lib", | 
|  | ]`, | 
|  | "java_version":     `"7"`, | 
|  | "sdk_version":      `"current"`, | 
|  | "certificate_name": `"foocert"`, | 
|  | "proguard_specs": `[ | 
|  | "proguard.flags", | 
|  | ":TestApp_proguard_flags", | 
|  | ]`, | 
|  | }), | 
|  | MakeBazelTarget("genrule", "TestApp_proguard_flags", AttrNameToString{ | 
|  | "outs": `["TestApp_proguard.flags"]`, | 
|  | "cmd":  `"echo -ignorewarning -dontshrink -dontoptimize -dontobfuscate > $(OUTS)"`, | 
|  | }), | 
|  | }}) | 
|  | } | 
|  |  | 
|  | func TestAndroidAppArchVariantSrcs(t *testing.T) { | 
|  | runAndroidAppTestCase(t, Bp2buildTestCase{ | 
|  | Description:                "Android app - arch variant srcs", | 
|  | ModuleTypeUnderTest:        "android_app", | 
|  | ModuleTypeUnderTestFactory: java.AndroidAppFactory, | 
|  | Filesystem: map[string]string{ | 
|  | "arm.java":            "", | 
|  | "x86.java":            "", | 
|  | "res/res.png":         "", | 
|  | "AndroidManifest.xml": "", | 
|  | }, | 
|  | Blueprint: ` | 
|  | android_app { | 
|  | name: "TestApp", | 
|  | sdk_version: "current", | 
|  | arch: { | 
|  | arm: { | 
|  | srcs: ["arm.java"], | 
|  | }, | 
|  | x86: { | 
|  | srcs: ["x86.java"], | 
|  | } | 
|  | }, | 
|  | optimize: { | 
|  | enabled: false, | 
|  | }, | 
|  | } | 
|  | `, | 
|  | ExpectedBazelTargets: []string{ | 
|  | MakeBazelTarget("android_binary", "TestApp", AttrNameToString{ | 
|  | "srcs": `select({ | 
|  | "//build/bazel_common_rules/platforms/arch:arm": ["arm.java"], | 
|  | "//build/bazel_common_rules/platforms/arch:x86": ["x86.java"], | 
|  | "//conditions:default": [], | 
|  | })`, | 
|  | "manifest":       `"AndroidManifest.xml"`, | 
|  | "resource_files": `["res/res.png"]`, | 
|  | "sdk_version":    `"current"`, | 
|  | "optimize":       `False`, | 
|  | }), | 
|  | }}) | 
|  | } | 
|  |  | 
|  | func TestAndroidAppCertIsModule(t *testing.T) { | 
|  | runAndroidAppTestCase(t, Bp2buildTestCase{ | 
|  | Description:                "Android app - cert is module", | 
|  | ModuleTypeUnderTest:        "android_app", | 
|  | ModuleTypeUnderTestFactory: java.AndroidAppFactory, | 
|  | Filesystem:                 map[string]string{}, | 
|  | StubbedBuildDefinitions:    []string{"foocert"}, | 
|  | Blueprint: simpleModule("filegroup", "foocert") + ` | 
|  | android_app { | 
|  | name: "TestApp", | 
|  | certificate: ":foocert", | 
|  | sdk_version: "current", | 
|  | optimize: { | 
|  | enabled: false, | 
|  | }, | 
|  | } | 
|  | `, | 
|  | ExpectedBazelTargets: []string{ | 
|  | MakeBazelTarget("android_binary", "TestApp", AttrNameToString{ | 
|  | "certificate":    `":foocert"`, | 
|  | "manifest":       `"AndroidManifest.xml"`, | 
|  | "resource_files": `[]`, | 
|  | "sdk_version":    `"current"`, // use as default | 
|  | "optimize":       `False`, | 
|  | }), | 
|  | }}) | 
|  | } | 
|  |  | 
|  | func TestAndroidAppCertIsSrcFile(t *testing.T) { | 
|  | runAndroidAppTestCase(t, Bp2buildTestCase{ | 
|  | Description:                "Android app - cert is src file", | 
|  | ModuleTypeUnderTest:        "android_app", | 
|  | ModuleTypeUnderTestFactory: java.AndroidAppFactory, | 
|  | Filesystem: map[string]string{ | 
|  | "foocert": "", | 
|  | }, | 
|  | Blueprint: ` | 
|  | android_app { | 
|  | name: "TestApp", | 
|  | certificate: "foocert", | 
|  | sdk_version: "current", | 
|  | optimize: { | 
|  | enabled: false, | 
|  | }, | 
|  | } | 
|  | `, | 
|  | ExpectedBazelTargets: []string{ | 
|  | MakeBazelTarget("android_binary", "TestApp", AttrNameToString{ | 
|  | "certificate":    `"foocert"`, | 
|  | "manifest":       `"AndroidManifest.xml"`, | 
|  | "resource_files": `[]`, | 
|  | "sdk_version":    `"current"`, // use as default | 
|  | "optimize":       `False`, | 
|  | }), | 
|  | }}) | 
|  | } | 
|  |  | 
|  | func TestAndroidAppCertIsNotSrcOrModule(t *testing.T) { | 
|  | runAndroidAppTestCase(t, Bp2buildTestCase{ | 
|  | Description:                "Android app - cert is not src or module", | 
|  | ModuleTypeUnderTest:        "android_app", | 
|  | ModuleTypeUnderTestFactory: java.AndroidAppFactory, | 
|  | Filesystem:                 map[string]string{ | 
|  | // deliberate empty | 
|  | }, | 
|  | Blueprint: ` | 
|  | android_app { | 
|  | name: "TestApp", | 
|  | certificate: "foocert", | 
|  | sdk_version: "current", | 
|  | optimize: { | 
|  | enabled: false, | 
|  | }, | 
|  | } | 
|  | `, | 
|  | ExpectedBazelTargets: []string{ | 
|  | MakeBazelTarget("android_binary", "TestApp", AttrNameToString{ | 
|  | "certificate_name": `"foocert"`, | 
|  | "manifest":         `"AndroidManifest.xml"`, | 
|  | "resource_files":   `[]`, | 
|  | "sdk_version":      `"current"`, // use as default | 
|  | "optimize":         `False`, | 
|  | }), | 
|  | }}) | 
|  | } | 
|  |  | 
|  | func TestAndroidAppLibs(t *testing.T) { | 
|  | runAndroidAppTestCase(t, Bp2buildTestCase{ | 
|  | Description:                "Android app with libs", | 
|  | ModuleTypeUnderTest:        "android_app", | 
|  | ModuleTypeUnderTestFactory: java.AndroidAppFactory, | 
|  | Filesystem:                 map[string]string{}, | 
|  | StubbedBuildDefinitions:    []string{"barLib"}, | 
|  | Blueprint: simpleModule("java_library", "barLib") + ` | 
|  | android_app { | 
|  | name: "foo", | 
|  | libs: ["barLib"], | 
|  | sdk_version: "current", | 
|  | optimize: { | 
|  | enabled: false, | 
|  | }, | 
|  | } | 
|  | `, | 
|  | ExpectedBazelTargets: []string{ | 
|  | MakeBazelTarget("android_binary", "foo", AttrNameToString{ | 
|  | "manifest":       `"AndroidManifest.xml"`, | 
|  | "resource_files": `[]`, | 
|  | "deps":           `[":barLib-neverlink"]`, | 
|  | "sdk_version":    `"current"`, // use as default | 
|  | "optimize":       `False`, | 
|  | }), | 
|  | }}) | 
|  | } | 
|  |  | 
|  | func TestAndroidAppKotlinSrcs(t *testing.T) { | 
|  | runAndroidAppTestCase(t, Bp2buildTestCase{ | 
|  | Description:                "Android app with kotlin sources and common_srcs", | 
|  | ModuleTypeUnderTest:        "android_app", | 
|  | ModuleTypeUnderTestFactory: java.AndroidAppFactory, | 
|  | Filesystem: map[string]string{ | 
|  | "res/res.png": "", | 
|  | }, | 
|  | StubbedBuildDefinitions: []string{"foocert", "barLib"}, | 
|  | Blueprint: simpleModule("filegroup", "foocert") + | 
|  | simpleModule("java_library", "barLib") + ` | 
|  | android_app { | 
|  | name: "foo", | 
|  | srcs: ["a.java", "b.kt"], | 
|  | certificate: ":foocert", | 
|  | manifest: "fooManifest.xml", | 
|  | libs: ["barLib"], | 
|  | sdk_version: "current", | 
|  | optimize: { | 
|  | enabled: false, | 
|  | }, | 
|  | } | 
|  | `, | 
|  | ExpectedBazelTargets: []string{ | 
|  | MakeBazelTarget("android_library", "foo_kt", AttrNameToString{ | 
|  | "srcs": `[ | 
|  | "a.java", | 
|  | "b.kt", | 
|  | ]`, | 
|  | "manifest":       `"fooManifest.xml"`, | 
|  | "resource_files": `["res/res.png"]`, | 
|  | "deps":           `[":barLib-neverlink"]`, | 
|  | "sdk_version":    `"current"`, // use as default | 
|  | }), | 
|  | MakeBazelTarget("android_binary", "foo", AttrNameToString{ | 
|  | "deps":        `[":foo_kt"]`, | 
|  | "certificate": `":foocert"`, | 
|  | "manifest":    `"fooManifest.xml"`, | 
|  | "sdk_version": `"current"`, // use as default | 
|  | "optimize":    `False`, | 
|  | }), | 
|  | }}) | 
|  | } | 
|  |  | 
|  | func TestAndroidAppCommonSrcs(t *testing.T) { | 
|  | runAndroidAppTestCase(t, Bp2buildTestCase{ | 
|  | Description:                "Android app with common_srcs", | 
|  | ModuleTypeUnderTest:        "android_app", | 
|  | ModuleTypeUnderTestFactory: java.AndroidAppFactory, | 
|  | Filesystem: map[string]string{ | 
|  | "res/res.png": "", | 
|  | }, | 
|  | StubbedBuildDefinitions: []string{"barLib"}, | 
|  | Blueprint: ` | 
|  | android_app { | 
|  | name: "foo", | 
|  | srcs: ["a.java"], | 
|  | common_srcs: ["b.kt"], | 
|  | manifest: "fooManifest.xml", | 
|  | libs:        ["barLib"], | 
|  | sdk_version: "current", | 
|  | optimize: { | 
|  | enabled: false, | 
|  | }, | 
|  | } | 
|  | java_library{ | 
|  | name:   "barLib", | 
|  | } | 
|  | `, | 
|  | ExpectedBazelTargets: []string{ | 
|  | MakeBazelTarget("android_library", "foo_kt", AttrNameToString{ | 
|  | "srcs":           `["a.java"]`, | 
|  | "common_srcs":    `["b.kt"]`, | 
|  | "manifest":       `"fooManifest.xml"`, | 
|  | "resource_files": `["res/res.png"]`, | 
|  | "deps":           `[":barLib-neverlink"]`, | 
|  | "sdk_version":    `"current"`, // use as default | 
|  | }), | 
|  | MakeBazelTarget("android_binary", "foo", AttrNameToString{ | 
|  | "deps":        `[":foo_kt"]`, | 
|  | "manifest":    `"fooManifest.xml"`, | 
|  | "sdk_version": `"current"`, // use as default | 
|  | "optimize":    `False`, | 
|  | }), | 
|  | }}) | 
|  | } | 
|  |  | 
|  | func TestAndroidAppKotlinCflags(t *testing.T) { | 
|  | runAndroidAppTestCase(t, Bp2buildTestCase{ | 
|  | Description:                "Android app with kotlincflags", | 
|  | ModuleTypeUnderTest:        "android_app", | 
|  | ModuleTypeUnderTestFactory: java.AndroidAppFactory, | 
|  | Filesystem: map[string]string{ | 
|  | "res/res.png": "", | 
|  | }, | 
|  | Blueprint: ` | 
|  | android_app { | 
|  | name: "foo", | 
|  | srcs: ["a.java", "b.kt"], | 
|  | manifest: "fooManifest.xml", | 
|  | kotlincflags: ["-flag1", "-flag2"], | 
|  | sdk_version: "current", | 
|  | optimize: { | 
|  | enabled: false, | 
|  | }, | 
|  | } | 
|  | `, | 
|  | ExpectedBazelTargets: []string{ | 
|  | MakeBazelTarget("android_library", "foo_kt", AttrNameToString{ | 
|  | "srcs": `[ | 
|  | "a.java", | 
|  | "b.kt", | 
|  | ]`, | 
|  | "manifest":       `"fooManifest.xml"`, | 
|  | "resource_files": `["res/res.png"]`, | 
|  | "kotlincflags": `[ | 
|  | "-flag1", | 
|  | "-flag2", | 
|  | ]`, | 
|  | "sdk_version": `"current"`, // use as default | 
|  | }), | 
|  | MakeBazelTarget("android_binary", "foo", AttrNameToString{ | 
|  | "deps":        `[":foo_kt"]`, | 
|  | "manifest":    `"fooManifest.xml"`, | 
|  | "sdk_version": `"current"`, | 
|  | "optimize":    `False`, | 
|  | }), | 
|  | }}) | 
|  | } | 
|  |  | 
|  | func TestAndroidAppManifestSdkVersionsProvided(t *testing.T) { | 
|  | runAndroidAppTestCase(t, Bp2buildTestCase{ | 
|  | Description:                "Android app with value for min_sdk_version", | 
|  | ModuleTypeUnderTest:        "android_app", | 
|  | ModuleTypeUnderTestFactory: java.AndroidAppFactory, | 
|  | Filesystem:                 map[string]string{}, | 
|  | Blueprint: ` | 
|  | android_app { | 
|  | name: "foo", | 
|  | sdk_version: "current", | 
|  | min_sdk_version: "24", | 
|  | target_sdk_version: "29", | 
|  | optimize: { | 
|  | enabled: false, | 
|  | }, | 
|  | } | 
|  | `, | 
|  | ExpectedBazelTargets: []string{ | 
|  | MakeBazelTarget("android_binary", "foo", AttrNameToString{ | 
|  | "manifest":       `"AndroidManifest.xml"`, | 
|  | "resource_files": `[]`, | 
|  | "manifest_values": `{ | 
|  | "minSdkVersion": "24", | 
|  | "targetSdkVersion": "29", | 
|  | }`, | 
|  | "sdk_version": `"current"`, | 
|  | "optimize":    `False`, | 
|  | }), | 
|  | }}) | 
|  | } | 
|  |  | 
|  | func TestAndroidAppMinAndTargetSdkDefaultToSdkVersion(t *testing.T) { | 
|  | runAndroidAppTestCase(t, Bp2buildTestCase{ | 
|  | Description:                "Android app with value for sdk_version", | 
|  | ModuleTypeUnderTest:        "android_app", | 
|  | ModuleTypeUnderTestFactory: java.AndroidAppFactory, | 
|  | Filesystem:                 map[string]string{}, | 
|  | Blueprint: ` | 
|  | android_app { | 
|  | name: "foo", | 
|  | sdk_version: "30", | 
|  | optimize: { | 
|  | enabled: false, | 
|  | }, | 
|  | } | 
|  | `, | 
|  | ExpectedBazelTargets: []string{ | 
|  | MakeBazelTarget("android_binary", "foo", AttrNameToString{ | 
|  | "manifest":       `"AndroidManifest.xml"`, | 
|  | "resource_files": `[]`, | 
|  | "sdk_version":    `"30"`, | 
|  | "optimize":       `False`, | 
|  | }), | 
|  | }}) | 
|  | } | 
|  |  | 
|  | func TestFrameworkResConversion(t *testing.T) { | 
|  | runAndroidAppTestCase(t, Bp2buildTestCase{ | 
|  | Description:                "Framework Res custom conversion", | 
|  | ModuleTypeUnderTest:        "android_app", | 
|  | ModuleTypeUnderTestFactory: java.AndroidAppFactory, | 
|  | Filesystem: map[string]string{ | 
|  | "res/values/attrs.xml": "", | 
|  | "resource_zip.zip":     "", | 
|  | }, | 
|  | Blueprint: ` | 
|  | android_app { | 
|  | name: "framework-res", | 
|  | resource_zips: [ | 
|  | "resource_zip.zip", | 
|  | ], | 
|  | certificate: "platform", | 
|  | } | 
|  |  | 
|  | filegroup { | 
|  | name: "framework-res-package-jar", | 
|  | srcs: [":framework-res{.export-package.apk}"], | 
|  | } | 
|  | `, | 
|  | ExpectedBazelTargets: []string{ | 
|  | MakeBazelTarget("framework_resources", "framework-res", AttrNameToString{ | 
|  | "certificate_name":       `"platform"`, | 
|  | "manifest":               `"AndroidManifest.xml"`, | 
|  | "resource_files":         `["res/values/attrs.xml"]`, | 
|  | "resource_zips":          `["resource_zip.zip"]`, | 
|  | "target_compatible_with": `["//build/bazel_common_rules/platforms/os:android"]`, | 
|  | }), | 
|  | MakeBazelTargetNoRestrictions("filegroup", "framework-res-package-jar", AttrNameToString{ | 
|  | "srcs": `[":framework-res.export-package.apk"]`, | 
|  | }), | 
|  | }}) | 
|  |  | 
|  | } |