Refactor ResourcesLoader Tests
This change refactors the tests for ResourcesLoaders to support the
new concept of loaders owning providers.
Bug: 147359613
Test: atest ResourceLoaderTests
Change-Id: Id61dc27bf5876afe10c25ed57333541131e910b7
diff --git a/apct-tests/perftests/core/src/android/app/ResourcesManagerPerfTest.java b/apct-tests/perftests/core/src/android/app/ResourcesManagerPerfTest.java
index 2955d2c..050fecd 100644
--- a/apct-tests/perftests/core/src/android/app/ResourcesManagerPerfTest.java
+++ b/apct-tests/perftests/core/src/android/app/ResourcesManagerPerfTest.java
@@ -80,7 +80,7 @@
private void getResourcesForPath(String path) {
ResourcesManager.getInstance().getResources(null, path, null, null, null,
Display.DEFAULT_DISPLAY, null, sContext.getResources().getCompatibilityInfo(),
- null);
+ null, null);
}
@Test
diff --git a/apct-tests/perftests/core/src/android/app/ResourcesThemePerfTest.java b/apct-tests/perftests/core/src/android/app/ResourcesThemePerfTest.java
index 6123e69..f4c0a17 100644
--- a/apct-tests/perftests/core/src/android/app/ResourcesThemePerfTest.java
+++ b/apct-tests/perftests/core/src/android/app/ResourcesThemePerfTest.java
@@ -96,7 +96,7 @@
Resources destResources = resourcesManager.getResources(null, ai.sourceDir,
ai.splitSourceDirs, ai.resourceDirs, ai.sharedLibraryFiles, Display.DEFAULT_DISPLAY,
- c, mContext.getResources().getCompatibilityInfo(), null);
+ c, mContext.getResources().getCompatibilityInfo(), null, null);
Assert.assertNotEquals(destResources.getAssets(), mContext.getAssets());
Resources.Theme destTheme = destResources.newTheme();
diff --git a/core/tests/ResourceLoaderTests/Android.bp b/core/tests/ResourceLoaderTests/Android.bp
index 53db832..fec4628 100644
--- a/core/tests/ResourceLoaderTests/Android.bp
+++ b/core/tests/ResourceLoaderTests/Android.bp
@@ -32,15 +32,16 @@
"truth-prebuilt",
],
resource_zips: [ ":FrameworksResourceLoaderTestsAssets" ],
+ platform_apis: true,
test_suites: ["device-tests"],
- sdk_version: "test_current",
aaptflags: [
"--no-compress",
],
data: [
- ":FrameworksResourceLoaderTestsOverlay",
":FrameworksResourceLoaderTestsSplitOne",
":FrameworksResourceLoaderTestsSplitTwo",
+ ":FrameworksResourceLoaderTestsSplitThree",
+ ":FrameworksResourceLoaderTestsSplitFour",
],
java_resources: [ "NonAsset.txt" ]
}
diff --git a/core/tests/ResourceLoaderTests/AndroidTest.xml b/core/tests/ResourceLoaderTests/AndroidTest.xml
index 702151d..d732132 100644
--- a/core/tests/ResourceLoaderTests/AndroidTest.xml
+++ b/core/tests/ResourceLoaderTests/AndroidTest.xml
@@ -22,13 +22,7 @@
<option name="cleanup-apks" value="true" />
<!-- The following value cannot be multi-line as whitespace is parsed by the installer -->
<option name="split-apk-file-names"
- value="FrameworksResourceLoaderTests.apk,FrameworksResourceLoaderTestsSplitOne.apk,FrameworksResourceLoaderTestsSplitTwo.apk" />
- <option name="test-file-name" value="FrameworksResourceLoaderTestsOverlay.apk" />
- </target_preparer>
-
- <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
- <option name="run-command"
- value="cmd overlay disable android.content.res.loader.test.overlay" />
+ value="FrameworksResourceLoaderTests.apk,FrameworksResourceLoaderTestsSplitOne.apk,FrameworksResourceLoaderTestsSplitTwo.apk,FrameworksResourceLoaderTestsSplitThree.apk,FrameworksResourceLoaderTestsSplitFour.apk" />
</target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest">
diff --git a/core/tests/ResourceLoaderTests/res/drawable-nodpi/non_asset_bitmap.png b/core/tests/ResourceLoaderTests/res/drawable-nodpi/non_asset_bitmap.png
index efd71ee..8102d15 100644
--- a/core/tests/ResourceLoaderTests/res/drawable-nodpi/non_asset_bitmap.png
+++ b/core/tests/ResourceLoaderTests/res/drawable-nodpi/non_asset_bitmap.png
Binary files differ
diff --git a/core/tests/ResourceLoaderTests/res/layout/layout.xml b/core/tests/ResourceLoaderTests/res/layout/layout.xml
index d59059b..05499ed 100644
--- a/core/tests/ResourceLoaderTests/res/layout/layout.xml
+++ b/core/tests/ResourceLoaderTests/res/layout/layout.xml
@@ -15,7 +15,7 @@
~ limitations under the License.
-->
-<FrameLayout
+<MysteryLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
diff --git a/core/tests/ResourceLoaderTests/resources/compileAndLink.sh b/core/tests/ResourceLoaderTests/resources/compileAndLink.sh
index 885f681..8e05aef 100755
--- a/core/tests/ResourceLoaderTests/resources/compileAndLink.sh
+++ b/core/tests/ResourceLoaderTests/resources/compileAndLink.sh
@@ -68,9 +68,13 @@
compileAndLink stringOne BOTH AndroidManifestFramework.xml res/values/string_one.xml
compileAndLink stringTwo BOTH AndroidManifestFramework.xml res/values/string_two.xml
+compileAndLink stringThree BOTH AndroidManifestFramework.xml res/values/string_three.xml
+compileAndLink stringFour BOTH AndroidManifestFramework.xml res/values/string_four.xml
compileAndLink dimenOne BOTH AndroidManifestFramework.xml res/values/dimen_one.xml
compileAndLink dimenTwo BOTH AndroidManifestFramework.xml res/values/dimen_two.xml
+compileAndLink dimenThree BOTH AndroidManifestFramework.xml res/values/dimen_three.xml
+compileAndLink dimenFour BOTH AndroidManifestFramework.xml res/values/dimen_four.xml
compileAndLink drawableMdpiWithoutFile BOTH_WITHOUT_FILE AndroidManifestFramework.xml res/values/drawable_one.xml res/drawable-mdpi/ic_delete.png
compileAndLink drawableMdpiWithFile APK AndroidManifestFramework.xml res/values/drawable_one.xml res/drawable-mdpi/ic_delete.png
@@ -86,6 +90,14 @@
compileAndLink layoutTwo ARSC AndroidManifestApp.xml "$genDir"/temp/res/layout/layout.xml res/values/layout_id.xml
cp -f "$genDir"/out/layoutTwo/unzip/res/layout/layout.xml "$genDir"/output/raw/layoutTwo.xml
+cp -f "$inDir"/res/layout/layout_three.xml "$genDir"/temp/res/layout/layout.xml
+compileAndLink layoutThree ARSC AndroidManifestApp.xml "$genDir"/temp/res/layout/layout.xml res/values/layout_id.xml
+cp -f "$genDir"/out/layoutThree/unzip/res/layout/layout.xml "$genDir"/output/raw/layoutThree.xml
+
+cp -f "$inDir"/res/layout/layout_four.xml "$genDir"/temp/res/layout/layout.xml
+compileAndLink layoutFour ARSC AndroidManifestApp.xml "$genDir"/temp/res/layout/layout.xml res/values/layout_id.xml
+cp -f "$genDir"/out/layoutFour/unzip/res/layout/layout.xml "$genDir"/output/raw/layoutFour.xml
+
drawableNoDpi="/res/drawable-nodpi"
inDirDrawableNoDpi="$inDir$drawableNoDpi"
@@ -97,6 +109,18 @@
compileAndLink nonAssetDrawableTwo ARSC AndroidManifestApp.xml "$genDir"/temp/res/drawable-nodpi/non_asset_drawable.xml res/values/non_asset_drawable_id.xml
cp -f "$genDir"/out/nonAssetDrawableTwo/unzip/res/drawable-nodpi-v4/non_asset_drawable.xml "$genDir"/output/raw/nonAssetDrawableTwo.xml
+cp -f "$inDirDrawableNoDpi"/nonAssetDrawableThree.xml "$genDir"/temp/res/drawable-nodpi/non_asset_drawable.xml
+compileAndLink nonAssetDrawableThree ARSC AndroidManifestApp.xml "$genDir"/temp/res/drawable-nodpi/non_asset_drawable.xml res/values/non_asset_drawable_id.xml
+cp -f "$genDir"/out/nonAssetDrawableThree/unzip/res/drawable-nodpi-v4/non_asset_drawable.xml "$genDir"/output/raw/nonAssetDrawableThree.xml
+
+cp -f "$inDirDrawableNoDpi"/nonAssetDrawableFour.xml "$genDir"/temp/res/drawable-nodpi/non_asset_drawable.xml
+compileAndLink nonAssetDrawableFour ARSC AndroidManifestApp.xml "$genDir"/temp/res/drawable-nodpi/non_asset_drawable.xml res/values/non_asset_drawable_id.xml
+cp -f "$genDir"/out/nonAssetDrawableFour/unzip/res/drawable-nodpi-v4/non_asset_drawable.xml "$genDir"/output/raw/nonAssetDrawableFour.xml
+
+cp -f "$inDirDrawableNoDpi"/nonAssetBitmapRed.png "$genDir"/temp/res/drawable-nodpi/non_asset_bitmap.png
+compileAndLink nonAssetBitmapRed BOTH AndroidManifestApp.xml "$genDir"/temp/res/drawable-nodpi/non_asset_bitmap.png res/values/non_asset_bitmap_id.xml
+cp -f "$genDir"/out/nonAssetBitmapRed/unzip/res/drawable-nodpi-v4/non_asset_bitmap.png "$genDir"/output/raw/nonAssetBitmapRed.png
+
cp -f "$inDirDrawableNoDpi"/nonAssetBitmapGreen.png "$genDir"/temp/res/drawable-nodpi/non_asset_bitmap.png
compileAndLink nonAssetBitmapGreen BOTH AndroidManifestApp.xml "$genDir"/temp/res/drawable-nodpi/non_asset_bitmap.png res/values/non_asset_bitmap_id.xml
cp -f "$genDir"/out/nonAssetBitmapGreen/unzip/res/drawable-nodpi-v4/non_asset_bitmap.png "$genDir"/output/raw/nonAssetBitmapGreen.png
@@ -105,4 +129,8 @@
compileAndLink nonAssetBitmapBlue ARSC AndroidManifestApp.xml "$genDir"/temp/res/drawable-nodpi/non_asset_bitmap.png res/values/non_asset_bitmap_id.xml
cp -f "$genDir"/out/nonAssetBitmapBlue/unzip/res/drawable-nodpi-v4/non_asset_bitmap.png "$genDir"/output/raw/nonAssetBitmapBlue.png
+cp -f "$inDirDrawableNoDpi"/nonAssetBitmapWhite.png "$genDir"/temp/res/drawable-nodpi/non_asset_bitmap.png
+compileAndLink nonAssetBitmapWhite ARSC AndroidManifestApp.xml "$genDir"/temp/res/drawable-nodpi/non_asset_bitmap.png res/values/non_asset_bitmap_id.xml
+cp -f "$genDir"/out/nonAssetBitmapWhite/unzip/res/drawable-nodpi-v4/non_asset_bitmap.png "$genDir"/output/raw/nonAssetBitmapWhite.png
+
$soong_zip -o "$genDir"/out.zip -C "$genDir"/output/ -D "$genDir"/output/
diff --git a/core/tests/ResourceLoaderTests/resources/res/drawable-nodpi/nonAssetBitmapRed.png b/core/tests/ResourceLoaderTests/resources/res/drawable-nodpi/nonAssetBitmapRed.png
new file mode 100644
index 0000000..4eb8ca3
--- /dev/null
+++ b/core/tests/ResourceLoaderTests/resources/res/drawable-nodpi/nonAssetBitmapRed.png
Binary files differ
diff --git a/core/tests/ResourceLoaderTests/resources/res/drawable-nodpi/nonAssetBitmapWhite.png b/core/tests/ResourceLoaderTests/resources/res/drawable-nodpi/nonAssetBitmapWhite.png
new file mode 100644
index 0000000..e9a4cfc
--- /dev/null
+++ b/core/tests/ResourceLoaderTests/resources/res/drawable-nodpi/nonAssetBitmapWhite.png
Binary files differ
diff --git a/core/tests/ResourceLoaderTests/overlay/res/values/strings.xml b/core/tests/ResourceLoaderTests/resources/res/drawable-nodpi/nonAssetDrawableFour.xml
similarity index 78%
copy from core/tests/ResourceLoaderTests/overlay/res/values/strings.xml
copy to core/tests/ResourceLoaderTests/resources/res/drawable-nodpi/nonAssetDrawableFour.xml
index 348bb35..0623245 100644
--- a/core/tests/ResourceLoaderTests/overlay/res/values/strings.xml
+++ b/core/tests/ResourceLoaderTests/resources/res/drawable-nodpi/nonAssetDrawableFour.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- ~ Copyright (C) 2019 The Android Open Source Project
+ ~ Copyright (C) 2020 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
@@ -15,8 +15,7 @@
~ limitations under the License.
-->
-<resources>
-
- <string name="loader_path_change_test">Overlaid</string>
-
-</resources>
+<color
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:color="#000004"
+ />
diff --git a/core/tests/ResourceLoaderTests/resources/res/drawable-nodpi/nonAssetDrawableOne.xml b/core/tests/ResourceLoaderTests/resources/res/drawable-nodpi/nonAssetDrawableOne.xml
index f1a93d2..57a8cf1 100644
--- a/core/tests/ResourceLoaderTests/resources/res/drawable-nodpi/nonAssetDrawableOne.xml
+++ b/core/tests/ResourceLoaderTests/resources/res/drawable-nodpi/nonAssetDrawableOne.xml
@@ -17,5 +17,5 @@
<color
xmlns:android="http://schemas.android.com/apk/res/android"
- android:color="#A3C3E3"
+ android:color="#000001"
/>
diff --git a/core/tests/ResourceLoaderTests/overlay/res/values/strings.xml b/core/tests/ResourceLoaderTests/resources/res/drawable-nodpi/nonAssetDrawableThree.xml
similarity index 78%
copy from core/tests/ResourceLoaderTests/overlay/res/values/strings.xml
copy to core/tests/ResourceLoaderTests/resources/res/drawable-nodpi/nonAssetDrawableThree.xml
index 348bb35..41095d4 100644
--- a/core/tests/ResourceLoaderTests/overlay/res/values/strings.xml
+++ b/core/tests/ResourceLoaderTests/resources/res/drawable-nodpi/nonAssetDrawableThree.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- ~ Copyright (C) 2019 The Android Open Source Project
+ ~ Copyright (C) 2020 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
@@ -15,8 +15,7 @@
~ limitations under the License.
-->
-<resources>
-
- <string name="loader_path_change_test">Overlaid</string>
-
-</resources>
+<color
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:color="#000003"
+ />
diff --git a/core/tests/ResourceLoaderTests/resources/res/drawable-nodpi/nonAssetDrawableTwo.xml b/core/tests/ResourceLoaderTests/resources/res/drawable-nodpi/nonAssetDrawableTwo.xml
index 7c455a5..333fe34 100644
--- a/core/tests/ResourceLoaderTests/resources/res/drawable-nodpi/nonAssetDrawableTwo.xml
+++ b/core/tests/ResourceLoaderTests/resources/res/drawable-nodpi/nonAssetDrawableTwo.xml
@@ -17,5 +17,5 @@
<color
xmlns:android="http://schemas.android.com/apk/res/android"
- android:color="#3A3C3E"
+ android:color="#000002"
/>
diff --git a/core/tests/ResourceLoaderTests/overlay/res/values/strings.xml b/core/tests/ResourceLoaderTests/resources/res/layout/layout_four.xml
similarity index 73%
copy from core/tests/ResourceLoaderTests/overlay/res/values/strings.xml
copy to core/tests/ResourceLoaderTests/resources/res/layout/layout_four.xml
index 348bb35..ab9e265 100644
--- a/core/tests/ResourceLoaderTests/overlay/res/values/strings.xml
+++ b/core/tests/ResourceLoaderTests/resources/res/layout/layout_four.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- ~ Copyright (C) 2019 The Android Open Source Project
+ ~ Copyright (C) 2020 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
@@ -15,8 +15,9 @@
~ limitations under the License.
-->
-<resources>
+<TableLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ />
- <string name="loader_path_change_test">Overlaid</string>
-
-</resources>
diff --git a/core/tests/ResourceLoaderTests/overlay/res/values/strings.xml b/core/tests/ResourceLoaderTests/resources/res/layout/layout_three.xml
similarity index 73%
copy from core/tests/ResourceLoaderTests/overlay/res/values/strings.xml
copy to core/tests/ResourceLoaderTests/resources/res/layout/layout_three.xml
index 348bb35..d58d3db 100644
--- a/core/tests/ResourceLoaderTests/overlay/res/values/strings.xml
+++ b/core/tests/ResourceLoaderTests/resources/res/layout/layout_three.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- ~ Copyright (C) 2019 The Android Open Source Project
+ ~ Copyright (C) 2020 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
@@ -15,8 +15,9 @@
~ limitations under the License.
-->
-<resources>
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ />
- <string name="loader_path_change_test">Overlaid</string>
-
-</resources>
diff --git a/core/tests/ResourceLoaderTests/overlay/res/values/strings.xml b/core/tests/ResourceLoaderTests/resources/res/values/dimen_four.xml
similarity index 79%
copy from core/tests/ResourceLoaderTests/overlay/res/values/strings.xml
copy to core/tests/ResourceLoaderTests/resources/res/values/dimen_four.xml
index 348bb35..5b30eba 100644
--- a/core/tests/ResourceLoaderTests/overlay/res/values/strings.xml
+++ b/core/tests/ResourceLoaderTests/resources/res/values/dimen_four.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- ~ Copyright (C) 2019 The Android Open Source Project
+ ~ Copyright (C) 2020 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
-->
<resources>
-
- <string name="loader_path_change_test">Overlaid</string>
-
+ <public type="dimen" name="app_icon_size" id="0x01050000" />
+ <dimen name="app_icon_size">400dp</dimen>
</resources>
diff --git a/core/tests/ResourceLoaderTests/resources/res/values/dimen_one.xml b/core/tests/ResourceLoaderTests/resources/res/values/dimen_one.xml
index 69ecf23..b17ec1c 100644
--- a/core/tests/ResourceLoaderTests/resources/res/values/dimen_one.xml
+++ b/core/tests/ResourceLoaderTests/resources/res/values/dimen_one.xml
@@ -17,5 +17,5 @@
<resources>
<public type="dimen" name="app_icon_size" id="0x01050000" />
- <dimen name="app_icon_size">564716dp</dimen>
+ <dimen name="app_icon_size">100dp</dimen>
</resources>
diff --git a/core/tests/ResourceLoaderTests/overlay/res/values/strings.xml b/core/tests/ResourceLoaderTests/resources/res/values/dimen_three.xml
similarity index 79%
rename from core/tests/ResourceLoaderTests/overlay/res/values/strings.xml
rename to core/tests/ResourceLoaderTests/resources/res/values/dimen_three.xml
index 348bb35..07a35ce 100644
--- a/core/tests/ResourceLoaderTests/overlay/res/values/strings.xml
+++ b/core/tests/ResourceLoaderTests/resources/res/values/dimen_three.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- ~ Copyright (C) 2019 The Android Open Source Project
+ ~ Copyright (C) 2020 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
-->
<resources>
-
- <string name="loader_path_change_test">Overlaid</string>
-
+ <public type="dimen" name="app_icon_size" id="0x01050000" />
+ <dimen name="app_icon_size">300dp</dimen>
</resources>
diff --git a/core/tests/ResourceLoaderTests/resources/res/values/dimen_two.xml b/core/tests/ResourceLoaderTests/resources/res/values/dimen_two.xml
index 4d55def..570b40a 100644
--- a/core/tests/ResourceLoaderTests/resources/res/values/dimen_two.xml
+++ b/core/tests/ResourceLoaderTests/resources/res/values/dimen_two.xml
@@ -17,5 +17,5 @@
<resources>
<public type="dimen" name="app_icon_size" id="0x01050000" />
- <dimen name="app_icon_size">565717dp</dimen>
+ <dimen name="app_icon_size">200dp</dimen>
</resources>
diff --git a/core/tests/ResourceLoaderTests/overlay/res/values/strings.xml b/core/tests/ResourceLoaderTests/resources/res/values/string_four.xml
similarity index 77%
copy from core/tests/ResourceLoaderTests/overlay/res/values/strings.xml
copy to core/tests/ResourceLoaderTests/resources/res/values/string_four.xml
index 348bb35..8789bcd 100644
--- a/core/tests/ResourceLoaderTests/overlay/res/values/strings.xml
+++ b/core/tests/ResourceLoaderTests/resources/res/values/string_four.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- ~ Copyright (C) 2019 The Android Open Source Project
+ ~ Copyright (C) 2020 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
-->
<resources>
-
- <string name="loader_path_change_test">Overlaid</string>
-
+ <public type="string" name="cancel" id="0x01040000" />
+ <string name="cancel">SomeRidiculouslyUnlikelyStringFour</string>
</resources>
diff --git a/core/tests/ResourceLoaderTests/overlay/res/values/strings.xml b/core/tests/ResourceLoaderTests/resources/res/values/string_three.xml
similarity index 77%
copy from core/tests/ResourceLoaderTests/overlay/res/values/strings.xml
copy to core/tests/ResourceLoaderTests/resources/res/values/string_three.xml
index 348bb35..82cd6ec 100644
--- a/core/tests/ResourceLoaderTests/overlay/res/values/strings.xml
+++ b/core/tests/ResourceLoaderTests/resources/res/values/string_three.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- ~ Copyright (C) 2019 The Android Open Source Project
+ ~ Copyright (C) 2020 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
-->
<resources>
-
- <string name="loader_path_change_test">Overlaid</string>
-
+ <public type="string" name="cancel" id="0x01040000" />
+ <string name="cancel">SomeRidiculouslyUnlikelyStringThree</string>
</resources>
diff --git a/core/tests/ResourceLoaderTests/overlay/Android.bp b/core/tests/ResourceLoaderTests/splits/SplitFour/Android.bp
similarity index 74%
rename from core/tests/ResourceLoaderTests/overlay/Android.bp
rename to core/tests/ResourceLoaderTests/splits/SplitFour/Android.bp
index 63e7e61..eb4d8e1 100644
--- a/core/tests/ResourceLoaderTests/overlay/Android.bp
+++ b/core/tests/ResourceLoaderTests/splits/SplitFour/Android.bp
@@ -1,4 +1,5 @@
-// Copyright (C) 2018 The Android Open Source Project
+//
+// Copyright (C) 2019 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -11,10 +12,8 @@
// 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.
+//
-android_test {
- name: "FrameworksResourceLoaderTestsOverlay",
- sdk_version: "current",
-
- aaptflags: ["--no-resource-removal"],
+android_test_helper_app {
+ name: "FrameworksResourceLoaderTestsSplitFour"
}
diff --git a/core/tests/ResourceLoaderTests/overlay/AndroidManifest.xml b/core/tests/ResourceLoaderTests/splits/SplitFour/AndroidManifest.xml
similarity index 79%
copy from core/tests/ResourceLoaderTests/overlay/AndroidManifest.xml
copy to core/tests/ResourceLoaderTests/splits/SplitFour/AndroidManifest.xml
index 942f7da..24a0a2a 100644
--- a/core/tests/ResourceLoaderTests/overlay/AndroidManifest.xml
+++ b/core/tests/ResourceLoaderTests/splits/SplitFour/AndroidManifest.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- ~ Copyright (C) 2019 The Android Open Source Project
+ ~ Copyright (C) 2020 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
@@ -17,11 +17,11 @@
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.content.res.loader.test.overlay"
+ package="android.content.res.loader.test"
+ split="split_four"
>
+ <uses-sdk android:minSdkVersion="1" android:targetSdkVersion="1" />
<application android:hasCode="false" />
- <overlay android:targetPackage="android.content.res.loader.test" />
-
</manifest>
diff --git a/core/tests/ResourceLoaderTests/overlay/res/values/strings.xml b/core/tests/ResourceLoaderTests/splits/SplitFour/res/values/string_split.xml
similarity index 77%
copy from core/tests/ResourceLoaderTests/overlay/res/values/strings.xml
copy to core/tests/ResourceLoaderTests/splits/SplitFour/res/values/string_split.xml
index 348bb35..4759db9 100644
--- a/core/tests/ResourceLoaderTests/overlay/res/values/strings.xml
+++ b/core/tests/ResourceLoaderTests/splits/SplitFour/res/values/string_split.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- ~ Copyright (C) 2019 The Android Open Source Project
+ ~ Copyright (C) 2020 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
-->
<resources>
-
- <string name="loader_path_change_test">Overlaid</string>
-
+ <public type="string" name="split_overlaid" id="0x7f040001" />
+ <string name="split_overlaid">Split FOUR Overlaid</string>
</resources>
diff --git a/core/tests/ResourceLoaderTests/SplitOne/Android.bp b/core/tests/ResourceLoaderTests/splits/SplitOne/Android.bp
similarity index 100%
rename from core/tests/ResourceLoaderTests/SplitOne/Android.bp
rename to core/tests/ResourceLoaderTests/splits/SplitOne/Android.bp
diff --git a/core/tests/ResourceLoaderTests/SplitOne/AndroidManifest.xml b/core/tests/ResourceLoaderTests/splits/SplitOne/AndroidManifest.xml
similarity index 100%
rename from core/tests/ResourceLoaderTests/SplitOne/AndroidManifest.xml
rename to core/tests/ResourceLoaderTests/splits/SplitOne/AndroidManifest.xml
diff --git a/core/tests/ResourceLoaderTests/SplitOne/res/values/string_split_one.xml b/core/tests/ResourceLoaderTests/splits/SplitOne/res/values/string_split.xml
similarity index 100%
rename from core/tests/ResourceLoaderTests/SplitOne/res/values/string_split_one.xml
rename to core/tests/ResourceLoaderTests/splits/SplitOne/res/values/string_split.xml
diff --git a/core/tests/ResourceLoaderTests/overlay/Android.bp b/core/tests/ResourceLoaderTests/splits/SplitThree/Android.bp
similarity index 74%
copy from core/tests/ResourceLoaderTests/overlay/Android.bp
copy to core/tests/ResourceLoaderTests/splits/SplitThree/Android.bp
index 63e7e61..bf98a74 100644
--- a/core/tests/ResourceLoaderTests/overlay/Android.bp
+++ b/core/tests/ResourceLoaderTests/splits/SplitThree/Android.bp
@@ -1,4 +1,5 @@
-// Copyright (C) 2018 The Android Open Source Project
+//
+// Copyright (C) 2019 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -11,10 +12,8 @@
// 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.
+//
-android_test {
- name: "FrameworksResourceLoaderTestsOverlay",
- sdk_version: "current",
-
- aaptflags: ["--no-resource-removal"],
+android_test_helper_app {
+ name: "FrameworksResourceLoaderTestsSplitThree"
}
diff --git a/core/tests/ResourceLoaderTests/overlay/AndroidManifest.xml b/core/tests/ResourceLoaderTests/splits/SplitThree/AndroidManifest.xml
similarity index 79%
rename from core/tests/ResourceLoaderTests/overlay/AndroidManifest.xml
rename to core/tests/ResourceLoaderTests/splits/SplitThree/AndroidManifest.xml
index 942f7da..ae1579b 100644
--- a/core/tests/ResourceLoaderTests/overlay/AndroidManifest.xml
+++ b/core/tests/ResourceLoaderTests/splits/SplitThree/AndroidManifest.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- ~ Copyright (C) 2019 The Android Open Source Project
+ ~ Copyright (C) 2020 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
@@ -17,11 +17,11 @@
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.content.res.loader.test.overlay"
+ package="android.content.res.loader.test"
+ split="split_three"
>
+ <uses-sdk android:minSdkVersion="1" android:targetSdkVersion="1" />
<application android:hasCode="false" />
- <overlay android:targetPackage="android.content.res.loader.test" />
-
</manifest>
diff --git a/core/tests/ResourceLoaderTests/overlay/res/values/strings.xml b/core/tests/ResourceLoaderTests/splits/SplitThree/res/values/string_spli.xml
similarity index 77%
copy from core/tests/ResourceLoaderTests/overlay/res/values/strings.xml
copy to core/tests/ResourceLoaderTests/splits/SplitThree/res/values/string_spli.xml
index 348bb35..97682aa 100644
--- a/core/tests/ResourceLoaderTests/overlay/res/values/strings.xml
+++ b/core/tests/ResourceLoaderTests/splits/SplitThree/res/values/string_spli.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- ~ Copyright (C) 2019 The Android Open Source Project
+ ~ Copyright (C) 2020 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
-->
<resources>
-
- <string name="loader_path_change_test">Overlaid</string>
-
+ <public type="string" name="split_overlaid" id="0x7f040001" />
+ <string name="split_overlaid">Split THREE Overlaid</string>
</resources>
diff --git a/core/tests/ResourceLoaderTests/splits/Android.bp b/core/tests/ResourceLoaderTests/splits/SplitTwo/Android.bp
similarity index 100%
rename from core/tests/ResourceLoaderTests/splits/Android.bp
rename to core/tests/ResourceLoaderTests/splits/SplitTwo/Android.bp
diff --git a/core/tests/ResourceLoaderTests/splits/AndroidManifest.xml b/core/tests/ResourceLoaderTests/splits/SplitTwo/AndroidManifest.xml
similarity index 100%
rename from core/tests/ResourceLoaderTests/splits/AndroidManifest.xml
rename to core/tests/ResourceLoaderTests/splits/SplitTwo/AndroidManifest.xml
diff --git a/core/tests/ResourceLoaderTests/splits/res/values/string_split_two.xml b/core/tests/ResourceLoaderTests/splits/SplitTwo/res/values/string_split.xml
similarity index 100%
rename from core/tests/ResourceLoaderTests/splits/res/values/string_split_two.xml
rename to core/tests/ResourceLoaderTests/splits/SplitTwo/res/values/string_split.xml
diff --git a/core/tests/ResourceLoaderTests/src/android/content/res/loader/test/DirectoryResourceLoaderTest.kt b/core/tests/ResourceLoaderTests/src/android/content/res/loader/test/DirectoryAssetsProviderTest.kt
similarity index 68%
rename from core/tests/ResourceLoaderTests/src/android/content/res/loader/test/DirectoryResourceLoaderTest.kt
rename to core/tests/ResourceLoaderTests/src/android/content/res/loader/test/DirectoryAssetsProviderTest.kt
index b1bdc96..9e94bdc 100644
--- a/core/tests/ResourceLoaderTests/src/android/content/res/loader/test/DirectoryResourceLoaderTest.kt
+++ b/core/tests/ResourceLoaderTests/src/android/content/res/loader/test/DirectoryAssetsProviderTest.kt
@@ -16,8 +16,9 @@
package android.content.res.loader.test
-import android.content.res.loader.DirectoryResourceLoader
-import android.content.res.loader.ResourceLoader
+import android.content.res.loader.AssetsProvider
+import android.content.res.loader.DirectoryAssetsProvider
+import android.content.res.loader.ResourcesLoader
import android.graphics.Color
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.ColorDrawable
@@ -29,18 +30,21 @@
import org.junit.rules.TestName
import java.io.File
-class DirectoryResourceLoaderTest : ResourceLoaderTestBase() {
+class DirectoryAssetsProviderTest : ResourceLoaderTestBase() {
@get:Rule
val testName = TestName()
private lateinit var testDir: File
- private lateinit var loader: ResourceLoader
+ private lateinit var assetsProvider: AssetsProvider
+ private lateinit var loader: ResourcesLoader
@Before
fun setUpTestDir() {
- testDir = context.filesDir.resolve("DirectoryResourceLoaderTest_${testName.methodName}")
- loader = DirectoryResourceLoader(testDir)
+ testDir = context.filesDir.resolve("DirectoryAssetsProvider_${testName.methodName}")
+ assetsProvider = DirectoryAssetsProvider(testDir)
+ loader = ResourcesLoader()
+ resources.addLoader(loader)
}
@After
@@ -51,29 +55,29 @@
@Test
fun loadDrawableXml() {
"nonAssetDrawableOne" writeTo "res/drawable-nodpi-v4/non_asset_drawable.xml"
- val provider = openArsc("nonAssetDrawableOne")
+ val provider = openArsc("nonAssetDrawableOne", assetsProvider)
fun getValue() = (resources.getDrawable(R.drawable.non_asset_drawable) as ColorDrawable)
.color
assertThat(getValue()).isEqualTo(Color.parseColor("#B2D2F2"))
- addLoader(loader to provider)
+ loader.addProvider(provider)
- assertThat(getValue()).isEqualTo(Color.parseColor("#A3C3E3"))
+ assertThat(getValue()).isEqualTo(Color.parseColor("#000001"))
}
@Test
fun loadDrawableBitmap() {
"nonAssetBitmapGreen" writeTo "res/drawable-nodpi-v4/non_asset_bitmap.png"
- val provider = openArsc("nonAssetBitmapGreen")
+ val provider = openArsc("nonAssetBitmapGreen", assetsProvider)
fun getValue() = (resources.getDrawable(R.drawable.non_asset_bitmap) as BitmapDrawable)
.bitmap.getColor(0, 0).toArgb()
- assertThat(getValue()).isEqualTo(Color.RED)
+ assertThat(getValue()).isEqualTo(Color.MAGENTA)
- addLoader(loader to provider)
+ loader.addProvider(provider)
assertThat(getValue()).isEqualTo(Color.GREEN)
}
@@ -81,13 +85,13 @@
@Test
fun loadXml() {
"layoutOne" writeTo "res/layout/layout.xml"
- val provider = openArsc("layoutOne")
+ val provider = openArsc("layoutOne", assetsProvider)
fun getValue() = resources.getLayout(R.layout.layout).advanceToRoot().name
- assertThat(getValue()).isEqualTo("FrameLayout")
+ assertThat(getValue()).isEqualTo("MysteryLayout")
- addLoader(loader to provider)
+ loader.addProvider(provider)
assertThat(getValue()).isEqualTo("RelativeLayout")
}
diff --git a/core/tests/ResourceLoaderTests/src/android/content/res/loader/test/ResourceLoaderAssetTest.kt b/core/tests/ResourceLoaderTests/src/android/content/res/loader/test/ResourceLoaderAssetTest.kt
deleted file mode 100644
index a6a8378..0000000
--- a/core/tests/ResourceLoaderTests/src/android/content/res/loader/test/ResourceLoaderAssetTest.kt
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * 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 android.content.res.loader.test
-
-import android.content.res.AssetManager
-import android.content.res.loader.DirectoryResourceLoader
-import android.content.res.loader.ResourceLoader
-import android.content.res.loader.ResourcesProvider
-import com.google.common.truth.Truth.assertThat
-import org.junit.Before
-import org.junit.Rule
-import org.junit.Test
-import org.junit.rules.TestName
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-import org.mockito.Mockito.anyInt
-import org.mockito.Mockito.anyString
-import org.mockito.Mockito.doAnswer
-import org.mockito.Mockito.doReturn
-import org.mockito.Mockito.eq
-import org.mockito.Mockito.inOrder
-import org.mockito.Mockito.mock
-import java.io.File
-import java.io.FileNotFoundException
-import java.io.IOException
-import java.nio.file.Paths
-
-@RunWith(Parameterized::class)
-class ResourceLoaderAssetTest : ResourceLoaderTestBase() {
-
- companion object {
- private const val BASE_TEST_PATH = "android/content/res/loader/test/file.txt"
- private const val TEST_TEXT = "some text"
-
- @JvmStatic
- @Parameterized.Parameters(name = "{0}")
- fun parameters(): Array<Array<out Any?>> {
- val fromInputStream: ResourceLoader.(String) -> Any? = {
- loadAsset(eq(it), anyInt())
- }
-
- val fromFileDescriptor: ResourceLoader.(String) -> Any? = {
- loadAssetFd(eq(it))
- }
-
- val openAsset: AssetManager.() -> String? = {
- open(BASE_TEST_PATH).reader().readText()
- }
-
- val openNonAsset: AssetManager.() -> String? = {
- openNonAssetFd(BASE_TEST_PATH).readText()
- }
-
- return arrayOf(
- arrayOf("assets", fromInputStream, openAsset),
- arrayOf("", fromFileDescriptor, openNonAsset)
- )
- }
- }
-
- @get:Rule
- val testName = TestName()
-
- @JvmField
- @field:Parameterized.Parameter(0)
- var prefix: String? = null
-
- @field:Parameterized.Parameter(1)
- lateinit var loadAssetFunction: ResourceLoader.(String) -> Any?
-
- @field:Parameterized.Parameter(2)
- lateinit var openAssetFunction: AssetManager.() -> String?
-
- private val testPath: String
- get() = Paths.get(prefix.orEmpty(), BASE_TEST_PATH).toString()
-
- private fun ResourceLoader.loadAsset() = loadAssetFunction(testPath)
-
- private fun AssetManager.openAsset() = openAssetFunction()
-
- private lateinit var testDir: File
-
- @Before
- fun setUpTestDir() {
- testDir = context.filesDir.resolve("DirectoryResourceLoaderTest_${testName.methodName}")
- testDir.resolve(testPath).apply { parentFile!!.mkdirs() }.writeText(TEST_TEXT)
- }
-
- @Test
- fun multipleLoadersSearchesBackwards() {
- // DirectoryResourceLoader relies on a private field and can't be spied directly, so wrap it
- val loader = DirectoryResourceLoader(testDir)
- val loaderWrapper = mock(ResourceLoader::class.java).apply {
- doAnswer { loader.loadAsset(it.arguments[0] as String, it.arguments[1] as Int) }
- .`when`(this).loadAsset(anyString(), anyInt())
- doAnswer { loader.loadAssetFd(it.arguments[0] as String) }
- .`when`(this).loadAssetFd(anyString())
- }
-
- val one = loaderWrapper to ResourcesProvider.empty()
- val two = mockLoader {
- doReturn(null).`when`(it).loadAsset()
- }
-
- addLoader(one, two)
-
- assertOpenedAsset()
- inOrder(two.first, one.first).apply {
- verify(two.first).loadAsset()
- verify(one.first).loadAsset()
- }
- }
-
- @Test(expected = FileNotFoundException::class)
- fun failToFindThrowsFileNotFound() {
- val one = mockLoader {
- doReturn(null).`when`(it).loadAsset()
- }
- val two = mockLoader {
- doReturn(null).`when`(it).loadAsset()
- }
-
- addLoader(one, two)
-
- assertOpenedAsset()
- }
-
- @Test
- fun throwingIOExceptionIsSkipped() {
- val one = DirectoryResourceLoader(testDir) to ResourcesProvider.empty()
- val two = mockLoader {
- doAnswer { throw IOException() }.`when`(it).loadAsset()
- }
-
- addLoader(one, two)
-
- assertOpenedAsset()
- }
-
- @Test(expected = IllegalStateException::class)
- fun throwingNonIOExceptionCausesFailure() {
- val one = DirectoryResourceLoader(testDir) to ResourcesProvider.empty()
- val two = mockLoader {
- doAnswer { throw IllegalStateException() }.`when`(it).loadAsset()
- }
-
- addLoader(one, two)
-
- assertOpenedAsset()
- }
-
- private fun assertOpenedAsset() {
- assertThat(resources.assets.openAsset()).isEqualTo(TEST_TEXT)
- }
-}
diff --git a/core/tests/ResourceLoaderTests/src/android/content/res/loader/test/ResourceLoaderAssetsTest.kt b/core/tests/ResourceLoaderTests/src/android/content/res/loader/test/ResourceLoaderAssetsTest.kt
new file mode 100644
index 0000000..e3ba93d
--- /dev/null
+++ b/core/tests/ResourceLoaderTests/src/android/content/res/loader/test/ResourceLoaderAssetsTest.kt
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * 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 android.content.res.loader.test
+
+import android.content.res.AssetManager
+import android.content.res.loader.AssetsProvider
+import android.content.res.loader.DirectoryAssetsProvider
+import android.content.res.loader.ResourcesLoader
+import android.content.res.loader.ResourcesProvider
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.rules.TestName
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+import org.mockito.Mockito.anyInt
+import org.mockito.Mockito.anyString
+import org.mockito.Mockito.doAnswer
+import org.mockito.Mockito.doReturn
+import org.mockito.Mockito.eq
+import org.mockito.Mockito.inOrder
+import org.mockito.Mockito.mock
+import java.io.File
+import java.io.FileNotFoundException
+import java.io.IOException
+import java.nio.file.Paths
+
+@RunWith(Parameterized::class)
+class ResourceLoaderAssetsTest : ResourceLoaderTestBase() {
+
+ companion object {
+ private const val BASE_TEST_PATH = "android/content/res/loader/test/file.txt"
+ private const val TEST_TEXT = "some text"
+
+ @JvmStatic
+ @Parameterized.Parameters(name = "{0}")
+ fun parameters(): Array<Array<out Any?>> {
+ val fromInputStream: AssetsProvider.(String) -> Any? = {
+ loadAsset(eq(it), anyInt())
+ }
+
+ val fromFileDescriptor: AssetsProvider.(String) -> Any? = {
+ loadAssetParcelFd(eq(it))
+ }
+
+ val openAsset: AssetManager.() -> String? = {
+ open(BASE_TEST_PATH).reader().readText()
+ }
+
+ val openNonAsset: AssetManager.() -> String? = {
+ openNonAssetFd(BASE_TEST_PATH).readText()
+ }
+
+ return arrayOf(
+ arrayOf("assets", fromInputStream, openAsset),
+ arrayOf("", fromFileDescriptor, openNonAsset)
+ )
+ }
+ }
+
+ @get:Rule
+ val testName = TestName()
+
+ @JvmField
+ @field:Parameterized.Parameter(0)
+ var prefix: String? = null
+
+ @field:Parameterized.Parameter(1)
+ lateinit var loadAssetFunction: AssetsProvider.(String) -> Any?
+
+ @field:Parameterized.Parameter(2)
+ lateinit var openAssetFunction: AssetManager.() -> String?
+
+ private val testPath: String
+ get() = Paths.get(prefix.orEmpty(), BASE_TEST_PATH).toString()
+
+ private fun AssetsProvider.loadAsset() = loadAssetFunction(testPath)
+
+ private fun AssetManager.openAsset() = openAssetFunction()
+
+ private lateinit var testDir: File
+
+ @Before
+ fun setUpTestDir() {
+ testDir = context.filesDir.resolve("DirectoryAssetsProvider_${testName.methodName}")
+ testDir.resolve(testPath).apply { parentFile!!.mkdirs() }.writeText(TEST_TEXT)
+ }
+
+ @Test
+ fun multipleProvidersSearchesBackwards() {
+ // DirectoryResourceLoader relies on a private field and can't be spied directly, so wrap it
+ val assetsProvider = DirectoryAssetsProvider(testDir)
+ val assetProviderWrapper = mock(AssetsProvider::class.java).apply {
+ doAnswer { assetsProvider.loadAsset(it.arguments[0] as String, it.arguments[1] as Int) }
+ .`when`(this).loadAsset(anyString(), anyInt())
+ doAnswer { assetsProvider.loadAssetParcelFd(it.arguments[0] as String) }
+ .`when`(this).loadAssetParcelFd(anyString())
+ }
+
+ val one = ResourcesProvider.empty(assetProviderWrapper)
+ val two = mockProvider {
+ doReturn(null).`when`(it).loadAsset()
+ }
+
+ val loader = ResourcesLoader()
+ loader.providers = listOf(one, two)
+ resources.addLoader(loader)
+
+ assertOpenedAsset()
+ inOrder(two.assetsProvider, one.assetsProvider).apply {
+ verify(two.assetsProvider)?.loadAsset()
+ verify(one.assetsProvider)?.loadAsset()
+ }
+ }
+
+ @Test
+ fun multipleLoadersSearchesBackwards() {
+ // DirectoryResourceLoader relies on a private field and can't be spied directly, so wrap it
+ val assetsProvider = DirectoryAssetsProvider(testDir)
+ val assetProviderWrapper = mock(AssetsProvider::class.java).apply {
+ doAnswer { assetsProvider.loadAsset(it.arguments[0] as String, it.arguments[1] as Int) }
+ .`when`(this).loadAsset(anyString(), anyInt())
+ doAnswer { assetsProvider.loadAssetParcelFd(it.arguments[0] as String) }
+ .`when`(this).loadAssetParcelFd(anyString())
+ }
+
+ val one = ResourcesProvider.empty(assetProviderWrapper)
+ val two = mockProvider {
+ doReturn(null).`when`(it).loadAsset()
+ }
+
+ val loader1 = ResourcesLoader()
+ loader1.addProvider(one)
+ val loader2 = ResourcesLoader()
+ loader2.addProvider(two)
+
+ resources.loaders = listOf(loader1, loader2)
+
+ assertOpenedAsset()
+ inOrder(two.assetsProvider, one.assetsProvider).apply {
+ verify(two.assetsProvider)?.loadAsset()
+ verify(one.assetsProvider)?.loadAsset()
+ }
+ }
+
+ @Test(expected = FileNotFoundException::class)
+ fun failToFindThrowsFileNotFound() {
+ val assetsProvider1 = mock(AssetsProvider::class.java).apply {
+ doReturn(null).`when`(this).loadAsset()
+ }
+ val assetsProvider2 = mock(AssetsProvider::class.java).apply {
+ doReturn(null).`when`(this).loadAsset()
+ }
+
+ val loader = ResourcesLoader()
+ val one = ResourcesProvider.empty(assetsProvider1)
+ val two = ResourcesProvider.empty(assetsProvider2)
+ resources.addLoader(loader)
+ loader.providers = listOf(one, two)
+
+ assertOpenedAsset()
+ }
+
+ @Test
+ fun throwingIOExceptionIsSkipped() {
+ val assetsProvider1 = DirectoryAssetsProvider(testDir)
+ val assetsProvider2 = mock(AssetsProvider::class.java).apply {
+ doAnswer { throw IOException() }.`when`(this).loadAsset()
+ }
+
+ val loader = ResourcesLoader()
+ val one = ResourcesProvider.empty(assetsProvider1)
+ val two = ResourcesProvider.empty(assetsProvider2)
+ resources.addLoader(loader)
+ loader.providers = listOf(one, two)
+
+ assertOpenedAsset()
+ }
+
+ @Test(expected = IllegalStateException::class)
+ fun throwingNonIOExceptionCausesFailure() {
+ val assetsProvider1 = DirectoryAssetsProvider(testDir)
+ val assetsProvider2 = mock(AssetsProvider::class.java).apply {
+ doAnswer { throw IllegalStateException() }.`when`(this).loadAsset()
+ }
+
+ val loader = ResourcesLoader()
+ val one = ResourcesProvider.empty(assetsProvider1)
+ val two = ResourcesProvider.empty(assetsProvider2)
+ resources.addLoader(loader)
+ loader.providers = listOf(one, two)
+
+ assertOpenedAsset()
+ }
+
+ private fun mockProvider(block: (AssetsProvider) -> Unit = {}): ResourcesProvider {
+ return ResourcesProvider.empty(mock(AssetsProvider::class.java).apply {
+ block.invoke(this)
+ })
+ }
+
+ private fun assertOpenedAsset() {
+ assertThat(resources.assets.openAsset()).isEqualTo(TEST_TEXT)
+ }
+}
diff --git a/core/tests/ResourceLoaderTests/src/android/content/res/loader/test/ResourceLoaderChangesTest.kt b/core/tests/ResourceLoaderTests/src/android/content/res/loader/test/ResourceLoaderChangesTest.kt
deleted file mode 100644
index 0c3d34e..0000000
--- a/core/tests/ResourceLoaderTests/src/android/content/res/loader/test/ResourceLoaderChangesTest.kt
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * 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 android.content.res.loader.test
-
-import android.app.Activity
-import android.app.Instrumentation
-import android.app.UiAutomation
-import android.content.res.Configuration
-import android.content.res.Resources
-import android.graphics.Color
-import android.os.Bundle
-import android.os.ParcelFileDescriptor
-import android.widget.FrameLayout
-import androidx.test.InstrumentationRegistry
-import androidx.test.rule.ActivityTestRule
-import androidx.test.runner.lifecycle.ActivityLifecycleMonitorRegistry
-import androidx.test.runner.lifecycle.Stage
-import com.google.common.truth.Truth.assertThat
-import org.junit.After
-import org.junit.Before
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-import java.util.Arrays
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.Executor
-import java.util.concurrent.FutureTask
-import java.util.concurrent.TimeUnit
-
-@RunWith(Parameterized::class)
-class ResourceLoaderChangesTest : ResourceLoaderTestBase() {
-
- companion object {
- private const val TIMEOUT = 30L
- private const val OVERLAY_PACKAGE = "android.content.res.loader.test.overlay"
-
- @JvmStatic
- @Parameterized.Parameters(name = "{0}")
- fun data() = arrayOf(DataType.APK, DataType.ARSC)
- }
-
- @field:Parameterized.Parameter(0)
- override lateinit var dataType: DataType
-
- @get:Rule
- val activityRule: ActivityTestRule<TestActivity> =
- ActivityTestRule<TestActivity>(TestActivity::class.java, false, true)
-
- // Redirect to the Activity's resources
- override val resources: Resources
- get() = activityRule.getActivity().resources
-
- private val activity: TestActivity
- get() = activityRule.getActivity()
-
- private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
-
- @Before
- @After
- fun disableOverlay() {
- enableOverlay(OVERLAY_PACKAGE, false)
- }
-
- @Test
- fun activityRecreate() = verifySameBeforeAndAfter {
- val oldActivity = activity
- var newActivity: Activity? = null
- instrumentation.runOnMainSync { oldActivity.recreate() }
- instrumentation.waitForIdleSync()
- instrumentation.runOnMainSync {
- newActivity = ActivityLifecycleMonitorRegistry.getInstance()
- .getActivitiesInStage(Stage.RESUMED)
- .single()
- }
-
- assertThat(newActivity).isNotNull()
- assertThat(newActivity).isNotSameAs(oldActivity)
-
- // Return the new resources to assert on
- return@verifySameBeforeAndAfter newActivity!!.resources
- }
-
- @Test
- fun activityHandledOrientationChange() = verifySameBeforeAndAfter {
- val latch = CountDownLatch(1)
- val oldConfig = Configuration().apply { setTo(resources.configuration) }
- var changedConfig: Configuration? = null
-
- activity.callback = object : TestActivity.Callback {
- override fun onConfigurationChanged(newConfig: Configuration) {
- changedConfig = newConfig
- latch.countDown()
- }
- }
-
- val isPortrait = resources.displayMetrics.run { widthPixels < heightPixels }
- val newRotation = if (isPortrait) {
- UiAutomation.ROTATION_FREEZE_90
- } else {
- UiAutomation.ROTATION_FREEZE_0
- }
-
- instrumentation.uiAutomation.setRotation(newRotation)
-
- assertThat(latch.await(TIMEOUT, TimeUnit.SECONDS)).isTrue()
- assertThat(changedConfig).isNotEqualTo(oldConfig)
- return@verifySameBeforeAndAfter activity.resources
- }
-
- @Test
- fun enableOverlayCausingPathChange() = verifySameBeforeAndAfter {
- assertThat(getString(R.string.loader_path_change_test)).isEqualTo("Not overlaid")
-
- enableOverlay(OVERLAY_PACKAGE, true)
-
- assertThat(getString(R.string.loader_path_change_test)).isEqualTo("Overlaid")
-
- return@verifySameBeforeAndAfter activity.resources
- }
-
- @Test
- fun enableOverlayChildContextUnaffected() {
- val childContext = activity.createConfigurationContext(Configuration())
- val childResources = childContext.resources
- val originalValue = childResources.getString(android.R.string.cancel)
- assertThat(childResources.getString(R.string.loader_path_change_test))
- .isEqualTo("Not overlaid")
-
- verifySameBeforeAndAfter {
- enableOverlay(OVERLAY_PACKAGE, true)
- return@verifySameBeforeAndAfter activity.resources
- }
-
- // Loader not applied, but overlay change propagated
- assertThat(childResources.getString(android.R.string.cancel)).isEqualTo(originalValue)
- assertThat(childResources.getString(R.string.loader_path_change_test))
- .isEqualTo("Overlaid")
- }
-
- // All these tests assert for the exact same loaders/values, so extract that logic out
- private fun verifySameBeforeAndAfter(block: () -> Resources) {
- fun Resources.resource() = this.getString(android.R.string.cancel)
- fun Resources.asset() = this.assets.open("Asset.txt").reader().readText()
-
- val originalResource = resources.resource()
- val originalAsset = resources.asset()
-
- val loaderResource = "stringOne".openLoader()
- val loaderAsset = "assetOne".openLoader(dataType = DataType.ASSET)
- addLoader(loaderResource)
- addLoader(loaderAsset)
-
- val oldLoaders = resources.loaders
- val oldResource = resources.resource()
- val oldAsset = resources.asset()
-
- assertThat(oldResource).isNotEqualTo(originalResource)
- assertThat(oldAsset).isNotEqualTo(originalAsset)
-
- val newResources = block()
-
- val newLoaders = newResources.loaders
- val newResource = newResources.resource()
- val newAsset = newResources.asset()
-
- assertThat(newResource).isEqualTo(oldResource)
- assertThat(newAsset).isEqualTo(oldAsset)
- assertThat(newLoaders).isEqualTo(oldLoaders)
- }
-
- // Copied from overlaytests LocalOverlayManager
- private fun enableOverlay(packageName: String, enable: Boolean) {
- val executor = Executor { Thread(it).start() }
- val pattern = (if (enable) "[x]" else "[ ]") + " " + packageName
- if (executeShellCommand("cmd overlay list").contains(pattern)) {
- // nothing to do, overlay already in the requested state
- return
- }
-
- val oldApkPaths = resources.assets.apkPaths
- val task = FutureTask {
- while (true) {
- if (!Arrays.equals(oldApkPaths, resources.assets.apkPaths)) {
- return@FutureTask true
- }
- Thread.sleep(10)
- }
-
- @Suppress("UNREACHABLE_CODE")
- return@FutureTask false
- }
-
- val command = if (enable) "enable" else "disable"
- executeShellCommand("cmd overlay $command $packageName")
- executor.execute(task)
- assertThat(task.get(TIMEOUT, TimeUnit.SECONDS)).isTrue()
- }
-
- private fun executeShellCommand(command: String): String {
- val uiAutomation = instrumentation.uiAutomation
- val pfd = uiAutomation.executeShellCommand(command)
- return ParcelFileDescriptor.AutoCloseInputStream(pfd).use { it.reader().readText() }
- }
-}
-
-class TestActivity : Activity() {
-
- var callback: Callback? = null
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
-
- setContentView(FrameLayout(this).apply {
- setBackgroundColor(Color.BLUE)
- })
- }
-
- override fun onConfigurationChanged(newConfig: Configuration) {
- super.onConfigurationChanged(newConfig)
- callback?.onConfigurationChanged(newConfig)
- }
-
- interface Callback {
- fun onConfigurationChanged(newConfig: Configuration)
- }
-}
diff --git a/core/tests/ResourceLoaderTests/src/android/content/res/loader/test/ResourceLoaderDrawableTest.kt b/core/tests/ResourceLoaderTests/src/android/content/res/loader/test/ResourceLoaderDrawableTest.kt
deleted file mode 100644
index 09fd27e..0000000
--- a/core/tests/ResourceLoaderTests/src/android/content/res/loader/test/ResourceLoaderDrawableTest.kt
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * 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 android.content.res.loader.test
-
-import android.content.res.Resources
-import android.content.res.loader.ResourceLoader
-import android.content.res.loader.ResourcesProvider
-import android.graphics.Color
-import android.graphics.drawable.ColorDrawable
-import com.google.common.truth.Truth.assertThat
-import org.hamcrest.CoreMatchers.not
-import org.junit.Assume.assumeThat
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-import org.mockito.ArgumentMatchers.anyInt
-import org.mockito.Mockito.`when`
-import org.mockito.Mockito.any
-import org.mockito.Mockito.argThat
-import org.mockito.Mockito.eq
-import org.mockito.Mockito.never
-import org.mockito.Mockito.verify
-
-@RunWith(Parameterized::class)
-class ResourceLoaderDrawableTest : ResourceLoaderTestBase() {
-
- companion object {
-
- @JvmStatic
- @Parameterized.Parameters(name = "{0}")
- fun data() = arrayOf(DataType.APK, DataType.ARSC)
- }
-
- @field:Parameterized.Parameter(0)
- override lateinit var dataType: DataType
-
- @Test
- fun matchingConfig() {
- val original = getDrawable(android.R.drawable.ic_delete)
- val loader = "drawableMdpiWithoutFile".openLoader()
- `when`(loader.first.loadDrawable(any(), anyInt(), anyInt(), any()))
- .thenReturn(ColorDrawable(Color.BLUE))
-
- addLoader(loader)
-
- updateConfiguration { densityDpi = 160 /* mdpi */ }
-
- val drawable = getDrawable(android.R.drawable.ic_delete)
-
- loader.verifyLoadDrawableCalled()
-
- assertThat(drawable).isNotEqualTo(original)
- assertThat(drawable).isInstanceOf(ColorDrawable::class.java)
- assertThat((drawable as ColorDrawable).color).isEqualTo(Color.BLUE)
- }
-
- @Test
- fun worseConfig() {
- val loader = "drawableMdpiWithoutFile".openLoader()
- addLoader(loader)
-
- updateConfiguration { densityDpi = 480 /* xhdpi */ }
-
- getDrawable(android.R.drawable.ic_delete)
-
- verify(loader.first, never()).loadDrawable(any(), anyInt(), anyInt(), any())
- }
-
- @Test
- fun multipleLoaders() {
- val original = getDrawable(android.R.drawable.ic_delete)
- val loaderOne = "drawableMdpiWithoutFile".openLoader()
- val loaderTwo = "drawableMdpiWithoutFile".openLoader()
-
- `when`(loaderTwo.first.loadDrawable(any(), anyInt(), anyInt(), any()))
- .thenReturn(ColorDrawable(Color.BLUE))
-
- addLoader(loaderOne, loaderTwo)
-
- updateConfiguration { densityDpi = 160 /* mdpi */ }
-
- val drawable = getDrawable(android.R.drawable.ic_delete)
- loaderOne.verifyLoadDrawableNotCalled()
- loaderTwo.verifyLoadDrawableCalled()
-
- assertThat(drawable).isNotEqualTo(original)
- assertThat(drawable).isInstanceOf(ColorDrawable::class.java)
- assertThat((drawable as ColorDrawable).color).isEqualTo(Color.BLUE)
- }
-
- @Test(expected = Resources.NotFoundException::class)
- fun multipleLoadersNoReturnWithoutFile() {
- val loaderOne = "drawableMdpiWithoutFile".openLoader()
- val loaderTwo = "drawableMdpiWithoutFile".openLoader()
-
- addLoader(loaderOne, loaderTwo)
-
- updateConfiguration { densityDpi = 160 /* mdpi */ }
-
- try {
- getDrawable(android.R.drawable.ic_delete)
- } finally {
- // We expect the call to fail because at least the loader won't resolve the overridden
- // drawable, but we should still verify that both loaders were called before allowing
- // the exception to propagate.
- loaderOne.verifyLoadDrawableNotCalled()
- loaderTwo.verifyLoadDrawableCalled()
- }
- }
-
- @Test
- fun multipleLoadersReturnWithFile() {
- // Can't return a file if an ARSC
- assumeThat(dataType, not(DataType.ARSC))
-
- val original = getDrawable(android.R.drawable.ic_delete)
- val loaderOne = "drawableMdpiWithFile".openLoader()
- val loaderTwo = "drawableMdpiWithFile".openLoader()
-
- addLoader(loaderOne, loaderTwo)
-
- updateConfiguration { densityDpi = 160 /* mdpi */ }
-
- val drawable = getDrawable(android.R.drawable.ic_delete)
- loaderOne.verifyLoadDrawableNotCalled()
- loaderTwo.verifyLoadDrawableCalled()
-
- assertThat(drawable).isNotNull()
- assertThat(drawable).isInstanceOf(original.javaClass)
- }
-
- @Test
- fun unhandledResourceIgnoresLoaders() {
- val loader = "drawableMdpiWithoutFile".openLoader()
- `when`(loader.first.loadDrawable(any(), anyInt(), anyInt(), any()))
- .thenReturn(ColorDrawable(Color.BLUE))
- addLoader(loader)
-
- getDrawable(android.R.drawable.ic_menu_add)
-
- loader.verifyLoadDrawableNotCalled()
-
- getDrawable(android.R.drawable.ic_delete)
-
- loader.verifyLoadDrawableCalled()
- }
-
- private fun Pair<ResourceLoader, ResourcesProvider>.verifyLoadDrawableCalled() {
- verify(first).loadDrawable(
- argThat {
- it.density == 160 &&
- it.resourceId == android.R.drawable.ic_delete &&
- it.string == "res/drawable-mdpi-v4/ic_delete.png"
- },
- eq(android.R.drawable.ic_delete),
- eq(0),
- any()
- )
- }
-
- private fun Pair<ResourceLoader, ResourcesProvider>.verifyLoadDrawableNotCalled() {
- verify(first, never()).loadDrawable(
- any(),
- anyInt(),
- anyInt(),
- any()
- )
- }
-}
diff --git a/core/tests/ResourceLoaderTests/src/android/content/res/loader/test/ResourceLoaderLayoutTest.kt b/core/tests/ResourceLoaderTests/src/android/content/res/loader/test/ResourceLoaderLayoutTest.kt
deleted file mode 100644
index 1ec2094..0000000
--- a/core/tests/ResourceLoaderTests/src/android/content/res/loader/test/ResourceLoaderLayoutTest.kt
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * 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 android.content.res.loader.test
-
-import android.content.res.Resources
-import android.content.res.XmlResourceParser
-import android.content.res.loader.ResourceLoader
-import android.content.res.loader.ResourcesProvider
-import com.google.common.truth.Truth.assertThat
-import org.hamcrest.CoreMatchers.not
-import org.junit.Assume.assumeThat
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-import org.mockito.ArgumentMatchers.anyString
-import org.mockito.Mockito.`when`
-import org.mockito.Mockito.any
-import org.mockito.Mockito.anyInt
-import org.mockito.Mockito.mock
-import org.mockito.Mockito.never
-import org.mockito.Mockito.verify
-
-@RunWith(Parameterized::class)
-class ResourceLoaderLayoutTest : ResourceLoaderTestBase() {
-
- companion object {
-
- @JvmStatic
- @Parameterized.Parameters(name = "{0}")
- fun data() = arrayOf(DataType.APK, DataType.ARSC)
- }
-
- @field:Parameterized.Parameter(0)
- override lateinit var dataType: DataType
-
- @Test
- fun singleLoader() {
- val original = getLayout(android.R.layout.activity_list_item)
- val mockXml = mock(XmlResourceParser::class.java)
- val loader = "layoutWithoutFile".openLoader()
- `when`(loader.first.loadXmlResourceParser(any(), anyInt()))
- .thenReturn(mockXml)
-
- addLoader(loader)
-
- val layout = getLayout(android.R.layout.activity_list_item)
- loader.verifyLoadLayoutCalled()
-
- assertThat(layout).isNotEqualTo(original)
- assertThat(layout).isSameAs(mockXml)
- }
-
- @Test
- fun multipleLoaders() {
- val original = getLayout(android.R.layout.activity_list_item)
- val loaderOne = "layoutWithoutFile".openLoader()
- val loaderTwo = "layoutWithoutFile".openLoader()
-
- val mockXml = mock(XmlResourceParser::class.java)
- `when`(loaderTwo.first.loadXmlResourceParser(any(), anyInt()))
- .thenReturn(mockXml)
-
- addLoader(loaderOne, loaderTwo)
-
- val layout = getLayout(android.R.layout.activity_list_item)
- loaderOne.verifyLoadLayoutNotCalled()
- loaderTwo.verifyLoadLayoutCalled()
-
- assertThat(layout).isNotEqualTo(original)
- assertThat(layout).isSameAs(mockXml)
- }
-
- @Test(expected = Resources.NotFoundException::class)
- fun multipleLoadersNoReturnWithoutFile() {
- val loaderOne = "layoutWithoutFile".openLoader()
- val loaderTwo = "layoutWithoutFile".openLoader()
-
- addLoader(loaderOne, loaderTwo)
-
- try {
- getLayout(android.R.layout.activity_list_item)
- } finally {
- // We expect the call to fail because at least one loader must resolve the overridden
- // layout, but we should still verify that both loaders were called before allowing
- // the exception to propagate.
- loaderOne.verifyLoadLayoutNotCalled()
- loaderTwo.verifyLoadLayoutCalled()
- }
- }
-
- @Test
- fun multipleLoadersReturnWithFile() {
- // Can't return a file if an ARSC
- assumeThat(dataType, not(DataType.ARSC))
-
- val loaderOne = "layoutWithFile".openLoader()
- val loaderTwo = "layoutWithFile".openLoader()
-
- addLoader(loaderOne, loaderTwo)
-
- val xml = getLayout(android.R.layout.activity_list_item)
- loaderOne.verifyLoadLayoutNotCalled()
- loaderTwo.verifyLoadLayoutCalled()
-
- assertThat(xml).isNotNull()
- }
-
- @Test
- fun unhandledResourceIgnoresLoaders() {
- val loader = "layoutWithoutFile".openLoader()
- val mockXml = mock(XmlResourceParser::class.java)
- `when`(loader.first.loadXmlResourceParser(any(), anyInt()))
- .thenReturn(mockXml)
- addLoader(loader)
-
- getLayout(android.R.layout.preference_category)
-
- verify(loader.first, never())
- .loadXmlResourceParser(anyString(), anyInt())
-
- getLayout(android.R.layout.activity_list_item)
-
- loader.verifyLoadLayoutCalled()
- }
-
- private fun Pair<ResourceLoader, ResourcesProvider>.verifyLoadLayoutCalled() {
- verify(first).loadXmlResourceParser(
- "res/layout/activity_list_item.xml",
- android.R.layout.activity_list_item
- )
- }
-
- private fun Pair<ResourceLoader, ResourcesProvider>.verifyLoadLayoutNotCalled() {
- verify(first, never()).loadXmlResourceParser(
- anyString(),
- anyInt()
- )
- }
-}
diff --git a/core/tests/ResourceLoaderTests/src/android/content/res/loader/test/ResourceLoaderTestBase.kt b/core/tests/ResourceLoaderTests/src/android/content/res/loader/test/ResourceLoaderTestBase.kt
index 5af453d..4c62955 100644
--- a/core/tests/ResourceLoaderTests/src/android/content/res/loader/test/ResourceLoaderTestBase.kt
+++ b/core/tests/ResourceLoaderTests/src/android/content/res/loader/test/ResourceLoaderTestBase.kt
@@ -18,25 +18,16 @@
import android.content.Context
import android.content.res.AssetManager
-import android.content.res.Configuration
import android.content.res.Resources
-import android.content.res.loader.ResourceLoader
+import android.content.res.loader.AssetsProvider
import android.content.res.loader.ResourcesProvider
import android.os.ParcelFileDescriptor
-import android.util.TypedValue
-import androidx.annotation.DimenRes
-import androidx.annotation.DrawableRes
-import androidx.annotation.LayoutRes
-import androidx.annotation.StringRes
import androidx.test.InstrumentationRegistry
import org.junit.After
import org.junit.Before
-import org.mockito.ArgumentMatchers
import org.mockito.ArgumentMatchers.anyInt
-import org.mockito.ArgumentMatchers.argThat
import org.mockito.ArgumentMatchers.eq
import org.mockito.Mockito.doAnswer
-import org.mockito.Mockito.doReturn
import org.mockito.Mockito.mock
import java.io.Closeable
@@ -60,7 +51,8 @@
@After
fun removeAllLoaders() {
- resources.setLoaders(null)
+ resources.clearLoaders()
+ context.applicationContext.resources.clearLoaders()
openedObjects.forEach {
try {
it.close()
@@ -69,149 +61,73 @@
}
}
- protected fun getString(@StringRes stringRes: Int, debugLog: Boolean = false) =
- logResolution(debugLog) { getString(stringRes) }
-
- protected fun getDrawable(@DrawableRes drawableRes: Int, debugLog: Boolean = false) =
- logResolution(debugLog) { getDrawable(drawableRes) }
-
- protected fun getLayout(@LayoutRes layoutRes: Int, debugLog: Boolean = false) =
- logResolution(debugLog) { getLayout(layoutRes) }
-
- protected fun getDimensionPixelSize(@DimenRes dimenRes: Int, debugLog: Boolean = false) =
- logResolution(debugLog) { getDimensionPixelSize(dimenRes) }
-
- private fun <T> logResolution(debugLog: Boolean = false, block: Resources.() -> T): T {
- if (debugLog) {
- resources.assets.setResourceResolutionLoggingEnabled(true)
- }
-
- var thrown = false
-
- try {
- return resources.block()
- } catch (t: Throwable) {
- // No good way to log to test output other than throwing an exception
- if (debugLog) {
- thrown = true
- throw IllegalStateException(resources.assets.lastResourceResolution, t)
- } else {
- throw t
- }
- } finally {
- if (!thrown && debugLog) {
- throw IllegalStateException(resources.assets.lastResourceResolution)
- }
- }
- }
-
- protected fun updateConfiguration(block: Configuration.() -> Unit) {
- val configuration = Configuration().apply {
- setTo(resources.configuration)
- block()
- }
-
- resources.updateConfiguration(configuration, resources.displayMetrics)
- }
-
- protected fun String.openLoader(
+ protected fun String.openProvider(
dataType: DataType = this@ResourceLoaderTestBase.dataType
- ): Pair<ResourceLoader, ResourcesProvider> = when (dataType) {
+ ): ResourcesProvider = when (dataType) {
DataType.APK -> {
- mock(ResourceLoader::class.java) to context.copiedRawFile("${this}Apk").use {
- ResourcesProvider.loadFromApk(it)
+ context.copiedRawFile("${this}Apk").use {
+ ResourcesProvider.loadFromApk(it, mock(AssetsProvider::class.java))
}.also { openedObjects += it }
}
DataType.ARSC -> {
- mock(ResourceLoader::class.java) to openArsc(this)
+ openArsc(this, mock(AssetsProvider::class.java))
}
DataType.SPLIT -> {
- mock(ResourceLoader::class.java) to ResourcesProvider.loadFromSplit(context, this)
+ ResourcesProvider.loadFromSplit(context, this)
}
- DataType.ASSET -> mockLoader {
- doAnswer { byteInputStream() }.`when`(it)
+ DataType.ASSET -> {
+ val assetsProvider = mock(AssetsProvider::class.java)
+ doAnswer { byteInputStream() }.`when`(assetsProvider)
.loadAsset(eq("assets/Asset.txt"), anyInt())
+ ResourcesProvider.empty(assetsProvider)
}
- DataType.ASSET_FD -> mockLoader {
+ DataType.ASSET_FD -> {
+ val assetsProvider = mock(AssetsProvider::class.java)
doAnswer {
val file = context.filesDir.resolve("Asset.txt")
file.writeText(this)
ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY)
- }.`when`(it).loadAssetFd("assets/Asset.txt")
+ }.`when`(assetsProvider).loadAssetParcelFd("assets/Asset.txt")
+ ResourcesProvider.empty(assetsProvider)
}
- DataType.NON_ASSET -> mockLoader {
+ DataType.NON_ASSET -> {
+ val assetsProvider = mock(AssetsProvider::class.java)
doAnswer {
val file = context.filesDir.resolve("NonAsset.txt")
file.writeText(this)
ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY)
- }.`when`(it).loadAssetFd("NonAsset.txt")
+ }.`when`(assetsProvider).loadAssetParcelFd("NonAsset.txt")
+ ResourcesProvider.empty(assetsProvider)
}
- DataType.NON_ASSET_DRAWABLE -> mockLoader(openArsc(this)) {
- doReturn(null).`when`(it).loadDrawable(argThat { value ->
- value.type == TypedValue.TYPE_STRING &&
- value.resourceId == 0x7f010001 &&
- value.string == "res/drawable-nodpi-v4/non_asset_drawable.xml"
- }, eq(0x7f010001), anyInt(), ArgumentMatchers.any())
-
- doAnswer { context.copiedRawFile(this) }.`when`(it)
- .loadAssetFd("res/drawable-nodpi-v4/non_asset_drawable.xml")
+ DataType.NON_ASSET_DRAWABLE -> {
+ val assetsProvider = mock(AssetsProvider::class.java)
+ doAnswer { context.copiedRawFile(this) }.`when`(assetsProvider)
+ .loadAssetParcelFd("res/drawable-nodpi-v4/non_asset_drawable.xml")
+ openArsc(this, assetsProvider)
}
- DataType.NON_ASSET_BITMAP -> mockLoader(openArsc(this)) {
- doReturn(null).`when`(it).loadDrawable(argThat { value ->
- value.type == TypedValue.TYPE_STRING &&
- value.resourceId == 0x7f010000 &&
- value.string == "res/drawable-nodpi-v4/non_asset_bitmap.png"
- }, eq(0x7f010000), anyInt(), ArgumentMatchers.any())
-
- doAnswer { resources.openRawResourceFd(rawFile(this)).createInputStream() }
- .`when`(it)
+ DataType.NON_ASSET_BITMAP -> {
+ val assetsProvider = mock(AssetsProvider::class.java)
+ doAnswer { resources.openRawResource(rawFile(this)) }
+ .`when`(assetsProvider)
.loadAsset(eq("res/drawable-nodpi-v4/non_asset_bitmap.png"), anyInt())
+ openArsc(this, assetsProvider)
}
- DataType.NON_ASSET_LAYOUT -> mockLoader(openArsc(this)) {
- doReturn(null).`when`(it)
- .loadXmlResourceParser("res/layout/layout.xml", 0x7f020000)
-
- doAnswer { context.copiedRawFile(this) }.`when`(it)
- .loadAssetFd("res/layout/layout.xml")
+ DataType.NON_ASSET_LAYOUT -> {
+ val assetsProvider = mock(AssetsProvider::class.java)
+ doAnswer { resources.openRawResource(rawFile(this)) }.`when`(assetsProvider)
+ .loadAsset(eq("res/layout/layout.xml"), anyInt())
+ doAnswer { context.copiedRawFile(this) }.`when`(assetsProvider)
+ .loadAssetParcelFd("res/layout/layout.xml")
+ openArsc(this, assetsProvider)
}
}
- protected fun mockLoader(
- provider: ResourcesProvider = ResourcesProvider.empty(),
- block: (ResourceLoader) -> Unit = {}
- ): Pair<ResourceLoader, ResourcesProvider> {
- return mock(ResourceLoader::class.java, Utils.ANSWER_THROWS)
- .apply(block) to provider
- }
-
- protected fun openArsc(rawName: String): ResourcesProvider {
+ protected fun openArsc(rawName: String, assetsProvider: AssetsProvider): ResourcesProvider {
return context.copiedRawFile("${rawName}Arsc")
- .use { ResourcesProvider.loadFromArsc(it) }
+ .use { ResourcesProvider.loadFromTable(it, assetsProvider) }
.also { openedObjects += it }
}
- // This specifically uses addLoader so both behaviors are tested
- protected fun addLoader(vararg pairs: Pair<out ResourceLoader, ResourcesProvider>) {
- pairs.forEach { resources.addLoader(it.first, it.second) }
- }
-
- protected fun setLoaders(vararg pairs: Pair<out ResourceLoader, ResourcesProvider>) {
- resources.setLoaders(pairs.map { android.util.Pair(it.first, it.second) })
- }
-
- protected fun addLoader(pair: Pair<out ResourceLoader, ResourcesProvider>, index: Int) {
- resources.addLoader(pair.first, pair.second, index)
- }
-
- protected fun removeLoader(vararg pairs: Pair<out ResourceLoader, ResourcesProvider>) {
- pairs.forEach { resources.removeLoader(it.first) }
- }
-
- protected fun getLoaders(): MutableList<Pair<ResourceLoader, ResourcesProvider>> {
- // Cast instead of toMutableList to maintain the same object
- return resources.getLoaders() as MutableList<Pair<ResourceLoader, ResourcesProvider>>
- }
-
enum class DataType {
APK,
ARSC,
diff --git a/core/tests/ResourceLoaderTests/src/android/content/res/loader/test/ResourceLoaderValuesTest.kt b/core/tests/ResourceLoaderTests/src/android/content/res/loader/test/ResourceLoaderValuesTest.kt
index 017552a..0cc56d7 100644
--- a/core/tests/ResourceLoaderTests/src/android/content/res/loader/test/ResourceLoaderValuesTest.kt
+++ b/core/tests/ResourceLoaderTests/src/android/content/res/loader/test/ResourceLoaderValuesTest.kt
@@ -16,15 +16,24 @@
package android.content.res.loader.test
+import android.app.Activity
+import android.content.Context
+import android.content.Intent
+import android.content.res.Configuration
+import android.content.res.Resources
+import android.content.res.loader.ResourcesLoader
import android.graphics.Color
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.ColorDrawable
-import com.google.common.truth.Truth.assertThat
+import android.os.IBinder
+import androidx.test.rule.ActivityTestRule
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotEquals
+import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
+import java.util.Collections
/**
* Tests generic ResourceLoader behavior. Intentionally abstract in its test methodology because
@@ -36,6 +45,9 @@
@RunWith(Parameterized::class)
class ResourceLoaderValuesTest : ResourceLoaderTestBase() {
+ @get:Rule
+ private val mTestActivityRule = ActivityTestRule<TestActivity>(TestActivity::class.java)
+
companion object {
@Parameterized.Parameters(name = "{1} {0}")
@JvmStatic
@@ -47,14 +59,18 @@
{ getString(android.R.string.cancel) },
"stringOne", { "SomeRidiculouslyUnlikelyStringOne" },
"stringTwo", { "SomeRidiculouslyUnlikelyStringTwo" },
+ "stringThree", { "SomeRidiculouslyUnlikelyStringThree" },
+ "stringFour", { "SomeRidiculouslyUnlikelyStringFour" },
listOf(DataType.APK, DataType.ARSC)
)
// R.dimen
parameters += Parameter(
- { resources.getDimensionPixelSize(android.R.dimen.app_icon_size) },
- "dimenOne", { 564716.dpToPx(resources) },
- "dimenTwo", { 565717.dpToPx(resources) },
+ { getDimensionPixelSize(android.R.dimen.app_icon_size) },
+ "dimenOne", { 100.dpToPx(resources) },
+ "dimenTwo", { 200.dpToPx(resources) },
+ "dimenThree", { 300.dpToPx(resources) },
+ "dimenFour", { 400.dpToPx(resources) },
listOf(DataType.APK, DataType.ARSC)
)
@@ -63,6 +79,8 @@
{ assets.open("Asset.txt").reader().readText() },
"assetOne", { "assetOne" },
"assetTwo", { "assetTwo" },
+ "assetFour", { "assetFour" },
+ "assetThree", { "assetThree" },
listOf(DataType.ASSET)
)
@@ -71,6 +89,8 @@
{ assets.openFd("Asset.txt").readText() },
"assetOne", { "assetOne" },
"assetTwo", { "assetTwo" },
+ "assetFour", { "assetFour" },
+ "assetThree", { "assetThree" },
listOf(DataType.ASSET_FD)
)
@@ -79,14 +99,18 @@
{ assets.openNonAssetFd("NonAsset.txt").readText() },
"NonAssetOne", { "NonAssetOne" },
"NonAssetTwo", { "NonAssetTwo" },
+ "NonAssetThree", { "NonAssetThree" },
+ "NonAssetFour", { "NonAssetFour" },
listOf(DataType.NON_ASSET)
)
// Asset as compiled XML drawable
parameters += Parameter(
{ (getDrawable(R.drawable.non_asset_drawable) as ColorDrawable).color },
- "nonAssetDrawableOne", { Color.parseColor("#A3C3E3") },
- "nonAssetDrawableTwo", { Color.parseColor("#3A3C3E") },
+ "nonAssetDrawableOne", { Color.parseColor("#000001") },
+ "nonAssetDrawableTwo", { Color.parseColor("#000002") },
+ "nonAssetDrawableThree", { Color.parseColor("#000003") },
+ "nonAssetDrawableFour", { Color.parseColor("#000004") },
listOf(DataType.NON_ASSET_DRAWABLE)
)
@@ -96,8 +120,10 @@
(getDrawable(R.drawable.non_asset_bitmap) as BitmapDrawable)
.bitmap.getColor(0, 0).toArgb()
},
+ "nonAssetBitmapRed", { Color.RED },
"nonAssetBitmapGreen", { Color.GREEN },
"nonAssetBitmapBlue", { Color.BLUE },
+ "nonAssetBitmapWhite", { Color.WHITE },
listOf(DataType.NON_ASSET_BITMAP)
)
@@ -106,6 +132,8 @@
{ getLayout(R.layout.layout).advanceToRoot().name },
"layoutOne", { "RelativeLayout" },
"layoutTwo", { "LinearLayout" },
+ "layoutThree", { "FrameLayout" },
+ "layoutFour", { "TableLayout" },
listOf(DataType.NON_ASSET_LAYOUT)
)
@@ -114,6 +142,8 @@
{ getString(R.string.split_overlaid) },
"split_one", { "Split ONE Overlaid" },
"split_two", { "Split TWO Overlaid" },
+ "split_three", { "Split THREE Overlaid" },
+ "split_four", { "Split FOUR Overlaid" },
listOf(DataType.SPLIT)
)
@@ -134,19 +164,52 @@
private val valueOne by lazy { parameter.valueOne(this) }
private val valueTwo by lazy { parameter.valueTwo(this) }
+ private val valueThree by lazy { parameter.valueThree(this) }
+ private val valueFour by lazy { parameter.valueFour(this) }
- private fun openOne() = parameter.loaderOne.openLoader()
- private fun openTwo() = parameter.loaderTwo.openLoader()
+ private fun openOne() = parameter.providerOne.openProvider()
+ private fun openTwo() = parameter.providerTwo.openProvider()
+ private fun openThree() = parameter.providerThree.openProvider()
+ private fun openFour() = parameter.providerFour.openProvider()
// Class method for syntax highlighting purposes
- private fun getValue() = parameter.getValue(this)
+ private fun getValue(c: Context = context) = parameter.getValue(c.resources)
@Test
- fun verifyValueUniqueness() {
+ fun assertValueUniqueness() {
// Ensure the parameters are valid in case of coding errors
- assertNotEquals(valueOne, getValue())
- assertNotEquals(valueTwo, getValue())
- assertNotEquals(valueOne, valueTwo)
+ val original = getValue()
+ assertNotEquals(valueOne, original)
+ assertNotEquals(valueTwo, original)
+ assertNotEquals(valueThree, original)
+ assertNotEquals(valueFour, original)
+ assertNotEquals(valueTwo, valueOne)
+ assertNotEquals(valueThree, valueOne)
+ assertNotEquals(valueFour, valueOne)
+ assertNotEquals(valueThree, valueTwo)
+ assertNotEquals(valueFour, valueTwo)
+ assertNotEquals(valueFour, valueThree)
+ }
+
+ @Test
+ fun addMultipleProviders() {
+ val originalValue = getValue()
+ val testOne = openOne()
+ val testTwo = openTwo()
+ val loader = ResourcesLoader()
+
+ resources.addLoader(loader)
+ loader.addProvider(testOne)
+ assertEquals(valueOne, getValue())
+
+ loader.addProvider(testTwo)
+ assertEquals(valueTwo, getValue())
+
+ loader.removeProvider(testOne)
+ assertEquals(valueTwo, getValue())
+
+ loader.removeProvider(testTwo)
+ assertEquals(originalValue, getValue())
}
@Test
@@ -154,201 +217,429 @@
val originalValue = getValue()
val testOne = openOne()
val testTwo = openTwo()
+ val loader1 = ResourcesLoader()
+ val loader2 = ResourcesLoader()
- addLoader(testOne, testTwo)
-
- assertEquals(valueTwo, getValue())
-
- removeLoader(testTwo)
-
+ resources.addLoader(loader1)
+ loader1.addProvider(testOne)
assertEquals(valueOne, getValue())
- removeLoader(testOne)
+ resources.addLoader(loader2)
+ loader2.addProvider(testTwo)
+ assertEquals(valueTwo, getValue())
+ resources.removeLoader(loader1)
+ assertEquals(valueTwo, getValue())
+
+ resources.removeLoader(loader2)
+ assertEquals(originalValue, getValue())
+ }
+
+ @Test
+ fun setMultipleProviders() {
+ val originalValue = getValue()
+ val testOne = openOne()
+ val testTwo = openTwo()
+ val loader = ResourcesLoader()
+
+ resources.addLoader(loader)
+ loader.providers = listOf(testOne, testTwo)
+ assertEquals(valueTwo, getValue())
+
+ loader.removeProvider(testTwo)
+ assertEquals(valueOne, getValue())
+
+ loader.providers = Collections.emptyList()
assertEquals(originalValue, getValue())
}
@Test
fun setMultipleLoaders() {
val originalValue = getValue()
- val testOne = openOne()
- val testTwo = openTwo()
+ val loader1 = ResourcesLoader()
+ loader1.addProvider(openOne())
+ val loader2 = ResourcesLoader()
+ loader2.addProvider(openTwo())
- setLoaders(testOne, testTwo)
-
+ resources.loaders = listOf(loader1, loader2)
assertEquals(valueTwo, getValue())
- removeLoader(testTwo)
-
+ resources.removeLoader(loader2)
assertEquals(valueOne, getValue())
- setLoaders()
-
+ resources.loaders = Collections.emptyList()
assertEquals(originalValue, getValue())
}
- @Test
- fun getLoadersContainsAll() {
+ @Test(expected = UnsupportedOperationException::class)
+ fun getProvidersDoesNotLeakMutability() {
val testOne = openOne()
- val testTwo = openTwo()
-
- addLoader(testOne, testTwo)
-
- assertThat(getLoaders()).containsAllOf(testOne, testTwo)
+ val loader = ResourcesLoader()
+ val providers = loader.providers
+ providers += testOne
}
- @Test
+ @Test(expected = UnsupportedOperationException::class)
fun getLoadersDoesNotLeakMutability() {
+ val loaders = resources.loaders
+ loaders += ResourcesLoader()
+ }
+
+ @Test
+ fun alreadyAddedProviderNoOps() {
+ val testOne = openOne()
+ val testTwo = openTwo()
+ val loader = ResourcesLoader()
+
+ resources.addLoader(loader)
+ loader.addProvider(testOne)
+ loader.addProvider(testTwo)
+ loader.addProvider(testOne)
+
+ assertEquals(2, loader.providers.size)
+ assertEquals(loader.providers[0], testOne)
+ assertEquals(loader.providers[1], testTwo)
+ }
+
+ @Test
+ fun alreadyAddedLoaderNoOps() {
+ val loader1 = ResourcesLoader()
+ loader1.addProvider(openOne())
+ val loader2 = ResourcesLoader()
+ loader2.addProvider(openTwo())
+
+ resources.addLoader(loader1)
+ resources.addLoader(loader2)
+ resources.addLoader(loader1)
+
+ assertEquals(2, resources.loaders.size)
+ assertEquals(resources.loaders[0], loader1)
+ assertEquals(resources.loaders[1], loader2)
+ }
+
+ @Test
+ fun repeatedRemoveProviderNoOps() {
+ val testOne = openOne()
+ val testTwo = openTwo()
+ val loader = ResourcesLoader()
+
+ resources.addLoader(loader)
+ loader.addProvider(testOne)
+ loader.addProvider(testTwo)
+
+ loader.removeProvider(testOne)
+ loader.removeProvider(testOne)
+
+ assertEquals(1, loader.providers.size)
+ assertEquals(loader.providers[0], testTwo)
+ }
+
+ @Test
+ fun repeatedRemoveLoaderNoOps() {
+ val loader1 = ResourcesLoader()
+ loader1.addProvider(openOne())
+ val loader2 = ResourcesLoader()
+ loader2.addProvider(openTwo())
+
+ resources.loaders = listOf(loader1, loader2)
+ resources.removeLoader(loader1)
+ resources.removeLoader(loader1)
+
+ assertEquals(1, resources.loaders.size)
+ assertEquals(resources.loaders[0], loader2)
+ }
+
+ @Test
+ fun repeatedSetProvider() {
+ val testOne = openOne()
+ val testTwo = openTwo()
+ val loader = ResourcesLoader()
+
+ resources.addLoader(loader)
+ loader.providers = listOf(testOne, testTwo)
+ loader.providers = listOf(testOne, testTwo)
+
+ assertEquals(2, loader.providers.size)
+ assertEquals(loader.providers[0], testOne)
+ assertEquals(loader.providers[1], testTwo)
+ }
+
+ @Test
+ fun repeatedSetLoaders() {
+ val loader1 = ResourcesLoader()
+ loader1.addProvider(openOne())
+ val loader2 = ResourcesLoader()
+ loader2.addProvider(openTwo())
+
+ resources.loaders = listOf(loader1, loader2)
+ resources.loaders = listOf(loader1, loader2)
+
+ assertEquals(2, resources.loaders.size)
+ assertEquals(resources.loaders[0], loader1)
+ assertEquals(resources.loaders[1], loader2)
+ }
+
+ @Test
+ fun reorderProviders() {
val originalValue = getValue()
val testOne = openOne()
val testTwo = openTwo()
+ val loader = ResourcesLoader()
- addLoader(testOne)
-
- assertEquals(valueOne, getValue())
-
- val loaders = getLoaders()
- loaders += testTwo
-
- assertEquals(valueOne, getValue())
-
- removeLoader(testOne)
-
- assertEquals(originalValue, getValue())
- }
-
- @Test(expected = IllegalArgumentException::class)
- fun alreadyAddedThrows() {
- val testOne = openOne()
- val testTwo = openTwo()
-
- addLoader(testOne)
- addLoader(testTwo)
- addLoader(testOne)
- }
-
- @Test(expected = IllegalArgumentException::class)
- fun alreadyAddedAndSetThrows() {
- val testOne = openOne()
- val testTwo = openTwo()
-
- addLoader(testOne)
- addLoader(testTwo)
- setLoaders(testTwo)
- }
-
- @Test
- fun repeatedRemoveSucceeds() {
- val originalValue = getValue()
- val testOne = openOne()
-
- addLoader(testOne)
-
- assertNotEquals(originalValue, getValue())
-
- removeLoader(testOne)
-
- assertEquals(originalValue, getValue())
-
- removeLoader(testOne)
-
- assertEquals(originalValue, getValue())
- }
-
- @Test
- fun addToFront() {
- val testOne = openOne()
- val testTwo = openTwo()
-
- addLoader(testOne)
-
- assertEquals(valueOne, getValue())
-
- addLoader(testTwo, 0)
-
- assertEquals(valueOne, getValue())
-
- // Remove top loader, so previously added to front should now resolve
- removeLoader(testOne)
+ resources.addLoader(loader)
+ loader.addProvider(testOne)
+ loader.addProvider(testTwo)
assertEquals(valueTwo, getValue())
- }
- @Test
- fun addToEnd() {
- val testOne = openOne()
- val testTwo = openTwo()
-
- addLoader(testOne)
-
- assertEquals(valueOne, getValue())
-
- addLoader(testTwo, 1)
-
+ loader.removeProvider(testOne)
assertEquals(valueTwo, getValue())
- }
- @Test(expected = IndexOutOfBoundsException::class)
- fun addPastEnd() {
- val testOne = openOne()
- val testTwo = openTwo()
-
- addLoader(testOne)
-
+ loader.addProvider(testOne)
assertEquals(valueOne, getValue())
- addLoader(testTwo, 2)
- }
-
- @Test(expected = IndexOutOfBoundsException::class)
- fun addBeforeFront() {
- val testOne = openOne()
- val testTwo = openTwo()
-
- addLoader(testOne)
-
+ loader.removeProvider(testTwo)
assertEquals(valueOne, getValue())
- addLoader(testTwo, -1)
+ loader.removeProvider(testOne)
+ assertEquals(originalValue, getValue())
}
@Test
- fun reorder() {
+ fun reorderLoaders() {
val originalValue = getValue()
val testOne = openOne()
val testTwo = openTwo()
+ val loader1 = ResourcesLoader()
+ loader1.addProvider(testOne)
+ val loader2 = ResourcesLoader()
+ loader2.addProvider(testTwo)
- addLoader(testOne, testTwo)
-
+ resources.addLoader(loader1)
+ resources.addLoader(loader2)
assertEquals(valueTwo, getValue())
- removeLoader(testOne)
-
+ resources.removeLoader(loader1)
assertEquals(valueTwo, getValue())
- addLoader(testOne)
-
+ resources.addLoader(loader1)
assertEquals(valueOne, getValue())
- removeLoader(testTwo)
-
+ resources.removeLoader(loader2)
assertEquals(valueOne, getValue())
- removeLoader(testOne)
-
+ resources.removeLoader(loader1)
assertEquals(originalValue, getValue())
}
+ @Test
+ fun reorderMultipleLoadersAndProviders() {
+ val testOne = openOne()
+ val testTwo = openTwo()
+ val testThree = openThree()
+ val testFour = openFour()
+
+ val loader1 = ResourcesLoader()
+ loader1.providers = listOf(testOne, testTwo)
+
+ val loader2 = ResourcesLoader()
+ loader2.providers = listOf(testThree, testFour)
+
+ resources.loaders = listOf(loader1, loader2)
+ assertEquals(valueFour, getValue())
+
+ resources.loaders = listOf(loader2, loader1)
+ assertEquals(valueTwo, getValue())
+
+ loader1.removeProvider(testTwo)
+ assertEquals(valueOne, getValue())
+
+ loader1.removeProvider(testOne)
+ assertEquals(valueFour, getValue())
+ }
+
+ private fun createContext(context: Context, id: Int): Context {
+ val overrideConfig = Configuration()
+ overrideConfig.orientation = Int.MAX_VALUE - id
+ return context.createConfigurationContext(overrideConfig)
+ }
+
+ @Test
+ fun copyContextLoaders() {
+ val originalValue = getValue()
+ val loader1 = ResourcesLoader()
+ loader1.addProvider(openOne())
+ val loader2 = ResourcesLoader()
+ loader2.addProvider(openTwo())
+
+ resources.loaders = listOf(loader1)
+ assertEquals(valueOne, getValue())
+
+ // The child context should include the loaders of the original context.
+ val childContext = createContext(context, 0)
+ assertEquals(valueOne, getValue(childContext))
+
+ // Changing the loaders of the child context should not affect the original context.
+ childContext.resources.loaders = listOf(loader1, loader2)
+ assertEquals(valueOne, getValue())
+ assertEquals(valueTwo, getValue(childContext))
+
+ // Changing the loaders of the original context should not affect the child context.
+ resources.removeLoader(loader1)
+ assertEquals(originalValue, getValue())
+ assertEquals(valueTwo, getValue(childContext))
+
+ // A new context created from the original after an update to the original's loaders should
+ // have the updated loaders.
+ val originalPrime = createContext(context, 2)
+ assertEquals(originalValue, getValue(originalPrime))
+
+ // A new context created from the child context after an update to the child's loaders
+ // should have the updated loaders.
+ val childPrime = createContext(childContext, 1)
+ assertEquals(valueTwo, getValue(childPrime))
+ }
+
+ @Test
+ fun loaderUpdatesAffectContexts() {
+ val originalValue = getValue()
+ val testOne = openOne()
+ val testTwo = openTwo()
+ val loader = ResourcesLoader()
+
+ resources.addLoader(loader)
+ loader.addProvider(testOne)
+ assertEquals(valueOne, getValue())
+
+ val childContext = createContext(context, 0)
+ assertEquals(valueOne, getValue(childContext))
+
+ // Adding a provider to a loader affects all contexts that use the loader.
+ loader.addProvider(testTwo)
+ assertEquals(valueTwo, getValue())
+ assertEquals(valueTwo, getValue(childContext))
+
+ // Changes to the loaders for a context do not affect providers.
+ resources.clearLoaders()
+ assertEquals(originalValue, getValue())
+ assertEquals(valueTwo, getValue(childContext))
+
+ val childContext2 = createContext(context, 1)
+ assertEquals(originalValue, getValue())
+ assertEquals(originalValue, getValue(childContext2))
+
+ childContext2.resources.addLoader(loader)
+ assertEquals(originalValue, getValue())
+ assertEquals(valueTwo, getValue(childContext))
+ assertEquals(valueTwo, getValue(childContext2))
+ }
+
+ @Test
+ fun appLoadersIncludedInActivityContexts() {
+ val loader = ResourcesLoader()
+ loader.addProvider(openOne())
+
+ val applicationContext = context.applicationContext
+ applicationContext.resources.addLoader(loader)
+ assertEquals(valueOne, getValue(applicationContext))
+
+ val activity = mTestActivityRule.launchActivity(Intent())
+ assertEquals(valueOne, getValue(activity))
+
+ applicationContext.resources.clearLoaders()
+ }
+
+ @Test
+ fun loadersApplicationInfoChanged() {
+ val loader1 = ResourcesLoader()
+ loader1.addProvider(openOne())
+ val loader2 = ResourcesLoader()
+ loader2.addProvider(openTwo())
+
+ val applicationContext = context.applicationContext
+ applicationContext.resources.addLoader(loader1)
+ assertEquals(valueOne, getValue(applicationContext))
+
+ var token: IBinder? = null
+ val activity = mTestActivityRule.launchActivity(Intent())
+ mTestActivityRule.runOnUiThread(Runnable {
+ token = activity.activityToken
+ val at = activity.activityThread
+
+ // The activity should have the loaders from the application.
+ assertEquals(valueOne, getValue(applicationContext))
+ assertEquals(valueOne, getValue(activity))
+
+ activity.resources.addLoader(loader2)
+ assertEquals(valueOne, getValue(applicationContext))
+ assertEquals(valueTwo, getValue(activity))
+
+ // Relaunches the activity.
+ at.handleApplicationInfoChanged(activity.applicationInfo)
+ })
+
+ mTestActivityRule.runOnUiThread(Runnable {
+ val activityThread = activity.activityThread
+ val newActivity = activityThread.getActivity(token)
+
+ // The loader added to the activity loaders should not be persisted.
+ assertEquals(valueOne, getValue(applicationContext))
+ assertEquals(valueOne, getValue(newActivity))
+ })
+
+ applicationContext.resources.clearLoaders()
+ }
+
+ @Test
+ fun multipleLoadersHaveSameProviders() {
+ val provider1 = openOne()
+ val loader1 = ResourcesLoader()
+ loader1.addProvider(provider1)
+ val loader2 = ResourcesLoader()
+ loader2.addProvider(provider1)
+ loader2.addProvider(openTwo())
+
+ resources.loaders = listOf(loader1, loader2)
+ assertEquals(valueTwo, getValue())
+
+ resources.loaders = listOf(loader2, loader1)
+ assertEquals(valueOne, getValue())
+
+ assertEquals(2, resources.assets.apkAssets.count { apkAssets -> apkAssets.isForLoader })
+ }
+
+ @Test(expected = IllegalStateException::class)
+ fun cannotUseClosedProvider() {
+ val provider = openOne()
+ provider.close()
+ val loader = ResourcesLoader()
+ loader.addProvider(provider)
+ }
+
+ @Test(expected = IllegalStateException::class)
+ fun cannotCloseUsedProvider() {
+ val provider = openOne()
+ val loader = ResourcesLoader()
+ loader.addProvider(provider)
+ provider.close()
+ }
+
data class Parameter(
- val getValue: ResourceLoaderValuesTest.() -> Any,
- val loaderOne: String,
+ val getValue: Resources.() -> Any,
+ val providerOne: String,
val valueOne: ResourceLoaderValuesTest.() -> Any,
- val loaderTwo: String,
+ val providerTwo: String,
val valueTwo: ResourceLoaderValuesTest.() -> Any,
+ val providerThree: String,
+ val valueThree: ResourceLoaderValuesTest.() -> Any,
+ val providerFour: String,
+ val valueFour: ResourceLoaderValuesTest.() -> Any,
val dataTypes: List<DataType>
) {
override fun toString(): String {
- val prefix = loaderOne.commonPrefixWith(loaderTwo)
- return "$prefix${loaderOne.removePrefix(prefix)}|${loaderTwo.removePrefix(prefix)}"
+ val prefix = providerOne.commonPrefixWith(providerTwo)
+ return "$prefix${providerOne.removePrefix(prefix)}|${providerTwo.removePrefix(prefix)}"
}
}
}
+
+class TestActivity : Activity()
\ No newline at end of file
diff --git a/core/tests/ResourceLoaderTests/src/android/content/res/loader/test/Utils.kt b/core/tests/ResourceLoaderTests/src/android/content/res/loader/test/Utils.kt
index df2d09a..4e8ee5c 100644
--- a/core/tests/ResourceLoaderTests/src/android/content/res/loader/test/Utils.kt
+++ b/core/tests/ResourceLoaderTests/src/android/content/res/loader/test/Utils.kt
@@ -26,10 +26,6 @@
import org.xmlpull.v1.XmlPullParser
import java.io.File
-// Enforce use of [android.util.Pair] instead of Kotlin's so it matches the ResourceLoader APIs
-typealias Pair<F, S> = android.util.Pair<F, S>
-infix fun <A, B> A.to(that: B): Pair<A, B> = Pair.create(this, that)!!
-
object Utils {
val ANSWER_THROWS = Answer<Any> {
when (val name = it.method.name) {
diff --git a/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java b/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java
index a2dab99..df5c9d2 100644
--- a/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java
+++ b/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java
@@ -72,12 +72,12 @@
public void testMultipleCallsWithIdenticalParametersCacheReference() {
Resources resources = mResourcesManager.getResources(
null, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null,
- CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
+ CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
assertNotNull(resources);
Resources newResources = mResourcesManager.getResources(
null, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null,
- CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
+ CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
assertNotNull(newResources);
assertSame(resources, newResources);
}
@@ -86,14 +86,14 @@
public void testMultipleCallsWithDifferentParametersReturnDifferentReferences() {
Resources resources = mResourcesManager.getResources(
null, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null,
- CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
+ CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
assertNotNull(resources);
Configuration overrideConfig = new Configuration();
overrideConfig.smallestScreenWidthDp = 200;
Resources newResources = mResourcesManager.getResources(
null, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, overrideConfig,
- CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
+ CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
assertNotNull(newResources);
assertNotSame(resources, newResources);
}
@@ -102,12 +102,13 @@
public void testAddingASplitCreatesANewImpl() {
Resources resources1 = mResourcesManager.getResources(
null, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null,
- CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
+ CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
assertNotNull(resources1);
Resources resources2 = mResourcesManager.getResources(
null, APP_ONE_RES_DIR, new String[] { APP_ONE_RES_SPLIT_DIR }, null, null,
- Display.DEFAULT_DISPLAY, null, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
+ Display.DEFAULT_DISPLAY, null, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO,null,
+ null);
assertNotNull(resources2);
assertNotSame(resources1, resources2);
@@ -118,12 +119,12 @@
public void testUpdateConfigurationUpdatesAllAssetManagers() {
Resources resources1 = mResourcesManager.getResources(
null, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null,
- CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
+ CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
assertNotNull(resources1);
Resources resources2 = mResourcesManager.getResources(
null, APP_TWO_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null,
- CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
+ CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
assertNotNull(resources2);
Binder activity = new Binder();
@@ -131,7 +132,7 @@
overrideConfig.orientation = Configuration.ORIENTATION_LANDSCAPE;
Resources resources3 = mResourcesManager.getResources(
activity, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY,
- overrideConfig, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
+ overrideConfig, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
assertNotNull(resources3);
// No Resources object should be the same.
@@ -164,13 +165,13 @@
Binder activity1 = new Binder();
Resources resources1 = mResourcesManager.getResources(
activity1, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null,
- CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
+ CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
assertNotNull(resources1);
Binder activity2 = new Binder();
Resources resources2 = mResourcesManager.getResources(
activity2, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null,
- CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
+ CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
assertNotNull(resources1);
// The references themselves should be unique.
@@ -185,7 +186,7 @@
Binder activity1 = new Binder();
Resources resources1 = mResourcesManager.createBaseActivityResources(
activity1, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null,
- CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
+ CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
assertNotNull(resources1);
Resources.Theme theme = resources1.newTheme();
@@ -218,7 +219,7 @@
config1.densityDpi = 280;
Resources resources1 = mResourcesManager.createBaseActivityResources(
activity1, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, config1,
- CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
+ CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
assertNotNull(resources1);
// Create a Resources based on the Activity.
@@ -226,7 +227,7 @@
config2.screenLayout |= Configuration.SCREENLAYOUT_ROUND_YES;
Resources resources2 = mResourcesManager.getResources(
activity1, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, config2,
- CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
+ CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
assertNotNull(resources2);
assertNotSame(resources1, resources2);