Update permission checks for dual permission mode.
Callers must hold both the old and new permissions, so that we can
handle obscure cases like when an app targets Q but was installed on
a device that was originally running on P before being upgraded to Q.
Bug: 126785920, 126788266
Test: atest android.appsecurity.cts.ExternalStorageHostTest
Exempt-From-Owner-Approval: trivial tests
Change-Id: I7e474738053c0d7fb9e1a9a77911927558f9f051
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java
index fe0557a..2456c24 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java
@@ -62,9 +62,13 @@
private static final String MULTIUSER_APK = "CtsMultiUserStorageApp.apk";
private static final String MULTIUSER_PKG = "com.android.cts.multiuserstorageapp";
private static final String MULTIUSER_CLASS = MULTIUSER_PKG + ".MultiUserStorageTest";
+
private static final String MEDIA_APK = "CtsMediaStorageApp.apk";
private static final String MEDIA_PKG = "com.android.cts.mediastorageapp";
private static final String MEDIA_CLASS = MEDIA_PKG + ".MediaStorageTest";
+ private static final String MEDIA28_APK = "CtsMediaStorageApp28.apk";
+ private static final String MEDIA28_PKG = "com.android.cts.mediastorageapp28";
+ private static final String MEDIA28_CLASS = MEDIA28_PKG + ".MediaStorageTest";
private static final String PKG_A = "com.android.cts.storageapp_a";
private static final String PKG_B = "com.android.cts.storageapp_b";
@@ -72,6 +76,8 @@
private static final String APK_B = "CtsStorageAppB.apk";
private static final String CLASS = "com.android.cts.storageapp.StorageTest";
+ private static final String PERM_READ_EXTERNAL_STORAGE = "android.permission.READ_EXTERNAL_STORAGE";
+ private static final String PERM_WRITE_EXTERNAL_STORAGE = "android.permission.WRITE_EXTERNAL_STORAGE";
private static final String PERM_READ_MEDIA_AUDIO = "android.permission.READ_MEDIA_AUDIO";
private static final String PERM_READ_MEDIA_VIDEO = "android.permission.READ_MEDIA_VIDEO";
private static final String PERM_READ_MEDIA_IMAGES = "android.permission.READ_MEDIA_IMAGES";
@@ -545,6 +551,23 @@
}
@Test
+ public void testMediaNone28() throws Exception {
+ // STOPSHIP: remove this once isolated storage is always enabled
+ Assume.assumeTrue(hasIsolatedStorage());
+
+ installPackage(MEDIA28_APK);
+ for (int user : mUsers) {
+ updatePermissions(MEDIA28_PKG, user, new String[] {
+ PERM_READ_EXTERNAL_STORAGE,
+ PERM_WRITE_EXTERNAL_STORAGE,
+ }, false);
+ updateRole(MEDIA28_PKG, user, ROLE_GALLERY, false);
+
+ runDeviceTests(MEDIA28_PKG, MEDIA_CLASS, "testMediaNone", user);
+ }
+ }
+
+ @Test
public void testMediaRead() throws Exception {
// STOPSHIP: remove this once isolated storage is always enabled
Assume.assumeTrue(hasIsolatedStorage());
@@ -563,6 +586,23 @@
}
@Test
+ public void testMediaRead28() throws Exception {
+ // STOPSHIP: remove this once isolated storage is always enabled
+ Assume.assumeTrue(hasIsolatedStorage());
+
+ installPackage(MEDIA28_APK);
+ for (int user : mUsers) {
+ updatePermissions(MEDIA28_PKG, user, new String[] {
+ PERM_READ_EXTERNAL_STORAGE,
+ PERM_WRITE_EXTERNAL_STORAGE,
+ }, true);
+ updateRole(MEDIA28_PKG, user, ROLE_GALLERY, false);
+
+ runDeviceTests(MEDIA28_PKG, MEDIA_CLASS, "testMediaRead", user);
+ }
+ }
+
+ @Test
public void testMediaWrite() throws Exception {
// STOPSHIP: remove this once isolated storage is always enabled
Assume.assumeTrue(hasIsolatedStorage());
@@ -581,6 +621,23 @@
}
@Test
+ public void testMediaWrite28() throws Exception {
+ // STOPSHIP: remove this once isolated storage is always enabled
+ Assume.assumeTrue(hasIsolatedStorage());
+
+ installPackage(MEDIA28_APK);
+ for (int user : mUsers) {
+ updatePermissions(MEDIA28_PKG, user, new String[] {
+ PERM_READ_EXTERNAL_STORAGE,
+ PERM_WRITE_EXTERNAL_STORAGE,
+ }, true);
+ updateRole(MEDIA28_PKG, user, ROLE_GALLERY, true);
+
+ runDeviceTests(MEDIA28_PKG, MEDIA_CLASS, "testMediaWrite", user);
+ }
+ }
+
+ @Test
public void testMediaEscalation() throws Exception {
// STOPSHIP: remove this once isolated storage is always enabled
Assume.assumeTrue(hasIsolatedStorage());
diff --git a/hostsidetests/appsecurity/test-apps/MediaStorageApp/Android.mk b/hostsidetests/appsecurity/test-apps/MediaStorageApp/Android.mk
index 569520f..92da12d 100644
--- a/hostsidetests/appsecurity/test-apps/MediaStorageApp/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/MediaStorageApp/Android.mk
@@ -26,6 +26,7 @@
LOCAL_JAVA_LIBRARIES := android.test.base.stubs
LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_ASSET_DIR := $(LOCAL_PATH)/assets
LOCAL_PACKAGE_NAME := CtsMediaStorageApp
diff --git a/hostsidetests/appsecurity/test-apps/MediaStorageApp/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/MediaStorageApp/AndroidManifest.xml
index f1c0239..41d07eb 100644
--- a/hostsidetests/appsecurity/test-apps/MediaStorageApp/AndroidManifest.xml
+++ b/hostsidetests/appsecurity/test-apps/MediaStorageApp/AndroidManifest.xml
@@ -34,8 +34,6 @@
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="com.android.cts.mediastorageapp" />
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
diff --git a/hostsidetests/appsecurity/test-apps/MediaStorageApp/res/raw/testmp3.mp3 b/hostsidetests/appsecurity/test-apps/MediaStorageApp/assets/testmp3.mp3
similarity index 100%
rename from hostsidetests/appsecurity/test-apps/MediaStorageApp/res/raw/testmp3.mp3
rename to hostsidetests/appsecurity/test-apps/MediaStorageApp/assets/testmp3.mp3
Binary files differ
diff --git a/hostsidetests/appsecurity/test-apps/MediaStorageApp/src/com/android/cts/mediastorageapp/MediaStorageTest.java b/hostsidetests/appsecurity/test-apps/MediaStorageApp/src/com/android/cts/mediastorageapp/MediaStorageTest.java
index a546893..fdb46c2 100644
--- a/hostsidetests/appsecurity/test-apps/MediaStorageApp/src/com/android/cts/mediastorageapp/MediaStorageTest.java
+++ b/hostsidetests/appsecurity/test-apps/MediaStorageApp/src/com/android/cts/mediastorageapp/MediaStorageTest.java
@@ -44,9 +44,6 @@
import com.android.cts.mediastorageapp.MediaStoreUtils.PendingParams;
import com.android.cts.mediastorageapp.MediaStoreUtils.PendingSession;
-import androidx.test.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -57,6 +54,9 @@
import java.io.OutputStream;
import java.util.HashSet;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
@RunWith(AndroidJUnit4.class)
public class MediaStorageTest {
private Context mContext;
@@ -254,7 +254,7 @@
collectionUri, displayName, "audio/mpeg");
final Uri pendingUri = MediaStoreUtils.createPending(context, params);
try (PendingSession session = MediaStoreUtils.openPending(context, pendingUri)) {
- try (InputStream in = context.getResources().openRawResource(R.raw.testmp3);
+ try (InputStream in = context.getResources().getAssets().open("testmp3.mp3");
OutputStream out = session.openOutputStream()) {
FileUtils.copy(in, out);
}
diff --git a/hostsidetests/appsecurity/test-apps/MediaStorageApp28/Android.mk b/hostsidetests/appsecurity/test-apps/MediaStorageApp28/Android.mk
new file mode 100644
index 0000000..97f8a2c
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/MediaStorageApp28/Android.mk
@@ -0,0 +1,36 @@
+# Copyright (C) 2018 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_SDK_VERSION := test_current
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ compatibility-device-util-axt \
+ androidx.test.rules \
+ ub-uiautomator
+
+LOCAL_JAVA_LIBRARIES := android.test.base.stubs
+
+LOCAL_SRC_FILES := $(call all-java-files-under, ../MediaStorageApp/src/)
+LOCAL_ASSET_DIR := $(LOCAL_PATH)/../MediaStorageApp/assets
+
+LOCAL_PACKAGE_NAME := CtsMediaStorageApp28
+
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_DEX_PREOPT := false
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/MediaStorageApp28/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/MediaStorageApp28/AndroidManifest.xml
new file mode 100644
index 0000000..77acd3a
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/MediaStorageApp28/AndroidManifest.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.cts.mediastorageapp28">
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+
+ <activity android:name=".StubActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.APP_GALLERY" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".GetResultActivity" />
+ </application>
+
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.cts.mediastorageapp28" />
+
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
+ <uses-sdk
+ android:minSdkVersion="28"
+ android:targetSdkVersion="28" />
+
+</manifest>