Test instant app's access to external storage
Add CtsScopedStorageHostTest to cts test-suite which runs tests in both
instant and non-instant mode. Annotate tests that will fail in instant
mode as @AppModeFull.
Bug: 149004073
Test: atest CtsScopedStorageHostTest
Test: atest CtsScopedStorageHostTest --instant
Change-Id: I9c9fa1cb094259bef414e39b36e1f52964b8cdc3
Merged-In: I9c9fa1cb094259bef414e39b36e1f52964b8cdc3
(cherry picked from commit cdd387a4c7f431c16c81a48ea7c923b23ad45144)
diff --git a/hostsidetests/scopedstorage/Android.bp b/hostsidetests/scopedstorage/Android.bp
index 3e5096b..1a1a7f9 100644
--- a/hostsidetests/scopedstorage/Android.bp
+++ b/hostsidetests/scopedstorage/Android.bp
@@ -15,28 +15,28 @@
android_test_helper_app {
name: "CtsScopedStorageTestAppA",
manifest: "ScopedStorageTestHelper/TestAppA.xml",
- static_libs: ["androidx.test.rules", "cts-scopedstorage-lib"],
+ static_libs: ["cts-scopedstorage-lib"],
sdk_version: "test_current",
srcs: ["ScopedStorageTestHelper/src/**/*.java"],
}
android_test_helper_app {
name: "CtsScopedStorageTestAppB",
manifest: "ScopedStorageTestHelper/TestAppB.xml",
- static_libs: ["androidx.test.rules", "cts-scopedstorage-lib"],
+ static_libs: ["cts-scopedstorage-lib"],
sdk_version: "test_current",
srcs: ["ScopedStorageTestHelper/src/**/*.java"],
}
android_test_helper_app {
name: "CtsScopedStorageTestAppC",
manifest: "ScopedStorageTestHelper/TestAppC.xml",
- static_libs: ["androidx.test.rules", "cts-scopedstorage-lib"],
+ static_libs: ["cts-scopedstorage-lib"],
sdk_version: "test_current",
srcs: ["ScopedStorageTestHelper/src/**/*.java"],
}
android_test_helper_app {
name: "CtsScopedStorageTestAppCLegacy",
manifest: "ScopedStorageTestHelper/TestAppCLegacy.xml",
- static_libs: ["androidx.test.rules", "cts-scopedstorage-lib"],
+ static_libs: ["cts-scopedstorage-lib"],
sdk_version: "test_current",
target_sdk_version: "28",
srcs: ["ScopedStorageTestHelper/src/**/*.java"],
@@ -46,9 +46,9 @@
name: "ScopedStorageTest",
manifest: "AndroidManifest.xml",
srcs: ["src/**/*.java"],
- static_libs: ["androidx.test.rules", "truth-prebuilt", "cts-scopedstorage-lib"],
+ static_libs: ["truth-prebuilt", "cts-scopedstorage-lib"],
compile_multilib: "both",
- test_suites: ["general-tests", "mts"],
+ test_suites: ["general-tests", "mts", "cts"],
sdk_version: "test_current",
java_resources: [
":CtsScopedStorageTestAppA",
@@ -61,9 +61,9 @@
name: "LegacyStorageTest",
manifest: "legacy/AndroidManifest.xml",
srcs: ["legacy/src/**/*.java"],
- static_libs: ["androidx.test.rules", "truth-prebuilt", "cts-scopedstorage-lib"],
+ static_libs: ["truth-prebuilt", "cts-scopedstorage-lib"],
compile_multilib: "both",
- test_suites: ["general-tests", "mts"],
+ test_suites: ["general-tests", "mts", "cts"],
sdk_version: "test_current",
target_sdk_version: "29",
java_resources: [
@@ -74,17 +74,15 @@
java_test_host {
name: "CtsScopedStorageHostTest",
srcs: ["host/src/**/*.java"],
- libs: ["tradefed"],
- static_libs: ["testng"],
- test_suites: ["general-tests", "mts"],
+ libs: ["tradefed", "testng"],
+ test_suites: ["general-tests", "mts", "cts"],
test_config: "AndroidTest.xml",
}
java_test_host {
name: "CtsScopedStoragePublicVolumeHostTest",
srcs: ["host/src/**/*.java"],
- libs: ["tradefed"],
- static_libs: ["testng"],
+ libs: ["tradefed", "testng"],
test_suites: ["general-tests", "mts"],
test_config: "PublicVolumeTest.xml",
}
diff --git a/hostsidetests/scopedstorage/AndroidTest.xml b/hostsidetests/scopedstorage/AndroidTest.xml
index 64599d8..43208ac 100644
--- a/hostsidetests/scopedstorage/AndroidTest.xml
+++ b/hostsidetests/scopedstorage/AndroidTest.xml
@@ -15,6 +15,10 @@
-->
<configuration description="External storage host test for legacy and scoped storage">
<option name="test-suite-tag" value="cts" />
+ <option name="config-descriptor:metadata" key="component" value="framework" />
+ <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_secondary_user" />
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
<option name="test-file-name" value="ScopedStorageTest.apk" />
@@ -23,6 +27,7 @@
<test class="com.android.tradefed.testtype.HostTest" >
<option name="class" value="android.scopedstorage.cts.host.LegacyStorageHostTest" />
<option name="class" value="android.scopedstorage.cts.host.ScopedStorageHostTest" />
+ <option name="class" value="android.scopedstorage.cts.host.ScopedStorageInstantAppHostTest" />
</test>
<object type="module_controller" class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController">
diff --git a/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/LegacyStorageHostTest.java b/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/LegacyStorageHostTest.java
index 7c2bf54..ef196c4 100644
--- a/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/LegacyStorageHostTest.java
+++ b/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/LegacyStorageHostTest.java
@@ -20,6 +20,8 @@
import static org.junit.Assert.assertTrue;
+import android.platform.test.annotations.AppModeFull;
+
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
@@ -32,6 +34,7 @@
* Runs the legacy file path access tests.
*/
@RunWith(DeviceJUnit4ClassRunner.class)
+@AppModeFull
public class LegacyStorageHostTest extends BaseHostJUnit4Test {
private boolean isExternalStorageSetup = false;
diff --git a/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/ScopedStorageHostTest.java b/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/ScopedStorageHostTest.java
index c380d1a..3bbae2d 100644
--- a/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/ScopedStorageHostTest.java
+++ b/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/ScopedStorageHostTest.java
@@ -18,6 +18,8 @@
import static org.junit.Assert.assertTrue;
+import android.platform.test.annotations.AppModeFull;
+
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
@@ -30,6 +32,7 @@
* Runs the ScopedStorageTest tests.
*/
@RunWith(DeviceJUnit4ClassRunner.class)
+@AppModeFull
public class ScopedStorageHostTest extends BaseHostJUnit4Test {
private boolean mIsExternalStorageSetup = false;
diff --git a/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/ScopedStorageInstantAppHostTest.java b/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/ScopedStorageInstantAppHostTest.java
new file mode 100644
index 0000000..c97b41f
--- /dev/null
+++ b/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/ScopedStorageInstantAppHostTest.java
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ * 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.scopedstorage.cts.host;
+
+import static org.junit.Assert.assertTrue;
+
+import android.platform.test.annotations.AppModeInstant;
+
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Runs the ScopedStorageTest tests for an instant app.
+ */
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class ScopedStorageInstantAppHostTest extends BaseHostJUnit4Test {
+ /**
+ * Runs the given phase of Test by calling into the device.
+ * Throws an exception if the test phase fails.
+ */
+ protected void runDeviceTest(String phase) throws Exception {
+ assertTrue(runDeviceTests("android.scopedstorage.cts",
+ "android.scopedstorage.cts.ScopedStorageTest", phase));
+ }
+
+ @Test
+ @AppModeInstant
+ public void testInstantAppsCantAccessExternalStorage() throws Exception {
+ runDeviceTest("testInstantAppsCantAccessExternalStorage");
+ }
+}
diff --git a/hostsidetests/scopedstorage/libs/ScopedStorageTestLib/Android.bp b/hostsidetests/scopedstorage/libs/ScopedStorageTestLib/Android.bp
index 3a5ba59..be2ae44 100644
--- a/hostsidetests/scopedstorage/libs/ScopedStorageTestLib/Android.bp
+++ b/hostsidetests/scopedstorage/libs/ScopedStorageTestLib/Android.bp
@@ -15,6 +15,6 @@
java_library {
name: "cts-scopedstorage-lib",
srcs: ["src/**/*.java"],
- static_libs: ["androidx.test.rules", "cts-install-lib"],
+ static_libs: ["androidx.test.rules", "cts-install-lib", "platform-test-annotations",],
sdk_version: "test_current"
}
diff --git a/hostsidetests/scopedstorage/src/android/scopedstorage/cts/ScopedStorageTest.java b/hostsidetests/scopedstorage/src/android/scopedstorage/cts/ScopedStorageTest.java
index 4022fb5..6c9a49f 100644
--- a/hostsidetests/scopedstorage/src/android/scopedstorage/cts/ScopedStorageTest.java
+++ b/hostsidetests/scopedstorage/src/android/scopedstorage/cts/ScopedStorageTest.java
@@ -118,6 +118,7 @@
import android.os.FileUtils;
import android.os.ParcelFileDescriptor;
import android.os.Process;
+import android.platform.test.annotations.AppModeInstant;
import android.provider.MediaStore;
import android.system.ErrnoException;
import android.system.Os;
@@ -185,8 +186,10 @@
// skips all test cases if FUSE is not active.
assumeTrue(getBoolean("persist.sys.fuse", false));
- pollForExternalStorageState();
- getExternalFilesDir().mkdirs();
+ if (!getContext().getPackageManager().isInstantApp()) {
+ pollForExternalStorageState();
+ getExternalFilesDir().mkdirs();
+ }
}
/**
@@ -1577,8 +1580,7 @@
THIS_PACKAGE_NAME, TEST_APP_A.getPackageName()));
final File otherAppExternalDataFile = new File(otherAppExternalDataDir,
NONMEDIA_FILE_NAME);
- assertThat(createFileAs(TEST_APP_A, otherAppExternalDataFile.getAbsolutePath()))
- .isTrue();
+ assertCreateFilesAs(TEST_APP_A, otherAppExternalDataFile);
// File Manager app gets global access with MANAGE_EXTERNAL_STORAGE permission, however,
// file manager app doesn't have access to other app's external files directory
@@ -1598,6 +1600,41 @@
}
/**
+ * Tests that an instant app can't access external storage.
+ */
+ @Test
+ @AppModeInstant
+ public void testInstantAppsCantAccessExternalStorage() throws Exception {
+ assumeTrue("This test requires that the test runs as an Instant app",
+ getContext().getPackageManager().isInstantApp());
+ assertThat(getContext().getPackageManager().isInstantApp()).isTrue();
+
+ // Can't read ExternalStorageDir
+ assertThat(getExternalStorageDir().list()).isNull();
+
+ // Can't create a top-level direcotry
+ final File topLevelDir = new File(getExternalStorageDir(), TEST_DIRECTORY_NAME);
+ assertThat(topLevelDir.mkdir()).isFalse();
+
+ // Can't create file under root dir
+ final File newTxtFile = new File(getExternalStorageDir(), NONMEDIA_FILE_NAME);
+ assertThrows(IOException.class,
+ () -> { newTxtFile.createNewFile(); });
+
+ // Can't create music file under /MUSIC
+ final File newMusicFile = new File(getMusicDir(), AUDIO_FILE_NAME);
+ assertThrows(IOException.class,
+ () -> { newMusicFile.createNewFile(); });
+
+ // getExternalFilesDir() is not null
+ assertThat(getExternalFilesDir()).isNotNull();
+
+ // Can't read/write app specific dir
+ assertThat(getExternalFilesDir().list()).isNull();
+ assertThat(getExternalFilesDir().exists()).isFalse();
+ }
+
+ /**
* Test that apps can create and delete hidden file.
*/
@Test