2017-11-23 01:19:37 +01:00
// Copyright 2017 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 java
import (
2018-04-18 20:06:47 +02:00
"fmt"
2018-10-03 07:03:40 +02:00
"path/filepath"
2017-11-23 01:19:37 +01:00
"reflect"
2017-12-01 19:48:26 +01:00
"sort"
2018-04-18 20:06:47 +02:00
"strings"
2017-11-23 01:19:37 +01:00
"testing"
2019-04-26 23:31:50 +02:00
"github.com/google/blueprint/proptools"
"android/soong/android"
"android/soong/cc"
2021-03-22 17:02:28 +01:00
"android/soong/dexpreopt"
2017-11-23 01:19:37 +01:00
)
2021-03-22 16:36:52 +01:00
// testApp runs tests using the prepareForJavaTest
2021-03-13 03:19:32 +01:00
//
// See testJava for an explanation as to how to stop using this deprecated method.
//
// deprecated
func testApp ( t * testing . T , bp string ) * android . TestContext {
t . Helper ( )
2021-03-22 16:36:52 +01:00
result := prepareForJavaTest . RunTestWithBp ( t , bp )
2021-03-13 03:19:32 +01:00
return result . TestContext
}
func TestApp ( t * testing . T ) {
resourceFiles := [ ] string {
2017-11-23 01:19:37 +01:00
"res/layout/layout.xml" ,
"res/values/strings.xml" ,
"res/values-en-rUS/strings.xml" ,
}
2021-03-13 03:19:32 +01:00
compiledResourceFiles := [ ] string {
2017-11-23 01:19:37 +01:00
"aapt2/res/layout_layout.xml.flat" ,
"aapt2/res/values_strings.arsc.flat" ,
"aapt2/res/values-en-rUS_strings.arsc.flat" ,
}
2018-03-28 23:58:31 +02:00
for _ , moduleType := range [ ] string { "android_app" , "android_library" } {
t . Run ( moduleType , func ( t * testing . T ) {
2021-03-22 16:36:52 +01:00
result := android . GroupFixturePreparers (
prepareForJavaTest ,
2021-03-13 03:19:32 +01:00
android . FixtureModifyMockFS ( func ( fs android . MockFS ) {
for _ , file := range resourceFiles {
fs [ file ] = nil
}
} ) ,
) . RunTestWithBp ( t , moduleType + ` {
2018-03-28 23:58:31 +02:00
name : "foo" ,
srcs : [ "a.java" ] ,
2019-07-11 08:54:27 +02:00
sdk_version : "current"
2018-03-28 23:58:31 +02:00
}
` )
2021-03-13 03:19:32 +01:00
foo := result . ModuleForTests ( "foo" , "android_common" )
2018-03-28 23:58:31 +02:00
2018-05-25 01:11:20 +02:00
var expectedLinkImplicits [ ] string
manifestFixer := foo . Output ( "manifest_fixer/AndroidManifest.xml" )
expectedLinkImplicits = append ( expectedLinkImplicits , manifestFixer . Output . String ( ) )
2018-03-28 23:58:31 +02:00
2021-03-13 03:19:32 +01:00
frameworkRes := result . ModuleForTests ( "framework-res" , "android_common" )
2018-03-28 23:58:31 +02:00
expectedLinkImplicits = append ( expectedLinkImplicits ,
frameworkRes . Output ( "package-res.apk" ) . Output . String ( ) )
// Test the mapping from input files to compiled output file names
compile := foo . Output ( compiledResourceFiles [ 0 ] )
2021-03-13 03:19:32 +01:00
android . AssertDeepEquals ( t , "aapt2 compile inputs" , resourceFiles , compile . Inputs . Strings ( ) )
2018-03-28 23:58:31 +02:00
compiledResourceOutputs := compile . Outputs . Strings ( )
sort . Strings ( compiledResourceOutputs )
expectedLinkImplicits = append ( expectedLinkImplicits , compiledResourceOutputs ... )
list := foo . Output ( "aapt2/res.list" )
expectedLinkImplicits = append ( expectedLinkImplicits , list . Output . String ( ) )
// Check that the link rule uses
2021-03-13 03:19:32 +01:00
res := result . ModuleForTests ( "foo" , "android_common" ) . Output ( "package-res.apk" )
android . AssertDeepEquals ( t , "aapt2 link implicits" , expectedLinkImplicits , res . Implicits . Strings ( ) )
2018-03-28 23:58:31 +02:00
} )
2017-11-23 01:19:37 +01:00
}
}
2017-12-01 05:13:19 +01:00
2019-03-20 00:03:11 +01:00
func TestAppSplits ( t * testing . T ) {
ctx := testApp ( t , `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
package_splits : [ "v4" , "v7,hdpi" ] ,
2019-07-11 08:54:27 +02:00
sdk_version : "current"
2019-03-20 00:03:11 +01:00
} ` )
foo := ctx . ModuleForTests ( "foo" , "android_common" )
expectedOutputs := [ ] string {
2021-03-22 18:31:52 +01:00
"out/soong/.intermediates/foo/android_common/foo.apk" ,
"out/soong/.intermediates/foo/android_common/foo_v4.apk" ,
"out/soong/.intermediates/foo/android_common/foo_v7_hdpi.apk" ,
2019-03-20 00:03:11 +01:00
}
for _ , expectedOutput := range expectedOutputs {
foo . Output ( expectedOutput )
}
2019-05-29 23:40:35 +02:00
outputFiles , err := foo . Module ( ) . ( * AndroidApp ) . OutputFiles ( "" )
if err != nil {
t . Fatal ( err )
}
2021-03-22 18:31:52 +01:00
android . AssertPathsRelativeToTopEquals ( t , ` OutputFiles("") ` , expectedOutputs , outputFiles )
2019-03-20 00:03:11 +01:00
}
2019-07-11 08:54:27 +02:00
func TestPlatformAPIs ( t * testing . T ) {
testJava ( t , `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
platform_apis : true ,
}
` )
testJava ( t , `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
sdk_version : "current" ,
}
` )
2021-11-16 05:15:33 +01:00
testJavaError ( t , "This module has conflicting settings. sdk_version is empty, which means that this module is build against platform APIs. However platform_apis is not set to true" , `
2019-07-11 08:54:27 +02:00
android_app {
name : "bar" ,
srcs : [ "b.java" ] ,
}
` )
2021-11-16 05:15:33 +01:00
testJavaError ( t , "This module has conflicting settings. sdk_version is not empty, which means this module cannot use platform APIs. However platform_apis is set to true." , `
2019-07-11 08:54:27 +02:00
android_app {
name : "bar" ,
srcs : [ "b.java" ] ,
sdk_version : "system_current" ,
platform_apis : true ,
}
` )
}
2019-12-06 16:16:24 +01:00
func TestAndroidAppLinkType ( t * testing . T ) {
testJava ( t , `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
libs : [ "bar" ] ,
static_libs : [ "baz" ] ,
platform_apis : true ,
}
java_library {
name : "bar" ,
sdk_version : "current" ,
srcs : [ "b.java" ] ,
}
android_library {
name : "baz" ,
sdk_version : "system_current" ,
srcs : [ "c.java" ] ,
}
` )
2020-11-17 22:44:36 +01:00
testJavaError ( t , "consider adjusting sdk_version: OR platform_apis:" , `
2019-12-06 16:16:24 +01:00
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
libs : [ "bar" ] ,
sdk_version : "current" ,
static_libs : [ "baz" ] ,
}
java_library {
name : "bar" ,
sdk_version : "current" ,
srcs : [ "b.java" ] ,
}
android_library {
name : "baz" ,
sdk_version : "system_current" ,
srcs : [ "c.java" ] ,
}
` )
testJava ( t , `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
libs : [ "bar" ] ,
sdk_version : "system_current" ,
static_libs : [ "baz" ] ,
}
java_library {
name : "bar" ,
sdk_version : "current" ,
srcs : [ "b.java" ] ,
}
android_library {
name : "baz" ,
sdk_version : "system_current" ,
srcs : [ "c.java" ] ,
}
` )
2020-11-17 22:44:36 +01:00
testJavaError ( t , "consider adjusting sdk_version: OR platform_apis:" , `
2019-12-06 16:16:24 +01:00
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
libs : [ "bar" ] ,
sdk_version : "system_current" ,
static_libs : [ "baz" ] ,
}
java_library {
name : "bar" ,
sdk_version : "current" ,
srcs : [ "b.java" ] ,
}
android_library {
name : "baz" ,
srcs : [ "c.java" ] ,
}
` )
}
2020-04-08 20:09:30 +02:00
func TestUpdatableApps ( t * testing . T ) {
testCases := [ ] struct {
name string
bp string
expectedError string
} {
{
name : "Stable public SDK" ,
bp : ` android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
sdk_version : "29" ,
2020-04-16 14:43:02 +02:00
min_sdk_version : "29" ,
2020-04-08 20:09:30 +02:00
updatable : true ,
} ` ,
} ,
{
name : "Stable system SDK" ,
bp : ` android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
sdk_version : "system_29" ,
2020-04-16 14:43:02 +02:00
min_sdk_version : "29" ,
2020-04-08 20:09:30 +02:00
updatable : true ,
} ` ,
} ,
{
name : "Current public SDK" ,
bp : ` android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
sdk_version : "current" ,
2020-04-16 14:43:02 +02:00
min_sdk_version : "29" ,
2020-04-08 20:09:30 +02:00
updatable : true ,
} ` ,
} ,
{
name : "Current system SDK" ,
bp : ` android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
sdk_version : "system_current" ,
2020-04-16 14:43:02 +02:00
min_sdk_version : "29" ,
2020-04-08 20:09:30 +02:00
updatable : true ,
} ` ,
} ,
{
name : "Current module SDK" ,
bp : ` android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
sdk_version : "module_current" ,
2020-04-16 14:43:02 +02:00
min_sdk_version : "29" ,
2020-04-08 20:09:30 +02:00
updatable : true ,
} ` ,
} ,
{
name : "Current core SDK" ,
bp : ` android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
sdk_version : "core_current" ,
2020-04-16 14:43:02 +02:00
min_sdk_version : "29" ,
2020-04-08 20:09:30 +02:00
updatable : true ,
} ` ,
} ,
{
name : "No Platform APIs" ,
bp : ` android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
platform_apis : true ,
2020-04-16 14:43:02 +02:00
min_sdk_version : "29" ,
2020-04-08 20:09:30 +02:00
updatable : true ,
} ` ,
expectedError : "Updatable apps must use stable SDKs" ,
} ,
{
name : "No Core Platform APIs" ,
bp : ` android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
sdk_version : "core_platform" ,
2020-04-16 14:43:02 +02:00
min_sdk_version : "29" ,
2020-04-08 20:09:30 +02:00
updatable : true ,
} ` ,
expectedError : "Updatable apps must use stable SDKs" ,
} ,
{
name : "No unspecified APIs" ,
bp : ` android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
updatable : true ,
2020-04-16 14:43:02 +02:00
min_sdk_version : "29" ,
2020-04-08 20:09:30 +02:00
} ` ,
expectedError : "Updatable apps must use stable SDK" ,
} ,
2020-04-16 14:43:02 +02:00
{
name : "Must specify min_sdk_version" ,
bp : ` android_app {
name : "app_without_min_sdk_version" ,
srcs : [ "a.java" ] ,
sdk_version : "29" ,
updatable : true ,
} ` ,
expectedError : "updatable apps must set min_sdk_version." ,
} ,
2020-04-08 20:09:30 +02:00
}
for _ , test := range testCases {
t . Run ( test . name , func ( t * testing . T ) {
2021-03-14 01:36:50 +01:00
errorHandler := android . FixtureExpectsNoErrors
if test . expectedError != "" {
errorHandler = android . FixtureExpectsAtLeastOneErrorMatchingPattern ( test . expectedError )
2020-04-08 20:09:30 +02:00
}
2021-03-22 16:36:52 +01:00
android . GroupFixturePreparers (
prepareForJavaTest , FixtureWithPrebuiltApis ( map [ string ] [ ] string {
2021-03-13 03:36:00 +01:00
"29" : { "foo" } ,
} ) ) .
2021-03-14 01:36:50 +01:00
ExtendWithErrorHandler ( errorHandler ) . RunTestWithBp ( t , test . bp )
2020-04-08 20:09:30 +02:00
} )
}
}
2020-04-15 04:03:39 +02:00
func TestUpdatableApps_TransitiveDepsShouldSetMinSdkVersion ( t * testing . T ) {
testJavaError ( t , ` module "bar".*: should support min_sdk_version\(29\) ` , cc . GatherRequiredDepsForTest ( android . Android ) + `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
updatable : true ,
sdk_version : "current" ,
min_sdk_version : "29" ,
static_libs : [ "bar" ] ,
}
java_library {
name : "bar" ,
sdk_version : "current" ,
}
` )
}
2020-04-29 07:01:06 +02:00
func TestUpdatableApps_JniLibsShouldShouldSupportMinSdkVersion ( t * testing . T ) {
testJava ( t , cc . GatherRequiredDepsForTest ( android . Android ) + `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
updatable : true ,
sdk_version : "current" ,
min_sdk_version : "current" ,
jni_libs : [ "libjni" ] ,
}
cc_library {
name : "libjni" ,
stl : "none" ,
system_shared_libs : [ ] ,
sdk_version : "current" ,
}
` )
}
func TestUpdatableApps_JniLibShouldBeBuiltAgainstMinSdkVersion ( t * testing . T ) {
bp := cc . GatherRequiredDepsForTest ( android . Android ) + `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
updatable : true ,
sdk_version : "current" ,
min_sdk_version : "29" ,
jni_libs : [ "libjni" ] ,
}
cc_library {
name : "libjni" ,
stl : "none" ,
system_shared_libs : [ ] ,
2022-05-08 02:39:35 +02:00
sdk_version : "current" ,
min_sdk_version : "29" ,
2020-04-29 07:01:06 +02:00
}
`
fs := map [ string ] [ ] byte {
"prebuilts/ndk/current/platforms/android-29/arch-arm64/usr/lib/crtbegin_so.o" : nil ,
"prebuilts/ndk/current/platforms/android-29/arch-arm64/usr/lib/crtend_so.o" : nil ,
"prebuilts/ndk/current/platforms/android-29/arch-arm/usr/lib/crtbegin_so.o" : nil ,
"prebuilts/ndk/current/platforms/android-29/arch-arm/usr/lib/crtend_so.o" : nil ,
}
2021-03-22 18:31:52 +01:00
ctx , _ := testJavaWithFS ( t , bp , fs )
2020-04-29 07:01:06 +02:00
inputs := ctx . ModuleForTests ( "libjni" , "android_arm64_armv8-a_sdk_shared" ) . Description ( "link" ) . Implicits
var crtbeginFound , crtendFound bool
2020-07-15 22:33:30 +02:00
expectedCrtBegin := ctx . ModuleForTests ( "crtbegin_so" ,
2022-12-06 23:50:08 +01:00
"android_arm64_armv8-a_sdk_29" ) . Rule ( "noAddrSig" ) . Output
2020-07-15 22:33:30 +02:00
expectedCrtEnd := ctx . ModuleForTests ( "crtend_so" ,
2022-12-06 23:50:08 +01:00
"android_arm64_armv8-a_sdk_29" ) . Rule ( "noAddrSig" ) . Output
2020-07-15 22:33:30 +02:00
implicits := [ ] string { }
2020-04-29 07:01:06 +02:00
for _ , input := range inputs {
2020-07-15 22:33:30 +02:00
implicits = append ( implicits , input . String ( ) )
if strings . HasSuffix ( input . String ( ) , expectedCrtBegin . String ( ) ) {
2020-04-29 07:01:06 +02:00
crtbeginFound = true
2020-07-15 22:33:30 +02:00
} else if strings . HasSuffix ( input . String ( ) , expectedCrtEnd . String ( ) ) {
2020-04-29 07:01:06 +02:00
crtendFound = true
}
}
2020-07-15 22:33:30 +02:00
if ! crtbeginFound {
t . Error ( fmt . Sprintf (
"expected implicit with suffix %q, have the following implicits:\n%s" ,
expectedCrtBegin , strings . Join ( implicits , "\n" ) ) )
}
if ! crtendFound {
t . Error ( fmt . Sprintf (
"expected implicit with suffix %q, have the following implicits:\n%s" ,
expectedCrtEnd , strings . Join ( implicits , "\n" ) ) )
2020-04-29 07:01:06 +02:00
}
}
func TestUpdatableApps_ErrorIfJniLibDoesntSupportMinSdkVersion ( t * testing . T ) {
bp := cc . GatherRequiredDepsForTest ( android . Android ) + `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
updatable : true ,
sdk_version : "current" ,
min_sdk_version : "29" , // this APK should support 29
jni_libs : [ "libjni" ] ,
}
cc_library {
name : "libjni" ,
stl : "none" ,
sdk_version : "current" ,
2022-05-08 02:39:35 +02:00
min_sdk_version : "current" ,
2020-04-29 07:01:06 +02:00
}
`
2022-05-08 02:39:35 +02:00
testJavaError ( t , ` "libjni" .*: min_sdk_version\(current\) is higher than min_sdk_version\(29\) ` , bp )
2020-04-29 07:01:06 +02:00
}
2022-05-08 02:39:35 +02:00
func TestUpdatableApps_ErrorIfDepMinSdkVersionIsHigher ( t * testing . T ) {
2020-04-29 07:01:06 +02:00
bp := cc . GatherRequiredDepsForTest ( android . Android ) + `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
updatable : true ,
sdk_version : "current" ,
min_sdk_version : "29" , // this APK should support 29
jni_libs : [ "libjni" ] ,
}
cc_library {
name : "libjni" ,
stl : "none" ,
shared_libs : [ "libbar" ] ,
system_shared_libs : [ ] ,
sdk_version : "27" ,
2022-05-08 02:39:35 +02:00
min_sdk_version : "27" ,
2020-04-29 07:01:06 +02:00
}
cc_library {
name : "libbar" ,
stl : "none" ,
system_shared_libs : [ ] ,
sdk_version : "current" ,
2022-05-08 02:39:35 +02:00
min_sdk_version : "current" ,
2020-04-29 07:01:06 +02:00
}
`
testJavaError ( t , ` "libjni" .*: links "libbar" built against newer API version "current" ` , bp )
}
2019-02-08 00:30:01 +01:00
func TestResourceDirs ( t * testing . T ) {
testCases := [ ] struct {
name string
prop string
resources [ ] string
} {
{
name : "no resource_dirs" ,
prop : "" ,
resources : [ ] string { "res/res/values/strings.xml" } ,
} ,
{
name : "resource_dirs" ,
prop : ` resource_dirs: ["res"] ` ,
resources : [ ] string { "res/res/values/strings.xml" } ,
} ,
{
name : "empty resource_dirs" ,
prop : ` resource_dirs: [] ` ,
resources : nil ,
} ,
}
2021-03-22 18:31:52 +01:00
fs := android . MockFS {
2019-02-08 00:30:01 +01:00
"res/res/values/strings.xml" : nil ,
}
bp := `
android_app {
name : "foo" ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-02-08 00:30:01 +01:00
% s
}
`
for _ , testCase := range testCases {
t . Run ( testCase . name , func ( t * testing . T ) {
2021-03-22 18:31:52 +01:00
result := android . GroupFixturePreparers (
PrepareForTestWithJavaDefaultModules ,
fs . AddToFixture ( ) ,
) . RunTestWithBp ( t , fmt . Sprintf ( bp , testCase . prop ) )
2019-02-08 00:30:01 +01:00
2021-03-22 18:31:52 +01:00
module := result . ModuleForTests ( "foo" , "android_common" )
2019-02-08 00:30:01 +01:00
resourceList := module . MaybeOutput ( "aapt2/res.list" )
var resources [ ] string
if resourceList . Rule != nil {
for _ , compiledResource := range resourceList . Inputs . Strings ( ) {
resources = append ( resources , module . Output ( compiledResource ) . Inputs . Strings ( ) ... )
}
}
2021-03-22 18:31:52 +01:00
android . AssertDeepEquals ( t , "resource files" , testCase . resources , resources )
2019-02-08 00:30:01 +01:00
} )
}
}
2020-01-15 23:15:10 +01:00
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" ,
2023-07-14 19:23:41 +02:00
static_libs : [ "lib4" , "import" ] ,
2020-01-15 23:15:10 +01:00
}
android_library {
name : "lib4" ,
sdk_version : "current" ,
asset_dirs : [ "assets_b" ] ,
}
2023-07-14 19:23:41 +02:00
2023-10-13 19:08:59 +02:00
android_library {
name : "lib5" ,
sdk_version : "current" ,
assets : [
"path/to/asset_file_1" ,
"path/to/asset_file_2" ,
] ,
}
2023-07-14 19:23:41 +02:00
android_library_import {
name : "import" ,
sdk_version : "current" ,
aars : [ "import.aar" ] ,
}
2020-01-15 23:15:10 +01:00
`
testCases := [ ] struct {
2023-10-13 19:08:59 +02:00
name string
assetFlag string
assetPackages [ ] string
tmpAssetDirInputs [ ] string
tmpAssetDirOutputs [ ] string
2020-01-15 23:15:10 +01:00
} {
{
name : "foo" ,
2023-07-14 19:23:41 +02:00
// lib1 has its own assets. lib3 doesn't have any, but lib4 and import have assets.
2020-01-15 23:15:10 +01:00
assetPackages : [ ] string {
2021-03-22 18:31:52 +01:00
"out/soong/.intermediates/foo/android_common/aapt2/package-res.apk" ,
"out/soong/.intermediates/lib1/android_common/assets.zip" ,
2023-07-14 19:23:41 +02:00
"out/soong/.intermediates/lib4/android_common/assets.zip" ,
"out/soong/.intermediates/import/android_common/assets.zip" ,
2020-01-15 23:15:10 +01:00
} ,
} ,
{
name : "lib1" ,
assetFlag : "-A assets_a" ,
} ,
{
name : "lib2" ,
} ,
{
name : "lib3" ,
} ,
{
name : "lib4" ,
assetFlag : "-A assets_b" ,
} ,
2023-10-13 19:08:59 +02:00
{
name : "lib5" ,
assetFlag : "-A out/soong/.intermediates/lib5/android_common/tmp_asset_dir" ,
tmpAssetDirInputs : [ ] string {
"path/to/asset_file_1" ,
"path/to/asset_file_2" ,
} ,
tmpAssetDirOutputs : [ ] string {
"out/soong/.intermediates/lib5/android_common/tmp_asset_dir/path/to/asset_file_1" ,
"out/soong/.intermediates/lib5/android_common/tmp_asset_dir/path/to/asset_file_2" ,
} ,
} ,
2020-01-15 23:15:10 +01:00
}
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" )
}
2021-03-29 01:42:57 +02:00
aapt2link = aapt2link
2020-01-15 23:15:10 +01:00
aapt2Flags := aapt2link . Args [ "flags" ]
if test . assetFlag != "" {
2021-03-22 18:31:52 +01:00
android . AssertStringDoesContain ( t , "asset flag" , aapt2Flags , test . assetFlag )
2020-01-15 23:15:10 +01:00
} else {
2021-03-22 18:31:52 +01:00
android . AssertStringDoesNotContain ( t , "aapt2 link flags" , aapt2Flags , " -A " )
2020-01-15 23:15:10 +01:00
}
// Check asset merge rule.
if len ( test . assetPackages ) > 0 {
mergeAssets := m . Output ( "package-res.apk" )
2021-03-22 18:31:52 +01:00
android . AssertPathsRelativeToTopEquals ( t , "mergeAssets inputs" , test . assetPackages , mergeAssets . Inputs )
2020-01-15 23:15:10 +01:00
}
2023-10-13 19:08:59 +02:00
if len ( test . tmpAssetDirInputs ) > 0 {
rule := m . Rule ( "tmp_asset_dir" )
inputs := rule . Implicits
outputs := append ( android . WritablePaths { rule . Output } , rule . ImplicitOutputs ... ) . Paths ( )
android . AssertPathsRelativeToTopEquals ( t , "tmp_asset_dir inputs" , test . tmpAssetDirInputs , inputs )
android . AssertPathsRelativeToTopEquals ( t , "tmp_asset_dir outputs" , test . tmpAssetDirOutputs , outputs )
}
2020-01-15 23:15:10 +01:00
} )
}
}
2021-02-26 23:54:36 +01:00
func TestAppJavaResources ( t * testing . T ) {
bp := `
android_app {
name : "foo" ,
sdk_version : "current" ,
java_resources : [ "resources/a" ] ,
srcs : [ "a.java" ] ,
}
android_app {
name : "bar" ,
sdk_version : "current" ,
java_resources : [ "resources/a" ] ,
}
`
ctx := testApp ( t , bp )
foo := ctx . ModuleForTests ( "foo" , "android_common" )
fooResources := foo . Output ( "res/foo.jar" )
fooDexJar := foo . Output ( "dex-withres/foo.jar" )
fooDexJarAligned := foo . Output ( "dex-withres-aligned/foo.jar" )
fooApk := foo . Rule ( "combineApk" )
if g , w := fooDexJar . Inputs . Strings ( ) , fooResources . Output . String ( ) ; ! android . InList ( w , g ) {
t . Errorf ( "expected resource jar %q in foo dex jar inputs %q" , w , g )
}
if g , w := fooDexJarAligned . Input . String ( ) , fooDexJar . Output . String ( ) ; g != w {
t . Errorf ( "expected dex jar %q in foo aligned dex jar inputs %q" , w , g )
}
if g , w := fooApk . Inputs . Strings ( ) , fooDexJarAligned . Output . String ( ) ; ! android . InList ( w , g ) {
t . Errorf ( "expected aligned dex jar %q in foo apk inputs %q" , w , g )
}
bar := ctx . ModuleForTests ( "bar" , "android_common" )
barResources := bar . Output ( "res/bar.jar" )
barApk := bar . Rule ( "combineApk" )
if g , w := barApk . Inputs . Strings ( ) , barResources . Output . String ( ) ; ! android . InList ( w , g ) {
t . Errorf ( "expected resources jar %q in bar apk inputs %q" , w , g )
}
}
2023-07-05 23:04:12 +02:00
func TestAndroidResourceProcessor ( t * testing . T ) {
testCases := [ ] struct {
2023-10-13 00:58:57 +02:00
name string
appUsesRP bool
directLibUsesRP bool
transitiveLibUsesRP bool
sharedLibUsesRP bool
sharedTransitiveStaticLibUsesRP bool
sharedTransitiveSharedLibUsesRP bool
2023-07-05 23:04:12 +02:00
dontVerifyApp bool
appResources [ ] string
appOverlays [ ] string
appImports [ ] string
appSrcJars [ ] string
appClasspath [ ] string
appCombined [ ] string
dontVerifyDirect bool
directResources [ ] string
directOverlays [ ] string
directImports [ ] string
directSrcJars [ ] string
directClasspath [ ] string
directCombined [ ] string
dontVerifyTransitive bool
transitiveResources [ ] string
transitiveOverlays [ ] string
transitiveImports [ ] string
transitiveSrcJars [ ] string
transitiveClasspath [ ] string
transitiveCombined [ ] string
dontVerifyDirectImport bool
directImportResources [ ] string
directImportOverlays [ ] string
directImportImports [ ] string
dontVerifyTransitiveImport bool
transitiveImportResources [ ] string
transitiveImportOverlays [ ] string
transitiveImportImports [ ] string
2023-10-13 00:58:57 +02:00
dontVerifyShared bool
sharedResources [ ] string
sharedOverlays [ ] string
sharedImports [ ] string
sharedSrcJars [ ] string
sharedClasspath [ ] string
sharedCombined [ ] string
2023-07-05 23:04:12 +02:00
} {
{
2023-06-21 07:40:02 +02:00
// Test with all modules set to use_resource_processor: false (except android_library_import modules,
// which always use resource processor).
name : "legacy" ,
appUsesRP : false ,
directLibUsesRP : false ,
transitiveLibUsesRP : false ,
2023-07-05 23:04:12 +02:00
appResources : nil ,
appOverlays : [ ] string {
"out/soong/.intermediates/transitive/android_common/package-res.apk" ,
2023-07-14 19:23:41 +02:00
"out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk" ,
2023-07-05 23:04:12 +02:00
"out/soong/.intermediates/transitive_import/android_common/package-res.apk" ,
"out/soong/.intermediates/direct/android_common/package-res.apk" ,
2023-07-14 19:23:41 +02:00
"out/soong/.intermediates/direct_import_dep/android_common/package-res.apk" ,
2023-07-05 23:04:12 +02:00
"out/soong/.intermediates/direct_import/android_common/package-res.apk" ,
"out/soong/.intermediates/app/android_common/aapt2/app/res/values_strings.arsc.flat" ,
} ,
2023-10-13 00:58:57 +02:00
appImports : [ ] string {
"out/soong/.intermediates/shared/android_common/package-res.apk" ,
"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk" ,
} ,
2023-07-05 23:04:12 +02:00
appSrcJars : [ ] string { "out/soong/.intermediates/app/android_common/gen/android/R.srcjar" } ,
appClasspath : [ ] string {
"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar" ,
2023-10-13 00:58:57 +02:00
"out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar" ,
2023-07-05 23:04:12 +02:00
"out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar" ,
2024-03-23 05:43:41 +01:00
"out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar" ,
2023-07-05 23:04:12 +02:00
} ,
appCombined : [ ] string {
"out/soong/.intermediates/app/android_common/javac/app.jar" ,
"out/soong/.intermediates/direct/android_common/combined/direct.jar" ,
2024-03-23 05:43:41 +01:00
"out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar" ,
2023-07-05 23:04:12 +02:00
} ,
directResources : nil ,
directOverlays : [ ] string {
"out/soong/.intermediates/transitive/android_common/package-res.apk" ,
2023-07-14 19:23:41 +02:00
"out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk" ,
2023-07-05 23:04:12 +02:00
"out/soong/.intermediates/transitive_import/android_common/package-res.apk" ,
"out/soong/.intermediates/direct/android_common/aapt2/direct/res/values_strings.arsc.flat" ,
} ,
directImports : [ ] string { "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk" } ,
directSrcJars : [ ] string { "out/soong/.intermediates/direct/android_common/gen/android/R.srcjar" } ,
directClasspath : [ ] string {
"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar" ,
"out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar" ,
2024-03-23 05:43:41 +01:00
"out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.jar" ,
2023-07-05 23:04:12 +02:00
} ,
directCombined : [ ] string {
"out/soong/.intermediates/direct/android_common/javac/direct.jar" ,
"out/soong/.intermediates/transitive/android_common/javac/transitive.jar" ,
2024-03-23 05:43:41 +01:00
"out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar" ,
2023-07-05 23:04:12 +02:00
} ,
transitiveResources : [ ] string { "out/soong/.intermediates/transitive/android_common/aapt2/transitive/res/values_strings.arsc.flat" } ,
transitiveOverlays : nil ,
transitiveImports : [ ] string { "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk" } ,
transitiveSrcJars : [ ] string { "out/soong/.intermediates/transitive/android_common/gen/android/R.srcjar" } ,
transitiveClasspath : [ ] string { "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar" } ,
transitiveCombined : nil ,
2023-10-13 00:58:57 +02:00
sharedResources : nil ,
sharedOverlays : [ ] string {
"out/soong/.intermediates/shared_transitive_static/android_common/package-res.apk" ,
"out/soong/.intermediates/shared/android_common/aapt2/shared/res/values_strings.arsc.flat" ,
} ,
sharedImports : [ ] string {
"out/soong/.intermediates/shared_transitive_shared/android_common/package-res.apk" ,
"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk" ,
} ,
sharedSrcJars : [ ] string { "out/soong/.intermediates/shared/android_common/gen/android/R.srcjar" } ,
sharedClasspath : [ ] string {
"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar" ,
"out/soong/.intermediates/shared_transitive_shared/android_common/turbine-combined/shared_transitive_shared.jar" ,
"out/soong/.intermediates/shared_transitive_static/android_common/turbine-combined/shared_transitive_static.jar" ,
} ,
sharedCombined : [ ] string {
"out/soong/.intermediates/shared/android_common/javac/shared.jar" ,
"out/soong/.intermediates/shared_transitive_static/android_common/javac/shared_transitive_static.jar" ,
} ,
2023-07-05 23:04:12 +02:00
directImportResources : nil ,
2023-06-21 07:40:02 +02:00
directImportOverlays : [ ] string { "out/soong/.intermediates/direct_import/android_common/flat-res/gen_res.flata" } ,
directImportImports : [ ] string {
"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk" ,
"out/soong/.intermediates/direct_import_dep/android_common/package-res.apk" ,
} ,
transitiveImportResources : nil ,
transitiveImportOverlays : [ ] string { "out/soong/.intermediates/transitive_import/android_common/flat-res/gen_res.flata" } ,
transitiveImportImports : [ ] string {
"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk" ,
"out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk" ,
} ,
} ,
{
// Test with all modules set to use_resource_processor: true.
2023-10-13 00:58:57 +02:00
name : "resource_processor" ,
appUsesRP : true ,
directLibUsesRP : true ,
transitiveLibUsesRP : true ,
sharedLibUsesRP : true ,
sharedTransitiveSharedLibUsesRP : true ,
sharedTransitiveStaticLibUsesRP : true ,
2023-06-21 07:40:02 +02:00
appResources : nil ,
appOverlays : [ ] string {
"out/soong/.intermediates/transitive/android_common/package-res.apk" ,
"out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk" ,
"out/soong/.intermediates/transitive_import/android_common/package-res.apk" ,
"out/soong/.intermediates/direct/android_common/package-res.apk" ,
"out/soong/.intermediates/direct_import_dep/android_common/package-res.apk" ,
"out/soong/.intermediates/direct_import/android_common/package-res.apk" ,
"out/soong/.intermediates/app/android_common/aapt2/app/res/values_strings.arsc.flat" ,
} ,
2023-10-13 00:58:57 +02:00
appImports : [ ] string {
"out/soong/.intermediates/shared/android_common/package-res.apk" ,
"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk" ,
} ,
2023-06-21 07:40:02 +02:00
appSrcJars : nil ,
appClasspath : [ ] string {
"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar" ,
"out/soong/.intermediates/app/android_common/busybox/R.jar" ,
2023-10-13 00:58:57 +02:00
"out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar" ,
2023-06-21 07:40:02 +02:00
"out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar" ,
2024-03-23 05:43:41 +01:00
"out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar" ,
2023-06-21 07:40:02 +02:00
} ,
appCombined : [ ] string {
"out/soong/.intermediates/app/android_common/javac/app.jar" ,
2024-02-23 19:05:21 +01:00
"out/soong/.intermediates/app/android_common/busybox/R.jar" ,
2023-06-21 07:40:02 +02:00
"out/soong/.intermediates/direct/android_common/combined/direct.jar" ,
2024-03-23 05:43:41 +01:00
"out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar" ,
2023-06-21 07:40:02 +02:00
} ,
directResources : nil ,
directOverlays : [ ] string { "out/soong/.intermediates/direct/android_common/aapt2/direct/res/values_strings.arsc.flat" } ,
directImports : [ ] string {
"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk" ,
"out/soong/.intermediates/transitive_import/android_common/package-res.apk" ,
"out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk" ,
"out/soong/.intermediates/transitive/android_common/package-res.apk" ,
} ,
directSrcJars : nil ,
directClasspath : [ ] string {
"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar" ,
"out/soong/.intermediates/direct/android_common/busybox/R.jar" ,
2024-03-05 20:51:54 +01:00
"out/soong/.intermediates/transitive/android_common/busybox/R.jar" ,
"out/soong/.intermediates/transitive_import_dep/android_common/busybox/R.jar" ,
"out/soong/.intermediates/transitive_import/android_common/busybox/R.jar" ,
2023-06-21 07:40:02 +02:00
"out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar" ,
2024-03-23 05:43:41 +01:00
"out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.jar" ,
2023-06-21 07:40:02 +02:00
} ,
directCombined : [ ] string {
"out/soong/.intermediates/direct/android_common/javac/direct.jar" ,
"out/soong/.intermediates/transitive/android_common/javac/transitive.jar" ,
2024-03-23 05:43:41 +01:00
"out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar" ,
2023-06-21 07:40:02 +02:00
} ,
transitiveResources : [ ] string { "out/soong/.intermediates/transitive/android_common/aapt2/transitive/res/values_strings.arsc.flat" } ,
transitiveOverlays : nil ,
transitiveImports : [ ] string { "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk" } ,
transitiveSrcJars : nil ,
transitiveClasspath : [ ] string {
"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar" ,
"out/soong/.intermediates/transitive/android_common/busybox/R.jar" ,
} ,
transitiveCombined : nil ,
2023-10-13 00:58:57 +02:00
sharedResources : nil ,
sharedOverlays : [ ] string { "out/soong/.intermediates/shared/android_common/aapt2/shared/res/values_strings.arsc.flat" } ,
sharedImports : [ ] string {
"out/soong/.intermediates/shared_transitive_shared/android_common/package-res.apk" ,
"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk" ,
"out/soong/.intermediates/shared_transitive_static/android_common/package-res.apk" ,
} ,
sharedSrcJars : nil ,
sharedClasspath : [ ] string {
"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar" ,
2024-03-05 20:51:54 +01:00
"out/soong/.intermediates/shared/android_common/busybox/R.jar" ,
2023-10-13 00:58:57 +02:00
"out/soong/.intermediates/shared_transitive_static/android_common/busybox/R.jar" ,
"out/soong/.intermediates/shared_transitive_shared/android_common/busybox/R.jar" ,
"out/soong/.intermediates/shared_transitive_shared/android_common/turbine-combined/shared_transitive_shared.jar" ,
"out/soong/.intermediates/shared_transitive_static/android_common/turbine-combined/shared_transitive_static.jar" ,
} ,
sharedCombined : [ ] string {
"out/soong/.intermediates/shared/android_common/javac/shared.jar" ,
"out/soong/.intermediates/shared_transitive_static/android_common/javac/shared_transitive_static.jar" ,
} ,
2023-06-21 07:40:02 +02:00
directImportResources : nil ,
directImportOverlays : [ ] string { "out/soong/.intermediates/direct_import/android_common/flat-res/gen_res.flata" } ,
directImportImports : [ ] string {
"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk" ,
2023-07-05 23:04:12 +02:00
"out/soong/.intermediates/direct_import_dep/android_common/package-res.apk" ,
} ,
transitiveImportResources : nil ,
2023-06-21 07:40:02 +02:00
transitiveImportOverlays : [ ] string { "out/soong/.intermediates/transitive_import/android_common/flat-res/gen_res.flata" } ,
transitiveImportImports : [ ] string {
"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk" ,
"out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk" ,
} ,
} , {
// Test an app building with resource processor enabled but with dependencies built without
// resource processor.
name : "app_resource_processor" ,
appUsesRP : true ,
directLibUsesRP : false ,
transitiveLibUsesRP : false ,
appResources : nil ,
appOverlays : [ ] string {
"out/soong/.intermediates/transitive/android_common/package-res.apk" ,
"out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk" ,
"out/soong/.intermediates/transitive_import/android_common/package-res.apk" ,
"out/soong/.intermediates/direct/android_common/package-res.apk" ,
"out/soong/.intermediates/direct_import_dep/android_common/package-res.apk" ,
"out/soong/.intermediates/direct_import/android_common/package-res.apk" ,
"out/soong/.intermediates/app/android_common/aapt2/app/res/values_strings.arsc.flat" ,
} ,
2023-10-13 00:58:57 +02:00
appImports : [ ] string {
"out/soong/.intermediates/shared/android_common/package-res.apk" ,
"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk" ,
} ,
2023-06-21 07:40:02 +02:00
appSrcJars : nil ,
appClasspath : [ ] string {
"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar" ,
// R.jar has to come before direct.jar
"out/soong/.intermediates/app/android_common/busybox/R.jar" ,
2023-10-13 00:58:57 +02:00
"out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar" ,
2023-06-21 07:40:02 +02:00
"out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar" ,
2024-03-23 05:43:41 +01:00
"out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar" ,
2023-06-21 07:40:02 +02:00
} ,
appCombined : [ ] string {
"out/soong/.intermediates/app/android_common/javac/app.jar" ,
2024-02-23 19:05:21 +01:00
"out/soong/.intermediates/app/android_common/busybox/R.jar" ,
2023-06-21 07:40:02 +02:00
"out/soong/.intermediates/direct/android_common/combined/direct.jar" ,
2024-03-23 05:43:41 +01:00
"out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar" ,
2023-06-21 07:40:02 +02:00
} ,
dontVerifyDirect : true ,
dontVerifyTransitive : true ,
2023-10-13 00:58:57 +02:00
dontVerifyShared : true ,
2023-06-21 07:40:02 +02:00
dontVerifyDirectImport : true ,
dontVerifyTransitiveImport : true ,
} ,
{
// Test an app building without resource processor enabled but with a dependency built with
// resource processor.
name : "app_dependency_lib_resource_processor" ,
appUsesRP : false ,
directLibUsesRP : true ,
transitiveLibUsesRP : false ,
appOverlays : [ ] string {
"out/soong/.intermediates/transitive/android_common/package-res.apk" ,
2023-07-05 23:04:12 +02:00
"out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk" ,
2023-06-21 07:40:02 +02:00
"out/soong/.intermediates/transitive_import/android_common/package-res.apk" ,
"out/soong/.intermediates/direct/android_common/package-res.apk" ,
"out/soong/.intermediates/direct_import_dep/android_common/package-res.apk" ,
"out/soong/.intermediates/direct_import/android_common/package-res.apk" ,
"out/soong/.intermediates/app/android_common/aapt2/app/res/values_strings.arsc.flat" ,
} ,
2023-10-13 00:58:57 +02:00
appImports : [ ] string {
"out/soong/.intermediates/shared/android_common/package-res.apk" ,
"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk" ,
} ,
2023-06-21 07:40:02 +02:00
appSrcJars : [ ] string { "out/soong/.intermediates/app/android_common/gen/android/R.srcjar" } ,
appClasspath : [ ] string {
"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar" ,
2023-10-13 00:58:57 +02:00
"out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar" ,
2023-06-21 07:40:02 +02:00
"out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar" ,
2024-03-23 05:43:41 +01:00
"out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar" ,
2023-06-21 07:40:02 +02:00
} ,
appCombined : [ ] string {
"out/soong/.intermediates/app/android_common/javac/app.jar" ,
"out/soong/.intermediates/direct/android_common/combined/direct.jar" ,
2024-03-23 05:43:41 +01:00
"out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar" ,
2023-06-21 07:40:02 +02:00
} ,
directResources : nil ,
directOverlays : [ ] string { "out/soong/.intermediates/direct/android_common/aapt2/direct/res/values_strings.arsc.flat" } ,
directImports : [ ] string {
"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk" ,
"out/soong/.intermediates/transitive_import/android_common/package-res.apk" ,
"out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk" ,
"out/soong/.intermediates/transitive/android_common/package-res.apk" ,
} ,
directSrcJars : nil ,
directClasspath : [ ] string {
"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar" ,
"out/soong/.intermediates/direct/android_common/busybox/R.jar" ,
2024-03-05 20:51:54 +01:00
"out/soong/.intermediates/transitive_import_dep/android_common/busybox/R.jar" ,
"out/soong/.intermediates/transitive_import/android_common/busybox/R.jar" ,
2023-06-21 07:40:02 +02:00
"out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar" ,
2024-03-23 05:43:41 +01:00
"out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.jar" ,
2023-06-21 07:40:02 +02:00
} ,
directCombined : [ ] string {
"out/soong/.intermediates/direct/android_common/javac/direct.jar" ,
"out/soong/.intermediates/transitive/android_common/javac/transitive.jar" ,
2024-03-23 05:43:41 +01:00
"out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar" ,
2023-06-21 07:40:02 +02:00
} ,
dontVerifyTransitive : true ,
2023-10-13 00:58:57 +02:00
dontVerifyShared : true ,
2023-06-21 07:40:02 +02:00
dontVerifyDirectImport : true ,
dontVerifyTransitiveImport : true ,
} ,
{
// Test a library building without resource processor enabled but with a dependency built with
// resource processor.
name : "lib_dependency_lib_resource_processor" ,
appUsesRP : false ,
directLibUsesRP : false ,
transitiveLibUsesRP : true ,
appOverlays : [ ] string {
"out/soong/.intermediates/transitive/android_common/package-res.apk" ,
"out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk" ,
"out/soong/.intermediates/transitive_import/android_common/package-res.apk" ,
"out/soong/.intermediates/direct/android_common/package-res.apk" ,
"out/soong/.intermediates/direct_import_dep/android_common/package-res.apk" ,
"out/soong/.intermediates/direct_import/android_common/package-res.apk" ,
"out/soong/.intermediates/app/android_common/aapt2/app/res/values_strings.arsc.flat" ,
} ,
2023-10-13 00:58:57 +02:00
appImports : [ ] string {
"out/soong/.intermediates/shared/android_common/package-res.apk" ,
"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk" ,
} ,
2023-06-21 07:40:02 +02:00
appSrcJars : [ ] string { "out/soong/.intermediates/app/android_common/gen/android/R.srcjar" } ,
appClasspath : [ ] string {
"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar" ,
2023-10-13 00:58:57 +02:00
"out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar" ,
2023-06-21 07:40:02 +02:00
"out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar" ,
2024-03-23 05:43:41 +01:00
"out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar" ,
2023-06-21 07:40:02 +02:00
} ,
appCombined : [ ] string {
"out/soong/.intermediates/app/android_common/javac/app.jar" ,
"out/soong/.intermediates/direct/android_common/combined/direct.jar" ,
2024-03-23 05:43:41 +01:00
"out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar" ,
2023-07-05 23:04:12 +02:00
} ,
2023-06-21 07:40:02 +02:00
directResources : nil ,
directOverlays : [ ] string {
"out/soong/.intermediates/transitive/android_common/package-res.apk" ,
"out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk" ,
"out/soong/.intermediates/transitive_import/android_common/package-res.apk" ,
"out/soong/.intermediates/direct/android_common/aapt2/direct/res/values_strings.arsc.flat" ,
} ,
directImports : [ ] string { "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk" } ,
directSrcJars : [ ] string { "out/soong/.intermediates/direct/android_common/gen/android/R.srcjar" } ,
directClasspath : [ ] string {
"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar" ,
"out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar" ,
2024-03-23 05:43:41 +01:00
"out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.jar" ,
2023-06-21 07:40:02 +02:00
} ,
directCombined : [ ] string {
"out/soong/.intermediates/direct/android_common/javac/direct.jar" ,
"out/soong/.intermediates/transitive/android_common/javac/transitive.jar" ,
2024-03-23 05:43:41 +01:00
"out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar" ,
2023-06-21 07:40:02 +02:00
} ,
transitiveResources : [ ] string { "out/soong/.intermediates/transitive/android_common/aapt2/transitive/res/values_strings.arsc.flat" } ,
transitiveOverlays : nil ,
transitiveImports : [ ] string { "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk" } ,
transitiveSrcJars : nil ,
transitiveClasspath : [ ] string {
"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar" ,
"out/soong/.intermediates/transitive/android_common/busybox/R.jar" ,
} ,
transitiveCombined : nil ,
2023-10-13 00:58:57 +02:00
dontVerifyShared : true ,
2023-06-21 07:40:02 +02:00
dontVerifyDirectImport : true ,
dontVerifyTransitiveImport : true ,
2023-07-05 23:04:12 +02:00
} ,
}
for _ , testCase := range testCases {
t . Run ( testCase . name , func ( t * testing . T ) {
bp := fmt . Sprintf ( `
android_app {
name : "app" ,
sdk_version : "current" ,
srcs : [ "app/app.java" ] ,
resource_dirs : [ "app/res" ] ,
manifest : "app/AndroidManifest.xml" ,
2023-10-13 00:58:57 +02:00
libs : [ "shared" ] ,
2023-07-05 23:04:12 +02:00
static_libs : [ "direct" , "direct_import" ] ,
2023-06-21 07:40:02 +02:00
use_resource_processor : % v ,
2023-07-05 23:04:12 +02:00
}
android_library {
name : "direct" ,
sdk_version : "current" ,
srcs : [ "direct/direct.java" ] ,
resource_dirs : [ "direct/res" ] ,
manifest : "direct/AndroidManifest.xml" ,
static_libs : [ "transitive" , "transitive_import" ] ,
2023-06-21 07:40:02 +02:00
use_resource_processor : % v ,
2023-07-05 23:04:12 +02:00
}
android_library {
name : "transitive" ,
sdk_version : "current" ,
srcs : [ "transitive/transitive.java" ] ,
resource_dirs : [ "transitive/res" ] ,
manifest : "transitive/AndroidManifest.xml" ,
2023-06-21 07:40:02 +02:00
use_resource_processor : % v ,
2023-07-05 23:04:12 +02:00
}
2023-10-13 00:58:57 +02:00
android_library {
name : "shared" ,
sdk_version : "current" ,
srcs : [ "shared/shared.java" ] ,
resource_dirs : [ "shared/res" ] ,
manifest : "shared/AndroidManifest.xml" ,
use_resource_processor : % v ,
libs : [ "shared_transitive_shared" ] ,
static_libs : [ "shared_transitive_static" ] ,
}
android_library {
name : "shared_transitive_shared" ,
sdk_version : "current" ,
srcs : [ "shared_transitive_shared/shared_transitive_shared.java" ] ,
resource_dirs : [ "shared_transitive_shared/res" ] ,
manifest : "shared_transitive_shared/AndroidManifest.xml" ,
use_resource_processor : % v ,
}
android_library {
name : "shared_transitive_static" ,
sdk_version : "current" ,
srcs : [ "shared_transitive_static/shared.java" ] ,
resource_dirs : [ "shared_transitive_static/res" ] ,
manifest : "shared_transitive_static/AndroidManifest.xml" ,
use_resource_processor : % v ,
}
2023-07-05 23:04:12 +02:00
android_library_import {
name : "direct_import" ,
sdk_version : "current" ,
aars : [ "direct_import.aar" ] ,
static_libs : [ "direct_import_dep" ] ,
}
android_library_import {
name : "direct_import_dep" ,
sdk_version : "current" ,
aars : [ "direct_import_dep.aar" ] ,
}
android_library_import {
name : "transitive_import" ,
sdk_version : "current" ,
aars : [ "transitive_import.aar" ] ,
static_libs : [ "transitive_import_dep" ] ,
}
android_library_import {
name : "transitive_import_dep" ,
sdk_version : "current" ,
aars : [ "transitive_import_dep.aar" ] ,
}
2023-10-13 00:58:57 +02:00
` , testCase . appUsesRP , testCase . directLibUsesRP , testCase . transitiveLibUsesRP ,
testCase . sharedLibUsesRP , testCase . sharedTransitiveSharedLibUsesRP , testCase . sharedTransitiveStaticLibUsesRP )
2023-07-05 23:04:12 +02:00
fs := android . MockFS {
2023-10-13 00:58:57 +02:00
"app/res/values/strings.xml" : nil ,
"direct/res/values/strings.xml" : nil ,
"transitive/res/values/strings.xml" : nil ,
"shared/res/values/strings.xml" : nil ,
"shared_transitive_static/res/values/strings.xml" : nil ,
"shared_transitive_shared/res/values/strings.xml" : nil ,
2023-07-05 23:04:12 +02:00
}
result := android . GroupFixturePreparers (
PrepareForTestWithJavaDefaultModules ,
fs . AddToFixture ( ) ,
) . RunTestWithBp ( t , bp )
type aaptInfo struct {
resources , overlays , imports , srcJars , classpath , combined android . Paths
}
getAaptInfo := func ( moduleName string ) ( aaptInfo aaptInfo ) {
mod := result . ModuleForTests ( moduleName , "android_common" )
resourceListRule := mod . MaybeOutput ( "aapt2/res.list" )
overlayListRule := mod . MaybeOutput ( "aapt2/overlay.list" )
aaptRule := mod . Rule ( "aapt2Link" )
javacRule := mod . MaybeRule ( "javac" )
combinedRule := mod . MaybeOutput ( "combined/" + moduleName + ".jar" )
aaptInfo . resources = resourceListRule . Inputs
aaptInfo . overlays = overlayListRule . Inputs
aaptFlags := strings . Split ( aaptRule . Args [ "flags" ] , " " )
for i , flag := range aaptFlags {
if flag == "-I" && i + 1 < len ( aaptFlags ) {
aaptInfo . imports = append ( aaptInfo . imports , android . PathForTesting ( aaptFlags [ i + 1 ] ) )
}
}
if len ( javacRule . Args [ "srcJars" ] ) > 0 {
aaptInfo . srcJars = android . PathsForTesting ( strings . Split ( javacRule . Args [ "srcJars" ] , " " ) ... )
}
if len ( javacRule . Args [ "classpath" ] ) > 0 {
classpathArg := strings . TrimPrefix ( javacRule . Args [ "classpath" ] , "-classpath " )
aaptInfo . classpath = android . PathsForTesting ( strings . Split ( classpathArg , ":" ) ... )
}
aaptInfo . combined = combinedRule . Inputs
return
}
app := getAaptInfo ( "app" )
direct := getAaptInfo ( "direct" )
transitive := getAaptInfo ( "transitive" )
2023-10-13 00:58:57 +02:00
shared := getAaptInfo ( "shared" )
2023-07-05 23:04:12 +02:00
directImport := getAaptInfo ( "direct_import" )
transitiveImport := getAaptInfo ( "transitive_import" )
if ! testCase . dontVerifyApp {
android . AssertPathsRelativeToTopEquals ( t , "app resources" , testCase . appResources , app . resources )
android . AssertPathsRelativeToTopEquals ( t , "app overlays" , testCase . appOverlays , app . overlays )
android . AssertPathsRelativeToTopEquals ( t , "app imports" , testCase . appImports , app . imports )
android . AssertPathsRelativeToTopEquals ( t , "app srcjars" , testCase . appSrcJars , app . srcJars )
android . AssertPathsRelativeToTopEquals ( t , "app classpath" , testCase . appClasspath , app . classpath )
android . AssertPathsRelativeToTopEquals ( t , "app combined" , testCase . appCombined , app . combined )
}
if ! testCase . dontVerifyDirect {
android . AssertPathsRelativeToTopEquals ( t , "direct resources" , testCase . directResources , direct . resources )
android . AssertPathsRelativeToTopEquals ( t , "direct overlays" , testCase . directOverlays , direct . overlays )
android . AssertPathsRelativeToTopEquals ( t , "direct imports" , testCase . directImports , direct . imports )
android . AssertPathsRelativeToTopEquals ( t , "direct srcjars" , testCase . directSrcJars , direct . srcJars )
android . AssertPathsRelativeToTopEquals ( t , "direct classpath" , testCase . directClasspath , direct . classpath )
android . AssertPathsRelativeToTopEquals ( t , "direct combined" , testCase . directCombined , direct . combined )
}
if ! testCase . dontVerifyTransitive {
android . AssertPathsRelativeToTopEquals ( t , "transitive resources" , testCase . transitiveResources , transitive . resources )
android . AssertPathsRelativeToTopEquals ( t , "transitive overlays" , testCase . transitiveOverlays , transitive . overlays )
android . AssertPathsRelativeToTopEquals ( t , "transitive imports" , testCase . transitiveImports , transitive . imports )
android . AssertPathsRelativeToTopEquals ( t , "transitive srcjars" , testCase . transitiveSrcJars , transitive . srcJars )
android . AssertPathsRelativeToTopEquals ( t , "transitive classpath" , testCase . transitiveClasspath , transitive . classpath )
android . AssertPathsRelativeToTopEquals ( t , "transitive combined" , testCase . transitiveCombined , transitive . combined )
}
2023-10-13 00:58:57 +02:00
if ! testCase . dontVerifyShared {
android . AssertPathsRelativeToTopEquals ( t , "shared resources" , testCase . sharedResources , shared . resources )
android . AssertPathsRelativeToTopEquals ( t , "shared overlays" , testCase . sharedOverlays , shared . overlays )
android . AssertPathsRelativeToTopEquals ( t , "shared imports" , testCase . sharedImports , shared . imports )
android . AssertPathsRelativeToTopEquals ( t , "shared srcjars" , testCase . sharedSrcJars , shared . srcJars )
android . AssertPathsRelativeToTopEquals ( t , "shared classpath" , testCase . sharedClasspath , shared . classpath )
android . AssertPathsRelativeToTopEquals ( t , "shared combined" , testCase . sharedCombined , shared . combined )
}
2023-07-05 23:04:12 +02:00
if ! testCase . dontVerifyDirectImport {
android . AssertPathsRelativeToTopEquals ( t , "direct_import resources" , testCase . directImportResources , directImport . resources )
android . AssertPathsRelativeToTopEquals ( t , "direct_import overlays" , testCase . directImportOverlays , directImport . overlays )
android . AssertPathsRelativeToTopEquals ( t , "direct_import imports" , testCase . directImportImports , directImport . imports )
}
if ! testCase . dontVerifyTransitiveImport {
android . AssertPathsRelativeToTopEquals ( t , "transitive_import resources" , testCase . transitiveImportResources , transitiveImport . resources )
android . AssertPathsRelativeToTopEquals ( t , "transitive_import overlays" , testCase . transitiveImportOverlays , transitiveImport . overlays )
android . AssertPathsRelativeToTopEquals ( t , "transitive_import imports" , testCase . transitiveImportImports , transitiveImport . imports )
}
} )
}
}
func TestAndroidResourceOverlays ( t * testing . T ) {
2019-02-01 20:44:44 +01:00
testCases := [ ] struct {
name string
enforceRROTargets [ ] string
enforceRROExcludedOverlays [ ] string
2019-02-13 22:15:46 +01:00
resourceFiles map [ string ] [ ] string
2019-02-01 20:44:44 +01:00
overlayFiles map [ string ] [ ] string
rroDirs map [ string ] [ ] string
} {
{
name : "no RRO" ,
enforceRROTargets : nil ,
enforceRROExcludedOverlays : nil ,
2019-02-13 22:15:46 +01:00
resourceFiles : map [ string ] [ ] string {
"foo" : nil ,
"bar" : { "bar/res/res/values/strings.xml" } ,
"lib" : nil ,
"lib2" : { "lib2/res/res/values/strings.xml" } ,
} ,
2019-02-01 20:44:44 +01:00
overlayFiles : map [ string ] [ ] string {
2019-02-13 22:15:46 +01:00
"foo" : {
2021-03-22 18:31:52 +01:00
"out/soong/.intermediates/lib2/android_common/package-res.apk" ,
"out/soong/.intermediates/lib/android_common/package-res.apk" ,
"out/soong/.intermediates/lib3/android_common/package-res.apk" ,
2019-01-31 23:44:30 +01:00
"foo/res/res/values/strings.xml" ,
2019-02-01 20:44:44 +01:00
"device/vendor/blah/static_overlay/foo/res/values/strings.xml" ,
"device/vendor/blah/overlay/foo/res/values/strings.xml" ,
2019-03-18 16:53:16 +01:00
"product/vendor/blah/overlay/foo/res/values/strings.xml" ,
2019-02-01 20:44:44 +01:00
} ,
2019-02-13 22:15:46 +01:00
"bar" : {
2019-02-01 20:44:44 +01:00
"device/vendor/blah/static_overlay/bar/res/values/strings.xml" ,
"device/vendor/blah/overlay/bar/res/values/strings.xml" ,
} ,
2019-02-13 22:15:46 +01:00
"lib" : {
2021-03-22 18:31:52 +01:00
"out/soong/.intermediates/lib2/android_common/package-res.apk" ,
2019-02-13 22:15:46 +01:00
"lib/res/res/values/strings.xml" ,
"device/vendor/blah/overlay/lib/res/values/strings.xml" ,
} ,
2019-01-24 15:39:19 +01:00
} ,
2019-02-01 20:44:44 +01:00
rroDirs : map [ string ] [ ] string {
"foo" : nil ,
"bar" : nil ,
2019-01-24 15:39:19 +01:00
} ,
2017-12-01 05:13:19 +01:00
} ,
2019-02-01 20:44:44 +01:00
{
name : "enforce RRO on foo" ,
enforceRROTargets : [ ] string { "foo" } ,
enforceRROExcludedOverlays : [ ] string { "device/vendor/blah/static_overlay" } ,
2019-02-13 22:15:46 +01:00
resourceFiles : map [ string ] [ ] string {
"foo" : nil ,
"bar" : { "bar/res/res/values/strings.xml" } ,
"lib" : nil ,
"lib2" : { "lib2/res/res/values/strings.xml" } ,
} ,
2019-02-01 20:44:44 +01:00
overlayFiles : map [ string ] [ ] string {
2019-02-13 22:15:46 +01:00
"foo" : {
2021-03-22 18:31:52 +01:00
"out/soong/.intermediates/lib2/android_common/package-res.apk" ,
"out/soong/.intermediates/lib/android_common/package-res.apk" ,
"out/soong/.intermediates/lib3/android_common/package-res.apk" ,
2019-01-31 23:44:30 +01:00
"foo/res/res/values/strings.xml" ,
"device/vendor/blah/static_overlay/foo/res/values/strings.xml" ,
} ,
2019-02-13 22:15:46 +01:00
"bar" : {
2019-02-01 20:44:44 +01:00
"device/vendor/blah/static_overlay/bar/res/values/strings.xml" ,
"device/vendor/blah/overlay/bar/res/values/strings.xml" ,
} ,
2019-02-13 22:15:46 +01:00
"lib" : {
2021-03-22 18:31:52 +01:00
"out/soong/.intermediates/lib2/android_common/package-res.apk" ,
2019-02-13 22:15:46 +01:00
"lib/res/res/values/strings.xml" ,
} ,
2019-02-01 20:44:44 +01:00
} ,
2019-01-31 20:42:41 +01:00
2019-02-01 20:44:44 +01:00
rroDirs : map [ string ] [ ] string {
2019-02-13 22:15:46 +01:00
"foo" : {
2019-03-18 16:53:16 +01:00
"device:device/vendor/blah/overlay/foo/res" ,
"product:product/vendor/blah/overlay/foo/res" ,
2020-10-07 03:56:10 +02:00
"device:device/vendor/blah/overlay/lib/res" ,
2019-01-31 20:42:41 +01:00
} ,
2019-02-01 20:44:44 +01:00
"bar" : nil ,
2020-10-07 03:56:10 +02:00
"lib" : { "device:device/vendor/blah/overlay/lib/res" } ,
2019-01-24 15:39:19 +01:00
} ,
2017-12-01 05:13:19 +01:00
} ,
2019-02-01 20:44:44 +01:00
{
name : "enforce RRO on all" ,
enforceRROTargets : [ ] string { "*" } ,
enforceRROExcludedOverlays : [ ] string {
// Excluding specific apps/res directories also allowed.
"device/vendor/blah/static_overlay/foo" ,
"device/vendor/blah/static_overlay/bar/res" ,
} ,
2019-02-13 22:15:46 +01:00
resourceFiles : map [ string ] [ ] string {
"foo" : nil ,
"bar" : { "bar/res/res/values/strings.xml" } ,
"lib" : nil ,
"lib2" : { "lib2/res/res/values/strings.xml" } ,
} ,
2019-02-01 20:44:44 +01:00
overlayFiles : map [ string ] [ ] string {
2019-02-13 22:15:46 +01:00
"foo" : {
2021-03-22 18:31:52 +01:00
"out/soong/.intermediates/lib2/android_common/package-res.apk" ,
"out/soong/.intermediates/lib/android_common/package-res.apk" ,
"out/soong/.intermediates/lib3/android_common/package-res.apk" ,
2019-01-31 23:44:30 +01:00
"foo/res/res/values/strings.xml" ,
"device/vendor/blah/static_overlay/foo/res/values/strings.xml" ,
} ,
2019-02-13 22:15:46 +01:00
"bar" : { "device/vendor/blah/static_overlay/bar/res/values/strings.xml" } ,
"lib" : {
2021-03-22 18:31:52 +01:00
"out/soong/.intermediates/lib2/android_common/package-res.apk" ,
2019-02-13 22:15:46 +01:00
"lib/res/res/values/strings.xml" ,
} ,
2019-02-01 20:44:44 +01:00
} ,
rroDirs : map [ string ] [ ] string {
2019-02-13 22:15:46 +01:00
"foo" : {
2019-03-18 16:53:16 +01:00
"device:device/vendor/blah/overlay/foo/res" ,
"product:product/vendor/blah/overlay/foo/res" ,
// Lib dep comes after the direct deps
"device:device/vendor/blah/overlay/lib/res" ,
2019-01-31 20:42:41 +01:00
} ,
2019-03-18 16:53:16 +01:00
"bar" : { "device:device/vendor/blah/overlay/bar/res" } ,
"lib" : { "device:device/vendor/blah/overlay/lib/res" } ,
2019-02-01 20:44:44 +01:00
} ,
2017-12-01 05:13:19 +01:00
} ,
2019-02-01 20:44:44 +01:00
}
2017-12-01 05:13:19 +01:00
2019-03-18 16:53:16 +01:00
deviceResourceOverlays := [ ] string {
2017-12-01 05:13:19 +01:00
"device/vendor/blah/overlay" ,
"device/vendor/blah/overlay2" ,
"device/vendor/blah/static_overlay" ,
}
2019-03-18 16:53:16 +01:00
productResourceOverlays := [ ] string {
"product/vendor/blah/overlay" ,
}
2021-03-22 18:31:52 +01:00
fs := android . MockFS {
2017-12-01 05:13:19 +01:00
"foo/res/res/values/strings.xml" : nil ,
"bar/res/res/values/strings.xml" : nil ,
2019-01-31 23:44:30 +01:00
"lib/res/res/values/strings.xml" : nil ,
2019-02-13 22:15:46 +01:00
"lib2/res/res/values/strings.xml" : nil ,
2017-12-01 05:13:19 +01:00
"device/vendor/blah/overlay/foo/res/values/strings.xml" : nil ,
"device/vendor/blah/overlay/bar/res/values/strings.xml" : nil ,
2019-01-31 23:44:30 +01:00
"device/vendor/blah/overlay/lib/res/values/strings.xml" : nil ,
2017-12-01 05:13:19 +01:00
"device/vendor/blah/static_overlay/foo/res/values/strings.xml" : nil ,
"device/vendor/blah/static_overlay/bar/res/values/strings.xml" : nil ,
"device/vendor/blah/overlay2/res/values/strings.xml" : nil ,
2019-03-18 16:53:16 +01:00
"product/vendor/blah/overlay/foo/res/values/strings.xml" : nil ,
2017-12-01 05:13:19 +01:00
}
bp := `
android_app {
name : "foo" ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2017-12-01 05:13:19 +01:00
resource_dirs : [ "foo/res" ] ,
2019-03-18 16:53:16 +01:00
static_libs : [ "lib" , "lib3" ] ,
2017-12-01 05:13:19 +01:00
}
android_app {
name : "bar" ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2017-12-01 05:13:19 +01:00
resource_dirs : [ "bar/res" ] ,
}
2019-01-31 23:44:30 +01:00
android_library {
name : "lib" ,
2019-11-01 07:28:00 +01:00
sdk_version : "current" ,
2019-01-31 23:44:30 +01:00
resource_dirs : [ "lib/res" ] ,
2019-02-13 22:15:46 +01:00
static_libs : [ "lib2" ] ,
}
android_library {
name : "lib2" ,
2019-11-01 07:28:00 +01:00
sdk_version : "current" ,
2019-02-13 22:15:46 +01:00
resource_dirs : [ "lib2/res" ] ,
2019-01-31 23:44:30 +01:00
}
2019-03-18 16:53:16 +01:00
// This library has the same resources as lib (should not lead to dupe RROs)
android_library {
name : "lib3" ,
2019-11-01 07:28:00 +01:00
sdk_version : "current" ,
2019-03-18 16:53:16 +01:00
resource_dirs : [ "lib/res" ]
}
2017-12-01 05:13:19 +01:00
`
2019-02-01 20:44:44 +01:00
for _ , testCase := range testCases {
2017-12-01 05:13:19 +01:00
t . Run ( testCase . name , func ( t * testing . T ) {
2021-03-22 18:31:52 +01:00
result := android . GroupFixturePreparers (
PrepareForTestWithJavaDefaultModules ,
fs . AddToFixture ( ) ,
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
variables . DeviceResourceOverlays = deviceResourceOverlays
variables . ProductResourceOverlays = productResourceOverlays
if testCase . enforceRROTargets != nil {
variables . EnforceRROTargets = testCase . enforceRROTargets
}
if testCase . enforceRROExcludedOverlays != nil {
variables . EnforceRROExcludedOverlays = testCase . enforceRROExcludedOverlays
}
} ) ,
) . RunTestWithBp ( t , bp )
2017-12-01 05:13:19 +01:00
2019-02-13 22:15:46 +01:00
resourceListToFiles := func ( module android . TestingModule , list [ ] string ) ( files [ ] string ) {
for _ , o := range list {
res := module . MaybeOutput ( o )
if res . Rule != nil {
// If the overlay is compiled as part of this module (i.e. a .arsc.flat file),
// verify the inputs to the .arsc.flat rule.
files = append ( files , res . Inputs . Strings ( ) ... )
} else {
// Otherwise, verify the full path to the output of the other module
files = append ( files , o )
2019-01-30 17:03:37 +01:00
}
2017-12-01 05:13:19 +01:00
}
2019-02-13 22:15:46 +01:00
return files
}
getResources := func ( moduleName string ) ( resourceFiles , overlayFiles , rroDirs [ ] string ) {
2021-03-22 18:31:52 +01:00
module := result . ModuleForTests ( moduleName , "android_common" )
2019-02-13 22:15:46 +01:00
resourceList := module . MaybeOutput ( "aapt2/res.list" )
if resourceList . Rule != nil {
2021-03-22 18:31:52 +01:00
resourceFiles = resourceListToFiles ( module , android . PathsRelativeToTop ( resourceList . Inputs ) )
2019-02-13 22:15:46 +01:00
}
overlayList := module . MaybeOutput ( "aapt2/overlay.list" )
if overlayList . Rule != nil {
2021-03-22 18:31:52 +01:00
overlayFiles = resourceListToFiles ( module , android . PathsRelativeToTop ( overlayList . Inputs ) )
2019-02-13 22:15:46 +01:00
}
2017-12-01 05:13:19 +01:00
2023-07-14 19:23:41 +02:00
for _ , d := range module . Module ( ) . ( AndroidLibraryDependency ) . RRODirsDepSet ( ) . ToList ( ) {
2019-03-18 16:53:16 +01:00
var prefix string
if d . overlayType == device {
prefix = "device:"
} else if d . overlayType == product {
prefix = "product:"
} else {
t . Fatalf ( "Unexpected overlayType %d" , d . overlayType )
}
2021-03-22 18:31:52 +01:00
rroDirs = append ( rroDirs , prefix + android . PathRelativeToTop ( d . path ) )
2019-03-18 16:53:16 +01:00
}
2017-12-01 05:13:19 +01:00
2019-02-13 22:15:46 +01:00
return resourceFiles , overlayFiles , rroDirs
2017-12-01 05:13:19 +01:00
}
2019-02-13 22:15:46 +01:00
modules := [ ] string { "foo" , "bar" , "lib" , "lib2" }
for _ , module := range modules {
resourceFiles , overlayFiles , rroDirs := getResources ( module )
2017-12-01 05:13:19 +01:00
2019-02-13 22:15:46 +01:00
if ! reflect . DeepEqual ( resourceFiles , testCase . resourceFiles [ module ] ) {
t . Errorf ( "expected %s resource files:\n %#v\n got:\n %#v" ,
module , testCase . resourceFiles [ module ] , resourceFiles )
}
if ! reflect . DeepEqual ( overlayFiles , testCase . overlayFiles [ module ] ) {
2019-01-24 15:39:19 +01:00
t . Errorf ( "expected %s overlay files:\n %#v\n got:\n %#v" ,
2019-02-13 22:15:46 +01:00
module , testCase . overlayFiles [ module ] , overlayFiles )
2019-01-24 15:39:19 +01:00
}
2019-02-13 22:15:46 +01:00
if ! reflect . DeepEqual ( rroDirs , testCase . rroDirs [ module ] ) {
2019-01-24 15:39:19 +01:00
t . Errorf ( "expected %s rroDirs: %#v\n got:\n %#v" ,
2019-02-13 22:15:46 +01:00
module , testCase . rroDirs [ module ] , rroDirs )
2019-01-24 15:39:19 +01:00
}
2017-12-01 05:13:19 +01:00
}
} )
}
}
2018-04-18 20:06:47 +02:00
2021-03-14 01:36:50 +01:00
func checkSdkVersion ( t * testing . T , result * android . TestResult , expectedSdkVersion string ) {
foo := result . ModuleForTests ( "foo" , "android_common" )
2020-08-06 16:00:37 +02:00
link := foo . Output ( "package-res.apk" )
linkFlags := strings . Split ( link . Args [ "flags" ] , " " )
min := android . IndexList ( "--min-sdk-version" , linkFlags )
target := android . IndexList ( "--target-sdk-version" , linkFlags )
if min == - 1 || target == - 1 || min == len ( linkFlags ) - 1 || target == len ( linkFlags ) - 1 {
t . Fatalf ( "missing --min-sdk-version or --target-sdk-version in link flags: %q" , linkFlags )
}
gotMinSdkVersion := linkFlags [ min + 1 ]
gotTargetSdkVersion := linkFlags [ target + 1 ]
2021-03-14 01:36:50 +01:00
android . AssertStringEquals ( t , "incorrect --min-sdk-version" , expectedSdkVersion , gotMinSdkVersion )
2020-08-06 16:00:37 +02:00
2021-03-14 01:36:50 +01:00
android . AssertStringEquals ( t , "incorrect --target-sdk-version" , expectedSdkVersion , gotTargetSdkVersion )
2020-08-06 16:00:37 +02:00
}
2018-04-18 20:06:47 +02:00
func TestAppSdkVersion ( t * testing . T ) {
testCases := [ ] struct {
name string
sdkVersion string
platformSdkInt int
platformSdkCodename string
platformSdkFinal bool
2023-03-01 20:46:18 +01:00
minSdkVersionBp string
2018-04-18 20:06:47 +02:00
expectedMinSdkVersion string
2019-07-11 08:54:27 +02:00
platformApis bool
2020-07-24 02:32:15 +02:00
activeCodenames [ ] string
2018-04-18 20:06:47 +02:00
} {
{
name : "current final SDK" ,
sdkVersion : "current" ,
platformSdkInt : 27 ,
platformSdkCodename : "REL" ,
platformSdkFinal : true ,
expectedMinSdkVersion : "27" ,
} ,
{
name : "current non-final SDK" ,
sdkVersion : "current" ,
platformSdkInt : 27 ,
platformSdkCodename : "OMR1" ,
platformSdkFinal : false ,
expectedMinSdkVersion : "OMR1" ,
2020-07-24 02:32:15 +02:00
activeCodenames : [ ] string { "OMR1" } ,
2018-04-18 20:06:47 +02:00
} ,
{
name : "default final SDK" ,
sdkVersion : "" ,
2019-07-11 08:54:27 +02:00
platformApis : true ,
2018-04-18 20:06:47 +02:00
platformSdkInt : 27 ,
platformSdkCodename : "REL" ,
platformSdkFinal : true ,
expectedMinSdkVersion : "27" ,
} ,
{
name : "default non-final SDK" ,
sdkVersion : "" ,
2019-07-11 08:54:27 +02:00
platformApis : true ,
2018-04-18 20:06:47 +02:00
platformSdkInt : 27 ,
platformSdkCodename : "OMR1" ,
platformSdkFinal : false ,
expectedMinSdkVersion : "OMR1" ,
2020-07-24 02:32:15 +02:00
activeCodenames : [ ] string { "OMR1" } ,
2018-04-18 20:06:47 +02:00
} ,
{
name : "14" ,
sdkVersion : "14" ,
expectedMinSdkVersion : "14" ,
2020-07-24 02:32:15 +02:00
platformSdkCodename : "S" ,
activeCodenames : [ ] string { "S" } ,
2018-04-18 20:06:47 +02:00
} ,
2023-03-01 20:46:18 +01:00
{
name : "two active SDKs" ,
sdkVersion : "module_current" ,
minSdkVersionBp : "UpsideDownCake" ,
expectedMinSdkVersion : "UpsideDownCake" , // And not VanillaIceCream
platformSdkCodename : "VanillaIceCream" ,
activeCodenames : [ ] string { "UpsideDownCake" , "VanillaIceCream" } ,
} ,
2018-04-18 20:06:47 +02:00
}
for _ , moduleType := range [ ] string { "android_app" , "android_library" } {
for _ , test := range testCases {
t . Run ( moduleType + " " + test . name , func ( t * testing . T ) {
2019-07-11 08:54:27 +02:00
platformApiProp := ""
if test . platformApis {
platformApiProp = "platform_apis: true,"
}
2023-03-01 20:46:18 +01:00
minSdkVersionProp := ""
if test . minSdkVersionBp != "" {
minSdkVersionProp = fmt . Sprintf ( ` min_sdk_version: "%s", ` , test . minSdkVersionBp )
}
2018-04-18 20:06:47 +02:00
bp := fmt . Sprintf ( ` % s {
name : "foo" ,
srcs : [ "a.java" ] ,
sdk_version : "%s" ,
2019-07-11 08:54:27 +02:00
% s
2023-03-01 20:46:18 +01:00
% s
} ` , moduleType , test . sdkVersion , platformApiProp , minSdkVersionProp )
2018-04-18 20:06:47 +02:00
2021-03-22 16:36:52 +01:00
result := android . GroupFixturePreparers (
prepareForJavaTest ,
2021-03-14 01:36:50 +01:00
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
variables . Platform_sdk_version = & test . platformSdkInt
variables . Platform_sdk_codename = & test . platformSdkCodename
variables . Platform_version_active_codenames = test . activeCodenames
variables . Platform_sdk_final = & test . platformSdkFinal
} ) ,
2021-03-13 03:36:00 +01:00
FixtureWithPrebuiltApis ( map [ string ] [ ] string {
"14" : { "foo" } ,
} ) ,
2021-03-14 01:36:50 +01:00
) . RunTestWithBp ( t , bp )
2018-04-18 20:06:47 +02:00
2021-03-14 01:36:50 +01:00
checkSdkVersion ( t , result , test . expectedMinSdkVersion )
2020-08-06 16:00:37 +02:00
} )
}
}
}
2018-04-18 20:06:47 +02:00
2020-08-06 16:00:37 +02:00
func TestVendorAppSdkVersion ( t * testing . T ) {
testCases := [ ] struct {
name string
sdkVersion string
platformSdkInt int
platformSdkCodename string
platformSdkFinal bool
deviceCurrentApiLevelForVendorModules string
expectedMinSdkVersion string
} {
{
name : "current final SDK" ,
sdkVersion : "current" ,
platformSdkInt : 29 ,
platformSdkCodename : "REL" ,
platformSdkFinal : true ,
deviceCurrentApiLevelForVendorModules : "29" ,
expectedMinSdkVersion : "29" ,
} ,
{
name : "current final SDK" ,
sdkVersion : "current" ,
platformSdkInt : 29 ,
platformSdkCodename : "REL" ,
platformSdkFinal : true ,
deviceCurrentApiLevelForVendorModules : "28" ,
expectedMinSdkVersion : "28" ,
} ,
{
name : "current final SDK" ,
sdkVersion : "current" ,
platformSdkInt : 29 ,
platformSdkCodename : "Q" ,
platformSdkFinal : false ,
deviceCurrentApiLevelForVendorModules : "28" ,
expectedMinSdkVersion : "28" ,
} ,
}
2018-04-18 20:06:47 +02:00
2020-08-06 16:00:37 +02:00
for _ , moduleType := range [ ] string { "android_app" , "android_library" } {
for _ , sdkKind := range [ ] string { "" , "system_" } {
for _ , test := range testCases {
t . Run ( moduleType + " " + test . name , func ( t * testing . T ) {
bp := fmt . Sprintf ( ` % s {
name : "foo" ,
srcs : [ "a.java" ] ,
sdk_version : "%s%s" ,
vendor : true ,
} ` , moduleType , sdkKind , test . sdkVersion )
2021-03-22 16:36:52 +01:00
result := android . GroupFixturePreparers (
prepareForJavaTest ,
2021-03-14 01:36:50 +01:00
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
variables . Platform_sdk_version = & test . platformSdkInt
variables . Platform_sdk_codename = & test . platformSdkCodename
variables . Platform_sdk_final = & test . platformSdkFinal
variables . DeviceCurrentApiLevelForVendorModules = & test . deviceCurrentApiLevelForVendorModules
variables . DeviceSystemSdkVersions = [ ] string { "28" , "29" }
} ) ,
2021-03-13 03:36:00 +01:00
FixtureWithPrebuiltApis ( map [ string ] [ ] string {
"28" : { "foo" } ,
"29" : { "foo" } ,
"current" : { "foo" } ,
} ) ,
2021-03-14 01:36:50 +01:00
) . RunTestWithBp ( t , bp )
checkSdkVersion ( t , result , test . expectedMinSdkVersion )
2020-08-06 16:00:37 +02:00
} )
}
2018-04-18 20:06:47 +02:00
}
}
}
2018-10-03 07:03:40 +02:00
2019-06-12 14:25:22 +02:00
func TestJNIABI ( t * testing . T ) {
2019-07-17 20:15:09 +02:00
ctx , _ := testJava ( t , cc . GatherRequiredDepsForTest ( android . Android ) + `
2019-06-12 14:25:22 +02:00
cc_library {
name : "libjni" ,
system_shared_libs : [ ] ,
2020-04-07 18:50:32 +02:00
sdk_version : "current" ,
2019-06-12 14:25:22 +02:00
stl : "none" ,
}
android_test {
name : "test" ,
sdk_version : "core_platform" ,
jni_libs : [ "libjni" ] ,
}
android_test {
name : "test_first" ,
sdk_version : "core_platform" ,
compile_multilib : "first" ,
jni_libs : [ "libjni" ] ,
}
android_test {
name : "test_both" ,
sdk_version : "core_platform" ,
compile_multilib : "both" ,
jni_libs : [ "libjni" ] ,
}
android_test {
name : "test_32" ,
sdk_version : "core_platform" ,
compile_multilib : "32" ,
jni_libs : [ "libjni" ] ,
}
android_test {
name : "test_64" ,
sdk_version : "core_platform" ,
compile_multilib : "64" ,
jni_libs : [ "libjni" ] ,
}
` )
testCases := [ ] struct {
name string
abis [ ] string
} {
{ "test" , [ ] string { "arm64-v8a" } } ,
{ "test_first" , [ ] string { "arm64-v8a" } } ,
{ "test_both" , [ ] string { "arm64-v8a" , "armeabi-v7a" } } ,
{ "test_32" , [ ] string { "armeabi-v7a" } } ,
{ "test_64" , [ ] string { "arm64-v8a" } } ,
}
for _ , test := range testCases {
t . Run ( test . name , func ( t * testing . T ) {
app := ctx . ModuleForTests ( test . name , "android_common" )
2023-07-27 01:14:56 +02:00
jniLibZip := app . Output ( "jnilibs.zip" )
2019-06-12 14:25:22 +02:00
var abis [ ] string
args := strings . Fields ( jniLibZip . Args [ "jarArgs" ] )
for i := 0 ; i < len ( args ) ; i ++ {
if args [ i ] == "-P" {
abis = append ( abis , filepath . Base ( args [ i + 1 ] ) )
i ++
}
}
if ! reflect . DeepEqual ( abis , test . abis ) {
t . Errorf ( "want abis %v, got %v" , test . abis , abis )
}
} )
}
}
2019-10-29 07:44:45 +01:00
func TestAppSdkVersionByPartition ( t * testing . T ) {
testJavaError ( t , "sdk_version must have a value when the module is located at vendor or product" , `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
vendor : true ,
platform_apis : true ,
}
` )
testJava ( t , `
android_app {
name : "bar" ,
srcs : [ "b.java" ] ,
platform_apis : true ,
}
` )
for _ , enforce := range [ ] bool { true , false } {
bp := `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
product_specific : true ,
platform_apis : true ,
}
`
2019-12-14 05:41:13 +01:00
2021-03-22 18:31:52 +01:00
errorHandler := android . FixtureExpectsNoErrors
2019-10-29 07:44:45 +01:00
if enforce {
2021-03-22 18:31:52 +01:00
errorHandler = android . FixtureExpectsAtLeastOneErrorMatchingPattern ( "sdk_version must have a value when the module is located at vendor or product" )
2019-10-29 07:44:45 +01:00
}
2021-03-22 18:31:52 +01:00
android . GroupFixturePreparers (
PrepareForTestWithJavaDefaultModules ,
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
variables . EnforceProductPartitionInterface = proptools . BoolPtr ( enforce )
} ) ,
) .
ExtendWithErrorHandler ( errorHandler ) .
RunTestWithBp ( t , bp )
2019-10-29 07:44:45 +01:00
}
}
2019-06-12 14:25:22 +02:00
func TestJNIPackaging ( t * testing . T ) {
2019-07-17 20:15:09 +02:00
ctx , _ := testJava ( t , cc . GatherRequiredDepsForTest ( android . Android ) + `
2019-06-12 14:25:22 +02:00
cc_library {
name : "libjni" ,
system_shared_libs : [ ] ,
stl : "none" ,
2020-02-15 19:38:00 +01:00
sdk_version : "current" ,
2019-06-12 14:25:22 +02:00
}
android_app {
name : "app" ,
jni_libs : [ "libjni" ] ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-06-12 14:25:22 +02:00
}
android_app {
name : "app_noembed" ,
jni_libs : [ "libjni" ] ,
use_embedded_native_libs : false ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-06-12 14:25:22 +02:00
}
android_app {
name : "app_embed" ,
jni_libs : [ "libjni" ] ,
use_embedded_native_libs : true ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-06-12 14:25:22 +02:00
}
android_test {
name : "test" ,
2020-04-07 18:50:32 +02:00
sdk_version : "current" ,
2019-06-12 14:25:22 +02:00
jni_libs : [ "libjni" ] ,
}
android_test {
name : "test_noembed" ,
2020-04-07 18:50:32 +02:00
sdk_version : "current" ,
2019-06-12 14:25:22 +02:00
jni_libs : [ "libjni" ] ,
use_embedded_native_libs : false ,
}
android_test_helper_app {
name : "test_helper" ,
2020-04-07 18:50:32 +02:00
sdk_version : "current" ,
2019-06-12 14:25:22 +02:00
jni_libs : [ "libjni" ] ,
}
android_test_helper_app {
name : "test_helper_noembed" ,
2020-04-07 18:50:32 +02:00
sdk_version : "current" ,
2019-06-12 14:25:22 +02:00
jni_libs : [ "libjni" ] ,
use_embedded_native_libs : false ,
}
` )
testCases := [ ] struct {
name string
packaged bool
compressed bool
} {
2024-05-14 19:09:54 +02:00
{ "app" , false , false } ,
{ "app_noembed" , false , false } ,
2019-06-12 14:25:22 +02:00
{ "app_embed" , true , false } ,
{ "test" , true , false } ,
{ "test_noembed" , true , true } ,
{ "test_helper" , true , false } ,
{ "test_helper_noembed" , true , true } ,
}
for _ , test := range testCases {
t . Run ( test . name , func ( t * testing . T ) {
app := ctx . ModuleForTests ( test . name , "android_common" )
2023-07-27 01:14:56 +02:00
jniLibZip := app . MaybeOutput ( "jnilibs.zip" )
2019-06-12 14:25:22 +02:00
if g , w := ( jniLibZip . Rule != nil ) , test . packaged ; g != w {
t . Errorf ( "expected jni packaged %v, got %v" , w , g )
}
2019-03-26 18:51:39 +01:00
2019-06-12 14:25:22 +02:00
if jniLibZip . Rule != nil {
if g , w := ! strings . Contains ( jniLibZip . Args [ "jarArgs" ] , "-L 0" ) , test . compressed ; g != w {
t . Errorf ( "expected jni compressed %v, got %v" , w , g )
}
2020-04-07 18:50:32 +02:00
if ! strings . Contains ( jniLibZip . Implicits [ 0 ] . String ( ) , "_sdk_" ) {
t . Errorf ( "expected input %q to use sdk variant" , jniLibZip . Implicits [ 0 ] . String ( ) )
}
2019-06-12 14:25:22 +02:00
}
} )
}
2019-03-26 18:51:39 +01:00
}
2020-05-08 20:20:24 +02:00
func TestJNISDK ( t * testing . T ) {
ctx , _ := testJava ( t , cc . GatherRequiredDepsForTest ( android . Android ) + `
cc_library {
name : "libjni" ,
system_shared_libs : [ ] ,
stl : "none" ,
sdk_version : "current" ,
}
android_test {
name : "app_platform" ,
jni_libs : [ "libjni" ] ,
platform_apis : true ,
}
android_test {
name : "app_sdk" ,
jni_libs : [ "libjni" ] ,
sdk_version : "current" ,
}
android_test {
name : "app_force_platform" ,
jni_libs : [ "libjni" ] ,
sdk_version : "current" ,
jni_uses_platform_apis : true ,
}
android_test {
name : "app_force_sdk" ,
jni_libs : [ "libjni" ] ,
platform_apis : true ,
jni_uses_sdk_apis : true ,
}
2020-05-13 20:05:02 +02:00
cc_library {
name : "libvendorjni" ,
system_shared_libs : [ ] ,
stl : "none" ,
vendor : true ,
}
android_test {
name : "app_vendor" ,
jni_libs : [ "libvendorjni" ] ,
sdk_version : "current" ,
vendor : true ,
}
2020-05-08 20:20:24 +02:00
` )
testCases := [ ] struct {
2020-05-13 20:05:02 +02:00
name string
sdkJNI bool
vendorJNI bool
2020-05-08 20:20:24 +02:00
} {
2020-05-13 20:05:02 +02:00
{ name : "app_platform" } ,
{ name : "app_sdk" , sdkJNI : true } ,
{ name : "app_force_platform" } ,
{ name : "app_force_sdk" , sdkJNI : true } ,
{ name : "app_vendor" , vendorJNI : true } ,
2020-05-08 20:20:24 +02:00
}
2020-05-13 20:05:02 +02:00
platformJNI := ctx . ModuleForTests ( "libjni" , "android_arm64_armv8-a_shared" ) .
Output ( "libjni.so" ) . Output . String ( )
sdkJNI := ctx . ModuleForTests ( "libjni" , "android_arm64_armv8-a_sdk_shared" ) .
Output ( "libjni.so" ) . Output . String ( )
2024-01-03 06:24:34 +01:00
vendorJNI := ctx . ModuleForTests ( "libvendorjni" , "android_vendor_arm64_armv8-a_shared" ) .
2020-05-13 20:05:02 +02:00
Output ( "libvendorjni.so" ) . Output . String ( )
2020-05-08 20:20:24 +02:00
for _ , test := range testCases {
t . Run ( test . name , func ( t * testing . T ) {
app := ctx . ModuleForTests ( test . name , "android_common" )
2023-07-27 01:14:56 +02:00
jniLibZip := app . MaybeOutput ( "jnilibs.zip" )
2020-05-08 20:20:24 +02:00
if len ( jniLibZip . Implicits ) != 1 {
t . Fatalf ( "expected exactly one jni library, got %q" , jniLibZip . Implicits . Strings ( ) )
}
gotJNI := jniLibZip . Implicits [ 0 ] . String ( )
if test . sdkJNI {
if gotJNI != sdkJNI {
t . Errorf ( "expected SDK JNI library %q, got %q" , sdkJNI , gotJNI )
}
2020-05-13 20:05:02 +02:00
} else if test . vendorJNI {
if gotJNI != vendorJNI {
t . Errorf ( "expected platform JNI library %q, got %q" , vendorJNI , gotJNI )
}
2020-05-08 20:20:24 +02:00
} else {
if gotJNI != platformJNI {
t . Errorf ( "expected platform JNI library %q, got %q" , platformJNI , gotJNI )
}
}
} )
}
t . Run ( "jni_uses_platform_apis_error" , func ( t * testing . T ) {
testJavaError ( t , ` jni_uses_platform_apis: can only be set for modules that set sdk_version ` , `
android_test {
name : "app_platform" ,
platform_apis : true ,
jni_uses_platform_apis : true ,
}
` )
} )
t . Run ( "jni_uses_sdk_apis_error" , func ( t * testing . T ) {
testJavaError ( t , ` jni_uses_sdk_apis: can only be set for modules that do not set sdk_version ` , `
android_test {
name : "app_sdk" ,
sdk_version : "current" ,
jni_uses_sdk_apis : true ,
}
` )
} )
}
2019-01-18 23:27:16 +01:00
func TestCertificates ( t * testing . T ) {
testCases := [ ] struct {
2021-11-03 15:39:39 +01:00
name string
bp string
2022-12-13 00:11:46 +01:00
allowMissingDependencies bool
2021-11-03 15:39:39 +01:00
certificateOverride string
expectedCertSigningFlags string
expectedCertificate string
2019-01-18 23:27:16 +01:00
} {
{
name : "default" ,
bp : `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-01-18 23:27:16 +01:00
}
` ,
2021-11-03 15:39:39 +01:00
certificateOverride : "" ,
expectedCertSigningFlags : "" ,
2022-12-13 00:11:46 +01:00
expectedCertificate : "build/make/target/product/security/testkey" ,
2019-01-18 23:27:16 +01:00
} ,
{
name : "module certificate property" ,
bp : `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
2019-07-11 08:54:27 +02:00
certificate : ":new_certificate" ,
sdk_version : "current" ,
2019-01-18 23:27:16 +01:00
}
android_app_certificate {
name : "new_certificate" ,
2020-05-08 20:20:24 +02:00
certificate : "cert/new_cert" ,
2019-01-18 23:27:16 +01:00
}
` ,
2021-11-03 15:39:39 +01:00
certificateOverride : "" ,
expectedCertSigningFlags : "" ,
2022-12-13 00:11:46 +01:00
expectedCertificate : "cert/new_cert" ,
2019-01-18 23:27:16 +01:00
} ,
{
name : "path certificate property" ,
bp : `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
2019-07-11 08:54:27 +02:00
certificate : "expiredkey" ,
sdk_version : "current" ,
2019-01-18 23:27:16 +01:00
}
` ,
2021-11-03 15:39:39 +01:00
certificateOverride : "" ,
expectedCertSigningFlags : "" ,
2022-12-13 00:11:46 +01:00
expectedCertificate : "build/make/target/product/security/expiredkey" ,
2019-01-18 23:27:16 +01:00
} ,
{
name : "certificate overrides" ,
bp : `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
2019-07-11 08:54:27 +02:00
certificate : "expiredkey" ,
sdk_version : "current" ,
2019-01-18 23:27:16 +01:00
}
android_app_certificate {
name : "new_certificate" ,
2020-05-08 20:20:24 +02:00
certificate : "cert/new_cert" ,
2019-01-18 23:27:16 +01:00
}
` ,
2021-11-03 15:39:39 +01:00
certificateOverride : "foo:new_certificate" ,
expectedCertSigningFlags : "" ,
2022-12-13 00:11:46 +01:00
expectedCertificate : "cert/new_cert" ,
2020-05-07 22:24:05 +02:00
} ,
{
2021-11-03 15:39:39 +01:00
name : "certificate signing flags" ,
2020-05-07 22:24:05 +02:00
bp : `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
certificate : ":new_certificate" ,
lineage : "lineage.bin" ,
2021-11-03 15:39:39 +01:00
rotationMinSdkVersion : "32" ,
2020-05-07 22:24:05 +02:00
sdk_version : "current" ,
}
android_app_certificate {
name : "new_certificate" ,
certificate : "cert/new_cert" ,
}
` ,
2021-11-03 15:39:39 +01:00
certificateOverride : "" ,
expectedCertSigningFlags : "--lineage lineage.bin --rotation-min-sdk-version 32" ,
2022-12-13 00:11:46 +01:00
expectedCertificate : "cert/new_cert" ,
2019-01-18 23:27:16 +01:00
} ,
2021-03-10 00:02:31 +01:00
{
2021-11-03 15:39:39 +01:00
name : "cert signing flags from filegroup" ,
2021-03-10 00:02:31 +01:00
bp : `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
certificate : ":new_certificate" ,
lineage : ":lineage_bin" ,
2021-11-03 15:39:39 +01:00
rotationMinSdkVersion : "32" ,
2021-03-10 00:02:31 +01:00
sdk_version : "current" ,
}
android_app_certificate {
name : "new_certificate" ,
certificate : "cert/new_cert" ,
}
filegroup {
name : "lineage_bin" ,
srcs : [ "lineage.bin" ] ,
}
` ,
2021-11-03 15:39:39 +01:00
certificateOverride : "" ,
expectedCertSigningFlags : "--lineage lineage.bin --rotation-min-sdk-version 32" ,
2022-12-13 00:11:46 +01:00
expectedCertificate : "cert/new_cert" ,
} ,
{
name : "missing with AllowMissingDependencies" ,
bp : `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
certificate : ":new_certificate" ,
sdk_version : "current" ,
}
` ,
expectedCertificate : "out/soong/.intermediates/foo/android_common/missing" ,
allowMissingDependencies : true ,
2021-03-10 00:02:31 +01:00
} ,
2019-01-18 23:27:16 +01:00
}
for _ , test := range testCases {
t . Run ( test . name , func ( t * testing . T ) {
2021-03-22 18:31:52 +01:00
result := android . GroupFixturePreparers (
PrepareForTestWithJavaDefaultModules ,
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
if test . certificateOverride != "" {
variables . CertificateOverrides = [ ] string { test . certificateOverride }
}
2022-12-13 00:11:46 +01:00
if test . allowMissingDependencies {
variables . Allow_missing_dependencies = proptools . BoolPtr ( true )
}
} ) ,
android . FixtureModifyContext ( func ( ctx * android . TestContext ) {
ctx . SetAllowMissingDependencies ( test . allowMissingDependencies )
2021-03-22 18:31:52 +01:00
} ) ,
) . RunTestWithBp ( t , test . bp )
2019-01-18 23:27:16 +01:00
2021-03-22 18:31:52 +01:00
foo := result . ModuleForTests ( "foo" , "android_common" )
2019-01-18 23:27:16 +01:00
2022-12-13 00:11:46 +01:00
certificate := foo . Module ( ) . ( * AndroidApp ) . certificate
android . AssertPathRelativeToTopEquals ( t , "certificates key" , test . expectedCertificate + ".pk8" , certificate . Key )
// The sign_target_files_apks and check_target_files_signatures
// tools require that certificates have a .x509.pem extension.
android . AssertPathRelativeToTopEquals ( t , "certificates pem" , test . expectedCertificate + ".x509.pem" , certificate . Pem )
2019-01-18 23:27:16 +01:00
signapk := foo . Output ( "foo.apk" )
2022-12-13 00:11:46 +01:00
if signapk . Rule != android . ErrorRule {
signCertificateFlags := signapk . Args [ "certificates" ]
expectedFlags := certificate . Pem . String ( ) + " " + certificate . Key . String ( )
android . AssertStringEquals ( t , "certificates flags" , expectedFlags , signCertificateFlags )
2020-05-07 22:24:05 +02:00
2022-12-13 00:11:46 +01:00
certSigningFlags := signapk . Args [ "flags" ]
android . AssertStringEquals ( t , "cert signing flags" , test . expectedCertSigningFlags , certSigningFlags )
}
2019-01-18 23:27:16 +01:00
} )
}
}
2019-01-24 01:27:47 +01:00
2020-03-25 04:32:24 +01:00
func TestRequestV4SigningFlag ( t * testing . T ) {
testCases := [ ] struct {
name string
bp string
expected string
} {
{
name : "default" ,
bp : `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
sdk_version : "current" ,
}
` ,
expected : "" ,
} ,
{
name : "default" ,
bp : `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
sdk_version : "current" ,
v4_signature : false ,
}
` ,
expected : "" ,
} ,
{
name : "module certificate property" ,
bp : `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
sdk_version : "current" ,
v4_signature : true ,
}
` ,
expected : "--enable-v4" ,
} ,
}
for _ , test := range testCases {
t . Run ( test . name , func ( t * testing . T ) {
2021-03-22 18:31:52 +01:00
result := android . GroupFixturePreparers (
PrepareForTestWithJavaDefaultModules ,
) . RunTestWithBp ( t , test . bp )
2020-03-25 04:32:24 +01:00
2021-03-22 18:31:52 +01:00
foo := result . ModuleForTests ( "foo" , "android_common" )
2020-03-25 04:32:24 +01:00
signapk := foo . Output ( "foo.apk" )
signFlags := signapk . Args [ "flags" ]
2021-03-22 18:31:52 +01:00
android . AssertStringEquals ( t , "signing flags" , test . expected , signFlags )
2020-03-25 04:32:24 +01:00
} )
}
}
2019-01-24 01:27:47 +01:00
func TestPackageNameOverride ( t * testing . T ) {
testCases := [ ] struct {
name string
bp string
packageNameOverride string
expected [ ] string
} {
{
name : "default" ,
bp : `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-01-24 01:27:47 +01:00
}
` ,
packageNameOverride : "" ,
expected : [ ] string {
2021-03-22 18:31:52 +01:00
"out/soong/.intermediates/foo/android_common/foo.apk" ,
"out/soong/target/product/test_device/system/app/foo/foo.apk" ,
2019-01-24 01:27:47 +01:00
} ,
} ,
{
2022-01-08 04:13:59 +01:00
name : "overridden via PRODUCT_PACKAGE_NAME_OVERRIDES" ,
2019-01-24 01:27:47 +01:00
bp : `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-01-24 01:27:47 +01:00
}
` ,
packageNameOverride : "foo:bar" ,
expected : [ ] string {
// The package apk should be still be the original name for test dependencies.
2021-03-22 18:31:52 +01:00
"out/soong/.intermediates/foo/android_common/bar.apk" ,
"out/soong/target/product/test_device/system/app/bar/bar.apk" ,
2019-01-24 01:27:47 +01:00
} ,
} ,
2022-01-08 04:13:59 +01:00
{
name : "overridden via stem" ,
bp : `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
sdk_version : "current" ,
stem : "bar" ,
}
` ,
packageNameOverride : "" ,
expected : [ ] string {
"out/soong/.intermediates/foo/android_common/bar.apk" ,
"out/soong/target/product/test_device/system/app/bar/bar.apk" ,
} ,
} ,
2019-01-24 01:27:47 +01:00
}
for _ , test := range testCases {
t . Run ( test . name , func ( t * testing . T ) {
2021-03-22 18:31:52 +01:00
result := android . GroupFixturePreparers (
PrepareForTestWithJavaDefaultModules ,
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
if test . packageNameOverride != "" {
variables . PackageNameOverrides = [ ] string { test . packageNameOverride }
}
} ) ,
) . RunTestWithBp ( t , test . bp )
2019-01-24 01:27:47 +01:00
2021-03-22 18:31:52 +01:00
foo := result . ModuleForTests ( "foo" , "android_common" )
2021-08-19 09:36:42 +02:00
outSoongDir := result . Config . SoongOutDir ( )
2019-01-24 01:27:47 +01:00
outputs := foo . AllOutputs ( )
outputMap := make ( map [ string ] bool )
for _ , o := range outputs {
2021-03-22 18:31:52 +01:00
outputMap [ android . StringPathRelativeToTop ( outSoongDir , o ) ] = true
2019-01-24 01:27:47 +01:00
}
for _ , e := range test . expected {
if _ , exist := outputMap [ e ] ; ! exist {
t . Errorf ( "Can't find %q in output files.\nAll outputs:%v" , e , outputs )
}
}
} )
}
}
2019-02-28 01:26:28 +01:00
func TestInstrumentationTargetOverridden ( t * testing . T ) {
bp := `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-02-28 01:26:28 +01:00
}
android_test {
name : "bar" ,
instrumentation_for : "foo" ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-02-28 01:26:28 +01:00
}
`
2021-03-22 18:31:52 +01:00
result := android . GroupFixturePreparers (
PrepareForTestWithJavaDefaultModules ,
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
variables . ManifestPackageNameOverrides = [ ] string { "foo:org.dandroid.bp" }
} ) ,
) . RunTestWithBp ( t , bp )
2019-02-28 01:26:28 +01:00
2021-03-22 18:31:52 +01:00
bar := result . ModuleForTests ( "bar" , "android_common" )
2019-02-28 01:26:28 +01:00
res := bar . Output ( "package-res.apk" )
aapt2Flags := res . Args [ "flags" ]
e := "--rename-instrumentation-target-package org.dandroid.bp"
if ! strings . Contains ( aapt2Flags , e ) {
t . Errorf ( "target package renaming flag, %q is missing in aapt2 link flags, %q" , e , aapt2Flags )
}
}
2019-03-01 00:35:54 +01:00
func TestOverrideAndroidApp ( t * testing . T ) {
2021-03-22 18:31:52 +01:00
result := PrepareForTestWithJavaDefaultModules . RunTestWithBp (
t , `
2019-03-01 00:35:54 +01:00
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
2019-03-27 19:17:14 +01:00
certificate : "expiredkey" ,
2019-05-11 00:16:29 +02:00
overrides : [ "qux" ] ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-03-01 00:35:54 +01:00
}
override_android_app {
name : "bar" ,
base : "foo" ,
certificate : ":new_certificate" ,
2020-05-07 22:24:05 +02:00
lineage : "lineage.bin" ,
2021-11-03 15:39:39 +01:00
rotationMinSdkVersion : "32" ,
2020-02-12 02:27:19 +01:00
logging_parent : "bah" ,
2019-03-01 00:35:54 +01:00
}
android_app_certificate {
name : "new_certificate" ,
certificate : "cert/new_cert" ,
}
2019-03-13 18:13:24 +01:00
override_android_app {
name : "baz" ,
base : "foo" ,
package_name : "org.dandroid.bp" ,
}
2020-06-18 21:44:06 +02:00
override_android_app {
name : "baz_no_rename_resources" ,
base : "foo" ,
package_name : "org.dandroid.bp" ,
rename_resources_package : false ,
}
android_app {
name : "foo_no_rename_resources" ,
srcs : [ "a.java" ] ,
certificate : "expiredkey" ,
overrides : [ "qux" ] ,
rename_resources_package : false ,
sdk_version : "current" ,
}
override_android_app {
name : "baz_base_no_rename_resources" ,
base : "foo_no_rename_resources" ,
package_name : "org.dandroid.bp" ,
}
override_android_app {
name : "baz_override_base_rename_resources" ,
base : "foo_no_rename_resources" ,
package_name : "org.dandroid.bp" ,
rename_resources_package : true ,
}
2019-03-01 00:35:54 +01:00
` )
expectedVariants := [ ] struct {
2021-11-03 15:39:39 +01:00
name string
moduleName string
variantName string
apkName string
apkPath string
certFlag string
certSigningFlags string
overrides [ ] string
packageFlag string
renameResources bool
logging_parent string
2019-03-01 00:35:54 +01:00
} {
{
2021-11-03 15:39:39 +01:00
name : "foo" ,
moduleName : "foo" ,
variantName : "android_common" ,
apkPath : "out/soong/target/product/test_device/system/app/foo/foo.apk" ,
certFlag : "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8" ,
certSigningFlags : "" ,
overrides : [ ] string { "qux" } ,
packageFlag : "" ,
renameResources : false ,
logging_parent : "" ,
2020-06-18 21:44:06 +02:00
} ,
{
2021-11-03 15:39:39 +01:00
name : "foo" ,
moduleName : "bar" ,
variantName : "android_common_bar" ,
apkPath : "out/soong/target/product/test_device/system/app/bar/bar.apk" ,
certFlag : "cert/new_cert.x509.pem cert/new_cert.pk8" ,
certSigningFlags : "--lineage lineage.bin --rotation-min-sdk-version 32" ,
overrides : [ ] string { "qux" , "foo" } ,
packageFlag : "" ,
renameResources : false ,
logging_parent : "bah" ,
2020-06-18 21:44:06 +02:00
} ,
{
2021-11-03 15:39:39 +01:00
name : "foo" ,
moduleName : "baz" ,
variantName : "android_common_baz" ,
apkPath : "out/soong/target/product/test_device/system/app/baz/baz.apk" ,
certFlag : "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8" ,
certSigningFlags : "" ,
overrides : [ ] string { "qux" , "foo" } ,
packageFlag : "org.dandroid.bp" ,
renameResources : true ,
logging_parent : "" ,
2020-06-18 21:44:06 +02:00
} ,
{
2021-11-03 15:39:39 +01:00
name : "foo" ,
moduleName : "baz_no_rename_resources" ,
variantName : "android_common_baz_no_rename_resources" ,
apkPath : "out/soong/target/product/test_device/system/app/baz_no_rename_resources/baz_no_rename_resources.apk" ,
certFlag : "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8" ,
certSigningFlags : "" ,
overrides : [ ] string { "qux" , "foo" } ,
packageFlag : "org.dandroid.bp" ,
renameResources : false ,
logging_parent : "" ,
2020-06-18 21:44:06 +02:00
} ,
{
2021-11-03 15:39:39 +01:00
name : "foo_no_rename_resources" ,
moduleName : "baz_base_no_rename_resources" ,
variantName : "android_common_baz_base_no_rename_resources" ,
apkPath : "out/soong/target/product/test_device/system/app/baz_base_no_rename_resources/baz_base_no_rename_resources.apk" ,
certFlag : "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8" ,
certSigningFlags : "" ,
overrides : [ ] string { "qux" , "foo_no_rename_resources" } ,
packageFlag : "org.dandroid.bp" ,
renameResources : false ,
logging_parent : "" ,
2020-06-18 21:44:06 +02:00
} ,
{
2021-11-03 15:39:39 +01:00
name : "foo_no_rename_resources" ,
moduleName : "baz_override_base_rename_resources" ,
variantName : "android_common_baz_override_base_rename_resources" ,
apkPath : "out/soong/target/product/test_device/system/app/baz_override_base_rename_resources/baz_override_base_rename_resources.apk" ,
certFlag : "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8" ,
certSigningFlags : "" ,
overrides : [ ] string { "qux" , "foo_no_rename_resources" } ,
packageFlag : "org.dandroid.bp" ,
renameResources : true ,
logging_parent : "" ,
2019-03-01 00:35:54 +01:00
} ,
}
for _ , expected := range expectedVariants {
2021-03-22 18:31:52 +01:00
variant := result . ModuleForTests ( expected . name , expected . variantName )
2019-03-01 00:35:54 +01:00
// Check the final apk name
2021-03-22 18:31:52 +01:00
variant . Output ( expected . apkPath )
2019-03-01 00:35:54 +01:00
// Check the certificate paths
2019-11-07 23:14:38 +01:00
signapk := variant . Output ( expected . moduleName + ".apk" )
2020-05-07 22:24:05 +02:00
certFlag := signapk . Args [ "certificates" ]
2021-03-22 18:31:52 +01:00
android . AssertStringEquals ( t , "certificates flags" , expected . certFlag , certFlag )
2020-05-07 22:24:05 +02:00
2021-11-03 15:39:39 +01:00
// Check the cert signing flags
certSigningFlags := signapk . Args [ "flags" ]
android . AssertStringEquals ( t , "cert signing flags" , expected . certSigningFlags , certSigningFlags )
2019-03-01 00:35:54 +01:00
2019-03-13 18:13:24 +01:00
// Check if the overrides field values are correctly aggregated.
2019-03-01 00:35:54 +01:00
mod := variant . Module ( ) . ( * AndroidApp )
2022-02-17 03:33:12 +01:00
android . AssertDeepEquals ( t , "overrides property" , expected . overrides , mod . overridableAppProperties . Overrides )
2019-03-13 18:13:24 +01:00
2020-02-12 02:27:19 +01:00
// Test Overridable property: Logging_parent
logging_parent := mod . aapt . LoggingParent
2021-03-22 18:31:52 +01:00
android . AssertStringEquals ( t , "overrides property value for logging parent" , expected . logging_parent , logging_parent )
2020-02-12 02:27:19 +01:00
2020-05-19 21:15:37 +02:00
// Check the package renaming flag, if exists.
2019-03-13 18:13:24 +01:00
res := variant . Output ( "package-res.apk" )
aapt2Flags := res . Args [ "flags" ]
2020-06-18 21:44:06 +02:00
checkAapt2LinkFlag ( t , aapt2Flags , "rename-manifest-package" , expected . packageFlag )
expectedPackage := expected . packageFlag
if ! expected . renameResources {
expectedPackage = ""
2020-05-19 21:15:37 +02:00
}
2020-06-18 21:44:06 +02:00
checkAapt2LinkFlag ( t , aapt2Flags , "rename-resources-package" , expectedPackage )
2019-03-01 00:35:54 +01:00
}
}
2019-04-15 18:48:31 +02:00
2022-02-17 03:33:12 +01:00
func TestOverrideAndroidAppOverrides ( t * testing . T ) {
ctx , _ := testJava (
t , `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
sdk_version : "current" ,
overrides : [ "qux" ]
}
android_app {
name : "bar" ,
srcs : [ "b.java" ] ,
sdk_version : "current" ,
overrides : [ "foo" ]
}
override_android_app {
name : "foo_override" ,
base : "foo" ,
overrides : [ "bar" ]
}
` )
expectedVariants := [ ] struct {
name string
moduleName string
variantName string
overrides [ ] string
} {
{
name : "foo" ,
moduleName : "foo" ,
variantName : "android_common" ,
overrides : [ ] string { "qux" } ,
} ,
{
name : "bar" ,
moduleName : "bar" ,
variantName : "android_common" ,
overrides : [ ] string { "foo" } ,
} ,
{
name : "foo" ,
moduleName : "foo_override" ,
variantName : "android_common_foo_override" ,
overrides : [ ] string { "bar" , "foo" } ,
} ,
}
for _ , expected := range expectedVariants {
variant := ctx . ModuleForTests ( expected . name , expected . variantName )
// Check if the overrides field values are correctly aggregated.
mod := variant . Module ( ) . ( * AndroidApp )
android . AssertDeepEquals ( t , "overrides property" , expected . overrides , mod . overridableAppProperties . Overrides )
}
}
2022-05-17 01:19:54 +02:00
func TestOverrideAndroidAppWithPrebuilt ( t * testing . T ) {
result := PrepareForTestWithJavaDefaultModules . RunTestWithBp (
t , `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
sdk_version : "current" ,
}
override_android_app {
name : "bar" ,
base : "foo" ,
}
android_app_import {
name : "bar" ,
prefer : true ,
apk : "bar.apk" ,
presigned : true ,
}
` )
// An app that has an override that also has a prebuilt should not be hidden.
foo := result . ModuleForTests ( "foo" , "android_common" )
if foo . Module ( ) . IsHideFromMake ( ) {
t . Errorf ( "expected foo to have HideFromMake false" )
}
// An override that also has a prebuilt should be hidden.
barOverride := result . ModuleForTests ( "foo" , "android_common_bar" )
if ! barOverride . Module ( ) . IsHideFromMake ( ) {
t . Errorf ( "expected bar override variant of foo to have HideFromMake true" )
}
}
2022-01-08 04:16:32 +01:00
func TestOverrideAndroidAppStem ( t * testing . T ) {
ctx , _ := testJava ( t , `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
sdk_version : "current" ,
}
override_android_app {
name : "bar" ,
base : "foo" ,
}
override_android_app {
name : "baz" ,
base : "foo" ,
stem : "baz_stem" ,
}
android_app {
name : "foo2" ,
srcs : [ "a.java" ] ,
sdk_version : "current" ,
stem : "foo2_stem" ,
}
override_android_app {
name : "bar2" ,
base : "foo2" ,
}
override_android_app {
name : "baz2" ,
base : "foo2" ,
stem : "baz2_stem" ,
}
` )
for _ , expected := range [ ] struct {
moduleName string
variantName string
apkPath string
} {
{
moduleName : "foo" ,
variantName : "android_common" ,
apkPath : "out/soong/target/product/test_device/system/app/foo/foo.apk" ,
} ,
{
moduleName : "foo" ,
variantName : "android_common_bar" ,
apkPath : "out/soong/target/product/test_device/system/app/bar/bar.apk" ,
} ,
{
moduleName : "foo" ,
variantName : "android_common_baz" ,
apkPath : "out/soong/target/product/test_device/system/app/baz_stem/baz_stem.apk" ,
} ,
{
moduleName : "foo2" ,
variantName : "android_common" ,
apkPath : "out/soong/target/product/test_device/system/app/foo2_stem/foo2_stem.apk" ,
} ,
{
moduleName : "foo2" ,
variantName : "android_common_bar2" ,
// Note that this may cause the duplicate output error.
apkPath : "out/soong/target/product/test_device/system/app/foo2_stem/foo2_stem.apk" ,
} ,
{
moduleName : "foo2" ,
variantName : "android_common_baz2" ,
apkPath : "out/soong/target/product/test_device/system/app/baz2_stem/baz2_stem.apk" ,
} ,
} {
variant := ctx . ModuleForTests ( expected . moduleName , expected . variantName )
variant . Output ( expected . apkPath )
}
}
2019-05-11 00:16:29 +02:00
func TestOverrideAndroidAppDependency ( t * testing . T ) {
2019-07-17 20:15:09 +02:00
ctx , _ := testJava ( t , `
2019-05-11 00:16:29 +02:00
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-05-11 00:16:29 +02:00
}
override_android_app {
name : "bar" ,
base : "foo" ,
package_name : "org.dandroid.bp" ,
}
android_test {
name : "baz" ,
srcs : [ "b.java" ] ,
instrumentation_for : "foo" ,
}
android_test {
name : "qux" ,
srcs : [ "b.java" ] ,
instrumentation_for : "bar" ,
}
` )
// Verify baz, which depends on the overridden module foo, has the correct classpath javac arg.
2021-03-29 01:42:57 +02:00
javac := ctx . ModuleForTests ( "baz" , "android_common" ) . Rule ( "javac" )
2021-03-22 18:31:52 +01:00
fooTurbine := "out/soong/.intermediates/foo/android_common/turbine-combined/foo.jar"
2019-05-11 00:16:29 +02:00
if ! strings . Contains ( javac . Args [ "classpath" ] , fooTurbine ) {
t . Errorf ( "baz classpath %v does not contain %q" , javac . Args [ "classpath" ] , fooTurbine )
}
// Verify qux, which depends on the overriding module bar, has the correct classpath javac arg.
2021-03-29 01:42:57 +02:00
javac = ctx . ModuleForTests ( "qux" , "android_common" ) . Rule ( "javac" )
2021-03-22 18:31:52 +01:00
barTurbine := "out/soong/.intermediates/foo/android_common_bar/turbine-combined/foo.jar"
2019-05-11 00:16:29 +02:00
if ! strings . Contains ( javac . Args [ "classpath" ] , barTurbine ) {
t . Errorf ( "qux classpath %v does not contain %q" , javac . Args [ "classpath" ] , barTurbine )
}
}
2019-06-06 17:45:58 +02:00
func TestOverrideAndroidTest ( t * testing . T ) {
ctx , _ := testJava ( t , `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
package_name : "com.android.foo" ,
sdk_version : "current" ,
}
override_android_app {
name : "bar" ,
base : "foo" ,
package_name : "com.android.bar" ,
}
android_test {
name : "foo_test" ,
srcs : [ "b.java" ] ,
instrumentation_for : "foo" ,
}
override_android_test {
name : "bar_test" ,
base : "foo_test" ,
package_name : "com.android.bar.test" ,
instrumentation_for : "bar" ,
instrumentation_target_package : "com.android.bar" ,
}
` )
expectedVariants := [ ] struct {
moduleName string
variantName string
apkPath string
overrides [ ] string
targetVariant string
packageFlag string
targetPackageFlag string
} {
{
variantName : "android_common" ,
2019-11-21 19:41:00 +01:00
apkPath : "/target/product/test_device/testcases/foo_test/arm64/foo_test.apk" ,
2019-06-06 17:45:58 +02:00
overrides : nil ,
targetVariant : "android_common" ,
packageFlag : "" ,
targetPackageFlag : "" ,
} ,
{
variantName : "android_common_bar_test" ,
2019-11-21 19:41:00 +01:00
apkPath : "/target/product/test_device/testcases/bar_test/arm64/bar_test.apk" ,
2019-06-06 17:45:58 +02:00
overrides : [ ] string { "foo_test" } ,
targetVariant : "android_common_bar" ,
packageFlag : "com.android.bar.test" ,
targetPackageFlag : "com.android.bar" ,
} ,
}
for _ , expected := range expectedVariants {
variant := ctx . ModuleForTests ( "foo_test" , expected . variantName )
// Check the final apk name
2021-03-22 18:31:52 +01:00
variant . Output ( "out/soong" + expected . apkPath )
2019-06-06 17:45:58 +02:00
// Check if the overrides field values are correctly aggregated.
mod := variant . Module ( ) . ( * AndroidTest )
2022-02-17 03:33:12 +01:00
if ! reflect . DeepEqual ( expected . overrides , mod . overridableAppProperties . Overrides ) {
2019-06-06 17:45:58 +02:00
t . Errorf ( "Incorrect overrides property value, expected: %q, got: %q" ,
2022-02-17 03:33:12 +01:00
expected . overrides , mod . overridableAppProperties . Overrides )
2019-06-06 17:45:58 +02:00
}
// Check if javac classpath has the correct jar file path. This checks instrumentation_for overrides.
2021-03-29 01:42:57 +02:00
javac := variant . Rule ( "javac" )
2021-03-22 18:31:52 +01:00
turbine := filepath . Join ( "out" , "soong" , ".intermediates" , "foo" , expected . targetVariant , "turbine-combined" , "foo.jar" )
2019-06-06 17:45:58 +02:00
if ! strings . Contains ( javac . Args [ "classpath" ] , turbine ) {
t . Errorf ( "classpath %q does not contain %q" , javac . Args [ "classpath" ] , turbine )
}
// Check aapt2 flags.
res := variant . Output ( "package-res.apk" )
aapt2Flags := res . Args [ "flags" ]
checkAapt2LinkFlag ( t , aapt2Flags , "rename-manifest-package" , expected . packageFlag )
2020-06-18 21:44:06 +02:00
checkAapt2LinkFlag ( t , aapt2Flags , "rename-resources-package" , expected . packageFlag )
2019-06-06 17:45:58 +02:00
checkAapt2LinkFlag ( t , aapt2Flags , "rename-instrumentation-target-package" , expected . targetPackageFlag )
}
}
2020-01-14 19:27:18 +01:00
func TestAndroidTest_FixTestConfig ( t * testing . T ) {
ctx , _ := testJava ( t , `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
package_name : "com.android.foo" ,
sdk_version : "current" ,
}
android_test {
name : "foo_test" ,
srcs : [ "b.java" ] ,
instrumentation_for : "foo" ,
}
android_test {
name : "bar_test" ,
srcs : [ "b.java" ] ,
package_name : "com.android.bar.test" ,
instrumentation_for : "foo" ,
2023-02-02 22:22:26 +01:00
mainline_package_name : "com.android.bar" ,
2020-01-14 19:27:18 +01:00
}
override_android_test {
name : "baz_test" ,
base : "foo_test" ,
package_name : "com.android.baz.test" ,
2023-02-02 22:22:26 +01:00
mainline_package_name : "com.android.baz" ,
2020-01-14 19:27:18 +01:00
}
` )
testCases := [ ] struct {
moduleName string
variantName string
expectedFlags [ ] string
} {
{
moduleName : "foo_test" ,
variantName : "android_common" ,
} ,
{
moduleName : "bar_test" ,
variantName : "android_common" ,
expectedFlags : [ ] string {
2021-03-22 18:31:52 +01:00
"--manifest out/soong/.intermediates/bar_test/android_common/manifest_fixer/AndroidManifest.xml" ,
2020-01-14 19:27:18 +01:00
"--package-name com.android.bar.test" ,
2023-02-02 22:22:26 +01:00
"--mainline-package-name com.android.bar" ,
2020-01-14 19:27:18 +01:00
} ,
} ,
{
moduleName : "foo_test" ,
variantName : "android_common_baz_test" ,
expectedFlags : [ ] string {
2021-03-22 18:31:52 +01:00
"--manifest out/soong/.intermediates/foo_test/android_common_baz_test/manifest_fixer/AndroidManifest.xml" ,
2020-01-14 19:27:18 +01:00
"--package-name com.android.baz.test" ,
"--test-file-name baz_test.apk" ,
2023-02-02 22:22:26 +01:00
"out/soong/.intermediates/foo_test/android_common_baz_test/test_config_fixer/AndroidTest.xml" ,
"--mainline-package-name com.android.baz" ,
2020-01-14 19:27:18 +01:00
} ,
} ,
}
for _ , test := range testCases {
variant := ctx . ModuleForTests ( test . moduleName , test . variantName )
2021-03-29 01:42:57 +02:00
params := variant . MaybeOutput ( "test_config_fixer/AndroidTest.xml" )
2020-01-14 19:27:18 +01:00
if len ( test . expectedFlags ) > 0 {
if params . Rule == nil {
t . Errorf ( "test_config_fixer was expected to run, but didn't" )
} else {
for _ , flag := range test . expectedFlags {
if ! strings . Contains ( params . RuleParams . Command , flag ) {
t . Errorf ( "Flag %q was not found in command: %q" , flag , params . RuleParams . Command )
}
}
}
} else {
if params . Rule != nil {
t . Errorf ( "test_config_fixer was not expected to run, but did: %q" , params . RuleParams . Command )
}
}
}
}
2022-01-11 15:35:55 +01:00
func TestInstrumentationTargetPrebuilt ( t * testing . T ) {
bp := `
android_app_import {
name : "foo" ,
apk : "foo.apk" ,
presigned : true ,
}
android_test {
name : "bar" ,
srcs : [ "a.java" ] ,
instrumentation_for : "foo" ,
sdk_version : "current" ,
}
`
android . GroupFixturePreparers (
PrepareForTestWithJavaDefaultModules ,
) . ExtendWithErrorHandler (
android . FixtureExpectsAtLeastOneErrorMatchingPattern (
"instrumentation_for: dependency \"foo\" of type \"android_app_import\" does not provide JavaInfo so is unsuitable for use with this property" ) ) .
RunTestWithBp ( t , bp )
}
2019-05-07 00:48:44 +02:00
func TestStl ( t * testing . T ) {
2019-07-17 20:15:09 +02:00
ctx , _ := testJava ( t , cc . GatherRequiredDepsForTest ( android . Android ) + `
2019-05-07 00:48:44 +02:00
cc_library {
name : "libjni" ,
2019-12-18 01:46:18 +01:00
sdk_version : "current" ,
stl : "c++_shared" ,
2019-05-07 00:48:44 +02:00
}
android_test {
name : "stl" ,
jni_libs : [ "libjni" ] ,
compile_multilib : "both" ,
sdk_version : "current" ,
stl : "c++_shared" ,
}
android_test {
name : "system" ,
jni_libs : [ "libjni" ] ,
compile_multilib : "both" ,
sdk_version : "current" ,
}
` )
testCases := [ ] struct {
name string
jnis [ ] string
} {
{ "stl" ,
[ ] string {
"libjni.so" ,
2019-06-04 20:53:47 +02:00
"libc++_shared.so" ,
2019-05-07 00:48:44 +02:00
} ,
} ,
{ "system" ,
[ ] string {
"libjni.so" ,
} ,
} ,
}
for _ , test := range testCases {
t . Run ( test . name , func ( t * testing . T ) {
app := ctx . ModuleForTests ( test . name , "android_common" )
2023-07-27 01:14:56 +02:00
jniLibZip := app . Output ( "jnilibs.zip" )
2019-05-07 00:48:44 +02:00
var jnis [ ] string
args := strings . Fields ( jniLibZip . Args [ "jarArgs" ] )
for i := 0 ; i < len ( args ) ; i ++ {
if args [ i ] == "-f" {
jnis = append ( jnis , args [ i + 1 ] )
i += 1
}
}
jnisJoined := strings . Join ( jnis , " " )
for _ , jni := range test . jnis {
if ! strings . Contains ( jnisJoined , jni ) {
t . Errorf ( "missing jni %q in %q" , jni , jnis )
}
}
} )
}
}
2019-05-16 21:28:22 +02:00
func TestUsesLibraries ( t * testing . T ) {
bp := `
java_sdk_library {
name : "foo" ,
srcs : [ "a.java" ] ,
api_packages : [ "foo" ] ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-05-16 21:28:22 +02:00
}
2020-05-15 11:20:31 +02:00
java_sdk_library {
name : "qux" ,
srcs : [ "a.java" ] ,
api_packages : [ "qux" ] ,
sdk_version : "current" ,
}
java_sdk_library {
name : "quuz" ,
srcs : [ "a.java" ] ,
api_packages : [ "quuz" ] ,
sdk_version : "current" ,
}
2020-12-03 17:50:22 +01:00
java_sdk_library {
name : "fred" ,
srcs : [ "a.java" ] ,
api_packages : [ "fred" ] ,
sdk_version : "current" ,
}
2019-05-16 21:28:22 +02:00
java_sdk_library {
name : "bar" ,
srcs : [ "a.java" ] ,
api_packages : [ "bar" ] ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-05-16 21:28:22 +02:00
}
2020-08-19 15:58:01 +02:00
java_sdk_library {
name : "runtime-library" ,
srcs : [ "a.java" ] ,
sdk_version : "current" ,
}
java_library {
name : "static-runtime-helper" ,
srcs : [ "a.java" ] ,
libs : [ "runtime-library" ] ,
sdk_version : "current" ,
}
2021-08-18 17:57:11 +02:00
java_library {
name : "runtime-required-x" ,
srcs : [ "a.java" ] ,
installable : true ,
sdk_version : "current" ,
}
java_library {
name : "runtime-optional-x" ,
srcs : [ "a.java" ] ,
installable : true ,
sdk_version : "current" ,
}
android_library {
name : "static-x" ,
uses_libs : [ "runtime-required-x" ] ,
optional_uses_libs : [ "runtime-optional-x" ] ,
sdk_version : "current" ,
}
java_library {
name : "runtime-required-y" ,
srcs : [ "a.java" ] ,
installable : true ,
sdk_version : "current" ,
}
java_library {
name : "runtime-optional-y" ,
srcs : [ "a.java" ] ,
installable : true ,
sdk_version : "current" ,
}
java_library {
name : "static-y" ,
srcs : [ "a.java" ] ,
uses_libs : [ "runtime-required-y" ] ,
2024-04-15 13:15:50 +02:00
optional_uses_libs : [
"runtime-optional-y" ,
"missing-lib-a" ,
] ,
2021-08-18 17:57:11 +02:00
sdk_version : "current" ,
}
2021-02-26 15:49:07 +01:00
// A library that has to use "provides_uses_lib", because:
// - it is not an SDK library
// - its library name is different from its module name
java_library {
name : "non-sdk-lib" ,
provides_uses_lib : "com.non.sdk.lib" ,
installable : true ,
srcs : [ "a.java" ] ,
}
2019-05-16 21:28:22 +02:00
android_app {
name : "app" ,
srcs : [ "a.java" ] ,
2021-02-26 15:49:07 +01:00
libs : [
"qux" ,
"quuz.stubs"
] ,
2020-12-03 17:50:22 +01:00
static_libs : [
"static-runtime-helper" ,
// statically linked component libraries should not pull their SDK libraries,
// so "fred" should not be added to class loader context
"fred.stubs" ,
2021-08-18 17:57:11 +02:00
"static-x" ,
"static-y" ,
2020-12-03 17:50:22 +01:00
] ,
2021-02-26 15:49:07 +01:00
uses_libs : [
"foo" ,
"non-sdk-lib"
] ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-05-16 21:28:22 +02:00
optional_uses_libs : [
"bar" ,
Refactor the contruction of the manifest check inputs.
This is a no-op change for a majority of cases.
Before this change, the contruction of the manifest check inputs is
confusing. It mutates uses_libs properties in place just for the
manifest check, by replacing module names with library names for
direct dependencies and merging library names from CLC for both direct
denpendencies and transitive denpendencies, and then constructs manifest
check inputs from those mutated uses_libs properties. This is
error-prone and leads to insistency: the goal is to check that the CLC
matches the manifest, but the inputs to the check don't reflect the CLC.
After this change, we no longer mutate uses_libs properties in place.
Instead, we maintain a separate list of missing denpendencies, and then
construct manifest check inputs directly from the CLC for all existing
libraries, no matter they are direct or transtive, and from the separate
list of missing libraries. This change makes the logic more
consistent and straightforward, and it also allows us to easily do the
next change, which is to propagate transtive missing denpendencies.
In fact, this change revealed several bugs around library optionality
and order in CLC construction, and fixed them.
Bug: 331528424
Test: m --no-skip-soong-tests
Ignore-AOSP-First: Depends on internal changes. Will cherry-pick once merged.
Merged-In: I0de82e76c47995b54aba9efd41538d950256a95f
Change-Id: I0de82e76c47995b54aba9efd41538d950256a95f
2024-04-15 13:15:41 +02:00
"missing-lib-b" ,
2019-05-16 21:28:22 +02:00
] ,
}
android_app_import {
name : "prebuilt" ,
apk : "prebuilts/apk/app.apk" ,
certificate : "platform" ,
2021-02-26 15:49:07 +01:00
uses_libs : [
"foo" ,
"non-sdk-lib" ,
"android.test.runner"
] ,
2019-05-16 21:28:22 +02:00
optional_uses_libs : [
"bar" ,
Refactor the contruction of the manifest check inputs.
This is a no-op change for a majority of cases.
Before this change, the contruction of the manifest check inputs is
confusing. It mutates uses_libs properties in place just for the
manifest check, by replacing module names with library names for
direct dependencies and merging library names from CLC for both direct
denpendencies and transitive denpendencies, and then constructs manifest
check inputs from those mutated uses_libs properties. This is
error-prone and leads to insistency: the goal is to check that the CLC
matches the manifest, but the inputs to the check don't reflect the CLC.
After this change, we no longer mutate uses_libs properties in place.
Instead, we maintain a separate list of missing denpendencies, and then
construct manifest check inputs directly from the CLC for all existing
libraries, no matter they are direct or transtive, and from the separate
list of missing libraries. This change makes the logic more
consistent and straightforward, and it also allows us to easily do the
next change, which is to propagate transtive missing denpendencies.
In fact, this change revealed several bugs around library optionality
and order in CLC construction, and fixed them.
Bug: 331528424
Test: m --no-skip-soong-tests
Ignore-AOSP-First: Depends on internal changes. Will cherry-pick once merged.
Merged-In: I0de82e76c47995b54aba9efd41538d950256a95f
Change-Id: I0de82e76c47995b54aba9efd41538d950256a95f
2024-04-15 13:15:41 +02:00
"missing-lib-b" ,
2019-05-16 21:28:22 +02:00
] ,
}
`
2021-03-22 16:36:52 +01:00
result := android . GroupFixturePreparers (
prepareForJavaTest ,
2021-03-13 03:36:00 +01:00
PrepareForTestWithJavaSdkLibraryFiles ,
FixtureWithLastReleaseApis ( "runtime-library" , "foo" , "quuz" , "qux" , "bar" , "fred" ) ,
2023-06-03 00:42:21 +02:00
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
variables . BuildWarningBadOptionalUsesLibsAllowlist = [ ] string { "app" , "prebuilt" }
} ) ,
2021-03-13 00:04:46 +01:00
) . RunTestWithBp ( t , bp )
2019-05-16 21:28:22 +02:00
2021-03-13 00:04:46 +01:00
app := result . ModuleForTests ( "app" , "android_common" )
prebuilt := result . ModuleForTests ( "prebuilt" , "android_common" )
2019-05-16 21:28:22 +02:00
2020-05-15 11:20:31 +02:00
// Test that implicit dependencies on java_sdk_library instances are passed to the manifest.
2022-05-04 13:00:02 +02:00
// These also include explicit `uses_libs`/`optional_uses_libs` entries, as they may be
// propagated from dependencies.
2021-02-26 13:05:11 +01:00
actualManifestFixerArgs := app . Output ( "manifest_fixer/AndroidManifest.xml" ) . Args [ "args" ]
2024-05-14 19:09:54 +02:00
expectManifestFixerArgs := ` --extract-native-libs=true ` +
` --uses-library foo ` +
2022-05-04 13:00:02 +02:00
` --uses-library com.non.sdk.lib ` +
Refactor the contruction of the manifest check inputs.
This is a no-op change for a majority of cases.
Before this change, the contruction of the manifest check inputs is
confusing. It mutates uses_libs properties in place just for the
manifest check, by replacing module names with library names for
direct dependencies and merging library names from CLC for both direct
denpendencies and transitive denpendencies, and then constructs manifest
check inputs from those mutated uses_libs properties. This is
error-prone and leads to insistency: the goal is to check that the CLC
matches the manifest, but the inputs to the check don't reflect the CLC.
After this change, we no longer mutate uses_libs properties in place.
Instead, we maintain a separate list of missing denpendencies, and then
construct manifest check inputs directly from the CLC for all existing
libraries, no matter they are direct or transtive, and from the separate
list of missing libraries. This change makes the logic more
consistent and straightforward, and it also allows us to easily do the
next change, which is to propagate transtive missing denpendencies.
In fact, this change revealed several bugs around library optionality
and order in CLC construction, and fixed them.
Bug: 331528424
Test: m --no-skip-soong-tests
Ignore-AOSP-First: Depends on internal changes. Will cherry-pick once merged.
Merged-In: I0de82e76c47995b54aba9efd41538d950256a95f
Change-Id: I0de82e76c47995b54aba9efd41538d950256a95f
2024-04-15 13:15:41 +02:00
` --uses-library qux ` +
` --uses-library quuz ` +
2022-05-04 13:00:02 +02:00
` --uses-library runtime-library ` +
` --uses-library runtime-required-x ` +
` --uses-library runtime-required-y ` +
` --optional-uses-library bar ` +
` --optional-uses-library runtime-optional-x ` +
` --optional-uses-library runtime-optional-y `
2022-01-24 18:44:05 +01:00
android . AssertStringDoesContain ( t , "manifest_fixer args" , actualManifestFixerArgs , expectManifestFixerArgs )
2020-05-15 11:20:31 +02:00
2021-02-26 13:05:11 +01:00
// Test that all libraries are verified (library order matters).
verifyCmd := app . Rule ( "verify_uses_libraries" ) . RuleParams . Command
verifyArgs := ` --uses-library foo ` +
2021-02-26 12:38:21 +01:00
` --uses-library com.non.sdk.lib ` +
2021-02-26 13:05:11 +01:00
` --uses-library qux ` +
` --uses-library quuz ` +
` --uses-library runtime-library ` +
2021-08-18 17:57:11 +02:00
` --uses-library runtime-required-x ` +
` --uses-library runtime-required-y ` +
2021-02-26 13:05:11 +01:00
` --optional-uses-library bar ` +
2021-08-18 17:57:11 +02:00
` --optional-uses-library runtime-optional-x ` +
Refactor the contruction of the manifest check inputs.
This is a no-op change for a majority of cases.
Before this change, the contruction of the manifest check inputs is
confusing. It mutates uses_libs properties in place just for the
manifest check, by replacing module names with library names for
direct dependencies and merging library names from CLC for both direct
denpendencies and transitive denpendencies, and then constructs manifest
check inputs from those mutated uses_libs properties. This is
error-prone and leads to insistency: the goal is to check that the CLC
matches the manifest, but the inputs to the check don't reflect the CLC.
After this change, we no longer mutate uses_libs properties in place.
Instead, we maintain a separate list of missing denpendencies, and then
construct manifest check inputs directly from the CLC for all existing
libraries, no matter they are direct or transtive, and from the separate
list of missing libraries. This change makes the logic more
consistent and straightforward, and it also allows us to easily do the
next change, which is to propagate transtive missing denpendencies.
In fact, this change revealed several bugs around library optionality
and order in CLC construction, and fixed them.
Bug: 331528424
Test: m --no-skip-soong-tests
Ignore-AOSP-First: Depends on internal changes. Will cherry-pick once merged.
Merged-In: I0de82e76c47995b54aba9efd41538d950256a95f
Change-Id: I0de82e76c47995b54aba9efd41538d950256a95f
2024-04-15 13:15:41 +02:00
` --optional-uses-library runtime-optional-y ` +
2024-04-15 13:15:50 +02:00
` --missing-optional-uses-library missing-lib-b ` +
` --missing-optional-uses-library missing-lib-a `
2021-03-13 00:04:46 +01:00
android . AssertStringDoesContain ( t , "verify cmd args" , verifyCmd , verifyArgs )
2019-05-16 21:28:22 +02:00
2021-02-26 13:05:11 +01:00
// Test that all libraries are verified for an APK (library order matters).
verifyApkCmd := prebuilt . Rule ( "verify_uses_libraries" ) . RuleParams . Command
2021-03-03 17:38:37 +01:00
verifyApkArgs := ` --uses-library foo ` +
` --uses-library com.non.sdk.lib ` +
` --uses-library android.test.runner ` +
` --optional-uses-library bar ` +
Refactor the contruction of the manifest check inputs.
This is a no-op change for a majority of cases.
Before this change, the contruction of the manifest check inputs is
confusing. It mutates uses_libs properties in place just for the
manifest check, by replacing module names with library names for
direct dependencies and merging library names from CLC for both direct
denpendencies and transitive denpendencies, and then constructs manifest
check inputs from those mutated uses_libs properties. This is
error-prone and leads to insistency: the goal is to check that the CLC
matches the manifest, but the inputs to the check don't reflect the CLC.
After this change, we no longer mutate uses_libs properties in place.
Instead, we maintain a separate list of missing denpendencies, and then
construct manifest check inputs directly from the CLC for all existing
libraries, no matter they are direct or transtive, and from the separate
list of missing libraries. This change makes the logic more
consistent and straightforward, and it also allows us to easily do the
next change, which is to propagate transtive missing denpendencies.
In fact, this change revealed several bugs around library optionality
and order in CLC construction, and fixed them.
Bug: 331528424
Test: m --no-skip-soong-tests
Ignore-AOSP-First: Depends on internal changes. Will cherry-pick once merged.
Merged-In: I0de82e76c47995b54aba9efd41538d950256a95f
Change-Id: I0de82e76c47995b54aba9efd41538d950256a95f
2024-04-15 13:15:41 +02:00
` --missing-optional-uses-library missing-lib-b `
2021-03-13 00:04:46 +01:00
android . AssertStringDoesContain ( t , "verify apk cmd args" , verifyApkCmd , verifyApkArgs )
2019-05-16 21:28:22 +02:00
Move CLC construction to Ninja phase.
Before this change, dexpreopt was often broken with optional libraries.
This was because the CLC construction was done in Soong at an early
stage, where we don't have sufficient information to determine whether
an optional library is installed or not.
For example, the "Settings" package uses an optional library called
"androidx.window.extensions". On some devices, the library is installed,
but on some other devices, it's not. Soong always adds the library to
the CLC, meaning the CLC is wrong for devices which don't have the
library. This change fixes the problem. See the tests below.
After this change, the CLC construction is done by a Python script
invoked at a very late stage. It uses product_packages.txt, which is
generated by Make, to determine whether an optional library is
installed or not, and filter out libraries that are not installed.
Note that optional libraries are still added as dependencies by Soong.
This is because dependencies have to be added at an early stage. This
means what dex2oat eventually uses will be a subset of the dependencies,
which is fine.
Bug: 282877248
Test: m
Test: atest construct_context_test
Test: -
1. lunch aosp_cf_x86_64_phone-userdebug && m
2. Check the .invocation file of the "Settings" package (defined in
.bp file)
3. See androidx.window.extensions
Test: -
1. lunch aosp_redfin-userdebug && m
2. Check the .invocation file of the "Settings" package (defined in
.bp file)
3. Don't see androidx.window.extensions
Test: Check the .invocation file of the "Dialer" package (defined in
.mk file)
Test: -
1. Build a Pixel 5 system image and flash it to a Pixel 5 device.
2. adb shell pm art dump
3. See "reason=prebuilt" instead of "reason=vdex".
(https://diff.googleplex.com/#key=fB6Ls9q2QGSN, before: left,
after: right)
Change-Id: Ia112bd7c2328373e68db6bffb74bf34030f683d8
2023-05-17 17:57:30 +02:00
// Test that necessary args are passed for constructing CLC in Ninja phase.
2021-02-26 13:05:11 +01:00
cmd := app . Rule ( "dexpreopt" ) . RuleParams . Command
Move CLC construction to Ninja phase.
Before this change, dexpreopt was often broken with optional libraries.
This was because the CLC construction was done in Soong at an early
stage, where we don't have sufficient information to determine whether
an optional library is installed or not.
For example, the "Settings" package uses an optional library called
"androidx.window.extensions". On some devices, the library is installed,
but on some other devices, it's not. Soong always adds the library to
the CLC, meaning the CLC is wrong for devices which don't have the
library. This change fixes the problem. See the tests below.
After this change, the CLC construction is done by a Python script
invoked at a very late stage. It uses product_packages.txt, which is
generated by Make, to determine whether an optional library is
installed or not, and filter out libraries that are not installed.
Note that optional libraries are still added as dependencies by Soong.
This is because dependencies have to be added at an early stage. This
means what dex2oat eventually uses will be a subset of the dependencies,
which is fine.
Bug: 282877248
Test: m
Test: atest construct_context_test
Test: -
1. lunch aosp_cf_x86_64_phone-userdebug && m
2. Check the .invocation file of the "Settings" package (defined in
.bp file)
3. See androidx.window.extensions
Test: -
1. lunch aosp_redfin-userdebug && m
2. Check the .invocation file of the "Settings" package (defined in
.bp file)
3. Don't see androidx.window.extensions
Test: Check the .invocation file of the "Dialer" package (defined in
.mk file)
Test: -
1. Build a Pixel 5 system image and flash it to a Pixel 5 device.
2. adb shell pm art dump
3. See "reason=prebuilt" instead of "reason=vdex".
(https://diff.googleplex.com/#key=fB6Ls9q2QGSN, before: left,
after: right)
Change-Id: Ia112bd7c2328373e68db6bffb74bf34030f683d8
2023-05-17 17:57:30 +02:00
android . AssertStringDoesContain ( t , "dexpreopt app cmd context" , cmd , "--context-json=" )
android . AssertStringDoesContain ( t , "dexpreopt app cmd product_packages" , cmd ,
2023-12-06 20:40:24 +01:00
"--product-packages=out/soong/.intermediates/app/android_common/dexpreopt/app/product_packages.txt" )
2019-05-16 21:28:22 +02:00
}
2019-05-31 00:51:14 +02:00
2021-03-22 17:02:28 +01:00
func TestDexpreoptBcp ( t * testing . T ) {
bp := `
java_sdk_library {
name : "foo" ,
srcs : [ "a.java" ] ,
api_packages : [ "foo" ] ,
sdk_version : "current" ,
}
java_sdk_library {
name : "bar" ,
srcs : [ "a.java" ] ,
api_packages : [ "bar" ] ,
permitted_packages : [ "bar" ] ,
sdk_version : "current" ,
}
android_app {
name : "app" ,
srcs : [ "a.java" ] ,
sdk_version : "current" ,
}
`
testCases := [ ] struct {
name string
with bool
expect string
} {
{
name : "with updatable bcp" ,
with : true ,
expect : "/system/framework/foo.jar:/system/framework/bar.jar" ,
} ,
{
name : "without updatable bcp" ,
with : false ,
expect : "/system/framework/foo.jar" ,
} ,
}
for _ , test := range testCases {
t . Run ( test . name , func ( t * testing . T ) {
result := android . GroupFixturePreparers (
prepareForJavaTest ,
PrepareForTestWithJavaSdkLibraryFiles ,
FixtureWithLastReleaseApis ( "runtime-library" , "foo" , "bar" ) ,
dexpreopt . FixtureSetBootJars ( "platform:foo" ) ,
2021-07-21 15:23:52 +02:00
dexpreopt . FixtureSetApexBootJars ( "platform:bar" ) ,
2021-03-22 17:02:28 +01:00
dexpreopt . FixtureSetPreoptWithUpdatableBcp ( test . with ) ,
) . RunTestWithBp ( t , bp )
app := result . ModuleForTests ( "app" , "android_common" )
cmd := app . Rule ( "dexpreopt" ) . RuleParams . Command
bcp := " -Xbootclasspath-locations:" + test . expect + " " // space at the end matters
android . AssertStringDoesContain ( t , "dexpreopt app bcp" , cmd , bcp )
} )
}
}
2019-05-31 00:51:14 +02:00
func TestCodelessApp ( t * testing . T ) {
testCases := [ ] struct {
name string
bp string
noCode bool
} {
{
name : "normal" ,
bp : `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-05-31 00:51:14 +02:00
}
` ,
noCode : false ,
} ,
{
name : "app without sources" ,
bp : `
android_app {
name : "foo" ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-05-31 00:51:14 +02:00
}
` ,
noCode : true ,
} ,
{
name : "app with libraries" ,
bp : `
android_app {
name : "foo" ,
static_libs : [ "lib" ] ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-05-31 00:51:14 +02:00
}
java_library {
name : "lib" ,
srcs : [ "a.java" ] ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-05-31 00:51:14 +02:00
}
` ,
noCode : false ,
} ,
{
name : "app with sourceless libraries" ,
bp : `
android_app {
name : "foo" ,
static_libs : [ "lib" ] ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-05-31 00:51:14 +02:00
}
java_library {
name : "lib" ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-05-31 00:51:14 +02:00
}
` ,
// TODO(jungjw): this should probably be true
noCode : false ,
} ,
}
for _ , test := range testCases {
t . Run ( test . name , func ( t * testing . T ) {
ctx := testApp ( t , test . bp )
foo := ctx . ModuleForTests ( "foo" , "android_common" )
manifestFixerArgs := foo . Output ( "manifest_fixer/AndroidManifest.xml" ) . Args [ "args" ]
if strings . Contains ( manifestFixerArgs , "--has-no-code" ) != test . noCode {
t . Errorf ( "unexpected manifest_fixer args: %q" , manifestFixerArgs )
}
} )
}
}
2019-06-18 02:40:56 +02:00
2019-06-25 22:35:30 +02:00
func TestUncompressDex ( t * testing . T ) {
testCases := [ ] struct {
name string
bp string
uncompressedPlatform bool
uncompressedUnbundled bool
} {
{
name : "normal" ,
bp : `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-06-25 22:35:30 +02:00
}
` ,
uncompressedPlatform : true ,
uncompressedUnbundled : false ,
} ,
{
name : "use_embedded_dex" ,
bp : `
android_app {
name : "foo" ,
use_embedded_dex : true ,
srcs : [ "a.java" ] ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-06-25 22:35:30 +02:00
}
` ,
uncompressedPlatform : true ,
uncompressedUnbundled : true ,
} ,
{
name : "privileged" ,
bp : `
android_app {
name : "foo" ,
privileged : true ,
srcs : [ "a.java" ] ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-06-25 22:35:30 +02:00
}
` ,
uncompressedPlatform : true ,
uncompressedUnbundled : true ,
} ,
2020-05-20 23:20:28 +02:00
{
name : "normal_uncompress_dex_true" ,
bp : `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
sdk_version : "current" ,
uncompress_dex : true ,
}
` ,
uncompressedPlatform : true ,
uncompressedUnbundled : true ,
} ,
{
name : "normal_uncompress_dex_false" ,
bp : `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
sdk_version : "current" ,
uncompress_dex : false ,
}
` ,
uncompressedPlatform : false ,
uncompressedUnbundled : false ,
} ,
2019-06-25 22:35:30 +02:00
}
test := func ( t * testing . T , bp string , want bool , unbundled bool ) {
t . Helper ( )
2021-03-22 16:36:52 +01:00
result := android . GroupFixturePreparers (
prepareForJavaTest ,
2021-03-13 03:36:00 +01:00
PrepareForTestWithPrebuiltsOfCurrentApi ,
2021-03-14 01:36:50 +01:00
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
if unbundled {
variables . Unbundled_build = proptools . BoolPtr ( true )
variables . Always_use_prebuilt_sdks = proptools . BoolPtr ( true )
}
} ) ,
) . RunTestWithBp ( t , bp )
2019-06-25 22:35:30 +02:00
2021-03-14 01:36:50 +01:00
foo := result . ModuleForTests ( "foo" , "android_common" )
2019-06-25 22:35:30 +02:00
dex := foo . Rule ( "r8" )
uncompressedInDexJar := strings . Contains ( dex . Args [ "zipFlags" ] , "-L 0" )
aligned := foo . MaybeRule ( "zipalign" ) . Rule != nil
2021-03-14 01:36:50 +01:00
android . AssertBoolEquals ( t , "uncompressed in dex" , want , uncompressedInDexJar )
2019-06-25 22:35:30 +02:00
2021-03-14 01:36:50 +01:00
android . AssertBoolEquals ( t , "aligne" , want , aligned )
2019-06-25 22:35:30 +02:00
}
for _ , tt := range testCases {
t . Run ( tt . name , func ( t * testing . T ) {
t . Run ( "platform" , func ( t * testing . T ) {
test ( t , tt . bp , tt . uncompressedPlatform , false )
} )
t . Run ( "unbundled" , func ( t * testing . T ) {
test ( t , tt . bp , tt . uncompressedUnbundled , true )
} )
} )
}
}
2019-06-06 17:45:58 +02:00
func checkAapt2LinkFlag ( t * testing . T , aapt2Flags , flagName , expectedValue string ) {
if expectedValue != "" {
expectedFlag := "--" + flagName + " " + expectedValue
if ! strings . Contains ( aapt2Flags , expectedFlag ) {
t . Errorf ( "%q is missing in aapt2 link flags, %q" , expectedFlag , aapt2Flags )
}
} else {
unexpectedFlag := "--" + flagName
if strings . Contains ( aapt2Flags , unexpectedFlag ) {
t . Errorf ( "unexpected flag, %q is found in aapt2 link flags, %q" , unexpectedFlag , aapt2Flags )
}
}
}
2020-01-18 19:33:43 +01:00
2020-10-22 23:05:24 +02:00
func TestExportedProguardFlagFiles ( t * testing . T ) {
ctx , _ := testJava ( t , `
android_app {
name : "foo" ,
sdk_version : "current" ,
2024-03-27 22:11:51 +01:00
static_libs : [
"lib1" ,
"lib3" ,
] ,
2020-10-22 23:05:24 +02:00
}
android_library {
name : "lib1" ,
sdk_version : "current" ,
optimize : {
proguard_flags_files : [ "lib1proguard.cfg" ] ,
2024-03-27 22:11:51 +01:00
} ,
static_libs : [ "lib2" ] ,
}
android_library {
name : "lib2" ,
sdk_version : "current" ,
optimize : {
proguard_flags_files : [ "lib2proguard.cfg" ] ,
2020-10-22 23:05:24 +02:00
}
}
2024-03-27 22:11:51 +01:00
android_library_import {
name : "lib3" ,
sdk_version : "current" ,
aars : [ "lib3.aar" ] ,
static_libs : [ "lib4" ] ,
2020-10-22 23:05:24 +02:00
}
2024-03-27 22:11:51 +01:00
android_library {
name : "lib4" ,
sdk_version : "current" ,
optimize : {
proguard_flags_files : [ "lib4proguard.cfg" ] ,
}
}
` )
m := ctx . ModuleForTests ( "foo" , "android_common" )
r8 := m . Rule ( "java.r8" )
implicits := r8 . Implicits . RelativeToTop ( ) . Strings ( )
android . AssertStringListContains ( t , "r8 implicits" , implicits , "lib1proguard.cfg" )
android . AssertStringListContains ( t , "r8 implicits" , implicits , "lib2proguard.cfg" )
android . AssertStringListContains ( t , "r8 implicits" , implicits , "lib4proguard.cfg" )
android . AssertStringListContains ( t , "r8 implicits" , implicits , "out/soong/.intermediates/lib3/android_common/aar/proguard.txt" )
flags := r8 . Args [ "r8Flags" ]
android . AssertStringDoesContain ( t , "r8 flags" , flags , "-include lib1proguard.cfg" )
android . AssertStringDoesContain ( t , "r8 flags" , flags , "-include lib2proguard.cfg" )
android . AssertStringDoesContain ( t , "r8 flags" , flags , "-include lib4proguard.cfg" )
android . AssertStringDoesContain ( t , "r8 flags" , flags , "-include out/soong/.intermediates/lib3/android_common/aar/proguard.txt" )
2020-10-22 23:05:24 +02:00
}
2021-12-08 18:00:38 +01:00
func TestTargetSdkVersionManifestFixer ( t * testing . T ) {
platform_sdk_codename := "Tiramisu"
2023-04-27 18:08:26 +02:00
platform_sdk_version := 33
2021-12-08 18:00:38 +01:00
testCases := [ ] struct {
name string
targetSdkVersionInBp string
targetSdkVersionExpected string
unbundledBuild bool
2023-04-27 18:08:26 +02:00
platformSdkFinal bool
2021-12-08 18:00:38 +01:00
} {
{
name : "Non-Unbundled build: Android.bp has targetSdkVersion" ,
targetSdkVersionInBp : "30" ,
targetSdkVersionExpected : "30" ,
unbundledBuild : false ,
} ,
{
name : "Unbundled build: Android.bp has targetSdkVersion" ,
targetSdkVersionInBp : "30" ,
targetSdkVersionExpected : "30" ,
unbundledBuild : true ,
} ,
{
name : "Non-Unbundled build: Android.bp has targetSdkVersion equal to platform_sdk_codename" ,
targetSdkVersionInBp : platform_sdk_codename ,
targetSdkVersionExpected : platform_sdk_codename ,
unbundledBuild : false ,
} ,
{
name : "Unbundled build: Android.bp has targetSdkVersion equal to platform_sdk_codename" ,
targetSdkVersionInBp : platform_sdk_codename ,
targetSdkVersionExpected : "10000" ,
unbundledBuild : true ,
} ,
{
name : "Non-Unbundled build: Android.bp has no targetSdkVersion" ,
targetSdkVersionExpected : platform_sdk_codename ,
unbundledBuild : false ,
} ,
{
name : "Unbundled build: Android.bp has no targetSdkVersion" ,
targetSdkVersionExpected : "10000" ,
unbundledBuild : true ,
} ,
2023-04-27 18:08:26 +02:00
{
name : "Bundled build in REL branches" ,
targetSdkVersionExpected : "33" ,
unbundledBuild : false ,
platformSdkFinal : true ,
} ,
2021-12-08 18:00:38 +01:00
}
for _ , testCase := range testCases {
2023-03-02 00:38:49 +01:00
targetSdkVersionTemplate := ""
if testCase . targetSdkVersionInBp != "" {
targetSdkVersionTemplate = fmt . Sprintf ( ` target_sdk_version: "%s", ` , testCase . targetSdkVersionInBp )
}
2021-12-08 18:00:38 +01:00
bp := fmt . Sprintf ( `
android_app {
name : "foo" ,
sdk_version : "current" ,
2023-03-02 00:38:49 +01:00
% s
2021-12-08 18:00:38 +01:00
}
2023-03-02 00:38:49 +01:00
` , targetSdkVersionTemplate )
2021-12-08 18:00:38 +01:00
fixture := android . GroupFixturePreparers (
prepareForJavaTest ,
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
2023-04-27 18:08:26 +02:00
if testCase . platformSdkFinal {
variables . Platform_sdk_final = proptools . BoolPtr ( true )
}
2021-12-08 18:00:38 +01:00
// explicitly set platform_sdk_codename to make the test deterministic
variables . Platform_sdk_codename = & platform_sdk_codename
2023-04-27 18:08:26 +02:00
variables . Platform_sdk_version = & platform_sdk_version
2021-12-08 18:00:38 +01:00
variables . Platform_version_active_codenames = [ ] string { platform_sdk_codename }
// create a non-empty list if unbundledBuild==true
if testCase . unbundledBuild {
variables . Unbundled_build_apps = [ ] string { "apex_a" , "apex_b" }
}
} ) ,
)
result := fixture . RunTestWithBp ( t , bp )
foo := result . ModuleForTests ( "foo" , "android_common" )
2022-01-24 18:44:05 +01:00
manifestFixerArgs := foo . Output ( "manifest_fixer/AndroidManifest.xml" ) . Args [ "args" ]
android . AssertStringDoesContain ( t , testCase . name , manifestFixerArgs , "--targetSdkVersion " + testCase . targetSdkVersionExpected )
2021-12-08 18:00:38 +01:00
}
}
2022-04-08 02:40:07 +02:00
2022-06-10 13:24:05 +02:00
func TestDefaultAppTargetSdkVersionForUpdatableModules ( t * testing . T ) {
platform_sdk_codename := "Tiramisu"
platform_sdk_version := 33
testCases := [ ] struct {
name string
platform_sdk_final bool
targetSdkVersionInBp * string
targetSdkVersionExpected * string
updatable bool
} {
{
name : "Non-Updatable Module: Android.bp has older targetSdkVersion" ,
targetSdkVersionInBp : proptools . StringPtr ( "29" ) ,
targetSdkVersionExpected : proptools . StringPtr ( "29" ) ,
updatable : false ,
} ,
{
name : "Updatable Module: Android.bp has older targetSdkVersion" ,
targetSdkVersionInBp : proptools . StringPtr ( "30" ) ,
targetSdkVersionExpected : proptools . StringPtr ( "30" ) ,
updatable : true ,
} ,
{
name : "Updatable Module: Android.bp has no targetSdkVersion" ,
targetSdkVersionExpected : proptools . StringPtr ( "10000" ) ,
updatable : true ,
} ,
{
name : "[SDK finalised] Non-Updatable Module: Android.bp has older targetSdkVersion" ,
platform_sdk_final : true ,
targetSdkVersionInBp : proptools . StringPtr ( "30" ) ,
targetSdkVersionExpected : proptools . StringPtr ( "30" ) ,
updatable : false ,
} ,
{
name : "[SDK finalised] Updatable Module: Android.bp has older targetSdkVersion" ,
platform_sdk_final : true ,
targetSdkVersionInBp : proptools . StringPtr ( "30" ) ,
targetSdkVersionExpected : proptools . StringPtr ( "30" ) ,
updatable : true ,
} ,
{
name : "[SDK finalised] Updatable Module: Android.bp has targetSdkVersion as platform sdk codename" ,
platform_sdk_final : true ,
targetSdkVersionInBp : proptools . StringPtr ( platform_sdk_codename ) ,
targetSdkVersionExpected : proptools . StringPtr ( "33" ) ,
updatable : true ,
} ,
{
name : "[SDK finalised] Updatable Module: Android.bp has no targetSdkVersion" ,
platform_sdk_final : true ,
targetSdkVersionExpected : proptools . StringPtr ( "33" ) ,
updatable : true ,
} ,
}
for _ , testCase := range testCases {
2023-03-02 00:38:49 +01:00
targetSdkVersionTemplate := ""
if testCase . targetSdkVersionInBp != nil {
targetSdkVersionTemplate = fmt . Sprintf ( ` target_sdk_version: "%s", ` , * testCase . targetSdkVersionInBp )
}
2022-06-10 13:24:05 +02:00
bp := fmt . Sprintf ( `
android_app {
name : "foo" ,
sdk_version : "current" ,
min_sdk_version : "29" ,
2023-03-02 00:38:49 +01:00
% s
2022-06-10 13:24:05 +02:00
updatable : % t ,
enforce_default_target_sdk_version : % t
}
2023-03-02 00:38:49 +01:00
` , targetSdkVersionTemplate , testCase . updatable , testCase . updatable ) // enforce default target sdk version if app is updatable
2022-06-10 13:24:05 +02:00
fixture := android . GroupFixturePreparers (
PrepareForTestWithJavaDefaultModules ,
android . PrepareForTestWithAllowMissingDependencies ,
android . PrepareForTestWithAndroidMk ,
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
// explicitly set following platform variables to make the test deterministic
variables . Platform_sdk_final = & testCase . platform_sdk_final
variables . Platform_sdk_version = & platform_sdk_version
variables . Platform_sdk_codename = & platform_sdk_codename
variables . Platform_version_active_codenames = [ ] string { platform_sdk_codename }
2023-01-11 19:39:12 +01:00
variables . Unbundled_build = proptools . BoolPtr ( true )
2022-06-10 13:24:05 +02:00
variables . Unbundled_build_apps = [ ] string { "sampleModule" }
} ) ,
)
result := fixture . RunTestWithBp ( t , bp )
foo := result . ModuleForTests ( "foo" , "android_common" )
manifestFixerArgs := foo . Output ( "manifest_fixer/AndroidManifest.xml" ) . Args [ "args" ]
android . AssertStringDoesContain ( t , testCase . name , manifestFixerArgs , "--targetSdkVersion " + * testCase . targetSdkVersionExpected )
}
}
func TestEnforceDefaultAppTargetSdkVersionFlag ( t * testing . T ) {
platform_sdk_codename := "Tiramisu"
platform_sdk_version := 33
testCases := [ ] struct {
name string
enforceDefaultTargetSdkVersion bool
expectedError string
platform_sdk_final bool
targetSdkVersionInBp string
targetSdkVersionExpected string
updatable bool
} {
{
name : "Not enforcing Target SDK Version: Android.bp has older targetSdkVersion" ,
enforceDefaultTargetSdkVersion : false ,
targetSdkVersionInBp : "29" ,
targetSdkVersionExpected : "29" ,
updatable : false ,
} ,
{
name : "[SDK finalised] Enforce Target SDK Version: Android.bp has current targetSdkVersion" ,
enforceDefaultTargetSdkVersion : true ,
platform_sdk_final : true ,
targetSdkVersionInBp : "current" ,
targetSdkVersionExpected : "33" ,
updatable : true ,
} ,
{
2023-01-09 21:45:55 +01:00
name : "Enforce Target SDK Version: Android.bp has current targetSdkVersion" ,
2022-06-10 13:24:05 +02:00
enforceDefaultTargetSdkVersion : true ,
platform_sdk_final : false ,
targetSdkVersionInBp : "current" ,
targetSdkVersionExpected : "10000" ,
updatable : false ,
} ,
{
name : "Not enforcing Target SDK Version for Updatable app" ,
enforceDefaultTargetSdkVersion : false ,
expectedError : "Updatable apps must enforce default target sdk version" ,
targetSdkVersionInBp : "29" ,
targetSdkVersionExpected : "29" ,
updatable : true ,
} ,
}
for _ , testCase := range testCases {
errExpected := testCase . expectedError != ""
bp := fmt . Sprintf ( `
android_app {
name : "foo" ,
enforce_default_target_sdk_version : % t ,
sdk_version : "current" ,
min_sdk_version : "29" ,
target_sdk_version : "%v" ,
updatable : % t
}
` , testCase . enforceDefaultTargetSdkVersion , testCase . targetSdkVersionInBp , testCase . updatable )
fixture := android . GroupFixturePreparers (
2023-01-09 21:45:55 +01:00
PrepareForTestWithJavaDefaultModules ,
android . PrepareForTestWithAllowMissingDependencies ,
android . PrepareForTestWithAndroidMk ,
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
// explicitly set following platform variables to make the test deterministic
variables . Platform_sdk_final = & testCase . platform_sdk_final
variables . Platform_sdk_version = & platform_sdk_version
variables . Platform_sdk_codename = & platform_sdk_codename
2023-01-11 19:39:12 +01:00
variables . Unbundled_build = proptools . BoolPtr ( true )
2023-01-09 21:45:55 +01:00
variables . Unbundled_build_apps = [ ] string { "sampleModule" }
} ) ,
)
errorHandler := android . FixtureExpectsNoErrors
if errExpected {
errorHandler = android . FixtureExpectsAtLeastOneErrorMatchingPattern ( testCase . expectedError )
}
result := fixture . ExtendWithErrorHandler ( errorHandler ) . RunTestWithBp ( t , bp )
if ! errExpected {
foo := result . ModuleForTests ( "foo" , "android_common" )
manifestFixerArgs := foo . Output ( "manifest_fixer/AndroidManifest.xml" ) . Args [ "args" ]
android . AssertStringDoesContain ( t , testCase . name , manifestFixerArgs , "--targetSdkVersion " + testCase . targetSdkVersionExpected )
}
}
}
func TestEnforceDefaultAppTargetSdkVersionFlagForTests ( t * testing . T ) {
platform_sdk_codename := "Tiramisu"
platform_sdk_version := 33
testCases := [ ] struct {
name string
enforceDefaultTargetSdkVersion bool
expectedError string
platform_sdk_final bool
targetSdkVersionInBp string
targetSdkVersionExpected string
} {
{
name : "Not enforcing Target SDK Version: Android.bp has older targetSdkVersion" ,
enforceDefaultTargetSdkVersion : false ,
targetSdkVersionInBp : "29" ,
targetSdkVersionExpected : "29" ,
} ,
{
name : "[SDK finalised] Enforce Target SDK Version: Android.bp has current targetSdkVersion" ,
enforceDefaultTargetSdkVersion : true ,
platform_sdk_final : true ,
targetSdkVersionInBp : "current" ,
targetSdkVersionExpected : "33" ,
} ,
{
name : "Enforce Target SDK Version: Android.bp has current targetSdkVersion" ,
enforceDefaultTargetSdkVersion : true ,
platform_sdk_final : false ,
targetSdkVersionInBp : "current" ,
targetSdkVersionExpected : "10000" ,
} ,
}
for _ , testCase := range testCases {
errExpected := testCase . expectedError != ""
bp := fmt . Sprintf ( `
android_test {
name : "foo" ,
enforce_default_target_sdk_version : % t ,
min_sdk_version : "29" ,
target_sdk_version : "%v" ,
}
` , testCase . enforceDefaultTargetSdkVersion , testCase . targetSdkVersionInBp )
fixture := android . GroupFixturePreparers (
2022-06-10 13:24:05 +02:00
PrepareForTestWithJavaDefaultModules ,
android . PrepareForTestWithAllowMissingDependencies ,
android . PrepareForTestWithAndroidMk ,
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
// explicitly set following platform variables to make the test deterministic
variables . Platform_sdk_final = & testCase . platform_sdk_final
variables . Platform_sdk_version = & platform_sdk_version
variables . Platform_sdk_codename = & platform_sdk_codename
2023-01-11 19:39:12 +01:00
variables . Unbundled_build = proptools . BoolPtr ( true )
2022-06-10 13:24:05 +02:00
variables . Unbundled_build_apps = [ ] string { "sampleModule" }
} ) ,
)
errorHandler := android . FixtureExpectsNoErrors
if errExpected {
errorHandler = android . FixtureExpectsAtLeastOneErrorMatchingPattern ( testCase . expectedError )
}
result := fixture . ExtendWithErrorHandler ( errorHandler ) . RunTestWithBp ( t , bp )
if ! errExpected {
foo := result . ModuleForTests ( "foo" , "android_common" )
manifestFixerArgs := foo . Output ( "manifest_fixer/AndroidManifest.xml" ) . Args [ "args" ]
android . AssertStringDoesContain ( t , testCase . name , manifestFixerArgs , "--targetSdkVersion " + testCase . targetSdkVersionExpected )
}
}
}
2022-04-08 02:40:07 +02:00
func TestAppMissingCertificateAllowMissingDependencies ( t * testing . T ) {
result := android . GroupFixturePreparers (
PrepareForTestWithJavaDefaultModules ,
android . PrepareForTestWithAllowMissingDependencies ,
android . PrepareForTestWithAndroidMk ,
) . RunTestWithBp ( t , `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
certificate : ":missing_certificate" ,
sdk_version : "current" ,
2023-05-18 09:46:31 +02:00
}
android_app {
name : "bar" ,
srcs : [ "a.java" ] ,
certificate : ":missing_certificate" ,
product_specific : true ,
sdk_version : "current" ,
2022-04-08 02:40:07 +02:00
} ` )
foo := result . ModuleForTests ( "foo" , "android_common" )
fooApk := foo . Output ( "foo.apk" )
if fooApk . Rule != android . ErrorRule {
t . Fatalf ( "expected ErrorRule for foo.apk, got %s" , fooApk . Rule . String ( ) )
}
android . AssertStringDoesContain ( t , "expected error rule message" , fooApk . Args [ "error" ] , "missing dependencies: missing_certificate\n" )
}
2022-06-10 19:05:42 +02:00
func TestAppIncludesJniPackages ( t * testing . T ) {
ctx := android . GroupFixturePreparers (
PrepareForTestWithJavaDefaultModules ,
) . RunTestWithBp ( t , `
android_library_import {
name : "aary-nodeps" ,
aars : [ "aary.aar" ] ,
extract_jni : true ,
}
android_library {
name : "aary-lib" ,
sdk_version : "current" ,
min_sdk_version : "21" ,
static_libs : [ "aary-nodeps" ] ,
}
android_app {
name : "aary-lib-dep" ,
sdk_version : "current" ,
min_sdk_version : "21" ,
manifest : "AndroidManifest.xml" ,
static_libs : [ "aary-lib" ] ,
use_embedded_native_libs : true ,
}
android_app {
name : "aary-import-dep" ,
sdk_version : "current" ,
min_sdk_version : "21" ,
manifest : "AndroidManifest.xml" ,
static_libs : [ "aary-nodeps" ] ,
use_embedded_native_libs : true ,
}
android_app {
name : "aary-no-use-embedded" ,
sdk_version : "current" ,
min_sdk_version : "21" ,
manifest : "AndroidManifest.xml" ,
static_libs : [ "aary-nodeps" ] ,
} ` )
testCases := [ ] struct {
name string
hasPackage bool
} {
{
name : "aary-import-dep" ,
hasPackage : true ,
} ,
{
name : "aary-lib-dep" ,
hasPackage : true ,
} ,
{
name : "aary-no-use-embedded" ,
2024-05-14 19:09:54 +02:00
hasPackage : false ,
2022-06-10 19:05:42 +02:00
} ,
}
for _ , tc := range testCases {
t . Run ( tc . name , func ( t * testing . T ) {
app := ctx . ModuleForTests ( tc . name , "android_common" )
outputFile := "jnilibs.zip"
jniOutputLibZip := app . MaybeOutput ( outputFile )
if jniOutputLibZip . Rule == nil && ! tc . hasPackage {
return
}
jniPackage := "arm64-v8a_jni.zip"
inputs := jniOutputLibZip . Inputs
foundPackage := false
for i := 0 ; i < len ( inputs ) ; i ++ {
if strings . Contains ( inputs [ i ] . String ( ) , jniPackage ) {
foundPackage = true
}
}
if foundPackage != tc . hasPackage {
t . Errorf ( "expected to find %v in %v inputs; inputs = %v" , jniPackage , outputFile , inputs )
}
} )
}
}
2022-07-25 02:34:18 +02:00
func TestTargetSdkVersionMtsTests ( t * testing . T ) {
platformSdkCodename := "Tiramisu"
android_test := "android_test"
android_test_helper_app := "android_test_helper_app"
bpTemplate := `
% v {
name : "mytest" ,
target_sdk_version : "%v" ,
test_suites : [ "othersuite" , "%v" ] ,
}
`
testCases := [ ] struct {
desc string
moduleType string
targetSdkVersionInBp string
targetSdkVersionExpected string
testSuites string
} {
{
desc : "Non-MTS android_test_apps targeting current should not be upgraded to 10000" ,
moduleType : android_test ,
targetSdkVersionInBp : "current" ,
targetSdkVersionExpected : platformSdkCodename ,
testSuites : "non-mts-suite" ,
} ,
{
desc : "MTS android_test_apps targeting released sdks should not be upgraded to 10000" ,
moduleType : android_test ,
targetSdkVersionInBp : "29" ,
targetSdkVersionExpected : "29" ,
testSuites : "mts-suite" ,
} ,
{
desc : "MTS android_test_apps targeting current should be upgraded to 10000" ,
moduleType : android_test ,
targetSdkVersionInBp : "current" ,
targetSdkVersionExpected : "10000" ,
testSuites : "mts-suite" ,
} ,
{
desc : "MTS android_test_helper_apps targeting current should be upgraded to 10000" ,
moduleType : android_test_helper_app ,
targetSdkVersionInBp : "current" ,
targetSdkVersionExpected : "10000" ,
testSuites : "mts-suite" ,
} ,
}
fixture := android . GroupFixturePreparers (
prepareForJavaTest ,
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
variables . Platform_sdk_codename = & platformSdkCodename
variables . Platform_version_active_codenames = [ ] string { platformSdkCodename }
} ) ,
)
for _ , testCase := range testCases {
result := fixture . RunTestWithBp ( t , fmt . Sprintf ( bpTemplate , testCase . moduleType , testCase . targetSdkVersionInBp , testCase . testSuites ) )
mytest := result . ModuleForTests ( "mytest" , "android_common" )
manifestFixerArgs := mytest . Output ( "manifest_fixer/AndroidManifest.xml" ) . Args [ "args" ]
android . AssertStringDoesContain ( t , testCase . desc , manifestFixerArgs , "--targetSdkVersion " + testCase . targetSdkVersionExpected )
}
}
2022-08-17 18:53:46 +02:00
func TestPrivappAllowlist ( t * testing . T ) {
testJavaError ( t , "privileged must be set in order to use privapp_allowlist" , `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
privapp_allowlist : "perms.xml" ,
}
` )
result := PrepareForTestWithJavaDefaultModules . RunTestWithBp (
t ,
`
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
2023-05-15 23:21:47 +02:00
privapp_allowlist : "privapp_allowlist_com.android.foo.xml" ,
2022-08-17 18:53:46 +02:00
privileged : true ,
sdk_version : "current" ,
}
override_android_app {
name : "bar" ,
base : "foo" ,
package_name : "com.google.android.foo" ,
}
` ,
)
app := result . ModuleForTests ( "foo" , "android_common" )
overrideApp := result . ModuleForTests ( "foo" , "android_common_bar" )
2023-05-15 23:21:47 +02:00
// verify that privapp allowlist is created for override apps
2022-08-17 18:53:46 +02:00
overrideApp . Output ( "out/soong/.intermediates/foo/android_common_bar/privapp_allowlist_com.google.android.foo.xml" )
2023-05-15 23:21:47 +02:00
expectedAllowlistInput := "privapp_allowlist_com.android.foo.xml"
overrideActualAllowlistInput := overrideApp . Rule ( "modifyAllowlist" ) . Input . String ( )
if expectedAllowlistInput != overrideActualAllowlistInput {
t . Errorf ( "expected override allowlist to be %q; got %q" , expectedAllowlistInput , overrideActualAllowlistInput )
2022-08-17 18:53:46 +02:00
}
// verify that permissions are copied to device
2023-06-01 18:38:35 +02:00
app . Output ( "out/soong/target/product/test_device/system/etc/permissions/foo.xml" )
overrideApp . Output ( "out/soong/target/product/test_device/system/etc/permissions/bar.xml" )
2022-08-17 18:53:46 +02:00
}
2023-05-25 20:45:30 +02:00
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 ] ,
2023-06-01 18:38:35 +02:00
"privapp_allowlist_com.android.foo.xml:\\S+/target/product/test_device/system/etc/permissions/foo.xml" ,
2023-05-25 20:45:30 +02:00
)
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 ] ,
2023-06-01 18:38:35 +02:00
"\\S+soong/.intermediates/foo/android_common_bar/privapp_allowlist_com.google.android.foo.xml:\\S+/target/product/test_device/system/etc/permissions/bar.xml" ,
2023-05-25 20:45:30 +02:00
)
}
2023-08-19 00:43:28 +02:00
func TestApexGlobalMinSdkVersionOverride ( t * testing . T ) {
result := android . GroupFixturePreparers (
PrepareForTestWithJavaDefaultModules ,
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
variables . ApexGlobalMinSdkVersionOverride = proptools . StringPtr ( "Tiramisu" )
} ) ,
) . RunTestWithBp ( t , `
android_app {
name : "com.android.bar" ,
srcs : [ "a.java" ] ,
sdk_version : "current" ,
}
android_app {
name : "com.android.foo" ,
srcs : [ "a.java" ] ,
sdk_version : "current" ,
min_sdk_version : "S" ,
updatable : true ,
}
override_android_app {
name : "com.android.go.foo" ,
base : "com.android.foo" ,
}
` )
foo := result . ModuleForTests ( "com.android.foo" , "android_common" ) . Rule ( "manifestFixer" )
fooOverride := result . ModuleForTests ( "com.android.foo" , "android_common_com.android.go.foo" ) . Rule ( "manifestFixer" )
bar := result . ModuleForTests ( "com.android.bar" , "android_common" ) . Rule ( "manifestFixer" )
android . AssertStringDoesContain ( t ,
"expected manifest fixer to set com.android.bar minSdkVersion to S" ,
bar . BuildParams . Args [ "args" ] ,
"--minSdkVersion S" ,
)
android . AssertStringDoesContain ( t ,
"com.android.foo: expected manifest fixer to set minSdkVersion to T" ,
foo . BuildParams . Args [ "args" ] ,
"--minSdkVersion T" ,
)
android . AssertStringDoesContain ( t ,
"com.android.go.foo: expected manifest fixer to set minSdkVersion to T" ,
fooOverride . BuildParams . Args [ "args" ] ,
"--minSdkVersion T" ,
)
}
2023-12-01 23:01:06 +01:00
func TestAppFlagsPackages ( t * testing . T ) {
ctx := testApp ( t , `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
sdk_version : "current" ,
flags_packages : [
"bar" ,
"baz" ,
] ,
}
aconfig_declarations {
name : "bar" ,
2024-01-05 20:06:50 +01:00
package : "com.example.package.bar" ,
2024-04-24 18:41:57 +02:00
container : "com.android.foo" ,
2023-12-01 23:01:06 +01:00
srcs : [
"bar.aconfig" ,
] ,
}
aconfig_declarations {
name : "baz" ,
2024-01-05 20:06:50 +01:00
package : "com.example.package.baz" ,
2024-04-24 18:41:57 +02:00
container : "com.android.foo" ,
2023-12-01 23:01:06 +01:00
srcs : [
"baz.aconfig" ,
] ,
}
` )
foo := ctx . ModuleForTests ( "foo" , "android_common" )
// android_app module depends on aconfig_declarations listed in flags_packages
android . AssertBoolEquals ( t , "foo expected to depend on bar" , true ,
CheckModuleHasDependency ( t , ctx , "foo" , "android_common" , "bar" ) )
android . AssertBoolEquals ( t , "foo expected to depend on baz" , true ,
CheckModuleHasDependency ( t , ctx , "foo" , "android_common" , "baz" ) )
aapt2LinkRule := foo . Rule ( "android/soong/java.aapt2Link" )
linkInFlags := aapt2LinkRule . Args [ "inFlags" ]
android . AssertStringDoesContain ( t ,
"aapt2 link command expected to pass feature flags arguments" ,
linkInFlags ,
"--feature-flags @out/soong/.intermediates/bar/intermediate.txt --feature-flags @out/soong/.intermediates/baz/intermediate.txt" ,
)
}
2024-02-13 17:37:43 +01:00
// Test that dexpreopt is disabled if an optional_uses_libs exists, but does not provide an implementation.
func TestNoDexpreoptOptionalUsesLibDoesNotHaveImpl ( t * testing . T ) {
bp := `
java_sdk_library_import {
name : "sdklib_noimpl" ,
public : {
jars : [ "stub.jar" ] ,
} ,
}
android_app {
name : "app" ,
srcs : [ "a.java" ] ,
sdk_version : "current" ,
optional_uses_libs : [
"sdklib_noimpl" ,
] ,
}
`
result := prepareForJavaTest . RunTestWithBp ( t , bp )
dexpreopt := result . ModuleForTests ( "app" , "android_common" ) . MaybeRule ( "dexpreopt" ) . Rule
android . AssertBoolEquals ( t , "dexpreopt should be disabled if optional_uses_libs does not have an implementation" , true , dexpreopt == nil )
}
2024-03-15 10:29:29 +01:00
2024-04-12 20:23:19 +02:00
func TestTestOnlyApp ( t * testing . T ) {
t . Parallel ( )
ctx := android . GroupFixturePreparers (
prepareForJavaTest ,
) . RunTestWithBp ( t , `
// These should be test-only
android_test {
name : "android-test" ,
}
android_test_helper_app {
name : "helper-app" ,
}
override_android_test {
name : "override-test" ,
base : "android-app" ,
}
// And these should not be
android_app {
name : "android-app" ,
srcs : [ "b.java" ] ,
sdk_version : "current" ,
}
` )
expectedTestOnly := [ ] string {
"android-test" ,
"helper-app" ,
"override-test" ,
}
expectedTopLevel := [ ] string {
"android-test" ,
"override-test" ,
}
assertTestOnlyAndTopLevel ( t , ctx , expectedTestOnly , expectedTopLevel )
}
2024-03-15 10:29:29 +01:00
func TestAppStem ( t * testing . T ) {
ctx := testApp ( t , `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
stem : "foo-new" ,
sdk_version : "current" ,
} ` )
foo := ctx . ModuleForTests ( "foo" , "android_common" )
outputs := fmt . Sprint ( foo . AllOutputs ( ) )
if ! strings . Contains ( outputs , "foo-new.apk" ) {
t . Errorf ( "Module output does not contain expected apk %s" , "foo-new.apk" )
}
}