Merge "Camera: Skip invalid physical requests for depth only devices"
diff --git a/apps/CameraITS/tests/scene1/test_multi_camera_match.py b/apps/CameraITS/tests/scene1/test_multi_camera_match.py
index 76c8146..3310e27 100644
--- a/apps/CameraITS/tests/scene1/test_multi_camera_match.py
+++ b/apps/CameraITS/tests/scene1/test_multi_camera_match.py
@@ -36,16 +36,14 @@
with its.device.ItsSession() as cam:
props = cam.get_camera_properties()
its.caps.skip_unless(its.caps.per_frame_control(props) and
- its.caps.raw16(props) and
its.caps.logical_multi_camera(props))
ids = its.caps.logical_multi_camera_physical_ids(props)
- max_raw_size = its.objects.get_available_output_sizes('raw', props)[0]
for i in ids:
physical_props = cam.get_camera_properties_by_id(i)
its.caps.skip_unless(not its.caps.mono_camera(physical_props))
yuv_sizes[i] = its.objects.get_available_output_sizes(
- 'yuv', physical_props, match_ar_size=max_raw_size)
- if i == ids[0]:
+ 'yuv', physical_props)
+ if i == ids[0]: # get_available_output_sizes returns sorted list
yuv_match_sizes = yuv_sizes[i]
else:
list(set(yuv_sizes[i]).intersection(yuv_match_sizes))
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 05e430a..8b389c5 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -1259,6 +1259,7 @@
<category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_security" />
+ <meta-data android:name="test_required_features" android:value="android.software.secure_lock_screen" />
<meta-data android:name="test_excluded_features"
android:value="android.hardware.type.television:android.software.leanback:android.hardware.type.watch" />
</activity>
@@ -1273,7 +1274,8 @@
<meta-data android:name="test_category" android:value="@string/test_category_security" />
<meta-data android:name="test_excluded_features"
android:value="android.hardware.type.television:android.software.leanback:android.hardware.type.watch" />
- <meta-data android:name="test_required_features" android:value="android.hardware.fingerprint" />
+ <meta-data android:name="test_required_features"
+ android:value="android.hardware.fingerprint:android.software.secure_lock_screen" />
</activity>
<activity android:name=".security.BiometricPromptBoundKeysTest"
@@ -1284,6 +1286,7 @@
<category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_security" />
+ <meta-data android:name="test_required_features" android:value="android.software.secure_lock_screen" />
<meta-data android:name="test_excluded_features"
android:value="android.hardware.type.television:android.software.leanback:android.hardware.type.watch" />
</activity>
@@ -1299,7 +1302,7 @@
<meta-data android:name="test_excluded_features"
android:value="android.software.lockscreen_disabled" />
<meta-data android:name="test_required_features"
- android:value="android.software.device_admin" />
+ android:value="android.software.device_admin:android.software.secure_lock_screen" />
</activity>
<activity android:name=".security.LockConfirmBypassTest"
@@ -1313,7 +1316,7 @@
<meta-data android:name="test_excluded_features"
android:value="android.software.lockscreen_disabled" />
<meta-data android:name="test_required_features"
- android:value="android.software.device_admin" />
+ android:value="android.software.device_admin:android.software.secure_lock_screen" />
</activity>
<activity android:name=".security.SetNewPasswordComplexityTest"
@@ -1324,6 +1327,8 @@
<category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_security" />
+ <meta-data android:name="test_required_features"
+ android:value="android.software.secure_lock_screen" />
<meta-data android:name="test_excluded_features"
android:value="android.software.lockscreen_disabled" />
</activity>
diff --git a/apps/CtsVerifier/res/drawable/user_icon_1.png b/apps/CtsVerifier/res/drawable/user_icon_1.png
new file mode 100644
index 0000000..941458d
--- /dev/null
+++ b/apps/CtsVerifier/res/drawable/user_icon_1.png
Binary files differ
diff --git a/apps/CtsVerifier/res/drawable/user_icon_2.png b/apps/CtsVerifier/res/drawable/user_icon_2.png
new file mode 100644
index 0000000..6792671
--- /dev/null
+++ b/apps/CtsVerifier/res/drawable/user_icon_2.png
Binary files differ
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index bbe01a0..f15a675 100755
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -3252,13 +3252,18 @@
</string>
<string name="device_owner_set_user_icon">Setting the user icon</string>
<string name="device_owner_set_user_icon_instruction">
- This test verifies that the user icon can be set.\n
- 1. Press the set user icon button.\n
- 2. Press the go button to go to Settings.\n
- 3a. If there is a \"users\" section in Settings, check that the icon of the user \"owner\" is the CtsVerifier one and mark this test accordingly.\n
- 3b. If there is no \"users\" section, mark this test as passed.\n
+ This test verifies that the user icon can be set by the device owner, depending on whether the user restriction is set or not.\n
+ 1. Press the \"Set user icon 1\" button.\n
+ 2. Press the \"Go\" button to go to Settings.\n
+ 3. If there is no \"users\" section, mark this test as passed.\n
+ 4. If the icon of the user \"owner\" is not \"1\", mark this test as failed.\n
+ 5. Press the \"Disallow set user icon\" button.\n
+ 6. Press the \"Set user icon 2\" button.\n
+ 7. Press the \"Go\" button to go to Settings. Verify that the icon can\'t be changed manually.\n
+ 8. Check that the icon of the user \"owner\" is \"2\", and mark this test accordingly.
</string>
- <string name="device_owner_set_user_icon_button">Set user icon</string>
+ <string name="device_owner_set_user_icon_button">Set user icon 1</string>
+ <string name="device_owner_set_user_icon2_button">Set user icon 2</string>
<string name="profile_owner_permission_lockdown_test_info">
<b>
@@ -3575,6 +3580,7 @@
<string name="disallow_remove_managed_profile_action">Removing the work profile. It shouldn\'t be possible neither from the Accounts screen nor the Device Administrators screen (after selecting the Device Administrator that corresponds to the badged version of \"CTS Verifier\")</string>
<string name="disallow_share_location">Disallow share location</string>
<string name="disallow_share_location_action">Turning on location sharing</string>
+ <string name="disallow_set_user_icon">Disallow set user icon</string>
<string name="disallow_uninstall_apps">Disallow uninstall apps</string>
<string name="disallow_uninstall_apps_action">
a. If testing in work profile: uninstall applications from the work profile (badged applications) other than CtsVerifier and system apps. \n
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsReport.java b/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsReport.java
index 8893e0d..7d3026a 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsReport.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsReport.java
@@ -102,7 +102,7 @@
DevicePropertyInfo devicePropertyInfo = new DevicePropertyInfo(Build.CPU_ABI,
Build.CPU_ABI2, abis, abis32, abis64, Build.BOARD, Build.BRAND, Build.DEVICE,
- Build.FINGERPRINT, Build.ID, Build.MANUFACTURER, Build.MODEL, Build.PRODUCT,
+ Build.FINGERPRINT, null, Build.ID, Build.MANUFACTURER, Build.MODEL, Build.PRODUCT,
referenceFingerprint, Build.getSerial(), Build.TAGS, Build.TYPE, versionBaseOs,
Build.VERSION.RELEASE, Integer.toString(Build.VERSION.SDK_INT),
versionSecurityPatch, Build.VERSION.INCREMENTAL);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/admin/PolicySerializationTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/admin/PolicySerializationTestActivity.java
index ee24868..72c54c2 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/admin/PolicySerializationTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/admin/PolicySerializationTestActivity.java
@@ -27,6 +27,7 @@
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
+import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
@@ -95,7 +96,11 @@
mPolicyItems.add(new PasswordQualityPolicy(this));
mPolicyItems.add(new PasswordMinimumLengthPolicy(this));
- mPolicyItems.add(new MaximumFailedPasswordsForWipePolicy(this));
+
+ if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_SECURE_LOCK_SCREEN)) {
+ mPolicyItems.add(new MaximumFailedPasswordsForWipePolicy(this));
+ }
+
mPolicyItems.add(new MaximumTimeToLockPolicy(this));
mAdapter = new PolicyAdapter(this);
setListAdapter(mAdapter);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CommandReceiverActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CommandReceiverActivity.java
index 3ad2b82..9e63995 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CommandReceiverActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CommandReceiverActivity.java
@@ -305,8 +305,9 @@
if (!mDpm.isDeviceOwnerApp(getPackageName())) {
return;
}
- mDpm.setUserIcon(mAdmin, BitmapFactory.decodeResource(getResources(),
- com.android.cts.verifier.R.drawable.icon));
+ int iconRes = intent.getIntExtra(EXTRA_VALUE,
+ com.android.cts.verifier.R.drawable.icon);
+ mDpm.setUserIcon(mAdmin, BitmapFactory.decodeResource(getResources(), iconRes));
} break;
case COMMAND_RETRIEVE_NETWORK_LOGS: {
if (!mDpm.isDeviceOwnerApp(getPackageName())) {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
index 72bc3ab..911e08a 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
@@ -313,7 +313,14 @@
new ButtonInfo[] {
new ButtonInfo(
R.string.device_owner_set_user_icon_button,
- createSetUserIconIntent()),
+ createSetUserIconIntent(R.drawable.user_icon_1)),
+ new ButtonInfo(
+ R.string.disallow_set_user_icon,
+ CommandReceiverActivity.createSetUserRestrictionIntent(
+ UserManager.DISALLOW_SET_USER_ICON, true)),
+ new ButtonInfo(
+ R.string.device_owner_set_user_icon2_button,
+ createSetUserIconIntent(R.drawable.user_icon_2)),
new ButtonInfo(
R.string.device_owner_settings_go,
new Intent(Settings.ACTION_SETTINGS))}));
@@ -465,10 +472,11 @@
.putExtra(CommandReceiverActivity.EXTRA_ENFORCED, value);
}
- private Intent createSetUserIconIntent() {
+ private Intent createSetUserIconIntent(int iconRes) {
return new Intent(this, CommandReceiverActivity.class)
.putExtra(CommandReceiverActivity.EXTRA_COMMAND,
- CommandReceiverActivity.COMMAND_SET_USER_ICON);
+ CommandReceiverActivity.COMMAND_SET_USER_ICON)
+ .putExtra(CommandReceiverActivity.EXTRA_VALUE, iconRes);
}
private Intent createEnableNetworkLoggingIntent() {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/net/ConnectivityBackgroundTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/net/ConnectivityBackgroundTestActivity.java
index 496bbe4..57da095 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/net/ConnectivityBackgroundTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/net/ConnectivityBackgroundTestActivity.java
@@ -160,8 +160,7 @@
// Whether or not this device (currently) has a battery.
mWaitForPowerDisconnected =
- batteryInfo.getBooleanExtra(BatteryManager.EXTRA_PRESENT, false)
- && !hasPersistentPower();
+ batteryInfo.getBooleanExtra(BatteryManager.EXTRA_PRESENT, false);
// Check if the device is already on battery power.
if (mWaitForPowerDisconnected) {
@@ -643,14 +642,6 @@
return new HttpResult(rcode, msg);
}
- private boolean hasPersistentPower() {
- // Cars and TVsets are always connected to the persistent power source
- final PackageManager pm = getPackageManager();
- return (pm != null
- && (pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK)
- || pm.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)));
- }
-
private boolean requiresScreenOffSupport() {
// Cars may not support screen-off function
final PackageManager pm = getPackageManager();
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/testcase/DataPathInBandTestCase.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/testcase/DataPathInBandTestCase.java
index e6bc590..5533d9b 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/testcase/DataPathInBandTestCase.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/testcase/DataPathInBandTestCase.java
@@ -166,8 +166,7 @@
// 6. request network
WifiAwareNetworkSpecifier.Builder nsBuilder =
- new WifiAwareNetworkSpecifier.Builder().setDiscoverySession(
- mWifiAwareDiscoverySession).setPeerHandle(mPeerHandle);
+ new WifiAwareNetworkSpecifier.Builder(mWifiAwareDiscoverySession, mPeerHandle);
if (!mIsSecurityOpen) {
nsBuilder.setPskPassphrase(PASSPHRASE);
}
@@ -354,8 +353,7 @@
// 5. Request network
WifiAwareNetworkSpecifier.Builder nsBuilder =
- new WifiAwareNetworkSpecifier.Builder().setDiscoverySession(
- mWifiAwareDiscoverySession).setPeerHandle(mPeerHandle);
+ new WifiAwareNetworkSpecifier.Builder(mWifiAwareDiscoverySession, mPeerHandle);
if (!mIsSecurityOpen) {
nsBuilder.setPskPassphrase(PASSPHRASE).setPort(port).setTransportProtocol(
6); // 6 == TCP
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/DeviceConfigStateManager.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/DeviceConfigStateManager.java
index 9279924..104bd18 100644
--- a/common/device-side/util-axt/src/com/android/compatibility/common/util/DeviceConfigStateManager.java
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/DeviceConfigStateManager.java
@@ -16,6 +16,8 @@
package com.android.compatibility.common.util;
+import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
+
import android.content.Context;
import android.provider.DeviceConfig;
import android.provider.Settings;
@@ -26,6 +28,8 @@
import com.google.common.base.Preconditions;
+import java.util.concurrent.atomic.AtomicReference;
+
/**
* Manages the state of a preference backed by {@link DeviceConfig}.
*/
@@ -61,17 +65,22 @@
mKey);
DeviceConfig.addOnPropertyChangedListener(mNamespace, mContext.getMainExecutor(), listener);
- DeviceConfig.setProperty(mNamespace, mKey, value, /* makeDefault= */ false);
+ runWithShellPermissionIdentity(() -> DeviceConfig.setProperty(
+ mNamespace, mKey, value, /* makeDefault= */ false),
+ "android.permission.WRITE_DEVICE_CONFIG");
listener.assertCalled();
}
@Override
@Nullable
public String get() {
- final String value = DeviceConfig.getProperty(mNamespace, mKey);
- debug("get", value);
+ final AtomicReference<String> reference = new AtomicReference<>();
+ runWithShellPermissionIdentity(()
+ -> reference.set(DeviceConfig.getProperty(mNamespace, mKey)),
+ "android.permission.READ_DEVICE_CONFIG");
+ debug("get", reference.get());
- return value;
+ return reference.get();
}
private void debug(@NonNull String methodName, @NonNull String msg, Object...args) {
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/DeviceConfigStateManager.java b/common/device-side/util/src/com/android/compatibility/common/util/DeviceConfigStateManager.java
index 9279924..104bd18 100644
--- a/common/device-side/util/src/com/android/compatibility/common/util/DeviceConfigStateManager.java
+++ b/common/device-side/util/src/com/android/compatibility/common/util/DeviceConfigStateManager.java
@@ -16,6 +16,8 @@
package com.android.compatibility.common.util;
+import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
+
import android.content.Context;
import android.provider.DeviceConfig;
import android.provider.Settings;
@@ -26,6 +28,8 @@
import com.google.common.base.Preconditions;
+import java.util.concurrent.atomic.AtomicReference;
+
/**
* Manages the state of a preference backed by {@link DeviceConfig}.
*/
@@ -61,17 +65,22 @@
mKey);
DeviceConfig.addOnPropertyChangedListener(mNamespace, mContext.getMainExecutor(), listener);
- DeviceConfig.setProperty(mNamespace, mKey, value, /* makeDefault= */ false);
+ runWithShellPermissionIdentity(() -> DeviceConfig.setProperty(
+ mNamespace, mKey, value, /* makeDefault= */ false),
+ "android.permission.WRITE_DEVICE_CONFIG");
listener.assertCalled();
}
@Override
@Nullable
public String get() {
- final String value = DeviceConfig.getProperty(mNamespace, mKey);
- debug("get", value);
+ final AtomicReference<String> reference = new AtomicReference<>();
+ runWithShellPermissionIdentity(()
+ -> reference.set(DeviceConfig.getProperty(mNamespace, mKey)),
+ "android.permission.READ_DEVICE_CONFIG");
+ debug("get", reference.get());
- return value;
+ return reference.get();
}
private void debug(@NonNull String methodName, @NonNull String msg, Object...args) {
diff --git a/hostsidetests/appsecurity/OWNERS b/hostsidetests/appsecurity/OWNERS
index 5507ae8..f86fd96 100644
--- a/hostsidetests/appsecurity/OWNERS
+++ b/hostsidetests/appsecurity/OWNERS
@@ -6,6 +6,7 @@
per-file AppSecurityTests.java = cbrubaker@google.com
per-file AuthBoundKeyTest.java = cbrubaker@google.com
per-file BaseInstallMultiple.java = toddke@google.com
+per-file BasePermissionsTest.java = moltmann@google.com
per-file CorruptApkTests.java = rtmitchell@google.com
per-file DirectBootHostTest.java = jsharkey@google.com
per-file DocumentsTestCase.java = jsharkey@google.com
@@ -28,3 +29,4 @@
per-file SplitTests.java = toddke@google.com
per-file StorageHostTest.java = jsharkey@google.com
per-file UseEmbeddedDexTest.java = victorhsieh@google.com
+per-file UsePermission*.java = moltmann@google.com
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/MediaStorageApp/src/com/android/cts/mediastorageapp/MediaStoreUtils.java b/hostsidetests/appsecurity/test-apps/MediaStorageApp/src/com/android/cts/mediastorageapp/MediaStoreUtils.java
index c2d5a85..d27235a 100644
--- a/hostsidetests/appsecurity/test-apps/MediaStorageApp/src/com/android/cts/mediastorageapp/MediaStoreUtils.java
+++ b/hostsidetests/appsecurity/test-apps/MediaStorageApp/src/com/android/cts/mediastorageapp/MediaStoreUtils.java
@@ -19,7 +19,6 @@
import android.content.ContentValues;
import android.content.Context;
import android.net.Uri;
-import android.os.Environment;
import android.os.ParcelFileDescriptor;
import android.provider.MediaStore;
import android.provider.MediaStore.DownloadColumns;
@@ -27,13 +26,13 @@
import android.provider.MediaStore.MediaColumns;
import android.text.format.DateUtils;
-import androidx.annotation.Nullable;
-import androidx.annotation.NonNull;
-
import java.io.FileNotFoundException;
import java.io.OutputStream;
import java.util.Objects;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
public class MediaStoreUtils {
/**
* Create a new pending media item using the given parameters. Pending items
@@ -102,45 +101,11 @@
(System.currentTimeMillis() + DateUtils.DAY_IN_MILLIS) / 1000);
}
- /**
- * Optionally set the primary directory under which this pending item
- * should be persisted. Only specific well-defined directories from
- * {@link Environment} are allowed based on the media type being
- * inserted.
- * <p>
- * For example, when creating pending {@link MediaStore.Images.Media}
- * items, only {@link Environment#DIRECTORY_PICTURES} or
- * {@link Environment#DIRECTORY_DCIM} are allowed.
- * <p>
- * You may leave this value undefined to store the media in a default
- * location. For example, when this value is left undefined, pending
- * {@link MediaStore.Audio.Media} items are stored under
- * {@link Environment#DIRECTORY_MUSIC}.
- *
- * @see MediaColumns#PRIMARY_DIRECTORY
- */
- public void setPrimaryDirectory(@Nullable String primaryDirectory) {
- if (primaryDirectory == null) {
- this.insertValues.remove(MediaColumns.PRIMARY_DIRECTORY);
+ public void setPath(@Nullable String path) {
+ if (path == null) {
+ this.insertValues.remove(MediaColumns.RELATIVE_PATH);
} else {
- this.insertValues.put(MediaColumns.PRIMARY_DIRECTORY, primaryDirectory);
- }
- }
-
- /**
- * Optionally set the secondary directory under which this pending item
- * should be persisted. Any valid directory name is allowed.
- * <p>
- * You may leave this value undefined to store the media as a direct
- * descendant of the {@link #setPrimaryDirectory(String)} location.
- *
- * @see MediaColumns#SECONDARY_DIRECTORY
- */
- public void setSecondaryDirectory(@Nullable String secondaryDirectory) {
- if (secondaryDirectory == null) {
- this.insertValues.remove(MediaColumns.SECONDARY_DIRECTORY);
- } else {
- this.insertValues.put(MediaColumns.SECONDARY_DIRECTORY, secondaryDirectory);
+ this.insertValues.put(MediaColumns.RELATIVE_PATH, path);
}
}
diff --git a/tests/jank/Android.mk b/hostsidetests/appsecurity/test-apps/MediaStorageApp28/Android.mk
similarity index 64%
copy from tests/jank/Android.mk
copy to hostsidetests/appsecurity/test-apps/MediaStorageApp28/Android.mk
index 2ce4a98..97f8a2c 100644
--- a/tests/jank/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/MediaStorageApp28/Android.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2015 The Android Open Source Project
+# 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.
@@ -16,25 +16,21 @@
include $(CLEAR_VARS)
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := CtsJankDeviceTestCases
-LOCAL_SDK_VERSION := current
-
-# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-
+LOCAL_MODULE_TAGS := tests
+LOCAL_SDK_VERSION := test_current
LOCAL_STATIC_JAVA_LIBRARIES := \
compatibility-device-util-axt \
- ctstestrunner-axt \
- ub-uiautomator \
- androidx.test.janktesthelper \
- junit
+ androidx.test.rules \
+ ub-uiautomator
LOCAL_JAVA_LIBRARIES := android.test.base.stubs
-include $(BUILD_CTS_PACKAGE)
+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>
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java
index 9a23f0b..56cd234 100755
--- a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java
@@ -133,6 +133,13 @@
Manifest.permission.RECEIVE_MMS, "@android:string/permgrouplab_sms");
sPermissionToLabelResNameMap.put(
"android.permission.READ_CELL_BROADCASTS", "@android:string/permgrouplab_sms");
+ // Storage
+ sPermissionToLabelResNameMap.put(
+ Manifest.permission.READ_EXTERNAL_STORAGE,
+ "@android:string/permgrouplab_storage");
+ sPermissionToLabelResNameMap.put(
+ Manifest.permission.WRITE_EXTERNAL_STORAGE,
+ "@android:string/permgrouplab_storage");
// Music
sPermissionToLabelResNameMap.put(
Manifest.permission.READ_MEDIA_AUDIO,
@@ -204,6 +211,13 @@
sPermissionToLabelResNameMap.put(
"android.permission.READ_CELL_BROADCASTS",
"@android:string/permlab_readCellBroadcasts");
+ // Storage
+ sPermissionToLabelResNameMap.put(
+ Manifest.permission.READ_EXTERNAL_STORAGE,
+ "@android:string/permgrouplab_storage");
+ sPermissionToLabelResNameMap.put(
+ Manifest.permission.WRITE_EXTERNAL_STORAGE,
+ "@android:string/permgrouplab_storage");
// Music
sPermissionToLabelResNameMap.put(
Manifest.permission.READ_MEDIA_AUDIO,
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/UsePermissionTest23.java b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/UsePermissionTest23.java
index 02e8bd7..6614ede 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/UsePermissionTest23.java
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/UsePermissionTest23.java
@@ -26,6 +26,7 @@
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
+import android.os.Build;
import android.provider.CalendarContract;
import androidx.test.InstrumentationRegistry;
@@ -33,6 +34,9 @@
import org.junit.Before;
import org.junit.Test;
+import java.util.ArrayList;
+import java.util.Arrays;
+
/**
* Runtime permission behavior tests for apps targeting API 23
*/
@@ -486,18 +490,25 @@
@Test
public void testNoResidualPermissionsOnUninstall_part1() throws Exception {
- // Grant all permissions
- grantPermissions(new String[] {
+ ArrayList<String> perms = new ArrayList<>(Arrays.asList(
Manifest.permission.WRITE_CALENDAR,
Manifest.permission.WRITE_CONTACTS,
- Manifest.permission.READ_MEDIA_AUDIO,
- Manifest.permission.READ_MEDIA_IMAGES,
Manifest.permission.READ_SMS,
Manifest.permission.CALL_PHONE,
Manifest.permission.RECORD_AUDIO,
Manifest.permission.BODY_SENSORS,
Manifest.permission.CAMERA
- });
+ ));
+
+ if (mContext.getApplicationInfo().targetSdkVersion <= Build.VERSION_CODES.Q) {
+ perms.add(Manifest.permission.READ_EXTERNAL_STORAGE);
+ } else {
+ perms.add(Manifest.permission.READ_MEDIA_AUDIO);
+ perms.add(Manifest.permission.READ_MEDIA_IMAGES);
+ }
+
+ // Grant all permissions
+ grantPermissions(perms.toArray(new String[perms.size()]));
// Don't use UI for granting location permission as this shows another dialog
String packageName = InstrumentationRegistry.getTargetContext().getPackageName();
@@ -634,7 +645,7 @@
}
private void assertAllPermissionsGrantState(int grantState) {
- assertPermissionsGrantState(new String[] {
+ ArrayList<String> perms = new ArrayList<>(Arrays.asList(
Manifest.permission.SEND_SMS,
Manifest.permission.RECEIVE_SMS,
Manifest.permission.RECEIVE_WAP_PUSH,
@@ -642,9 +653,6 @@
Manifest.permission.READ_CALENDAR,
Manifest.permission.WRITE_CALENDAR,
Manifest.permission.WRITE_CONTACTS,
- Manifest.permission.READ_MEDIA_VIDEO,
- Manifest.permission.READ_MEDIA_IMAGES,
- Manifest.permission.READ_MEDIA_AUDIO,
Manifest.permission.READ_SMS,
Manifest.permission.READ_PHONE_STATE,
Manifest.permission.READ_CALL_LOG,
@@ -662,7 +670,17 @@
// Split permissions
Manifest.permission.ACCESS_BACKGROUND_LOCATION
- }, grantState);
+ ));
+
+ if (mContext.getApplicationInfo().targetSdkVersion <= Build.VERSION_CODES.Q) {
+ perms.add(Manifest.permission.READ_EXTERNAL_STORAGE);
+ perms.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
+ } else {
+ perms.add(Manifest.permission.READ_MEDIA_VIDEO);
+ perms.add(Manifest.permission.READ_MEDIA_IMAGES);
+ perms.add(Manifest.permission.READ_MEDIA_AUDIO);
+ }
+ assertPermissionsGrantState(perms.toArray(new String[perms.size()]), grantState);
}
private void assertPermissionsGrantState(String[] permissions, int grantState) {
diff --git a/hostsidetests/classloaders/useslibrary/AndroidTest.xml b/hostsidetests/classloaders/useslibrary/AndroidTest.xml
index b7796d7..7146f92 100644
--- a/hostsidetests/classloaders/useslibrary/AndroidTest.xml
+++ b/hostsidetests/classloaders/useslibrary/AndroidTest.xml
@@ -16,6 +16,7 @@
<configuration description="Config for the CTS UsesLibrary host tests">
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="framework" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
<test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
<option name="jar" value="CtsUsesLibraryHostTestCases.jar" />
<option name="runtime-hint" value="1m" />
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AlwaysOnVpnMultiStageTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AlwaysOnVpnMultiStageTest.java
index e86abd7..eebe18d 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AlwaysOnVpnMultiStageTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AlwaysOnVpnMultiStageTest.java
@@ -25,7 +25,8 @@
import com.android.cts.deviceandprofileowner.vpn.VpnTestHelper;
-import java.util.List;
+import java.util.Collections;
+import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
@@ -55,13 +56,13 @@
VpnTestHelper.waitForVpn(mContext, null,
/* usable */ true, /* lockdown */ true, /* whitelist */ true);
VpnTestHelper.checkPing(TEST_ADDRESS);
- final List<String> whitelist =
+ final Set<String> whitelist =
mDevicePolicyManager.getAlwaysOnVpnLockdownWhitelist(ADMIN_RECEIVER_COMPONENT);
assertTrue("Lockdown bit lost after reboot",
mDevicePolicyManager.isAlwaysOnVpnLockdownEnabled(ADMIN_RECEIVER_COMPONENT));
assertNotNull("whitelist is lost after reboot", whitelist);
- assertTrue("whitelist changed after reboot",
- whitelist.size() == 1 && mContext.getPackageName().equals(whitelist.get(0)));
+ assertEquals("whitelist changed after reboot",
+ Collections.singleton(mContext.getPackageName()), whitelist);
}
public void testNetworkBlocked() throws Exception {
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/UnavailableSecureLockScreenTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/UnavailableSecureLockScreenTest.java
new file mode 100644
index 0000000..4fa6774
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/UnavailableSecureLockScreenTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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 com.android.cts.deviceandprofileowner;
+
+
+import android.app.admin.DevicePolicyManager;
+import android.content.pm.PackageManager;
+
+/**
+ * Tests some password APIs in {@link DevicePolicyManager} on devices which don't support the
+ * {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature.
+ */
+public class UnavailableSecureLockScreenTest extends BaseDeviceAdminTest {
+
+ private static final byte[] TOKEN = "abcdefghijklmnopqrstuvwxyz0123456789".getBytes();
+ private static final String COMPLEX_PASSWORD = "XYZabc123#&*!.";
+
+ public void testResetWithTokenAndPasswordSufficiency() throws Exception {
+ // The password is always empty on devices which don't support the secure lock screen
+ // feature.
+
+ // Initially, when no password quality requirements are set, the empty password is
+ // sufficient.
+ assertPasswordSufficiency(true);
+ try {
+
+ // Resetting password should fail - it is not possible to set a password reset token or
+ // a password on a device without the secure lock screen feature.
+ assertFalse(mDevicePolicyManager.setResetPasswordToken(ADMIN_RECEIVER_COMPONENT, TOKEN));
+ assertFalse(mDevicePolicyManager.resetPasswordWithToken(ADMIN_RECEIVER_COMPONENT,
+ COMPLEX_PASSWORD, TOKEN, 0));
+
+ // As soon as some requirement for minimal password quality is set...
+ mDevicePolicyManager.setPasswordQuality(
+ ADMIN_RECEIVER_COMPONENT, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
+
+ // ... the password is not sufficient any more.
+ assertPasswordSufficiency(false);
+
+ // If the requirement for minimal password quality is removed later...
+ mDevicePolicyManager.setPasswordQuality(
+ ADMIN_RECEIVER_COMPONENT, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
+
+ // The empty password is sufficient again.
+ assertPasswordSufficiency(true);
+ } finally {
+ mDevicePolicyManager.clearResetPasswordToken(ADMIN_RECEIVER_COMPONENT);
+ mDevicePolicyManager.setPasswordQuality(
+ ADMIN_RECEIVER_COMPONENT, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
+ }
+ }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/vpn/VpnTestHelper.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/vpn/VpnTestHelper.java
index 18d3553..bed0943 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/vpn/VpnTestHelper.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/vpn/VpnTestHelper.java
@@ -23,7 +23,6 @@
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.assertTrue;
import static junit.framework.Assert.fail;
@@ -55,7 +54,7 @@
import java.net.InetSocketAddress;
import java.util.Arrays;
import java.util.Collections;
-import java.util.List;
+import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -158,10 +157,10 @@
Context context, String packageName, boolean lockdown, boolean whitelist)
throws PackageManager.NameNotFoundException {
final DevicePolicyManager dpm = context.getSystemService(DevicePolicyManager.class);
- final List<String> lockdownWhitelist;
+ final Set<String> lockdownWhitelist;
if (lockdown) {
lockdownWhitelist = whitelist ?
- Collections.singletonList(context.getPackageName()) : Collections.emptyList();
+ Collections.singleton(context.getPackageName()) : Collections.emptySet();
} else {
lockdownWhitelist = null;
}
@@ -170,7 +169,7 @@
assertEquals(packageName, dpm.getAlwaysOnVpnPackage(ADMIN_RECEIVER_COMPONENT));
assertEquals(lockdown, dpm.isAlwaysOnVpnLockdownEnabled(ADMIN_RECEIVER_COMPONENT));
assertEquals(lockdownWhitelist,
- dpm.getAlwaysOnVpnLockdownWhitelist(ADMIN_RECEIVER_COMPONENT));
+ dpm.getAlwaysOnVpnLockdownWhitelist(ADMIN_RECEIVER_COMPONENT));
}
public static boolean isNetworkVpn(Context context) {
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
index 1c5bf76..cf638d0 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
@@ -1193,6 +1193,14 @@
}
}
+ public void testPasswordQualityWithoutSecureLockScreen() throws Exception {
+ if (!mHasFeature || mHasSecureLockScreen) {
+ return;
+ }
+
+ runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".UnavailableSecureLockScreenTest", mUserId);
+ }
+
public void testSetSystemSetting() throws Exception {
if (!mHasFeature) {
return;
diff --git a/hostsidetests/edi/src/android/edi/cts/DynamicPartitionsDeviceInfo.java b/hostsidetests/edi/src/android/edi/cts/DynamicPartitionsDeviceInfo.java
new file mode 100644
index 0000000..305d632
--- /dev/null
+++ b/hostsidetests/edi/src/android/edi/cts/DynamicPartitionsDeviceInfo.java
@@ -0,0 +1,84 @@
+/*
+ * 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.edi.cts;
+
+import com.android.compatibility.common.util.DeviceInfo;
+import com.android.compatibility.common.util.HostInfoStore;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.util.CommandResult;
+import java.io.File;
+import java.io.FileWriter;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+public class DynamicPartitionsDeviceInfo extends DeviceInfo {
+
+ @Override
+ protected void collectDeviceInfo(HostInfoStore store) throws Exception {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ protected void collectDeviceInfo(File jsonFile) throws Exception {
+ ITestDevice device = getDevice();
+
+ CommandResult commandResult = device.executeShellV2Command(
+ "lpdump --json");
+ if (commandResult.getExitCode() == null) {
+ CLog.w("lpdump exit code is null");
+ return;
+ }
+ if (commandResult.getExitCode() != 0) {
+ CLog.w("lpdump returns %d: %s", commandResult.getExitCode(),
+ commandResult.getStderr());
+ // TODO(b/126233777): Fail here to ensure that lpdump --json is correct.
+ }
+
+ if (commandResult.getExitCode() == 0 && !commandResult.getStderr().isEmpty()) {
+ CLog.w("Warnings occur when running lpdump --json:\n%s",
+ commandResult.getStderr());
+ }
+
+ String output = commandResult.getStdout();
+ if (output == null) output = "";
+ output = output.trim();
+ if (output.isEmpty()) {
+ CLog.w("lpdump --json does not generate anything");
+ // TODO(b/126233777): Fail here to ensure that lpdump --json is correct.
+ output = "{}";
+ }
+
+ if (!isJsonString(output)) {
+ CLog.w("lpdump --json does not generate a valid JSON string: %s", output);
+ // TODO(b/126233777): Fail here to ensure that lpdump --json is correct.
+ output = "{}";
+ }
+
+ try (FileWriter writer = new FileWriter(jsonFile)) {
+ writer.write(output);
+ }
+ }
+
+ private static boolean isJsonString(String s) {
+ try {
+ new JSONObject(s);
+ return true;
+ } catch (JSONException e) {
+ return false;
+ }
+ }
+}
diff --git a/hostsidetests/incident/src/com/android/server/cts/BatteryIncidentTest.java b/hostsidetests/incident/src/com/android/server/cts/BatteryIncidentTest.java
index 596720c..3b542ba 100644
--- a/hostsidetests/incident/src/com/android/server/cts/BatteryIncidentTest.java
+++ b/hostsidetests/incident/src/com/android/server/cts/BatteryIncidentTest.java
@@ -59,13 +59,10 @@
assertTrue(dump.getVoltage() >= 0);
}
- static boolean hasBattery(ITestDevice device) throws DeviceNotAvailableException {
- /* Android TV reports that it has a battery, but it doesn't really. */
- return !isLeanback(device);
+ static boolean hasBattery(ITestDevice device) throws DeviceNotAvailableException {
+ final String batteryinfo = device.executeShellCommand("dumpsys battery");
+ boolean hasBattery = batteryinfo.contains("present: true");
+ return hasBattery;
}
- private static boolean isLeanback(ITestDevice device) throws DeviceNotAvailableException {
- final String commandOutput = device.executeShellCommand("pm list features");
- return commandOutput.contains(LEANBACK_FEATURE);
- }
}
diff --git a/hostsidetests/incident/src/com/android/server/cts/BatteryStatsValidationTest.java b/hostsidetests/incident/src/com/android/server/cts/BatteryStatsValidationTest.java
index 115e1ad..90e5d8a 100644
--- a/hostsidetests/incident/src/com/android/server/cts/BatteryStatsValidationTest.java
+++ b/hostsidetests/incident/src/com/android/server/cts/BatteryStatsValidationTest.java
@@ -266,7 +266,7 @@
}
public void testBleScans() throws Exception {
- if (isTV() || !hasFeature(FEATURE_BLUETOOTH_LE, true)) {
+ if (noBattery() || !hasFeature(FEATURE_BLUETOOTH_LE, true)) {
return;
}
@@ -290,7 +290,7 @@
public void testUnoptimizedBleScans() throws Exception {
- if (isTV() || !hasFeature(FEATURE_BLUETOOTH_LE, true)) {
+ if (noBattery() || !hasFeature(FEATURE_BLUETOOTH_LE, true)) {
return;
}
batteryOnScreenOff();
@@ -341,7 +341,7 @@
}
public void testGpsUpdates() throws Exception {
- if (isTV() || !hasFeature(FEATURE_LOCATION_GPS, true)) {
+ if (noBattery() || !hasFeature(FEATURE_LOCATION_GPS, true)) {
return;
}
@@ -380,7 +380,7 @@
}
public void testJobBgVsFg() throws Exception {
- if (isTV()) {
+ if (noBattery()) {
return;
}
batteryOnScreenOff();
@@ -403,7 +403,7 @@
}
public void testSyncBgVsFg() throws Exception {
- if (isTV()) {
+ if (noBattery()) {
return;
}
batteryOnScreenOff();
@@ -631,9 +631,14 @@
return String.format("Completed performing %s for request %s", actionValue, requestCode);
}
- /** Determine if device is just a TV and is not expected to have proper batterystats. */
- private boolean isTV() throws Exception {
- return hasFeature(FEATURE_LEANBACK_ONLY, false);
+ /** Determine if device has no battery and is not expected to have proper batterystats. */
+ private boolean noBattery() throws Exception {
+ final String batteryinfo = getDevice().executeShellCommand("dumpsys battery");
+ boolean hasBattery = batteryinfo.contains("present: true");
+ if (!hasBattery) {
+ LogUtil.CLog.w("Device does not have a battery");
+ }
+ return !hasBattery;
}
/**
diff --git a/hostsidetests/media/bitstreams/AndroidTest.xml b/hostsidetests/media/bitstreams/AndroidTest.xml
index c9e30e0a..cd716d5 100644
--- a/hostsidetests/media/bitstreams/AndroidTest.xml
+++ b/hostsidetests/media/bitstreams/AndroidTest.xml
@@ -16,6 +16,8 @@
<configuration description="Config for CTS Sample host test cases">
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="media" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher">
<option name="target" value="host" />
<option name="config-filename" value="cts" />
diff --git a/hostsidetests/media/bitstreams/DynamicConfig.xml b/hostsidetests/media/bitstreams/DynamicConfig.xml
index dfe5cc9..319bbb3 100644
--- a/hostsidetests/media/bitstreams/DynamicConfig.xml
+++ b/hostsidetests/media/bitstreams/DynamicConfig.xml
@@ -9567,94 +9567,94 @@
<value>mime=video/hevc,size=381384,width=3840,height=2160,frame-rate=50,profile=1,level=65536,bitrate=16905776,package=full</value>
</entry>
<entry key="hevc/yuv420/8bit/gop/crowd_640x360p50/crowd_640x360p50f10_gop8.mp4">
- <value>mime=video/hevc,size=27950,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1077360,package=standard</value>
+ <value>mime=video/hevc,size=27950,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1077360,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/gop/crowd_640x360p50/crowd_640x360p50f11_gop8.mp4">
- <value>mime=video/hevc,size=28995,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1016976,package=standard</value>
+ <value>mime=video/hevc,size=28995,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1016976,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/gop/crowd_640x360p50/crowd_640x360p50f12_gop8.mp4">
- <value>mime=video/hevc,size=30142,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=970064,package=standard</value>
+ <value>mime=video/hevc,size=30142,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=970064,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/gop/crowd_640x360p50/crowd_640x360p50f13_gop8.mp4">
- <value>mime=video/hevc,size=31315,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=931168,package=standard</value>
+ <value>mime=video/hevc,size=31315,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=931168,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/gop/crowd_640x360p50/crowd_640x360p50f14_gop8.mp4">
- <value>mime=video/hevc,size=31793,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=878192,package=standard</value>
+ <value>mime=video/hevc,size=31793,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=878192,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/gop/crowd_640x360p50/crowd_640x360p50f15_gop8.mp4">
- <value>mime=video/hevc,size=33475,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=864400,package=standard</value>
+ <value>mime=video/hevc,size=33475,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=864400,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/gop/crowd_640x360p50/crowd_640x360p50f16_gop8.mp4">
- <value>mime=video/hevc,size=33170,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=802648,package=standard</value>
+ <value>mime=video/hevc,size=33170,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=802648,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/gop/crowd_640x360p50/crowd_640x360p50f1_gop1.mp4">
- <value>mime=video/hevc,size=13556,width=640,height=360,frame-rate=1,profile=1,level=64,bitrate=101624,package=standard</value>
+ <value>mime=video/hevc,size=13556,width=640,height=360,frame-rate=1,profile=1,level=64,bitrate=101624,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/gop/crowd_640x360p50/crowd_640x360p50f1_gop2.mp4">
- <value>mime=video/hevc,size=13567,width=640,height=360,frame-rate=1,profile=1,level=64,bitrate=101704,package=standard</value>
+ <value>mime=video/hevc,size=13567,width=640,height=360,frame-rate=1,profile=1,level=64,bitrate=101704,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/gop/crowd_640x360p50/crowd_640x360p50f1_gop4.mp4">
- <value>mime=video/hevc,size=13567,width=640,height=360,frame-rate=1,profile=1,level=64,bitrate=101704,package=standard</value>
+ <value>mime=video/hevc,size=13567,width=640,height=360,frame-rate=1,profile=1,level=64,bitrate=101704,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/gop/crowd_640x360p50/crowd_640x360p50f1_gop8.mp4">
- <value>mime=video/hevc,size=13569,width=640,height=360,frame-rate=1,profile=1,level=64,bitrate=101704,package=standard</value>
+ <value>mime=video/hevc,size=13569,width=640,height=360,frame-rate=1,profile=1,level=64,bitrate=101704,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/gop/crowd_640x360p50/crowd_640x360p50f2_gop1.mp4">
- <value>mime=video/hevc,size=16317,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=3087200,package=standard</value>
+ <value>mime=video/hevc,size=16317,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=3087200,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/gop/crowd_640x360p50/crowd_640x360p50f2_gop2.mp4">
- <value>mime=video/hevc,size=16328,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=3089200,package=standard</value>
+ <value>mime=video/hevc,size=16328,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=3089200,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/gop/crowd_640x360p50/crowd_640x360p50f2_gop4.mp4">
- <value>mime=video/hevc,size=16328,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=3089200,package=standard</value>
+ <value>mime=video/hevc,size=16328,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=3089200,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/gop/crowd_640x360p50/crowd_640x360p50f2_gop8.mp4">
- <value>mime=video/hevc,size=16330,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=3089200,package=standard</value>
+ <value>mime=video/hevc,size=16330,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=3089200,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/gop/crowd_640x360p50/crowd_640x360p50f3_gop2.mp4">
- <value>mime=video/hevc,size=18115,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=2287064,package=standard</value>
+ <value>mime=video/hevc,size=18115,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=2287064,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/gop/crowd_640x360p50/crowd_640x360p50f3_gop4.mp4">
- <value>mime=video/hevc,size=18115,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=2287064,package=standard</value>
+ <value>mime=video/hevc,size=18115,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=2287064,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/gop/crowd_640x360p50/crowd_640x360p50f3_gop8.mp4">
- <value>mime=video/hevc,size=18117,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=2287064,package=standard</value>
+ <value>mime=video/hevc,size=18117,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=2287064,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/gop/crowd_640x360p50/crowd_640x360p50f4_gop2.mp4">
- <value>mime=video/hevc,size=19418,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1844400,package=standard</value>
+ <value>mime=video/hevc,size=19418,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1844400,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/gop/crowd_640x360p50/crowd_640x360p50f4_gop4.mp4">
- <value>mime=video/hevc,size=19520,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1854600,package=standard</value>
+ <value>mime=video/hevc,size=19520,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1854600,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/gop/crowd_640x360p50/crowd_640x360p50f4_gop8.mp4">
- <value>mime=video/hevc,size=19522,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1854600,package=standard</value>
+ <value>mime=video/hevc,size=19522,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1854600,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/gop/crowd_640x360p50/crowd_640x360p50f5_gop4.mp4">
- <value>mime=video/hevc,size=20788,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1584160,package=standard</value>
+ <value>mime=video/hevc,size=20788,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1584160,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/gop/crowd_640x360p50/crowd_640x360p50f5_gop8.mp4">
- <value>mime=video/hevc,size=20790,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1584160,package=standard</value>
+ <value>mime=video/hevc,size=20790,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1584160,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/gop/crowd_640x360p50/crowd_640x360p50f6_gop4.mp4">
- <value>mime=video/hevc,size=21940,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1396128,package=standard</value>
+ <value>mime=video/hevc,size=21940,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1396128,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/gop/crowd_640x360p50/crowd_640x360p50f6_gop8.mp4">
- <value>mime=video/hevc,size=21569,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1371800,package=standard</value>
+ <value>mime=video/hevc,size=21569,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1371800,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/gop/crowd_640x360p50/crowd_640x360p50f7_gop4.mp4">
- <value>mime=video/hevc,size=23165,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1265992,package=standard</value>
+ <value>mime=video/hevc,size=23165,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1265992,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/gop/crowd_640x360p50/crowd_640x360p50f7_gop8.mp4">
- <value>mime=video/hevc,size=23213,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1269536,package=standard</value>
+ <value>mime=video/hevc,size=23213,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1269536,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/gop/crowd_640x360p50/crowd_640x360p50f8_gop4.mp4">
- <value>mime=video/hevc,size=23973,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1147544,package=standard</value>
+ <value>mime=video/hevc,size=23973,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1147544,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/gop/crowd_640x360p50/crowd_640x360p50f8_gop8.mp4">
- <value>mime=video/hevc,size=23526,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1126296,package=standard</value>
+ <value>mime=video/hevc,size=23526,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1126296,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/gop/crowd_640x360p50/crowd_640x360p50f9_gop8.mp4">
- <value>mime=video/hevc,size=25228,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1076616,package=standard</value>
+ <value>mime=video/hevc,size=25228,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1076616,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/gop/crowd_854x480p50/crowd_854x480p50f10_gop8.mp4">
<value>mime=video/hevc,size=64778,width=854,height=480,frame-rate=50,profile=1,level=256,bitrate=2550480,package=standard</value>
@@ -9753,10 +9753,10 @@
<value>mime=video/hevc,size=665558,width=1280,height=720,frame-rate=50,profile=1,level=4096,bitrate=8302872,package=full</value>
</entry>
<entry key="hevc/yuv420/8bit/level/crowd_128x96p50f32_200kbps_level_2.0.mp4">
- <value>mime=video/hevc,size=15635,width=128,height=96,frame-rate=50,profile=1,level=4,bitrate=179048,package=standard</value>
+ <value>mime=video/hevc,size=15635,width=128,height=96,frame-rate=50,profile=1,level=4,bitrate=179048,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/level/crowd_176x144p50f32_200kbps_level_2.0.mp4">
- <value>mime=video/hevc,size=16050,width=176,height=144,frame-rate=50,profile=1,level=4,bitrate=184024,package=standard</value>
+ <value>mime=video/hevc,size=16050,width=176,height=144,frame-rate=50,profile=1,level=4,bitrate=184024,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/level/crowd_1920x1080p50f32_4000kbps_level_4.1.mp4">
<value>mime=video/hevc,size=302439,width=1920,height=1080,frame-rate=50,profile=1,level=4096,bitrate=3763872,package=standard</value>
@@ -9765,7 +9765,7 @@
<value>mime=video/hevc,size=726997,width=1920,height=1088,frame-rate=50,profile=1,level=16384,bitrate=9070848,package=full</value>
</entry>
<entry key="hevc/yuv420/8bit/level/crowd_352x288p50f32_300kbps_level_2.1.mp4">
- <value>mime=video/hevc,size=24836,width=352,height=288,frame-rate=50,profile=1,level=16,bitrate=293848,package=standard</value>
+ <value>mime=video/hevc,size=24836,width=352,height=288,frame-rate=50,profile=1,level=16,bitrate=293848,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/level/crowd_3840x2160p50f32_12000kbps_level_5.1.mp4">
<value>mime=video/hevc,size=897132,width=3840,height=2160,frame-rate=50,profile=1,level=65536,bitrate=11197824,package=full</value>
@@ -9774,10 +9774,10 @@
<value>mime=video/hevc,size=1793855,width=3840,height=2160,frame-rate=50,profile=1,level=1048576,bitrate=22406856,package=full</value>
</entry>
<entry key="hevc/yuv420/8bit/level/crowd_640x480p50f32_500kbps_level_3.0.mp4">
- <value>mime=video/hevc,size=43621,width=640,height=480,frame-rate=50,profile=1,level=64,bitrate=528656,package=standard</value>
+ <value>mime=video/hevc,size=43621,width=640,height=480,frame-rate=50,profile=1,level=64,bitrate=528656,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/level/crowd_64x64p50f32_200kbps_level_2.0.mp4">
- <value>mime=video/hevc,size=14472,width=64,height=64,frame-rate=50,profile=1,level=4,bitrate=165512,package=standard</value>
+ <value>mime=video/hevc,size=14472,width=64,height=64,frame-rate=50,profile=1,level=4,bitrate=165512,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/level/crowd_720x480p50f32_600kbps_level_3.1.mp4">
<value>mime=video/hevc,size=50650,width=720,height=480,frame-rate=50,profile=1,level=256,bitrate=616520,package=standard</value>
@@ -11088,22 +11088,22 @@
<value>mime=video/hevc,size=2415569,width=3840,height=2160,frame-rate=50,profile=1,level=65536,bitrate=30181872,package=full</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_100kbps.mp4">
- <value>mime=video/hevc,size=28874,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=344344,package=standard</value>
+ <value>mime=video/hevc,size=28874,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=344344,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_10mbps.mp4">
<value>mime=video/hevc,size=778226,width=640,height=360,frame-rate=50,profile=1,level=256,bitrate=9711248,package=full</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_1mbps.mp4">
- <value>mime=video/hevc,size=74639,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=916408,package=standard</value>
+ <value>mime=video/hevc,size=74639,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=916408,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_20mbps.mp4">
<value>mime=video/hevc,size=1580741,width=640,height=360,frame-rate=50,profile=1,level=2048,bitrate=19742680,package=full</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_4mbps_adaptiveqp0.mp4">
- <value>mime=video/hevc,size=327764,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=4080472,package=standard</value>
+ <value>mime=video/hevc,size=327764,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=4080472,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_4mbps_adaptiveqp2.mp4">
- <value>mime=video/hevc,size=324986,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=4045744,package=standard</value>
+ <value>mime=video/hevc,size=324986,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=4045744,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_4mbps_deltaqp1.mp4">
<value>mime=video/hevc,size=323295,width=640,height=360,frame-rate=25,profile=1,level=16777216,bitrate=2011968,package=standard</value>
@@ -11118,16 +11118,16 @@
<value>mime=video/hevc,size=323295,width=640,height=360,frame-rate=25,profile=1,level=16777216,bitrate=2011968,package=standard</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_4mbps_qpg16.mp4">
- <value>mime=video/hevc,size=112854,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1394096,package=standard</value>
+ <value>mime=video/hevc,size=112854,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1394096,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_4mbps_qpg64.mp4">
- <value>mime=video/hevc,size=113718,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1404912,package=standard</value>
+ <value>mime=video/hevc,size=113718,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1404912,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_4mbps_qpg8.mp4">
- <value>mime=video/hevc,size=113361,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1400432,package=standard</value>
+ <value>mime=video/hevc,size=113361,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1400432,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_500kbps.mp4">
- <value>mime=video/hevc,size=41305,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=499736,package=standard</value>
+ <value>mime=video/hevc,size=41305,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=499736,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_5mbps.mp4">
<value>mime=video/hevc,size=383707,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=4779760,package=full</value>
@@ -11136,91 +11136,91 @@
<value>mime=video/hevc,size=318227,width=640,height=360,frame-rate=50,profile=,level=,bitrate=3965384,package=standard</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_altidr.mp4">
- <value>mime=video/hevc,size=317903,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=3960312,package=standard</value>
+ <value>mime=video/hevc,size=317903,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=3960312,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_amp0.mp4">
- <value>mime=video/hevc,size=111830,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381296,package=standard</value>
+ <value>mime=video/hevc,size=111830,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381296,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_amp1.mp4">
- <value>mime=video/hevc,size=111830,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381296,package=standard</value>
+ <value>mime=video/hevc,size=111830,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381296,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_aud.mp4">
- <value>mime=video/hevc,size=111827,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381256,package=standard</value>
+ <value>mime=video/hevc,size=111827,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381256,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_b_adapt_0.mp4">
- <value>mime=video/hevc,size=101275,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1249960,package=standard</value>
+ <value>mime=video/hevc,size=101275,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1249960,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_b_adapt_1.mp4">
- <value>mime=video/hevc,size=125087,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1547008,package=standard</value>
+ <value>mime=video/hevc,size=125087,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1547008,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_beta0.mp4">
- <value>mime=video/hevc,size=111830,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381296,package=standard</value>
+ <value>mime=video/hevc,size=111830,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381296,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_beta4.mp4">
- <value>mime=video/hevc,size=111566,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1377984,package=standard</value>
+ <value>mime=video/hevc,size=111566,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1377984,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_beta6.mp4">
- <value>mime=video/hevc,size=111681,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1379424,package=standard</value>
+ <value>mime=video/hevc,size=111681,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1379424,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_beta6_tcm6.mp4">
- <value>mime=video/hevc,size=111419,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1376136,package=standard</value>
+ <value>mime=video/hevc,size=111419,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1376136,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_betam4.mp4">
- <value>mime=video/hevc,size=111901,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1382168,package=standard</value>
+ <value>mime=video/hevc,size=111901,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1382168,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_betam6.mp4">
- <value>mime=video/hevc,size=111653,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1379072,package=standard</value>
+ <value>mime=video/hevc,size=111653,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1379072,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_betam6_tc6.mp4">
- <value>mime=video/hevc,size=111690,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1379520,package=standard</value>
+ <value>mime=video/hevc,size=111690,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1379520,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_cnstrn_intra.mp4">
- <value>mime=video/hevc,size=112825,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1393736,package=standard</value>
+ <value>mime=video/hevc,size=112825,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1393736,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_cra16.mp4">
- <value>mime=video/hevc,size=124228,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1535456,package=standard</value>
+ <value>mime=video/hevc,size=124228,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1535456,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_crf0.mp4">
<value>mime=video/hevc,size=3095548,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=38677768,package=full</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_crf51.mp4">
- <value>mime=video/hevc,size=10315,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=112360,package=standard</value>
+ <value>mime=video/hevc,size=10315,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=112360,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_ctb16.mp4">
- <value>mime=video/hevc,size=114030,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1408824,package=standard</value>
+ <value>mime=video/hevc,size=114030,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1408824,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_ctb32.mp4">
- <value>mime=video/hevc,size=112985,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1395744,package=standard</value>
+ <value>mime=video/hevc,size=112985,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1395744,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_fastdecode.mp4">
- <value>mime=video/hevc,size=112032,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1383824,package=standard</value>
+ <value>mime=video/hevc,size=112032,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1383824,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_faster.mp4">
- <value>mime=video/hevc,size=96043,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1184560,package=standard</value>
+ <value>mime=video/hevc,size=96043,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1184560,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_fast.mp4">
- <value>mime=video/hevc,size=99525,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1228080,package=standard</value>
+ <value>mime=video/hevc,size=99525,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1228080,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_grain.mp4">
- <value>mime=video/hevc,size=177737,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=2205144,package=standard</value>
+ <value>mime=video/hevc,size=177737,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=2205144,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_hash_chksum.mp4">
- <value>mime=video/hevc,size=112534,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1390096,package=standard</value>
+ <value>mime=video/hevc,size=112534,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1390096,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_hash_crc.mp4">
- <value>mime=video/hevc,size=112342,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1387696,package=standard</value>
+ <value>mime=video/hevc,size=112342,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1387696,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_hash_md5.mp4">
- <value>mime=video/hevc,size=113686,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1404496,package=standard</value>
+ <value>mime=video/hevc,size=113686,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1404496,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_hrd.mp4">
- <value>mime=video/hevc,size=111830,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381296,package=standard</value>
+ <value>mime=video/hevc,size=111830,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381296,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_idr16.mp4">
- <value>mime=video/hevc,size=125520,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1552368,package=standard</value>
+ <value>mime=video/hevc,size=125520,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1552368,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_intraminus1.mp4">
- <value>mime=video/hevc,size=111839,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381408,package=standard</value>
+ <value>mime=video/hevc,size=111839,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381408,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_lossless.mp4">
<value>mime=video/hevc,size=5068113,width=640,height=360,frame-rate=50,profile=1,level=,bitrate=63334848,package=full</value>
@@ -11229,43 +11229,43 @@
<value>mime=video/hevc,size=124435,width=640,height=360,frame-rate=25,profile=1,level=16777216,bitrate=769096,package=standard</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_max_log2poc_10.mp4">
- <value>mime=video/hevc,size=111841,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381432,package=standard</value>
+ <value>mime=video/hevc,size=111841,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381432,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_max_log2poc_16.mp4">
- <value>mime=video/hevc,size=111863,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381696,package=standard</value>
+ <value>mime=video/hevc,size=111863,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381696,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_max_log2poc_4.mp4">
- <value>mime=video/hevc,size=111826,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381248,package=standard</value>
+ <value>mime=video/hevc,size=111826,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381248,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_max_log2poc_5.mp4">
- <value>mime=video/hevc,size=111826,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381248,package=standard</value>
+ <value>mime=video/hevc,size=111826,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381248,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_max_log2poc_6.mp4">
- <value>mime=video/hevc,size=111826,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381248,package=standard</value>
+ <value>mime=video/hevc,size=111826,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381248,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_maxtu16.mp4">
- <value>mime=video/hevc,size=112217,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1386136,package=standard</value>
+ <value>mime=video/hevc,size=112217,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1386136,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_maxtu4.mp4">
- <value>mime=video/hevc,size=108222,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1336208,package=standard</value>
+ <value>mime=video/hevc,size=108222,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1336208,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_maxtu8.mp4">
- <value>mime=video/hevc,size=112711,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1392312,package=standard</value>
+ <value>mime=video/hevc,size=112711,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1392312,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_medium.mp4">
- <value>mime=video/hevc,size=111830,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381296,package=standard</value>
+ <value>mime=video/hevc,size=111830,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381296,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_merge1.mp4">
- <value>mime=video/hevc,size=113883,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1406960,package=standard</value>
+ <value>mime=video/hevc,size=113883,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1406960,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_merge3.mp4">
- <value>mime=video/hevc,size=111195,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1373360,package=standard</value>
+ <value>mime=video/hevc,size=111195,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1373360,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_merge4.mp4">
- <value>mime=video/hevc,size=110854,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1369096,package=standard</value>
+ <value>mime=video/hevc,size=110854,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1369096,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_merge5.mp4">
- <value>mime=video/hevc,size=111457,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1376632,package=standard</value>
+ <value>mime=video/hevc,size=111457,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1376632,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_mincu16.mp4">
<value>mime=video/hevc,size=121085,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1496968,package=standard</value>
@@ -11274,16 +11274,16 @@
<value>mime=video/hevc,size=139796,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1730848,package=standard</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_nodblk.mp4">
- <value>mime=video/hevc,size=112190,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1385800,package=standard</value>
+ <value>mime=video/hevc,size=112190,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1385800,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_no_pps_qp_opt.mp4">
- <value>mime=video/hevc,size=111833,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381336,package=standard</value>
+ <value>mime=video/hevc,size=111833,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381336,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_no_pps_reflist_opt.mp4">
- <value>mime=video/hevc,size=111833,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381336,package=standard</value>
+ <value>mime=video/hevc,size=111833,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381336,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_no_vui_hrd.mp4">
- <value>mime=video/hevc,size=111833,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381336,package=standard</value>
+ <value>mime=video/hevc,size=111833,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381336,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_pcm1bitdepth0.mp4">
<value>mime=video/hevc,size=124622,width=640,height=360,frame-rate=25,profile=1,level=16777216,bitrate=770256,package=standard</value>
@@ -11316,7 +11316,7 @@
<value>mime=video/hevc,size=124511,width=640,height=360,frame-rate=25,profile=1,level=16777216,bitrate=769568,package=standard</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_placebo.mp4">
- <value>mime=video/hevc,size=118557,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1465344,package=standard</value>
+ <value>mime=video/hevc,size=118557,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1465344,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_prllmerge2.mp4">
<value>mime=video/hevc,size=124435,width=640,height=360,frame-rate=25,profile=1,level=16777216,bitrate=769096,package=standard</value>
@@ -11331,10 +11331,10 @@
<value>mime=video/hevc,size=126145,width=640,height=360,frame-rate=25,profile=1,level=16777216,bitrate=779784,package=standard</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_profilenone.mp4">
- <value>mime=video/hevc,size=111827,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381256,package=standard</value>
+ <value>mime=video/hevc,size=111827,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381256,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_psnr.mp4">
- <value>mime=video/hevc,size=167247,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=2074008,package=standard</value>
+ <value>mime=video/hevc,size=167247,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=2074008,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_qp0cb12cr12.mp4">
<value>mime=video/hevc,size=5007107,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=62572248,package=full</value>
@@ -11361,37 +11361,37 @@
<value>mime=video/hevc,size=378829,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=4718800,package=full</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_qp39cbm12cr12.mp4">
- <value>mime=video/hevc,size=104812,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1293560,package=standard</value>
+ <value>mime=video/hevc,size=104812,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1293560,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_qp4.mp4">
<value>mime=video/hevc,size=4725576,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=59053136,package=full</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_qp50.mp4">
- <value>mime=video/hevc,size=10265,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=111744,package=standard</value>
+ <value>mime=video/hevc,size=10265,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=111744,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_qp51cb12cr12.mp4">
- <value>mime=video/hevc,size=8519,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=89896,package=standard</value>
+ <value>mime=video/hevc,size=8519,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=89896,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_qp51cb12crm12.mp4">
- <value>mime=video/hevc,size=9406,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=100984,package=standard</value>
+ <value>mime=video/hevc,size=9406,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=100984,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_qp51cbm12cr12.mp4">
- <value>mime=video/hevc,size=9969,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=108024,package=standard</value>
+ <value>mime=video/hevc,size=9969,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=108024,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_qp51cbm12crm12.mp4">
- <value>mime=video/hevc,size=10799,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=118400,package=standard</value>
+ <value>mime=video/hevc,size=10799,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=118400,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_qp51.mp4">
- <value>mime=video/hevc,size=8627,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=91272,package=standard</value>
+ <value>mime=video/hevc,size=8627,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=91272,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_rect0.mp4">
- <value>mime=video/hevc,size=111830,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381296,package=standard</value>
+ <value>mime=video/hevc,size=111830,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381296,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_rpt_hdrs.mp4">
- <value>mime=video/hevc,size=111827,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381256,package=standard</value>
+ <value>mime=video/hevc,size=111827,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381256,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_sao0.mp4">
- <value>mime=video/hevc,size=111659,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1379160,package=standard</value>
+ <value>mime=video/hevc,size=111659,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1379160,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_saobndry1.mp4">
<value>mime=video/hevc,size=124612,width=640,height=360,frame-rate=25,profile=1,level=16777216,bitrate=770200,package=standard</value>
@@ -11400,52 +11400,52 @@
<value>mime=video/hevc,size=126979,width=640,height=360,frame-rate=25,profile=1,level=16777216,bitrate=784992,package=standard</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_sbh1.mp4">
- <value>mime=video/hevc,size=111830,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381296,package=standard</value>
+ <value>mime=video/hevc,size=111830,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381296,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_slower.mp4">
- <value>mime=video/hevc,size=112314,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1387320,package=standard</value>
+ <value>mime=video/hevc,size=112314,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1387320,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_slow.mp4">
- <value>mime=video/hevc,size=106931,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1320056,package=standard</value>
+ <value>mime=video/hevc,size=106931,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1320056,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_srng0.mp4">
- <value>mime=video/hevc,size=158677,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1966880,package=standard</value>
+ <value>mime=video/hevc,size=158677,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1966880,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_srng32.mp4">
- <value>mime=video/hevc,size=111830,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381296,package=standard</value>
+ <value>mime=video/hevc,size=111830,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381296,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_srng64.mp4">
- <value>mime=video/hevc,size=111830,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381296,package=standard</value>
+ <value>mime=video/hevc,size=111830,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381296,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_srng8.mp4">
- <value>mime=video/hevc,size=112057,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1384136,package=standard</value>
+ <value>mime=video/hevc,size=112057,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1384136,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_ssim.mp4">
- <value>mime=video/hevc,size=154624,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1916224,package=standard</value>
+ <value>mime=video/hevc,size=154624,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1916224,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_strngintra0.mp4">
- <value>mime=video/hevc,size=111534,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1377600,package=standard</value>
+ <value>mime=video/hevc,size=111534,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1377600,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_superfast.mp4">
- <value>mime=video/hevc,size=171951,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=2132824,package=standard</value>
+ <value>mime=video/hevc,size=171951,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=2132824,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_tc4.mp4">
- <value>mime=video/hevc,size=111708,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1379760,package=standard</value>
+ <value>mime=video/hevc,size=111708,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1379760,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_tc6.mp4">
- <value>mime=video/hevc,size=111739,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1380144,package=standard</value>
+ <value>mime=video/hevc,size=111739,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1380144,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_tcm4.mp4">
- <value>mime=video/hevc,size=111989,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1383272,package=standard</value>
+ <value>mime=video/hevc,size=111989,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1383272,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_tcm6.mp4">
- <value>mime=video/hevc,size=112166,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1385480,package=standard</value>
+ <value>mime=video/hevc,size=112166,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1385480,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_tmp_lyrs.mp4">
- <value>mime=video/hevc,size=111834,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381256,package=standard</value>
+ <value>mime=video/hevc,size=111834,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381256,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_tmvp0.mp4">
- <value>mime=video/hevc,size=112793,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1393336,package=standard</value>
+ <value>mime=video/hevc,size=112793,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1393336,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_transquant1.mp4">
<value>mime=video/hevc,size=5023585,width=640,height=360,frame-rate=25,profile=1,level=16777216,bitrate=31388784,package=full</value>
@@ -11457,22 +11457,22 @@
<value>mime=video/hevc,size=124176,width=640,height=360,frame-rate=25,profile=1,level=16777216,bitrate=767472,package=standard</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_tuinterdepth2.mp4">
- <value>mime=video/hevc,size=113824,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1406208,package=standard</value>
+ <value>mime=video/hevc,size=113824,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1406208,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_tuinterdepth4.mp4">
- <value>mime=video/hevc,size=113012,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1396072,package=standard</value>
+ <value>mime=video/hevc,size=113012,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1396072,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_tuintradepth2.mp4">
- <value>mime=video/hevc,size=111838,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381384,package=standard</value>
+ <value>mime=video/hevc,size=111838,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381384,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_tuintradepth4.mp4">
- <value>mime=video/hevc,size=111418,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1376144,package=standard</value>
+ <value>mime=video/hevc,size=111418,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1376144,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_tulimit2.mp4">
- <value>mime=video/hevc,size=111830,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381296,package=standard</value>
+ <value>mime=video/hevc,size=111830,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381296,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_tulimit4.mp4">
- <value>mime=video/hevc,size=111830,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381296,package=standard</value>
+ <value>mime=video/hevc,size=111830,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381296,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_tumin4_tumax4.mp4">
<value>mime=video/hevc,size=134975,width=640,height=360,frame-rate=25,profile=1,level=16777216,bitrate=834968,package=standard</value>
@@ -11487,40 +11487,40 @@
<value>mime=video/hevc,size=165087,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=2047008,package=standard</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_veryfast.mp4">
- <value>mime=video/hevc,size=96162,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1186048,package=standard</value>
+ <value>mime=video/hevc,size=96162,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1186048,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_veryslow.mp4">
- <value>mime=video/hevc,size=112788,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1393248,package=standard</value>
+ <value>mime=video/hevc,size=112788,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1393248,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_vui_color_matrix.mp4">
- <value>mime=video/hevc,size=111833,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381296,package=standard</value>
+ <value>mime=video/hevc,size=111833,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381296,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_vui_color_prim_bt2020.mp4">
- <value>mime=video/hevc,size=111833,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381296,package=standard</value>
+ <value>mime=video/hevc,size=111833,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381296,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_vui_color_prim_bt709.mp4">
- <value>mime=video/hevc,size=111833,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381296,package=standard</value>
+ <value>mime=video/hevc,size=111833,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381296,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_vui_transfer.mp4">
- <value>mime=video/hevc,size=111833,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381296,package=standard</value>
+ <value>mime=video/hevc,size=111833,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381296,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_weightb0weightp1.mp4">
- <value>mime=video/hevc,size=111830,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381296,package=standard</value>
+ <value>mime=video/hevc,size=111830,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381296,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_weightb1.mp4">
- <value>mime=video/hevc,size=112197,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1385880,package=standard</value>
+ <value>mime=video/hevc,size=112197,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1385880,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_weightp0.mp4">
- <value>mime=video/hevc,size=111830,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381296,package=standard</value>
+ <value>mime=video/hevc,size=111830,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1381296,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_weightp0weightb1.mp4">
- <value>mime=video/hevc,size=112004,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1383472,package=standard</value>
+ <value>mime=video/hevc,size=112004,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1383472,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_wpp1.mp4">
- <value>mime=video/hevc,size=111754,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1380344,package=standard</value>
+ <value>mime=video/hevc,size=111754,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1380344,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_640x360p50f32/crowd_640x360p50f32_zerolatency.mp4">
- <value>mime=video/hevc,size=131571,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1631920,package=standard</value>
+ <value>mime=video/hevc,size=131571,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=1631920,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/params/crowd_854x480p50f32/crowd_854x480p50f32_100kbps.mp4">
<value>mime=video/hevc,size=44809,width=854,height=480,frame-rate=50,profile=1,level=256,bitrate=543520,package=standard</value>
@@ -12003,16 +12003,16 @@
<value>mime=video/hevc,size=181760,width=1280,height=960,frame-rate=50,profile=1,level=1024,bitrate=2255424,package=standard</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_128x128p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=15827,width=128,height=128,frame-rate=50,profile=1,level=4,bitrate=181360,package=standard</value>
+ <value>mime=video/hevc,size=15827,width=128,height=128,frame-rate=50,profile=1,level=4,bitrate=181360,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_128x192p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=16225,width=128,height=192,frame-rate=50,profile=1,level=4,bitrate=186232,package=standard</value>
+ <value>mime=video/hevc,size=16225,width=128,height=192,frame-rate=50,profile=1,level=4,bitrate=186232,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_128x72p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=15231,width=128,height=72,frame-rate=50,profile=1,level=4,bitrate=174120,package=standard</value>
+ <value>mime=video/hevc,size=15231,width=128,height=72,frame-rate=50,profile=1,level=4,bitrate=174120,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_128x96p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=15632,width=128,height=96,frame-rate=50,profile=1,level=4,bitrate=179032,package=standard</value>
+ <value>mime=video/hevc,size=15632,width=128,height=96,frame-rate=50,profile=1,level=4,bitrate=179032,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_1440x1080p50f32_3100kbps.mp4">
<value>mime=video/hevc,size=234357,width=1440,height=1080,frame-rate=50,profile=1,level=4096,bitrate=2912872,package=standard</value>
@@ -12030,25 +12030,25 @@
<value>mime=video/hevc,size=204715,width=1440,height=960,frame-rate=50,profile=1,level=4096,bitrate=2542360,package=standard</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_144x144p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=15932,width=144,height=144,frame-rate=50,profile=1,level=4,bitrate=182568,package=standard</value>
+ <value>mime=video/hevc,size=15932,width=144,height=144,frame-rate=50,profile=1,level=4,bitrate=182568,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_144x176p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=16206,width=144,height=176,frame-rate=50,profile=1,level=4,bitrate=186096,package=standard</value>
+ <value>mime=video/hevc,size=16206,width=144,height=176,frame-rate=50,profile=1,level=4,bitrate=186096,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_144x192p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=16510,width=144,height=192,frame-rate=50,profile=1,level=4,bitrate=189800,package=standard</value>
+ <value>mime=video/hevc,size=16510,width=144,height=192,frame-rate=50,profile=1,level=4,bitrate=189800,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_144x256p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=16496,width=144,height=256,frame-rate=50,profile=1,level=4,bitrate=189632,package=standard</value>
+ <value>mime=video/hevc,size=16496,width=144,height=256,frame-rate=50,profile=1,level=4,bitrate=189632,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_144x96p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=15600,width=144,height=96,frame-rate=50,profile=1,level=4,bitrate=178432,package=standard</value>
+ <value>mime=video/hevc,size=15600,width=144,height=96,frame-rate=50,profile=1,level=4,bitrate=178432,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_1536x2048p50f32_6200kbps.mp4">
<value>mime=video/hevc,size=452944,width=1536,height=2048,frame-rate=50,profile=1,level=16384,bitrate=5645512,package=full</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_160x240p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=16904,width=160,height=240,frame-rate=50,profile=1,level=4,bitrate=194720,package=standard</value>
+ <value>mime=video/hevc,size=16904,width=160,height=240,frame-rate=50,profile=1,level=4,bitrate=194720,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_16x1080p50f32_200kbps.mp4">
<value>mime=video/hevc,size=17424,width=16,height=1080,frame-rate=25,profile=1,level=16777216,bitrate=100424,package=standard</value>
@@ -12069,10 +12069,10 @@
<value>mime=video/hevc,size=16738,width=172,height=172,frame-rate=50,profile=1,level=4,bitrate=192632,package=standard</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_176x144p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=16047,width=176,height=144,frame-rate=50,profile=1,level=4,bitrate=184008,package=standard</value>
+ <value>mime=video/hevc,size=16047,width=176,height=144,frame-rate=50,profile=1,level=4,bitrate=184008,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_176x96p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=15763,width=176,height=96,frame-rate=50,profile=1,level=4,bitrate=180472,package=standard</value>
+ <value>mime=video/hevc,size=15763,width=176,height=96,frame-rate=50,profile=1,level=4,bitrate=180472,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_1920x1080p50f32_4100kbps.mp4">
<value>mime=video/hevc,size=309303,width=1920,height=1080,frame-rate=50,profile=1,level=4096,bitrate=3849696,package=standard</value>
@@ -12099,19 +12099,19 @@
<value>mime=video/hevc,size=17400,width=1920,height=64,frame-rate=50,profile=1,level=64,bitrate=201224,package=standard</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_192x128p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=16085,width=192,height=128,frame-rate=50,profile=1,level=4,bitrate=184584,package=standard</value>
+ <value>mime=video/hevc,size=16085,width=192,height=128,frame-rate=50,profile=1,level=4,bitrate=184584,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_192x144p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=16168,width=192,height=144,frame-rate=50,profile=1,level=4,bitrate=185624,package=standard</value>
+ <value>mime=video/hevc,size=16168,width=192,height=144,frame-rate=50,profile=1,level=4,bitrate=185624,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_192x192p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=17158,width=192,height=192,frame-rate=50,profile=1,level=4,bitrate=197896,package=standard</value>
+ <value>mime=video/hevc,size=17158,width=192,height=192,frame-rate=50,profile=1,level=4,bitrate=197896,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_192x256p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=17180,width=192,height=256,frame-rate=50,profile=1,level=4,bitrate=198184,package=standard</value>
+ <value>mime=video/hevc,size=17180,width=192,height=256,frame-rate=50,profile=1,level=4,bitrate=198184,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_192x288p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=17156,width=192,height=288,frame-rate=50,profile=1,level=4,bitrate=197880,package=standard</value>
+ <value>mime=video/hevc,size=17156,width=192,height=288,frame-rate=50,profile=1,level=4,bitrate=197880,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_2048x1152p50f32_4700kbps.mp4">
<value>mime=video/hevc,size=342926,width=2048,height=1152,frame-rate=50,profile=1,level=16384,bitrate=4270280,package=standard</value>
@@ -12126,22 +12126,22 @@
<value>mime=video/hevc,size=1245939,width=2160,height=3840,frame-rate=50,profile=1,level=65536,bitrate=15557936,package=full</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_216x288p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=17496,width=216,height=288,frame-rate=50,profile=1,level=4,bitrate=202136,package=standard</value>
+ <value>mime=video/hevc,size=17496,width=216,height=288,frame-rate=50,profile=1,level=4,bitrate=202136,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_2304x4096p50f32_18800kbps.mp4">
<value>mime=video/hevc,size=1434142,width=2304,height=4096,frame-rate=50,profile=1,level=1048576,bitrate=17910480,package=full</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_240x160p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=16760,width=240,height=160,frame-rate=50,profile=1,level=4,bitrate=192920,package=standard</value>
+ <value>mime=video/hevc,size=16760,width=240,height=160,frame-rate=50,profile=1,level=4,bitrate=192920,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_240x240p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=17554,width=240,height=240,frame-rate=50,profile=1,level=4,bitrate=202848,package=standard</value>
+ <value>mime=video/hevc,size=17554,width=240,height=240,frame-rate=50,profile=1,level=4,bitrate=202848,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_240x320p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=18207,width=240,height=320,frame-rate=50,profile=1,level=16,bitrate=211024,package=standard</value>
+ <value>mime=video/hevc,size=18207,width=240,height=320,frame-rate=50,profile=1,level=16,bitrate=211024,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_240x360p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=18466,width=240,height=360,frame-rate=50,profile=1,level=16,bitrate=214256,package=standard</value>
+ <value>mime=video/hevc,size=18466,width=240,height=360,frame-rate=50,profile=1,level=16,bitrate=214256,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_24x32p50f32_200kbps.mp4">
<value>mime=video/hevc,size=12425,width=24,height=32,frame-rate=25,profile=1,level=16777216,bitrate=69184,package=standard</value>
@@ -12159,34 +12159,34 @@
<value>mime=video/hevc,size=1495105,width=2560,height=3840,frame-rate=50,profile=1,level=1048576,bitrate=18672512,package=full</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_256x144p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=16965,width=256,height=144,frame-rate=50,profile=1,level=4,bitrate=195496,package=standard</value>
+ <value>mime=video/hevc,size=16965,width=256,height=144,frame-rate=50,profile=1,level=4,bitrate=195496,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_256x192p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=17228,width=256,height=192,frame-rate=50,profile=1,level=4,bitrate=198784,package=standard</value>
+ <value>mime=video/hevc,size=17228,width=256,height=192,frame-rate=50,profile=1,level=4,bitrate=198784,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_256x256p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=17786,width=256,height=256,frame-rate=50,profile=1,level=4,bitrate=205744,package=standard</value>
+ <value>mime=video/hevc,size=17786,width=256,height=256,frame-rate=50,profile=1,level=4,bitrate=205744,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_264x352p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=18541,width=264,height=352,frame-rate=50,profile=1,level=16,bitrate=215184,package=standard</value>
+ <value>mime=video/hevc,size=18541,width=264,height=352,frame-rate=50,profile=1,level=16,bitrate=215184,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_2880x3840p50f32_22100kbps.mp4">
<value>mime=video/hevc,size=1696884,width=2880,height=3840,frame-rate=50,profile=1,level=1048576,bitrate=21194744,package=full</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_288x192p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=17425,width=288,height=192,frame-rate=50,profile=1,level=4,bitrate=201248,package=standard</value>
+ <value>mime=video/hevc,size=17425,width=288,height=192,frame-rate=50,profile=1,level=4,bitrate=201248,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_288x216p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=17635,width=288,height=216,frame-rate=50,profile=1,level=4,bitrate=203872,package=standard</value>
+ <value>mime=video/hevc,size=17635,width=288,height=216,frame-rate=50,profile=1,level=4,bitrate=203872,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_288x288p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=17956,width=288,height=288,frame-rate=50,profile=1,level=16,bitrate=207872,package=standard</value>
+ <value>mime=video/hevc,size=17956,width=288,height=288,frame-rate=50,profile=1,level=16,bitrate=207872,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_288x352p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=19148,width=288,height=352,frame-rate=50,profile=1,level=16,bitrate=222768,package=standard</value>
+ <value>mime=video/hevc,size=19148,width=288,height=352,frame-rate=50,profile=1,level=16,bitrate=222768,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_288x512p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=20690,width=288,height=512,frame-rate=50,profile=1,level=16,bitrate=242048,package=standard</value>
+ <value>mime=video/hevc,size=20690,width=288,height=512,frame-rate=50,profile=1,level=16,bitrate=242048,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_3072x4096p50f32_24000kbps.mp4">
<value>mime=video/hevc,size=1852683,width=3072,height=4096,frame-rate=50,profile=1,level=1048576,bitrate=23142248,package=full</value>
@@ -12195,13 +12195,13 @@
<value>mime=video/hevc,size=1853419,width=3120,height=4160,frame-rate=50,profile=1,level=1048576,bitrate=23151448,package=full</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_320x240p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=18021,width=320,height=240,frame-rate=50,profile=1,level=16,bitrate=208696,package=standard</value>
+ <value>mime=video/hevc,size=18021,width=320,height=240,frame-rate=50,profile=1,level=16,bitrate=208696,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_320x320p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=18414,width=320,height=320,frame-rate=50,profile=1,level=16,bitrate=213600,package=standard</value>
+ <value>mime=video/hevc,size=18414,width=320,height=320,frame-rate=50,profile=1,level=16,bitrate=213600,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_320x480p50f32_300kbps.mp4">
- <value>mime=video/hevc,size=26348,width=320,height=480,frame-rate=50,profile=1,level=64,bitrate=312768,package=standard</value>
+ <value>mime=video/hevc,size=26348,width=320,height=480,frame-rate=50,profile=1,level=64,bitrate=312768,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_32x24p50f32_200kbps.mp4">
<value>mime=video/hevc,size=10743,width=32,height=24,frame-rate=25,profile=1,level=16777216,bitrate=58672,package=standard</value>
@@ -12213,13 +12213,13 @@
<value>mime=video/hevc,size=19879,width=350,height=350,frame-rate=50,profile=1,level=16,bitrate=231896,package=standard</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_352x264p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=18603,width=352,height=264,frame-rate=50,profile=1,level=16,bitrate=215960,package=standard</value>
+ <value>mime=video/hevc,size=18603,width=352,height=264,frame-rate=50,profile=1,level=16,bitrate=215960,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_352x288p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=18431,width=352,height=288,frame-rate=50,profile=1,level=16,bitrate=213808,package=standard</value>
+ <value>mime=video/hevc,size=18431,width=352,height=288,frame-rate=50,profile=1,level=16,bitrate=213808,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_352x352p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=19460,width=352,height=352,frame-rate=50,profile=1,level=16,bitrate=226672,package=standard</value>
+ <value>mime=video/hevc,size=19460,width=352,height=352,frame-rate=50,profile=1,level=16,bitrate=226672,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_356x638p50f32_400kbps.mp4">
<value>mime=video/hevc,size=35006,width=356,height=638,frame-rate=50,profile=1,level=64,bitrate=420984,package=standard</value>
@@ -12234,13 +12234,13 @@
<value>mime=video/hevc,size=34998,width=358,height=640,frame-rate=50,profile=1,level=64,bitrate=420880,package=standard</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_360x240p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=18425,width=360,height=240,frame-rate=50,profile=1,level=16,bitrate=213744,package=standard</value>
+ <value>mime=video/hevc,size=18425,width=360,height=240,frame-rate=50,profile=1,level=16,bitrate=213744,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_360x360p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=19725,width=360,height=360,frame-rate=50,profile=1,level=16,bitrate=229984,package=standard</value>
+ <value>mime=video/hevc,size=19725,width=360,height=360,frame-rate=50,profile=1,level=16,bitrate=229984,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_360x480p50f32_300kbps.mp4">
- <value>mime=video/hevc,size=27201,width=360,height=480,frame-rate=50,profile=1,level=64,bitrate=323432,package=standard</value>
+ <value>mime=video/hevc,size=27201,width=360,height=480,frame-rate=50,profile=1,level=64,bitrate=323432,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_360x636p50f32_400kbps.mp4">
<value>mime=video/hevc,size=35040,width=360,height=636,frame-rate=50,profile=1,level=64,bitrate=421408,package=standard</value>
@@ -12249,7 +12249,7 @@
<value>mime=video/hevc,size=35007,width=360,height=638,frame-rate=50,profile=1,level=64,bitrate=421000,package=standard</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_360x640p50f32_400kbps.mp4">
- <value>mime=video/hevc,size=34990,width=360,height=640,frame-rate=50,profile=1,level=64,bitrate=420800,package=standard</value>
+ <value>mime=video/hevc,size=34990,width=360,height=640,frame-rate=50,profile=1,level=64,bitrate=420800,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_3840x2160p50f32_16500kbps.mp4">
<value>mime=video/hevc,size=1224524,width=3840,height=2160,frame-rate=50,profile=1,level=65536,bitrate=15290248,package=full</value>
@@ -12264,7 +12264,7 @@
<value>mime=video/hevc,size=1846359,width=3840,height=3840,frame-rate=50,profile=1,level=1048576,bitrate=23063184,package=full</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_384x512p50f32_300kbps.mp4">
- <value>mime=video/hevc,size=28352,width=384,height=512,frame-rate=50,profile=1,level=64,bitrate=337824,package=standard</value>
+ <value>mime=video/hevc,size=28352,width=384,height=512,frame-rate=50,profile=1,level=64,bitrate=337824,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_4096x2304p50f32_18800kbps.mp4">
<value>mime=video/hevc,size=1441976,width=4096,height=2304,frame-rate=50,profile=1,level=1048576,bitrate=18008408,package=full</value>
@@ -12285,19 +12285,19 @@
<value>mime=video/hevc,size=1908628,width=4320,height=7680,frame-rate=50,profile=1,level=4194304,bitrate=23841544,package=full</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_472x472p50f32_400kbps.mp4">
- <value>mime=video/hevc,size=35085,width=472,height=472,frame-rate=50,profile=1,level=64,bitrate=421984,package=standard</value>
+ <value>mime=video/hevc,size=35085,width=472,height=472,frame-rate=50,profile=1,level=64,bitrate=421984,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_480x320p50f32_300kbps.mp4">
- <value>mime=video/hevc,size=26460,width=480,height=320,frame-rate=50,profile=1,level=64,bitrate=314168,package=standard</value>
+ <value>mime=video/hevc,size=26460,width=480,height=320,frame-rate=50,profile=1,level=64,bitrate=314168,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_480x360p50f32_300kbps.mp4">
- <value>mime=video/hevc,size=27258,width=480,height=360,frame-rate=50,profile=1,level=64,bitrate=324144,package=standard</value>
+ <value>mime=video/hevc,size=27258,width=480,height=360,frame-rate=50,profile=1,level=64,bitrate=324144,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_480x480p50f32_400kbps.mp4">
- <value>mime=video/hevc,size=35196,width=480,height=480,frame-rate=50,profile=1,level=64,bitrate=423368,package=standard</value>
+ <value>mime=video/hevc,size=35196,width=480,height=480,frame-rate=50,profile=1,level=64,bitrate=423368,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_480x640p50f32_600kbps.mp4">
- <value>mime=video/hevc,size=49677,width=480,height=640,frame-rate=50,profile=1,level=64,bitrate=604384,package=standard</value>
+ <value>mime=video/hevc,size=49677,width=480,height=640,frame-rate=50,profile=1,level=64,bitrate=604384,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_480x720p50f32_600kbps.mp4">
<value>mime=video/hevc,size=50681,width=480,height=720,frame-rate=50,profile=1,level=256,bitrate=616936,package=standard</value>
@@ -12309,10 +12309,10 @@
<value>mime=video/hevc,size=19756,width=48,height=64,frame-rate=25,profile=1,level=16777216,bitrate=115000,package=standard</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_512x288p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=20626,width=512,height=288,frame-rate=50,profile=1,level=16,bitrate=241248,package=standard</value>
+ <value>mime=video/hevc,size=20626,width=512,height=288,frame-rate=50,profile=1,level=16,bitrate=241248,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_512x384p50f32_300kbps.mp4">
- <value>mime=video/hevc,size=28164,width=512,height=384,frame-rate=50,profile=1,level=64,bitrate=335472,package=standard</value>
+ <value>mime=video/hevc,size=28164,width=512,height=384,frame-rate=50,profile=1,level=64,bitrate=335472,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_512x512p50f32_500kbps.mp4">
<value>mime=video/hevc,size=42386,width=512,height=512,frame-rate=50,profile=1,level=64,bitrate=513232,package=standard</value>
@@ -12351,10 +12351,10 @@
<value>mime=video/hevc,size=35398,width=640,height=358,frame-rate=50,profile=1,level=64,bitrate=425880,package=standard</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_640x360p50f32_400kbps.mp4">
- <value>mime=video/hevc,size=35178,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=423144,package=standard</value>
+ <value>mime=video/hevc,size=35178,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=423144,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_640x480p50f32_600kbps.mp4">
- <value>mime=video/hevc,size=49884,width=640,height=480,frame-rate=50,profile=1,level=64,bitrate=606968,package=standard</value>
+ <value>mime=video/hevc,size=49884,width=640,height=480,frame-rate=50,profile=1,level=64,bitrate=606968,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_640x640p50f32_800kbps.mp4">
<value>mime=video/hevc,size=65237,width=640,height=640,frame-rate=50,profile=1,level=256,bitrate=798872,package=standard</value>
@@ -12378,13 +12378,13 @@
<value>mime=video/hevc,size=19475,width=64,height=48,frame-rate=25,profile=1,level=16777216,bitrate=113248,package=standard</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_64x64p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=14469,width=64,height=64,frame-rate=50,profile=1,level=4,bitrate=165496,package=standard</value>
+ <value>mime=video/hevc,size=14469,width=64,height=64,frame-rate=50,profile=1,level=4,bitrate=165496,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_64x720p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=16614,width=64,height=720,frame-rate=50,profile=1,level=4,bitrate=191208,package=standard</value>
+ <value>mime=video/hevc,size=16614,width=64,height=720,frame-rate=50,profile=1,level=4,bitrate=191208,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_64x96p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=15195,width=64,height=96,frame-rate=50,profile=1,level=4,bitrate=173568,package=standard</value>
+ <value>mime=video/hevc,size=15195,width=64,height=96,frame-rate=50,profile=1,level=4,bitrate=173568,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_704x528p50f32_700kbps.mp4">
<value>mime=video/hevc,size=57633,width=704,height=528,frame-rate=50,profile=1,level=256,bitrate=703824,package=standard</value>
@@ -12408,7 +12408,7 @@
<value>mime=video/hevc,size=65161,width=720,height=576,frame-rate=50,profile=1,level=256,bitrate=797920,package=standard</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_720x64p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=17403,width=720,height=64,frame-rate=50,profile=1,level=4,bitrate=200968,package=standard</value>
+ <value>mime=video/hevc,size=17403,width=720,height=64,frame-rate=50,profile=1,level=4,bitrate=200968,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_720x720p50f32_1000kbps.mp4">
<value>mime=video/hevc,size=80695,width=720,height=720,frame-rate=50,profile=1,level=256,bitrate=992096,package=standard</value>
@@ -12417,10 +12417,10 @@
<value>mime=video/hevc,size=103483,width=720,height=960,frame-rate=50,profile=1,level=1024,bitrate=1277048,package=standard</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_72x128p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=15130,width=72,height=128,frame-rate=50,profile=1,level=4,bitrate=172656,package=standard</value>
+ <value>mime=video/hevc,size=15130,width=72,height=128,frame-rate=50,profile=1,level=4,bitrate=172656,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_72x96p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=15198,width=72,height=96,frame-rate=50,profile=1,level=4,bitrate=173712,package=standard</value>
+ <value>mime=video/hevc,size=15198,width=72,height=96,frame-rate=50,profile=1,level=4,bitrate=173712,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_7680x4320p50f32_24000kbps.mp4">
<value>mime=video/hevc,size=1916933,width=7680,height=4320,frame-rate=50,profile=1,level=4194304,bitrate=23945360,package=full</value>
@@ -12462,22 +12462,22 @@
<value>mime=video/hevc,size=141395,width=960,height=960,frame-rate=50,profile=1,level=1024,bitrate=1750944,package=standard</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_96x128p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=15331,width=96,height=128,frame-rate=50,profile=1,level=4,bitrate=175168,package=standard</value>
+ <value>mime=video/hevc,size=15331,width=96,height=128,frame-rate=50,profile=1,level=4,bitrate=175168,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_96x144p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=15320,width=96,height=144,frame-rate=50,profile=1,level=4,bitrate=175032,package=standard</value>
+ <value>mime=video/hevc,size=15320,width=96,height=144,frame-rate=50,profile=1,level=4,bitrate=175032,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_96x176p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=15983,width=96,height=176,frame-rate=50,profile=1,level=4,bitrate=183320,package=standard</value>
+ <value>mime=video/hevc,size=15983,width=96,height=176,frame-rate=50,profile=1,level=4,bitrate=183320,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_96x64p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=15189,width=96,height=64,frame-rate=50,profile=1,level=4,bitrate=175400,package=standard</value>
+ <value>mime=video/hevc,size=15189,width=96,height=64,frame-rate=50,profile=1,level=4,bitrate=175400,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_96x72p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=15172,width=96,height=72,frame-rate=50,profile=1,level=4,bitrate=173384,package=standard</value>
+ <value>mime=video/hevc,size=15172,width=96,height=72,frame-rate=50,profile=1,level=4,bitrate=173384,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/resolution/crowd_96x96p50f32_200kbps.mp4">
- <value>mime=video/hevc,size=15713,width=96,height=96,frame-rate=50,profile=1,level=4,bitrate=180344,package=standard</value>
+ <value>mime=video/hevc,size=15713,width=96,height=96,frame-rate=50,profile=1,level=4,bitrate=180344,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/scaling_list/crowd_1280x720p50f32/crowd_1280x720p50f32_defslist.mp4">
<value>mime=video/hevc,size=323058,width=1280,height=720,frame-rate=50,profile=1,level=1024,bitrate=4021648,package=standard</value>
@@ -12576,28 +12576,28 @@
<value>mime=video/hevc,size=3047156,width=3840,height=2160,frame-rate=50,profile=1,level=65536,bitrate=38068208,package=full</value>
</entry>
<entry key="hevc/yuv420/8bit/scaling_list/crowd_640x360p50f32/crowd_640x360p50f32_defslist.mp4">
- <value>mime=video/hevc,size=74176,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=910624,package=standard</value>
+ <value>mime=video/hevc,size=74176,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=910624,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/scaling_list/crowd_640x360p50f32/crowd_640x360p50f32_noslist.mp4">
- <value>mime=video/hevc,size=74639,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=916408,package=standard</value>
+ <value>mime=video/hevc,size=74639,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=916408,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/scaling_list/crowd_640x360p50f32/crowd_640x360p50f32_slist_flat_127.mp4">
<value>mime=video/hevc,size=81608,width=640,height=360,frame-rate=25,profile=1,level=,bitrate=501160,package=standard</value>
</entry>
<entry key="hevc/yuv420/8bit/scaling_list/crowd_640x360p50f32/crowd_640x360p50f32_slist_flat_16.mp4">
- <value>mime=video/hevc,size=74674,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=916408,package=standard</value>
+ <value>mime=video/hevc,size=74674,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=916408,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/scaling_list/crowd_640x360p50f32/crowd_640x360p50f32_slist_flat_1.mp4">
- <value>mime=video/hevc,size=163935,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=2032136,package=standard</value>
+ <value>mime=video/hevc,size=163935,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=2032136,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/scaling_list/crowd_640x360p50f32/crowd_640x360p50f32_slist_flat_255.mp4">
<value>mime=video/hevc,size=81668,width=640,height=360,frame-rate=25,profile=1,level=,bitrate=501536,package=standard</value>
</entry>
<entry key="hevc/yuv420/8bit/scaling_list/crowd_640x360p50f32/crowd_640x360p50f32_slist_rndm_1_16.mp4">
- <value>mime=video/hevc,size=81484,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=992208,package=standard</value>
+ <value>mime=video/hevc,size=81484,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=992208,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/scaling_list/crowd_640x360p50f32/crowd_640x360p50f32_slist_rndm_120_136.mp4">
- <value>mime=video/hevc,size=57929,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=697144,package=standard</value>
+ <value>mime=video/hevc,size=57929,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=697144,package=standard,enforce=true</value>
</entry>
<entry key="hevc/yuv420/8bit/scaling_list/crowd_640x360p50f32/crowd_640x360p50f32_slist_rndm_1_255.mp4">
<value>mime=video/hevc,size=68980,width=640,height=360,frame-rate=50,profile=1,level=64,bitrate=824120,package=standard</value>
diff --git a/hostsidetests/multiuser/AndroidTest.xml b/hostsidetests/multiuser/AndroidTest.xml
index 3c359c0..880aef9 100644
--- a/hostsidetests/multiuser/AndroidTest.xml
+++ b/hostsidetests/multiuser/AndroidTest.xml
@@ -16,6 +16,8 @@
<configuration description="Config for the CTS multiuser host tests">
<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" />
<test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
<option name="jar" value="CtsMultiUserHostTestCases.jar" />
<option name="runtime-hint" value="8m" />
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/HostsideOomCatcher.java b/hostsidetests/securitybulletin/src/android/security/cts/HostsideOomCatcher.java
index cd39c56..86f930b 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/HostsideOomCatcher.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/HostsideOomCatcher.java
@@ -79,14 +79,23 @@
* Utility to get the device memory total by reading /proc/meminfo and returning MemTotal
*/
private static long getMemTotal(ITestDevice device) throws DeviceNotAvailableException {
- String memInfo = device.executeShellCommand("cat /proc/meminfo");
- Pattern pattern = Pattern.compile("MemTotal:\\s*(.*?)\\s*[kK][bB]");
- Matcher matcher = pattern.matcher(memInfo);
- if (matcher.find()) {
- return Long.parseLong(matcher.group(1));
- } else {
- throw new RuntimeException("Could not get device memory total");
+ // cache device TotalMem to avoid an adb shell for every test.
+ String serial = device.getSerialNumber();
+ Long totalMemory = totalMemories.get(serial);
+ if (totalMemory == null) {
+ String memInfo = device.executeShellCommand("cat /proc/meminfo");
+ Pattern pattern = Pattern.compile("MemTotal:\\s*(.*?)\\s*[kK][bB]");
+ Matcher matcher = pattern.matcher(memInfo);
+ if (matcher.find()) {
+ totalMemory = Long.parseLong(matcher.group(1));
+ } else {
+ throw new RuntimeException("Could not get device memory total.");
+ }
+ Log.logAndDisplay(Log.LogLevel.INFO, LOG_TAG,
+ "Device " + serial + " has " + totalMemory + "KB total memory.");
+ totalMemories.put(serial, totalMemory);
}
+ return totalMemory;
}
/**
@@ -94,24 +103,14 @@
* Match this call to SecurityTestCase.setup().
*/
public synchronized void start() throws Exception {
- // cache device TotalMem to avoid and adb shell for every test.
- Long totalMemory = totalMemories.get(getDevice().getSerialNumber());
- if (totalMemory == null) {
- totalMemory = getMemTotal(getDevice());
- totalMemories.put(getDevice().getSerialNumber(), totalMemory);
- }
+ long totalMemory = getMemTotal(getDevice());
isLowMemoryDevice = totalMemory < LOW_MEMORY_DEVICE_THRESHOLD_KB;
// reset test oom behavior
- // Low memory devices should skip (pass) tests when OOMing and log so that the
- // high-memory-test flag can be added. Normal devices should fail tests that OOM so that
- // they'll be ran again with --retry. If the test OOMs because previous tests used the
- // memory, it will likely pass on a second try.
- if (isLowMemoryDevice) {
- oomBehavior = OomBehavior.PASS_AND_LOG;
- } else {
- oomBehavior = OomBehavior.FAIL_AND_LOG;
- }
+ // Devices should fail tests that OOM so that they'll be ran again with --retry.
+ // If the test OOMs because previous tests used the memory, it will likely pass
+ // on a second try.
+ oomBehavior = OomBehavior.FAIL_AND_LOG;
oomDetected = false;
// Cache OOM detection in separate persistent threads for each device.
@@ -207,12 +206,11 @@
Log.logAndDisplay(Log.LogLevel.INFO, LOG_TAG,
"lowmemorykiller detected; rebooting device.");
synchronized (HostsideOomCatcher.this) { // synchronized for oomDetected
- oomDetected = true;
+ oomDetected = true; // set HostSideOomCatcher var
}
try {
device.nonBlockingReboot();
device.waitForDeviceOnline(60 * 2 * 1000); // 2 minutes
- context.updateKernelStartTime();
} catch (Exception e) {
Log.e(LOG_TAG, e.toString());
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_04.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_04.java
index 9dd3d2d..b1ed666 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_04.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_04.java
@@ -34,8 +34,17 @@
* b/69634768
* Does not require root but must be a hostside test to avoid a race condition
*/
- @SecurityTest
+ @SecurityTest(minPatchLevel = "2018-04")
public void testPocCVE_2017_13288() throws Exception {
LaunchSomeWhere.launchSomeWhere("CVE_2017_13288", getDevice());
}
+
+ /**
+ * b/70398564
+ * Does not require root but must be a hostside test to avoid a race condition
+ */
+ @SecurityTest(minPatchLevel = "2018-04")
+ public void testPocCVE_2017_13289() throws Exception {
+ LaunchSomeWhere.launchSomeWhere("CVE_2017_13289", getDevice());
+ }
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc19_03.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_03.java
index fe85e87..115fad2 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc19_03.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_03.java
@@ -31,4 +31,4 @@
public void testPocBug_115739809() throws Exception {
assertFalse(AdbUtils.runPocCheckExitCode("Bug-115739809", getDevice(), 30));
}
-}
\ No newline at end of file
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java b/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java
index eea1380..ea6d66c 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java
@@ -96,26 +96,29 @@
oomCatcher.stop(getDevice().getSerialNumber());
getDevice().waitForDeviceAvailable(120 * 1000);
- String uptime = getDevice().executeShellCommand("cat /proc/uptime");
- assertTrue("Phone has had a hard reset",
- (System.currentTimeMillis()/1000 -
- Integer.parseInt(uptime.substring(0, uptime.indexOf('.')))
- - kernelStartTime < 2));
- //TODO(badash@): add ability to catch runtime restart
- getDevice().disableAdbRoot();
if (oomCatcher.isOomDetected()) {
+ // we don't need to check kernel start time if we intentionally rebooted because oom
+ updateKernelStartTime();
switch (oomCatcher.getOomBehavior()) {
case FAIL_AND_LOG:
fail("The device ran out of memory.");
- return;
+ break;
case PASS_AND_LOG:
Log.logAndDisplay(Log.LogLevel.INFO, LOG_TAG, "Skipping test.");
- return;
+ break;
case FAIL_NO_LOG:
fail();
- return;
+ break;
}
+ } else {
+ String uptime = getDevice().executeShellCommand("cat /proc/uptime");
+ assertTrue("Phone has had a hard reset",
+ (System.currentTimeMillis()/1000 -
+ Integer.parseInt(uptime.substring(0, uptime.indexOf('.')))
+ - kernelStartTime < 2));
+ //TODO(badash@): add ability to catch runtime restart
+ getDevice().disableAdbRoot();
}
}
diff --git a/hostsidetests/securitybulletin/test-apps/launchanywhere/src/com/android/security/cts/launchanywhere/CVE_2017_13289.java b/hostsidetests/securitybulletin/test-apps/launchanywhere/src/com/android/security/cts/launchanywhere/CVE_2017_13289.java
new file mode 100644
index 0000000..716dda6
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/launchanywhere/src/com/android/security/cts/launchanywhere/CVE_2017_13289.java
@@ -0,0 +1,92 @@
+/**
+ * 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.
+ */
+
+package com.android.security.cts.launchanywhere;
+
+import android.accounts.AccountManager;
+import android.content.Intent;
+import android.os.Parcel;
+
+public class CVE_2017_13289 implements IGenerateMalformedParcel {
+ public Parcel generate(Intent intent) {
+ Parcel data = Parcel.obtain();
+ String responseName = "android.accounts.IAccountAuthenticatorResponse";
+ data.writeInterfaceToken(responseName);
+ data.writeInt(1);
+ int bundleLenPos = data.dataPosition();
+ data.writeInt(0xffffffff);
+ data.writeInt(0x4C444E42);
+ int bundleStartPos = data.dataPosition();
+ data.writeInt(2);
+
+ data.writeString("launchanywhere");
+ data.writeInt(4);
+ data.writeString("android.net.wifi.RttManager$ParcelableRttResults");
+ data.writeInt(1);
+ data.writeString(null);
+ data.writeInt(0);
+ data.writeInt(0);
+ data.writeInt(0);
+ data.writeInt(0);
+ data.writeInt(0);
+ data.writeInt(0);
+ data.writeInt(0);
+ data.writeLong(0);
+ data.writeInt(0);
+ data.writeInt(0);
+ data.writeInt(0);
+ data.writeLong(0);
+ data.writeLong(0);
+ data.writeLong(0);
+ data.writeInt(0);
+ data.writeInt(0);
+ data.writeInt(0);
+ data.writeInt(0);
+ data.writeInt(0);
+ data.writeInt(0xff);
+ data.writeInt(12);
+ data.writeInt(12);
+ data.writeInt(12);
+ data.writeInt(0);
+ data.writeInt(0);
+ data.writeInt(0);
+
+ data.writeInt(0);
+
+ data.writeString(null);
+ data.writeInt(13);
+ int byteArrayLenPos = data.dataPosition();
+ data.writeInt(0xffffffff);
+ int byteArrayStartPos = data.dataPosition();
+ data.writeString(AccountManager.KEY_INTENT);
+ data.writeInt(4);
+ data.writeString("android.content.Intent");
+ intent.writeToParcel(data, 0);
+ int byteArrayEndPos = data.dataPosition();
+ data.setDataPosition(byteArrayLenPos);
+ int byteArrayLen = byteArrayEndPos - byteArrayStartPos;
+ data.writeInt(byteArrayLen);
+ data.setDataPosition(byteArrayEndPos);
+
+ int bundleEndPos = data.dataPosition();
+ data.setDataPosition(bundleLenPos);
+ int bundleLen = bundleEndPos - bundleStartPos;
+ data.writeInt(bundleLen);
+ data.setDataPosition(bundleEndPos);
+
+ return data;
+ }
+}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java b/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java
index 1fade2f..0d53fea 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java
@@ -88,6 +88,7 @@
public static final long CONFIG_ID = "cts_config".hashCode();
public static final String FEATURE_AUDIO_OUTPUT = "android.hardware.audio.output";
+ public static final String FEATURE_AUTOMOTIVE = "android.hardware.type.automotive";
public static final String FEATURE_BLUETOOTH = "android.hardware.bluetooth";
public static final String FEATURE_BLUETOOTH_LE = "android.hardware.bluetooth_le";
public static final String FEATURE_CAMERA = "android.hardware.camera";
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/HostAtomTests.java b/hostsidetests/statsd/src/android/cts/statsd/atom/HostAtomTests.java
index a4cd3b5..975739c 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/HostAtomTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/HostAtomTests.java
@@ -104,6 +104,7 @@
if (statsdDisabled()) {
return;
}
+ if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return;
// Setup, set charging state to full.
setChargingState(5);
Thread.sleep(WAIT_TIME_SHORT);
@@ -156,6 +157,7 @@
if (statsdDisabled()) {
return;
}
+ if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return;
// Setup, unplug device.
unplugDevice();
Thread.sleep(WAIT_TIME_SHORT);
@@ -208,6 +210,7 @@
if (statsdDisabled()) {
return;
}
+ if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return;
// Setup, set battery level to full.
setBatteryLevel(100);
Thread.sleep(WAIT_TIME_SHORT);
@@ -294,6 +297,7 @@
if (statsdDisabled()) {
return;
}
+ if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return;
// Setup, turn off battery saver.
turnBatterySaverOff();
Thread.sleep(WAIT_TIME_SHORT);
@@ -331,6 +335,7 @@
return;
}
if (!hasFeature(FEATURE_WATCH, false)) return;
+ if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return;
StatsdConfig.Builder config = getPulledConfig();
addGaugeAtomWithDimensions(config, Atom.REMAINING_BATTERY_CAPACITY_FIELD_NUMBER, null);
@@ -354,6 +359,7 @@
return;
}
if (!hasFeature(FEATURE_WATCH, false)) return;
+ if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return;
StatsdConfig.Builder config = getPulledConfig();
addGaugeAtomWithDimensions(config, Atom.FULL_BATTERY_CAPACITY_FIELD_NUMBER, null);
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
index cdb023f..9fb74f1 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
@@ -806,6 +806,9 @@
if (statsdDisabled()) {
return;
}
+ // For automotive, all wakeup alarm becomes normal alarm. So this
+ // test does not work.
+ if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return;
final int atomTag = Atom.WAKEUP_ALARM_OCCURRED_FIELD_NUMBER;
StatsdConfig.Builder config = createConfigBuilder();
diff --git a/hostsidetests/statsd/src/android/cts/statsd/validation/ValidationTests.java b/hostsidetests/statsd/src/android/cts/statsd/validation/ValidationTests.java
index ff4fc66..6c5de5a 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/validation/ValidationTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/validation/ValidationTests.java
@@ -60,6 +60,7 @@
public class ValidationTests extends DeviceAtomTestCase {
private static final String TAG = "Statsd.ValidationTests";
+ private static final String FEATURE_AUTOMOTIVE = "android.hardware.type.automotive";
private static final boolean ENABLE_LOAD_TEST = false;
@Override
@@ -78,6 +79,7 @@
if (statsdDisabled()) {
return;
}
+ if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return;
resetBatteryStats();
unplugDevice();
// AoD needs to be turned off because the screen should go into an off state. But, if AoD is
@@ -143,6 +145,7 @@
if (statsdDisabled()) {
return;
}
+ if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return;
turnScreenOn(); // To ensure that the ScreenOff later gets logged.
// AoD needs to be turned off because the screen should go into an off state. But, if AoD is
// on and the device doesn't support STATE_DOZE, the screen sadly goes back to STATE_ON.
diff --git a/hostsidetests/systemui/OWNERS b/hostsidetests/systemui/OWNERS
new file mode 100644
index 0000000..7e823ba
--- /dev/null
+++ b/hostsidetests/systemui/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 136515
+kozynski@google.com
+dsandler@android.com
+ashaikh@google.com
diff --git a/hostsidetests/usage/OWNERS b/hostsidetests/usage/OWNERS
new file mode 100644
index 0000000..e3ccf65
--- /dev/null
+++ b/hostsidetests/usage/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 532296
+mwachens@google.com
+yamasani@google.com
diff --git a/hostsidetests/wifibroadcasts/AndroidTest.xml b/hostsidetests/wifibroadcasts/AndroidTest.xml
index caa1d29..b9a0e59 100644
--- a/hostsidetests/wifibroadcasts/AndroidTest.xml
+++ b/hostsidetests/wifibroadcasts/AndroidTest.xml
@@ -23,4 +23,6 @@
<test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
<option name="jar" value="CtsWifiBroadcastsHostTestCases.jar" />
</test>
+ <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
</configuration>
diff --git a/tests/AlarmManager/OWNERS b/tests/AlarmManager/OWNERS
new file mode 100644
index 0000000..6c7a651
--- /dev/null
+++ b/tests/AlarmManager/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 533273
+suprabh@google.com
+ctate@google.com
diff --git a/tests/AlarmManager/src/android/alarmmanager/cts/UidCapTests.java b/tests/AlarmManager/src/android/alarmmanager/cts/UidCapTests.java
new file mode 100644
index 0000000..cd234b9
--- /dev/null
+++ b/tests/AlarmManager/src/android/alarmmanager/cts/UidCapTests.java
@@ -0,0 +1,122 @@
+/*
+ * 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.alarmmanager.cts;
+
+import static org.junit.Assert.fail;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.platform.test.annotations.AppModeFull;
+import android.util.Log;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.compatibility.common.util.SystemUtil;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+
+@AppModeFull
+@RunWith(AndroidJUnit4.class)
+public class UidCapTests {
+ private static final String TAG = UidCapTests.class.getSimpleName();
+ private static final String ACTION_PREFIX = "android.alarmmanager.cts.action.ALARM_";
+
+ private static final int SUFFICIENT_NUM_ALARMS = 450;
+ private static final int[] ALARM_TYPES = {
+ AlarmManager.RTC_WAKEUP,
+ AlarmManager.RTC,
+ AlarmManager.ELAPSED_REALTIME_WAKEUP,
+ AlarmManager.ELAPSED_REALTIME
+ };
+
+ private AlarmManager mAlarmManager;
+ private Context mContext;
+ private ArrayList<PendingIntent> mAlarmsSet = new ArrayList<>();
+
+ @Before
+ public void setUp() {
+ mContext = InstrumentationRegistry.getTargetContext();
+ mAlarmManager = mContext.getSystemService(AlarmManager.class);
+ }
+
+ @Test
+ public void sufficientAlarmsAllowedByDefault() {
+ deleteAlarmManagerConstants();
+ for (int i = 1; i <= SUFFICIENT_NUM_ALARMS; i++) {
+ try {
+ final PendingIntent pi = PendingIntent.getBroadcast(mContext, 0,
+ new Intent(ACTION_PREFIX + i), 0);
+ mAlarmManager.set(ALARM_TYPES[i % 4], Long.MAX_VALUE, pi);
+ mAlarmsSet.add(pi);
+ } catch (Exception e) {
+ Log.e(TAG, "Could not set the " + i + "th alarm", e);
+ fail("Caught exception [" + e.getMessage() + "] while setting " + i + "th alarm");
+ }
+ }
+ }
+
+ @Test
+ public void alarmsCannotExceedLimit() {
+ final int limit = 598;
+ setMaxAlarmsPerUid(limit);
+ for (int i = 0; i < limit; i++) {
+ final PendingIntent pi = PendingIntent.getBroadcast(mContext, 0,
+ new Intent(ACTION_PREFIX + i), 0);
+ mAlarmManager.set(ALARM_TYPES[i % 4], Long.MAX_VALUE, pi);
+ mAlarmsSet.add(pi);
+ }
+
+ final PendingIntent lastPi = PendingIntent.getBroadcast(mContext, 0,
+ new Intent(ACTION_PREFIX + limit), 0);
+ for (int type : ALARM_TYPES) {
+ try {
+ mAlarmManager.set(type, Long.MAX_VALUE, lastPi);
+ mAlarmsSet.add(lastPi);
+ fail("Able to set an alarm of type " + type + " after reaching the limit of "
+ + limit);
+ } catch (UnsupportedOperationException e) {
+ }
+ }
+ }
+
+ private void setMaxAlarmsPerUid(int maxAlarmsPerUid) {
+ SystemUtil.runShellCommand("settings put global alarm_manager_constants max_alarms_per_uid="
+ + maxAlarmsPerUid);
+ }
+
+ @After
+ public void cancelAlarms() {
+ for (PendingIntent pi : mAlarmsSet) {
+ mAlarmManager.cancel(pi);
+ }
+ mAlarmsSet.clear();
+ }
+
+ @After
+ public void deleteAlarmManagerConstants() {
+ SystemUtil.runShellCommand("settings delete global alarm_manager_constants");
+ }
+}
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/ConnectivityConstraintTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/ConnectivityConstraintTest.java
index 81ca4f9..daf7b31 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/ConnectivityConstraintTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/ConnectivityConstraintTest.java
@@ -66,6 +66,8 @@
private JobInfo.Builder mBuilder;
+ private TestAppInterface mTestAppInterface;
+
@Override
public void setUp() throws Exception {
super.setUp();
@@ -88,17 +90,20 @@
@Override
public void tearDown() throws Exception {
+ if (mTestAppInterface != null) {
+ mTestAppInterface.cleanup();
+ }
mJobScheduler.cancel(CONNECTIVITY_JOB_ID);
// Restore initial restrict background data usage policy
- if (mInitialRestrictBackground) {
- SystemUtil.runShellCommand(getInstrumentation(), RESTRICT_BACKGROUND_ON_CMD);
- }
+ setDataSaverEnabled(mInitialRestrictBackground);
// Ensure that we leave WiFi in its previous state.
if (mWifiManager.isWifiEnabled() != mInitialWiFiState) {
setWifiState(mInitialWiFiState, mContext, mCm, mWifiManager);
}
+
+ super.tearDown();
}
// --------------------------------------------------------------------------------------------
@@ -149,6 +154,29 @@
}
/**
+ * Schedule a job with a generic connectivity constraint, and ensure that it executes on WiFi,
+ * even with Data Saver on.
+ */
+ public void testConnectivityConstraintExecutes_withWifi_DataSaverOn() throws Exception {
+ if (!mHasWifi) {
+ Log.d(TAG, "Skipping test that requires the device be WiFi enabled.");
+ return;
+ }
+ connectToWifi();
+ setDataSaverEnabled(true);
+
+ kTestEnvironment.setExpectedExecutions(1);
+ mJobScheduler.schedule(
+ mBuilder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
+ .build());
+
+ sendExpediteStableChargingBroadcast();
+
+ assertTrue("Job with connectivity constraint did not fire on WiFi.",
+ kTestEnvironment.awaitExecution());
+ }
+
+ /**
* Schedule a job with a generic connectivity constraint, and ensure that it executes
* on a cellular data connection.
*/
@@ -170,6 +198,38 @@
}
/**
+ * Schedule a job with a generic connectivity constraint, and ensure that it isn't stopped when
+ * the device transitions to WiFi.
+ */
+ public void testConnectivityConstraintExecutes_transitionNetworks() throws Exception {
+ if (!mHasWifi) {
+ Log.d(TAG, "Skipping test that requires the device be WiFi enabled.");
+ return;
+ }
+ if (!checkDeviceSupportsMobileData()) {
+ return;
+ }
+ setDataSaverEnabled(false);
+ disconnectWifiToConnectToMobile();
+
+ kTestEnvironment.setExpectedExecutions(1);
+ kTestEnvironment.setExpectedStopped();
+ mJobScheduler.schedule(
+ mBuilder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
+ .build());
+
+ sendExpediteStableChargingBroadcast();
+
+ assertTrue("Job with connectivity constraint did not fire on mobile.",
+ kTestEnvironment.awaitExecution());
+
+ connectToWifi();
+ assertFalse(
+ "Job with connectivity constraint was stopped when network transitioned to WiFi.",
+ kTestEnvironment.awaitStopped());
+ }
+
+ /**
* Schedule a job with a metered connectivity constraint, and ensure that it executes
* on a mobile data connection.
*/
@@ -177,7 +237,7 @@
if (!checkDeviceSupportsMobileData()) {
return;
}
- ensureRestrictBackgroundPolicyOff();
+ setDataSaverEnabled(false);
disconnectWifiToConnectToMobile();
kTestEnvironment.setExpectedExecutions(1);
@@ -190,6 +250,67 @@
kTestEnvironment.awaitExecution());
}
+ /**
+ * Schedule a job with a cellular connectivity constraint, and ensure that it executes
+ * on a mobile data connection and is not stopped when Data Saver is turned on because the app
+ * is in the foreground.
+ */
+ public void testCellularConstraintExecutedAndStopped_Foreground() throws Exception {
+ if (!checkDeviceSupportsMobileData()) {
+ return;
+ }
+ setDataSaverEnabled(false);
+ disconnectWifiToConnectToMobile();
+ mTestAppInterface = new TestAppInterface(mContext, CONNECTIVITY_JOB_ID);
+ mTestAppInterface.startAndKeepTestActivity();
+
+ mTestAppInterface.scheduleJob(false, true);
+
+ sendExpediteStableChargingBroadcast();
+ assertTrue("Job with metered connectivity constraint did not fire on mobile.",
+ mTestAppInterface.awaitJobStart(30_000));
+
+ setDataSaverEnabled(true);
+ assertFalse(
+ "Job with metered connectivity constraint for foreground app was stopped when"
+ + " Data Saver was turned on.",
+ mTestAppInterface.awaitJobStop(30_000));
+ }
+
+ // --------------------------------------------------------------------------------------------
+ // Positives & Negatives - schedule jobs under conditions that require that pass initially and
+ // then fail with a constraint change.
+ // --------------------------------------------------------------------------------------------
+
+ /**
+ * Schedule a job with a cellular connectivity constraint, and ensure that it executes
+ * on a mobile data connection and is stopped when Data Saver is turned on.
+ */
+ public void testCellularConstraintExecutedAndStopped() throws Exception {
+ if (!checkDeviceSupportsMobileData()) {
+ return;
+ }
+ setDataSaverEnabled(false);
+ disconnectWifiToConnectToMobile();
+
+ kTestEnvironment.setExpectedExecutions(1);
+ kTestEnvironment.setContinueAfterStart();
+ kTestEnvironment.setExpectedStopped();
+ mJobScheduler.schedule(
+ mBuilder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_CELLULAR)
+ .build());
+
+ sendExpediteStableChargingBroadcast();
+ assertTrue("Job with metered connectivity constraint did not fire on mobile.",
+ kTestEnvironment.awaitExecution());
+
+ setDataSaverEnabled(true);
+ assertTrue(
+ "Job with metered connectivity constraint was not stopped when Data Saver was "
+ + "turned on.",
+ kTestEnvironment.awaitStopped());
+ }
+
// --------------------------------------------------------------------------------------------
// Negatives - schedule jobs under conditions that require that they fail.
// --------------------------------------------------------------------------------------------
@@ -218,6 +339,28 @@
/**
* Schedule a job that requires a metered connection, and verify that it does not run when
+ * the device is not connected to WiFi and Data Saver is on.
+ */
+ public void testMeteredConstraintFails_withMobile_DataSaverOn() throws Exception {
+ if (!checkDeviceSupportsMobileData()) {
+ Log.d(TAG, "Skipping test that requires the device be mobile data enabled.");
+ return;
+ }
+ disconnectWifiToConnectToMobile();
+ setDataSaverEnabled(true);
+
+ kTestEnvironment.setExpectedExecutions(0);
+ mJobScheduler.schedule(
+ mBuilder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_CELLULAR)
+ .build());
+ sendExpediteStableChargingBroadcast();
+
+ assertTrue("Job requiring metered connectivity still executed on WiFi.",
+ kTestEnvironment.awaitTimeout());
+ }
+
+ /**
+ * Schedule a job that requires a metered connection, and verify that it does not run when
* the device is connected to a WiFi provider.
* This test assumes that if the device supports a mobile data connection, then this connection
* will be available.
@@ -340,10 +483,9 @@
* Ensures that restrict background data usage policy is turned off.
* If the policy is on, it interferes with tests that relies on metered connection.
*/
- private void ensureRestrictBackgroundPolicyOff() throws Exception {
- if (mInitialRestrictBackground) {
- SystemUtil.runShellCommand(getInstrumentation(), RESTRICT_BACKGROUND_OFF_CMD);
- }
+ private void setDataSaverEnabled(boolean enabled) throws Exception {
+ SystemUtil.runShellCommand(getInstrumentation(),
+ enabled ? RESTRICT_BACKGROUND_ON_CMD : RESTRICT_BACKGROUND_OFF_CMD);
}
/** Capture the last connectivity change's network type and state. */
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/ConstraintTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/ConstraintTest.java
index 7b8bf4b..4cee13c 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/ConstraintTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/ConstraintTest.java
@@ -117,6 +117,9 @@
SystemUtil.runShellCommand(getInstrumentation(), "cmd devicestoragemonitor reset");
mStorageStateChanged = false;
}
+
+ // The super method should be called at the end.
+ super.tearDown();
}
/**
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java
index 8d9edfc..17bf0cc 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java
@@ -17,9 +17,7 @@
package android.jobscheduler.cts;
import static android.jobscheduler.cts.ConnectivityConstraintTest.setWifiState;
-import static android.jobscheduler.cts.jobtestapp.TestJobService.ACTION_JOB_STARTED;
-import static android.jobscheduler.cts.jobtestapp.TestJobService.ACTION_JOB_STOPPED;
-import static android.jobscheduler.cts.jobtestapp.TestJobService.JOB_PARAMS_EXTRA_KEY;
+import static android.jobscheduler.cts.TestAppInterface.TEST_APP_PACKAGE;
import static android.os.PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED;
import static android.os.PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED;
@@ -28,14 +26,11 @@
import static org.junit.Assume.assumeTrue;
import android.app.AppOpsManager;
-import android.app.job.JobParameters;
import android.content.BroadcastReceiver;
-import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
-import android.jobscheduler.cts.jobtestapp.TestActivity;
import android.jobscheduler.cts.jobtestapp.TestJobSchedulerReceiver;
import android.net.ConnectivityManager;
import android.net.wifi.WifiManager;
@@ -66,9 +61,6 @@
@LargeTest
public class JobThrottlingTest {
private static final String TAG = JobThrottlingTest.class.getSimpleName();
- private static final String TEST_APP_PACKAGE = "android.jobscheduler.cts.jobtestapp";
- private static final String TEST_APP_RECEIVER = TEST_APP_PACKAGE + ".TestJobSchedulerReceiver";
- private static final String TEST_APP_ACTIVITY = TEST_APP_PACKAGE + ".TestActivity";
private static final long BACKGROUND_JOBS_EXPECTED_DELAY = 3_000;
private static final long POLL_INTERVAL = 500;
private static final long DEFAULT_WAIT_TIMEOUT = 1000;
@@ -85,7 +77,6 @@
private Context mContext;
private UiDevice mUiDevice;
private PowerManager mPowerManager;
- private int mTestJobId;
private int mTestPackageUid;
private boolean mDeviceInDoze;
private boolean mDeviceIdleEnabled;
@@ -97,22 +88,13 @@
/** Track whether WiFi was enabled in case we turn it off. */
private boolean mInitialWiFiState;
- /* accesses must be synchronized on itself */
- private final TestJobStatus mTestJobStatus = new TestJobStatus();
+ private TestAppInterface mTestAppInterface;
+
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "Received action " + intent.getAction());
switch (intent.getAction()) {
- case ACTION_JOB_STARTED:
- case ACTION_JOB_STOPPED:
- final JobParameters params = intent.getParcelableExtra(JOB_PARAMS_EXTRA_KEY);
- Log.d(TAG, "JobId: " + params.getJobId());
- synchronized (mTestJobStatus) {
- mTestJobStatus.running = ACTION_JOB_STARTED.equals(intent.getAction());
- mTestJobStatus.jobId = params.getJobId();
- }
- break;
case ACTION_DEVICE_IDLE_MODE_CHANGED:
case ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED:
synchronized (JobThrottlingTest.this) {
@@ -136,11 +118,9 @@
mPowerManager = mContext.getSystemService(PowerManager.class);
mDeviceInDoze = mPowerManager.isDeviceIdleMode();
mTestPackageUid = mContext.getPackageManager().getPackageUid(TEST_APP_PACKAGE, 0);
- mTestJobId = (int) (SystemClock.uptimeMillis() / 1000);
- mTestJobStatus.reset();
+ int testJobId = (int) (SystemClock.uptimeMillis() / 1000);
+ mTestAppInterface = new TestAppInterface(mContext, testJobId);
final IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction(ACTION_JOB_STARTED);
- intentFilter.addAction(ACTION_JOB_STOPPED);
intentFilter.addAction(ACTION_DEVICE_IDLE_MODE_CHANGED);
intentFilter.addAction(ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED);
mContext.registerReceiver(mReceiver, intentFilter);
@@ -166,10 +146,11 @@
toggleDeviceIdleState(true);
Thread.sleep(DEFAULT_WAIT_TIMEOUT);
sendScheduleJobBroadcast(true);
- assertFalse("Job started without being tempwhitelisted", awaitJobStart(5_000));
+ assertFalse("Job started without being tempwhitelisted",
+ mTestAppInterface.awaitJobStart(5_000));
tempWhitelistTestApp(5_000);
assertTrue("Job with allow_while_idle flag did not start when the app was tempwhitelisted",
- awaitJobStart(5_000));
+ mTestAppInterface.awaitJobStart(5_000));
}
@Test
@@ -177,14 +158,16 @@
assumeTrue("device idle not enabled", mDeviceIdleEnabled);
sendScheduleJobBroadcast(false);
- assertTrue("Job did not start after scheduling", awaitJobStart(DEFAULT_WAIT_TIMEOUT));
+ assertTrue("Job did not start after scheduling",
+ mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT));
toggleDeviceIdleState(true);
- assertTrue("Job did not stop on entering doze", awaitJobStop(DEFAULT_WAIT_TIMEOUT));
+ assertTrue("Job did not stop on entering doze",
+ mTestAppInterface.awaitJobStop(DEFAULT_WAIT_TIMEOUT));
Thread.sleep(TestJobSchedulerReceiver.JOB_INITIAL_BACKOFF);
- startAndKeepTestActivity();
+ mTestAppInterface.startAndKeepTestActivity();
toggleDeviceIdleState(false);
assertTrue("Job for foreground app did not start immediately when device exited doze",
- awaitJobStart(3_000));
+ mTestAppInterface.awaitJobStart(3_000));
}
@Test
@@ -192,45 +175,51 @@
assumeTrue("device idle not enabled", mDeviceIdleEnabled);
sendScheduleJobBroadcast(false);
- assertTrue("Job did not start after scheduling", awaitJobStart(DEFAULT_WAIT_TIMEOUT));
+ assertTrue("Job did not start after scheduling",
+ mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT));
toggleDeviceIdleState(true);
- assertTrue("Job did not stop on entering doze", awaitJobStop(DEFAULT_WAIT_TIMEOUT));
+ assertTrue("Job did not stop on entering doze",
+ mTestAppInterface.awaitJobStop(DEFAULT_WAIT_TIMEOUT));
Thread.sleep(TestJobSchedulerReceiver.JOB_INITIAL_BACKOFF);
toggleDeviceIdleState(false);
assertFalse("Job for background app started immediately when device exited doze",
- awaitJobStart(DEFAULT_WAIT_TIMEOUT));
+ mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT));
Thread.sleep(BACKGROUND_JOBS_EXPECTED_DELAY - DEFAULT_WAIT_TIMEOUT);
assertTrue("Job for background app did not start after the expected delay of "
- + BACKGROUND_JOBS_EXPECTED_DELAY + "ms", awaitJobStart(DEFAULT_WAIT_TIMEOUT));
+ + BACKGROUND_JOBS_EXPECTED_DELAY + "ms",
+ mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT));
}
@Test
public void testJobStoppedWhenRestricted() throws Exception {
sendScheduleJobBroadcast(false);
- assertTrue("Job did not start after scheduling", awaitJobStart(DEFAULT_WAIT_TIMEOUT));
+ assertTrue("Job did not start after scheduling",
+ mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT));
setTestPackageRestricted(true);
assertTrue("Job did not stop after test app was restricted",
- awaitJobStop(DEFAULT_WAIT_TIMEOUT));
+ mTestAppInterface.awaitJobStop(DEFAULT_WAIT_TIMEOUT));
}
@Test
public void testRestrictedJobStartedWhenUnrestricted() throws Exception {
setTestPackageRestricted(true);
sendScheduleJobBroadcast(false);
- assertFalse("Job started for restricted app", awaitJobStart(DEFAULT_WAIT_TIMEOUT));
+ assertFalse("Job started for restricted app",
+ mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT));
setTestPackageRestricted(false);
assertTrue("Job did not start when app was unrestricted",
- awaitJobStart(DEFAULT_WAIT_TIMEOUT));
+ mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT));
}
@Test
public void testRestrictedJobAllowedWhenUidActive() throws Exception {
setTestPackageRestricted(true);
sendScheduleJobBroadcast(false);
- assertFalse("Job started for restricted app", awaitJobStart(DEFAULT_WAIT_TIMEOUT));
- startAndKeepTestActivity();
+ assertFalse("Job started for restricted app",
+ mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT));
+ mTestAppInterface.startAndKeepTestActivity();
assertTrue("Job did not start when app had an activity",
- awaitJobStart(DEFAULT_WAIT_TIMEOUT));
+ mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT));
}
@Test
@@ -241,13 +230,16 @@
}
setWifiState(true, mContext, mCm, mWifiManager);
assumeTrue("device idle not enabled", mDeviceIdleEnabled);
- sendScheduleJobBroadcast(false, true);
- assertTrue("Job did not start after scheduling", awaitJobStart(DEFAULT_WAIT_TIMEOUT));
+ mTestAppInterface.scheduleJob(false, true);
+ assertTrue("Job did not start after scheduling",
+ mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT));
ThermalUtils.overrideThermalStatus(Temperature.THROTTLING_CRITICAL);
- assertTrue("Job did not stop on thermal throttling", awaitJobStop(DEFAULT_WAIT_TIMEOUT));
+ assertTrue("Job did not stop on thermal throttling",
+ mTestAppInterface.awaitJobStop(DEFAULT_WAIT_TIMEOUT));
Thread.sleep(TestJobSchedulerReceiver.JOB_INITIAL_BACKOFF);
ThermalUtils.overrideThermalNotThrottling();
- assertTrue("Job did not start back from throttling", awaitJobStart(DEFAULT_WAIT_TIMEOUT));
+ assertTrue("Job did not start back from throttling",
+ mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT));
}
@Test
@@ -258,7 +250,7 @@
setTestPackageStandbyBucket(Bucket.NEVER);
Thread.sleep(DEFAULT_WAIT_TIMEOUT);
sendScheduleJobBroadcast(false);
- assertFalse("New job started in NEVER standby", awaitJobStart(3_000));
+ assertFalse("New job started in NEVER standby", mTestAppInterface.awaitJobStart(3_000));
}
@Test
@@ -269,7 +261,7 @@
Thread.sleep(DEFAULT_WAIT_TIMEOUT);
sendScheduleJobBroadcast(false);
assertTrue("New job in uid-active app failed to start in NEVER standby",
- awaitJobStart(4_000));
+ mTestAppInterface.awaitJobStart(4_000));
}
@Test
@@ -279,7 +271,8 @@
BatteryUtils.runDumpsysBatteryUnplug();
BatteryUtils.enableBatterySaver(false);
sendScheduleJobBroadcast(false);
- assertTrue("New job failed to start with battery saver OFF", awaitJobStart(3_000));
+ assertTrue("New job failed to start with battery saver OFF",
+ mTestAppInterface.awaitJobStart(3_000));
}
@Test
@@ -289,7 +282,8 @@
BatteryUtils.runDumpsysBatteryUnplug();
BatteryUtils.enableBatterySaver(true);
sendScheduleJobBroadcast(false);
- assertFalse("New job started with battery saver ON", awaitJobStart(3_000));
+ assertFalse("New job started with battery saver ON",
+ mTestAppInterface.awaitJobStart(3_000));
}
@Test
@@ -301,7 +295,7 @@
tempWhitelistTestApp(6_000);
sendScheduleJobBroadcast(false);
assertTrue("New job in uid-active app failed to start with battery saver OFF",
- awaitJobStart(3_000));
+ mTestAppInterface.awaitJobStart(3_000));
}
@Test
@@ -312,13 +306,14 @@
BatteryUtils.runDumpsysBatteryUnplug();
BatteryUtils.enableBatterySaver(true);
sendScheduleJobBroadcast(false);
- assertFalse("New job started with battery saver ON", awaitJobStart(3_000));
+ assertFalse("New job started with battery saver ON",
+ mTestAppInterface.awaitJobStart(3_000));
// Then make the UID active. Now the job should run.
tempWhitelistTestApp(120_000);
assertTrue("New job in uid-active app failed to start with battery saver OFF",
- awaitJobStart(120_000));
+ mTestAppInterface.awaitJobStart(120_000));
}
@After
@@ -329,12 +324,7 @@
if (mDeviceIdleEnabled) {
toggleDeviceIdleState(false);
}
- final Intent cancelJobsIntent = new Intent(TestJobSchedulerReceiver.ACTION_CANCEL_JOBS);
- cancelJobsIntent.setComponent(new ComponentName(TEST_APP_PACKAGE, TEST_APP_RECEIVER));
- cancelJobsIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- mContext.sendBroadcast(cancelJobsIntent);
- mContext.sendBroadcast(new Intent(TestActivity.ACTION_FINISH_ACTIVITY));
- mContext.unregisterReceiver(mReceiver);
+ mTestAppInterface.cleanup();
BatteryUtils.runDumpsysBatteryReset();
removeTestAppFromTempWhitelist();
@@ -359,26 +349,8 @@
return false;
}
- private void startAndKeepTestActivity() {
- final Intent testActivity = new Intent();
- testActivity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- testActivity.setComponent(new ComponentName(TEST_APP_PACKAGE, TEST_APP_ACTIVITY));
- mContext.startActivity(testActivity);
- }
-
- private void sendScheduleJobBroadcast(boolean allowWhileIdle, boolean needNetwork)
- throws Exception {
- final Intent scheduleJobIntent = new Intent(TestJobSchedulerReceiver.ACTION_SCHEDULE_JOB);
- scheduleJobIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
- scheduleJobIntent.putExtra(TestJobSchedulerReceiver.EXTRA_JOB_ID_KEY, mTestJobId);
- scheduleJobIntent.putExtra(TestJobSchedulerReceiver.EXTRA_ALLOW_IN_IDLE, allowWhileIdle);
- scheduleJobIntent.putExtra(TestJobSchedulerReceiver.EXTRA_REQUIRE_NETWORK_ANY, needNetwork);
- scheduleJobIntent.setComponent(new ComponentName(TEST_APP_PACKAGE, TEST_APP_RECEIVER));
- mContext.sendBroadcast(scheduleJobIntent);
- }
-
private void sendScheduleJobBroadcast(boolean allowWhileIdle) throws Exception {
- sendScheduleJobBroadcast(allowWhileIdle, false);
+ mTestAppInterface.scheduleJob(allowWhileIdle, false);
}
private void toggleDeviceIdleState(final boolean idle) throws Exception {
@@ -430,22 +402,6 @@
return waitUntilTrue(SHELL_TIMEOUT, () -> !isTestAppTempWhitelisted());
}
- private boolean awaitJobStart(long maxWait) throws Exception {
- return waitUntilTrue(maxWait, () -> {
- synchronized (mTestJobStatus) {
- return (mTestJobStatus.jobId == mTestJobId) && mTestJobStatus.running;
- }
- });
- }
-
- private boolean awaitJobStop(long maxWait) throws Exception {
- return waitUntilTrue(maxWait, () -> {
- synchronized (mTestJobStatus) {
- return (mTestJobStatus.jobId == mTestJobId) && !mTestJobStatus.running;
- }
- });
- }
-
private boolean waitUntilTrue(long maxWait, Condition condition) throws Exception {
final long deadLine = SystemClock.uptimeMillis() + maxWait;
do {
@@ -454,15 +410,6 @@
return condition.isTrue();
}
- private static final class TestJobStatus {
- int jobId;
- boolean running;
-
- private void reset() {
- running = false;
- }
- }
-
private interface Condition {
boolean isTrue() throws Exception;
}
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/TestAppInterface.java b/tests/JobScheduler/src/android/jobscheduler/cts/TestAppInterface.java
new file mode 100644
index 0000000..36d1825
--- /dev/null
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/TestAppInterface.java
@@ -0,0 +1,140 @@
+/*
+ * 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.jobscheduler.cts;
+
+import static android.jobscheduler.cts.jobtestapp.TestJobService.ACTION_JOB_STARTED;
+import static android.jobscheduler.cts.jobtestapp.TestJobService.ACTION_JOB_STOPPED;
+import static android.jobscheduler.cts.jobtestapp.TestJobService.JOB_PARAMS_EXTRA_KEY;
+
+import android.app.job.JobParameters;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.jobscheduler.cts.jobtestapp.TestActivity;
+import android.jobscheduler.cts.jobtestapp.TestJobSchedulerReceiver;
+import android.os.SystemClock;
+import android.util.Log;
+
+/**
+ * Common functions to interact with the test app.
+ */
+class TestAppInterface {
+ private static final String TAG = TestAppInterface.class.getSimpleName();
+
+ static final String TEST_APP_PACKAGE = "android.jobscheduler.cts.jobtestapp";
+ private static final String TEST_APP_ACTIVITY = TEST_APP_PACKAGE + ".TestActivity";
+ static final String TEST_APP_RECEIVER = TEST_APP_PACKAGE + ".TestJobSchedulerReceiver";
+
+ private final Context mContext;
+ private final int mJobId;
+
+ /* accesses must be synchronized on itself */
+ private final TestJobStatus mTestJobStatus = new TestJobStatus();
+
+ TestAppInterface(Context ctx, int jobId) {
+ mContext = ctx;
+ mJobId = jobId;
+
+ final IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(ACTION_JOB_STARTED);
+ intentFilter.addAction(ACTION_JOB_STOPPED);
+ mContext.registerReceiver(mReceiver, intentFilter);
+ }
+
+ void cleanup() {
+ final Intent cancelJobsIntent = new Intent(TestJobSchedulerReceiver.ACTION_CANCEL_JOBS);
+ cancelJobsIntent.setComponent(new ComponentName(TEST_APP_PACKAGE, TEST_APP_RECEIVER));
+ cancelJobsIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.sendBroadcast(cancelJobsIntent);
+ mContext.sendBroadcast(new Intent(TestActivity.ACTION_FINISH_ACTIVITY));
+ mContext.unregisterReceiver(mReceiver);
+ mTestJobStatus.reset();
+ }
+
+ void scheduleJob(boolean allowWhileIdle, boolean needNetwork) {
+ final Intent scheduleJobIntent = new Intent(TestJobSchedulerReceiver.ACTION_SCHEDULE_JOB);
+ scheduleJobIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+ scheduleJobIntent.putExtra(TestJobSchedulerReceiver.EXTRA_JOB_ID_KEY, mJobId);
+ scheduleJobIntent.putExtra(TestJobSchedulerReceiver.EXTRA_ALLOW_IN_IDLE, allowWhileIdle);
+ scheduleJobIntent.putExtra(TestJobSchedulerReceiver.EXTRA_REQUIRE_NETWORK_ANY, needNetwork);
+ scheduleJobIntent.setComponent(new ComponentName(TEST_APP_PACKAGE, TEST_APP_RECEIVER));
+ mContext.sendBroadcast(scheduleJobIntent);
+ }
+
+ void startAndKeepTestActivity() {
+ final Intent testActivity = new Intent();
+ testActivity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ testActivity.setComponent(new ComponentName(TEST_APP_PACKAGE, TEST_APP_ACTIVITY));
+ mContext.startActivity(testActivity);
+ }
+
+ private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Log.d(TAG, "Received action " + intent.getAction());
+ switch (intent.getAction()) {
+ case ACTION_JOB_STARTED:
+ case ACTION_JOB_STOPPED:
+ final JobParameters params = intent.getParcelableExtra(JOB_PARAMS_EXTRA_KEY);
+ Log.d(TAG, "JobId: " + params.getJobId());
+ synchronized (mTestJobStatus) {
+ mTestJobStatus.running = ACTION_JOB_STARTED.equals(intent.getAction());
+ mTestJobStatus.jobId = params.getJobId();
+ }
+ break;
+ }
+ }
+ };
+
+ boolean awaitJobStart(long maxWait) throws Exception {
+ return waitUntilTrue(maxWait, () -> {
+ synchronized (mTestJobStatus) {
+ return (mTestJobStatus.jobId == mJobId) && mTestJobStatus.running;
+ }
+ });
+ }
+
+ boolean awaitJobStop(long maxWait) throws Exception {
+ return waitUntilTrue(maxWait, () -> {
+ synchronized (mTestJobStatus) {
+ return (mTestJobStatus.jobId == mJobId) && !mTestJobStatus.running;
+ }
+ });
+ }
+
+ private boolean waitUntilTrue(long maxWait, Condition condition) throws Exception {
+ final long deadLine = SystemClock.uptimeMillis() + maxWait;
+ do {
+ Thread.sleep(500);
+ } while (!condition.isTrue() && SystemClock.uptimeMillis() < deadLine);
+ return condition.isTrue();
+ }
+
+ private static final class TestJobStatus {
+ int jobId;
+ boolean running;
+
+ private void reset() {
+ running = false;
+ }
+ }
+
+ private interface Condition {
+ boolean isTrue() throws Exception;
+ }
+}
diff --git a/tests/app/AndroidTest.xml b/tests/app/AndroidTest.xml
index d52eac7..0224fdf 100644
--- a/tests/app/AndroidTest.xml
+++ b/tests/app/AndroidTest.xml
@@ -16,6 +16,8 @@
<configuration description="Config for CTS App test cases">
<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" />
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.LocationCheck" />
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
diff --git a/tests/app/app/AndroidManifest.xml b/tests/app/app/AndroidManifest.xml
index 9ef2f3d..8ee87e2 100644
--- a/tests/app/app/AndroidManifest.xml
+++ b/tests/app/app/AndroidManifest.xml
@@ -386,9 +386,9 @@
<intent-filter>
<action android:name="android.app.action.AUTOMATIC_ZEN_RULE" />
</intent-filter>
- <meta-data android:name="android.app.automatic.ruleType"
+ <meta-data android:name="android.service.zen.automatic.ruleType"
android:value="@string/automatic_zen_rule_name" />
- <meta-data android:name="android.app.zen.automatic.ruleInstanceLimit"
+ <meta-data android:name="android.service.zen.automatic.ruleInstanceLimit"
android:value="1" />
</activity>
diff --git a/tests/app/res/drawable/ic_android.xml b/tests/app/res/drawable/ic_android.xml
new file mode 100644
index 0000000..fbadd7d
--- /dev/null
+++ b/tests/app/res/drawable/ic_android.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * 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.
+ -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M6,18c0,0.55 0.45,1 1,1h1v3.5c0,0.83 0.67,1.5 1.5,1.5s1.5,-0.67 1.5,-1.5L11,19h2v3.5c0,0.83 0.67,1.5 1.5,1.5s1.5,-0.67 1.5,-1.5L16,19h1c0.55,0 1,-0.45 1,-1L18,8L6,8v10zM3.5,8C2.67,8 2,8.67 2,9.5v7c0,0.83 0.67,1.5 1.5,1.5S5,17.33 5,16.5v-7C5,8.67 4.33,8 3.5,8zM20.5,8c-0.83,0 -1.5,0.67 -1.5,1.5v7c0,0.83 0.67,1.5 1.5,1.5s1.5,-0.67 1.5,-1.5v-7c0,-0.83 -0.67,-1.5 -1.5,-1.5zM15.53,2.16l1.3,-1.3c0.2,-0.2 0.2,-0.51 0,-0.71 -0.2,-0.2 -0.51,-0.2 -0.71,0l-1.48,1.48C13.85,1.23 12.95,1 12,1c-0.96,0 -1.86,0.23 -2.66,0.63L7.85,0.15c-0.2,-0.2 -0.51,-0.2 -0.71,0 -0.2,0.2 -0.2,0.51 0,0.71l1.31,1.31C6.97,3.26 6,5.01 6,7h12c0,-1.99 -0.97,-3.75 -2.47,-4.84zM10,5L9,5L9,4h1v1zM15,5h-1L14,4h1v1z"/>
+</vector>
+
diff --git a/tests/app/src/android/app/cts/KeyguardManagerTest.java b/tests/app/src/android/app/cts/KeyguardManagerTest.java
index b476023..908a581 100644
--- a/tests/app/src/android/app/cts/KeyguardManagerTest.java
+++ b/tests/app/src/android/app/cts/KeyguardManagerTest.java
@@ -16,11 +16,16 @@
package android.app.cts;
+import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
+
import android.app.KeyguardManager;
import android.app.stubs.KeyguardManagerActivity;
import android.content.Context;
import android.test.ActivityInstrumentationTestCase2;
+import java.lang.reflect.Method;
+import java.util.concurrent.CountDownLatch;
+
public class KeyguardManagerTest
extends ActivityInstrumentationTestCase2<KeyguardManagerActivity> {
@@ -37,4 +42,22 @@
final KeyguardManager.KeyguardLock keyLock = keyguardManager.newKeyguardLock(TAG);
assertNotNull(keyLock);
}
+
+ public void testPrivateNotificationsAllowed() throws Exception {
+ Context c = getInstrumentation().getContext();
+ KeyguardManager keyguardManager = (KeyguardManager) c.getSystemService(
+ Context.KEYGUARD_SERVICE);
+ Method set = KeyguardManager.class.getMethod(
+ "setPrivateNotificationsAllowed", boolean.class);
+ Method get = KeyguardManager.class.getMethod("getPrivateNotificationsAllowed");
+ CountDownLatch signal = new CountDownLatch(1);
+ runWithShellPermissionIdentity(() -> {
+ set.invoke(keyguardManager, false);
+ assertFalse((boolean) get.invoke(keyguardManager));
+ set.invoke(keyguardManager, true);
+ assertTrue((boolean) get.invoke(keyguardManager));
+ signal.countDown();
+ }, "android.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS");
+ signal.await();
+ }
}
diff --git a/tests/app/src/android/app/cts/NotificationManagerTest.java b/tests/app/src/android/app/cts/NotificationManagerTest.java
index 0f7bd72..40d0675 100644
--- a/tests/app/src/android/app/cts/NotificationManagerTest.java
+++ b/tests/app/src/android/app/cts/NotificationManagerTest.java
@@ -1879,6 +1879,64 @@
mNotificationManager.notifyAsPackage(DELEGATOR, "tag", 0, n);
findPostedNotification(0);
+
+ final Intent revokeIntent = new Intent();
+ revokeIntent.setClassName(DELEGATOR, REVOKE_CLASS);
+ revokeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivity(revokeIntent);
+ Thread.sleep(1000);
+ }
+
+ public void testNotificationDelegate_grantAndReadChannels() throws Exception {
+ // grant this test permission to post
+ final Intent activityIntent = new Intent();
+ activityIntent.setPackage(DELEGATOR);
+ activityIntent.setAction(Intent.ACTION_MAIN);
+ activityIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+ activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+ // wait for the activity to launch and finish
+ mContext.startActivity(activityIntent);
+ Thread.sleep(500);
+
+ List<NotificationChannel> channels =
+ mContext.createPackageContextAsUser(DELEGATOR, /* flags= */ 0, mContext.getUser())
+ .getSystemService(NotificationManager.class)
+ .getNotificationChannels();
+
+ assertNotNull(channels);
+
+ final Intent revokeIntent = new Intent();
+ revokeIntent.setClassName(DELEGATOR, REVOKE_CLASS);
+ revokeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivity(revokeIntent);
+ Thread.sleep(500);
+ }
+
+ public void testNotificationDelegate_grantAndReadChannel() throws Exception {
+ // grant this test permission to post
+ final Intent activityIntent = new Intent();
+ activityIntent.setPackage(DELEGATOR);
+ activityIntent.setAction(Intent.ACTION_MAIN);
+ activityIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+ activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+ // wait for the activity to launch and finish
+ mContext.startActivity(activityIntent);
+ Thread.sleep(500);
+
+ NotificationChannel channel =
+ mContext.createPackageContextAsUser(DELEGATOR, /* flags= */ 0, mContext.getUser())
+ .getSystemService(NotificationManager.class)
+ .getNotificationChannel("channel");
+
+ assertNotNull(channel);
+
+ final Intent revokeIntent = new Intent();
+ revokeIntent.setClassName(DELEGATOR, REVOKE_CLASS);
+ revokeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivity(revokeIntent);
+ Thread.sleep(500);
}
public void testNotificationDelegate_grantAndRevoke() throws Exception {
@@ -1890,7 +1948,7 @@
activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(activityIntent);
- Thread.sleep(1000);
+ Thread.sleep(500);
assertTrue(mNotificationManager.canNotifyAsPackage(DELEGATOR));
@@ -1898,7 +1956,7 @@
revokeIntent.setClassName(DELEGATOR, REVOKE_CLASS);
revokeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(revokeIntent);
- Thread.sleep(1000);
+ Thread.sleep(500);
try {
// send notification
diff --git a/tests/app/src/android/app/cts/NotificationTest.java b/tests/app/src/android/app/cts/NotificationTest.java
index c340032..79a9fcd 100644
--- a/tests/app/src/android/app/cts/NotificationTest.java
+++ b/tests/app/src/android/app/cts/NotificationTest.java
@@ -16,6 +16,10 @@
package android.app.cts;
+import android.app.cts.R;
+import static android.graphics.drawable.Icon.TYPE_ADAPTIVE_BITMAP;
+import static android.graphics.drawable.Icon.TYPE_RESOURCE;
+
import android.app.Notification;
import android.app.Notification.Action.Builder;
import android.app.Notification.MessagingStyle;
@@ -27,6 +31,8 @@
import android.app.RemoteInput;
import android.content.Context;
import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
import android.graphics.drawable.Icon;
import android.net.Uri;
import android.os.Build;
@@ -57,6 +63,7 @@
private static final String URI_STRING = "uriString";
private static final String ACTION_TITLE = "actionTitle";
private static final int BUBBLE_HEIGHT = 300;
+ private static final int BUBBLE_HEIGHT_RESID = 31415;
private static final int TOLERANCE = 200;
private static final long TIMEOUT = 4000;
private static final NotificationChannel CHANNEL = new NotificationChannel("id", "name",
@@ -653,7 +660,23 @@
assertEquals(deleteIntent, metadata.getDeleteIntent());
assertTrue(metadata.getAutoExpandBubble());
assertTrue(metadata.getSuppressInitialNotification());
+ }
+ public void testBubbleMetadata_parcelResId() {
+ PendingIntent bubbleIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0);
+ Icon icon = Icon.createWithResource(mContext, 1);
+ Notification.BubbleMetadata metadata =
+ new Notification.BubbleMetadata.Builder()
+ .setDesiredHeightResId(BUBBLE_HEIGHT_RESID)
+ .setIcon(icon)
+ .setIntent(bubbleIntent)
+ .build();
+ writeAndReadParcelable(metadata);
+ assertEquals(BUBBLE_HEIGHT_RESID, metadata.getDesiredHeightResId());
+ assertEquals(icon, metadata.getIcon());
+ assertEquals(bubbleIntent, metadata.getIntent());
+ assertFalse(metadata.getAutoExpandBubble());
+ assertFalse(metadata.getSuppressInitialNotification());
}
public void testBubbleMetadataBuilder_throwForNoIntent() {
@@ -684,6 +707,89 @@
}
}
+ public void testBubbleMetadataBuilder_throwForBitmapIcon() {
+ Bitmap b = Bitmap.createBitmap(50, 25, Bitmap.Config.ARGB_8888);
+ new Canvas(b).drawColor(0xffff0000);
+ Icon icon = Icon.createWithBitmap(b);
+
+ PendingIntent bubbleIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0);
+ try {
+ Notification.BubbleMetadata.Builder metadataBuilder =
+ new Notification.BubbleMetadata.Builder()
+ .setIcon(icon)
+ .setIntent(bubbleIntent);
+ fail("Should have thrown IllegalArgumentException, invalid icon type (bitmap)");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ public void testBubbleMetadataBuilder_noThrowForAdaptiveBitmapIcon() {
+ Bitmap b = Bitmap.createBitmap(50, 25, Bitmap.Config.ARGB_8888);
+ new Canvas(b).drawColor(0xffff0000);
+ Icon icon = Icon.createWithAdaptiveBitmap(b);
+
+ PendingIntent bubbleIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0);
+ Notification.BubbleMetadata.Builder metadataBuilder =
+ new Notification.BubbleMetadata.Builder()
+ .setIcon(icon)
+ .setIntent(bubbleIntent);
+ Notification.BubbleMetadata metadata = metadataBuilder.build();
+ assertNotNull(metadata.getIcon());
+ assertEquals(TYPE_ADAPTIVE_BITMAP, metadata.getIcon().getType());
+ }
+
+ public void testBubbleMetadataBuilder_noThrowForNonBitmapIcon() {
+ Icon icon = Icon.createWithResource(mContext, R.drawable.ic_android);
+
+ PendingIntent bubbleIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0);
+ Notification.BubbleMetadata.Builder metadataBuilder =
+ new Notification.BubbleMetadata.Builder()
+ .setIcon(icon)
+ .setIntent(bubbleIntent);
+ Notification.BubbleMetadata metadata = metadataBuilder.build();
+ assertNotNull(metadata.getIcon());
+ assertEquals(TYPE_RESOURCE, metadata.getIcon().getType());
+ }
+
+ public void testBubbleMetadataBuilder_replaceHeightRes() {
+ PendingIntent bubbleIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0);
+ PendingIntent deleteIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0);
+ Icon icon = Icon.createWithResource(mContext, 1);
+ Notification.BubbleMetadata.Builder metadataBuilder =
+ new Notification.BubbleMetadata.Builder()
+ .setDesiredHeight(BUBBLE_HEIGHT)
+ .setDesiredHeightResId(BUBBLE_HEIGHT_RESID)
+ .setIcon(icon)
+ .setIntent(bubbleIntent)
+ .setDeleteIntent(deleteIntent);
+
+ Notification.BubbleMetadata data = metadataBuilder.build();
+ // Desired height should be cleared
+ assertEquals(0, data.getDesiredHeight());
+ // Res id should be used
+ assertEquals(BUBBLE_HEIGHT_RESID, data.getDesiredHeightResId());
+ }
+
+ public void testBubbleMetadataBuilder_replaceHeightDp() {
+ PendingIntent bubbleIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0);
+ PendingIntent deleteIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0);
+ Icon icon = Icon.createWithResource(mContext, 1);
+ Notification.BubbleMetadata.Builder metadataBuilder =
+ new Notification.BubbleMetadata.Builder()
+ .setDesiredHeightResId(BUBBLE_HEIGHT_RESID)
+ .setDesiredHeight(BUBBLE_HEIGHT)
+ .setIcon(icon)
+ .setIntent(bubbleIntent)
+ .setDeleteIntent(deleteIntent);
+
+ Notification.BubbleMetadata data = metadataBuilder.build();
+ // Desired height should be used
+ assertEquals(BUBBLE_HEIGHT, data.getDesiredHeight());
+ // Res id should be cleared
+ assertEquals(0, data.getDesiredHeightResId());
+ }
+
private static RemoteInput newDataOnlyRemoteInput() {
return new RemoteInput.Builder(DATA_RESULT_KEY)
.setAllowFreeFormInput(false)
diff --git a/tests/app/src/android/app/cts/SystemFeaturesTest.java b/tests/app/src/android/app/cts/SystemFeaturesTest.java
index 7f47da8..3dbaa33 100644
--- a/tests/app/src/android/app/cts/SystemFeaturesTest.java
+++ b/tests/app/src/android/app/cts/SystemFeaturesTest.java
@@ -583,7 +583,7 @@
@Test
public void testUsbAccessory() {
if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE) &&
- !mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEVISION) &&
+ !mPackageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK) &&
!mPackageManager.hasSystemFeature(PackageManager.FEATURE_WATCH) &&
!mPackageManager.hasSystemFeature(PackageManager.FEATURE_EMBEDDED) &&
!isAndroidEmulator() &&
@@ -619,7 +619,7 @@
@Test
public void testAudioOutputFeature() throws Exception {
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE) ||
- mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEVISION)) {
+ mPackageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK)) {
assertAvailable(PackageManager.FEATURE_AUDIO_OUTPUT);
}
}
diff --git a/tests/apppredictionservice/OWNERS b/tests/apppredictionservice/OWNERS
new file mode 100644
index 0000000..b764e24
--- /dev/null
+++ b/tests/apppredictionservice/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 555429
+winsonc@google.com
+mett@google.com
diff --git a/tests/apppredictionservice/src/android/apppredictionservice/cts/AppPredictionServiceTest.java b/tests/apppredictionservice/src/android/apppredictionservice/cts/AppPredictionServiceTest.java
index eb10e16..5f037b2 100644
--- a/tests/apppredictionservice/src/android/apppredictionservice/cts/AppPredictionServiceTest.java
+++ b/tests/apppredictionservice/src/android/apppredictionservice/cts/AppPredictionServiceTest.java
@@ -117,7 +117,7 @@
// Ensure that future calls to the client fail
assertFails(() -> client.notifyAppTargetEvent(null));
- assertFails(() -> client.notifyLocationShown(null, null));
+ assertFails(() -> client.notifyLaunchLocationShown(null, null));
assertFails(() -> client.registerPredictionUpdates(null, null));
assertFails(() -> client.unregisterPredictionUpdates(null));
assertFails(() -> client.requestPredictionUpdate());
@@ -177,7 +177,7 @@
AppTargetId id = target.getId();
targetIds.add(id);
}
- client.notifyLocationShown(TEST_LAUNCH_LOCATION, targetIds);
+ client.notifyLaunchLocationShown(TEST_LAUNCH_LOCATION, targetIds);
mReporter.awaitOnLocationShown();
assertEquals(mReporter.mLocationsShown, TEST_LAUNCH_LOCATION);
assertEquals(mReporter.mLocationsShownTargets, targetIds);
@@ -219,8 +219,10 @@
List<AppTarget> targets = new ArrayList<>();
int n = (int) (Math.random() * 20);
for (int i = 0; i < n; i++) {
- targets.add(new AppTarget(new AppTargetId(String.valueOf(i)), "test.pkg",
- "test.class." + i, UserHandle.CURRENT));
+ targets.add(new AppTarget.Builder(new AppTargetId(String.valueOf(i)))
+ .setTarget("test.pkg", UserHandle.CURRENT)
+ .setClassName("test.class." + i)
+ .build());
}
return targets;
}
diff --git a/tests/apppredictionservice/src/android/apppredictionservice/cts/PredictionService.java b/tests/apppredictionservice/src/android/apppredictionservice/cts/PredictionService.java
index f65910c..6e69a3c 100644
--- a/tests/apppredictionservice/src/android/apppredictionservice/cts/PredictionService.java
+++ b/tests/apppredictionservice/src/android/apppredictionservice/cts/PredictionService.java
@@ -55,7 +55,7 @@
}
@Override
- public void onLocationShown(AppPredictionSessionId sessionId, String launchLocation,
+ public void onLaunchLocationShown(AppPredictionSessionId sessionId, String launchLocation,
List<AppTargetId> targetIds) {
mReporter.onLocationShown(sessionId, launchLocation, targetIds);
}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java b/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java
index b0f425a..b5f5b5c 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java
@@ -45,7 +45,9 @@
import com.android.compatibility.common.util.TestNameUtils;
import com.android.cts.mockime.MockImeSessionRule;
+import org.junit.AfterClass;
import org.junit.Before;
+import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.rules.RuleChain;
@@ -147,6 +149,22 @@
}
};
}
+
+ protected SimpleSaveActivity startSimpleSaveActivity() throws Exception {
+ final Intent intent = new Intent(mContext, SimpleSaveActivity.class)
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivity(intent);
+ mUiBot.assertShownByRelativeId(SimpleSaveActivity.ID_LABEL);
+ return SimpleSaveActivity.getInstance();
+ }
+
+ protected PreSimpleSaveActivity startPreSimpleSaveActivity() throws Exception {
+ final Intent intent = new Intent(mContext, PreSimpleSaveActivity.class)
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivity(intent);
+ mUiBot.assertShownByRelativeId(PreSimpleSaveActivity.ID_PRE_LABEL);
+ return PreSimpleSaveActivity.getInstance();
+ }
}
@RunWith(AndroidJUnit4.class)
@@ -277,6 +295,18 @@
@NonNull
protected abstract TestRule getMainTestRule();
+ @BeforeClass
+ public static void disableDefaultAugmentedService() {
+ Log.v(TAG, "@BeforeClass: disableDefaultAugmentedService()");
+ Helper.setDefaultAugmentedAutofillServiceEnabled(false);
+ }
+
+ @AfterClass
+ public static void enableDefaultAugmentedService() {
+ Log.v(TAG, "@AfterClass: enableDefaultAugmentedService()");
+ Helper.setDefaultAugmentedAutofillServiceEnabled(true);
+ }
+
@Before
public void prepareDevice() throws Exception {
Log.v(TAG, "@Before: prepareDevice()");
diff --git a/tests/autofillservice/src/android/autofillservice/cts/DisableAutofillTest.java b/tests/autofillservice/src/android/autofillservice/cts/DisableAutofillTest.java
index 49a43fe..2854b4c 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/DisableAutofillTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/DisableAutofillTest.java
@@ -20,7 +20,6 @@
import static android.autofillservice.cts.Timeouts.CALLBACK_NOT_CALLED_TIMEOUT_MS;
import android.autofillservice.cts.CannedFillResponse.CannedDataset;
-import android.content.Intent;
import android.os.SystemClock;
import android.platform.test.annotations.AppModeFull;
import android.service.autofill.FillResponse;
@@ -37,22 +36,6 @@
private static final String TAG = "DisableAutofillTest";
- private SimpleSaveActivity startSimpleSaveActivity() throws Exception {
- final Intent intent = new Intent(mContext, SimpleSaveActivity.class)
- .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- mContext.startActivity(intent);
- mUiBot.assertShownByRelativeId(SimpleSaveActivity.ID_LABEL);
- return SimpleSaveActivity.getInstance();
- }
-
- private PreSimpleSaveActivity startPreSimpleSaveActivity() throws Exception {
- final Intent intent = new Intent(mContext, PreSimpleSaveActivity.class)
- .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- mContext.startActivity(intent);
- mUiBot.assertShownByRelativeId(PreSimpleSaveActivity.ID_PRE_LABEL);
- return PreSimpleSaveActivity.getInstance();
- }
-
/**
* Defines what to do after the activity being tested is launched.
*/
diff --git a/tests/autofillservice/src/android/autofillservice/cts/Helper.java b/tests/autofillservice/src/android/autofillservice/cts/Helper.java
index 34fa7c8..4bd6f4e 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/Helper.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/Helper.java
@@ -937,6 +937,15 @@
}
/**
+ * Enables / disables the default augmented autofill service.
+ */
+ public static void setDefaultAugmentedAutofillServiceEnabled(boolean enabled) {
+ Log.d(TAG, "setDefaultAugmentedAutofillServiceEnabled(): " + enabled);
+ runShellCommand("cmd autofill set default-augmented-service-enabled 0 %s",
+ Boolean.toString(enabled));
+ }
+
+ /**
* Gets the instrumentation context.
*/
public static Context getContext() {
diff --git a/tests/autofillservice/src/android/autofillservice/cts/PreSimpleSaveActivity.java b/tests/autofillservice/src/android/autofillservice/cts/PreSimpleSaveActivity.java
index 1cb5942..0e14bc5 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/PreSimpleSaveActivity.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/PreSimpleSaveActivity.java
@@ -59,20 +59,24 @@
});
}
- FillExpectation expectAutoFill(String input) {
+ public FillExpectation expectAutoFill(String input) {
final FillExpectation expectation = new FillExpectation(input);
mPreInput.addTextChangedListener(expectation.mInputWatcher);
return expectation;
}
- final class FillExpectation {
+ public EditText getPreInput() {
+ return mPreInput;
+ }
+
+ public final class FillExpectation {
private final OneTimeTextWatcher mInputWatcher;
private FillExpectation(String input) {
mInputWatcher = new OneTimeTextWatcher("input", mPreInput, input);
}
- void assertAutoFilled() throws Exception {
+ public void assertAutoFilled() throws Exception {
mInputWatcher.assertAutoFilled();
}
}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivity.java b/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivity.java
index e292c3c..2666269 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivity.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivity.java
@@ -29,11 +29,11 @@
private static final String TAG = "SimpleSaveActivity";
- static final String ID_LABEL = "label";
- static final String ID_INPUT = "input";
- static final String ID_PASSWORD = "password";
- static final String ID_COMMIT = "commit";
- static final String TEXT_LABEL = "Label:";
+ public static final String ID_LABEL = "label";
+ public static final String ID_INPUT = "input";
+ public static final String ID_PASSWORD = "password";
+ public static final String ID_COMMIT = "commit";
+ public static final String TEXT_LABEL = "Label:";
private static SimpleSaveActivity sInstance;
@@ -46,7 +46,7 @@
private boolean mAutoCommit = true;
private boolean mClearFieldsOnSubmit = false;
- static SimpleSaveActivity getInstance() {
+ public static SimpleSaveActivity getInstance() {
return sInstance;
}
@@ -103,20 +103,24 @@
mClearFieldsOnSubmit = flag;
}
- FillExpectation expectAutoFill(String input) {
+ public FillExpectation expectAutoFill(String input) {
final FillExpectation expectation = new FillExpectation(input, null);
mInput.addTextChangedListener(expectation.mInputWatcher);
return expectation;
}
- FillExpectation expectAutoFill(String input, String password) {
+ public FillExpectation expectAutoFill(String input, String password) {
final FillExpectation expectation = new FillExpectation(input, password);
mInput.addTextChangedListener(expectation.mInputWatcher);
mPassword.addTextChangedListener(expectation.mPasswordWatcher);
return expectation;
}
- final class FillExpectation {
+ public EditText getInput() {
+ return mInput;
+ }
+
+ public final class FillExpectation {
private final OneTimeTextWatcher mInputWatcher;
private final OneTimeTextWatcher mPasswordWatcher;
@@ -127,7 +131,7 @@
: new OneTimeTextWatcher("password", mPassword, password);
}
- void assertAutoFilled() throws Exception {
+ public void assertAutoFilled() throws Exception {
mInputWatcher.assertAutoFilled();
if (mPasswordWatcher != null) {
mPasswordWatcher.assertAutoFilled();
diff --git a/tests/autofillservice/src/android/autofillservice/cts/UiBot.java b/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
index dbea494..ad3ef46 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
@@ -184,6 +184,10 @@
@Deprecated
// TODO: remove once we're sure no more OEM is getting failure due to screen size
public void setScreenResolution() {
+ if (true) {
+ Log.w(TAG, "setScreenResolution(): ignored");
+ return;
+ }
assumeMinimumResolution(500);
runShellCommand("wm size 1080x1920");
@@ -200,6 +204,10 @@
@Deprecated
// TODO: remove once we're sure no more OEM is getting failure due to screen size
public void resetScreenResolution() {
+ if (true) {
+ Log.w(TAG, "resetScreenResolution(): ignored");
+ return;
+ }
runShellCommand("wm density reset");
runShellCommand("wm size reset");
}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedAutofillAutoActivityLaunchTestCase.java b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedAutofillAutoActivityLaunchTestCase.java
index a0a5c3e..43dec19 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedAutofillAutoActivityLaunchTestCase.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedAutofillAutoActivityLaunchTestCase.java
@@ -32,6 +32,11 @@
import org.junit.Before;
import org.junit.BeforeClass;
+/////
+///// NOTE: changes in this class should also be applied to
+///// AugmentedAutofillManualActivityLaunchTestCase, which is exactly the same as this except
+///// by which class it extends.
+
// Must be public because of the @ClassRule
public abstract class AugmentedAutofillAutoActivityLaunchTestCase
<A extends AbstractAutoFillActivity> extends AutoFillServiceTestCase.AutoActivityLaunch<A> {
diff --git a/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedAutofillManualActivityLaunchTestCase.java b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedAutofillManualActivityLaunchTestCase.java
new file mode 100644
index 0000000..6caa368
--- /dev/null
+++ b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedAutofillManualActivityLaunchTestCase.java
@@ -0,0 +1,115 @@
+/*
+ * 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.autofillservice.cts.augmented;
+
+import static android.autofillservice.cts.Helper.allowOverlays;
+import static android.autofillservice.cts.Helper.disallowOverlays;
+
+import android.autofillservice.cts.AutoFillServiceTestCase;
+import android.autofillservice.cts.Helper;
+import android.autofillservice.cts.augmented.CtsAugmentedAutofillService.AugmentedReplier;
+import android.content.AutofillOptions;
+import android.os.SystemClock;
+import android.util.ArraySet;
+import android.util.Log;
+import android.view.autofill.AutofillManager;
+
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+
+/////
+///// NOTE: changes in this class should also be applied to
+///// AugmentedAutofillManualActivityLaunchTestCase, which is exactly the same as this except
+///// by which class it extends.
+
+// Must be public because of the @ClassRule
+public abstract class AugmentedAutofillManualActivityLaunchTestCase
+ extends AutoFillServiceTestCase.ManualActivityLaunch {
+
+ private static final String TAG = AugmentedAutofillManualActivityLaunchTestCase.class
+ .getSimpleName();
+
+ protected static AugmentedReplier sAugmentedReplier;
+ protected AugmentedUiBot mAugmentedUiBot;
+
+ private CtsAugmentedAutofillService.ServiceWatcher mServiceWatcher;
+
+ @BeforeClass
+ public static void allowAugmentedAutofill() {
+ sContext.getApplicationContext()
+ .setAutofillOptions(AutofillOptions.forWhitelistingItself());
+ allowOverlays();
+ }
+
+ @AfterClass
+ public static void resetAllowAugmentedAutofill() {
+ sContext.getApplicationContext().setAutofillOptions(null);
+ disallowOverlays();
+ }
+
+ @Before
+ public void setFixtures() {
+ sAugmentedReplier = CtsAugmentedAutofillService.getAugmentedReplier();
+ sAugmentedReplier.reset();
+ CtsAugmentedAutofillService.resetStaticState();
+ mAugmentedUiBot = new AugmentedUiBot(mUiBot);
+ mSafeCleanerRule
+ .run(() -> sAugmentedReplier.assertNoUnhandledFillRequests())
+ .run(() -> {
+ AugmentedHelper.resetAugmentedService();
+ if (mServiceWatcher != null) {
+ mServiceWatcher.waitOnDisconnected();
+ }
+ })
+ .add(() -> {
+ return sAugmentedReplier.getExceptions();
+ });
+ }
+
+ @Override
+ protected int getSmartSuggestionMode() {
+ return AutofillManager.FLAG_SMART_SUGGESTION_SYSTEM;
+ }
+
+ protected CtsAugmentedAutofillService enableAugmentedService() throws InterruptedException {
+ return enableAugmentedService(/* whitelistSelf= */ true);
+ }
+
+ protected CtsAugmentedAutofillService enableAugmentedService(boolean whitelistSelf)
+ throws InterruptedException {
+ if (mServiceWatcher != null) {
+ throw new IllegalStateException("There Can Be Only One!");
+ }
+
+ mServiceWatcher = CtsAugmentedAutofillService.setServiceWatcher();
+ AugmentedHelper.setAugmentedService(CtsAugmentedAutofillService.SERVICE_NAME);
+
+ // TODO(b/124456706): instead of sleeping it should wait for onConnected()
+ SystemClock.sleep(1000);
+
+ if (whitelistSelf) {
+ Log.d(TAG, "Whitelisting " + Helper.MY_PACKAGE + " for augmented autofill");
+ final ArraySet<String> packages = new ArraySet<>(1);
+ packages.add(Helper.MY_PACKAGE);
+ getAutofillManager().setAugmentedAutofillWhitelist(packages, /* activities= */ null);
+ }
+
+ CtsAugmentedAutofillService service = mServiceWatcher.waitOnConnected();
+ service.waitUntilConnected();
+ return service;
+ }
+}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedLoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedLoginActivityTest.java
index 6a33555..e620969 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedLoginActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedLoginActivityTest.java
@@ -24,6 +24,8 @@
import static android.autofillservice.cts.augmented.CannedAugmentedFillResponse.DO_NOT_REPLY_AUGMENTED_RESPONSE;
import static android.autofillservice.cts.augmented.CannedAugmentedFillResponse.NO_AUGMENTED_RESPONSE;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.junit.Assume.assumeTrue;
import static org.testng.Assert.assertThrows;
@@ -33,6 +35,7 @@
import android.autofillservice.cts.OneTimeCancellationSignalListener;
import android.autofillservice.cts.augmented.CtsAugmentedAutofillService.AugmentedFillRequest;
import android.content.ComponentName;
+import android.os.CancellationSignal;
import android.platform.test.annotations.AppModeFull;
import android.support.test.uiautomator.UiObject2;
import android.util.ArraySet;
@@ -42,7 +45,6 @@
import android.view.autofill.AutofillValue;
import android.widget.EditText;
-import org.junit.Ignore;
import org.junit.Test;
import java.util.Set;
@@ -140,6 +142,35 @@
}
@Test
+ public void testAutoFill_augmentedFillRequestCancelled() throws Exception {
+ // Set services
+ enableService();
+ enableAugmentedService();
+
+ // Set expectations
+ final EditText username = mActivity.getUsername();
+ final AutofillId usernameId = username.getAutofillId();
+ sReplier.addResponse(NO_RESPONSE);
+ sAugmentedReplier.addResponse(new CannedAugmentedFillResponse.Builder()
+ .setDataset(new CannedAugmentedFillResponse.Dataset.Builder("Augment Me")
+ .setField(usernameId, "dude")
+ .build(), usernameId)
+ .setDelay(AUGMENTED_FILL_TIMEOUT.ms() + 6000)
+ .build());
+
+ // Trigger autofill
+ mActivity.onUsername(View::requestFocus);
+ sReplier.getNextFillRequest();
+ sAugmentedReplier.getNextFillRequest();
+
+ // Make sure standard Autofill UI is not shown.
+ mUiBot.assertNoDatasetsEver();
+
+ // Make sure Augmented Autofill UI is shown.
+ mAugmentedUiBot.assertUiNeverShown();
+ }
+
+ @Test
@AppModeFull(reason = "testAutoFill_mainServiceReturnedNull_augmentedAutofillOneField enough")
public void testAutoFill_mainServiceReturnedNull_augmentedAutofillTwoFields() throws Exception {
// Set services
@@ -179,7 +210,6 @@
mAugmentedUiBot.assertUiGone();
}
- @Ignore("blocked on b/122728762")
@Test
@AppModeFull(reason = "testAutoFill_mainServiceReturnedNull_augmentedAutofillOneField enough")
public void testCancellationSignalCalledAfterTimeout() throws Exception {
@@ -191,20 +221,22 @@
sReplier.addResponse(NO_RESPONSE);
sAugmentedReplier.addResponse(DO_NOT_REPLY_AUGMENTED_RESPONSE);
final OneTimeCancellationSignalListener listener =
- new OneTimeCancellationSignalListener(AUGMENTED_FILL_TIMEOUT.ms() + 2000);
+ new OneTimeCancellationSignalListener(AUGMENTED_FILL_TIMEOUT.ms() + 5000);
// Trigger autofill
mActivity.onUsername(View::requestFocus);
sReplier.getNextFillRequest();
- // TODO(b/124456706): might need to wait until connected
- sAugmentedReplier.getNextFillRequest().cancellationSignal.setOnCancelListener(listener);
+ final CancellationSignal cancellationSignal = sAugmentedReplier.getNextFillRequest()
+ .cancellationSignal;
+
+ assertThat(cancellationSignal).isNotNull();
+ cancellationSignal.setOnCancelListener(listener);
// Assert results
listener.assertOnCancelCalled();
}
-
@Test
public void testAugmentedAutoFill_multipleRequests() throws Exception {
// Set services
@@ -377,6 +409,42 @@
}
@Test
+ public void testAugmentedAutoFill_mainServiceDisabled() throws Exception {
+ // Set services
+ Helper.disableAutofillService(sContext);
+ enableAugmentedService();
+
+ // Set expectations
+ final EditText username = mActivity.getUsername();
+ final AutofillId usernameId = username.getAutofillId();
+ final AutofillValue usernameValue = username.getAutofillValue();
+ sAugmentedReplier.addResponse(new CannedAugmentedFillResponse.Builder()
+ .setDataset(new CannedAugmentedFillResponse.Dataset.Builder("Augment Me")
+ .setField(usernameId, "dude")
+ .build(), usernameId)
+ .build());
+ mActivity.expectAutoFill("dude");
+
+ // Trigger autofill
+ mActivity.onUsername(View::requestFocus);
+ final AugmentedFillRequest request = sAugmentedReplier.getNextFillRequest();
+
+ // Assert request
+ assertBasicRequestInfo(request, mActivity, usernameId, usernameValue);
+
+ // Make sure standard Autofill UI is not shown.
+ mUiBot.assertNoDatasetsEver();
+
+ // Make sure Augmented Autofill UI is shown.
+ final UiObject2 ui = mAugmentedUiBot.assertUiShown(usernameId, "Augment Me");
+
+ // Autofill
+ ui.click();
+ mActivity.assertAutoFilled();
+ mAugmentedUiBot.assertUiGone();
+ }
+
+ @Test
public void testSetAugmentedAutofillWhitelist_noStandardServiceSet() throws Exception {
final AutofillManager mgr = mActivity.getAutofillManager();
assertThrows(SecurityException.class,
diff --git a/tests/autofillservice/src/android/autofillservice/cts/augmented/CannedAugmentedFillResponse.java b/tests/autofillservice/src/android/autofillservice/cts/augmented/CannedAugmentedFillResponse.java
index 4cca7c7..bb195f3 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/augmented/CannedAugmentedFillResponse.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/augmented/CannedAugmentedFillResponse.java
@@ -35,9 +35,11 @@
import android.widget.TextView;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import com.google.common.base.Preconditions;
+import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@@ -51,10 +53,14 @@
private final AugmentedResponseType mResponseType;
private final Map<AutofillId, Dataset> mDatasets;
+ private long mDelay;
+ private final Dataset mOnlyDataset;
private CannedAugmentedFillResponse(@NonNull Builder builder) {
mResponseType = builder.mResponseType;
mDatasets = builder.mDatasets;
+ mDelay = builder.mDelay;
+ mOnlyDataset = builder.mOnlyDataset;
}
/**
@@ -74,6 +80,10 @@
return mResponseType;
}
+ public long getDelay() {
+ return mDelay;
+ }
+
/**
* Creates the "real" response.
*/
@@ -81,7 +91,12 @@
@NonNull FillController controller) {
final AutofillId focusedId = request.getFocusedId();
- final Dataset dataset = mDatasets.get(focusedId);
+ final Dataset dataset;
+ if (mOnlyDataset != null) {
+ dataset = mOnlyDataset;
+ } else {
+ dataset = mDatasets.get(focusedId);
+ }
if (dataset == null) {
Log.d(TAG, "no dataset for field " + focusedId);
return null;
@@ -112,8 +127,16 @@
rootView.setOnClickListener((v) -> {
Log.d(TAG, "Destroying window first");
fillWindow.destroy();
- final List<Pair<AutofillId, AutofillValue>> values = dataset.getValues();
- Log.i(TAG, "Autofilling: " + AugmentedHelper.toString(values));
+ final List<Pair<AutofillId, AutofillValue>> values;
+ final AutofillValue onlyValue = dataset.getOnlyFieldValue();
+ if (onlyValue != null) {
+ Log.i(TAG, "Autofilling only value for " + focusedId + " as " + onlyValue);
+ values = new ArrayList<>(1);
+ values.add(new Pair<AutofillId, AutofillValue>(focusedId, onlyValue));
+ } else {
+ values = dataset.getValues();
+ Log.i(TAG, "Autofilling: " + AugmentedHelper.toString(values));
+ }
controller.autofill(values);
});
@@ -129,7 +152,8 @@
@Override
public String toString() {
return "CannedAugmentedFillResponse: [type=" + mResponseType
- + ",datasets=" + mDatasets
+ + ", onlyDataset=" + mOnlyDataset
+ + ", datasets=" + mDatasets
+ "]";
}
public enum AugmentedResponseType {
@@ -141,6 +165,8 @@
public static final class Builder {
private final Map<AutofillId, Dataset> mDatasets = new ArrayMap<>();
private final AugmentedResponseType mResponseType;
+ private long mDelay;
+ private Dataset mOnlyDataset;
public Builder(@NonNull AugmentedResponseType type) {
mResponseType = type;
@@ -154,13 +180,41 @@
* Sets the {@link Dataset} that will be filled when the given {@code ids} is focused and
* the UI is tapped.
*/
+ @NonNull
public Builder setDataset(@NonNull Dataset dataset, @NonNull AutofillId... ids) {
+ if (mOnlyDataset != null) {
+ throw new IllegalStateException("already called setOnlyDataset()");
+ }
for (AutofillId id : ids) {
mDatasets.put(id, dataset);
}
return this;
}
+ /**
+ * Sets the delay for onFillRequest().
+ */
+ public Builder setDelay(long delay) {
+ mDelay = delay;
+ return this;
+ }
+
+ /**
+ * Sets the only dataset that will be returned.
+ *
+ * <p>Used when the test case doesn't know the autofill id of the focused field.
+ * @param dataset
+ */
+ @NonNull
+ public Builder setOnlyDataset(@NonNull Dataset dataset) {
+ if (!mDatasets.isEmpty()) {
+ throw new IllegalStateException("already called setDataset()");
+ }
+ mOnlyDataset = dataset;
+ return this;
+ }
+
+ @NonNull
public CannedAugmentedFillResponse build() {
return new CannedAugmentedFillResponse(this);
}
@@ -174,21 +228,30 @@
public static class Dataset {
private final Map<AutofillId, AutofillValue> mFieldValuesById;
private final String mPresentation;
+ private final AutofillValue mOnlyFieldValue;
private Dataset(@NonNull Builder builder) {
mFieldValuesById = builder.mFieldValuesById;
mPresentation = builder.mPresentation;
+ mOnlyFieldValue = builder.mOnlyFieldValue;
}
+ @NonNull
public List<Pair<AutofillId, AutofillValue>> getValues() {
return mFieldValuesById.entrySet().stream()
.map((entry) -> (new Pair<>(entry.getKey(), entry.getValue())))
.collect(Collectors.toList());
}
+ @Nullable
+ public AutofillValue getOnlyFieldValue() {
+ return mOnlyFieldValue;
+ }
+
@Override
public String toString() {
return "Dataset: [presentation=" + mPresentation
+ + ", onlyField=" + mOnlyFieldValue
+ ", fields=" + mFieldValuesById
+ "]";
}
@@ -197,6 +260,7 @@
private final Map<AutofillId, AutofillValue> mFieldValuesById = new ArrayMap<>();
private final String mPresentation;
+ private AutofillValue mOnlyFieldValue;
public Builder(@NonNull String presentation) {
mPresentation = Preconditions.checkNotNull(presentation);
@@ -205,10 +269,28 @@
/**
* Sets the value that will be autofilled on the field with {@code id}.
*/
- public Builder setField(@NonNull AutofillId id, String text) {
+ public Builder setField(@NonNull AutofillId id, @NonNull String text) {
+ if (mOnlyFieldValue != null) {
+ throw new IllegalStateException("already called setOnlyField()");
+ }
mFieldValuesById.put(id, AutofillValue.forText(text));
return this;
}
+
+ /**
+ * Sets this dataset to return the given {@code text} for the focused field.
+ *
+ * <p>Used when the test case doesn't know the autofill id of the focused field.
+ */
+ public Builder setOnlyField(@NonNull String text) {
+ if (!mFieldValuesById.isEmpty()) {
+ throw new IllegalStateException("already called setField()");
+ }
+ mOnlyFieldValue = AutofillValue.forText(text);
+ return this;
+ }
+
+
public Dataset build() {
return new Dataset(this);
}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/augmented/CtsAugmentedAutofillService.java b/tests/autofillservice/src/android/autofillservice/cts/augmented/CtsAugmentedAutofillService.java
index c33202a..f7b2eba 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/augmented/CtsAugmentedAutofillService.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/augmented/CtsAugmentedAutofillService.java
@@ -29,6 +29,7 @@
import android.os.CancellationSignal;
import android.os.Handler;
import android.os.HandlerThread;
+import android.os.SystemClock;
import android.service.autofill.augmented.AugmentedAutofillService;
import android.service.autofill.augmented.FillCallback;
import android.service.autofill.augmented.FillController;
@@ -325,6 +326,10 @@
private void handleOnFillRequest(@NonNull Context context, @NonNull FillRequest request,
@NonNull CancellationSignal cancellationSignal, @NonNull FillController controller,
@NonNull FillCallback callback) {
+ final AugmentedFillRequest myRequest = new AugmentedFillRequest(request,
+ cancellationSignal, controller, callback);
+ Log.d(TAG, "offering " + myRequest);
+ Helper.offer(mFillRequests, myRequest, AUGMENTED_CONNECTION_TIMEOUT.ms());
try {
final CannedAugmentedFillResponse response;
try {
@@ -341,6 +346,13 @@
+ " received when no canned response was set.");
return;
}
+
+ // sleep for timeout tests.
+ final long delay = response.getDelay();
+ if (delay > 0) {
+ SystemClock.sleep(response.getDelay());
+ }
+
if (response.getResponseType() == NULL) {
Log.d(TAG, "onFillRequest(): replying with null");
callback.onSuccess(null);
@@ -359,11 +371,6 @@
callback.onSuccess(fillResponse);
} catch (Throwable t) {
addException(t);
- } finally {
- final AugmentedFillRequest myRequest = new AugmentedFillRequest(request,
- cancellationSignal, controller, callback);
- Log.d(TAG, "offering " + myRequest);
- Helper.offer(mFillRequests, myRequest, AUGMENTED_CONNECTION_TIMEOUT.ms());
}
}
}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/augmented/DisableAutofillTest.java b/tests/autofillservice/src/android/autofillservice/cts/augmented/DisableAutofillTest.java
new file mode 100644
index 0000000..bba97bd
--- /dev/null
+++ b/tests/autofillservice/src/android/autofillservice/cts/augmented/DisableAutofillTest.java
@@ -0,0 +1,133 @@
+/*
+ * 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.autofillservice.cts.augmented;
+
+import static android.autofillservice.cts.augmented.AugmentedHelper.assertBasicRequestInfo;
+import static android.autofillservice.cts.augmented.AugmentedHelper.resetAugmentedService;
+
+import android.autofillservice.cts.CannedFillResponse;
+import android.autofillservice.cts.PreSimpleSaveActivity;
+import android.autofillservice.cts.SimpleSaveActivity;
+import android.autofillservice.cts.augmented.CtsAugmentedAutofillService.AugmentedFillRequest;
+import android.platform.test.annotations.AppModeFull;
+import android.support.test.uiautomator.UiObject2;
+import android.view.autofill.AutofillId;
+import android.view.autofill.AutofillValue;
+import android.widget.EditText;
+
+import org.junit.Test;
+
+@AppModeFull(reason = "AugmentedLoginActivityTest is enough")
+public class DisableAutofillTest extends AugmentedAutofillManualActivityLaunchTestCase {
+
+ @Test
+ public void testAugmentedAutofill_standardAutofillDisabledByService_sameActivity()
+ throws Exception {
+ // Enable services
+ enableService();
+ enableAugmentedService();
+
+ // Set expectations
+ sReplier.addResponse(
+ new CannedFillResponse.Builder().disableAutofill(Long.MAX_VALUE).build());
+ sAugmentedReplier.addResponse(new CannedAugmentedFillResponse.Builder()
+ .setOnlyDataset(new CannedAugmentedFillResponse.Dataset.Builder("Augment Me")
+ .setOnlyField("dude")
+ .build())
+ .build());
+
+ final PreSimpleSaveActivity preSimpleActivity = startPreSimpleSaveActivity();
+ final EditText preInput = preSimpleActivity.getPreInput();
+ preSimpleActivity.syncRunOnUiThread(() -> preInput.requestFocus());
+ sReplier.getNextFillRequest();
+
+ // Make sure standard Autofill UI is not shown.
+ mUiBot.assertNoDatasetsEver();
+
+ // Assert augmented autofill request
+ final AugmentedFillRequest request = sAugmentedReplier.getNextFillRequest();
+ assertBasicRequestInfo(request, preSimpleActivity, preInput.getAutofillId(),
+ preInput.getAutofillValue());
+
+ // Make sure Augmented Autofill UI is shown.
+ final UiObject2 ui = mAugmentedUiBot.assertUiShown(preInput.getAutofillId(), "Augment Me");
+
+ // Then autofill it
+ final PreSimpleSaveActivity.FillExpectation autofillExpectation = preSimpleActivity
+ .expectAutoFill("dude");
+ ui.click();
+ autofillExpectation.assertAutoFilled();
+ mAugmentedUiBot.assertUiGone();
+
+ // Sanity check - make sure standard autofill was not requested
+ sReplier.assertNoUnhandledFillRequests();
+ }
+
+ @Test
+ public void testAugmentedAutofill_standardAutofillDisabledByService_otherActivity()
+ throws Exception {
+ // Set standard service only, so we don't trigger augmented autofill when we launch the
+ // first activity
+ enableService();
+ resetAugmentedService();
+
+ // Use PreSimpleSaveActivity disable standard autofill
+ sReplier.addResponse(
+ new CannedFillResponse.Builder().disableAutofill(Long.MAX_VALUE).build());
+ final PreSimpleSaveActivity preSimpleActivity = startPreSimpleSaveActivity();
+ final EditText preInput = preSimpleActivity.getPreInput();
+ preSimpleActivity.syncRunOnUiThread(() -> preInput.requestFocus());
+ sReplier.getNextFillRequest();
+
+ // Then use SimpleSaveActivity for the main test
+ enableAugmentedService();
+ final SimpleSaveActivity simpleActivity = startSimpleSaveActivity();
+ final EditText input = simpleActivity.getInput();
+
+
+ // Set expectations
+ final AutofillId inputId = input.getAutofillId();
+ final AutofillValue inputValue = input.getAutofillValue();
+ sAugmentedReplier.addResponse(new CannedAugmentedFillResponse.Builder()
+ .setDataset(new CannedAugmentedFillResponse.Dataset.Builder("Augment Me")
+ .setField(inputId, "dude")
+ .build(), inputId)
+ .build());
+
+ simpleActivity.syncRunOnUiThread(() -> input.requestFocus());
+
+ // Make sure standard Autofill UI is not shown.
+ mUiBot.assertNoDatasetsEver();
+
+ // Assert augmented autofill request
+ final AugmentedFillRequest request = sAugmentedReplier.getNextFillRequest();
+ assertBasicRequestInfo(request, simpleActivity, inputId, inputValue);
+
+ // Make sure Augmented Autofill UI is shown.
+ final UiObject2 ui = mAugmentedUiBot.assertUiShown(inputId, "Augment Me");
+
+ // Then autofill it
+ final SimpleSaveActivity.FillExpectation autofillExpectation = simpleActivity
+ .expectAutoFill("dude");
+ ui.click();
+ autofillExpectation.assertAutoFilled();
+ mAugmentedUiBot.assertUiGone();
+
+ // Sanity check - make sure standard autofill was not requested
+ sReplier.assertNoUnhandledFillRequests();
+ }
+}
diff --git a/tests/camera/libctscamera2jni/native-camera-jni.cpp b/tests/camera/libctscamera2jni/native-camera-jni.cpp
index a2a74ab..89bb31b 100644
--- a/tests/camera/libctscamera2jni/native-camera-jni.cpp
+++ b/tests/camera/libctscamera2jni/native-camera-jni.cpp
@@ -1042,21 +1042,18 @@
return createCaptureSessionWithLog(extraOutputs, isPreviewShared, sessionParameters);
}
- camera_status_t createCaptureSessionWithLog(
+ camera_status_t createCaptureSessionOutputContainer(
const std::vector<ACaptureSessionOutput*> extraOutputs,
+ ACaptureSessionOutputContainer** outputs,
bool isPreviewShared = false, ACaptureRequest *sessionParameters = nullptr) {
- if (mSession) {
- LOG_ERROR(errorString, "Cannot create session before closing existing one");
+ if (!mMgrInited || (!mImgReaderInited && !mPreviewInited) || !outputs) {
+ LOG_ERROR(errorString, "Cannot create session output container. mgrInit %d "
+ "readerInit %d previewInit %d outputs %p",
+ mMgrInited, mImgReaderInited, mPreviewInited, outputs);
return ACAMERA_ERROR_UNKNOWN;
}
- if (!mMgrInited || (!mImgReaderInited && !mPreviewInited)) {
- LOG_ERROR(errorString, "Cannot create session. mgrInit %d readerInit %d previewInit %d",
- mMgrInited, mImgReaderInited, mPreviewInited);
- return ACAMERA_ERROR_UNKNOWN;
- }
-
- camera_status_t ret = ACaptureSessionOutputContainer_create(&mOutputs);
+ camera_status_t ret = ACaptureSessionOutputContainer_create(outputs);
if (ret != ACAMERA_OK) {
LOG_ERROR(errorString, "Create capture session output container failed. ret %d", ret);
return ret;
@@ -1066,7 +1063,7 @@
ret = ACaptureSessionOutput_create(mImgReaderAnw, &mImgReaderOutput);
if (ret != ACAMERA_OK || mImgReaderOutput == nullptr) {
LOG_ERROR(errorString,
- "Sesssion image reader output create fail! ret %d output %p",
+ "Session image reader output create fail! ret %d output %p",
ret, mImgReaderOutput);
if (ret == ACAMERA_OK) {
ret = ACAMERA_ERROR_UNKNOWN; // ret OK but output is null
@@ -1074,17 +1071,17 @@
return ret;
}
- ret = ACaptureSessionOutputContainer_add(mOutputs, mImgReaderOutput);
+ ret = ACaptureSessionOutputContainer_add(*outputs, mImgReaderOutput);
if (ret != ACAMERA_OK) {
- LOG_ERROR(errorString, "Sesssion image reader output add failed! ret %d", ret);
+ LOG_ERROR(errorString, "Session image reader output add failed! ret %d", ret);
return ret;
}
}
for (auto extraOutput : extraOutputs) {
- ret = ACaptureSessionOutputContainer_add(mOutputs, extraOutput);
+ ret = ACaptureSessionOutputContainer_add(*outputs, extraOutput);
if (ret != ACAMERA_OK) {
- LOG_ERROR(errorString, "Sesssion image reader output add failed! ret %d", ret);
+ LOG_ERROR(errorString, "Session image reader output add failed! ret %d", ret);
return ret;
}
}
@@ -1097,7 +1094,7 @@
}
if (ret != ACAMERA_OK || mPreviewOutput == nullptr) {
LOG_ERROR(errorString,
- "Sesssion preview output create fail! ret %d output %p",
+ "Session preview output create fail! ret %d output %p",
ret, mPreviewOutput);
if (ret == ACAMERA_OK) {
ret = ACAMERA_ERROR_UNKNOWN; // ret OK but output is null
@@ -1105,12 +1102,36 @@
return ret;
}
- ret = ACaptureSessionOutputContainer_add(mOutputs, mPreviewOutput);
+ ret = ACaptureSessionOutputContainer_add(*outputs, mPreviewOutput);
if (ret != ACAMERA_OK) {
- LOG_ERROR(errorString, "Sesssion preview output add failed! ret %d", ret);
+ LOG_ERROR(errorString, "Session preview output add failed! ret %d", ret);
return ret;
}
}
+ return ret;
+ }
+
+ camera_status_t createCaptureSessionWithLog(
+ const std::vector<ACaptureSessionOutput*> extraOutputs,
+ bool isPreviewShared = false, ACaptureRequest *sessionParameters = nullptr) {
+ if (mSession) {
+ LOG_ERROR(errorString, "Cannot create session before closing existing one");
+ return ACAMERA_ERROR_UNKNOWN;
+ }
+
+ camera_status_t ret = createCaptureSessionOutputContainer(
+ extraOutputs, &mOutputs, isPreviewShared, sessionParameters);
+ if (ret != ACAMERA_OK) {
+ LOG_ERROR(errorString, "Failed to create session output container! ret %d", ret);
+ return ret;
+ }
+
+ ret = ACameraDevice_isSessionConfigurationSupported(mDevice, mOutputs);
+ if (ret != ACAMERA_OK && ret != ACAMERA_ERROR_UNSUPPORTED_OPERATION) {
+ LOG_ERROR(errorString, "isSessionConfigurationSupported must return either OK "
+ "or UNSUPPORTED_OPERATION, but returns %d", ret);
+ return ret;
+ }
ret = ACameraDevice_createCaptureSessionWithSessionParameters(
mDevice, mOutputs, sessionParameters, &mSessionCb, &mSession);
@@ -2120,6 +2141,18 @@
goto cleanup;
}
+ {
+ ACameraMetadata* chars = testCase.getCameraChars(cameraId);
+ StaticInfo staticInfo(chars);
+ if (!staticInfo.isColorOutputSupported()) {
+ ALOGI("%s: camera %s does not support color output. skipping",
+ __FUNCTION__, cameraId);
+ ACameraMetadata_free(chars);
+ continue;
+ }
+ ACameraMetadata_free(chars);
+ }
+
ret = testCase.openCamera(cameraId);
if (ret != ACAMERA_OK) {
LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
@@ -2257,6 +2290,18 @@
goto cleanup;
}
+ {
+ ACameraMetadata* chars = testCase.getCameraChars(cameraId);
+ StaticInfo staticInfo(chars);
+ if (!staticInfo.isColorOutputSupported()) {
+ ALOGI("%s: camera %s does not support color output. skipping",
+ __FUNCTION__, cameraId);
+ ACameraMetadata_free(chars);
+ continue;
+ }
+ ACameraMetadata_free(chars);
+ }
+
ret = testCase.openCamera(cameraId);
if (ret != ACAMERA_OK) {
LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
@@ -2503,6 +2548,18 @@
goto cleanup;
}
+ {
+ ACameraMetadata* chars = testCase.getCameraChars(cameraId);
+ StaticInfo staticInfo(chars);
+ if (!staticInfo.isColorOutputSupported()) {
+ ALOGI("%s: camera %s does not support color output. skipping",
+ __FUNCTION__, cameraId);
+ ACameraMetadata_free(chars);
+ continue;
+ }
+ ACameraMetadata_free(chars);
+ }
+
ret = testCase.openCamera(cameraId);
if (ret != ACAMERA_OK) {
LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
@@ -3021,6 +3078,18 @@
goto cleanup;
}
+ {
+ ACameraMetadata* chars = testCase.getCameraChars(cameraId);
+ StaticInfo staticInfo(chars);
+ if (!staticInfo.isColorOutputSupported()) {
+ ALOGI("%s: camera %s does not support color output. skipping",
+ __FUNCTION__, cameraId);
+ ACameraMetadata_free(chars);
+ continue;
+ }
+ ACameraMetadata_free(chars);
+ }
+
ret = testCase.openCamera(cameraId);
if (ret != ACAMERA_OK) {
LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
@@ -3420,6 +3489,18 @@
goto cleanup;
}
+ {
+ ACameraMetadata* chars = testCase.getCameraChars(cameraId);
+ StaticInfo staticInfo(chars);
+ if (!staticInfo.isColorOutputSupported()) {
+ ALOGI("%s: camera %s does not support color output. skipping",
+ __FUNCTION__, cameraId);
+ ACameraMetadata_free(chars);
+ continue;
+ }
+ ACameraMetadata_free(chars);
+ }
+
ret = testCase.openCamera(cameraId);
if (ret != ACAMERA_OK) {
LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
diff --git a/tests/camera/src/android/hardware/camera2/cts/CameraDeviceTest.java b/tests/camera/src/android/hardware/camera2/cts/CameraDeviceTest.java
index 390495a..a77ce03 100644
--- a/tests/camera/src/android/hardware/camera2/cts/CameraDeviceTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/CameraDeviceTest.java
@@ -151,8 +151,6 @@
any(CameraDevice.class));
mCameraListener = mCameraMockListener;
- createDefaultImageReader(DEFAULT_CAPTURE_SIZE, ImageFormat.YUV_420_888, MAX_NUM_IMAGES,
- new ImageDropperListener());
}
@Override
@@ -447,7 +445,6 @@
public void testChainedOperation() throws Throwable {
final ArrayList<Surface> outputs = new ArrayList<>();
- outputs.add(mReaderSurface);
// A queue for the chained listeners to push results to
// A success Throwable indicates no errors; other Throwables detail a test failure;
@@ -589,49 +586,60 @@
// Actual test code
for (int i = 0; i < mCameraIds.length; i++) {
- Throwable result;
+ try {
+ Throwable result;
- if (!(new StaticMetadata(mCameraManager.getCameraCharacteristics(mCameraIds[i]))).
- isColorOutputSupported()) {
- Log.i(TAG, "Camera " + mCameraIds[i] + " does not support color outputs, skipping");
- continue;
- }
-
- // Start chained cascade
- ChainedCameraListener cameraListener = new ChainedCameraListener();
- mCameraManager.openCamera(mCameraIds[i], cameraListener, mHandler);
-
- // Check if open succeeded
- result = results.poll(CAMERA_OPEN_TIMEOUT_MS, TimeUnit.MILLISECONDS);
- if (result != success) {
- if (cameraListener.cameraDevice != null) cameraListener.cameraDevice.close();
- if (result == null) {
- fail("Timeout waiting for camera open");
- } else {
- throw result;
+ if (!(new StaticMetadata(mCameraManager.getCameraCharacteristics(mCameraIds[i]))).
+ isColorOutputSupported()) {
+ Log.i(TAG, "Camera " + mCameraIds[i] +
+ " does not support color outputs, skipping");
+ continue;
}
- }
- // Check if configure succeeded
- result = results.poll(SESSION_CONFIGURE_TIMEOUT_MS, TimeUnit.MILLISECONDS);
- if (result != success) {
- if (cameraListener.cameraDevice != null) cameraListener.cameraDevice.close();
- if (result == null) {
- fail("Timeout waiting for session configure");
- } else {
- throw result;
- }
- }
+ createDefaultImageReader(DEFAULT_CAPTURE_SIZE, ImageFormat.YUV_420_888,
+ MAX_NUM_IMAGES, new ImageDropperListener());
+ outputs.add(mReaderSurface);
- // Check if capture succeeded
- result = results.poll(CAPTURE_RESULT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
- if (result != success) {
- if (cameraListener.cameraDevice != null) cameraListener.cameraDevice.close();
- if (result == null) {
- fail("Timeout waiting for capture completion");
- } else {
- throw result;
+ // Start chained cascade
+ ChainedCameraListener cameraListener = new ChainedCameraListener();
+ mCameraManager.openCamera(mCameraIds[i], cameraListener, mHandler);
+
+ // Check if open succeeded
+ result = results.poll(CAMERA_OPEN_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+ if (result != success) {
+ if (cameraListener.cameraDevice != null) cameraListener.cameraDevice.close();
+ if (result == null) {
+ fail("Timeout waiting for camera open");
+ } else {
+ throw result;
+ }
}
+
+ // Check if configure succeeded
+ result = results.poll(SESSION_CONFIGURE_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+ if (result != success) {
+ if (cameraListener.cameraDevice != null) cameraListener.cameraDevice.close();
+ if (result == null) {
+ fail("Timeout waiting for session configure");
+ } else {
+ throw result;
+ }
+ }
+
+ // Check if capture succeeded
+ result = results.poll(CAPTURE_RESULT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+ if (result != success) {
+ if (cameraListener.cameraDevice != null) cameraListener.cameraDevice.close();
+ if (result == null) {
+ fail("Timeout waiting for capture completion");
+ } else {
+ throw result;
+ }
+ }
+
+ } finally {
+ closeDefaultImageReader();
+ outputs.clear();
}
}
}
@@ -1836,6 +1844,9 @@
if (!mStaticInfo.isColorOutputSupported()) {
createDefaultImageReader(getMaxDepthSize(mCamera.getId(), mCameraManager),
ImageFormat.DEPTH16, MAX_NUM_IMAGES, new ImageDropperListener());
+ } else {
+ createDefaultImageReader(DEFAULT_CAPTURE_SIZE, ImageFormat.YUV_420_888, MAX_NUM_IMAGES,
+ new ImageDropperListener());
}
List<Surface> outputSurfaces = new ArrayList<>(Arrays.asList(mReaderSurface));
diff --git a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
index 8eff888..d661ffa 100644
--- a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
@@ -27,6 +27,7 @@
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.cts.helpers.CameraErrorCollector;
+import android.hardware.camera2.cts.testcases.Camera2AndroidTestCase;
import android.hardware.camera2.params.BlackLevelPattern;
import android.hardware.camera2.params.ColorSpaceTransform;
import android.hardware.camera2.params.RecommendedStreamConfigurationMap;
@@ -34,7 +35,6 @@
import android.media.CamcorderProfile;
import android.media.ImageReader;
import android.os.Build;
-import android.test.AndroidTestCase;
import android.util.Log;
import android.util.Rational;
import android.util.Range;
@@ -53,11 +53,14 @@
import java.util.Set;
import static android.hardware.camera2.cts.helpers.AssertHelpers.*;
+import static android.hardware.camera2.cts.CameraTestUtils.SimpleCaptureCallback;
+
+import static org.mockito.Mockito.*;
/**
* Extended tests for static camera characteristics.
*/
-public class ExtendedCameraCharacteristicsTest extends AndroidTestCase {
+public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
private static final String TAG = "ExChrsTest"; // must be short so next line doesn't throw
private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
@@ -68,10 +71,8 @@
*/
private static final int MIN_ALLOWABLE_WHITELEVEL = 32; // must have sensor bit depth > 5
- private CameraManager mCameraManager;
private List<CameraCharacteristics> mCharacteristics;
private String[] mIds; // include both standalone camera IDs and "hidden" physical camera IDs
- private CameraErrorCollector mCollector;
private static final Size FULLHD = new Size(1920, 1080);
private static final Size FULLHD_ALT = new Size(1920, 1088);
@@ -79,6 +80,10 @@
private static final Size VGA = new Size(640, 480);
private static final Size QVGA = new Size(320, 240);
+ private static final long LOW_LATENCY_THRESHOLD_MS = 200;
+ private static final float LATENCY_TOLERANCE_FACTOR = 1.1f; // 10% tolerance
+ private static final int MAX_NUM_IMAGES = 5;
+ private static final long PREVIEW_RUN_MS = 500;
private static final long FRAME_DURATION_30FPS_NSEC = (long) 1e9 / 30;
/*
* HW Levels short hand
@@ -114,19 +119,11 @@
private static final int HIGH_SPEED_FPS_UPPER_MIN = 120;
@Override
- public void setContext(Context context) {
- super.setContext(context);
- mCameraManager = (CameraManager)context.getSystemService(Context.CAMERA_SERVICE);
- assertNotNull("Can't connect to camera manager", mCameraManager);
- }
-
- @Override
protected void setUp() throws Exception {
super.setUp();
String[] ids = mCameraManager.getCameraIdList();
ArrayList<String> allIds = new ArrayList<String>();
mCharacteristics = new ArrayList<>();
- mCollector = new CameraErrorCollector();
for (int i = 0; i < ids.length; i++) {
CameraCharacteristics props = mCameraManager.getCameraCharacteristics(ids[i]);
assertNotNull(String.format("Can't get camera characteristics from: ID %s", ids[i]),
@@ -150,16 +147,8 @@
@Override
protected void tearDown() throws Exception {
+ super.tearDown();
mCharacteristics = null;
-
- try {
- mCollector.verify();
- } catch (Throwable e) {
- // When new Exception(e) is used, exception info will be printed twice.
- throw new Exception(e.getMessage());
- } finally {
- super.tearDown();
- }
}
/**
@@ -679,7 +668,85 @@
}
}
- public void testRecommendedStreamConfigurations() {
+ private void checkFormatLatency(int format, long latencyThresholdMs,
+ RecommendedStreamConfigurationMap configMap) throws Exception {
+ Set<Size> availableSizes = configMap.getOutputSizes(format);
+ assertNotNull(String.format("No available sizes for output format: %d", format),
+ availableSizes);
+
+ ImageReader previewReader = null;
+ long threshold = (long) (latencyThresholdMs * LATENCY_TOLERANCE_FACTOR);
+ // for each resolution, check that the end-to-end latency doesn't exceed the given threshold
+ for (Size sz : availableSizes) {
+ try {
+ // Create ImageReaders, capture session and requests
+ final ImageReader.OnImageAvailableListener mockListener = mock(
+ ImageReader.OnImageAvailableListener.class);
+ createDefaultImageReader(sz, format, MAX_NUM_IMAGES, mockListener);
+ Size previewSize = mOrderedPreviewSizes.get(0);
+ previewReader = createImageReader(previewSize, ImageFormat.YUV_420_888,
+ MAX_NUM_IMAGES, new CameraTestUtils.ImageDropperListener());
+ Surface previewSurface = previewReader.getSurface();
+ List<Surface> surfaces = new ArrayList<Surface>();
+ surfaces.add(previewSurface);
+ surfaces.add(mReaderSurface);
+ createSession(surfaces);
+ CaptureRequest.Builder captureBuilder =
+ mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+ captureBuilder.addTarget(previewSurface);
+ CaptureRequest request = captureBuilder.build();
+
+ // Let preview run for a while
+ startCapture(request, /*repeating*/ true, new SimpleCaptureCallback(), mHandler);
+ Thread.sleep(PREVIEW_RUN_MS);
+
+ // Start capture.
+ captureBuilder = mCamera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
+ captureBuilder.addTarget(mReaderSurface);
+ request = captureBuilder.build();
+
+ for (int i = 0; i < MAX_NUM_IMAGES; i++) {
+ startCapture(request, /*repeating*/ false, new SimpleCaptureCallback(),
+ mHandler);
+ verify(mockListener, timeout(threshold).times(1)).onImageAvailable(
+ any(ImageReader.class));
+ reset(mockListener);
+ }
+
+ // stop capture.
+ stopCapture(/*fast*/ false);
+ } finally {
+ closeDefaultImageReader();
+
+ if (previewReader != null) {
+ previewReader.close();
+ previewReader = null;
+ }
+ }
+
+ }
+ }
+
+ private void verifyRecommendedLowLatencyConfiguration(String cameraId, CameraCharacteristics c,
+ RecommendedStreamConfigurationMap lowLatencyConfig) throws Exception {
+ verifyCommonRecommendedConfiguration(cameraId, c, lowLatencyConfig, /*checkNoInput*/ true,
+ /*checkNoHighRes*/ false, /*checkNoHighSpeed*/ true, /*checkNoPrivate*/ false,
+ /*checkNoDepth*/ true);
+
+ try {
+ openDevice(cameraId);
+
+ Set<Integer> formats = lowLatencyConfig.getOutputFormats();
+ for (Integer format : formats) {
+ checkFormatLatency(format.intValue(), LOW_LATENCY_THRESHOLD_MS, lowLatencyConfig);
+ }
+ } finally {
+ closeDevice(cameraId);
+ }
+
+ }
+
+ public void testRecommendedStreamConfigurations() throws Exception {
int counter = 0;
for (CameraCharacteristics c : mCharacteristics) {
int[] actualCapabilities = c.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
@@ -703,7 +770,7 @@
try {
RecommendedStreamConfigurationMap map = c.getRecommendedStreamConfigurationMap(
- RecommendedStreamConfigurationMap.USECASE_RAW + 1);
+ RecommendedStreamConfigurationMap.USECASE_LOW_LATENCY_SNAPSHOT + 1);
fail("Recommended configuration map shouldn't be available for invalid " +
"use case!");
} catch (IllegalArgumentException e) {
@@ -728,9 +795,12 @@
RecommendedStreamConfigurationMap zslConfig =
c.getRecommendedStreamConfigurationMap(
RecommendedStreamConfigurationMap.USECASE_ZSL);
+ RecommendedStreamConfigurationMap lowLatencyConfig =
+ c.getRecommendedStreamConfigurationMap(
+ RecommendedStreamConfigurationMap.USECASE_LOW_LATENCY_SNAPSHOT);
if ((previewConfig == null) && (videoRecordingConfig == null) &&
(videoSnapshotConfig == null) && (snapshotConfig == null) &&
- (rawConfig == null) && (zslConfig == null)) {
+ (rawConfig == null) && (zslConfig == null) && (lowLatencyConfig == null)) {
Log.i(TAG, "Camera " + mIds[counter] +
" doesn't support recommended configurations, skipping test");
continue;
@@ -766,6 +836,10 @@
verifyRecommendedZSLConfiguration(mIds[counter], c, zslConfig);
}
+ if (lowLatencyConfig != null) {
+ verifyRecommendedLowLatencyConfiguration(mIds[counter], c, lowLatencyConfig);
+ }
+
counter++;
}
}
diff --git a/tests/camera/src/android/hardware/camera2/cts/RobustnessTest.java b/tests/camera/src/android/hardware/camera2/cts/RobustnessTest.java
index a519101..988a7f9 100644
--- a/tests/camera/src/android/hardware/camera2/cts/RobustnessTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/RobustnessTest.java
@@ -1552,7 +1552,13 @@
"Testing Camera %s for abandoning surface of a repeating request", id));
openDevice(id);
+ if (!mStaticInfo.isColorOutputSupported()) {
+ Log.i(TAG, "Camera " + id + " does not support color output, skipping");
+ continue;
+ }
+
try {
+
SurfaceTexture preview = new SurfaceTexture(/*random int*/ 1);
Surface previewSurface = new Surface(preview);
diff --git a/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2AndroidTestCase.java b/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2AndroidTestCase.java
index 55a4399..194266a 100644
--- a/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2AndroidTestCase.java
+++ b/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2AndroidTestCase.java
@@ -440,11 +440,15 @@
}
protected CaptureRequest prepareCaptureRequest() throws Exception {
+ return prepareCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+ }
+
+ protected CaptureRequest prepareCaptureRequest(int template) throws Exception {
List<Surface> outputSurfaces = new ArrayList<Surface>();
Surface surface = mReader.getSurface();
assertNotNull("Fail to get surface from ImageReader", surface);
outputSurfaces.add(surface);
- return prepareCaptureRequestForSurfaces(outputSurfaces, CameraDevice.TEMPLATE_PREVIEW)
+ return prepareCaptureRequestForSurfaces(outputSurfaces, template)
.build();
}
diff --git a/tests/camera/src/android/hardware/cts/CameraTest.java b/tests/camera/src/android/hardware/cts/CameraTest.java
index 6b2ecc5..51605f0 100644
--- a/tests/camera/src/android/hardware/cts/CameraTest.java
+++ b/tests/camera/src/android/hardware/cts/CameraTest.java
@@ -514,6 +514,7 @@
initializeMessageLooper(cameraId);
Parameters params = mCamera.getParameters();
if(!params.isVideoStabilizationSupported()) {
+ terminateMessageLooper();
return;
}
//Check whether we can support preview callbacks along with stabilization
diff --git a/tests/contentcaptureservice/OWNERS b/tests/contentcaptureservice/OWNERS
new file mode 100644
index 0000000..4df1ffa
--- /dev/null
+++ b/tests/contentcaptureservice/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 544200
+felipeal@google.com
\ No newline at end of file
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/AbstractContentCaptureIntegrationTest.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/AbstractContentCaptureIntegrationTest.java
index e37d48e..af0116e 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/AbstractContentCaptureIntegrationTest.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/AbstractContentCaptureIntegrationTest.java
@@ -42,6 +42,7 @@
import androidx.test.runner.AndroidJUnit4;
import com.android.compatibility.common.util.DeviceConfigStateChangerRule;
+import com.android.compatibility.common.util.DeviceConfigStateManager;
import com.android.compatibility.common.util.RequiredServiceRule;
import com.android.compatibility.common.util.SafeCleanerRule;
import com.android.compatibility.common.util.SettingsStateChangerRule;
@@ -65,6 +66,10 @@
private static final String TAG = AbstractContentCaptureIntegrationTest.class.getSimpleName();
+ protected static final DeviceConfigStateManager sKillSwitchManager =
+ new DeviceConfigStateManager(sContext, DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
+ ContentCaptureManager.DEVICE_CONFIG_PROPERTY_SERVICE_EXPLICITLY_ENABLED);
+
private final String mTag = getClass().getSimpleName();
protected ActivitiesWatcher mActivitiesWatcher;
@@ -103,12 +108,14 @@
return CtsContentCaptureService.getExceptions();
});
+ private final DeviceConfigStateChangerRule mKillSwitchKillerRule =
+ new DeviceConfigStateChangerRule(sKillSwitchManager, "true");
+
private final SettingsStateChangerRule mFeatureEnablerRule = new SettingsStateChangerRule(
sContext, CONTENT_CAPTURE_ENABLED, "1");
@Rule
public final RuleChain mLookAllTheseRules = RuleChain
- //
// mRequiredServiceRule should be first so the test can be skipped right away
.outerRule(mRequiredServiceRule)
@@ -116,14 +123,15 @@
.around(mVerboseLoggingRule)
// enable it as soon as possible, as it have to wait for the listener
+ .around(mKillSwitchKillerRule)
.around(mFeatureEnablerRule)
- //
+
// mLoggingRule wraps the test but doesn't interfere with it
.around(mLoggingRule)
- //
+
// mSafeCleanerRule will catch errors
.around(mSafeCleanerRule)
- //
+
// Finally, let subclasses set their own rule
.around(getMainTestRule());
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankActivityTest.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankActivityTest.java
index d62bdaf..889542e 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankActivityTest.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankActivityTest.java
@@ -144,7 +144,7 @@
final BlankActivity activity = launchActivity();
watcher.waitFor(RESUMED);
- service.disableContentCaptureServices();
+ service.disableSelf();
activity.finish();
watcher.waitFor(DESTROYED);
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CanaryTest.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CanaryTest.java
index f1fb439..704dc7b 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CanaryTest.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CanaryTest.java
@@ -64,4 +64,11 @@
assertWithMessage("Should be enabled when resource '%s' is not empty (settings='%s')",
serviceName, enableSettings).that(hasService).isTrue();
}
+
+ // TODO(b/128571561): temporary test to make sure the CtsContentCaptureServiceTestCases is
+ // running - if nobody files a bug due to this failure, it means it isn't :-(
+ @Test
+ public void test_Y_U_NO_PASS_QUESTION_MARK() throws Exception {
+ throw new Exception("If you're seeing this error in an automated test, please file a bug");
+ }
}
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ChildlessActivityTest.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ChildlessActivityTest.java
index 4e2e5c3..09588e5 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ChildlessActivityTest.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ChildlessActivityTest.java
@@ -49,7 +49,6 @@
import android.contentcaptureservice.cts.common.ActivityLauncher;
import android.os.SystemClock;
import android.platform.test.annotations.AppModeFull;
-import android.provider.DeviceConfig;
import android.util.Log;
import android.view.View;
import android.view.autofill.AutofillId;
@@ -65,14 +64,9 @@
import androidx.annotation.Nullable;
import androidx.test.rule.ActivityTestRule;
-import com.android.compatibility.common.util.DeviceConfigStateChangerRule;
-import com.android.compatibility.common.util.DeviceConfigStateManager;
-
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import org.junit.rules.RuleChain;
-import org.junit.rules.TestRule;
import java.util.Arrays;
import java.util.List;
@@ -87,14 +81,6 @@
private static final ActivityTestRule<ChildlessActivity> sActivityRule = new ActivityTestRule<>(
ChildlessActivity.class, false, false);
- private static final DeviceConfigStateManager sDeviceConfigManager =
- new DeviceConfigStateManager(sContext, DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
- ContentCaptureManager.DEVICE_CONFIG_PROPERTY_SERVICE_EXPLICITLY_ENABLED);
-
- private static final RuleChain sMyRules = RuleChain
- .outerRule(new DeviceConfigStateChangerRule(sDeviceConfigManager, "true"))
- .around(sActivityRule);
-
public ChildlessActivityTest() {
super(ChildlessActivity.class);
}
@@ -104,11 +90,6 @@
return sActivityRule;
}
- @Override
- protected TestRule getMainTestRule() {
- return sMyRules;
- }
-
@Before
@After
public void resetActivityStaticState() {
@@ -229,6 +210,7 @@
.activityStopped(name1)
.activityPaused(name2)
.activityResumed(name1)
+ .activityDestroyed(name2)
.activityPaused(name1);
// Assert the sessions
@@ -1080,7 +1062,7 @@
// The service cannot re-enable itself, so we use settings instead.
setFeatureEnabledBySettings(true);
} else {
- service.disableContentCaptureServices();
+ service.disableSelf();
}
break;
case BY_SETTINGS:
@@ -1268,7 +1250,7 @@
private void setFeatureEnabledByDeviceConfig(@Nullable String value) {
Log.d(TAG, "setFeatureEnabledByDeviceConfig(): " + value);
- sDeviceConfigManager.set(value);
+ sKillSwitchManager.set(value);
}
@NonNull
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CtsContentCaptureService.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CtsContentCaptureService.java
index c5f8a17..224aef3 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CtsContentCaptureService.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CtsContentCaptureService.java
@@ -552,6 +552,14 @@
return this;
}
+ @NonNull
+ public EventsAssertor activityDestroyed(@NonNull ComponentName expectedActivity) {
+ assertNextEvent((event) -> assertActivityEvent(event, expectedActivity,
+ ActivityEvent.TYPE_ACTIVITY_DESTROYED), "no ACTIVITY_DESTROYED event for %s",
+ expectedActivity);
+ return this;
+ }
+
private void assertNextEvent(@NonNull EventAssertion assertion, @NonNull String errorFormat,
@Nullable Object... errorArgs) {
if (mNextEvent >= mEvents.size()) {
diff --git a/tests/fragment/OWNERS b/tests/fragment/OWNERS
new file mode 100644
index 0000000..a6ac10d
--- /dev/null
+++ b/tests/fragment/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 25700
+ilake@google.com
+adamp@google.com
diff --git a/tests/framework/base/activitymanager/AndroidManifest.xml b/tests/framework/base/activitymanager/AndroidManifest.xml
index fabe2df..c85b868 100644
--- a/tests/framework/base/activitymanager/AndroidManifest.xml
+++ b/tests/framework/base/activitymanager/AndroidManifest.xml
@@ -125,9 +125,6 @@
<activity android:name="android.server.am.lifecycle.ActivityLifecycleClientTestBase$ResultActivity"/>
- <activity android:name="android.server.am.lifecycle.ActivityLifecycleClientTestBase$NoDisplayActivity"
- android:theme="@android:style/Theme.NoDisplay" />
-
<activity android:name="android.server.am.lifecycle.ActivityLifecycleClientTestBase$SingleTopActivity"
android:launchMode="singleTop" />
diff --git a/tests/framework/base/activitymanager/app/AndroidManifest.xml b/tests/framework/base/activitymanager/app/AndroidManifest.xml
index 65269d7..0e8be08 100755
--- a/tests/framework/base/activitymanager/app/AndroidManifest.xml
+++ b/tests/framework/base/activitymanager/app/AndroidManifest.xml
@@ -462,6 +462,19 @@
android:exported="true"
android:launchMode="singleInstance" />
+ <service
+ android:name="android.server.am.LiveWallpaper"
+ android:permission="android.permission.BIND_WALLPAPER">
+ <intent-filter>
+ <action android:name="android.service.wallpaper.WallpaperService">
+ </action>
+ </intent-filter>
+ <meta-data
+ android:name="android.service.wallpaper"
+ android:resource="@xml/wallpaper">
+ </meta-data>
+ </service>
+
<!-- Disable home activities by default or it may disturb other tests by
showing ResolverActivity when start home activity -->
<activity-alias android:name=".HomeActivity"
diff --git a/tests/framework/base/activitymanager/app/res/xml/wallpaper.xml b/tests/framework/base/activitymanager/app/res/xml/wallpaper.xml
new file mode 100644
index 0000000..20f447b
--- /dev/null
+++ b/tests/framework/base/activitymanager/app/res/xml/wallpaper.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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
+ -->
+<wallpaper
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:supportsMultipleDisplays="true"
+/>
diff --git a/tests/framework/base/activitymanager/app/src/android/server/am/Components.java b/tests/framework/base/activitymanager/app/src/android/server/am/Components.java
index 07856d6..1b4b461 100644
--- a/tests/framework/base/activitymanager/app/src/android/server/am/Components.java
+++ b/tests/framework/base/activitymanager/app/src/android/server/am/Components.java
@@ -122,6 +122,7 @@
public static final ComponentName TOP_ACTIVITY = component("TopActivity");
public static final ComponentName TEST_ACTIVITY_WITH_SAME_AFFINITY =
component("TestActivityWithSameAffinity");
+ public static final ComponentName TEST_LIVE_WALLPAPER_SERVICE = component("LiveWallpaper");
public static final ComponentName TOP_LEFT_LAYOUT_ACTIVITY = component("TopLeftLayoutActivity");
public static final ComponentName TOP_RIGHT_LAYOUT_ACTIVITY =
component("TopRightLayoutActivity");
@@ -180,6 +181,16 @@
public static final ComponentName SINGLE_TASK_INSTANCE_DISPLAY_ACTIVITY3 =
component("SingleTaskInstanceDisplayActivity3");
+
+ /**
+ * The keys are used for TestJournalProvider when testing wallpaper component.
+ */
+ public static class TestLiveWallpaperKeys {
+ public static final String COMPONENT = "LiveWallpaper";
+ public static final String ENGINE_CREATED = "engine_created";
+ public static final String ENGINE_DISPLAY_ID = "engine_display_Id";
+ }
+
/**
* Action and extra key constants for {@link #TEST_ACTIVITY}.
*
diff --git a/tests/framework/base/activitymanager/app/src/android/server/am/LiveWallpaper.java b/tests/framework/base/activitymanager/app/src/android/server/am/LiveWallpaper.java
new file mode 100644
index 0000000..dada756
--- /dev/null
+++ b/tests/framework/base/activitymanager/app/src/android/server/am/LiveWallpaper.java
@@ -0,0 +1,49 @@
+/*
+ * 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.server.am;
+
+import static android.server.am.Components.TestLiveWallpaperKeys.COMPONENT;
+import static android.server.am.Components.TestLiveWallpaperKeys.ENGINE_DISPLAY_ID;
+import static android.view.Display.DEFAULT_DISPLAY;
+
+import android.content.Context;
+import android.service.wallpaper.WallpaperService;
+import android.view.SurfaceHolder;
+
+public class LiveWallpaper extends WallpaperService {
+
+ @Override
+ public Engine onCreateEngine() {
+ return new Engine(){
+ @Override
+ public void onCreate(SurfaceHolder surfaceHolder) {
+ super.onCreate(surfaceHolder);
+ final Context baseContext = getBaseContext();
+ final Context displayContext = getDisplayContext();
+ final int displayId = displayContext.getDisplayId();
+
+ // Only need to verify that when it is the secondary display.
+ if (displayId != DEFAULT_DISPLAY) {
+ final String CURRENT_ENGINE_DISPLAY_ID = ENGINE_DISPLAY_ID + displayId;
+ TestJournalProvider.putExtras(baseContext, COMPONENT, bundle -> {
+ bundle.putBoolean(CURRENT_ENGINE_DISPLAY_ID, true);
+ });
+ }
+ }
+ };
+ }
+}
diff --git a/tests/framework/base/activitymanager/backgroundactivity/Android.mk b/tests/framework/base/activitymanager/backgroundactivity/Android.mk
new file mode 100644
index 0000000..642a1e8
--- /dev/null
+++ b/tests/framework/base/activitymanager/backgroundactivity/Android.mk
@@ -0,0 +1,38 @@
+# 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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests optional
+
+LOCAL_PACKAGE_NAME := CtsActivityManagerBackgroundActivityTestCases
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src) \
+ $(call all-java-files-under, ../util/src)
+
+LOCAL_SDK_VERSION := test_current
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ androidx.test.rules \
+ cts-amwm-util \
+ cts-am-app-base \
+ cts-core-test-runner-axt
+
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+
+include $(BUILD_CTS_PACKAGE)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
\ No newline at end of file
diff --git a/tests/framework/base/activitymanager/backgroundactivity/AndroidManifest.xml b/tests/framework/base/activitymanager/backgroundactivity/AndroidManifest.xml
new file mode 100644
index 0000000..f0182e0
--- /dev/null
+++ b/tests/framework/base/activitymanager/backgroundactivity/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.server.am.cts.backgroundactivity">
+
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.server.am.cts.backgroundactivity" />
+</manifest>
diff --git a/tests/framework/base/activitymanager/backgroundactivity/AndroidTest.xml b/tests/framework/base/activitymanager/backgroundactivity/AndroidTest.xml
new file mode 100644
index 0000000..94d757d
--- /dev/null
+++ b/tests/framework/base/activitymanager/backgroundactivity/AndroidTest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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
+ -->
+
+<configuration description="Config for CTS starting background activity test cases">
+ <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="multi_abi" />
+ <target_preparer class="com.android.compatibility.common.tradefed.targetprep.LocationCheck" />
+ <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+ <option name="cleanup-apks" value="true" />
+ <option name="test-file-name" value="CtsActivityManagerBackgroundActivityTestCases.apk" />
+ <option name="test-file-name" value="CtsBackgroundActivityAppA.apk" />
+ <option name="test-file-name" value="CtsBackgroundActivityAppB.apk" />
+ </target_preparer>
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest">
+ <option name="package" value="android.server.am.cts.backgroundactivity" />
+ <option name="runtime-hint" value="1m" />
+ </test>
+</configuration>
diff --git a/tests/jank/Android.mk b/tests/framework/base/activitymanager/backgroundactivity/AppA/Android.mk
similarity index 65%
copy from tests/jank/Android.mk
copy to tests/framework/base/activitymanager/backgroundactivity/AppA/Android.mk
index 2ce4a98..3b39527 100644
--- a/tests/jank/Android.mk
+++ b/tests/framework/base/activitymanager/backgroundactivity/AppA/Android.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2015 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.
@@ -16,25 +16,24 @@
include $(CLEAR_VARS)
-LOCAL_MODULE_TAGS := optional
+# Don't include this package in any target.
+LOCAL_MODULE_TAGS := tests
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+LOCAL_USE_AAPT2 := true
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ cts-am-app-base
+
+LOCAL_STATIC_ANDROID_LIBRARIES := \
+ androidx.legacy_legacy-support-v4
LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_PACKAGE_NAME := CtsJankDeviceTestCases
-LOCAL_SDK_VERSION := current
+LOCAL_SDK_VERSION := test_current
# Tag this module as a cts test artifact
LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-LOCAL_STATIC_JAVA_LIBRARIES := \
- compatibility-device-util-axt \
- ctstestrunner-axt \
- ub-uiautomator \
- androidx.test.janktesthelper \
- junit
+LOCAL_PACKAGE_NAME := CtsBackgroundActivityAppA
-LOCAL_JAVA_LIBRARIES := android.test.base.stubs
-
-include $(BUILD_CTS_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/framework/base/activitymanager/backgroundactivity/AppA/AndroidManifest.xml b/tests/framework/base/activitymanager/backgroundactivity/AppA/AndroidManifest.xml
new file mode 100755
index 0000000..8179b49
--- /dev/null
+++ b/tests/framework/base/activitymanager/backgroundactivity/AppA/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.server.am.cts.backgroundactivity.appa">
+
+ <application>
+ <receiver android:name="android.server.am.StartBackgroundActivityReceiver" android:exported="true"/>
+ <receiver android:name="android.server.am.SendPendingIntentReceiver" android:exported="true"/>
+ <activity android:name="android.server.am.ForegroundActivity" android:exported="true" />
+ <activity android:name="android.server.am.BackgroundActivity" android:exported="true" />
+ </application>
+</manifest>
diff --git a/tests/framework/base/activitymanager/backgroundactivity/AppA/src/android/server/am/BackgroundActivity.java b/tests/framework/base/activitymanager/backgroundactivity/AppA/src/android/server/am/BackgroundActivity.java
new file mode 100644
index 0000000..06fffc9
--- /dev/null
+++ b/tests/framework/base/activitymanager/backgroundactivity/AppA/src/android/server/am/BackgroundActivity.java
@@ -0,0 +1,27 @@
+/*
+ * 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.server.am;
+
+import android.app.Activity;
+
+/**
+ * A background activity that will be launched, for testing if app is able to start background
+ * activity.
+ */
+public class BackgroundActivity extends Activity {
+
+}
diff --git a/tests/framework/base/activitymanager/backgroundactivity/AppA/src/android/server/am/ForegroundActivity.java b/tests/framework/base/activitymanager/backgroundactivity/AppA/src/android/server/am/ForegroundActivity.java
new file mode 100644
index 0000000..78b6aa4
--- /dev/null
+++ b/tests/framework/base/activitymanager/backgroundactivity/AppA/src/android/server/am/ForegroundActivity.java
@@ -0,0 +1,42 @@
+/*
+ * 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.server.am;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+
+/**
+ * Foreground activity that makes AppA as foreground.
+ */
+public class ForegroundActivity extends Activity {
+
+ private static final String LAUNCH_BACKGROUND_ACTIVITY_EXTRA =
+ "LAUNCH_BACKGROUND_ACTIVITY_EXTRA";
+
+ @Override
+ public void onCreate(Bundle bundle) {
+ super.onCreate(bundle);
+ Intent intent = getIntent();
+ boolean launchBackground = intent.getBooleanExtra(LAUNCH_BACKGROUND_ACTIVITY_EXTRA, false);
+ if (launchBackground) {
+ Intent newIntent = new Intent();
+ newIntent.setClass(this, BackgroundActivity.class);
+ startActivity(newIntent);
+ }
+ }
+}
diff --git a/tests/framework/base/activitymanager/backgroundactivity/AppA/src/android/server/am/SendPendingIntentReceiver.java b/tests/framework/base/activitymanager/backgroundactivity/AppA/src/android/server/am/SendPendingIntentReceiver.java
new file mode 100644
index 0000000..9075154
--- /dev/null
+++ b/tests/framework/base/activitymanager/backgroundactivity/AppA/src/android/server/am/SendPendingIntentReceiver.java
@@ -0,0 +1,58 @@
+/*
+ * 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.server.am;
+
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+
+/**
+ * Receive broadcast command to create a pendingIntent and send it to AppB.
+ */
+public class SendPendingIntentReceiver extends BroadcastReceiver {
+
+ private static final String APP_A_PACKAGE_NAME =
+ "android.server.am.cts.backgroundactivity.appa";
+ private static final String APP_B_PACKAGE_NAME =
+ "android.server.am.cts.backgroundactivity.appb";
+ private static final ComponentName APP_A_BACKGROUND_ACTIVITY_COMPONENT = new ComponentName(
+ APP_A_PACKAGE_NAME, "android.server.am.BackgroundActivity");
+ private static final ComponentName APP_B_START_PENDING_INTENT_RECEIVER_COMPONENT =
+ new ComponentName(APP_B_PACKAGE_NAME, "android.server.am.StartPendingIntentReceiver");
+
+ private static final String PENDING_INTENT_EXTRA = "PENDING_INTENT_EXTRA";
+
+ @Override
+ public void onReceive(Context context, Intent notUsed) {
+
+ // Create a pendingIntent to launch appA's BackgroundActivity
+ Intent newIntent = new Intent();
+ newIntent.setComponent(APP_A_BACKGROUND_ACTIVITY_COMPONENT);
+ newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+ PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
+ newIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+
+ // Send the pendingIntent to appB
+ Intent intent = new Intent();
+ intent.setComponent(APP_B_START_PENDING_INTENT_RECEIVER_COMPONENT);
+ intent.putExtra(PENDING_INTENT_EXTRA, pendingIntent);
+ context.sendBroadcast(intent);
+ }
+}
diff --git a/tests/tests/rcs/src/android/telephony/ims/SmsApplicationReceiver.java b/tests/framework/base/activitymanager/backgroundactivity/AppA/src/android/server/am/StartBackgroundActivityReceiver.java
similarity index 62%
copy from tests/tests/rcs/src/android/telephony/ims/SmsApplicationReceiver.java
copy to tests/framework/base/activitymanager/backgroundactivity/AppA/src/android/server/am/StartBackgroundActivityReceiver.java
index 85692bc..72dba2e 100644
--- a/tests/tests/rcs/src/android/telephony/ims/SmsApplicationReceiver.java
+++ b/tests/framework/base/activitymanager/backgroundactivity/AppA/src/android/server/am/StartBackgroundActivityReceiver.java
@@ -11,22 +11,24 @@
* 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.
+ * limitations under the License
*/
-package android.telephony.ims;
+package android.server.am;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
/**
- * This receiver is used to provide the interface required for a default SMS application. It
- * intentionally has no custom behavior.
+ * A class to help test case to start background activity.
*/
-public class SmsApplicationReceiver extends BroadcastReceiver {
+public class StartBackgroundActivityReceiver extends BroadcastReceiver {
+
@Override
- public void onReceive(Context context, Intent intent) {
- // Do nothing
+ public void onReceive(Context context, Intent notUsed) {
+ Intent newIntent = new Intent(context, BackgroundActivity.class);
+ newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(newIntent);
}
}
diff --git a/tests/jank/Android.mk b/tests/framework/base/activitymanager/backgroundactivity/AppB/Android.mk
similarity index 65%
rename from tests/jank/Android.mk
rename to tests/framework/base/activitymanager/backgroundactivity/AppB/Android.mk
index 2ce4a98..57114c3 100644
--- a/tests/jank/Android.mk
+++ b/tests/framework/base/activitymanager/backgroundactivity/AppB/Android.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2015 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.
@@ -16,25 +16,24 @@
include $(CLEAR_VARS)
-LOCAL_MODULE_TAGS := optional
+# Don't include this package in any target.
+LOCAL_MODULE_TAGS := tests
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+LOCAL_USE_AAPT2 := true
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ cts-am-app-base
+
+LOCAL_STATIC_ANDROID_LIBRARIES := \
+ androidx.legacy_legacy-support-v4
LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_PACKAGE_NAME := CtsJankDeviceTestCases
-LOCAL_SDK_VERSION := current
+LOCAL_SDK_VERSION := test_current
# Tag this module as a cts test artifact
LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-LOCAL_STATIC_JAVA_LIBRARIES := \
- compatibility-device-util-axt \
- ctstestrunner-axt \
- ub-uiautomator \
- androidx.test.janktesthelper \
- junit
+LOCAL_PACKAGE_NAME := CtsBackgroundActivityAppB
-LOCAL_JAVA_LIBRARIES := android.test.base.stubs
-
-include $(BUILD_CTS_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/framework/base/activitymanager/backgroundactivity/AppB/AndroidManifest.xml b/tests/framework/base/activitymanager/backgroundactivity/AppB/AndroidManifest.xml
new file mode 100755
index 0000000..5bafee9
--- /dev/null
+++ b/tests/framework/base/activitymanager/backgroundactivity/AppB/AndroidManifest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.server.am.cts.backgroundactivity.appb">
+
+ <application>
+ <receiver android:name="android.server.am.StartPendingIntentReceiver" android:exported="true"/>
+ <activity android:name="android.server.am.ForegroundActivity" android:exported="true" />
+ </application>
+</manifest>
diff --git a/tests/framework/base/activitymanager/backgroundactivity/AppB/src/android/server/am/ForegroundActivity.java b/tests/framework/base/activitymanager/backgroundactivity/AppB/src/android/server/am/ForegroundActivity.java
new file mode 100644
index 0000000..9ae08e7
--- /dev/null
+++ b/tests/framework/base/activitymanager/backgroundactivity/AppB/src/android/server/am/ForegroundActivity.java
@@ -0,0 +1,25 @@
+/*
+ * 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.server.am;
+
+import android.app.Activity;
+
+/**
+ * Foreground activity that makes AppB as foreground.
+ */
+public class ForegroundActivity extends Activity {
+}
diff --git a/tests/framework/base/activitymanager/backgroundactivity/AppB/src/android/server/am/StartPendingIntentReceiver.java b/tests/framework/base/activitymanager/backgroundactivity/AppB/src/android/server/am/StartPendingIntentReceiver.java
new file mode 100644
index 0000000..3b50975
--- /dev/null
+++ b/tests/framework/base/activitymanager/backgroundactivity/AppB/src/android/server/am/StartPendingIntentReceiver.java
@@ -0,0 +1,39 @@
+/*
+ * 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.server.am;
+
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+/**
+ * Receive pending intent from AppA and launch it
+ */
+public class StartPendingIntentReceiver extends BroadcastReceiver {
+ private static final String PENDING_INTENT_EXTRA = "PENDING_INTENT_EXTRA";
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ PendingIntent pendingIntent = intent.getParcelableExtra(PENDING_INTENT_EXTRA);
+ try {
+ pendingIntent.send();
+ } catch (PendingIntent.CanceledException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/tests/framework/base/activitymanager/backgroundactivity/src/android/server/am/BackgroundActivityLaunchTest.java b/tests/framework/base/activitymanager/backgroundactivity/src/android/server/am/BackgroundActivityLaunchTest.java
new file mode 100644
index 0000000..23cb385
--- /dev/null
+++ b/tests/framework/base/activitymanager/backgroundactivity/src/android/server/am/BackgroundActivityLaunchTest.java
@@ -0,0 +1,186 @@
+/*
+ * 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.server.am;
+
+import static android.server.am.ActivityManagerState.STATE_RESUMED;
+import static android.server.am.UiDeviceUtils.pressUnlockButton;
+import static android.server.am.UiDeviceUtils.pressWakeupButton;
+
+import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.app.ActivityManager;
+import android.app.ActivityTaskManager;
+import android.platform.test.annotations.Presubmit;
+
+import android.content.ComponentName;
+import android.content.Intent;
+
+import androidx.test.InstrumentationRegistry;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * This class covers all test cases for starting/blocking background activities.
+ * As instrumentation tests started by shell are whitelisted to allow starting background activity,
+ * tests can't be done in this app alone.
+ * Hence, there are 2 extra apps, appA and appB. This class will send commands to appA/appB, for
+ * example, send a broadcast to appA and ask it to start a background activity, and we will monitor
+ * the result and see if it starts an activity successfully.
+ */
+@Presubmit
+public class BackgroundActivityLaunchTest extends ActivityManagerTestBase {
+
+ private static final int ACTIVITY_FOCUS_TIMEOUT_MS = 3000;
+
+ private static final String APP_A_PACKAGE_NAME = "android.server.am.cts.backgroundactivity.appa";
+ private static final String APP_B_PACKAGE_NAME = "android.server.am.cts.backgroundactivity.appb";
+
+ private static final ComponentName APP_A_START_ACTIVITY_RECEIVER_COMPONENT = new ComponentName(
+ APP_A_PACKAGE_NAME, "android.server.am.StartBackgroundActivityReceiver");
+ private static final ComponentName APP_A_BACKGROUND_ACTIVITY_COMPONENT = new ComponentName(
+ APP_A_PACKAGE_NAME, "android.server.am.BackgroundActivity");
+ private static final ComponentName APP_A_FOREGROUND_ACTIVITY_COMPONENT = new ComponentName(
+ APP_A_PACKAGE_NAME, "android.server.am.ForegroundActivity");
+ private static final ComponentName APP_A_SEND_PENDING_INTENT_RECEIVER_COMPONENT =
+ new ComponentName(APP_A_PACKAGE_NAME, "android.server.am.SendPendingIntentReceiver");
+ private static final ComponentName APP_B_FOREGROUND_ACTIVITY_COMPONENT = new ComponentName(
+ APP_B_PACKAGE_NAME, "android.server.am.ForegroundActivity");
+ private static final String LAUNCH_BACKGROUND_ACTIVITY_EXTRA =
+ "LAUNCH_BACKGROUND_ACTIVITY_EXTRA";
+
+ private final ActivityManagerState mAmState = new ActivityManagerState();
+
+ @Before
+ public void setUp() throws Exception {
+ mContext = InstrumentationRegistry.getContext();
+ mAm = mContext.getSystemService(ActivityManager.class);
+ mAtm = mContext.getSystemService(ActivityTaskManager.class);
+
+ pressWakeupButton();
+ pressUnlockButton();
+ removeStacksWithActivityTypes(ALL_ACTIVITY_TYPE_BUT_HOME);
+
+ runShellCommand("cmd deviceidle tempwhitelist -d 100000 " + APP_A_PACKAGE_NAME);
+ runShellCommand("cmd deviceidle tempwhitelist -d 100000 " + APP_B_PACKAGE_NAME);
+ }
+
+ @Test
+ public void testBackgroundActivityBlocked() throws Exception {
+ // Start AppA background activity and blocked
+ Intent intent = new Intent();
+ intent.setComponent(APP_A_START_ACTIVITY_RECEIVER_COMPONENT);
+ mContext.sendBroadcast(intent);
+ boolean result = waitForActivity(ACTIVITY_FOCUS_TIMEOUT_MS,
+ APP_A_BACKGROUND_ACTIVITY_COMPONENT);
+ assertFalse("Should not able to launch background activity", result);
+ }
+
+ @Test
+ public void testBackgroundActivityNotBlockedWhenForegroundActivityExists() throws Exception {
+ // Start AppA foreground activity
+ Intent intent = new Intent();
+ intent.setComponent(APP_A_FOREGROUND_ACTIVITY_COMPONENT);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivity(intent);
+ boolean result = waitForActivity(ACTIVITY_FOCUS_TIMEOUT_MS,
+ APP_A_FOREGROUND_ACTIVITY_COMPONENT);
+ assertTrue("Not able to start foreground Activity", result);
+
+ // Start AppA background activity successfully as there's a foreground activity
+ intent = new Intent();
+ intent.setComponent(APP_A_START_ACTIVITY_RECEIVER_COMPONENT);
+ mContext.sendBroadcast(intent);
+ result = waitForActivity(ACTIVITY_FOCUS_TIMEOUT_MS, APP_A_BACKGROUND_ACTIVITY_COMPONENT);
+ assertTrue("Not able to launch background activity", result);
+ }
+
+ @Test
+ public void testActivityNotBlockedwhenForegroundActivityLaunch() throws Exception {
+ // Start foreground activity, and foreground activity able to launch background activity
+ // successfully
+ Intent intent = new Intent();
+ intent.setComponent(APP_A_FOREGROUND_ACTIVITY_COMPONENT);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.putExtra(LAUNCH_BACKGROUND_ACTIVITY_EXTRA, true);
+ mContext.startActivity(intent);
+ boolean result = waitForActivity(ACTIVITY_FOCUS_TIMEOUT_MS,
+ APP_A_BACKGROUND_ACTIVITY_COMPONENT);
+ assertTrue("Not able to launch background activity", result);
+ }
+
+ @Test
+ public void testPendingIntentActivityBlocked() throws Exception {
+ // Cannot start activity by pending intent, as both appA and appB are in background
+ Intent intent = new Intent();
+ intent.setComponent(APP_A_SEND_PENDING_INTENT_RECEIVER_COMPONENT);
+ mContext.sendBroadcast(intent);
+ boolean result = waitForActivity(ACTIVITY_FOCUS_TIMEOUT_MS,
+ APP_A_BACKGROUND_ACTIVITY_COMPONENT);
+ assertFalse("Should not able to launch background activity", result);
+ }
+
+ @Test
+ public void testPendingIntentActivityNotBlocked_appAIsForeground() throws Exception {
+ // Start AppA foreground activity
+ Intent intent = new Intent();
+ intent.setComponent(APP_A_FOREGROUND_ACTIVITY_COMPONENT);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivity(intent);
+ boolean result = waitForActivity(ACTIVITY_FOCUS_TIMEOUT_MS,
+ APP_A_FOREGROUND_ACTIVITY_COMPONENT);
+ assertTrue("Not able to start foreground Activity", result);
+
+ // Send pendingIntent from AppA to AppB, and the AppB launch the pending intent to start
+ // activity in App A
+ intent = new Intent();
+ intent.setComponent(APP_A_SEND_PENDING_INTENT_RECEIVER_COMPONENT);
+ mContext.sendBroadcast(intent);
+ result = waitForActivity(ACTIVITY_FOCUS_TIMEOUT_MS, APP_A_BACKGROUND_ACTIVITY_COMPONENT);
+ assertTrue("Not able to launch background activity", result);
+ }
+
+ @Test
+ public void testPendingIntentBroadcastActivityNotBlocked_appBIsForeground() throws Exception {
+ // Start AppB foreground activity
+ Intent intent = new Intent();
+ intent.setComponent(APP_B_FOREGROUND_ACTIVITY_COMPONENT);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivity(intent);
+ boolean result = waitForActivity(ACTIVITY_FOCUS_TIMEOUT_MS,
+ APP_B_FOREGROUND_ACTIVITY_COMPONENT);
+ assertTrue("Not able to start foreground Activity", result);
+
+ // Send pendingIntent from AppA to AppB, and the AppB launch the pending intent to start
+ // activity in App A
+ intent = new Intent();
+ intent.setComponent(APP_A_SEND_PENDING_INTENT_RECEIVER_COMPONENT);
+ mContext.sendBroadcast(intent);
+ result = waitForActivity(ACTIVITY_FOCUS_TIMEOUT_MS, APP_A_BACKGROUND_ACTIVITY_COMPONENT);
+ assertTrue("Not able to launch background activity", result);
+ }
+
+ // Return true if the activity is shown before timeout
+ private boolean waitForActivity(int timeoutMs, ComponentName componentName) {
+ mAmWmState.waitForActivityState(componentName, STATE_RESUMED);
+ return componentName.flattenToString().equals(mAmWmState.getAmState().getFocusedActivity());
+ }
+}
\ No newline at end of file
diff --git a/tests/framework/base/activitymanager/src/android/server/am/KeyguardTests.java b/tests/framework/base/activitymanager/src/android/server/am/KeyguardTests.java
index a84a892..571e427 100755
--- a/tests/framework/base/activitymanager/src/android/server/am/KeyguardTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/KeyguardTests.java
@@ -605,14 +605,10 @@
* AOD is disabled for the default display, AOD status shouldn't be checked.
*/
private void testScreenOffWhileOccludedStopsActivity(boolean assertAod) {
- try (final LockScreenSession lockScreenSession
- = new LockScreenSession()) {
+ try (final LockScreenSession lockScreenSession = new LockScreenSession()) {
separateTestJournal();
lockScreenSession.gotoKeyguard();
mAmWmState.assertKeyguardShowingAndNotOccluded();
- if (assertAod) {
- mAmWmState.assertAodShowing();
- }
launchActivity(SHOW_WHEN_LOCKED_ATTR_ACTIVITY);
waitAndAssertTopResumedActivity(SHOW_WHEN_LOCKED_ATTR_ACTIVITY, DEFAULT_DISPLAY,
"Activity with showWhenLocked attribute should be resumed.");
@@ -621,6 +617,9 @@
mAmWmState.assertAodNotShowing();
}
lockScreenSession.sleepDevice();
+ if (assertAod) {
+ mAmWmState.assertAodShowing();
+ }
mAmWmState.waitForAllStoppedActivities();
assertSingleLaunchAndStop(SHOW_WHEN_LOCKED_ATTR_ACTIVITY);
}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/MultiDisplaySystemDecorationTests.java b/tests/framework/base/activitymanager/src/android/server/am/MultiDisplaySystemDecorationTests.java
index 0618c4f..acdc662 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/MultiDisplaySystemDecorationTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/MultiDisplaySystemDecorationTests.java
@@ -21,6 +21,10 @@
import static android.server.am.Components.SECONDARY_HOME_ACTIVITY;
import static android.server.am.Components.SINGLE_HOME_ACTIVITY;
import static android.server.am.Components.SINGLE_SECONDARY_HOME_ACTIVITY;
+import static android.server.am.Components.TEST_LIVE_WALLPAPER_SERVICE;
+import static android.server.am.Components.TestLiveWallpaperKeys.COMPONENT;
+import static android.server.am.Components.TestLiveWallpaperKeys.ENGINE_DISPLAY_ID;
+import static android.server.am.StateLogger.logAlways;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
@@ -33,18 +37,23 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
-import static org.junit.Assume.assumeNotNull;
import static org.junit.Assume.assumeTrue;
import android.app.Activity;
+import android.app.WallpaperManager;
+import android.content.ComponentName;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.res.Configuration;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.SystemClock;
import android.platform.test.annotations.Presubmit;
import android.server.am.ActivityManagerState.ActivityDisplay;
+import android.server.am.TestJournalProvider.TestJournalContainer;
import android.server.am.WindowManagerState.WindowState;
import android.text.TextUtils;
import android.view.WindowManager;
@@ -55,6 +64,7 @@
import com.android.compatibility.common.util.ImeAwareEditText;
import com.android.compatibility.common.util.SystemUtil;
+import com.android.compatibility.common.util.TestUtils;
import com.android.cts.mockime.ImeEvent;
import com.android.cts.mockime.ImeEventStream;
import com.android.cts.mockime.ImeSettings;
@@ -95,16 +105,38 @@
// Wallpaper related tests
/**
+ * Test WallpaperService.Engine#getDisplayContext can work on secondary display.
+ */
+ @Test
+ public void testWallpaperGetDisplayContext() throws Exception {
+ try (final ChangeWallpaperSession wallpaperSession = new ChangeWallpaperSession();
+ final VirtualDisplaySession virtualDisplaySession = new VirtualDisplaySession()) {
+
+ TestJournalContainer.start();
+
+ final ActivityDisplay newDisplay = virtualDisplaySession.setPublicDisplay(true)
+ .setShowSystemDecorations(true)
+ .createDisplay();
+
+ wallpaperSession.setWallpaperComponent(TEST_LIVE_WALLPAPER_SERVICE);
+ final String TARGET_ENGINE_DISPLAY_ID = ENGINE_DISPLAY_ID + newDisplay.mId;
+ final TestJournalProvider.TestJournal journal = TestJournalContainer.get(COMPONENT);
+ TestUtils.waitUntil("Waiting for wallpaper engine bounded", 5 /* timeoutSecond */,
+ () -> journal.extras.getBoolean(TARGET_ENGINE_DISPLAY_ID));
+ }
+ }
+
+ /**
* Tests that wallpaper shows on secondary displays.
*/
@Test
public void testWallpaperShowOnSecondaryDisplays() throws Exception {
- mAmWmState.computeState(true);
- final WindowManagerState.WindowState wallpaper =
- mAmWmState.getWmState().findFirstWindowWithType(TYPE_WALLPAPER);
- // Skip if there is no wallpaper.
- assumeNotNull(wallpaper);
- try (final VirtualDisplaySession virtualDisplaySession = new VirtualDisplaySession()) {
+ try (final ChangeWallpaperSession wallpaperSession = new ChangeWallpaperSession();
+ final VirtualDisplaySession virtualDisplaySession = new VirtualDisplaySession()) {
+
+ final Bitmap tmpWallpaper = wallpaperSession.getTestBitmap();
+ wallpaperSession.setImageWallpaper(tmpWallpaper);
+
final ActivityDisplay noDecorDisplay = virtualDisplaySession.setPublicDisplay(true)
.setShowSystemDecorations(false).createDisplay();
// Tests when the system decor flag is included in that display, the wallpaper must
@@ -122,6 +154,42 @@
}
}
+ private class ChangeWallpaperSession implements AutoCloseable {
+ private final WallpaperManager mWallpaperManager;
+ private Bitmap mTestBitmap;
+
+ public ChangeWallpaperSession() {
+ mWallpaperManager = WallpaperManager.getInstance(mContext);
+ }
+
+ public Bitmap getTestBitmap() {
+ if (mTestBitmap == null) {
+ mTestBitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
+ final Canvas canvas = new Canvas(mTestBitmap);
+ canvas.drawColor(Color.BLUE);
+ }
+ return mTestBitmap;
+ }
+
+ public void setImageWallpaper(Bitmap bitmap) throws Exception {
+ SystemUtil.runWithShellPermissionIdentity(() ->
+ mWallpaperManager.setBitmap(bitmap));
+ }
+
+ public void setWallpaperComponent(ComponentName componentName) throws Exception {
+ SystemUtil.runWithShellPermissionIdentity(() ->
+ mWallpaperManager.setWallpaperComponent(componentName));
+ }
+
+ @Override
+ public void close() throws Exception {
+ SystemUtil.runWithShellPermissionIdentity(mWallpaperManager::clearWallpaper);
+ if (mTestBitmap != null) {
+ mTestBitmap.recycle();
+ }
+ }
+ }
+
private boolean isWallpaperOnDisplay(WindowManagerState windowManagerState, int displayId) {
return windowManagerState.getMatchingWindowType(TYPE_WALLPAPER).stream().anyMatch(
w -> w.getDisplayId() == displayId);
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleClientTestBase.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleClientTestBase.java
index 2fceac4..a5f9507 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleClientTestBase.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleClientTestBase.java
@@ -59,12 +59,8 @@
public class ActivityLifecycleClientTestBase extends ActivityManagerDisplayTestBase {
static final String EXTRA_RECREATE = "recreate";
- static final String EXTRA_FINISH_IN_ON_CREATE = "finish_in_on_create";
- static final String EXTRA_FINISH_IN_ON_START = "finish_in_on_start";
static final String EXTRA_FINISH_IN_ON_RESUME = "finish_in_on_resume";
static final String EXTRA_FINISH_AFTER_RESUME = "finish_after_resume";
- static final String EXTRA_FINISH_IN_ON_PAUSE = "finish_in_on_pause";
- static final String EXTRA_FINISH_IN_ON_STOP = "finish_in_on_stop";
static final ComponentName CALLBACK_TRACKING_ACTIVITY =
getComponentName(CallbackTrackingActivity.class);
@@ -120,12 +116,6 @@
final ActivityTestRule mSlowActivityTestRule = new ActivityTestRule(
SlowActivity.class, true /* initialTouchMode */, false /* launchActivity */);
- final ActivityTestRule mResultActivityTestRule = new ActivityTestRule(
- ResultActivity.class, true /* initialTouchMode */, false /* launchActivity */);
-
- final ActivityTestRule mNoDisplayActivityTestRule = new ActivityTestRule(
- NoDisplayActivity.class, true /* initialTouchMode */, false /* launchActivity */);
-
private static LifecycleLog mLifecycleLog;
protected Context mTargetContext;
@@ -364,28 +354,12 @@
}
}
- /** Test activity that is started for result and finishes itself. */
+ /** Test activity that is started for result and finishes itself in ON_RESUME. */
public static class ResultActivity extends CallbackTrackingActivity {
@Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setResult(RESULT_OK);
- if (getIntent().getBooleanExtra(EXTRA_FINISH_IN_ON_CREATE, false)) {
- finish();
- }
- }
-
- @Override
- protected void onStart() {
- super.onStart();
- if (getIntent().getBooleanExtra(EXTRA_FINISH_IN_ON_START, false)) {
- finish();
- }
- }
-
- @Override
protected void onResume() {
super.onResume();
+ setResult(RESULT_OK);
final Intent intent = getIntent();
if (intent.getBooleanExtra(EXTRA_FINISH_IN_ON_RESUME, false)) {
finish();
@@ -393,26 +367,6 @@
new Handler().postDelayed(() -> finish(), 2000);
}
}
-
- @Override
- protected void onPause() {
- super.onPause();
- if (getIntent().getBooleanExtra(EXTRA_FINISH_IN_ON_PAUSE, false)) {
- finish();
- }
- }
-
- @Override
- protected void onStop() {
- super.onStop();
- if (getIntent().getBooleanExtra(EXTRA_FINISH_IN_ON_STOP, false)) {
- finish();
- }
- }
- }
-
- /** Test activity with NoDisplay theme that can finish itself. */
- public static class NoDisplayActivity extends ResultActivity {
}
/** Test activity that can call {@link Activity#recreate()} if requested in a new intent. */
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTests.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTests.java
index f6f8ff0..f410bac 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTests.java
@@ -51,7 +51,6 @@
import androidx.test.filters.FlakyTest;
import androidx.test.filters.MediumTest;
-import androidx.test.rule.ActivityTestRule;
import com.android.compatibility.common.util.AmUtils;
@@ -751,84 +750,4 @@
LifecycleVerifier.assertSequenceMatchesOneOf(SingleTopActivity.class, getLifecycleLog(),
Arrays.asList(expectedSequence, extraPauseSequence), "newIntent");
}
-
- @Test
- public void testFinishInOnCreate() throws Exception {
- verifyFinishAtStage(mResultActivityTestRule, ResultActivity.class,
- EXTRA_FINISH_IN_ON_CREATE, "onCreate");
- }
-
- @Test
- public void testFinishInOnCreateNoDisplay() throws Exception {
- verifyFinishAtStage(mNoDisplayActivityTestRule, NoDisplayActivity.class,
- EXTRA_FINISH_IN_ON_CREATE, "onCreate");
- }
-
- @Test
- public void testFinishInOnStart() throws Exception {
- verifyFinishAtStage(mResultActivityTestRule, ResultActivity.class,
- EXTRA_FINISH_IN_ON_START, "onStart");
- }
-
- @Test
- public void testFinishInOnStartNoDisplay() throws Exception {
- verifyFinishAtStage(mNoDisplayActivityTestRule, NoDisplayActivity.class,
- EXTRA_FINISH_IN_ON_START, "onStart");
- }
-
- @Test
- public void testFinishInOnResume() throws Exception {
- verifyFinishAtStage(mResultActivityTestRule, ResultActivity.class,
- EXTRA_FINISH_IN_ON_RESUME, "onResume");
- }
-
- @Test
- public void testFinishInOnResumeNoDisplay() throws Exception {
- verifyFinishAtStage(mNoDisplayActivityTestRule, NoDisplayActivity.class,
- EXTRA_FINISH_IN_ON_RESUME, "onResume");
- }
-
- private void verifyFinishAtStage(ActivityTestRule rule, Class<? extends Activity> activityClass,
- String finishStageExtra, String stageName) {
- final Intent intent = new Intent();
- intent.putExtra(finishStageExtra, true);
- rule.launchActivity(intent);
-
- final List<LifecycleLog.ActivityCallback> expectedSequence =
- LifecycleVerifier.getLaunchAndDestroySequence(activityClass);
- waitAndAssertActivityTransitions(activityClass, expectedSequence, "finish in " + stageName);
- }
-
- @Test
- public void testFinishInOnPause() throws Exception {
- verifyFinishAtStage(mResultActivityTestRule, ResultActivity.class,
- EXTRA_FINISH_IN_ON_PAUSE, "onPause", mTranslucentActivityTestRule);
- }
-
- @Test
- public void testFinishInOnStop() throws Exception {
- verifyFinishAtStage(mResultActivityTestRule, ResultActivity.class,
- EXTRA_FINISH_IN_ON_STOP, "onStop", mFirstActivityTestRule);
- }
-
- private void verifyFinishAtStage(ActivityTestRule rule, Class<? extends Activity> activityClass,
- String finishStageExtra, String stageName, ActivityTestRule launchOnTopRule) {
- final Intent intent = new Intent();
- intent.putExtra(finishStageExtra, true);
-
- // Activity will finish itself after onResume, so need to launch an extra activity on
- // top to get it there.
- final Activity testActivity = rule.launchActivity(intent);
-
- // Wait for the activity to resume and gain top position
- waitAndAssertActivityStates(state(testActivity, ON_TOP_POSITION_GAINED));
-
- // Launch an activity on top, which will make the first one paused or stopped.
- launchOnTopRule.launchActivity(new Intent());
-
- final List<LifecycleLog.ActivityCallback> expectedSequence =
- LifecycleVerifier.getLaunchAndDestroySequence(activityClass);
- waitAndAssertActivityTransitions(activityClass, expectedSequence, "finish in " + stageName);
-
- }
}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleVerifier.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleVerifier.java
index 5bb9c3b..a289682 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleVerifier.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleVerifier.java
@@ -59,7 +59,7 @@
assertEquals(errorMessage, expectedTransitions, observedTransitions);
}
- static List<ActivityCallback> getLaunchSequence(
+ public static List<ActivityCallback> getLaunchSequence(
Class<? extends Activity> activityClass) {
return CALLBACK_TRACKING_CLASS.isAssignableFrom(activityClass)
? Arrays.asList(PRE_ON_CREATE, ON_CREATE, ON_START, ON_POST_CREATE, ON_RESUME,
@@ -67,14 +67,6 @@
: Arrays.asList(PRE_ON_CREATE, ON_CREATE, ON_START, ON_RESUME);
}
- static List<ActivityCallback> getLaunchAndDestroySequence(
- Class<? extends Activity> activityClass) {
- final List<ActivityCallback> expectedTransitions = new ArrayList<>();
- expectedTransitions.addAll(getLaunchSequence(activityClass));
- expectedTransitions.addAll(getResumeToDestroySequence(activityClass));
- return expectedTransitions;
- }
-
static void assertLaunchSequence(Class<? extends Activity> launchingActivity,
Class<? extends Activity> existingActivity, LifecycleLog lifecycleLog,
boolean launchingIsTranslucent) {
diff --git a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java
index 5496891..e9c0db5 100644
--- a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java
+++ b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java
@@ -29,6 +29,7 @@
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
+import static android.content.pm.PackageManager.DONT_KILL_APP;
import static android.content.pm.PackageManager.FEATURE_AUTOMOTIVE;
import static android.content.pm.PackageManager.FEATURE_EMBEDDED;
import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
@@ -956,7 +957,7 @@
SystemUtil.runWithShellPermissionIdentity(
() -> mPackageManager.setComponentEnabledSetting(mSessionHome,
- COMPONENT_ENABLED_STATE_ENABLED, 0 /* flags */));
+ COMPONENT_ENABLED_STATE_ENABLED, DONT_KILL_APP));
setDefaultHome(mSessionHome);
}
@@ -964,7 +965,7 @@
public void close() {
SystemUtil.runWithShellPermissionIdentity(
() -> mPackageManager.setComponentEnabledSetting(mSessionHome,
- COMPONENT_ENABLED_STATE_DISABLED, 0 /* flags */));
+ COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP));
if (mOrigHome != null) {
setDefaultHome(mOrigHome);
}
diff --git a/tests/framework/base/windowmanager/Android.mk b/tests/framework/base/windowmanager/Android.mk
index f7e002c..197449e 100644
--- a/tests/framework/base/windowmanager/Android.mk
+++ b/tests/framework/base/windowmanager/Android.mk
@@ -35,7 +35,8 @@
compatibility-device-util-axt \
androidx.test.rules hamcrest-library \
platform-test-annotations \
- cts-amwm-util
+ cts-amwm-util \
+ CtsSurfaceValidatorLib
LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
diff --git a/tests/framework/base/windowmanager/AndroidManifest.xml b/tests/framework/base/windowmanager/AndroidManifest.xml
index 06027a3..f5816dd 100644
--- a/tests/framework/base/windowmanager/AndroidManifest.xml
+++ b/tests/framework/base/windowmanager/AndroidManifest.xml
@@ -78,6 +78,14 @@
<category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
</intent-filter>
</activity>
+ <activity android:name="android.view.cts.surfacevalidator.CapturedActivity"
+ android:screenOrientation="locked"
+ android:theme="@style/WhiteBackgroundTheme">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
</application>
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
diff --git a/tests/framework/base/windowmanager/res/values/styles.xml b/tests/framework/base/windowmanager/res/values/styles.xml
index e52bdb0..a3de74e 100644
--- a/tests/framework/base/windowmanager/res/values/styles.xml
+++ b/tests/framework/base/windowmanager/res/values/styles.xml
@@ -22,4 +22,13 @@
<item name="android:windowAnimationStyle">@null</item>
<item name="android:windowDisablePreview">true</item>
</style>
+ <style name="WhiteBackgroundTheme" parent="@android:style/Theme.Holo.NoActionBar.Fullscreen">
+ <item name="android:windowNoTitle">true</item>
+ <item name="android:windowFullscreen">true</item>
+ <item name="android:windowOverscan">true</item>
+ <item name="android:fadingEdge">none</item>
+ <item name="android:windowBackground">@android:color/white</item>
+ <item name="android:windowContentTransitions">false</item>
+ <item name="android:windowAnimationStyle">@null</item>
+ </style>
</resources>
\ No newline at end of file
diff --git a/tests/tests/view/src/android/view/cts/SurfaceControlTest.java b/tests/framework/base/windowmanager/src/android/server/wm/SurfaceControlTest.java
similarity index 98%
rename from tests/tests/view/src/android/view/cts/SurfaceControlTest.java
rename to tests/framework/base/windowmanager/src/android/server/wm/SurfaceControlTest.java
index 42cefe3..f4da9aa 100644
--- a/tests/tests/view/src/android/view/cts/SurfaceControlTest.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/SurfaceControlTest.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.view.cts;
+package android.server.wm;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -21,7 +21,6 @@
import android.graphics.Canvas;
import android.graphics.Color;
import android.support.test.uiautomator.UiObjectNotFoundException;
-import android.test.suitebuilder.annotation.LargeTest;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.cts.surfacevalidator.CapturedActivity;
@@ -29,6 +28,7 @@
import android.view.cts.surfacevalidator.PixelColor;
import android.view.cts.surfacevalidator.SurfaceControlTestCase;
+import androidx.test.filters.LargeTest;
import androidx.test.rule.ActivityTestRule;
import org.junit.After;
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/SurfaceViewSurfaceValidatorTest.java b/tests/framework/base/windowmanager/src/android/server/wm/SurfaceViewSurfaceValidatorTest.java
new file mode 100644
index 0000000..c8e59fd
--- /dev/null
+++ b/tests/framework/base/windowmanager/src/android/server/wm/SurfaceViewSurfaceValidatorTest.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 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.server.wm;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.graphics.Color;
+import android.support.test.uiautomator.UiObjectNotFoundException;
+import android.view.cts.surfacevalidator.CapturedActivity;
+import android.view.cts.surfacevalidator.PixelChecker;
+import android.view.cts.surfacevalidator.PixelColor;
+import android.view.cts.surfacevalidator.SurfaceControlTestCase;
+import android.view.SurfaceControl;
+
+import androidx.test.rule.ActivityTestRule;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestName;
+
+public class SurfaceViewSurfaceValidatorTest {
+ private static final int DEFAULT_LAYOUT_WIDTH = 100;
+ private static final int DEFAULT_LAYOUT_HEIGHT = 100;
+ private static final int DEFAULT_BUFFER_WIDTH = 640;
+ private static final int DEFAULT_BUFFER_HEIGHT = 480;
+
+ @Rule
+ public ActivityTestRule<CapturedActivity> mActivityRule =
+ new ActivityTestRule<>(CapturedActivity.class);
+
+ @Rule
+ public TestName mName = new TestName();
+ private CapturedActivity mActivity;
+
+ @Before
+ public void setup() {
+ mActivity = mActivityRule.getActivity();
+ mActivity.dismissPermissionDialog();
+ }
+
+ /**
+ * Want to be especially sure we don't leave up the permission dialog, so try and dismiss
+ * after test.
+ */
+ @After
+ public void tearDown() throws UiObjectNotFoundException {
+ mActivity.dismissPermissionDialog();
+ }
+
+ /**
+ * Verify that showing a SurfaceView on top but not drawing in to it will not produce a background.
+ */
+ @Test
+ public void testOnTopHasNoBackground() throws Throwable {
+ SurfaceControlTestCase.ParentSurfaceConsumer psc =
+ new SurfaceControlTestCase.ParentSurfaceConsumer () {
+ @Override
+ public void addChildren(SurfaceControl parent) {
+ }
+ };
+ PixelChecker pixelChecker = new PixelChecker(PixelColor.BLACK) {
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount == 0;
+ }
+ };
+ SurfaceControlTestCase t = new SurfaceControlTestCase(psc, null,
+ pixelChecker, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+ DEFAULT_BUFFER_WIDTH, DEFAULT_BUFFER_HEIGHT);
+ t.setOnTop(true);
+ mActivity.verifyTest(t, mName);
+ }
+}
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsTest.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsTest.java
index 7466e11..08d8b81 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsTest.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsTest.java
@@ -26,6 +26,7 @@
import android.graphics.Insets;
import android.graphics.Rect;
+import android.platform.test.annotations.Presubmit;
import android.view.DisplayCutout;
import android.view.WindowInsets;
@@ -42,6 +43,7 @@
*/
@SmallTest
@RunWith(AndroidJUnit4.class)
+@Presubmit
public class WindowInsetsTest {
private static final DisplayCutout CUTOUT = new DisplayCutout(new Rect(0, 10, 0, 0),
@@ -59,12 +61,16 @@
.setSystemWindowInsets(Insets.of(1, 2, 3, 4))
.setStableInsets(Insets.of(5, 6, 7, 8))
.setSystemGestureInsets(Insets.of(9, 10, 11, 12))
+ .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
+ .setTappableElementInsets(Insets.of(17, 18, 19, 20))
.setDisplayCutout(CUTOUT)
.build();
assertEquals(Insets.of(1, 2, 3, 4), insets.getSystemWindowInsets());
assertEquals(Insets.of(5, 6, 7, 8), insets.getStableInsets());
assertEquals(Insets.of(9, 10, 11, 12), insets.getSystemGestureInsets());
+ assertEquals(Insets.of(13, 14, 15, 16), insets.getMandatorySystemGestureInsets());
+ assertEquals(Insets.of(17, 18, 19, 20), insets.getTappableElementInsets());
assertSame(CUTOUT, insets.getDisplayCutout());
}
@@ -74,6 +80,8 @@
.setSystemWindowInsets(Insets.of(1, 2, 3, 4))
.setStableInsets(Insets.of(5, 6, 7, 8))
.setSystemGestureInsets(Insets.of(9, 10, 11, 12))
+ .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
+ .setTappableElementInsets(Insets.of(17, 18, 19, 20))
.setDisplayCutout(CUTOUT)
.build();
final WindowInsets copy = new WindowInsets.Builder(insets).build();
@@ -114,6 +122,8 @@
.setSystemWindowInsets(Insets.of(1, 2, 3, 4))
.setStableInsets(Insets.of(5, 6, 7, 8))
.setSystemGestureInsets(Insets.of(9, 10, 11, 12))
+ .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
+ .setTappableElementInsets(Insets.of(17, 18, 19, 20))
.setDisplayCutout(CUTOUT);
final WindowInsets insets = builder.build();
@@ -121,6 +131,8 @@
builder.setStableInsets(Insets.NONE);
builder.setDisplayCutout(null);
builder.setSystemGestureInsets(Insets.NONE);
+ builder.setMandatorySystemGestureInsets(Insets.NONE);
+ builder.setTappableElementInsets(Insets.NONE);
assertEquals(Insets.of(1, 2, 3, 4), insets.getSystemWindowInsets());
assertEquals(Insets.of(5, 6, 7, 8), insets.getStableInsets());
@@ -133,12 +145,16 @@
.setSystemWindowInsets(Insets.of(1, 2, 3, 4))
.setStableInsets(Insets.of(5, 6, 7, 8))
.setSystemGestureInsets(Insets.of(9, 10, 11, 12))
+ .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
+ .setTappableElementInsets(Insets.of(17, 18, 19, 20))
.setDisplayCutout(CUTOUT).build();
final WindowInsets insets2 = new WindowInsets.Builder()
.setSystemWindowInsets(Insets.of(1, 2, 3, 4))
.setStableInsets(Insets.of(5, 6, 7, 8))
.setSystemGestureInsets(Insets.of(9, 10, 11, 12))
+ .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
+ .setTappableElementInsets(Insets.of(17, 18, 19, 20))
.setDisplayCutout(CUTOUT).build();
assertNotSame("Test setup failed, insets and insets2 should not be identical",
@@ -154,6 +170,8 @@
.setSystemWindowInsets(Insets.of(1, 2, 3, 4))
.setStableInsets(Insets.of(5, 6, 7, 8))
.setSystemGestureInsets(Insets.of(9, 10, 11, 12))
+ .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
+ .setTappableElementInsets(Insets.of(17, 18, 19, 20))
.setDisplayCutout(CUTOUT).build();
assertNotEquals(insets, insets.consumeSystemWindowInsets());
@@ -167,6 +185,8 @@
.setSystemWindowInsets(Insets.of(1, 2, 3, 4))
.setStableInsets(Insets.of(5, 6, 7, 8))
.setSystemGestureInsets(Insets.of(9, 10, 11, 12))
+ .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
+ .setTappableElementInsets(Insets.of(17, 18, 19, 20))
.setDisplayCutout(CUTOUT).build();
final WindowInsets consumed = insets.consumeSystemWindowInsets();
@@ -174,7 +194,9 @@
assertEquals(Insets.NONE, consumed.getSystemWindowInsets());
assertEquals(insets.getStableInsets(), consumed.getStableInsets());
assertEquals(insets.getDisplayCutout(), consumed.getDisplayCutout());
- assertEquals(insets.getSystemGestureInsets(), consumed.getSystemGestureInsets());
+ assertEquals(Insets.NONE, consumed.getSystemGestureInsets());
+ assertEquals(Insets.NONE, consumed.getMandatorySystemGestureInsets());
+ assertEquals(Insets.NONE, consumed.getTappableElementInsets());
}
@Test
@@ -183,6 +205,8 @@
.setSystemWindowInsets(Insets.of(1, 2, 3, 4))
.setStableInsets(Insets.of(5, 6, 7, 8))
.setSystemGestureInsets(Insets.of(9, 10, 11, 12))
+ .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
+ .setTappableElementInsets(Insets.of(17, 18, 19, 20))
.setDisplayCutout(CUTOUT).build();
final WindowInsets consumed = insets.consumeStableInsets();
@@ -191,6 +215,8 @@
assertEquals(Insets.NONE, consumed.getStableInsets());
assertEquals(insets.getDisplayCutout(), consumed.getDisplayCutout());
assertEquals(insets.getSystemGestureInsets(), consumed.getSystemGestureInsets());
+ assertEquals(insets.getMandatorySystemGestureInsets(), consumed.getMandatorySystemGestureInsets());
+ assertEquals(insets.getTappableElementInsets(), consumed.getTappableElementInsets());
}
@Test
@@ -199,6 +225,8 @@
.setSystemWindowInsets(Insets.of(1, 2, 3, 4))
.setStableInsets(Insets.of(5, 6, 7, 8))
.setSystemGestureInsets(Insets.of(9, 10, 11, 12))
+ .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
+ .setTappableElementInsets(Insets.of(17, 18, 19, 20))
.setDisplayCutout(CUTOUT).build();
final WindowInsets consumed = insets.consumeDisplayCutout();
@@ -207,6 +235,8 @@
assertEquals(insets.getStableInsets(), consumed.getStableInsets());
assertNull(consumed.getDisplayCutout());
assertEquals(insets.getSystemGestureInsets(), consumed.getSystemGestureInsets());
+ assertEquals(insets.getMandatorySystemGestureInsets(), consumed.getMandatorySystemGestureInsets());
+ assertEquals(insets.getTappableElementInsets(), consumed.getTappableElementInsets());
}
@Test
@@ -215,6 +245,8 @@
.setSystemWindowInsets(Insets.of(1, 2, 3, 4))
.setStableInsets(Insets.of(5, 6, 7, 8))
.setSystemGestureInsets(Insets.of(9, 10, 11, 12))
+ .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
+ .setTappableElementInsets(Insets.of(17, 18, 19, 20))
.setDisplayCutout(CUTOUT).build();
assertEquals(insets.getSystemWindowInsets(), Insets.of(
@@ -239,15 +271,19 @@
@SuppressWarnings("deprecation")
public void testReplacingSystemWindowInsets_works() {
final WindowInsets replaced = new WindowInsets.Builder()
+ .setSystemWindowInsets(Insets.of(100, 200, 300, 400))
+ .setStableInsets(Insets.of(5, 6, 7, 8))
+ .setSystemGestureInsets(Insets.of(9, 10, 11, 12))
+ .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
+ .setTappableElementInsets(Insets.of(17, 18, 19, 20))
+ .setDisplayCutout(CUTOUT).build()
+ .replaceSystemWindowInsets(new Rect(1, 2, 3, 4));
+ final WindowInsets expected = new WindowInsets.Builder()
.setSystemWindowInsets(Insets.of(1, 2, 3, 4))
.setStableInsets(Insets.of(5, 6, 7, 8))
- .setSystemGestureInsets(Insets.of(13, 14, 15, 16))
- .setDisplayCutout(CUTOUT).build()
- .replaceSystemWindowInsets(new Rect(9, 10, 11, 12));
- final WindowInsets expected = new WindowInsets.Builder()
- .setSystemWindowInsets(Insets.of(9, 10, 11, 12))
- .setStableInsets(Insets.of(5, 6, 7, 8))
- .setSystemGestureInsets(Insets.of(13, 14, 15, 16))
+ .setSystemGestureInsets(Insets.of(9, 10, 11, 12))
+ .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
+ .setTappableElementInsets(Insets.of(17, 18, 19, 20))
.setDisplayCutout(CUTOUT).build();
assertEquals(expected, replaced);
@@ -256,11 +292,13 @@
@Test
@SuppressWarnings("deprecation")
public void testReplacingSystemWindowInsets_consistencyAcrossOverloads() {
- final Rect newInsets = new Rect(9, 10, 11, 12);
+ final Rect newInsets = new Rect(100, 200, 300, 400);
final WindowInsets insets = new WindowInsets.Builder()
.setSystemWindowInsets(Insets.of(1, 2, 3, 4))
.setStableInsets(Insets.of(5, 6, 7, 8))
- .setSystemGestureInsets(Insets.of(13, 14, 15, 16))
+ .setSystemGestureInsets(Insets.of(9, 10, 11, 12))
+ .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
+ .setTappableElementInsets(Insets.of(17, 18, 19, 20))
.setDisplayCutout(CUTOUT).build();
assertEquals(insets.replaceSystemWindowInsets(newInsets),
@@ -274,36 +312,64 @@
.setSystemWindowInsets(Insets.of(1, 2, 3, 4))
.setStableInsets(Insets.of(5, 6, 7, 8))
.setSystemGestureInsets(Insets.of(9, 10, 11, 12))
+ .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
+ .setTappableElementInsets(Insets.of(17, 18, 19, 20))
.setDisplayCutout(CUTOUT).build();
final WindowInsets insetsChangedSysWindowInsets = new WindowInsets.Builder()
.setSystemWindowInsets(Insets.of(10, 20, 30, 40))
.setStableInsets(Insets.of(5, 6, 7, 8))
.setSystemGestureInsets(Insets.of(9, 10, 11, 12))
+ .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
+ .setTappableElementInsets(Insets.of(17, 18, 19, 20))
.setDisplayCutout(CUTOUT).build();
final WindowInsets insetsChangedStableInsets = new WindowInsets.Builder()
.setSystemWindowInsets(Insets.of(1, 2, 3, 4))
.setStableInsets(Insets.of(50, 60, 70, 80))
.setSystemGestureInsets(Insets.of(9, 10, 11, 12))
+ .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
+ .setTappableElementInsets(Insets.of(17, 18, 19, 20))
.setDisplayCutout(CUTOUT).build();
final WindowInsets insetsChangedCutout = new WindowInsets.Builder()
.setSystemWindowInsets(Insets.of(1, 2, 3, 4))
.setStableInsets(Insets.of(5, 6, 7, 8))
.setSystemGestureInsets(Insets.of(9, 10, 11, 12))
+ .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
+ .setTappableElementInsets(Insets.of(17, 18, 19, 20))
.setDisplayCutout(CUTOUT2).build();
final WindowInsets insetsChangedGesture = new WindowInsets.Builder()
.setSystemWindowInsets(Insets.of(1, 2, 3, 4))
.setStableInsets(Insets.of(5, 6, 7, 8))
.setSystemGestureInsets(Insets.of(90, 100, 110, 120))
+ .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
+ .setTappableElementInsets(Insets.of(17, 18, 19, 20))
+ .setDisplayCutout(CUTOUT).build();
+
+ final WindowInsets insetsChangedMandatoryGesture = new WindowInsets.Builder()
+ .setSystemWindowInsets(Insets.of(1, 2, 3, 4))
+ .setStableInsets(Insets.of(5, 6, 7, 8))
+ .setSystemGestureInsets(Insets.of(9, 10, 11, 12))
+ .setMandatorySystemGestureInsets(Insets.of(130, 140, 150, 160))
+ .setTappableElementInsets(Insets.of(17, 18, 19, 20))
+ .setDisplayCutout(CUTOUT).build();
+
+ final WindowInsets insetsChangedTappableElement = new WindowInsets.Builder()
+ .setSystemWindowInsets(Insets.of(1, 2, 3, 4))
+ .setStableInsets(Insets.of(5, 6, 7, 8))
+ .setSystemGestureInsets(Insets.of(9, 10, 11, 12))
+ .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
+ .setTappableElementInsets(Insets.of(170, 180, 190, 200))
.setDisplayCutout(CUTOUT).build();
assertNotEquals(insets, insetsChangedSysWindowInsets);
assertNotEquals(insets, insetsChangedStableInsets);
assertNotEquals(insets, insetsChangedCutout);
assertNotEquals(insets, insetsChangedGesture);
+ assertNotEquals(insets, insetsChangedMandatoryGesture);
+ assertNotEquals(insets, insetsChangedTappableElement);
}
@Test
@@ -312,6 +378,8 @@
.setSystemWindowInsets(Insets.of(10, 20, 30, 40))
.setStableInsets(Insets.of(50, 60, 70, 80))
.setSystemGestureInsets(Insets.of(90, 100, 110, 120))
+ .setMandatorySystemGestureInsets(Insets.of(130, 140, 150, 160))
+ .setTappableElementInsets(Insets.of(170, 180, 190, 200))
.setDisplayCutout(CUTOUT).build();
final WindowInsets insetInsets = insets.inset(
@@ -322,6 +390,10 @@
assertEquals(applyInset(insets.getStableInsets()), insetInsets.getStableInsets());
assertEquals(applyInset(insets.getSystemGestureInsets()),
insetInsets.getSystemGestureInsets());
+ assertEquals(applyInset(insets.getMandatorySystemGestureInsets()),
+ insetInsets.getMandatorySystemGestureInsets());
+ assertEquals(applyInset(insets.getTappableElementInsets()),
+ insetInsets.getTappableElementInsets());
assertEquals(applyInset(getCutoutSafeInsets(insets)), getCutoutSafeInsets(insetInsets));
}
@@ -331,6 +403,8 @@
.setSystemWindowInsets(Insets.of(10, 20, 30, 40))
.setStableInsets(Insets.of(50, 60, 70, 80))
.setSystemGestureInsets(Insets.of(90, 100, 110, 120))
+ .setMandatorySystemGestureInsets(Insets.of(13, 14, 15, 16))
+ .setTappableElementInsets(Insets.of(17, 18, 19, 20))
.setDisplayCutout(CUTOUT).build();
final WindowInsets insetInsets = insets.inset(1000, 1000, 1000, 1000);
@@ -338,6 +412,8 @@
assertEquals(Insets.NONE, insetInsets.getSystemWindowInsets());
assertEquals(Insets.NONE, insetInsets.getStableInsets());
assertEquals(Insets.NONE, insetInsets.getSystemGestureInsets());
+ assertEquals(Insets.NONE, insetInsets.getMandatorySystemGestureInsets());
+ assertEquals(Insets.NONE, insetInsets.getTappableElementInsets());
assertNull(insetInsets.getDisplayCutout());
}
diff --git a/tests/jank/AndroidManifest.xml b/tests/jank/AndroidManifest.xml
deleted file mode 100644
index faeedab..0000000
--- a/tests/jank/AndroidManifest.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- * Copyright (C) 2015 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="android.jank.cts">
-
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- <application>
- <uses-library android:name="android.test.runner"/>
- </application>
-
- <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="android.jank.cts"
- android:label="Jank tests">
- <meta-data android:name="listener"
- android:value="com.android.cts.runner.CtsTestRunListener" />
- </instrumentation>
-
-</manifest>
diff --git a/tests/jank/AndroidTest.xml b/tests/jank/AndroidTest.xml
deleted file mode 100644
index 1b4fd1f..0000000
--- a/tests/jank/AndroidTest.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 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.
--->
-<configuration description="Config for CTS Jank test cases">
- <option name="test-suite-tag" value="cts" />
- <option name="not-shardable" value="true" />
- <option name="config-descriptor:metadata" key="component" value="graphics" />
- <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
- <option name="cleanup-apks" value="true" />
- <option name="test-file-name" value="CtsJankDeviceTestCases.apk" />
- </target_preparer>
- <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
- <option name="package" value="android.jank.cts" />
- <option name="runtime-hint" value="11m20s" />
- </test>
-</configuration>
diff --git a/tests/jank/src/android/jank/cts/CtsJankTestBase.java b/tests/jank/src/android/jank/cts/CtsJankTestBase.java
deleted file mode 100644
index 85cf700..0000000
--- a/tests/jank/src/android/jank/cts/CtsJankTestBase.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2015 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.jank.cts;
-
-import android.os.Bundle;
-import android.support.test.uiautomator.UiDevice;
-
-import androidx.test.jank.JankTestBase;
-import androidx.test.jank.WindowContentFrameStatsMonitor;
-
-import com.android.compatibility.common.util.DeviceReportLog;
-import com.android.compatibility.common.util.ResultType;
-import com.android.compatibility.common.util.ResultUnit;
-
-public abstract class CtsJankTestBase extends JankTestBase {
-
- private static final String REPORT_LOG_NAME = "CtsJankDeviceTestCases";
- private UiDevice mDevice;
- private DeviceReportLog mLog;
-
- @Override
- public void afterTest(Bundle metrics) {
- String source = String.format("%s#%s", getClass().getCanonicalName(), getName());
- mLog.addValue(source, "frame_fps",
- metrics.getDouble(WindowContentFrameStatsMonitor.KEY_AVG_FPS),
- ResultType.HIGHER_BETTER, ResultUnit.FPS);
- mLog.addValue(source, "frame_max_frame_duration",
- metrics.getDouble(WindowContentFrameStatsMonitor.KEY_AVG_LONGEST_FRAME),
- ResultType.LOWER_BETTER, ResultUnit.MS);
- mLog.addValue(source, "frame_max_jank",
- metrics.getInt(WindowContentFrameStatsMonitor.KEY_MAX_NUM_JANKY),
- ResultType.LOWER_BETTER, ResultUnit.COUNT);
- mLog.setSummary("frame_avg_jank",
- metrics.getDouble(WindowContentFrameStatsMonitor.KEY_AVG_NUM_JANKY),
- ResultType.LOWER_BETTER, ResultUnit.COUNT);
- }
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- String streamName = "cts_device_jank_test";
- mLog = new DeviceReportLog(REPORT_LOG_NAME, streamName);
- // fix device orientation
- mDevice = UiDevice.getInstance(getInstrumentation());
- mDevice.setOrientationNatural();
- }
-
- @Override
- protected void tearDown() throws Exception {
- mLog.submit(getInstrumentation());
- // restore device orientation
- mDevice.unfreezeRotation();
- super.tearDown();
- }
-
- protected UiDevice getUiDevice() {
- return mDevice;
- }
-}
diff --git a/tests/jank/src/android/jank/cts/ui/CtsDeviceJankUi.java b/tests/jank/src/android/jank/cts/ui/CtsDeviceJankUi.java
deleted file mode 100644
index 35565d7..0000000
--- a/tests/jank/src/android/jank/cts/ui/CtsDeviceJankUi.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2015 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.jank.cts.ui;
-
-import android.content.ComponentName;
-import android.content.Intent;
-import android.jank.cts.CtsJankTestBase;
-import android.os.SystemClock;
-import android.support.test.uiautomator.By;
-import android.support.test.uiautomator.Direction;
-import android.support.test.uiautomator.Until;
-import android.widget.ListView;
-
-import androidx.test.jank.JankTest;
-import androidx.test.jank.WindowContentFrameStatsMonitor;
-
-import java.io.IOException;
-
-public class CtsDeviceJankUi extends CtsJankTestBase {
- private final static int NUM_ELEMENTS = 1000;
- private static final long DEFAULT_ANIMATION_TIME = 2 * 1000;
- private static final long POST_SCROLL_IDLE_TIME = 2 *1000;
- private final static String PACKAGE = "android.ui.cts";
- private final static String CLASS = PACKAGE + ".ScrollingActivity";
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- // launch the activity as part of the set up
- Intent intent = new Intent(Intent.ACTION_MAIN);
- intent.setComponent(new ComponentName(PACKAGE, CLASS));
- intent.putExtra("num_elements", NUM_ELEMENTS);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- getInstrumentation().getTargetContext().startActivity(intent);
- getUiDevice().wait(Until.hasObject(By.pkg(PACKAGE)), DEFAULT_ANIMATION_TIME);
- }
-
- @Override
- protected void tearDown() throws Exception {
- getUiDevice().pressHome();
- super.tearDown();
- }
-
- @JankTest(expectedFrames=50, defaultIterationCount=5)
- @WindowContentFrameStatsMonitor
- public void testScrolling() throws IOException {
- getUiDevice().findObject(By.clazz(ListView.class)).fling(Direction.DOWN);
- SystemClock.sleep(POST_SCROLL_IDLE_TIME);
- }
-}
diff --git a/tests/libcore/OWNERS b/tests/libcore/OWNERS
new file mode 100644
index 0000000..2d36574
--- /dev/null
+++ b/tests/libcore/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 24949
+include platform/libcore:/OWNERS
diff --git a/tests/libcore/jsr166/OWNERS b/tests/libcore/jsr166/OWNERS
new file mode 100644
index 0000000..7b5c0ad
--- /dev/null
+++ b/tests/libcore/jsr166/OWNERS
@@ -0,0 +1,3 @@
+# NOTE: Each source root in CTS should have an OWNERS file as a reminder to
+# add owners to it. It's okay for this file to be empty because the parent
+# directory's owners get inherited by default.
diff --git a/tests/libcore/luni/OWNERS b/tests/libcore/luni/OWNERS
new file mode 100644
index 0000000..7b5c0ad
--- /dev/null
+++ b/tests/libcore/luni/OWNERS
@@ -0,0 +1,3 @@
+# NOTE: Each source root in CTS should have an OWNERS file as a reminder to
+# add owners to it. It's okay for this file to be empty because the parent
+# directory's owners get inherited by default.
diff --git a/tests/libcore/ojluni/OWNERS b/tests/libcore/ojluni/OWNERS
new file mode 100644
index 0000000..7b5c0ad
--- /dev/null
+++ b/tests/libcore/ojluni/OWNERS
@@ -0,0 +1,3 @@
+# NOTE: Each source root in CTS should have an OWNERS file as a reminder to
+# add owners to it. It's okay for this file to be empty because the parent
+# directory's owners get inherited by default.
diff --git a/tests/libcore/okhttp/OWNERS b/tests/libcore/okhttp/OWNERS
new file mode 100644
index 0000000..7b5c0ad
--- /dev/null
+++ b/tests/libcore/okhttp/OWNERS
@@ -0,0 +1,3 @@
+# NOTE: Each source root in CTS should have an OWNERS file as a reminder to
+# add owners to it. It's okay for this file to be empty because the parent
+# directory's owners get inherited by default.
diff --git a/tests/libcore/runner/OWNERS b/tests/libcore/runner/OWNERS
new file mode 100644
index 0000000..7b5c0ad
--- /dev/null
+++ b/tests/libcore/runner/OWNERS
@@ -0,0 +1,3 @@
+# NOTE: Each source root in CTS should have an OWNERS file as a reminder to
+# add owners to it. It's okay for this file to be empty because the parent
+# directory's owners get inherited by default.
diff --git a/tests/libcore/wycheproof-bc/OWNERS b/tests/libcore/wycheproof-bc/OWNERS
new file mode 100644
index 0000000..7b5c0ad
--- /dev/null
+++ b/tests/libcore/wycheproof-bc/OWNERS
@@ -0,0 +1,3 @@
+# NOTE: Each source root in CTS should have an OWNERS file as a reminder to
+# add owners to it. It's okay for this file to be empty because the parent
+# directory's owners get inherited by default.
diff --git a/tests/libcore/wycheproof/OWNERS b/tests/libcore/wycheproof/OWNERS
new file mode 100644
index 0000000..7b5c0ad
--- /dev/null
+++ b/tests/libcore/wycheproof/OWNERS
@@ -0,0 +1,3 @@
+# NOTE: Each source root in CTS should have an OWNERS file as a reminder to
+# add owners to it. It's okay for this file to be empty because the parent
+# directory's owners get inherited by default.
diff --git a/tests/sensor/src/android/hardware/cts/helpers/SensorCtsHelper.java b/tests/sensor/src/android/hardware/cts/helpers/SensorCtsHelper.java
index d9a1a75..5ad0c43 100644
--- a/tests/sensor/src/android/hardware/cts/helpers/SensorCtsHelper.java
+++ b/tests/sensor/src/android/hardware/cts/helpers/SensorCtsHelper.java
@@ -16,6 +16,7 @@
package android.hardware.cts.helpers;
import android.hardware.Sensor;
+import android.os.Environment;
import android.util.Log;
import java.io.File;
import java.io.IOException;
@@ -255,7 +256,7 @@
* @return A {@link File} representing a root directory to store sensor tests data.
*/
public static File getSensorTestDataDirectory() throws IOException {
- File dataDirectory = new File(System.getenv("EXTERNAL_STORAGE"), "sensorTests/");
+ File dataDirectory = new File(Environment.getExternalStorageDirectory(), "sensorTests/");
return createDirectoryStructure(dataDirectory);
}
diff --git a/tests/signature/api-check/Android.mk b/tests/signature/api-check/Android.mk
index 74bb7a0..d5b0be2 100644
--- a/tests/signature/api-check/Android.mk
+++ b/tests/signature/api-check/Android.mk
@@ -21,7 +21,6 @@
LOCAL_MODULE := cts-hiddenapi_flags-csv
LOCAL_MODULE_STEM := hiddenapi_flags.csv
LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH = $(TARGET_OUT_DATA_ETC)
LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
include $(BUILD_SYSTEM)/base_rules.mk
$(eval $(call copy-one-file,$(INTERNAL_PLATFORM_HIDDENAPI_FLAGS),$(LOCAL_BUILT_MODULE)))
diff --git a/tests/signature/api/Android.mk b/tests/signature/api/Android.mk
index 19ce5ee..0dedf0d 100644
--- a/tests/signature/api/Android.mk
+++ b/tests/signature/api/Android.mk
@@ -23,7 +23,6 @@
LOCAL_MODULE := cts-$(subst .,-,$(1))
LOCAL_MODULE_STEM := $(1)
LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH = $(TARGET_OUT_DATA_ETC)
LOCAL_COMPATIBILITY_SUITE := arcts cts vts general-tests
include $(BUILD_SYSTEM)/base_rules.mk
$$(LOCAL_BUILT_MODULE): $(2) | $(APICHECK)
diff --git a/tests/tests/appop/src/android/app/appops/cts/AppOpsTest.kt b/tests/tests/appop/src/android/app/appops/cts/AppOpsTest.kt
index 9a854a3..7a8130e 100644
--- a/tests/tests/appop/src/android/app/appops/cts/AppOpsTest.kt
+++ b/tests/tests/appop/src/android/app/appops/cts/AppOpsTest.kt
@@ -3,7 +3,7 @@
/*
* Copyright (C) 2014 The Android Open Source Project
*
- * Licensed under the Apache License, Version 2.0 (the "License");
+ * 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
*
@@ -19,6 +19,7 @@
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotNull
+import org.junit.Assert.assertSame
import org.junit.Assert.assertTrue
import org.junit.Assert.fail
@@ -30,9 +31,9 @@
import android.app.AppOpsManager.OPSTR_READ_SMS
import android.app.AppOpsManager.OPSTR_RECORD_AUDIO
-import android.app.appops.cts.AppOpsUtils.Companion.allowedOperationLogged;
-import android.app.appops.cts.AppOpsUtils.Companion.rejectedOperationLogged;
-import android.app.appops.cts.AppOpsUtils.Companion.setOpMode;
+import android.app.appops.cts.AppOpsUtils.Companion.allowedOperationLogged
+import android.app.appops.cts.AppOpsUtils.Companion.rejectedOperationLogged
+import android.app.appops.cts.AppOpsUtils.Companion.setOpMode
import org.mockito.Mockito.mock
import org.mockito.Mockito.reset
@@ -43,7 +44,6 @@
import android.Manifest.permission
import android.app.AppOpsManager
import android.app.AppOpsManager.OnOpChangedListener
-import android.app.Instrumentation
import android.content.Context
import android.os.Process
import androidx.test.runner.AndroidJUnit4
@@ -81,13 +81,13 @@
permissionToOpStr[permission.READ_CALL_LOG] =
AppOpsManager.OPSTR_READ_CALL_LOG
permissionToOpStr[permission.WRITE_CALL_LOG] =
- AppOpsManager.OPSTR_WRITE_CALL_LOG
+ AppOpsManager.OPSTR_WRITE_CALL_LOG
permissionToOpStr[permission.READ_CALENDAR] =
- AppOpsManager.OPSTR_READ_CALENDAR
+ AppOpsManager.OPSTR_READ_CALENDAR
permissionToOpStr[permission.WRITE_CALENDAR] =
- AppOpsManager.OPSTR_WRITE_CALENDAR
+ AppOpsManager.OPSTR_WRITE_CALENDAR
permissionToOpStr[permission.CALL_PHONE] =
- AppOpsManager.OPSTR_CALL_PHONE
+ AppOpsManager.OPSTR_CALL_PHONE
permissionToOpStr[permission.READ_SMS] =
AppOpsManager.OPSTR_READ_SMS
permissionToOpStr[permission.RECEIVE_SMS] =
@@ -233,7 +233,7 @@
// Package name doesn't match UID.
mAppOps.checkPackage(Process.SYSTEM_UID, mOpPackageName)
fail("SecurityException expected")
- } catch (expected: SecurityException ) {
+ } catch (expected: SecurityException) {
}
try {
@@ -367,4 +367,49 @@
assertTrue(mustBeLogged, allowedOperationLogged(mOpPackageName, OPSTR_RECORD_AUDIO))
assertTrue(mustBeLogged, rejectedOperationLogged(mOpPackageName, OPSTR_READ_CALENDAR))
}
+
+ @Test
+ fun testNonHistoricalStatePersistence() {
+ // Put a package and uid level data
+ runWithShellPermissionIdentity {
+ mAppOps.setMode(OPSTR_RECORD_AUDIO, Process.myUid(),
+ mOpPackageName, MODE_IGNORED)
+ mAppOps.setUidMode(OPSTR_RECORD_AUDIO, Process.myUid(), MODE_ERRORED)
+
+ // Write the data to disk and read it
+ mAppOps.reloadNonHistoricalState()
+ }
+
+ // Verify the uid state is preserved
+ assertSame(mAppOps.unsafeCheckOpNoThrow(OPSTR_RECORD_AUDIO,
+ Process.myUid(), mOpPackageName), MODE_ERRORED)
+
+ runWithShellPermissionIdentity {
+ // Clear the uid state
+ mAppOps.setUidMode(OPSTR_RECORD_AUDIO, Process.myUid(),
+ AppOpsManager.opToDefaultMode(OPSTR_RECORD_AUDIO))
+ }
+
+ // Verify the package state is preserved
+ assertSame(mAppOps.unsafeCheckOpNoThrow(OPSTR_RECORD_AUDIO,
+ Process.myUid(), mOpPackageName), MODE_IGNORED)
+
+ runWithShellPermissionIdentity {
+ // Clear the uid state
+ val defaultMode = AppOpsManager.opToDefaultMode(OPSTR_RECORD_AUDIO)
+ mAppOps.setUidMode(OPSTR_RECORD_AUDIO, Process.myUid(), defaultMode)
+ mAppOps.setMode(OPSTR_RECORD_AUDIO, Process.myUid(),
+ mOpPackageName, defaultMode)
+ }
+ }
+
+ private fun runWithShellPermissionIdentity(command: () -> Unit) {
+ val uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation()
+ uiAutomation.adoptShellPermissionIdentity()
+ try {
+ command.invoke()
+ } finally {
+ uiAutomation.dropShellPermissionIdentity()
+ }
+ }
}
diff --git a/tests/tests/batterysaving/AndroidTest.xml b/tests/tests/batterysaving/AndroidTest.xml
index c7ff09c..7c03291 100644
--- a/tests/tests/batterysaving/AndroidTest.xml
+++ b/tests/tests/batterysaving/AndroidTest.xml
@@ -13,11 +13,11 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<configuration description="Config for ShortcutManager CTS test cases">
+<configuration description="Config for Battery Saver CTS test cases">
<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_instant_app" />
<option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/Android.bp b/tests/tests/binder_ndk/libbinder_ndk_test/Android.bp
index a196ddd..761e020 100644
--- a/tests/tests/binder_ndk/libbinder_ndk_test/Android.bp
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/Android.bp
@@ -22,6 +22,11 @@
"test_package/Foo.aidl",
],
versions: ["1"],
+ backend: {
+ java: {
+ sdk_version: "28",
+ },
+ },
}
cc_defaults {
diff --git a/tests/tests/carrierapi/OWNERS b/tests/tests/carrierapi/OWNERS
new file mode 100644
index 0000000..5617896
--- /dev/null
+++ b/tests/tests/carrierapi/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 20868
+yinxu@google.com
\ No newline at end of file
diff --git a/tests/tests/contactsproviderwipe/src/android/provider/cts/contactsproviderwipe/ContactsContract_Wipe.java b/tests/tests/contactsproviderwipe/src/android/provider/cts/contactsproviderwipe/ContactsContract_Wipe.java
index 294735c..8bc8134 100644
--- a/tests/tests/contactsproviderwipe/src/android/provider/cts/contactsproviderwipe/ContactsContract_Wipe.java
+++ b/tests/tests/contactsproviderwipe/src/android/provider/cts/contactsproviderwipe/ContactsContract_Wipe.java
@@ -36,6 +36,8 @@
import android.text.TextUtils;
import android.util.Log;
+import com.android.compatibility.common.util.TestUtils;
+
import androidx.test.InstrumentationRegistry;
import java.io.BufferedReader;
@@ -127,7 +129,7 @@
return sb.toString().trim();
}
- private void wipeContactsProvider() {
+ private void wipeContactsProvider() throws Exception {
final String providerPackage = getContactsProviderPackageName();
Log.i(TAG, "Wiping " + providerPackage + "...");
@@ -138,6 +140,14 @@
Log.i(TAG, "Result:" + result);
assertEquals("Success", result);
+
+ // Wait until CP2 is ready to be used.
+ TestUtils.waitUntil("CP2 still not ready", () -> {
+ try (Cursor cursor = getContext().getContentResolver().query(
+ ProviderStatus.CONTENT_URI, null, null, null, null)) {
+ return cursor != null;
+ }
+ });
}
public void testCreationTimestamp() throws Exception {
diff --git a/tests/tests/content/jni/Android.mk b/tests/tests/content/jni/Android.mk
index 3b14b6f..bc934d5 100644
--- a/tests/tests/content/jni/Android.mk
+++ b/tests/tests/content/jni/Android.mk
@@ -21,11 +21,11 @@
# Don't include this package in any configuration by default.
LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := NativeCursorWindow.c
+LOCAL_SRC_FILES := NativeCursorWindow.cpp
LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
-LOCAL_CFLAGS := -Wall -Werror -Wno-pointer-arith -Wno-unused-parameter
+LOCAL_CFLAGS := -Wall -Werror -Wno-pointer-arith -Wno-unused-parameter -Wno-unused-variable
LOCAL_SHARED_LIBRARIES := libnativehelper_compat_libc++ liblog
LOCAL_CXX_STL := libc++_static
diff --git a/tests/tests/content/jni/NativeCursorWindow.c b/tests/tests/content/jni/NativeCursorWindow.cpp
similarity index 68%
rename from tests/tests/content/jni/NativeCursorWindow.c
rename to tests/tests/content/jni/NativeCursorWindow.cpp
index 95342e6..0872ff8 100644
--- a/tests/tests/content/jni/NativeCursorWindow.c
+++ b/tests/tests/content/jni/NativeCursorWindow.cpp
@@ -14,13 +14,18 @@
* limitations under the License.
*/
-#define LOG_TAG "NativeCursorWindow"
+#define TAG "NativeCursorWindow"
#include <jni.h>
#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
#include <sys/mman.h>
-#include <linux/ashmem.h>
-#include <utils/Log.h>
+#include <errno.h>
+
+#include <android/log.h>
+#define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
+#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
struct Header {
// Offset of the lowest unused byte in the window.
@@ -66,15 +71,32 @@
} data;
} __attribute((packed));
-JNIEXPORT jint JNICALL
-Java_android_content_cts_CursorWindowContentProvider_makeNativeCursorWindowFd(JNIEnv *env, jclass clazz,
-jint offset, jint size, jboolean isBlob) {
- int fd = open("/dev/ashmem", O_RDWR | O_CLOEXEC);
- ioctl(fd, ASHMEM_SET_NAME, "Fake CursorWindow");
+extern "C" JNIEXPORT jint JNICALL
+Java_android_content_cts_CursorWindowContentProvider_makeNativeCursorWindowFd(
+ JNIEnv *env, jclass clazz,
+ jstring filename, jint offset, jint size, jboolean isBlob) {
- ioctl(fd, ASHMEM_SET_SIZE, 1024);
+ const char* chars = env->GetStringUTFChars(filename, NULL);
- void *data = mmap(NULL, 1024, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ ALOGI("opening %s", chars);
+
+ const int FILE_SIZE = 1024;
+
+ int fd = open(chars, O_CREAT | O_RDWR | O_CLOEXEC, 0700);
+ // env->ReleaseStringUTFChars(filename, chars); // too lazy; skip.
+
+ if (fd == -1) {
+ ALOGE("open(%s) failed: %d", chars, errno);
+ return -1;
+ }
+
+ ftruncate(fd, FILE_SIZE);
+
+ char* data = (char*) mmap(NULL, FILE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (data == (char*) -1) {
+ ALOGE("mmap(%s) failed: %d", chars, errno);
+ return -1;
+ }
struct Header *header = (struct Header *) data;
unsigned rowSlotChunkOffset = sizeof(struct Header);
@@ -92,7 +114,7 @@
fieldSlot->data.buffer.offset = offset;
fieldSlot->data.buffer.size = size;
- munmap(data, 1024);
+ munmap(data, FILE_SIZE);
return fd;
diff --git a/tests/tests/content/src/android/content/cts/CursorWindowContentProvider.java b/tests/tests/content/src/android/content/cts/CursorWindowContentProvider.java
index 4266f35..9f70fe6 100644
--- a/tests/tests/content/src/android/content/cts/CursorWindowContentProvider.java
+++ b/tests/tests/content/src/android/content/cts/CursorWindowContentProvider.java
@@ -28,6 +28,8 @@
import android.os.ParcelFileDescriptor;
import android.util.Log;
+import java.io.File;
+
/**
* Content provider that uses a custom {@link CursorWindow} to inject file descriptor
* pointing to another ashmem region having window slots with references outside of allowed ranges.
@@ -40,6 +42,14 @@
System.loadLibrary("nativecursorwindow_jni");
}
+ private String mTempFilename;
+
+ @Override
+ public boolean onCreate() {
+ mTempFilename = (new File(getContext().getFilesDir(), "shared-file.dat")).getAbsolutePath();
+ return true;
+ }
+
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
@@ -85,7 +95,7 @@
}
// Write reply with replaced file descriptor
ParcelFileDescriptor evilFd = ParcelFileDescriptor
- .adoptFd(makeNativeCursorWindowFd(1000, 1000, true));
+ .adoptFd(makeNativeCursorWindowFd(mTempFilename, 1000, 1000, true));
dest.appendFrom(tmp, 0, fdPos);
dest.writeFileDescriptor(evilFd.getFileDescriptor());
tmp.setDataPosition(dest.dataPosition());
@@ -94,13 +104,10 @@
}
}
- private native static int makeNativeCursorWindowFd(int offset, int size, boolean isBlob);
+ private static native int makeNativeCursorWindowFd(String filename,
+ int offset, int size, boolean isBlob);
// Stubs
- @Override
- public boolean onCreate() {
- return true;
- }
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
diff --git a/tests/tests/content/src/android/content/om/cts/OverlayInfoTest.java b/tests/tests/content/src/android/content/om/cts/OverlayInfoTest.java
index b8f3cb8..8945338 100644
--- a/tests/tests/content/src/android/content/om/cts/OverlayInfoTest.java
+++ b/tests/tests/content/src/android/content/om/cts/OverlayInfoTest.java
@@ -38,37 +38,42 @@
private static final String PKG_NAME = "source package name";
private static final String TARGET_PKG_NAME = "target package name";
+ private static final String TARGET_OVERLAYABLE_NAME = "target package name";
private static final String CATEGORY = "sample category";
private static final String BASE_CODE_PATH = "base code path";
@Test
public void testEnsureValidState() {
- OverlayInfo info = new OverlayInfo(PKG_NAME, TARGET_PKG_NAME, CATEGORY, BASE_CODE_PATH,
- 0, 0, 0, true);
+ OverlayInfo info = new OverlayInfo(PKG_NAME, TARGET_PKG_NAME, TARGET_OVERLAYABLE_NAME,
+ CATEGORY, BASE_CODE_PATH,
+ 0, 0, 0, true);
assertNotNull(info);
}
@Test
public void testEnsureValidState_fail() {
try {
- OverlayInfo info = new OverlayInfo(null, TARGET_PKG_NAME, CATEGORY, BASE_CODE_PATH,
- 0, 0, 0, true);
+ OverlayInfo info = new OverlayInfo(null, TARGET_PKG_NAME, TARGET_OVERLAYABLE_NAME,
+ CATEGORY, BASE_CODE_PATH,
+ 0, 0, 0, true);
fail("Should throw exception.");
} catch (IllegalArgumentException e) {
// no op, working as intended.
}
try {
- OverlayInfo info = new OverlayInfo(PKG_NAME, null, CATEGORY, BASE_CODE_PATH,
- 0, 0, 0, true);
+ OverlayInfo info = new OverlayInfo(PKG_NAME, null, TARGET_OVERLAYABLE_NAME, CATEGORY,
+ BASE_CODE_PATH,
+ 0, 0, 0, true);
fail("Should throw exception.");
} catch (IllegalArgumentException e) {
// no op, working as intended.
}
try {
- OverlayInfo info = new OverlayInfo(PKG_NAME, TARGET_PKG_NAME, CATEGORY, null,
- 0, 0, 0, true);
+ OverlayInfo info = new OverlayInfo(PKG_NAME, TARGET_PKG_NAME, TARGET_OVERLAYABLE_NAME,
+ CATEGORY, null,
+ 0, 0, 0, true);
fail("Should throw exception.");
} catch (IllegalArgumentException e) {
// no op, working as intended.
@@ -77,8 +82,9 @@
@Test
public void testWriteToParcel() {
- OverlayInfo info = new OverlayInfo(PKG_NAME, TARGET_PKG_NAME, CATEGORY, BASE_CODE_PATH,
- 0, 0, 0, true);
+ OverlayInfo info = new OverlayInfo(PKG_NAME, TARGET_PKG_NAME, TARGET_OVERLAYABLE_NAME,
+ CATEGORY, BASE_CODE_PATH,
+ 0, 0, 0, true);
Parcel p = Parcel.obtain();
info.writeToParcel(p, 0);
p.setDataPosition(0);
@@ -87,6 +93,7 @@
assertEquals(info.packageName, copyInfo.packageName);
assertEquals(info.targetPackageName, copyInfo.targetPackageName);
+ assertEquals(info.targetOverlayableName, copyInfo.targetOverlayableName);
assertEquals(info.category, copyInfo.category);
assertEquals(info.baseCodePath, copyInfo.baseCodePath);
assertEquals(info.state, copyInfo.state);
diff --git a/tests/tests/content/src/android/content/om/cts/OverlayManagerTest.java b/tests/tests/content/src/android/content/om/cts/OverlayManagerTest.java
index 27a7917..be88afb 100644
--- a/tests/tests/content/src/android/content/om/cts/OverlayManagerTest.java
+++ b/tests/tests/content/src/android/content/om/cts/OverlayManagerTest.java
@@ -22,6 +22,7 @@
import android.content.Context;
import android.content.om.IOverlayManager;
import android.content.om.OverlayManager;
+import android.os.UserHandle;
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
@@ -53,18 +54,20 @@
@Test
public void testSetEnabledExclusiveInCategory() throws Exception {
String packageName = "overlay source package name";
- int userId = 10;
+ int userId = UserHandle.myUserId();
+ UserHandle user = UserHandle.of(userId);
verify(mMockService, times(0)).setEnabledExclusiveInCategory(packageName, userId);
- mManager.setEnabledExclusiveInCategory(packageName, userId);
+ mManager.setEnabledExclusiveInCategory(packageName, user);
verify(mMockService, times(1)).setEnabledExclusiveInCategory(packageName, userId);
}
@Test
public void testGetOverlayInfosForTarget() throws Exception {
String targetPackageName = "overlay target package name";
- int userId = 10;
+ int userId = UserHandle.myUserId();
+ UserHandle user = UserHandle.of(userId);
verify(mMockService, times(0)).getOverlayInfosForTarget(targetPackageName, userId);
- mManager.getOverlayInfosForTarget(targetPackageName, userId);
+ mManager.getOverlayInfosForTarget(targetPackageName, user);
verify(mMockService, times(1)).getOverlayInfosForTarget(targetPackageName, userId);
}
-}
\ No newline at end of file
+}
diff --git a/tests/tests/graphics/src/android/graphics/cts/PaintFlagsDrawFilterTest.java b/tests/tests/graphics/src/android/graphics/cts/PaintFlagsDrawFilterTest.java
index 40a77c8..0a85fab5 100644
--- a/tests/tests/graphics/src/android/graphics/cts/PaintFlagsDrawFilterTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/PaintFlagsDrawFilterTest.java
@@ -138,6 +138,7 @@
// Drawn without FILTER_BITMAP_FLAG, all pixels will be black or white.
Paint simplePaint = new Paint();
+ simplePaint.setFilterBitmap(false);
canvas.drawBitmap(grid, 0, 0, simplePaint);
verifyContainsOnlyBlackAndWhite(dst);
diff --git a/tests/tests/graphics/src/android/graphics/cts/PaintTest.java b/tests/tests/graphics/src/android/graphics/cts/PaintTest.java
index 75b87c1..4fbecde 100644
--- a/tests/tests/graphics/src/android/graphics/cts/PaintTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/PaintTest.java
@@ -812,15 +812,39 @@
}
}
+ private void testIsFilterBitmap(Paint orig) {
+ Paint p = new Paint(orig);
+ assertEquals(orig.isFilterBitmap(), p.isFilterBitmap());
+
+ p = new Paint();
+ p.set(orig);
+ assertEquals(orig.isFilterBitmap(), p.isFilterBitmap());
+ }
+
@Test
public void testSetFilterBitmap() {
Paint p = new Paint();
+ assertTrue(p.isFilterBitmap());
+ testIsFilterBitmap(p);
p.setFilterBitmap(true);
assertTrue(p.isFilterBitmap());
p.setFilterBitmap(false);
assertFalse(p.isFilterBitmap());
+ testIsFilterBitmap(p);
+
+ p.reset();
+ assertTrue(p.isFilterBitmap());
+
+ p.setFilterBitmap(false);
+ assertFalse(p.isFilterBitmap());
+
+ p.setFlags(Paint.FILTER_BITMAP_FLAG);
+ assertTrue(p.isFilterBitmap());
+
+ p.setFlags(~Paint.FILTER_BITMAP_FLAG);
+ assertFalse(p.isFilterBitmap());
}
@Test
@@ -1125,7 +1149,8 @@
assertEquals(Paint.ANTI_ALIAS_FLAG, p.getFlags());
p.reset();
- assertEquals(Paint.DEV_KERN_TEXT_FLAG | Paint.EMBEDDED_BITMAP_TEXT_FLAG, p.getFlags());
+ assertEquals(Paint.FILTER_BITMAP_FLAG | Paint.DEV_KERN_TEXT_FLAG
+ | Paint.EMBEDDED_BITMAP_TEXT_FLAG, p.getFlags());
assertEquals(null, p.getColorFilter());
assertEquals(null, p.getMaskFilter());
assertEquals(null, p.getPathEffect());
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/AdaptiveIconDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/AdaptiveIconDrawableTest.java
index 5375f5d..a0ba34b 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/AdaptiveIconDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/AdaptiveIconDrawableTest.java
@@ -46,6 +46,8 @@
public class AdaptiveIconDrawableTest {
public static final String TAG = AdaptiveIconDrawableTest.class.getSimpleName();
+ public static final boolean DEBUG = false;
+
public static void L(String s, Object... parts) {
Log.d(TAG, (parts.length == 0) ? s : String.format(s, parts));
}
@@ -196,11 +198,12 @@
iconDrawable.draw(can_test);
can_test.translate(left, top);
-
- bm_org.compress(Bitmap.CompressFormat.PNG, 100,
- new FileOutputStream(new File(dir, "adaptive-bm-original.png")));
- bm_test.compress(Bitmap.CompressFormat.PNG, 100,
- new FileOutputStream(new File(dir, "adaptive-bm-test.png")));
+ if (DEBUG) {
+ bm_org.compress(Bitmap.CompressFormat.PNG, 100,
+ new FileOutputStream(new File(dir, "adaptive-bm-original.png")));
+ bm_test.compress(Bitmap.CompressFormat.PNG, 100,
+ new FileOutputStream(new File(dir, "adaptive-bm-test.png")));
+ }
Region region = new Region(new Rect(0, 0, width, height));
Path circle = new Path();
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/ShapeDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/ShapeDrawableTest.java
index d88e907..2ecd8b9 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/ShapeDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/ShapeDrawableTest.java
@@ -204,7 +204,7 @@
public void testGetPaint() {
ShapeDrawable shapeDrawable = new ShapeDrawable();
assertNotNull(shapeDrawable.getPaint());
- assertEquals(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG
+ assertEquals(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG | Paint.FILTER_BITMAP_FLAG
| Paint.EMBEDDED_BITMAP_TEXT_FLAG, shapeDrawable.getPaint().getFlags());
}
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyPairGeneratorTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyPairGeneratorTest.java
index 31b644a..1493430 100644
--- a/tests/tests/keystore/src/android/keystore/cts/KeyPairGeneratorTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyPairGeneratorTest.java
@@ -1130,7 +1130,7 @@
KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes()));
MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getDigests()),
- KeyProperties.DIGEST_NONE, KeyProperties.DIGEST_SHA384);
+ KeyProperties.DIGEST_NONE, KeyProperties.DIGEST_SHA256);
MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getSignaturePaddings()));
MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getEncryptionPaddings()));
assertSelfSignedCertificateSignatureVerifies(TEST_ALIAS_1);
diff --git a/tests/tests/libcoreapievolution/OWNERS b/tests/tests/libcoreapievolution/OWNERS
new file mode 100644
index 0000000..c10ca24
--- /dev/null
+++ b/tests/tests/libcoreapievolution/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 24949
+include ../../libcore/OWNERS
diff --git a/tests/tests/libcorefileio/OWNERS b/tests/tests/libcorefileio/OWNERS
new file mode 100644
index 0000000..c10ca24
--- /dev/null
+++ b/tests/tests/libcorefileio/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 24949
+include ../../libcore/OWNERS
diff --git a/tests/tests/libcorelegacy22/OWNERS b/tests/tests/libcorelegacy22/OWNERS
new file mode 100644
index 0000000..c10ca24
--- /dev/null
+++ b/tests/tests/libcorelegacy22/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 24949
+include ../../libcore/OWNERS
diff --git a/tests/tests/location/src/android/location/cts/GnssClockTest.java b/tests/tests/location/src/android/location/cts/GnssClockTest.java
index 71e106a..5989040 100644
--- a/tests/tests/location/src/android/location/cts/GnssClockTest.java
+++ b/tests/tests/location/src/android/location/cts/GnssClockTest.java
@@ -40,6 +40,8 @@
clock.setLeapSecond(7);
clock.setTimeNanos(8);
clock.setTimeUncertaintyNanos(9.0);
+ clock.setElapsedRealtimeNanos(10987732253L);
+ clock.setElapsedRealtimeUncertaintyNanos(3943523L);
}
private static void verifyTestValues(GnssClock clock) {
@@ -52,6 +54,8 @@
assertEquals(7, clock.getLeapSecond());
assertEquals(8, clock.getTimeNanos());
assertEquals(9.0, clock.getTimeUncertaintyNanos());
+ assertEquals(10987732253L, clock.getElapsedRealtimeNanos());
+ assertEquals(3943523L, clock.getElapsedRealtimeUncertaintyNanos());
}
public void testWriteToParcel() {
@@ -104,5 +108,13 @@
assertTrue(clock.hasTimeUncertaintyNanos());
clock.resetTimeUncertaintyNanos();
assertFalse(clock.hasTimeUncertaintyNanos());
+
+ assertTrue(clock.hasElapsedRealtimeNanos());
+ clock.resetElapsedRealtimeNanos();
+ assertFalse(clock.hasElapsedRealtimeNanos());
+
+ assertTrue(clock.hasElapsedRealtimeUncertaintyNanos());
+ clock.resetElapsedRealtimeUncertaintyNanos();
+ assertFalse(clock.hasElapsedRealtimeUncertaintyNanos());
}
}
diff --git a/tests/tests/location2/src/android/location2/cts/LocationManagerTest.java b/tests/tests/location2/src/android/location2/cts/LocationManagerTest.java
index 253a620..8f8da53 100644
--- a/tests/tests/location2/src/android/location2/cts/LocationManagerTest.java
+++ b/tests/tests/location2/src/android/location2/cts/LocationManagerTest.java
@@ -139,6 +139,32 @@
doTestGetLocationUpdates_withListener("my coarse provider name");
}
+ public void testGnssProvidedClock() throws Exception {
+ String providerName = LocationManager.GPS_PROVIDER;
+ try {
+ addTestProvider(providerName, Criteria.ACCURACY_COARSE, true,
+ false, true);
+ Location location = new Location(providerName);
+ long elapsed = SystemClock.elapsedRealtimeNanos();
+ location.setLatitude(0);
+ location.setLongitude(0);
+ location.setAccuracy(0);
+ location.setElapsedRealtimeNanos(elapsed);
+ location.setTime(1);
+ mManager.setTestProviderLocation(providerName, location);
+ assertTrue(SystemClock.currentGnssTimeClock().millis() < 1000);
+
+ location.setTime(java.lang.System.currentTimeMillis());
+ location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
+ mManager.setTestProviderLocation(providerName, location);
+ Thread.sleep(200);
+ long clockms = SystemClock.currentGnssTimeClock().millis();
+ assertTrue(System.currentTimeMillis() - clockms < 1000);
+ } finally {
+ removeTestProvider(providerName);
+ }
+ }
+
private void doTestGetLocationUpdates_withIntent(String providerName) {
try {
diff --git a/tests/tests/media/OWNERS b/tests/tests/media/OWNERS
index 03b751c..f77425a 100644
--- a/tests/tests/media/OWNERS
+++ b/tests/tests/media/OWNERS
@@ -1,9 +1,12 @@
+# Bug component: 1344
chz@google.com
dwkang@google.com
elaurent@google.com
etalvala@google.com
gkasten@google.com
+hdmoon@google.com
hunga@google.com
+insun@google.com
jaewan@google.com
jmtrivi@google.com
jsharkey@android.com
diff --git a/tests/tests/media/res/raw/mkv_mp3_frame_incomplete.mkv b/tests/tests/media/res/raw/mkv_mp3_frame_incomplete.mkv
new file mode 100755
index 0000000..e629de3
--- /dev/null
+++ b/tests/tests/media/res/raw/mkv_mp3_frame_incomplete.mkv
Binary files differ
diff --git a/tests/tests/media/src/android/media/cts/AudioManagerTest.java b/tests/tests/media/src/android/media/cts/AudioManagerTest.java
index c10bfbe..84f4893 100644
--- a/tests/tests/media/src/android/media/cts/AudioManagerTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioManagerTest.java
@@ -55,8 +55,10 @@
import android.provider.Settings;
import android.provider.Settings.System;
import android.test.InstrumentationTestCase;
+import android.text.TextUtils;
import android.util.Log;
import android.view.SoundEffectConstants;
+import com.android.internal.annotations.GuardedBy;
import java.util.HashMap;
import java.util.List;
@@ -174,7 +176,8 @@
@AppModeFull(reason = "Instant apps cannot hold android.permission.MODIFY_AUDIO_SETTINGS")
public void testMicrophoneMuteIntent() throws Exception {
- final MyBlockingIntentReceiver receiver = new MyBlockingIntentReceiver();
+ final MyBlockingIntentReceiver receiver = new MyBlockingIntentReceiver(
+ AudioManager.ACTION_MICROPHONE_MUTE_CHANGED);
final boolean initialMicMute = mAudioManager.isMicrophoneMute();
try {
mContext.registerReceiver(receiver,
@@ -182,7 +185,7 @@
// change the mic mute state
mAudioManager.setMicrophoneMute(!initialMicMute);
// verify a change was reported
- final boolean intentFired = receiver.waitForMicMuteChanged(500/*ms*/);
+ final boolean intentFired = receiver.waitForExpectedAction(500/*ms*/);
assertTrue("ACTION_MICROPHONE_MUTE_CHANGED wasn't fired", intentFired);
// verify the mic mute state is expected
final boolean newMicMute = mAudioManager.isMicrophoneMute();
@@ -194,20 +197,54 @@
}
}
+ @AppModeFull(reason = "Instant apps cannot hold android.permission.MODIFY_AUDIO_SETTINGS")
+ public void testSpeakerphoneIntent() throws Exception {
+ final MyBlockingIntentReceiver receiver = new MyBlockingIntentReceiver(
+ AudioManager.ACTION_SPEAKERPHONE_STATE_CHANGED);
+ final boolean initialSpeakerphoneState = mAudioManager.isSpeakerphoneOn();
+ try {
+ mContext.registerReceiver(receiver,
+ new IntentFilter(AudioManager.ACTION_SPEAKERPHONE_STATE_CHANGED));
+ // change the speakerphone state
+ mAudioManager.setSpeakerphoneOn(!initialSpeakerphoneState);
+ // verify a change was reported
+ final boolean intentFired = receiver.waitForExpectedAction(500/*ms*/);
+ assertTrue("ACTION_SPEAKERPHONE_STATE_CHANGED wasn't fired", intentFired);
+ // verify the speakerphon state is expected
+ final boolean newSpeakerphoneState = mAudioManager.isSpeakerphoneOn();
+ assertTrue("new mic mute state not as expected ("
+ + !initialSpeakerphoneState + ")",
+ newSpeakerphoneState == !initialSpeakerphoneState);
+ } finally {
+ mContext.unregisterReceiver(receiver);
+ mAudioManager.setSpeakerphoneOn(initialSpeakerphoneState);
+ }
+ }
+
private static final class MyBlockingIntentReceiver extends BroadcastReceiver {
private final SafeWaitObject mLock = new SafeWaitObject();
- // state protected by mLock
+ // the action for the intent to check
+ private final String mAction;
+ @GuardedBy("mLock")
private boolean mIntentReceived = false;
+ MyBlockingIntentReceiver(String action) {
+ mAction = action;
+ }
+
@Override
public void onReceive(Context context, Intent intent) {
+ if (!TextUtils.equals(intent.getAction(), mAction)) {
+ // move along, this is not the action we're looking for
+ return;
+ }
synchronized (mLock) {
mIntentReceived = true;
mLock.safeNotify();
}
}
- public boolean waitForMicMuteChanged(long timeOutMs) {
+ public boolean waitForExpectedAction(long timeOutMs) {
synchronized (mLock) {
try {
mLock.safeWait(timeOutMs);
diff --git a/tests/tests/media/src/android/media/cts/AudioPlaybackCaptureTest.java b/tests/tests/media/src/android/media/cts/AudioPlaybackCaptureTest.java
index 352be37..3e6bff4 100644
--- a/tests/tests/media/src/android/media/cts/AudioPlaybackCaptureTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioPlaybackCaptureTest.java
@@ -80,16 +80,12 @@
if (matchingUsages != null) {
for (int usage : matchingUsages) {
- apccBuilder.addMatchingUsage(new AudioAttributes.Builder()
- .setUsage(usage)
- .build());
+ apccBuilder.addMatchingUsage(usage);
}
}
if (excludeUsages != null) {
for (int usage : excludeUsages) {
- apccBuilder.excludeUsage(new AudioAttributes.Builder()
- .setUsage(usage)
- .build());
+ apccBuilder.excludeUsage(usage);
}
}
if (matchingUids != null) {
diff --git a/tests/tests/media/src/android/media/cts/AudioSystemTest.java b/tests/tests/media/src/android/media/cts/AudioSystemTest.java
index 33a66a8..88ac120 100644
--- a/tests/tests/media/src/android/media/cts/AudioSystemTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioSystemTest.java
@@ -20,6 +20,7 @@
import static org.junit.Assert.assertTrue;
import android.media.AudioSystem;
+import android.platform.test.annotations.AppModeFull;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -35,6 +36,7 @@
@RunWith(AndroidJUnit4.class)
@SmallTest
+@AppModeFull(reason = "Instant applications do not have permission MODIFY_AUDIO_SETTINGS")
public class AudioSystemTest {
/**
diff --git a/tests/tests/media/src/android/media/cts/AudioTrackOffloadTest.java b/tests/tests/media/src/android/media/cts/AudioTrackOffloadTest.java
index 0a87f31..aa0d50b 100644
--- a/tests/tests/media/src/android/media/cts/AudioTrackOffloadTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioTrackOffloadTest.java
@@ -18,6 +18,7 @@
package android.media.cts;
import android.content.res.AssetFileDescriptor;
+import android.media.AudioAttributes;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
@@ -37,33 +38,42 @@
private static final int PRESENTATION_END_TIMEOUT_MS = 8 * 1000; // 8s
+ private static final AudioAttributes DEFAULT_ATTR = new AudioAttributes.Builder().build();
+
+ private static final AudioFormat DEFAULT_FORMAT = new AudioFormat.Builder()
+ .setEncoding(AudioFormat.ENCODING_MP3)
+ .setSampleRate(44100)
+ .setChannelMask(AudioFormat.CHANNEL_OUT_STEREO)
+ .build();
public void testIsOffloadSupportedNullFormat() throws Exception {
try {
- final boolean offloadableFormat = AudioManager.isOffloadedPlaybackSupported(null);
+ final boolean offloadableFormat = AudioManager.isOffloadedPlaybackSupported(null,
+ DEFAULT_ATTR);
fail("Shouldn't be able to use null AudioFormat in isOffloadedPlaybackSupported()");
- } catch (IllegalArgumentException e) {
- // ok, IAE is expected here
+ } catch (NullPointerException e) {
+ // ok, NPE is expected here
+ }
+ }
+
+ public void testIsOffloadSupportedNullAttributes() throws Exception {
+ try {
+ final boolean offloadableFormat = AudioManager.isOffloadedPlaybackSupported(
+ DEFAULT_FORMAT, null);
+ fail("Shouldn't be able to use null AudioAttributes in isOffloadedPlaybackSupported()");
+ } catch (NullPointerException e) {
+ // ok, NPE is expected here
}
}
public void testExerciseIsOffloadSupported() throws Exception {
- final AudioFormat af = new AudioFormat.Builder()
- .setEncoding(AudioFormat.ENCODING_MP3)
- .setSampleRate(44100)
- .setChannelMask(AudioFormat.CHANNEL_OUT_STEREO)
- .build();
- final boolean offloadableFormat = AudioManager.isOffloadedPlaybackSupported(af);
+ final boolean offloadableFormat =
+ AudioManager.isOffloadedPlaybackSupported(DEFAULT_FORMAT, DEFAULT_ATTR);
}
public void testAudioTrackOffload() throws Exception {
- final AudioFormat formatToOffload = new AudioFormat.Builder()
- .setEncoding(AudioFormat.ENCODING_MP3)
- .setSampleRate(44100)
- .setChannelMask(AudioFormat.CHANNEL_OUT_STEREO)
- .build();
AudioTrack track = null;
try (AssetFileDescriptor mp3ToOffload = getContext().getResources()
@@ -71,7 +81,7 @@
InputStream mp3InputStream = mp3ToOffload.createInputStream()) {
long mp3ToOffloadLength = mp3ToOffload.getLength();
- if (!AudioManager.isOffloadedPlaybackSupported(formatToOffload)) {
+ if (!AudioManager.isOffloadedPlaybackSupported(DEFAULT_FORMAT, DEFAULT_ATTR)) {
Log.i(TAG, "skipping test testPlayback");
// cannot test if offloading is not supported
return;
@@ -79,7 +89,8 @@
// format is offloadable, test playback head is progressing
track = new AudioTrack.Builder()
- .setAudioFormat(formatToOffload)
+ .setAudioAttributes(DEFAULT_ATTR)
+ .setAudioFormat(DEFAULT_FORMAT)
.setTransferMode(AudioTrack.MODE_STREAM)
.setBufferSizeInBytes(MP3_BUFF_SIZE)
.setOffloadedPlayback(true).build();
diff --git a/tests/tests/media/src/android/media/cts/DataSourceDescTest.java b/tests/tests/media/src/android/media/cts/DataSourceDescTest.java
index c276138..5ec24e8 100644
--- a/tests/tests/media/src/android/media/cts/DataSourceDescTest.java
+++ b/tests/tests/media/src/android/media/cts/DataSourceDescTest.java
@@ -17,6 +17,7 @@
package android.media.cts;
import android.content.Context;
+import android.media.DataSourceDesc;
import android.media.UriDataSourceDesc;
import android.net.Uri;
import android.test.AndroidTestCase;
@@ -43,40 +44,27 @@
java.util.Vector<HttpCookie> cookies = new java.util.Vector<HttpCookie>();
cookies.add(cookie);
- UriDataSourceDesc uriDsd = new UriDataSourceDesc.Builder()
- .setDataSource(mContext, uri, headers, cookies)
+ UriDataSourceDesc uriDsd = (UriDataSourceDesc) new DataSourceDesc.Builder()
+ .setDataSource(uri, headers, cookies)
.build();
- assertEquals(mContext, uriDsd.getContext());
assertEquals(uri, uriDsd.getUri());
assertEquals(headers, uriDsd.getHeaders());
assertEquals(cookies, uriDsd.getCookies());
- UriDataSourceDesc uriDsd2 = new UriDataSourceDesc.Builder(uriDsd)
+ UriDataSourceDesc uriDsd2 = (UriDataSourceDesc) new DataSourceDesc.Builder(uriDsd)
.build();
- assertEquals(mContext, uriDsd2.getContext());
assertEquals(uri, uriDsd2.getUri());
assertEquals(headers, uriDsd2.getHeaders());
assertEquals(cookies, uriDsd2.getCookies());
}
public void testUriDataSourceDescWithNullArguments() {
- String file = "file://foo";
- Uri uri = Uri.parse(file);
-
try {
- UriDataSourceDesc uriDsd = new UriDataSourceDesc.Builder()
- .setDataSource(null, uri)
+ DataSourceDesc uriDsd = new DataSourceDesc.Builder()
+ .setDataSource((Uri) null)
.build();
} catch (IllegalArgumentException e) {
// Expected
- try {
- UriDataSourceDesc uriDsd2 = new UriDataSourceDesc.Builder()
- .setDataSource(mContext, null)
- .build();
- } catch (IllegalArgumentException e2) {
- // Expected
- return;
- }
}
fail();
}
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecListTest.java b/tests/tests/media/src/android/media/cts/MediaCodecListTest.java
index 70d8dd8..3c4f6fd 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecListTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecListTest.java
@@ -31,6 +31,7 @@
import android.platform.test.annotations.RequiresDevice;
import android.test.AndroidTestCase;
import android.util.Log;
+import android.util.Size;
import androidx.test.filters.SmallTest;
@@ -622,6 +623,7 @@
MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, 720, 1280);
portraitHd240Format.setInteger(MediaFormat.KEY_FRAME_RATE, 240);
+ /* common-sense checks */
assertTrue(VideoCapabilities.PerformancePoint.HD_30.covers(hd25Format));
assertTrue(VideoCapabilities.PerformancePoint.HD_25.covers(hd25Format));
assertFalse(VideoCapabilities.PerformancePoint.HD_24.covers(hd25Format));
@@ -633,11 +635,90 @@
assertFalse(VideoCapabilities.PerformancePoint.HD_200.covers(portraitHd240Format));
assertTrue(VideoCapabilities.PerformancePoint.FHD_240.covers(portraitHd240Format));
assertFalse(VideoCapabilities.PerformancePoint.FHD_200.covers(portraitHd240Format));
+
+ /* test macroblock size and conversion support */
+ VideoCapabilities.PerformancePoint bigBlockFHD30_120 =
+ new VideoCapabilities.PerformancePoint(1920, 1080, 30, 120, new Size(128, 64));
+ assertEquals(120, bigBlockFHD30_120.getMaxFrameRate());
+ assertEquals(8160, bigBlockFHD30_120.getMaxMacroBlocks());
+ assertEquals(244800, bigBlockFHD30_120.getMaxMacroBlockRate());
+
+ VideoCapabilities.PerformancePoint bigRotBlockFHD30_120 =
+ new VideoCapabilities.PerformancePoint(1920, 1080, 30, 120, new Size(64, 128));
+ assertEquals(120, bigRotBlockFHD30_120.getMaxFrameRate());
+ assertEquals(8640, bigRotBlockFHD30_120.getMaxMacroBlocks());
+ assertEquals(259200, bigRotBlockFHD30_120.getMaxMacroBlockRate());
+
+ /* test conversion logic */
+ {
+ /* 900*900@25-50 */
+ VideoCapabilities.PerformancePoint unusual =
+ new VideoCapabilities.PerformancePoint(900, 900, 25, 50, new Size(1, 1));
+ assertEquals(50, unusual.getMaxFrameRate());
+ assertEquals(3249, unusual.getMaxMacroBlocks());
+ assertEquals(81225, unusual.getMaxMacroBlockRate());
+
+ /* becomes 960*1024@25-50 */
+ VideoCapabilities.PerformancePoint converted1 =
+ new VideoCapabilities.PerformancePoint(unusual, new Size(128, 64));
+ assertEquals(50, converted1.getMaxFrameRate());
+ assertEquals(3840, converted1.getMaxMacroBlocks());
+ assertEquals(96000, converted1.getMaxMacroBlockRate());
+
+ /* becomes 1024*960@25-50 */
+ VideoCapabilities.PerformancePoint converted2 =
+ new VideoCapabilities.PerformancePoint(unusual, new Size(64, 128));
+ assertEquals(50, converted2.getMaxFrameRate());
+ assertEquals(3840, converted2.getMaxMacroBlocks());
+ assertEquals(96000, converted2.getMaxMacroBlockRate());
+
+ /* becomes 1024*1024@25-50 */
+ VideoCapabilities.PerformancePoint converted3 =
+ new VideoCapabilities.PerformancePoint(converted1, new Size(64, 128));
+ assertEquals(50, converted3.getMaxFrameRate());
+ assertEquals(4096, converted3.getMaxMacroBlocks());
+ assertEquals(102400, converted3.getMaxMacroBlockRate());
+
+ assertEquals(converted1, converted2);
+ assertEquals(converted2, converted1);
+ assertEquals(converted1, converted3);
+ assertEquals(converted3, converted1);
+ assertTrue(converted1.covers(converted2));
+ assertTrue(converted2.covers(converted1));
+ assertTrue(converted2.covers(converted3));
+ assertTrue(converted3.covers(converted2));
+ }
+
+ // big macroblock size does not impact standard performance points as the dimensions are set
+ VideoCapabilities.PerformancePoint bigBlockFHD30 =
+ new VideoCapabilities.PerformancePoint(1920, 1080, 30, 30, new Size(128, 64));
+
+ assertTrue(bigBlockFHD30.covers(VideoCapabilities.PerformancePoint.FHD_30));
+ assertTrue(VideoCapabilities.PerformancePoint.FHD_30.covers(bigBlockFHD30));
+ assertTrue(bigBlockFHD30.equals(VideoCapabilities.PerformancePoint.FHD_30));
+ assertTrue(VideoCapabilities.PerformancePoint.FHD_30.equals(bigBlockFHD30));
+
+ // but it impacts the case where dimensions differ
+ assertFalse(bigBlockFHD30.covers(new VideoCapabilities.PerformancePoint(1080, 1920, 30)));
+ assertFalse(bigBlockFHD30.covers(new VideoCapabilities.PerformancePoint(1936, 1072, 30)));
+ assertFalse(bigBlockFHD30.covers(new VideoCapabilities.PerformancePoint(1280, 720, 63)));
+ assertTrue(bigBlockFHD30_120.covers(new VideoCapabilities.PerformancePoint(1280, 720, 63)));
+ assertFalse(bigBlockFHD30_120.covers(new VideoCapabilities.PerformancePoint(1280, 720, 64)));
+ assertTrue(VideoCapabilities.PerformancePoint.FHD_30.covers(
+ new VideoCapabilities.PerformancePoint(1080, 1920, 30)));
+ assertTrue(VideoCapabilities.PerformancePoint.FHD_30.covers(
+ new VideoCapabilities.PerformancePoint(1936, 1072, 30)));
+ assertTrue(new VideoCapabilities.PerformancePoint(1920, 1080, 30, 120, new Size(1, 1))
+ .covers(new VideoCapabilities.PerformancePoint(1280, 720, 68)));
}
public void verifyPerformancePoints(
MediaCodecInfo info, String mediaType,
List<VideoCapabilities.PerformancePoint> points) {
+ // Components must list all supported standard performance points unless those performance
+ // points are covered by other listed standard performance points.
+
+
// TODO: verify performance points listed conform to the requirements ... once those
// requirements are agreed upon.
}
@@ -717,9 +798,7 @@
}
} else {
for (VideoCapabilities.PerformancePoint p : pps) {
- Log.d(TAG, "got performance point "
- + p.macroBlocks + "block @ " + p.macroBlockRate / p.macroBlocks
- + "fps (max " + p.frameRate + "fps)");
+ Log.d(TAG, "got performance point " + p);
}
}
}
diff --git a/tests/tests/media/src/android/media/cts/MediaController2Test.java b/tests/tests/media/src/android/media/cts/MediaController2Test.java
index 7de9662..141ce18 100644
--- a/tests/tests/media/src/android/media/cts/MediaController2Test.java
+++ b/tests/tests/media/src/android/media/cts/MediaController2Test.java
@@ -58,7 +58,7 @@
static final int ALLOWED_COMMAND_CODE = 100;
static final Session2CommandGroup SESSION_ALLOWED_COMMANDS = new Session2CommandGroup.Builder()
- .addCommand(ALLOWED_COMMAND_CODE).build();
+ .addCommand(new Session2Command(ALLOWED_COMMAND_CODE)).build();
static final int SESSION_RESULT_CODE = 100;
static final String SESSION_RESULT_KEY = "test_result_key";
static final String SESSION_RESULT_VALUE = "test_result_value";
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayer2DrmTest.java b/tests/tests/media/src/android/media/cts/MediaPlayer2DrmTest.java
index 73a26dc..e6949cc 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayer2DrmTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayer2DrmTest.java
@@ -143,6 +143,14 @@
ModularDrmTestType.V5_ASYNC_CALLBACKS_TEST);
}
+ @LargeTest
+ public void testCAR_CLEARKEY_AUDIO_DOWNLOADED_V6_ASYNC_KEYREQUEST_ERR_TEST() throws Exception {
+ download(CENC_AUDIO_URL,
+ CENC_AUDIO_URL_DOWNLOADED,
+ RES_AUDIO,
+ ModularDrmTestType.V6_ASYNC_KEYREQUEST_ERR_TEST);
+ }
+
// helpers
private void stream(Uri uri, Resolution res, ModularDrmTestType testType) throws Exception {
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayer2DrmTestBase.java b/tests/tests/media/src/android/media/cts/MediaPlayer2DrmTestBase.java
index 66b38f2..776e4aa 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayer2DrmTestBase.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayer2DrmTestBase.java
@@ -23,9 +23,9 @@
import android.content.IntentFilter;
import android.content.res.Resources;
import android.media.DataSourceDesc;
-import android.media.UriDataSourceDesc;
import android.media.MediaDrm;
import android.media.MediaPlayer2;
+import android.media.MediaPlayer2.DrmEventCallback;
import android.media.MediaPlayer2.DrmInfo;
import android.media.MediaPlayer2.DrmPreparationInfo;
import android.media.MediaDrm.KeyRequest;
@@ -72,6 +72,7 @@
protected Monitor mOnPlaylistCompleted = new Monitor();
protected Monitor mOnDrmInfoCalled = new Monitor();
protected Monitor mOnDrmPreparedCalled = new Monitor();
+ protected Monitor mOnErrorCalled = new Monitor();
protected int mCallStatus = MediaPlayer2.CALL_STATUS_NO_ERROR;
protected Context mContext;
@@ -80,6 +81,7 @@
protected MediaPlayer2 mPlayer = null;
protected MediaStubActivity mActivity;
+ private boolean mExpectError;
protected ExecutorService mExecutor;
protected MediaPlayer2.EventCallback mECb = new MediaPlayer2.EventCallback() {
@Override
@@ -91,7 +93,8 @@
@Override
public void onError(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
- fail("Media player had error " + what + " playing video");
+ assertTrue("Media player had error " + what + " playing video", mExpectError);
+ mOnErrorCalled.signal();
}
@Override
@@ -192,6 +195,7 @@
V3_ASYNC_DRMPREPARED_TEST,
V4_SYNC_OFFLINE_KEY,
V5_ASYNC_CALLBACKS_TEST,
+ V6_ASYNC_KEYREQUEST_ERR_TEST,
}
// TODO: After living on these tests for a while, we can consider grouping them based on
@@ -264,6 +268,7 @@
case V2_SYNC_CONFIG_TEST:
case V3_ASYNC_DRMPREPARED_TEST:
case V5_ASYNC_CALLBACKS_TEST:
+ case V6_ASYNC_KEYREQUEST_ERR_TEST:
playLoadedModularDrmVideo_Generic(file, width, height, playTime, testType);
break;
@@ -285,7 +290,7 @@
mPlayer.registerEventCallback(mExecutor, mECb);
Log.v(TAG, "playLoadedVideo: setDataSource()");
- DataSourceDesc dsd = new UriDataSourceDesc.Builder().setDataSource(mContext, file).build();
+ DataSourceDesc dsd = new DataSourceDesc.Builder().setDataSource(file).build();
mPlayer.setDataSource(dsd);
mSetDataSourceCallCompleted.waitForSignal();
if (mCallStatus != MediaPlayer2.CALL_STATUS_NO_ERROR) {
@@ -297,6 +302,8 @@
mPlayer.setSurface(surfaceHolder.getSurface());
try {
+ final AtomicBoolean drmCallbackError = new AtomicBoolean(false);
+ final List<DataSourceDesc> dsds = Collections.singletonList(dsd);
switch (testType) {
case V0_SYNC_TEST:
preparePlayerAndDrm_V0_syncDrmSetup(dsd);
@@ -315,7 +322,16 @@
break;
case V5_ASYNC_CALLBACKS_TEST:
- preparePlayerAndDrm_V5_asyncDrmSetupCallbacks(dsd);
+ DrmEventCallback eventCallback = new CtsDrmEventCallback(
+ drmCallbackError, dsds, MediaDrm.KEY_TYPE_STREAMING);
+ preparePlayerAndDrm_asyncDrmSetupCallbacks(eventCallback, drmCallbackError);
+ break;
+
+ case V6_ASYNC_KEYREQUEST_ERR_TEST:
+ mExpectError = true;
+ DrmEventCallback misbehave = new CtsDrmBadServerResponseCallback(
+ drmCallbackError, dsds, MediaDrm.KEY_TYPE_STREAMING);
+ preparePlayerAndDrm_asyncDrmSetupCallbacks(misbehave , drmCallbackError);
break;
default:
@@ -397,6 +413,12 @@
Log.v(TAG, "preparePlayerAndDrm_V1: onDrmInfo done!");
return null;
}
+
+ @Override
+ public byte[] onDrmKeyRequest(MediaPlayer2 mp, DataSourceDesc dsd, KeyRequest request) {
+ return null;
+ }
+
});
Log.v(TAG, "preparePlayerAndDrm_V1: calling prepare()");
@@ -440,6 +462,18 @@
Log.v(TAG, "preparePlayerAndDrm_V2: onDrmConfig EXCEPTION " + e);
}
}
+
+ @Override
+ public DrmPreparationInfo onDrmInfo(MediaPlayer2 mp, DataSourceDesc dsd,
+ DrmInfo drmInfo) {
+ return null;
+ }
+
+ @Override
+ public byte[] onDrmKeyRequest(MediaPlayer2 mp, DataSourceDesc dsd, KeyRequest request) {
+ return null;
+ }
+
});
Log.v(TAG, "preparePlayerAndDrm_V2: calling prepare()");
@@ -528,6 +562,11 @@
mOnDrmPreparedCalled.signal();
Log.v(TAG, "preparePlayerAndDrm_V3: onDrmPrepared done!");
}
+
+ @Override
+ public byte[] onDrmKeyRequest(MediaPlayer2 mp, DataSourceDesc dsd, KeyRequest request) {
+ return null;
+ }
});
Log.v(TAG, "preparePlayerAndDrm_V3: calling prepare()");
@@ -545,7 +584,19 @@
}
}
- private final class CtsDrmEventCallback extends MediaPlayer2.DrmEventCallback {
+ private class CtsDrmBadServerResponseCallback extends CtsDrmEventCallback {
+ CtsDrmBadServerResponseCallback(
+ AtomicBoolean drmCallbackError, List<DataSourceDesc> dsds, int keyType) {
+ super(drmCallbackError, dsds, keyType);
+ }
+
+ @Override
+ public byte[] onDrmKeyRequest(MediaPlayer2 mp, DataSourceDesc dsd, KeyRequest req) {
+ return null;
+ }
+ }
+
+ private class CtsDrmEventCallback extends MediaPlayer2.DrmEventCallback {
final String DRM_EVENT_CB_TAG = CtsDrmEventCallback.class.getSimpleName();
final AtomicBoolean mDrmCallbackError;
final List<DataSourceDesc> mDsds;
@@ -576,9 +627,8 @@
// setting up with the first supported UUID
// instead of supportedSchemes[0] in GTS
- DrmPreparationInfo.Builder drmBuilder = new DrmPreparationInfo.Builder();
UUID drmScheme = CLEARKEY_SCHEME_UUID;
- drmBuilder.setUuid(drmScheme);
+ DrmPreparationInfo.Builder drmBuilder = new DrmPreparationInfo.Builder(drmScheme);
if (mOfflineKeySetId != null && mOfflineKeySetId.length > 0) {
drmBuilder.setKeySetId(mOfflineKeySetId);
return drmBuilder.build();
@@ -603,6 +653,7 @@
"initData[" + drmScheme + "]: " + Arrays.toString(initData));
Log.v(DRM_EVENT_CB_TAG, "onDrmInfo done!");
+ drmBuilder.setOptionalParameters(null);
return drmBuilder.build();
}
@@ -672,23 +723,22 @@
}
}
- private void preparePlayerAndDrm_V5_asyncDrmSetupCallbacks(DataSourceDesc dsd)
- throws InterruptedException {
-
- final AtomicBoolean drmCallbackError = new AtomicBoolean(false);
- List<DataSourceDesc> dsds = Collections.singletonList(dsd);
- mPlayer.setDrmEventCallback(mExecutor,
- new CtsDrmEventCallback(drmCallbackError, dsds, MediaDrm.KEY_TYPE_STREAMING));
- Log.v(TAG, "preparePlayerAndDrm_V5: calling prepare()");
+ private void preparePlayerAndDrm_asyncDrmSetupCallbacks(DrmEventCallback eventCallback,
+ AtomicBoolean drmCallbackError) throws InterruptedException {
+ mPlayer.setDrmEventCallback(mExecutor, eventCallback);
+ Log.v(TAG, "preparePlayerAndDrm_asyncDrmSetupCallbacks: calling prepare()");
mPlayer.prepare();
- // Waiting till the player is prepared
- mOnPreparedCalled.waitForSignal();
+ if (mExpectError) {
+ mOnErrorCalled.waitForSignal();
+ } else {
+ // Waiting till the player is prepared
+ mOnPreparedCalled.waitForSignal();
+ }
// handle error (async) in main thread rather than callbacks
- if (drmCallbackError.get()) {
- fail("preparePlayerAndDrm_V5: setupDrm");
- }
+ assertTrue("preparePlayerAndDrm_asyncDrmSetupCallbacks: setupDrm",
+ drmCallbackError.get() == mExpectError);
}
@@ -705,8 +755,8 @@
surfaceHolder.setKeepScreenOn(true);
final AtomicBoolean drmCallbackError = new AtomicBoolean(false);
- UriDataSourceDesc.Builder dsdBuilder = new UriDataSourceDesc.Builder();
- DataSourceDesc dsd = dsdBuilder.setDataSource(mContext, file).build();
+ DataSourceDesc.Builder dsdBuilder = new DataSourceDesc.Builder();
+ DataSourceDesc dsd = dsdBuilder.setDataSource(file).build();
DataSourceDesc dsd2 = dsdBuilder.build();
List<DataSourceDesc> dsds = Arrays.asList(dsd, dsd2);
@@ -814,6 +864,18 @@
}
drmPrepared.signal();
}
+
+ @Override
+ public DrmPreparationInfo onDrmInfo(MediaPlayer2 mp, DataSourceDesc dsd,
+ DrmInfo drmInfo) {
+ return null;
+ }
+
+ @Override
+ public byte[] onDrmKeyRequest(MediaPlayer2 mp, DataSourceDesc dsd,
+ KeyRequest request) {
+ return null;
+ }
});
mPlayer.prepareDrm(dsd, drmScheme);
drmPrepared.waitForSignal();
@@ -918,6 +980,18 @@
}
drmPrepared.signal();
}
+
+ @Override
+ public DrmPreparationInfo onDrmInfo(MediaPlayer2 mp, DataSourceDesc dsd,
+ DrmInfo drmInfo) {
+ return null;
+ }
+
+ @Override
+ public byte[] onDrmKeyRequest(MediaPlayer2 mp, DataSourceDesc dsd,
+ KeyRequest request) {
+ return null;
+ }
});
mPlayer.prepareDrm(dsd, drmScheme);
drmPrepared.waitForSignal();
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayer2Test.java b/tests/tests/media/src/android/media/cts/MediaPlayer2Test.java
index 4dbc16c..3e96b97 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayer2Test.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayer2Test.java
@@ -22,29 +22,32 @@
import android.hardware.Camera;
import android.media.AudioAttributes;
import android.media.AudioManager;
-import android.media.CallbackDataSourceDesc;
-import android.media.DataSourceCallback;
import android.media.DataSourceDesc;
import android.media.FileDataSourceDesc;
import android.media.MediaFormat;
import android.media.MediaMetadataRetriever;
import android.media.MediaPlayer2;
+import android.media.MediaPlayer2.SubtitleData;
+import android.media.MediaPlayer2.TrackInfo;
import android.media.MediaRecorder;
import android.media.MediaTimestamp;
import android.media.PlaybackParams;
-import android.media.SubtitleData;
import android.media.SyncParams;
-import android.media.UriDataSourceDesc;
import android.media.audiofx.AudioEffect;
import android.media.audiofx.Visualizer;
import android.media.cts.R;
import android.media.cts.TestUtils.Monitor;
import android.net.Uri;
import android.os.Environment;
+import android.os.Handler;
+import android.os.HandlerThread;
import android.os.ParcelFileDescriptor;
import android.os.PowerManager;
+import android.os.ProxyFileDescriptorCallback;
+import android.os.storage.StorageManager;
import android.platform.test.annotations.AppModeFull;
import android.platform.test.annotations.RequiresDevice;
+import android.system.ErrnoException;
import android.util.Log;
import android.util.Pair;
import android.util.Size;
@@ -126,7 +129,7 @@
MediaPlayer2 mp = mPlayer;
MediaPlayer2 mp2 = mPlayer2;
AssetFileDescriptor afd2 = mResources.openRawResourceFd(R.raw.testmp3_2);
- mp2.setDataSource(new FileDataSourceDesc.Builder()
+ mp2.setDataSource(new DataSourceDesc.Builder()
.setDataSource(ParcelFileDescriptor.dup(afd2.getFileDescriptor()),
afd2.getStartOffset(), afd2.getLength())
.build());
@@ -157,7 +160,7 @@
for (int i = 0; i < 20; i++) {
try {
AssetFileDescriptor afd = mResources.openRawResourceFd(R.raw.bug13652927);
- mp.setDataSource(new FileDataSourceDesc.Builder()
+ mp.setDataSource(new DataSourceDesc.Builder()
.setDataSource(ParcelFileDescriptor.dup(afd.getFileDescriptor()),
afd.getStartOffset(), afd.getLength())
.build());
@@ -284,8 +287,8 @@
// test stop and restart
mp.reset();
mp.registerEventCallback(mExecutor, ecb);
- mp.setDataSource(new UriDataSourceDesc.Builder()
- .setDataSource(mContext, uri)
+ mp.setDataSource(new DataSourceDesc.Builder()
+ .setDataSource(uri)
.build());
onPrepareCalled.reset();
mp.prepare();
@@ -387,7 +390,7 @@
// test stop and restart
mp.reset();
AssetFileDescriptor afd = mResources.openRawResourceFd(resid);
- mp.setDataSource(new FileDataSourceDesc.Builder()
+ mp.setDataSource(new DataSourceDesc.Builder()
.setDataSource(ParcelFileDescriptor.dup(afd.getFileDescriptor()),
afd.getStartOffset(), afd.getLength())
.build());
@@ -608,7 +611,7 @@
// test stop and restart
mp.reset();
AssetFileDescriptor afd = mResources.openRawResourceFd(resid);
- mp.setDataSource(new FileDataSourceDesc.Builder()
+ mp.setDataSource(new DataSourceDesc.Builder()
.setDataSource(ParcelFileDescriptor.dup(afd.getFileDescriptor()),
afd.getStartOffset(), afd.getLength())
.build());
@@ -949,7 +952,7 @@
}
AssetFileDescriptor afd2 = mResources.openRawResourceFd(resid);
- DataSourceDesc dsd2 = new FileDataSourceDesc.Builder()
+ DataSourceDesc dsd2 = new DataSourceDesc.Builder()
.setDataSource(ParcelFileDescriptor.dup(afd2.getFileDescriptor()),
afd2.getStartOffset(), afd2.getLength())
.build();
@@ -957,7 +960,7 @@
resid = R.raw.video_480x360_mp4_h264_1000kbps_30fps_aac_stereo_128kbps_44100hz;
AssetFileDescriptor afd3 = mResources.openRawResourceFd(resid);
- DataSourceDesc dsd3 = new FileDataSourceDesc.Builder()
+ DataSourceDesc dsd3 = new DataSourceDesc.Builder()
.setDataSource(ParcelFileDescriptor.dup(afd3.getFileDescriptor()),
afd3.getStartOffset(), afd3.getLength())
.build();
@@ -1046,7 +1049,7 @@
}
AssetFileDescriptor afd2 = mResources.openRawResourceFd(resid);
- DataSourceDesc dsd2 = new FileDataSourceDesc.Builder()
+ DataSourceDesc dsd2 = new DataSourceDesc.Builder()
.setDataSource(ParcelFileDescriptor.dup(afd2.getFileDescriptor()),
afd2.getStartOffset(), afd2.getLength())
.build();
@@ -1054,7 +1057,7 @@
resid = R.raw.video_480x360_mp4_h264_1000kbps_30fps_aac_stereo_128kbps_44100hz;
AssetFileDescriptor afd3 = mResources.openRawResourceFd(resid);
- DataSourceDesc dsd3 = new FileDataSourceDesc.Builder()
+ DataSourceDesc dsd3 = new DataSourceDesc.Builder()
.setDataSource(ParcelFileDescriptor.dup(afd3.getFileDescriptor()),
afd3.getStartOffset(), afd3.getLength())
.build();
@@ -1153,7 +1156,7 @@
}
AssetFileDescriptor afd2 = mResources.openRawResourceFd(resid);
- DataSourceDesc dsd2 = new FileDataSourceDesc.Builder()
+ DataSourceDesc dsd2 = new DataSourceDesc.Builder()
.setDataSource(ParcelFileDescriptor.dup(afd2.getFileDescriptor()),
afd2.getStartOffset(), afd2.getLength())
.build();
@@ -1740,8 +1743,7 @@
private void readSubtitleTracks() throws Exception {
mSubtitleTrackIndex.clear();
- List<MediaPlayer2.TrackInfo> trackInfos =
- mPlayer.getTrackInfo(mPlayer.getCurrentDataSource());
+ List<TrackInfo> trackInfos = mPlayer.getTrackInfo(mPlayer.getCurrentDataSource());
if (trackInfos == null || trackInfos.size() == 0) {
return;
}
@@ -1749,8 +1751,7 @@
Vector<Integer> subtitleTrackIndex = new Vector<>();
for (int i = 0; i < trackInfos.size(); ++i) {
assertTrue(trackInfos.get(i) != null);
- if (trackInfos.get(i).getTrackType() ==
- MediaPlayer2.TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE) {
+ if (trackInfos.get(i).getTrackType() == TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE) {
assertTrue(trackInfos.get(i).getLanguage() != null);
assertTrue(trackInfos.get(i).getFormat() != null);
subtitleTrackIndex.add(i);
@@ -1760,23 +1761,29 @@
mSubtitleTrackIndex.addAll(subtitleTrackIndex);
}
- private void selectSubtitleTrack(int index) throws Exception {
- int trackIndex = mSubtitleTrackIndex.get(index);
- // test both selectTrack API
- if (index == 0) {
- mPlayer.selectTrack(trackIndex);
- } else {
- mPlayer.selectTrack(mPlayer.getCurrentDataSource(), trackIndex);
- }
- mSelectedSubtitleIndex = index;
+ private TrackInfo getSubtitleTrackInfo(int subtitleIndex) {
+ int trackIndex = mSubtitleTrackIndex.get(subtitleIndex);
+ List<TrackInfo> trackInfos = mPlayer.getTrackInfo();
+ final TrackInfo trackInfo = trackInfos.get(trackIndex);
+ return trackInfo;
}
- private void deselectSubtitleTrack(int index) throws Exception {
- int trackIndex = mSubtitleTrackIndex.get(index);
+ private void selectSubtitleTrack(int subtitleIndex) throws Exception {
+ final TrackInfo trackInfo = getSubtitleTrackInfo(subtitleIndex);
+ // test both selectTrack API
+ if (subtitleIndex == 0) {
+ mPlayer.selectTrack(trackInfo);
+ } else {
+ mPlayer.selectTrack(mPlayer.getCurrentDataSource(), trackInfo);
+ }
+ mSelectedSubtitleIndex = subtitleIndex;
+ }
+
+ private void deselectSubtitleTrack(int subtitleIndex) throws Exception {
mOnDeselectTrackCalled.reset();
- mPlayer.deselectTrack(mPlayer.getCurrentDataSource(), trackIndex);
+ mPlayer.deselectTrack(mPlayer.getCurrentDataSource(), getSubtitleTrackInfo(subtitleIndex));
mOnDeselectTrackCalled.waitForSignal();
- if (mSelectedSubtitleIndex == index) {
+ if (mSelectedSubtitleIndex == subtitleIndex) {
mSelectedSubtitleIndex = -1;
}
}
@@ -1855,12 +1862,10 @@
assertTrue(mOnSubtitleDataCalled.waitForSignal(2500));
// Check selected track
- assertTrue(
- mPlayer.getSelectedTrack(MediaPlayer2.TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE) > 0);
- assertTrue(
- mPlayer.getSelectedTrack(
- mPlayer.getCurrentDataSource(),
- MediaPlayer2.TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE) > 0);
+ final int trackTypeSubtitle = TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE;
+ final DataSourceDesc currentDataSource = mPlayer.getCurrentDataSource();
+ assertTrue(mPlayer.getSelectedTrack(trackTypeSubtitle) != null);
+ assertTrue(mPlayer.getSelectedTrack(currentDataSource, trackTypeSubtitle) != null);
// Try deselecting track.
deselectSubtitleTrack(i);
@@ -2214,8 +2219,8 @@
Uri uri = Uri.parse(outputFileLocation);
MediaPlayer2 mp = new MediaPlayer2(mContext);
try {
- mp.setDataSource(new UriDataSourceDesc.Builder()
- .setDataSource(mContext, uri)
+ mp.setDataSource(new DataSourceDesc.Builder()
+ .setDataSource(uri)
.build());
mp.prepare();
Thread.sleep(SLEEP_TIME);
@@ -2274,8 +2279,8 @@
PackageManager.FEATURE_MICROPHONE);
}
- // Smoke test playback from a DataSourceCallback.
- public void testPlaybackFromADataSourceCallback() throws Exception {
+ // Smoke test playback from a ProxyFileDescriptorCallback.
+ public void testPlaybackFromProxyFileDescriptorCallback() throws Exception {
final int resid = R.raw.video_480x360_mp4_h264_1350kbps_30fps_aac_stereo_192kbps_44100hz;
final int duration = 10000;
@@ -2283,13 +2288,21 @@
return;
}
- TestDataSourceCallback dataSource =
- TestDataSourceCallback.fromAssetFd(mResources.openRawResourceFd(resid));
+ HandlerThread callbackThread = new HandlerThread("ProxyFileDescriptorCallbackThread");
+ callbackThread.start();
+ Handler handler = new Handler(callbackThread.getLooper());
+
+ TestProxyFileDescriptorCallback callback =
+ TestProxyFileDescriptorCallback.fromAssetFd(mResources.openRawResourceFd(resid));
// Test returning -1 from getSize() to indicate unknown size.
- dataSource.returnFromGetSize(-1);
- mPlayer.setDataSource(new CallbackDataSourceDesc.Builder()
- .setDataSource(dataSource)
- .build());
+ callback.returnFromGetSize(-1);
+
+ StorageManager storageManager =
+ (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE);
+ ParcelFileDescriptor pfd = storageManager.openProxyFileDescriptor(
+ ParcelFileDescriptor.MODE_READ_ONLY, callback, handler);
+
+ mPlayer.setDataSource(new DataSourceDesc.Builder().setDataSource(pfd).build());
playLoadedVideo(null, null, -1);
assertTrue(mPlayer.getState() == MediaPlayer2.PLAYER_STATE_PLAYING);
@@ -2322,8 +2335,11 @@
// Test reset.
mPlayer.reset();
- mPlayer.setDataSource(new CallbackDataSourceDesc.Builder()
- .setDataSource(dataSource)
+
+ ParcelFileDescriptor pfd2 = storageManager.openProxyFileDescriptor(
+ ParcelFileDescriptor.MODE_READ_ONLY, callback, handler);
+ mPlayer.setDataSource(new DataSourceDesc.Builder()
+ .setDataSource(pfd2)
.build());
mPlayer.registerEventCallback(mExecutor, ecb);
@@ -2343,9 +2359,12 @@
while (mPlayer.getState() == MediaPlayer2.PLAYER_STATE_PLAYING) {
Thread.sleep(SLEEP_TIME);
}
+
+ callbackThread.quitSafely();
+ callbackThread.join();
}
- public void testNullDataSourceCallbackIsRejected() throws Exception {
+ public void testNullDataSourceDescIsRejected() throws Exception {
MediaPlayer2.EventCallback ecb = new MediaPlayer2.EventCallback() {
@Override
public void onCallCompleted(MediaPlayer2 mp, DataSourceDesc dsd, int what, int status) {
@@ -2363,7 +2382,7 @@
assertTrue(mCallStatus != MediaPlayer2.CALL_STATUS_NO_ERROR);
}
- public void testDataSourceCallbackIsClosedOnReset() throws Exception {
+ public void testProxyFileDescriptorCallbackIsClosedOnReset() throws Exception {
MediaPlayer2.EventCallback ecb = new MediaPlayer2.EventCallback() {
@Override
public void onCallCompleted(MediaPlayer2 mp, DataSourceDesc dsd, int what, int status) {
@@ -2375,27 +2394,49 @@
};
mPlayer.registerEventCallback(mExecutor, ecb);
- TestDataSourceCallback dataSource = new TestDataSourceCallback(new byte[0]);
- mPlayer.setDataSource(new CallbackDataSourceDesc.Builder()
- .setDataSource(dataSource)
- .build());
+ HandlerThread callbackThread = new HandlerThread("ProxyFileDescriptorCallbackThread");
+ callbackThread.start();
+ Handler handler = new Handler(callbackThread.getLooper());
+
+ TestProxyFileDescriptorCallback callback =
+ new TestProxyFileDescriptorCallback(new byte[0]);
+
+ StorageManager storageManager =
+ (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE);
+ ParcelFileDescriptor pfd = storageManager.openProxyFileDescriptor(
+ ParcelFileDescriptor.MODE_READ_ONLY, callback, handler);
+
+ mPlayer.setDataSource(new DataSourceDesc.Builder().setDataSource(pfd).build());
+
mOnPlayCalled.waitForSignal();
mPlayer.reset();
- assertTrue(dataSource.isClosed());
+
+ callbackThread.quitSafely();
+ callbackThread.join();
+ assertTrue(callback.isClosed());
}
- public void testPlaybackFailsIfDataSourceCallbackThrows() throws Exception {
+ public void testPlaybackFailsIfProxyFileDescriptorCallbackThrows() throws Exception {
final int resid = R.raw.video_480x360_mp4_h264_1350kbps_30fps_aac_stereo_192kbps_44100hz;
if (!MediaUtils.hasCodecsForResource(mContext, resid)) {
return;
}
setOnErrorListener();
- TestDataSourceCallback dataSource =
- TestDataSourceCallback.fromAssetFd(mResources.openRawResourceFd(resid));
- mPlayer.setDataSource(new CallbackDataSourceDesc.Builder()
- .setDataSource(dataSource)
- .build());
+
+ HandlerThread callbackThread = new HandlerThread("ProxyFileDescriptorCallbackThread");
+ callbackThread.start();
+ Handler handler = new Handler(callbackThread.getLooper());
+
+ TestProxyFileDescriptorCallback callback =
+ TestProxyFileDescriptorCallback.fromAssetFd(mResources.openRawResourceFd(resid));
+
+ StorageManager storageManager =
+ (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE);
+ ParcelFileDescriptor pfd = storageManager.openProxyFileDescriptor(
+ ParcelFileDescriptor.MODE_READ_ONLY, callback, handler);
+
+ mPlayer.setDataSource(new DataSourceDesc.Builder().setDataSource(pfd).build());
MediaPlayer2.EventCallback ecb = new MediaPlayer2.EventCallback() {
@Override
@@ -2413,43 +2454,12 @@
mPlayer.prepare();
mOnPrepareCalled.waitForSignal();
- dataSource.throwFromReadAt();
+ callback.throwFromReadAt();
mPlayer.play();
assertTrue(mOnErrorCalled.waitForSignal());
- }
- public void testPlaybackFailsIfDataSourceCallbackReturnsAnError() throws Exception {
- final int resid = R.raw.video_480x360_mp4_h264_1350kbps_30fps_aac_stereo_192kbps_44100hz;
- if (!MediaUtils.hasCodecsForResource(mContext, resid)) {
- return;
- }
-
- TestDataSourceCallback dataSource =
- TestDataSourceCallback.fromAssetFd(mResources.openRawResourceFd(resid));
- mPlayer.setDataSource(new CallbackDataSourceDesc.Builder()
- .setDataSource(dataSource)
- .build());
-
- setOnErrorListener();
- MediaPlayer2.EventCallback ecb = new MediaPlayer2.EventCallback() {
- @Override
- public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
- if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
- mOnPrepareCalled.signal();
- }
- }
- };
- synchronized (mEventCbLock) {
- mEventCallbacks.add(ecb);
- }
-
- mOnPrepareCalled.reset();
- mPlayer.prepare();
- mOnPrepareCalled.waitForSignal();
-
- dataSource.returnFromReadAt(-2);
- mPlayer.play();
- assertTrue(mOnErrorCalled.waitForSignal());
+ callbackThread.quitSafely();
+ callbackThread.join();
}
public void testClose() throws Exception {
@@ -2514,29 +2524,30 @@
public void testConsecutiveSeeks() throws Exception {
final int resid = R.raw.video_480x360_mp4_h264_1350kbps_30fps_aac_stereo_192kbps_44100hz;
- final TestDataSourceCallback source =
- TestDataSourceCallback.fromAssetFd(mResources.openRawResourceFd(resid));
final Monitor readAllowed = new Monitor();
- DataSourceCallback dataSource = new DataSourceCallback() {
+ ProxyFileDescriptorCallback callback = new ProxyFileDescriptorCallback() {
+ TestProxyFileDescriptorCallback mTestSource =
+ TestProxyFileDescriptorCallback.fromAssetFd(
+ mResources.openRawResourceFd(resid));
+
@Override
- public int readAt(long position, byte[] buffer, int offset, int size)
- throws IOException {
+ public int onRead(long offset, int size, byte[] data) throws ErrnoException {
try {
readAllowed.waitForSignal();
} catch (InterruptedException e) {
fail();
}
- return source.readAt(position, buffer, offset, size);
+ return mTestSource.onRead(offset, size, data);
}
@Override
- public long getSize() throws IOException {
- return source.getSize();
+ public long onGetSize() throws ErrnoException {
+ return mTestSource.onGetSize();
}
@Override
- public void close() throws IOException {
- source.close();
+ public void onRelease() {
+ mTestSource.onRelease();
}
};
final Monitor labelReached = new Monitor();
@@ -2568,9 +2579,16 @@
mOnErrorCalled.reset();
- mPlayer.setDataSource(new CallbackDataSourceDesc.Builder()
- .setDataSource(dataSource)
- .build());
+ HandlerThread callbackThread = new HandlerThread("ProxyFileDescriptorCallbackThread");
+ callbackThread.start();
+ Handler handler = new Handler(callbackThread.getLooper());
+
+ StorageManager storageManager =
+ (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE);
+ ParcelFileDescriptor pfd = storageManager.openProxyFileDescriptor(
+ ParcelFileDescriptor.MODE_READ_ONLY, callback, handler);
+
+ mPlayer.setDataSource(new DataSourceDesc.Builder().setDataSource(pfd).build());
// prepare() will be pending until readAllowed is signaled.
mPlayer.prepare();
@@ -2624,6 +2642,9 @@
commandsCompleted.get(1));
mPlayer.reset();
+
+ callbackThread.quitSafely();
+ callbackThread.join();
}
public void testFileDataSourceDesc() throws Exception {
@@ -2631,7 +2652,7 @@
long endPosMs = 7000;
AssetFileDescriptor afd = mResources.openRawResourceFd(
R.raw.video_480x360_mp4_h264_1350kbps_30fps_aac_stereo_192kbps_44100hz);
- FileDataSourceDesc fdsd = new FileDataSourceDesc.Builder()
+ FileDataSourceDesc fdsd = (FileDataSourceDesc) new DataSourceDesc.Builder()
.setDataSource(ParcelFileDescriptor.dup(afd.getFileDescriptor()))
.setStartPosition(startPosMs)
.setEndPosition(endPosMs)
@@ -2642,7 +2663,7 @@
assertEquals(startPosMs, fdsd.getStartPosition());
assertEquals(endPosMs, fdsd.getEndPosition());
- FileDataSourceDesc fdsd2 = new FileDataSourceDesc.Builder(fdsd)
+ FileDataSourceDesc fdsd2 = (FileDataSourceDesc) new DataSourceDesc.Builder(fdsd)
.build();
assertEquals(0, fdsd2.getOffset());
assertEquals(FileDataSourceDesc.FD_LENGTH_UNKNOWN, fdsd2.getLength());
@@ -2652,31 +2673,17 @@
afd.close();
}
- public void testCallbackDataSourceDesc() throws Exception {
- TestDataSourceCallback dataSource = new TestDataSourceCallback(new byte[0]);
- CallbackDataSourceDesc cbdsd = new CallbackDataSourceDesc.Builder()
- .setDataSource(dataSource)
- .build();
- assertEquals(dataSource, cbdsd.getDataSourceCallback());
-
- CallbackDataSourceDesc cbdsd2 = new CallbackDataSourceDesc.Builder(cbdsd)
- .build();
- assertEquals(dataSource, cbdsd2.getDataSourceCallback());
- }
-
public void testStartEndPositions() throws Exception {
long startPosMs = 3000;
long endPosMs = 7000;
AssetFileDescriptor afd = mResources.openRawResourceFd(
R.raw.video_480x360_mp4_h264_1350kbps_30fps_aac_stereo_192kbps_44100hz);
- FileDataSourceDesc fdsd = new FileDataSourceDesc.Builder()
+ DataSourceDesc fdsd = new DataSourceDesc.Builder()
.setDataSource(ParcelFileDescriptor.dup(afd.getFileDescriptor()),
afd.getStartOffset(), afd.getLength())
.setStartPosition(startPosMs)
.setEndPosition(endPosMs)
.build();
- assertEquals(afd.getStartOffset(), fdsd.getOffset());
- assertEquals(afd.getLength(), fdsd.getLength());
mPlayer.setDataSource(fdsd);
afd.close();
mPlayer.setDisplay(mActivity.getSurfaceHolder());
@@ -2763,32 +2770,42 @@
final Monitor readRequested = new Monitor();
final Monitor readAllowed = new Monitor();
- DataSourceCallback dataSource = new DataSourceCallback() {
- TestDataSourceCallback mTestSource =
- TestDataSourceCallback.fromAssetFd(mResources.openRawResourceFd(resid));
+ ProxyFileDescriptorCallback callback = new ProxyFileDescriptorCallback() {
+ TestProxyFileDescriptorCallback mTestSource =
+ TestProxyFileDescriptorCallback.fromAssetFd(
+ mResources.openRawResourceFd(resid));
+
@Override
- public int readAt(long position, byte[] buffer, int offset, int size)
- throws IOException {
+ public int onRead(long offset, int size, byte[] data) throws ErrnoException {
try {
readRequested.signal();
readAllowed.waitForSignal();
} catch (InterruptedException e) {
fail();
}
- return mTestSource.readAt(position, buffer, offset, size);
+ return mTestSource.onRead(offset, size, data);
}
@Override
- public long getSize() throws IOException {
- return mTestSource.getSize();
+ public long onGetSize() throws ErrnoException {
+ return mTestSource.onGetSize();
}
@Override
- public void close() throws IOException {
- mTestSource.close();
+ public void onRelease() {
+ mTestSource.onRelease();
}
};
+ HandlerThread callbackThread = new HandlerThread("ProxyFileDescriptorCallbackThread");
+ callbackThread.start();
+ Handler handler = new Handler(callbackThread.getLooper());
+
+ StorageManager storageManager =
+ (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE);
+ ParcelFileDescriptor pfd = storageManager.openProxyFileDescriptor(
+ ParcelFileDescriptor.MODE_READ_ONLY, callback, handler);
+
final ArrayList<Integer> commandsCompleted = new ArrayList<>();
setOnErrorListener();
final Monitor labelReached = new Monitor();
@@ -2823,10 +2840,7 @@
mOnPrepareCalled.reset();
mOnErrorCalled.reset();
- mPlayer.setDataSource(new CallbackDataSourceDesc.Builder()
- .setDataSource(dataSource)
- .build());
-
+ mPlayer.setDataSource(new DataSourceDesc.Builder().setDataSource(pfd).build());
// prepare() will be pending until readAllowed is signaled.
mPlayer.prepare();
@@ -2857,6 +2871,9 @@
assertEquals(MediaPlayer2.CALL_COMPLETED_PREPARE, (int) commandsCompleted.get(1));
assertEquals(MediaPlayer2.CALL_COMPLETED_PAUSE, (int) commandsCompleted.get(2));
assertEquals(0, mOnErrorCalled.getNumSignal());
+
+ callbackThread.quitSafely();
+ callbackThread.join();
}
public void testHandleFileDataSourceDesc() throws Exception {
@@ -2939,17 +2956,17 @@
private FileDataSourceDesc openFile(int resid) throws Exception {
AssetFileDescriptor afd = mResources.openRawResourceFd(resid);
- FileDataSourceDesc fdsd = new FileDataSourceDesc.Builder()
+ DataSourceDesc fdsd = new DataSourceDesc.Builder()
.setDataSource(ParcelFileDescriptor.dup(afd.getFileDescriptor()),
afd.getStartOffset(), afd.getLength())
.build();
afd.close();
- return fdsd;
+ return (FileDataSourceDesc) fdsd;
}
- private boolean isFileDataSourceDescClosed(FileDataSourceDesc fdsd) {
+ private boolean isFileDataSourceDescClosed(DataSourceDesc fdsd) {
try {
- fdsd.getParcelFileDescriptor().getFd();
+ ((FileDataSourceDesc) fdsd).getParcelFileDescriptor().getFd();
} catch (IllegalStateException e) {
return true;
}
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayer2TestBase.java b/tests/tests/media/src/android/media/cts/MediaPlayer2TestBase.java
index cc44db6..bc831b0 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayer2TestBase.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayer2TestBase.java
@@ -25,8 +25,8 @@
import android.media.FileDataSourceDesc;
import android.media.UriDataSourceDesc;
import android.media.MediaPlayer2;
+import android.media.MediaPlayer2.SubtitleData;
import android.media.MediaTimestamp;
-import android.media.SubtitleData;
import android.media.TimedMetaData;
import android.media.TimedText;
import android.media.cts.TestUtils.Monitor;
@@ -107,8 +107,8 @@
new AudioAttributes.Builder().build();
mp.setAudioAttributes(aa);
mp.setAudioSessionId(audioSessionId);
- mp.setDataSource(new UriDataSourceDesc.Builder()
- .setDataSource(context, uri)
+ mp.setDataSource(new DataSourceDesc.Builder()
+ .setDataSource(uri)
.build());
if (holder != null) {
mp.setDisplay(holder);
@@ -164,7 +164,7 @@
mp.setAudioAttributes(aa);
mp.setAudioSessionId(audioSessionId);
- mp.setDataSource(new FileDataSourceDesc.Builder()
+ mp.setDataSource(new DataSourceDesc.Builder()
.setDataSource(ParcelFileDescriptor.dup(afd.getFileDescriptor()),
afd.getStartOffset(), afd.getLength())
.build());
@@ -333,7 +333,7 @@
AssetFileDescriptor afd = mResources.openRawResourceFd(resid);
try {
- mPlayer.setDataSource(new FileDataSourceDesc.Builder()
+ mPlayer.setDataSource(new DataSourceDesc.Builder()
.setDataSource(ParcelFileDescriptor.dup(afd.getFileDescriptor()),
afd.getStartOffset(), afd.getLength())
.build());
@@ -349,7 +349,7 @@
}
AssetFileDescriptor afd = mResources.openRawResourceFd(resid);
- FileDataSourceDesc fdsd = new FileDataSourceDesc.Builder()
+ DataSourceDesc fdsd = new DataSourceDesc.Builder()
.setDataSource(ParcelFileDescriptor.dup(afd.getFileDescriptor()),
afd.getStartOffset(), afd.getLength())
.build();
@@ -379,8 +379,8 @@
final Uri uri = Uri.parse(path);
for (int i = 0; i < STREAM_RETRIES; i++) {
try {
- mPlayer.setDataSource(new UriDataSourceDesc.Builder()
- .setDataSource(mContext, uri)
+ mPlayer.setDataSource(new DataSourceDesc.Builder()
+ .setDataSource(uri)
.build());
playLoadedVideo(width, height, playTime);
playedSuccessfully = true;
@@ -413,9 +413,8 @@
boolean playedSuccessfully = false;
for (int i = 0; i < STREAM_RETRIES; i++) {
try {
- mPlayer.setDataSource(new UriDataSourceDesc.Builder()
- .setDataSource(getInstrumentation().getTargetContext(),
- uri, headers, cookies)
+ mPlayer.setDataSource(new DataSourceDesc.Builder()
+ .setDataSource(uri, headers, cookies)
.build());
playLoadedVideo(width, height, playTime);
playedSuccessfully = true;
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
index ff3e979..b5c061f 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
@@ -1677,6 +1677,10 @@
playVideoTest(R.raw.cp1251_3_a_ms_acm_mp3, -1, -1);
}
+ public void testLocalVideo_mkv_mp3_frame_incomplete() throws Exception {
+ playVideoTest(R.raw.mkv_mp3_frame_incomplete, -1, -1);
+ }
+
private void readSubtitleTracks() throws Exception {
mSubtitleTrackIndex.clear();
MediaPlayer.TrackInfo[] trackInfos = mMediaPlayer.getTrackInfo();
diff --git a/tests/tests/media/src/android/media/cts/MediaTimestampTest.java b/tests/tests/media/src/android/media/cts/MediaTimestampTest.java
index c3e59dc..de91124 100644
--- a/tests/tests/media/src/android/media/cts/MediaTimestampTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaTimestampTest.java
@@ -24,21 +24,9 @@
*/
public class MediaTimestampTest extends AndroidTestCase {
public void testMediaTimestamp() {
- MediaTimestamp timestamp = new MediaTimestamp.Builder()
- .setMediaTimestamp(1000, 2000, 2.0f)
- .build();
+ MediaTimestamp timestamp = new MediaTimestamp(1000, 2000, 2.0f);
assertEquals(1000, timestamp.getAnchorMediaTimeUs());
assertEquals(2000, timestamp.getAnchorSystemNanoTime());
assertEquals(2.0f, timestamp.getMediaClockRate());
}
-
- public void testMediaTimestampCopyCtor() {
- MediaTimestamp timestamp = new MediaTimestamp.Builder()
- .setMediaTimestamp(10000, 20000, 1.0f)
- .build();
- MediaTimestamp copy = new MediaTimestamp.Builder(timestamp).build();
- assertEquals(10000, copy.getAnchorMediaTimeUs());
- assertEquals(20000, copy.getAnchorSystemNanoTime());
- assertEquals(1.0f, copy.getMediaClockRate());
- }
}
diff --git a/tests/tests/media/src/android/media/cts/Session2CommandGroupTest.java b/tests/tests/media/src/android/media/cts/Session2CommandGroupTest.java
index 4e3798b..988ea87 100644
--- a/tests/tests/media/src/android/media/cts/Session2CommandGroupTest.java
+++ b/tests/tests/media/src/android/media/cts/Session2CommandGroupTest.java
@@ -46,7 +46,7 @@
public void testHasCommand() {
Session2Command testCommand = new Session2Command(TEST_COMMAND_CODE_1);
Session2CommandGroup.Builder builder = new Session2CommandGroup.Builder()
- .addCommand(TEST_COMMAND_CODE_1);
+ .addCommand(testCommand);
Session2CommandGroup commandGroup = builder.build();
assertTrue(commandGroup.hasCommand(TEST_COMMAND_CODE_1));
assertTrue(commandGroup.hasCommand(testCommand));
@@ -55,13 +55,15 @@
@Test
public void testGetCommands() {
+ Session2Command command1 = new Session2Command(TEST_COMMAND_CODE_1);
+ Session2Command command2 = new Session2Command(TEST_COMMAND_CODE_2);
Session2CommandGroup.Builder builder = new Session2CommandGroup.Builder()
- .addCommand(TEST_COMMAND_CODE_1);
+ .addCommand(command1);
Session2CommandGroup commandGroup = builder.build();
Set<Session2Command> commands = commandGroup.getCommands();
- assertTrue(commands.contains(new Session2Command(TEST_COMMAND_CODE_1)));
- assertFalse(commands.contains(new Session2Command(TEST_COMMAND_CODE_2)));
+ assertTrue(commands.contains(command1));
+ assertFalse(commands.contains(command2));
}
@Test
@@ -69,7 +71,7 @@
final int expected = 0;
Session2Command command = new Session2Command(TEST_COMMAND_CODE_1);
Session2CommandGroup.Builder builder = new Session2CommandGroup.Builder()
- .addCommand(TEST_COMMAND_CODE_1);
+ .addCommand(command);
Session2CommandGroup commandGroup = builder.build();
assertEquals(expected, commandGroup.describeContents());
}
@@ -77,8 +79,8 @@
@Test
public void testWriteToParcel() {
Session2CommandGroup.Builder builder = new Session2CommandGroup.Builder()
- .addCommand(TEST_COMMAND_CODE_1)
- .addCommand(TEST_COMMAND_CODE_2);
+ .addCommand(new Session2Command(TEST_COMMAND_CODE_1))
+ .addCommand(new Session2Command(TEST_COMMAND_CODE_2));
Session2CommandGroup commandGroup = builder.build();
Parcel dest = Parcel.obtain();
commandGroup.writeToParcel(dest, 0);
@@ -92,7 +94,7 @@
@Test
public void testBuilder() {
Session2CommandGroup.Builder builder = new Session2CommandGroup.Builder()
- .addCommand(TEST_COMMAND_CODE_1);
+ .addCommand(new Session2Command(TEST_COMMAND_CODE_1));
Session2CommandGroup commandGroup = builder.build();
Session2CommandGroup.Builder newBuilder = new Session2CommandGroup.Builder(commandGroup);
Session2CommandGroup newCommandGroup = newBuilder.build();
@@ -101,16 +103,18 @@
@Test
public void testAddAndRemoveCommand() {
- Session2Command testCommand = new Session2Command(TEST_COMMAND_CODE_1);
+ Session2Command testCommand1 = new Session2Command(TEST_COMMAND_CODE_1);
+ Session2Command testCommand2 = new Session2Command(TEST_COMMAND_CODE_2);
+ Session2Command testCommand3 = new Session2Command(TEST_COMMAND_CODE_3);
Session2CommandGroup.Builder builder = new Session2CommandGroup.Builder()
- .addCommand(testCommand)
- .addCommand(TEST_COMMAND_CODE_2)
- .addCommand(TEST_COMMAND_CODE_3);
- builder.removeCommand(testCommand)
- .removeCommand(TEST_COMMAND_CODE_2);
+ .addCommand(testCommand1)
+ .addCommand(testCommand2)
+ .addCommand(testCommand3);
+ builder.removeCommand(testCommand1)
+ .removeCommand(testCommand2);
Session2CommandGroup commandGroup = builder.build();
- assertFalse(commandGroup.hasCommand(testCommand));
- assertFalse(commandGroup.hasCommand(TEST_COMMAND_CODE_2));
- assertTrue(commandGroup.hasCommand(TEST_COMMAND_CODE_3));
+ assertFalse(commandGroup.hasCommand(testCommand1));
+ assertFalse(commandGroup.hasCommand(testCommand2));
+ assertTrue(commandGroup.hasCommand(testCommand3));
}
}
diff --git a/tests/tests/media/src/android/media/cts/StreamingMediaPlayer2Test.java b/tests/tests/media/src/android/media/cts/StreamingMediaPlayer2Test.java
index 73e36cb..3d7b689 100644
--- a/tests/tests/media/src/android/media/cts/StreamingMediaPlayer2Test.java
+++ b/tests/tests/media/src/android/media/cts/StreamingMediaPlayer2Test.java
@@ -358,8 +358,8 @@
}
final Uri uri = Uri.parse(stream_url);
- mPlayer.setDataSource(new UriDataSourceDesc.Builder()
- .setDataSource(mContext, uri)
+ mPlayer.setDataSource(new DataSourceDesc.Builder()
+ .setDataSource(uri)
.build());
mPlayer.setDisplay(getActivity().getSurfaceHolder());
@@ -421,8 +421,8 @@
}
final Uri uri = Uri.parse(stream_url);
- mPlayer.setDataSource(new UriDataSourceDesc.Builder()
- .setDataSource(mContext, uri)
+ mPlayer.setDataSource(new DataSourceDesc.Builder()
+ .setDataSource(uri)
.build());
mPlayer.setDisplay(getActivity().getSurfaceHolder());
@@ -517,8 +517,8 @@
assertTrue(mCallStatus != MediaPlayer2.CALL_STATUS_NO_ERROR);
final Uri uri = Uri.parse(stream_url);
- mPlayer.setDataSource(new UriDataSourceDesc.Builder()
- .setDataSource(mContext, uri)
+ mPlayer.setDataSource(new DataSourceDesc.Builder()
+ .setDataSource(uri)
.build());
mPlayer.setDisplay(getActivity().getSurfaceHolder());
@@ -598,8 +598,8 @@
final AtomicInteger counter = new AtomicInteger();
String stream_url = mServer.getAssetUrl("prog_index.m3u8");
final Uri uri = Uri.parse(stream_url);
- mPlayer.setDataSource(new UriDataSourceDesc.Builder()
- .setDataSource(mContext, uri)
+ mPlayer.setDataSource(new DataSourceDesc.Builder()
+ .setDataSource(uri)
.build());
mPlayer.setDisplay(getActivity().getSurfaceHolder());
mPlayer.setScreenOnWhilePlaying(true);
@@ -690,7 +690,7 @@
}
}
assertTrue("Stream has no timed ID3 track", i >= 0);
- mPlayer.selectTrack(mPlayer.getCurrentDataSource(), i);
+ mPlayer.selectTrack(mPlayer.getCurrentDataSource(), trackInfos.get(i));
synchronized (completion) {
completion.wait();
@@ -764,8 +764,8 @@
try {
String path = mServer.getDelayedAssetUrl("noiseandchirps.ogg", 15000);
final Uri uri = Uri.parse(path);
- mp.setDataSource(new UriDataSourceDesc.Builder()
- .setDataSource(mContext, uri)
+ mp.setDataSource(new DataSourceDesc.Builder()
+ .setDataSource(uri)
.build());
MediaPlayer2.EventCallback ecb =
diff --git a/tests/tests/media/src/android/media/cts/SubtitleDataTest.java b/tests/tests/media/src/android/media/cts/SubtitleDataTest.java
index 7058e6c..7080436 100644
--- a/tests/tests/media/src/android/media/cts/SubtitleDataTest.java
+++ b/tests/tests/media/src/android/media/cts/SubtitleDataTest.java
@@ -28,31 +28,16 @@
private static final String SUBTITLE_RAW_DATA = "RAW_DATA";
public void testSubtitleData() {
- SubtitleData subtitle = new SubtitleData.Builder()
- .setSubtitleData(1, 1000, 100, SUBTITLE_RAW_DATA.getBytes())
- .build();
+ SubtitleData subtitle = new SubtitleData(1, 1000, 100, SUBTITLE_RAW_DATA.getBytes());
assertEquals(1, subtitle.getTrackIndex());
assertEquals(1000, subtitle.getStartTimeUs());
assertEquals(100, subtitle.getDurationUs());
assertEquals(SUBTITLE_RAW_DATA, new String(subtitle.getData(), StandardCharsets.UTF_8));
}
- public void testSubtitleDataCopyCtor() {
- SubtitleData subtitle = new SubtitleData.Builder()
- .setSubtitleData(2, 8000, 1000, SUBTITLE_RAW_DATA.getBytes())
- .build();
- SubtitleData copy = new SubtitleData.Builder(subtitle).build();
- assertEquals(2, copy.getTrackIndex());
- assertEquals(8000, copy.getStartTimeUs());
- assertEquals(1000, copy.getDurationUs());
- assertEquals(SUBTITLE_RAW_DATA, new String(copy.getData(), StandardCharsets.UTF_8));
- }
-
public void testSubtitleDataNullData() {
try {
- SubtitleData subtitle2 = new SubtitleData.Builder()
- .setSubtitleData(1, 0, 0, null)
- .build();
+ SubtitleData subtitle2 = new SubtitleData(1, 0, 0, null);
} catch (IllegalArgumentException e) {
// Expected
return;
diff --git a/tests/tests/media/src/android/media/cts/TestDataSourceCallback.java b/tests/tests/media/src/android/media/cts/TestProxyFileDescriptorCallback.java
similarity index 67%
rename from tests/tests/media/src/android/media/cts/TestDataSourceCallback.java
rename to tests/tests/media/src/android/media/cts/TestProxyFileDescriptorCallback.java
index 067e281..0bc0215 100644
--- a/tests/tests/media/src/android/media/cts/TestDataSourceCallback.java
+++ b/tests/tests/media/src/android/media/cts/TestProxyFileDescriptorCallback.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 The Android Open Source Project
+ * Copyright 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.
@@ -17,21 +17,21 @@
package android.media.cts;
import android.content.res.AssetFileDescriptor;
-import android.media.cts.TestUtils.Monitor;
-import android.media.DataSourceCallback;
+import android.os.ProxyFileDescriptorCallback;
import android.platform.test.annotations.AppModeFull;
+import android.system.ErrnoException;
+import android.system.OsConstants;
import android.util.Log;
-import java.io.FileInputStream;
-import java.io.InputStream;
import java.io.IOException;
+import java.io.InputStream;
/**
- * A DataSourceCallback that reads from a byte array for use in tests.
+ * A ProxyFileDescriptorCallback that reads from a byte array for use in tests.
*/
@AppModeFull(reason = "TODO: evaluate and port to instant")
-public class TestDataSourceCallback extends DataSourceCallback {
- private static final String TAG = "TestDataSourceCallback";
+public class TestProxyFileDescriptorCallback extends ProxyFileDescriptorCallback {
+ private static final String TAG = "TestProxyFileDescriptorCallback";
private byte[] mData;
@@ -42,7 +42,8 @@
private boolean mIsClosed;
// Read an asset fd into a new byte array data source. Closes afd.
- public static TestDataSourceCallback fromAssetFd(AssetFileDescriptor afd) throws IOException {
+ public static TestProxyFileDescriptorCallback fromAssetFd(AssetFileDescriptor afd)
+ throws IOException {
try {
InputStream in = afd.createInputStream();
final int size = (int) afd.getDeclaredLength();
@@ -53,41 +54,40 @@
numRead = in.read(data, writeIndex, size - writeIndex);
writeIndex += numRead;
} while (numRead >= 0);
- return new TestDataSourceCallback(data);
+ return new TestProxyFileDescriptorCallback(data);
} finally {
afd.close();
}
}
- public TestDataSourceCallback(byte[] data) {
+ public TestProxyFileDescriptorCallback(byte[] data) {
mData = data;
}
@Override
- public synchronized int readAt(long position, byte[] buffer, int offset, int size)
- throws IOException {
+ public int onRead(long offset, int size, byte[] data) throws ErrnoException {
if (mThrowFromReadAt) {
- throw new IOException("Test exception from readAt()");
+ throw new ErrnoException("onRead", OsConstants.EIO);
}
if (mReturnFromReadAt != null) {
return mReturnFromReadAt;
}
// Clamp reads past the end of the source.
- if (position >= mData.length) {
- return -1; // -1 indicates EOF
+ if (offset >= mData.length) {
+ return 0; // 0 indicates EOF
}
- if (position + size > mData.length) {
- size -= (position + size) - mData.length;
+ if (offset + size > mData.length) {
+ size -= (offset + size) - mData.length;
}
- System.arraycopy(mData, (int)position, buffer, offset, size);
+ System.arraycopy(mData, (int)offset, data, 0, size);
return size;
}
@Override
- public synchronized long getSize() throws IOException {
+ public long onGetSize() throws ErrnoException {
if (mThrowFromGetSize) {
- throw new IOException("Test exception from getSize()");
+ throw new ErrnoException("onGetSize", OsConstants.EIO);
}
if (mReturnFromGetSize != null) {
return mReturnFromGetSize;
@@ -97,10 +97,9 @@
return mData.length;
}
- // Note: it's fine to keep using this data source after closing it.
@Override
- public synchronized void close() {
- Log.v(TAG, "close()");
+ public void onRelease() {
+ Log.d(TAG, "onRelease()");
mIsClosed = true;
}
diff --git a/tests/tests/media/src/android/media/cts/TimedMetaDataTest.java b/tests/tests/media/src/android/media/cts/TimedMetaDataTest.java
index d79427f..a5309995 100644
--- a/tests/tests/media/src/android/media/cts/TimedMetaDataTest.java
+++ b/tests/tests/media/src/android/media/cts/TimedMetaDataTest.java
@@ -28,27 +28,14 @@
private static final String RAW_METADATA = "RAW_METADATA";
public void testTimedMetaData() {
- TimedMetaData metadata = new TimedMetaData.Builder()
- .setTimedMetaData(1000, RAW_METADATA.getBytes())
- .build();
+ TimedMetaData metadata = new TimedMetaData(1000, RAW_METADATA.getBytes());
assertEquals(1000, metadata.getTimestamp());
assertEquals(RAW_METADATA, new String(metadata.getMetaData(), StandardCharsets.UTF_8));
}
- public void testTimedMetaDataCopyCtor() {
- TimedMetaData metadata = new TimedMetaData.Builder()
- .setTimedMetaData(2000, RAW_METADATA.getBytes())
- .build();
- TimedMetaData copy = new TimedMetaData.Builder(metadata).build();
- assertEquals(2000, copy.getTimestamp());
- assertEquals(RAW_METADATA, new String(copy.getMetaData(), StandardCharsets.UTF_8));
- }
-
public void testTimedMetaDataNullMetaData() {
try {
- TimedMetaData metadata = new TimedMetaData.Builder()
- .setTimedMetaData(0, null)
- .build();
+ TimedMetaData metadata = new TimedMetaData(0, null);
} catch (IllegalArgumentException e) {
// Expected
return;
diff --git a/tests/tests/midi/AndroidTest.xml b/tests/tests/midi/AndroidTest.xml
index 23c305e..cb4f94e 100644
--- a/tests/tests/midi/AndroidTest.xml
+++ b/tests/tests/midi/AndroidTest.xml
@@ -16,6 +16,8 @@
<configuration description="Config for CTS MIDI test cases">
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="media" />
+ <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
+ <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
<target_preparer class="com.android.tradefed.targetprep.SwitchUserTargetPreparer">
<option name="user-type" value="system" />
</target_preparer>
diff --git a/tests/tests/nativemedia/aaudio/OWNERS b/tests/tests/nativemedia/aaudio/OWNERS
new file mode 100644
index 0000000..89c8405
--- /dev/null
+++ b/tests/tests/nativemedia/aaudio/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 1344
+philburk@google.com
+mnaganov@google.com
diff --git a/tests/tests/nativemidi/AndroidTest.xml b/tests/tests/nativemidi/AndroidTest.xml
index 9ad78ec..2087cb3 100644
--- a/tests/tests/nativemidi/AndroidTest.xml
+++ b/tests/tests/nativemidi/AndroidTest.xml
@@ -16,6 +16,8 @@
<configuration description="Config for CTS MIDI test cases">
<option name="config-descriptor:metadata" key="component" value="media" />
<option name="test-suite-tag" value="cts" />
+ <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
+ <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
<option name="test-file-name" value="CtsNativeMidiTestCases.apk" />
diff --git a/tests/tests/net/src/android/net/cts/DnsResolverTest.java b/tests/tests/net/src/android/net/cts/DnsResolverTest.java
index 308f1ed..f6cc768 100644
--- a/tests/tests/net/src/android/net/cts/DnsResolverTest.java
+++ b/tests/tests/net/src/android/net/cts/DnsResolverTest.java
@@ -17,16 +17,22 @@
package android.net.cts;
import static android.net.DnsResolver.CLASS_IN;
+import static android.net.DnsResolver.FLAG_EMPTY;
import static android.net.DnsResolver.FLAG_NO_CACHE_LOOKUP;
+import static android.net.DnsResolver.TYPE_A;
import static android.net.DnsResolver.TYPE_AAAA;
+import static android.system.OsConstants.EBADF;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.DnsPacket;
import android.net.DnsResolver;
import android.net.Network;
import android.net.NetworkCapabilities;
+import android.net.ParseException;
+import android.os.CancellationSignal;
import android.os.Handler;
import android.os.Looper;
import android.system.ErrnoException;
@@ -37,6 +43,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
@@ -46,16 +53,17 @@
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
};
static final int TIMEOUT_MS = 12_000;
+ static final int CANCEL_RETRY_TIMES = 5;
private ConnectivityManager mCM;
- private Handler mHandler;
+ private Executor mExecutor;
private DnsResolver mDns;
protected void setUp() throws Exception {
super.setUp();
mCM = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
- mHandler = new Handler(Looper.getMainLooper());
mDns = DnsResolver.getInstance();
+ mExecutor = new Handler(Looper.getMainLooper())::post;
}
private static String byteArrayToHexString(byte[] bytes) {
@@ -86,41 +94,56 @@
return testableNetworks.toArray(new Network[0]);
}
- public void testInetAddressQuery() throws ErrnoException {
+ public void testQueryWithInetAddressCallback() {
final String dname = "www.google.com";
- final String msg = "InetAddress query " + dname;
+ final String msg = "Query with InetAddressAnswerCallback " + dname;
for (Network network : getTestableNetworks()) {
final CountDownLatch latch = new CountDownLatch(1);
final AtomicReference<List<InetAddress>> answers = new AtomicReference<>();
-
- mDns.query(network, dname, FLAG_NO_CACHE_LOOKUP, mHandler, answerList -> {
- answers.set(answerList);
- for (InetAddress addr : answerList) {
- Log.d(TAG, "Reported addr:" + addr.toString());
- }
- latch.countDown();
+ final DnsResolver.InetAddressAnswerCallback callback =
+ new DnsResolver.InetAddressAnswerCallback() {
+ @Override
+ public void onAnswer(@NonNull List<InetAddress> answerList) {
+ answers.set(answerList);
+ for (InetAddress addr : answerList) {
+ Log.d(TAG, "Reported addr: " + addr.toString());
}
- );
+ latch.countDown();
+ }
+
+ @Override
+ public void onParseException(@NonNull ParseException e) {
+ fail(msg + e.getMessage());
+ }
+
+ @Override
+ public void onQueryException(@NonNull ErrnoException e) {
+ fail(msg + e.getMessage());
+ }
+ };
+ mDns.query(network, dname, CLASS_IN, TYPE_A, FLAG_NO_CACHE_LOOKUP,
+ mExecutor, null, callback);
try {
assertTrue(msg + " but no valid answer after " + TIMEOUT_MS + "ms.",
latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
assertGreaterThan(msg + " returned 0 result", answers.get().size(), 0);
} catch (InterruptedException e) {
+ fail(msg + " Waiting for DNS lookup was interrupted");
}
}
}
- static private void assertGreaterThan(String msg, int a, int b) {
- assertTrue(msg + ": " + a + " > " + b, a > b);
+ static private void assertGreaterThan(String msg, int first, int second) {
+ assertTrue(msg + " Excepted " + first + " to be greater than " + second, first > second);
}
static private void assertValidAnswer(String msg, @NonNull DnsAnswer ans) {
// Check rcode field.(0, No error condition).
assertTrue(msg + " Response error, rcode: " + ans.getRcode(), ans.getRcode() == 0);
// Check answer counts.
- assertTrue(msg + " No answer found", ans.getANCount() > 0);
+ assertGreaterThan(msg + " No answer found", ans.getANCount(), 0);
// Check question counts.
- assertTrue(msg + " No question found", ans.getQDCount() > 0);
+ assertGreaterThan(msg + " No question found", ans.getQDCount(), 0);
}
static private void assertValidEmptyAnswer(String msg, @NonNull DnsAnswer ans) {
@@ -129,10 +152,10 @@
// Check answer counts. Expect 0 answer.
assertTrue(msg + " Not an empty answer", ans.getANCount() == 0);
// Check question counts.
- assertTrue(msg + " No question found", ans.getQDCount() > 0);
+ assertGreaterThan(msg + " No question found", ans.getQDCount(), 0);
}
- private class DnsAnswer extends DnsPacket {
+ private static class DnsAnswer extends DnsPacket {
DnsAnswer(@NonNull byte[] data) throws ParseException {
super(data);
// Check QR field.(query (0), or a response (1)).
@@ -152,34 +175,63 @@
}
}
- public void testRawQuery() throws ErrnoException {
+ class RawAnswerCallbackImpl extends DnsResolver.RawAnswerCallback {
+ private final CountDownLatch mLatch = new CountDownLatch(1);
+ private final String mMsg;
+ private final int mTimeout;
+
+ RawAnswerCallbackImpl(@NonNull String msg, int timeout) {
+ this.mMsg = msg;
+ this.mTimeout = timeout;
+ }
+
+ RawAnswerCallbackImpl(@NonNull String msg) {
+ this(msg, TIMEOUT_MS);
+ }
+
+ public boolean waitForAnswer() throws InterruptedException {
+ return mLatch.await(mTimeout, TimeUnit.MILLISECONDS);
+ }
+
+ @Override
+ public void onAnswer(@NonNull byte[] answer) {
+ try {
+ assertValidAnswer(mMsg, new DnsAnswer(answer));
+ Log.d(TAG, "Reported blob: " + byteArrayToHexString(answer));
+ mLatch.countDown();
+ } catch (ParseException e) {
+ fail(mMsg + e.getMessage());
+ }
+ }
+
+ @Override
+ public void onParseException(@NonNull ParseException e) {
+ fail(mMsg + e.getMessage());
+ }
+
+ @Override
+ public void onQueryException(@NonNull ErrnoException e) {
+ fail(mMsg + e.getMessage());
+ }
+ }
+
+ public void testQueryWithRawAnswerCallback() {
final String dname = "www.google.com";
- final String msg = "Raw query " + dname;
+ final String msg = "Query with RawAnswerCallback " + dname;
for (Network network : getTestableNetworks()) {
- final CountDownLatch latch = new CountDownLatch(1);
- mDns.query(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, mHandler,
- answer -> {
- if (answer == null) {
- fail(msg + " no answer returned");
- }
- try {
- assertValidAnswer(msg, new DnsAnswer(answer));
- Log.d(TAG, "Reported blob:" + byteArrayToHexString(answer));
- latch.countDown();
- } catch (DnsPacket.ParseException e) {
- fail(msg + e.getMessage());
- }
- }
- );
+ final RawAnswerCallbackImpl callback = new RawAnswerCallbackImpl(msg);
+ mDns.query(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP,
+ mExecutor, null, callback);
try {
assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.",
- latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+ callback.waitForAnswer());
} catch (InterruptedException e) {
+ fail(msg + " Waiting for DNS lookup was interrupted");
}
}
}
- public void testRawQueryWithBlob() throws ErrnoException {
+ public void testQueryBlobWithRawAnswerCallback() {
final byte[] blob = new byte[]{
/* Header */
0x55, 0x66, /* Transaction ID */
@@ -194,74 +246,227 @@
0x00, 0x01, /* Type */
0x00, 0x01 /* Class */
};
- final String msg = "Raw query with blob " + byteArrayToHexString(blob);
+ final String msg = "Query with RawAnswerCallback " + byteArrayToHexString(blob);
for (Network network : getTestableNetworks()) {
- final CountDownLatch latch = new CountDownLatch(1);
- mDns.query(network, blob, FLAG_NO_CACHE_LOOKUP, mHandler, answer -> {
- if (answer == null) {
- fail(msg + " no answer returned");
- }
- try {
- assertValidAnswer(msg, new DnsAnswer(answer));
- Log.d(TAG, "Reported blob:" + byteArrayToHexString(answer));
- latch.countDown();
- } catch (DnsPacket.ParseException e) {
- fail(msg + e.getMessage());
- }
- }
- );
+ final RawAnswerCallbackImpl callback = new RawAnswerCallbackImpl(msg);
+ mDns.query(network, blob, FLAG_NO_CACHE_LOOKUP, mExecutor, null, callback);
try {
assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.",
- latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+ callback.waitForAnswer());
} catch (InterruptedException e) {
+ fail(msg + " Waiting for DNS lookup was interrupted");
}
}
}
- public void testEmptyQuery() throws ErrnoException {
+ public void testQueryRoot() {
final String dname = "";
- final String msg = "Raw query empty dname(ROOT)";
+ final String msg = "Query with RawAnswerCallback empty dname(ROOT) ";
for (Network network : getTestableNetworks()) {
final CountDownLatch latch = new CountDownLatch(1);
- mDns.query(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, mHandler,
- answer -> {
- if (answer == null) {
- fail(msg + " no answer returned");
- }
- try {
- // Except no answer record because of querying with empty dname(ROOT)
- assertValidEmptyAnswer(msg, new DnsAnswer(answer));
- latch.countDown();
- } catch (DnsPacket.ParseException e) {
- fail(msg + e.getMessage());
- }
+ final DnsResolver.RawAnswerCallback callback = new DnsResolver.RawAnswerCallback() {
+ @Override
+ public void onAnswer(@NonNull byte[] answer) {
+ try {
+ // Except no answer record because of querying with empty dname(ROOT)
+ assertValidEmptyAnswer(msg, new DnsAnswer(answer));
+ latch.countDown();
+ } catch (ParseException e) {
+ fail(msg + e.getMessage());
}
- );
+ }
+
+ @Override
+ public void onParseException(@NonNull ParseException e) {
+ fail(msg + e.getMessage());
+ }
+
+ @Override
+ public void onQueryException(@NonNull ErrnoException e) {
+ fail(msg + e.getMessage());
+ }
+ };
+ mDns.query(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP,
+ mExecutor, null, callback);
try {
- assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.",
+ assertTrue(msg + "but no answer after " + TIMEOUT_MS + "ms.",
latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
} catch (InterruptedException e) {
+ fail(msg + "Waiting for DNS lookup was interrupted");
}
}
}
- public void testNXQuery() throws ErrnoException {
+ public void testQueryNXDomain() {
final String dname = "test1-nx.metric.gstatic.com";
- final String msg = "InetAddress query " + dname;
+ final String msg = "Query with InetAddressAnswerCallback " + dname;
for (Network network : getTestableNetworks()) {
final CountDownLatch latch = new CountDownLatch(1);
- mDns.query(network, dname, FLAG_NO_CACHE_LOOKUP, mHandler, answerList -> {
- if (answerList.size() == 0) {
- latch.countDown();
- return;
- }
- fail(msg + " but get valid answers");
+ final DnsResolver.InetAddressAnswerCallback callback =
+ new DnsResolver.InetAddressAnswerCallback() {
+ @Override
+ public void onAnswer(@NonNull List<InetAddress> answerList) {
+ if (answerList.size() == 0) {
+ latch.countDown();
+ return;
}
- );
+ fail(msg + " but get valid answers");
+ }
+
+ @Override
+ public void onParseException(@NonNull ParseException e) {
+ fail(msg + e.getMessage());
+ }
+
+ @Override
+ public void onQueryException(@NonNull ErrnoException e) {
+ fail(msg + e.getMessage());
+ }
+ };
+ mDns.query(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP,
+ mExecutor, null, callback);
try {
assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.",
latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
} catch (InterruptedException e) {
+ fail(msg + " Waiting for DNS lookup was interrupted");
+ }
+ }
+ }
+
+ /**
+ * A query callback that ensures that the query is cancelled and that onAnswer is never
+ * called. If the query succeeds before it is cancelled, needRetry will return true so the
+ * test can retry.
+ */
+ class VerifyCancelCallback extends DnsResolver.RawAnswerCallback {
+ private static final int CANCEL_TIMEOUT = 3_000;
+
+ private final CountDownLatch mLatch = new CountDownLatch(1);
+ private final String mMsg;
+ private final CancellationSignal mCancelSignal;
+
+ VerifyCancelCallback(@NonNull String msg, @NonNull CancellationSignal cancelSignal) {
+ this.mMsg = msg;
+ this.mCancelSignal = cancelSignal;
+ }
+
+ public boolean needRetry() throws InterruptedException {
+ return mLatch.await(CANCEL_TIMEOUT, TimeUnit.MILLISECONDS);
+ }
+
+ @Override
+ public void onAnswer(@NonNull byte[] answer) {
+ if (mCancelSignal.isCanceled()) {
+ fail(mMsg + " should not have returned any answers");
+ }
+ mLatch.countDown();
+ }
+
+ @Override
+ public void onParseException(@NonNull ParseException e) {
+ fail(mMsg + e.getMessage());
+ }
+
+ @Override
+ public void onQueryException(@NonNull ErrnoException e) {
+ if (mCancelSignal.isCanceled() && e.errno == EBADF) return;
+ fail(mMsg + e.getMessage());
+ }
+ }
+
+ public void testQueryCancel() throws ErrnoException {
+ final String dname = "www.google.com";
+ final String msg = "Test cancel query " + dname;
+ // Start a DNS query and the cancel it immediately. Use VerifyCancelCallback to expect
+ // that the query is cancelled before it succeeds. If it is not cancelled before it
+ // succeeds, retry the until it is.
+ for (Network network : getTestableNetworks()) {
+ boolean retry = false;
+ int round = 0;
+ do {
+ if (++round > CANCEL_RETRY_TIMES) {
+ fail(msg + " cancel failed " + CANCEL_RETRY_TIMES + " times");
+ }
+ final CountDownLatch latch = new CountDownLatch(1);
+ final CancellationSignal cancelSignal = new CancellationSignal();
+ final VerifyCancelCallback callback = new VerifyCancelCallback(msg, cancelSignal);
+ mDns.query(network, dname, CLASS_IN, TYPE_AAAA, FLAG_EMPTY,
+ mExecutor, cancelSignal, callback);
+ mExecutor.execute(() -> {
+ cancelSignal.cancel();
+ latch.countDown();
+ });
+ try {
+ retry = callback.needRetry();
+ assertTrue(msg + " query was not cancelled",
+ latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+ } catch (InterruptedException e) {
+ fail(msg + "Waiting for DNS lookup was interrupted");
+ }
+ } while (retry);
+ }
+ }
+
+ public void testQueryBlobCancel() throws ErrnoException {
+ final byte[] blob = new byte[]{
+ /* Header */
+ 0x55, 0x66, /* Transaction ID */
+ 0x01, 0x00, /* Flags */
+ 0x00, 0x01, /* Questions */
+ 0x00, 0x00, /* Answer RRs */
+ 0x00, 0x00, /* Authority RRs */
+ 0x00, 0x00, /* Additional RRs */
+ /* Queries */
+ 0x03, 0x77, 0x77, 0x77, 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6c, 0x65,
+ 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name */
+ 0x00, 0x01, /* Type */
+ 0x00, 0x01 /* Class */
+ };
+ final String msg = "Test cancel raw Query " + byteArrayToHexString(blob);
+ // Start a DNS query and the cancel it immediately. Use VerifyCancelCallback to expect
+ // that the query is cancelled before it succeeds. If it is not cancelled before it
+ // succeeds, retry the until it is.
+ for (Network network : getTestableNetworks()) {
+ boolean retry = false;
+ int round = 0;
+ do {
+ if (++round > CANCEL_RETRY_TIMES) {
+ fail(msg + " cancel failed " + CANCEL_RETRY_TIMES + " times");
+ }
+ final CountDownLatch latch = new CountDownLatch(1);
+ final CancellationSignal cancelSignal = new CancellationSignal();
+ final VerifyCancelCallback callback = new VerifyCancelCallback(msg, cancelSignal);
+ mDns.query(network, blob, FLAG_EMPTY, mExecutor, cancelSignal, callback);
+ mExecutor.execute(() -> {
+ cancelSignal.cancel();
+ latch.countDown();
+ });
+ try {
+ retry = callback.needRetry();
+ assertTrue(msg + " cancel is not done",
+ latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+ } catch (InterruptedException e) {
+ fail(msg + " Waiting for DNS lookup was interrupted");
+ }
+ } while (retry);
+ }
+ }
+
+ public void testCancelBeforeQuery() throws ErrnoException {
+ final String dname = "www.google.com";
+ final String msg = "Test cancelled query " + dname;
+ for (Network network : getTestableNetworks()) {
+ final RawAnswerCallbackImpl callback = new RawAnswerCallbackImpl(msg, 3_000);
+ final CancellationSignal cancelSignal = new CancellationSignal();
+ cancelSignal.cancel();
+ mDns.query(network, dname, CLASS_IN, TYPE_AAAA, FLAG_EMPTY,
+ mExecutor, cancelSignal, callback);
+ try {
+ assertTrue(msg + " should not return any answers",
+ !callback.waitForAnswer());
+ } catch (InterruptedException e) {
+ fail(msg + " Waiting for DNS lookup was interrupted");
}
}
}
diff --git a/tests/tests/net/src/android/net/cts/DnsTest.java b/tests/tests/net/src/android/net/cts/DnsTest.java
index 84231c2..746dcb0 100644
--- a/tests/tests/net/src/android/net/cts/DnsTest.java
+++ b/tests/tests/net/src/android/net/cts/DnsTest.java
@@ -287,7 +287,7 @@
final NetworkCallback callback = new NetworkCallback() {
@Override
public void onLinkPropertiesChanged(Network network, LinkProperties lp) {
- if (lp.hasGlobalIPv6Address()) {
+ if (lp.hasGlobalIpv6Address()) {
latch.countDown();
}
}
diff --git a/tests/tests/os/src/android/os/cts/PowerManagerTest.java b/tests/tests/os/src/android/os/cts/PowerManagerTest.java
index 24ba6ac..0d9b71f 100644
--- a/tests/tests/os/src/android/os/cts/PowerManagerTest.java
+++ b/tests/tests/os/src/android/os/cts/PowerManagerTest.java
@@ -66,7 +66,7 @@
public void setUp() {
// store the current value so we can restore it
ContentResolver resolver = getContext().getContentResolver();
- mInitialPowerSaverMode = Global.getInt(resolver, Global.AUTOMATIC_POWER_SAVER_MODE, 0);
+ mInitialPowerSaverMode = Global.getInt(resolver, Global.AUTOMATIC_POWER_SAVE_MODE, 0);
mInitialDynamicPowerSavingsEnabled =
Global.getInt(resolver, Global.DYNAMIC_POWER_SAVINGS_ENABLED, 0);
mInitialThreshold =
@@ -80,7 +80,7 @@
ContentResolver resolver = getContext().getContentResolver();
// Verify we can change it to dynamic.
- Global.putInt(resolver, Global.AUTOMATIC_POWER_SAVER_MODE, mInitialPowerSaverMode);
+ Global.putInt(resolver, Global.AUTOMATIC_POWER_SAVE_MODE, mInitialPowerSaverMode);
Global.putInt(resolver,
Global.DYNAMIC_POWER_SAVINGS_ENABLED, mInitialDynamicPowerSavingsEnabled);
Global.putInt(resolver,
@@ -94,16 +94,16 @@
ContentResolver resolver = getContext().getContentResolver();
// Verify we can change it to percentage.
- Global.putInt(resolver, Global.AUTOMATIC_POWER_SAVER_MODE, 0);
+ Global.putInt(resolver, Global.AUTOMATIC_POWER_SAVE_MODE, 0);
assertEquals(
- PowerManager.POWER_SAVER_MODE_PERCENTAGE,
- manager.getPowerSaveMode());
+ PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE,
+ manager.getPowerSaveModeTrigger());
// Verify we can change it to dynamic.
- Global.putInt(resolver, Global.AUTOMATIC_POWER_SAVER_MODE, 1);
+ Global.putInt(resolver, Global.AUTOMATIC_POWER_SAVE_MODE, 1);
assertEquals(
- PowerManager.POWER_SAVER_MODE_DYNAMIC,
- manager.getPowerSaveMode());
+ PowerManager.POWER_SAVE_MODE_TRIGGER_DYNAMIC,
+ manager.getPowerSaveModeTrigger());
});
}
@@ -113,12 +113,12 @@
ContentResolver resolver = getContext().getContentResolver();
// Verify settings are actually updated.
- manager.setDynamicPowerSavings(true, 80);
+ manager.setDynamicPowerSaveHint(true, 80);
assertEquals(1, Global.getInt(resolver, Global.DYNAMIC_POWER_SAVINGS_ENABLED, 0));
assertEquals(80, Global.getInt(resolver,
Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, 0));
- manager.setDynamicPowerSavings(false, 20);
+ manager.setDynamicPowerSaveHint(false, 20);
assertEquals(0, Global.getInt(resolver, Global.DYNAMIC_POWER_SAVINGS_ENABLED, 1));
assertEquals(20, Global.getInt(resolver,
Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, 0));
diff --git a/tests/tests/os/src/android/os/cts/SystemClockTest.java b/tests/tests/os/src/android/os/cts/SystemClockTest.java
index 21ca442..0764e79 100644
--- a/tests/tests/os/src/android/os/cts/SystemClockTest.java
+++ b/tests/tests/os/src/android/os/cts/SystemClockTest.java
@@ -74,5 +74,4 @@
long end = SystemClock.uptimeMillis();
assertTrue(end - 100 >= start);
}
-
}
diff --git a/tests/tests/packageinstaller/install/OWNERS b/tests/tests/packageinstaller/install/OWNERS
new file mode 100644
index 0000000..0088192
--- /dev/null
+++ b/tests/tests/packageinstaller/install/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 36137
+moltmann@google.com
\ No newline at end of file
diff --git a/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/SessionTest.kt b/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/SessionTest.kt
index 92b9262..7c7a776 100644
--- a/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/SessionTest.kt
+++ b/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/SessionTest.kt
@@ -17,20 +17,19 @@
import android.app.Activity.RESULT_CANCELED
import android.app.AppOpsManager.MODE_ALLOWED
-import android.app.PendingIntent
-import android.app.PendingIntent.FLAG_UPDATE_CURRENT
-import android.content.Intent
import android.content.pm.ApplicationInfo.CATEGORY_MAPS
import android.content.pm.ApplicationInfo.CATEGORY_UNDEFINED
+import android.content.pm.PackageInstaller
import android.content.pm.PackageInstaller.STATUS_FAILURE_ABORTED
-import android.content.pm.PackageInstaller.STATUS_PENDING_USER_ACTION
import android.content.pm.PackageInstaller.STATUS_SUCCESS
import android.content.pm.PackageManager
-import androidx.test.InstrumentationRegistry
-import androidx.test.runner.AndroidJUnit4
+import android.platform.test.annotations.AppModeFull
+import android.platform.test.annotations.AppModeInstant
import android.support.test.uiautomator.By
import android.support.test.uiautomator.UiDevice
import android.support.test.uiautomator.Until
+import androidx.test.InstrumentationRegistry
+import androidx.test.runner.AndroidJUnit4
import com.android.compatibility.common.util.AppOpsUtils
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNull
@@ -39,7 +38,11 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import java.lang.NullPointerException
import java.util.concurrent.TimeUnit
+import kotlin.Int
+import kotlin.Long
+import kotlin.String
private const val INSTALL_BUTTON_ID = "button1"
private const val CANCEL_BUTTON_ID = "button2"
@@ -96,6 +99,17 @@
/**
* Check that we can install an app via a package-installer session
*/
+ @AppModeInstant(reason = "Only instant apps cannot create installer sessions")
+ @Test(expected = NullPointerException::class)
+ fun instantAppsCannotCreateInstallSessions() {
+ pm.packageInstaller.createSession(
+ PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL))
+ }
+
+ /**
+ * Check that we can install an app via a package-installer session
+ */
+ @AppModeFull(reason = "Instant apps cannot create installer sessions")
@Test
fun confirmInstallation() {
startInstallationViaSession()
@@ -116,6 +130,7 @@
/**
* Check that we can set an app category for an app we installed
*/
+ @AppModeFull(reason = "Instant apps cannot create installer sessions")
@Test
fun setAppCategory() {
startInstallationViaSession()
@@ -136,6 +151,7 @@
* Install an app via a package-installer session, but then cancel it when the package installer
* pops open.
*/
+ @AppModeFull(reason = "Instant apps cannot create installer sessions")
@Test
fun cancelInstallation() {
startInstallationViaSession()
diff --git a/tests/tests/packageinstaller/nopermission/OWNERS b/tests/tests/packageinstaller/nopermission/OWNERS
new file mode 100644
index 0000000..c126a70
--- /dev/null
+++ b/tests/tests/packageinstaller/nopermission/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 137825
+moltmann@google.com
\ No newline at end of file
diff --git a/tests/tests/packageinstaller/nopermission25/OWNERS b/tests/tests/packageinstaller/nopermission25/OWNERS
new file mode 100644
index 0000000..c126a70
--- /dev/null
+++ b/tests/tests/packageinstaller/nopermission25/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 137825
+moltmann@google.com
\ No newline at end of file
diff --git a/tests/tests/permission/AndroidTest.xml b/tests/tests/permission/AndroidTest.xml
index efe1b58..5f28a77 100644
--- a/tests/tests/permission/AndroidTest.xml
+++ b/tests/tests/permission/AndroidTest.xml
@@ -46,6 +46,10 @@
<option name="push" value="CtsAppThatRequestsLocationAndBackgroundPermission29.apk->/data/local/tmp/cts/permissions/CtsAppThatRequestsLocationAndBackgroundPermission29.apk" />
<option name="push" value="CtsAppThatAccessesLocationOnCommand.apk->/data/local/tmp/cts/permissions/CtsAppThatAccessesLocationOnCommand.apk" />
<option name="push" value="AppThatDoesNotHaveBgLocationAccess.apk->/data/local/tmp/cts/permissions/AppThatDoesNotHaveBgLocationAccess.apk" />
+ <option name="push" value="CtsAppThatAccessesStorageOnCommand22.apk->/data/local/tmp/cts/permissions/CtsAppThatAccessesStorageOnCommand22.apk" />
+ <option name="push" value="CtsAppThatAccessesStorageOnCommand28.apk->/data/local/tmp/cts/permissions/CtsAppThatAccessesStorageOnCommand28.apk" />
+ <option name="push" value="CtsAppThatAccessesStorageOnCommand29.apk->/data/local/tmp/cts/permissions/CtsAppThatAccessesStorageOnCommand29.apk" />
+ <option name="push" value="CtsAppThatAccessesStorageOnCommand28v3.apk->/data/local/tmp/cts/permissions/CtsAppThatAccessesStorageOnCommand28v3.apk" />
</target_preparer>
<!-- Remove additional apps if installed -->
diff --git a/tests/jank/Android.mk b/tests/tests/permission/AppThatAccessesStorage22/Android.mk
similarity index 62%
copy from tests/jank/Android.mk
copy to tests/tests/permission/AppThatAccessesStorage22/Android.mk
index 2ce4a98..db662e0 100644
--- a/tests/jank/Android.mk
+++ b/tests/tests/permission/AppThatAccessesStorage22/Android.mk
@@ -1,4 +1,5 @@
-# Copyright (C) 2015 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,30 +12,19 @@
# 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 := optional
+LOCAL_MODULE_TAGS := tests
+LOCAL_SDK_VERSION := current
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := CtsJankDeviceTestCases
-LOCAL_SDK_VERSION := current
-
# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
-LOCAL_STATIC_JAVA_LIBRARIES := \
- compatibility-device-util-axt \
- ctstestrunner-axt \
- ub-uiautomator \
- androidx.test.janktesthelper \
- junit
-
-LOCAL_JAVA_LIBRARIES := android.test.base.stubs
+LOCAL_PACKAGE_NAME := CtsAppThatAccessesStorageOnCommand22
include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/permission/AppThatAccessesStorage22/AndroidManifest.xml b/tests/tests/permission/AppThatAccessesStorage22/AndroidManifest.xml
new file mode 100644
index 0000000..152ed4c
--- /dev/null
+++ b/tests/tests/permission/AppThatAccessesStorage22/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.permission.cts.appthataccessesstorage"
+ android:versionCode="1">
+
+ <uses-sdk android:targetSdkVersion="22" />
+
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+
+ <application android:label="CtsStorageAccess" />
+</manifest>
+
diff --git a/tests/jank/Android.mk b/tests/tests/permission/AppThatAccessesStorage28/Android.mk
similarity index 62%
copy from tests/jank/Android.mk
copy to tests/tests/permission/AppThatAccessesStorage28/Android.mk
index 2ce4a98..2edf5b5 100644
--- a/tests/jank/Android.mk
+++ b/tests/tests/permission/AppThatAccessesStorage28/Android.mk
@@ -1,4 +1,5 @@
-# Copyright (C) 2015 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,30 +12,19 @@
# 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 := optional
+LOCAL_MODULE_TAGS := tests
+LOCAL_SDK_VERSION := current
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := CtsJankDeviceTestCases
-LOCAL_SDK_VERSION := current
-
# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
-LOCAL_STATIC_JAVA_LIBRARIES := \
- compatibility-device-util-axt \
- ctstestrunner-axt \
- ub-uiautomator \
- androidx.test.janktesthelper \
- junit
-
-LOCAL_JAVA_LIBRARIES := android.test.base.stubs
+LOCAL_PACKAGE_NAME := CtsAppThatAccessesStorageOnCommand28
include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/permission/AppThatAccessesStorage28/AndroidManifest.xml b/tests/tests/permission/AppThatAccessesStorage28/AndroidManifest.xml
new file mode 100644
index 0000000..55cc4d4
--- /dev/null
+++ b/tests/tests/permission/AppThatAccessesStorage28/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.permission.cts.appthataccessesstorage"
+ android:versionCode="1">
+
+ <uses-sdk android:targetSdkVersion="28" />
+
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+
+ <application android:label="CtsStorageAccess" />
+</manifest>
+
diff --git a/tests/jank/Android.mk b/tests/tests/permission/AppThatAccessesStorage28v3/Android.mk
similarity index 62%
copy from tests/jank/Android.mk
copy to tests/tests/permission/AppThatAccessesStorage28v3/Android.mk
index 2ce4a98..64aedd1 100644
--- a/tests/jank/Android.mk
+++ b/tests/tests/permission/AppThatAccessesStorage28v3/Android.mk
@@ -1,4 +1,5 @@
-# Copyright (C) 2015 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,30 +12,19 @@
# 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 := optional
+LOCAL_MODULE_TAGS := tests
+LOCAL_SDK_VERSION := current
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := CtsJankDeviceTestCases
-LOCAL_SDK_VERSION := current
-
# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
-LOCAL_STATIC_JAVA_LIBRARIES := \
- compatibility-device-util-axt \
- ctstestrunner-axt \
- ub-uiautomator \
- androidx.test.janktesthelper \
- junit
-
-LOCAL_JAVA_LIBRARIES := android.test.base.stubs
+LOCAL_PACKAGE_NAME := CtsAppThatAccessesStorageOnCommand28v3
include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/permission/AppThatAccessesStorage28v3/AndroidManifest.xml b/tests/tests/permission/AppThatAccessesStorage28v3/AndroidManifest.xml
new file mode 100644
index 0000000..af8311e
--- /dev/null
+++ b/tests/tests/permission/AppThatAccessesStorage28v3/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.permission.cts.appthataccessesstorage"
+ android:versionCode="3">
+
+ <uses-sdk android:targetSdkVersion="28" />
+
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+
+ <application android:label="CtsStorageAccess" />
+</manifest>
+
diff --git a/tests/jank/Android.mk b/tests/tests/permission/AppThatAccessesStorage29/Android.mk
similarity index 62%
copy from tests/jank/Android.mk
copy to tests/tests/permission/AppThatAccessesStorage29/Android.mk
index 2ce4a98..3c3571e 100644
--- a/tests/jank/Android.mk
+++ b/tests/tests/permission/AppThatAccessesStorage29/Android.mk
@@ -1,4 +1,5 @@
-# Copyright (C) 2015 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,30 +12,19 @@
# 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 := optional
+LOCAL_MODULE_TAGS := tests
+LOCAL_SDK_VERSION := current
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := CtsJankDeviceTestCases
-LOCAL_SDK_VERSION := current
-
# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
-LOCAL_STATIC_JAVA_LIBRARIES := \
- compatibility-device-util-axt \
- ctstestrunner-axt \
- ub-uiautomator \
- androidx.test.janktesthelper \
- junit
-
-LOCAL_JAVA_LIBRARIES := android.test.base.stubs
+LOCAL_PACKAGE_NAME := CtsAppThatAccessesStorageOnCommand29
include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/permission/AppThatAccessesStorage29/AndroidManifest.xml b/tests/tests/permission/AppThatAccessesStorage29/AndroidManifest.xml
new file mode 100644
index 0000000..d4ec8d7
--- /dev/null
+++ b/tests/tests/permission/AppThatAccessesStorage29/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.permission.cts.appthataccessesstorage"
+ android:versionCode="2">
+
+ <!-- STOPSHIP: Set to apk level that shipped the location tristate -->
+ <!-- <uses-sdk android:targetSdkVersion="29" /> -->
+
+ <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
+
+ <application android:label="CtsStorageAccess" />
+</manifest>
+
diff --git a/tests/tests/permission/OWNERS b/tests/tests/permission/OWNERS
index e5912b6..1a453cc 100644
--- a/tests/tests/permission/OWNERS
+++ b/tests/tests/permission/OWNERS
@@ -1,2 +1,3 @@
# Bug component: 137825
moltmann@google.com
+per-file PowerManagerServicePermissionTest.java = dehboxturtle@google.com
diff --git a/tests/tests/permission/src/android/permission/cts/DualStoragePermissionModelTest.java b/tests/tests/permission/src/android/permission/cts/DualStoragePermissionModelTest.java
new file mode 100644
index 0000000..915a13d
--- /dev/null
+++ b/tests/tests/permission/src/android/permission/cts/DualStoragePermissionModelTest.java
@@ -0,0 +1,377 @@
+/*
+ * 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.permission.cts;
+
+import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
+import static android.Manifest.permission.READ_MEDIA_AUDIO;
+import static android.Manifest.permission.READ_MEDIA_IMAGES;
+import static android.Manifest.permission.READ_MEDIA_VIDEO;
+import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
+import static android.app.AppOpsManager.MODE_ALLOWED;
+import static android.app.AppOpsManager.OPSTR_LEGACY_STORAGE;
+import static android.content.pm.PackageManager.FLAG_PERMISSION_HIDDEN;
+import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
+import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
+import static android.permission.cts.PermissionUtils.getPermissionFlags;
+import static android.permission.cts.PermissionUtils.getPermissions;
+import static android.permission.cts.PermissionUtils.getRuntimePermissions;
+import static android.permission.cts.PermissionUtils.grantPermission;
+import static android.permission.cts.PermissionUtils.install;
+import static android.permission.cts.PermissionUtils.isGranted;
+import static android.permission.cts.PermissionUtils.isPermissionGranted;
+import static android.permission.cts.PermissionUtils.setAppOpByName;
+import static android.permission.cts.PermissionUtils.setPermissionFlags;
+import static android.permission.cts.PermissionUtils.uninstallApp;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static java.util.stream.Collectors.toList;
+
+import android.platform.test.annotations.AppModeFull;
+
+import androidx.annotation.NonNull;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Verify changes to the storage permission model when it switches from one mode to the other
+ */
+@AppModeFull(reason = "This tests the behavior of a different app, not this app.")
+public class DualStoragePermissionModelTest {
+ /** The package name of all apps used in the test */
+ private static final String APP_PKG = "android.permission.cts.appthataccessesstorage";
+
+ private static final String TMP_DIR = "/data/local/tmp/cts/permissions/";
+ private static final String APK_22 = TMP_DIR + "CtsAppThatAccessesStorageOnCommand22.apk";
+ private static final String APK_28 = TMP_DIR + "CtsAppThatAccessesStorageOnCommand28.apk";
+ private static final String APK_29 = TMP_DIR + "CtsAppThatAccessesStorageOnCommand29.apk";
+ private static final String APK_28v3 = TMP_DIR + "CtsAppThatAccessesStorageOnCommand28v3.apk";
+
+ /**
+ * Assert that a permission of {@link #APP_PKG} has some flags.
+ *
+ * @param permission The permission having the flags
+ * @param flags The flags required
+ */
+ private void assertHasFlags(@NonNull String permission, int flags) {
+ assertThat(getPermissionFlags(APP_PKG, permission) & flags).isEqualTo(flags);
+ }
+
+ /**
+ * Assert that a permission of {@link #APP_PKG} does <u>not</u> have some flags.
+ *
+ * @param permission The permission owning the flags
+ * @param flags The flags required to not to be set
+ */
+ private void assertHasNotFlags(@NonNull String permission, int flags) {
+ assertThat(getPermissionFlags(APP_PKG, permission) & flags).isEqualTo(0);
+ }
+
+ /**
+ * Assert the state that is always true for P apps
+ */
+ private void assertLegacyStoragePermissionModel() throws Exception {
+ assertHasFlags(READ_MEDIA_IMAGES, FLAG_PERMISSION_HIDDEN);
+ assertHasFlags(READ_MEDIA_VIDEO, FLAG_PERMISSION_HIDDEN);
+ assertHasFlags(READ_MEDIA_AUDIO, FLAG_PERMISSION_HIDDEN);
+
+ assertHasNotFlags(READ_EXTERNAL_STORAGE, FLAG_PERMISSION_HIDDEN);
+ assertHasNotFlags(WRITE_EXTERNAL_STORAGE, FLAG_PERMISSION_HIDDEN);
+
+ // Modern permission are always granted to not get into the way when checking both legacy
+ // and modern permissions
+ assertThat(isGranted(APP_PKG, READ_MEDIA_IMAGES)).isTrue();
+ assertThat(isGranted(APP_PKG, READ_MEDIA_VIDEO)).isTrue();
+ assertThat(isGranted(APP_PKG, READ_MEDIA_AUDIO)).isTrue();
+ }
+
+ /**
+ * Assert the state that is always true for <u>not</u> grandfathered Q apps
+ */
+ private void assertModernStoragePermissionModel() throws Exception {
+ assertHasFlags(READ_EXTERNAL_STORAGE, FLAG_PERMISSION_HIDDEN);
+ assertHasFlags(WRITE_EXTERNAL_STORAGE, FLAG_PERMISSION_HIDDEN);
+
+ assertHasNotFlags(READ_MEDIA_IMAGES, FLAG_PERMISSION_HIDDEN);
+
+ assertThat(getPermissions(APP_PKG)).doesNotContain(READ_MEDIA_VIDEO);
+ assertThat(getPermissions(APP_PKG)).doesNotContain(READ_MEDIA_AUDIO);
+
+ // Legacy permission are always granted to not get into the way when checking both legacy
+ // and modern permissions
+ assertThat(isGranted(APP_PKG, READ_EXTERNAL_STORAGE)).isTrue();
+ assertThat(isGranted(APP_PKG, WRITE_EXTERNAL_STORAGE)).isTrue();
+ }
+
+ /**
+ * Assert the state that is always true for grandfathered Q apps
+ */
+ private void assertGrandfatheredStoragePermissionModel() throws Exception {
+ assertHasFlags(READ_MEDIA_IMAGES, FLAG_PERMISSION_HIDDEN);
+
+ assertHasNotFlags(READ_EXTERNAL_STORAGE, FLAG_PERMISSION_HIDDEN);
+ assertHasNotFlags(WRITE_EXTERNAL_STORAGE, FLAG_PERMISSION_HIDDEN);
+
+ assertThat(getPermissions(APP_PKG)).doesNotContain(READ_MEDIA_VIDEO);
+ assertThat(getPermissions(APP_PKG)).doesNotContain(READ_MEDIA_AUDIO);
+
+ // In grandfathered mode all permissions are always granted
+ assertThat(isGranted(APP_PKG, READ_EXTERNAL_STORAGE)).isTrue();
+ assertThat(isGranted(APP_PKG, WRITE_EXTERNAL_STORAGE)).isTrue();
+ assertThat(isGranted(APP_PKG, READ_MEDIA_IMAGES)).isTrue();
+ }
+
+ /**
+ * Install an app as if it would have been grandfathered during the P->Q update
+ *
+ * @param apkFile The file to install
+ */
+ private void installGrandfatheredApp(@NonNull String apkFile) {
+ install(apkFile);
+ setAppOpByName(APP_PKG, OPSTR_LEGACY_STORAGE, MODE_ALLOWED);
+
+ // Re-run storage mode change code
+ install(apkFile);
+ }
+
+ @Before
+ @After
+ public void uninstallTestApp() {
+ uninstallApp(APP_PKG);
+ }
+
+ @Test
+ public void lNoUpdate() throws Exception {
+ install(APK_22);
+
+ assertLegacyStoragePermissionModel();
+
+ // L apps always have all permissions granted, but the app-ops might be denied
+ assertThat(getRuntimePermissions(APP_PKG)).containsExactlyElementsIn(
+ getRuntimePermissions(APP_PKG).stream()
+ .filter(p -> isPermissionGranted(APP_PKG, p))
+ .collect(toList()));
+
+ assertThat(isGranted(APP_PKG, READ_EXTERNAL_STORAGE)).isTrue();
+ assertThat(isGranted(APP_PKG, WRITE_EXTERNAL_STORAGE)).isTrue();
+ }
+
+ @Test
+ public void pNoUpdate() throws Exception {
+ install(APK_28);
+
+ assertLegacyStoragePermissionModel();
+
+ assertThat(isGranted(APP_PKG, READ_EXTERNAL_STORAGE)).isFalse();
+ assertThat(isGranted(APP_PKG, WRITE_EXTERNAL_STORAGE)).isFalse();
+ }
+
+ @Test
+ public void qNoUpdate() throws Exception {
+ install(APK_29);
+
+ assertModernStoragePermissionModel();
+
+ assertThat(isGranted(APP_PKG, READ_MEDIA_IMAGES)).isFalse();
+ }
+
+ @Test
+ public void lToPUpdate() throws Exception {
+ install(APK_22);
+ install(APK_28v3);
+
+ assertLegacyStoragePermissionModel();
+
+ // Permissions will get revoked on upgrade 22->23
+ assertThat(isGranted(APP_PKG, READ_EXTERNAL_STORAGE)).isFalse();
+ assertThat(isGranted(APP_PKG, WRITE_EXTERNAL_STORAGE)).isFalse();
+ }
+
+ @Test
+ public void lToQUpdate() throws Exception {
+ install(APK_22);
+ install(APK_29);
+
+ assertModernStoragePermissionModel();
+
+ // Permissions will get revoked on upgrade 22->23
+ assertThat(isGranted(APP_PKG, READ_MEDIA_IMAGES)).isFalse();
+ }
+
+ @Test
+ public void pToPUpdate() throws Exception {
+ install(APK_28);
+ // No change of permission model, just version change of app
+ install(APK_28v3);
+
+ assertLegacyStoragePermissionModel();
+
+ assertThat(isGranted(APP_PKG, READ_EXTERNAL_STORAGE)).isFalse();
+ assertThat(isGranted(APP_PKG, WRITE_EXTERNAL_STORAGE)).isFalse();
+ }
+
+ @Test
+ public void pToQUpdate() throws Exception {
+ install(APK_28);
+ install(APK_29);
+
+ assertModernStoragePermissionModel();
+
+ assertThat(isGranted(APP_PKG, READ_MEDIA_IMAGES)).isFalse();
+ }
+
+ @Test
+ public void qToPUpdate() throws Exception {
+ install(APK_29);
+ install(APK_28v3);
+
+ assertLegacyStoragePermissionModel();
+
+ assertThat(isGranted(APP_PKG, READ_EXTERNAL_STORAGE)).isFalse();
+ assertThat(isGranted(APP_PKG, WRITE_EXTERNAL_STORAGE)).isFalse();
+ }
+
+ @Test
+ public void pToPUpdateGranted() throws Exception {
+ install(APK_28);
+ grantPermission(APP_PKG, READ_EXTERNAL_STORAGE);
+ // No change of permission model, just version change of app
+ install(APK_28v3);
+
+ assertLegacyStoragePermissionModel();
+
+ assertThat(isGranted(APP_PKG, READ_EXTERNAL_STORAGE)).isTrue();
+ assertThat(isGranted(APP_PKG, WRITE_EXTERNAL_STORAGE)).isFalse();
+ }
+
+ @Test
+ public void pToQUpdateGranted() throws Exception {
+ install(APK_28);
+ grantPermission(APP_PKG, WRITE_EXTERNAL_STORAGE);
+ install(APK_29);
+
+ assertModernStoragePermissionModel();
+
+ assertThat(isGranted(APP_PKG, READ_MEDIA_IMAGES)).isTrue();
+ }
+
+ @Test
+ public void qToPUpdateGranted() throws Exception {
+ install(APK_29);
+ grantPermission(APP_PKG, READ_MEDIA_IMAGES);
+ install(APK_28v3);
+
+ assertLegacyStoragePermissionModel();
+
+ assertThat(isGranted(APP_PKG, READ_EXTERNAL_STORAGE)).isTrue();
+ assertThat(isGranted(APP_PKG, WRITE_EXTERNAL_STORAGE)).isTrue();
+ }
+
+ @Test
+ public void preserveUserSetDuringPToQUpdate() {
+ install(APK_28);
+ setPermissionFlags(APP_PKG, READ_EXTERNAL_STORAGE, FLAG_PERMISSION_USER_SET,
+ FLAG_PERMISSION_USER_SET);
+ install(APK_29);
+
+ assertHasFlags(READ_MEDIA_IMAGES, FLAG_PERMISSION_USER_SET);
+ }
+
+ @Test
+ public void preserveUserSetDuringQToPUpdate() {
+ install(APK_29);
+ setPermissionFlags(APP_PKG, READ_MEDIA_IMAGES, FLAG_PERMISSION_USER_SET,
+ FLAG_PERMISSION_USER_SET);
+ install(APK_28v3);
+
+ assertHasFlags(READ_EXTERNAL_STORAGE, FLAG_PERMISSION_USER_SET);
+ assertHasFlags(WRITE_EXTERNAL_STORAGE, FLAG_PERMISSION_USER_SET);
+ }
+
+ @Test
+ public void dontCreateSystemFixedGrantedDuringPToQUpdate() throws Exception {
+ install(APK_28);
+ setPermissionFlags(APP_PKG, READ_EXTERNAL_STORAGE, FLAG_PERMISSION_USER_FIXED,
+ FLAG_PERMISSION_USER_FIXED);
+ grantPermission(APP_PKG, WRITE_EXTERNAL_STORAGE);
+ install(APK_29);
+
+ // USER_FIXED and granted cannot happen at the same time. Hence when inheriting the state,
+ // granted is preferred
+ assertThat(isGranted(APP_PKG, READ_MEDIA_IMAGES)).isTrue();
+ assertHasNotFlags(READ_MEDIA_IMAGES, FLAG_PERMISSION_USER_FIXED);
+ }
+
+ @Test
+ public void grandfatheredLNoUpdate() throws Exception {
+ installGrandfatheredApp(APK_22);
+
+ assertLegacyStoragePermissionModel();
+ }
+
+ @Test
+ public void grandfatheredPNoUpdate() throws Exception {
+ installGrandfatheredApp(APK_28);
+
+ assertLegacyStoragePermissionModel();
+ }
+
+ @Test
+ public void grandfatheredQNoUpdate() throws Exception {
+ installGrandfatheredApp(APK_29);
+
+ assertGrandfatheredStoragePermissionModel();
+ }
+
+ @Test
+ public void grandfatheredLToPUpdate() throws Exception {
+ installGrandfatheredApp(APK_22);
+ install(APK_28);
+
+ assertLegacyStoragePermissionModel();
+
+ // Permissions will get revoked on upgrade 22->23
+ assertThat(isGranted(APP_PKG, READ_EXTERNAL_STORAGE)).isFalse();
+ assertThat(isGranted(APP_PKG, WRITE_EXTERNAL_STORAGE)).isFalse();
+ }
+
+ @Test
+ public void grandfatheredLToQUpdate() throws Exception {
+ installGrandfatheredApp(APK_22);
+ install(APK_29);
+
+ assertGrandfatheredStoragePermissionModel();
+ }
+
+ @Test
+ public void grandfatheredPToQUpdate() throws Exception {
+ installGrandfatheredApp(APK_28);
+ install(APK_29);
+
+ assertGrandfatheredStoragePermissionModel();
+ }
+
+ @Test
+ public void grandfatheredQToPUpdate() throws Exception {
+ installGrandfatheredApp(APK_29);
+ install(APK_28v3);
+
+ assertLegacyStoragePermissionModel();
+ }
+}
diff --git a/tests/tests/permission/src/android/permission/cts/PermissionUtils.java b/tests/tests/permission/src/android/permission/cts/PermissionUtils.java
index 8aa6bd4..e8622ab 100644
--- a/tests/tests/permission/src/android/permission/cts/PermissionUtils.java
+++ b/tests/tests/permission/src/android/permission/cts/PermissionUtils.java
@@ -22,13 +22,15 @@
import static android.app.AppOpsManager.MODE_FOREGROUND;
import static android.app.AppOpsManager.MODE_IGNORED;
import static android.app.AppOpsManager.permissionToOp;
+import static android.content.pm.PackageManager.FLAG_PERMISSION_HIDDEN;
import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
-import static android.content.pm.PackageManager.PERMISSION_DENIED;
+import static android.content.pm.PackageManager.GET_PERMISSIONS;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.content.pm.PermissionInfo.PROTECTION_DANGEROUS;
import static com.android.compatibility.common.util.SystemUtil.callWithShellPermissionIdentity;
import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
@@ -37,18 +39,24 @@
import android.app.AppOpsManager;
import android.app.UiAutomation;
import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PermissionInfo;
import android.os.Process;
import android.os.UserHandle;
import androidx.annotation.NonNull;
import androidx.test.InstrumentationRegistry;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
public class PermissionUtils {
private static long TIMEOUT_MILLIS = 10000;
private static int TESTED_FLAGS = FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_USER_FIXED
| FLAG_PERMISSION_REVOKE_ON_UPGRADE | FLAG_PERMISSION_REVIEW_REQUIRED
- | FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
+ | FLAG_PERMISSION_REVOKE_WHEN_REQUESTED | FLAG_PERMISSION_HIDDEN;
private static final Context sContext = InstrumentationRegistry.getTargetContext();
private static final UiAutomation sUiAutomation =
@@ -88,19 +96,45 @@
}
/**
- * Set a new state for an app-op
+ * Set a new state for an app-op (using the permission-name)
*
* @param packageName The package the app-op belongs to
* @param permission The permission the app-op belongs to
* @param mode The new mode
*/
static void setAppOp(@NonNull String packageName, @NonNull String permission, int mode) {
- runWithShellPermissionIdentity(() -> sContext.getSystemService(AppOpsManager.class)
- .setUidMode(permissionToOp(permission),
+ setAppOpByName(packageName, permissionToOp(permission), mode);
+ }
+
+ /**
+ * Set a new state for an app-op (using the app-op-name)
+ *
+ * @param packageName The package the app-op belongs to
+ * @param op The name of the op
+ * @param mode The new mode
+ */
+ static void setAppOpByName(@NonNull String packageName, @NonNull String op, int mode) {
+ runWithShellPermissionIdentity(
+ () -> sContext.getSystemService(AppOpsManager.class).setUidMode(op,
sContext.getPackageManager().getPackageUid(packageName, 0), mode));
}
/**
+ * Checks a permission. Does <u>not</u> check the appOp.
+ *
+ * <p>Users should use {@link #isGranted} instead.
+ *
+ * @param packageName The package that might have the permission granted
+ * @param permission The permission that might be granted
+ *
+ * @return {@code true} iff the permission is granted
+ */
+ static boolean isPermissionGranted(@NonNull String packageName, @NonNull String permission) {
+ return sContext.getPackageManager().checkPermission(permission, packageName)
+ == PERMISSION_GRANTED;
+ }
+
+ /**
* Checks if a permission is granted for a package.
*
* <p>This correctly handles pre-M apps by checking the app-ops instead.
@@ -114,8 +148,7 @@
*/
static boolean isGranted(@NonNull String packageName, @NonNull String permission)
throws Exception {
- if (sContext.getPackageManager().checkPermission(permission, packageName)
- == PERMISSION_DENIED) {
+ if (!isPermissionGranted(packageName, permission)) {
return false;
}
@@ -138,23 +171,20 @@
* @param packageName The app that should have the permission granted
* @param permission The permission to grant
*/
- static void grantPermission(@NonNull String packageName, @NonNull String permission)
- throws Exception {
+ static void grantPermission(@NonNull String packageName, @NonNull String permission) {
sUiAutomation.grantRuntimePermission(packageName, permission);
if (permission.equals(ACCESS_BACKGROUND_LOCATION)) {
// The app-op for background location is encoded into the mode of the foreground
// location
- if (sContext.getPackageManager().checkPermission(ACCESS_COARSE_LOCATION, packageName)
- == PERMISSION_GRANTED) {
+ if (isPermissionGranted(packageName, ACCESS_COARSE_LOCATION)) {
setAppOp(packageName, ACCESS_COARSE_LOCATION, MODE_ALLOWED);
} else {
setAppOp(packageName, ACCESS_COARSE_LOCATION, MODE_FOREGROUND);
}
} else if (permission.equals(ACCESS_COARSE_LOCATION)) {
// The app-op for location depends on the state of the bg location
- if (sContext.getPackageManager().checkPermission(ACCESS_BACKGROUND_LOCATION,
- packageName) == PERMISSION_GRANTED) {
+ if (isPermissionGranted(packageName, ACCESS_BACKGROUND_LOCATION)) {
setAppOp(packageName, ACCESS_COARSE_LOCATION, MODE_ALLOWED);
} else {
setAppOp(packageName, ACCESS_COARSE_LOCATION, MODE_FOREGROUND);
@@ -207,6 +237,42 @@
}
/**
+ * Get all permissions an app requests. This includes the split permissions.
+ *
+ * @param packageName The package that requests the permissions.
+ *
+ * @return The permissions requested by the app
+ */
+ public static @NonNull List<String> getPermissions(@NonNull String packageName)
+ throws Exception {
+ PackageInfo appInfo = sContext.getPackageManager().getPackageInfo(packageName,
+ GET_PERMISSIONS);
+
+ return Arrays.asList(appInfo.requestedPermissions);
+ }
+
+ /**
+ * Get all runtime permissions that an app requests. This includes the split permissions.
+ *
+ * @param packageName The package that requests the permissions.
+ *
+ * @return The runtime permissions requested by the app
+ */
+ static @NonNull List<String> getRuntimePermissions(@NonNull String packageName)
+ throws Exception {
+ ArrayList<String> runtimePermissions = new ArrayList<>();
+
+ for (String perm : getPermissions(packageName)) {
+ PermissionInfo info = sContext.getPackageManager().getPermissionInfo(perm, 0);
+ if ((info.getProtection() & PROTECTION_DANGEROUS) != 0) {
+ runtimePermissions.add(perm);
+ }
+ }
+
+ return runtimePermissions;
+ }
+
+ /**
* Make sure that a {@link Runnable} eventually finishes without throwing a {@link
* Exception}.
*
diff --git a/tests/tests/permission/src/android/permission/cts/PowerManagerServicePermissionTest.java b/tests/tests/permission/src/android/permission/cts/PowerManagerServicePermissionTest.java
index 59e20e5..0926a0f 100644
--- a/tests/tests/permission/src/android/permission/cts/PowerManagerServicePermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/PowerManagerServicePermissionTest.java
@@ -35,7 +35,7 @@
public void testGetPowerSaverMode_requiresPermissions() {
try {
PowerManager manager = getContext().getSystemService(PowerManager.class);
- manager.getPowerSaveMode();
+ manager.getPowerSaveModeTrigger();
fail("Getting the current power saver mode requires the POWER_SAVER permission");
} catch (SecurityException e) {
// Expected Exception
@@ -45,7 +45,7 @@
public void testsetDynamicPowerSavings_requiresPermissions() {
try {
PowerManager manager = getContext().getSystemService(PowerManager.class);
- manager.setDynamicPowerSavings(true, 0);
+ manager.setDynamicPowerSaveHint(true, 0);
fail("Updating the dynamic power savings state requires the POWER_SAVER permission");
} catch (SecurityException e) {
// Expected Exception
diff --git a/tests/tests/permission/src/android/permission/cts/SplitPermissionTest.java b/tests/tests/permission/src/android/permission/cts/SplitPermissionTest.java
index da4d727..d878db7 100644
--- a/tests/tests/permission/src/android/permission/cts/SplitPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/SplitPermissionTest.java
@@ -23,9 +23,9 @@
import static android.app.AppOpsManager.MODE_FOREGROUND;
import static android.app.AppOpsManager.MODE_IGNORED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
-import static android.content.pm.PackageManager.GET_PERMISSIONS;
import static android.permission.cts.PermissionUtils.getAppOp;
import static android.permission.cts.PermissionUtils.getPermissionFlags;
+import static android.permission.cts.PermissionUtils.getPermissions;
import static android.permission.cts.PermissionUtils.grantPermission;
import static android.permission.cts.PermissionUtils.isGranted;
import static android.permission.cts.PermissionUtils.setAppOp;
@@ -37,8 +37,6 @@
import static org.junit.Assert.assertEquals;
import android.app.UiAutomation;
-import android.content.Context;
-import android.content.pm.PackageInfo;
import android.platform.test.annotations.AppModeFull;
import androidx.annotation.NonNull;
@@ -49,9 +47,6 @@
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.util.Arrays;
-import java.util.List;
-
/**
* Tests how split permissions behave.
*
@@ -83,10 +78,8 @@
private static final String APK_LOCATION_BACKGROUND_29 =
TMP_DIR + "CtsAppThatRequestsLocationAndBackgroundPermission29.apk";
- private static final Context sContext = InstrumentationRegistry.getTargetContext();
private static final UiAutomation sUiAutomation =
InstrumentationRegistry.getInstrumentation().getUiAutomation();
- private static final String LOG_TAG = SplitPermissionTest.class.getSimpleName();
/**
* Revoke a permission from an app.
@@ -114,20 +107,6 @@
}
/**
- * Get all permissions that an app requests. This includes the split permissions.
- *
- * @param packageName The package that requests the permissions.
- *
- * @return The permissions requested by the app
- */
- private @NonNull List<String> getPermissions(@NonNull String packageName) throws Exception {
- PackageInfo appInfo = sContext.getPackageManager().getPackageInfo(packageName,
- GET_PERMISSIONS);
-
- return Arrays.asList(appInfo.requestedPermissions);
- }
-
- /**
* Assert that {@link #APP_PKG} requests a certain permission.
*
* @param permName The permission that needs to be requested
diff --git a/tests/tests/permission2/res/raw/OWNERS b/tests/tests/permission2/res/raw/OWNERS
index d8476ed..17e828d 100644
--- a/tests/tests/permission2/res/raw/OWNERS
+++ b/tests/tests/permission2/res/raw/OWNERS
@@ -4,3 +4,5 @@
hackbod@google.com
toddke@google.com
yamasani@google.com
+michaelwr@google.com
+narayan@google.com
diff --git a/tests/tests/permission2/res/raw/android_manifest.xml b/tests/tests/permission2/res/raw/android_manifest.xml
index 3effa53..8ca676b 100644
--- a/tests/tests/permission2/res/raw/android_manifest.xml
+++ b/tests/tests/permission2/res/raw/android_manifest.xml
@@ -1872,8 +1872,8 @@
<permission android:name="android.permission.HARDWARE_TEST"
android:protectionLevel="signature" />
- <!-- @hide Allows an application to manage DynamicAndroid image -->
- <permission android:name="android.permission.MANAGE_DYNAMIC_ANDROID"
+ <!-- @hide Allows an application to manage DynamicSystem image -->
+ <permission android:name="android.permission.MANAGE_DYNAMIC_SYSTEM"
android:protectionLevel="signature" />
<!-- @SystemApi Allows access to Broadcast Radio
@@ -2012,6 +2012,12 @@
<permission android:name="android.permission.BIND_INCALL_SERVICE"
android:protectionLevel="signature|privileged" />
+ <!-- Allows the app to request network scans from telephony.
+ <p>Not for use by third-party applications.
+ @SystemApi @hide-->
+ <permission android:name="android.permission.NETWORK_SCAN"
+ android:protectionLevel="signature|privileged" />
+
<!-- Must be required by a link {@link android.telephony.VisualVoicemailService} to ensure that
only the system can bind to it.
<p>Protection level: signature|privileged
@@ -3954,6 +3960,10 @@
<permission android:name="android.permission.MANAGE_ROLLBACKS"
android:protectionLevel="signature|verifier" />
+ <!-- @SystemApi @TestApi @hide Allows testing apk level rollbacks. -->
+ <permission android:name="android.permission.TEST_MANAGE_ROLLBACKS"
+ android:protectionLevel="signature" />
+
<!-- @SystemApi @hide Allows an application to mark other applications as harmful -->
<permission android:name="android.permission.SET_HARMFUL_APP_WARNINGS"
android:protectionLevel="signature|verifier" />
@@ -4500,6 +4510,11 @@
<permission android:name="android.permission.SUBSTITUTE_SHARE_TARGET_APP_NAME_AND_ICON"
android:protectionLevel="signature|privileged" />
+ <!-- @SystemApi Allows an application to access shared libraries.
+ @hide -->
+ <permission android:name="android.permission.ACCESS_SHARED_LIBRARIES"
+ android:protectionLevel="signature|installer" />
+
<application android:process="system"
android:persistent="true"
android:hasCode="false"
diff --git a/tests/tests/permission2/src/android/permission2/cts/PrivappPermissionsTest.java b/tests/tests/permission2/src/android/permission2/cts/PrivappPermissionsTest.java
index b615277..5743b27 100755
--- a/tests/tests/permission2/src/android/permission2/cts/PrivappPermissionsTest.java
+++ b/tests/tests/permission2/src/android/permission2/cts/PrivappPermissionsTest.java
@@ -26,19 +26,27 @@
import static com.google.common.collect.Sets.intersection;
import static com.google.common.collect.Sets.newHashSet;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PermissionInfo;
-import android.test.AndroidTestCase;
+import android.platform.test.annotations.AppModeFull;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
import com.android.compatibility.common.util.PropertyUtil;
import com.android.compatibility.common.util.SystemUtil;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
@@ -59,18 +67,24 @@
* <privapp-permissions>
* </ul>
*/
-public class PrivappPermissionsTest extends AndroidTestCase {
+@AppModeFull(reason = "This test test platform properties, not capabilities of an apps")
+@RunWith(AndroidJUnit4.class)
+public class PrivappPermissionsTest {
private static final String TAG = "PrivappPermissionsTest";
private static final String PLATFORM_PACKAGE_NAME = "android";
- public void testPrivappPermissionsEnforcement() throws Exception {
+ @Test
+ public void privappPermissionsMustBeEnforced() {
assertEquals("ro.control_privapp_permissions is not set to enforce",
"enforce", PropertyUtil.getProperty("ro.control_privapp_permissions"));
+ }
+ @Test
+ public void privappPermissionsNeedToBeWhitelisted() throws Exception {
Set<String> platformPrivPermissions = new HashSet<>();
- PackageManager pm = getContext().getPackageManager();
+ PackageManager pm = InstrumentationRegistry.getContext().getPackageManager();
PackageInfo platformPackage = pm.getPackageInfo(PLATFORM_PACKAGE_NAME,
PackageManager.GET_PERMISSIONS);
@@ -95,7 +109,8 @@
}
PackageInfo factoryPkg = pm
- .getPackageInfo(packageName, MATCH_FACTORY_ONLY | GET_PERMISSIONS);
+ .getPackageInfo(packageName, MATCH_FACTORY_ONLY | GET_PERMISSIONS
+ | MATCH_UNINSTALLED_PACKAGES);
assertNotNull("No system image version found for " + packageName, factoryPkg);
diff --git a/tests/tests/provider/AndroidManifest.xml b/tests/tests/provider/AndroidManifest.xml
index c652dd6..f30f160 100644
--- a/tests/tests/provider/AndroidManifest.xml
+++ b/tests/tests/provider/AndroidManifest.xml
@@ -103,11 +103,33 @@
<activity android:name="android.provider.cts.contacts.StubDialerActivity">
<intent-filter>
- <action android:name="android.intent.action.DIAL"/>
- <data android:scheme="tel"/>
+ <action android:name="android.intent.action.DIAL" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.BROWSABLE" />
+ <data android:mimeType="vnd.android.cursor.item/phone" />
+ <data android:mimeType="vnd.android.cursor.item/person" />
</intent-filter>
<intent-filter>
- <action android:name="android.intent.action.DIAL"/>
+ <action android:name="android.intent.action.DIAL" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.BROWSABLE" />
+ <data android:scheme="voicemail" />
+ </intent-filter>
+ <intent-filter>
+ <action android:name="android.intent.action.DIAL" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ <intent-filter>
+ <action android:name="android.intent.action.VIEW" />
+ <action android:name="android.intent.action.DIAL" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.BROWSABLE" />
+ <data android:scheme="tel" />
+ </intent-filter>
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
diff --git a/tests/tests/provider/res/raw/lg_g4_iso_800_jpg.jpg b/tests/tests/provider/res/raw/lg_g4_iso_800_jpg.jpg
new file mode 100644
index 0000000..d264196
--- /dev/null
+++ b/tests/tests/provider/res/raw/lg_g4_iso_800_jpg.jpg
Binary files differ
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStoreAudioTestHelper.java b/tests/tests/provider/src/android/provider/cts/MediaStoreAudioTestHelper.java
index 1ab9559..a3ef607 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStoreAudioTestHelper.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStoreAudioTestHelper.java
@@ -97,8 +97,8 @@
public static final String TITLE = "Jam";
public static final int SIZE = 2737870;
public static final String MIME_TYPE = "audio/x-mpeg";
- public static final String DISPLAY_NAME = "Jam -Michael Jackson";
public static final String FILE_NAME = "Jam.mp3";
+ public static final String DISPLAY_NAME = FILE_NAME;
public static final long DATE_MODIFIED = System.currentTimeMillis() / 1000;
public static final String GENRE = "POP";
@@ -160,8 +160,8 @@
public static final String TITLE = "Jam";
public static final int SIZE = 2737321;
public static final String MIME_TYPE = "audio/x-mpeg";
- public static final String DISPLAY_NAME = "Jam(Live)-Michael Jackson";
public static final String FILE_NAME = "Jam_live.mp3";
+ public static final String DISPLAY_NAME = FILE_NAME;
public static final long DATE_MODIFIED = System.currentTimeMillis() / 1000;
@Override
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStorePendingTest.java b/tests/tests/provider/src/android/provider/cts/MediaStorePendingTest.java
index c8a805f..2fa2efe 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStorePendingTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStorePendingTest.java
@@ -283,7 +283,7 @@
final PendingParams params = new PendingParams(mExternalAudio,
displayName, "audio/ogg");
for (String dir : everything) {
- params.setPrimaryDirectory(dir);
+ params.setPath(dir);
if (allowedAudio.contains(dir)) {
assertCreatePending(params);
} else {
@@ -295,7 +295,7 @@
final PendingParams params = new PendingParams(mExternalVideo,
displayName, "video/ogg");
for (String dir : everything) {
- params.setPrimaryDirectory(dir);
+ params.setPath(dir);
if (allowedVideo.contains(dir)) {
assertCreatePending(params);
} else {
@@ -307,7 +307,7 @@
final PendingParams params = new PendingParams(mExternalImages,
displayName, "image/png");
for (String dir : everything) {
- params.setPrimaryDirectory(dir);
+ params.setPath(dir);
if (allowedImages.contains(dir)) {
assertCreatePending(params);
} else {
@@ -319,7 +319,7 @@
final PendingParams params = new PendingParams(mExternalDownloads,
displayName, "video/ogg");
for (String dir : everything) {
- params.setPrimaryDirectory(dir);
+ params.setPath(dir);
if (allowedDownloads.contains(dir)) {
assertCreatePending(params);
} else {
@@ -362,30 +362,13 @@
public void testDirectories_Primary() throws Exception {
final String displayName = "cts" + System.nanoTime();
final PendingParams params = new PendingParams(mExternalImages, displayName, "image/png");
- params.setPrimaryDirectory(Environment.DIRECTORY_DCIM);
+ params.setPath(Environment.DIRECTORY_DCIM);
final Uri uri = execPending(params, R.raw.scenery);
assertEquals(Environment.DIRECTORY_DCIM, getRawFile(uri).getParentFile().getName());
// Verify that shady paths don't work
- params.setPrimaryDirectory("foo/bar");
- assertNotCreatePending(params);
- }
-
- @Test
- public void testDirectories_Secondary() throws Exception {
- final String displayName = "cts" + System.nanoTime();
- final PendingParams params = new PendingParams(mExternalImages, displayName, "image/png");
- params.setSecondaryDirectory("Kittens");
-
- final Uri uri = execPending(params, R.raw.scenery);
- final File rawFile = getRawFile(uri);
- assertEquals("Kittens", rawFile.getParentFile().getName());
- assertEquals(Environment.DIRECTORY_PICTURES,
- rawFile.getParentFile().getParentFile().getName());
-
- // Verify that shady paths don't work
- params.setSecondaryDirectory("foo/bar");
+ params.setPath("foo/../bar");
assertNotCreatePending(params);
}
@@ -393,8 +376,7 @@
public void testDirectories_PrimarySecondary() throws Exception {
final String displayName = "cts" + System.nanoTime();
final PendingParams params = new PendingParams(mExternalImages, displayName, "image/png");
- params.setPrimaryDirectory(Environment.DIRECTORY_DCIM);
- params.setSecondaryDirectory("Kittens");
+ params.setPath("DCIM/Kittens");
final Uri uri = execPending(params, R.raw.scenery);
final File rawFile = getRawFile(uri);
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStorePlacementTest.java b/tests/tests/provider/src/android/provider/cts/MediaStorePlacementTest.java
index f7b16a9..93497f6 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStorePlacementTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStorePlacementTest.java
@@ -29,9 +29,6 @@
import android.provider.MediaStore;
import android.provider.MediaStore.MediaColumns;
import android.util.Log;
-import android.util.Pair;
-
-import androidx.test.InstrumentationRegistry;
import org.junit.Before;
import org.junit.Test;
@@ -41,6 +38,9 @@
import org.junit.runners.Parameterized.Parameters;
import java.io.File;
+import java.util.Optional;
+
+import androidx.test.InstrumentationRegistry;
@RunWith(Parameterized.class)
public class MediaStorePlacementTest {
@@ -92,13 +92,13 @@
}
// Make sure shady paths can't be passed in
- for (String column : new String[] {
- MediaColumns.DISPLAY_NAME,
- MediaColumns.PRIMARY_DIRECTORY,
- MediaColumns.SECONDARY_DIRECTORY
+ for (String probe : new String[] {
+ "path/.to/dir",
+ ".dir",
+ "path/../dir",
}) {
final ContentValues values = new ContentValues();
- values.put(column, "path/to/file");
+ values.put(MediaColumns.RELATIVE_PATH, probe);
try {
mContentResolver.update(uri, values, null, null);
fail();
@@ -115,7 +115,7 @@
// Movement within same MIME type is okay
final File before = ProviderTestUtils.getRelativeFile(uri);
final String name = "CTS" + System.nanoTime() + ".JPEG";
- assertTrue(updatePlacement(uri, Pair.create(MediaColumns.DISPLAY_NAME, name)));
+ assertTrue(updatePlacement(uri, null, Optional.of(name)));
final File after = ProviderTestUtils.getRelativeFile(uri);
assertEquals(before.getParent(), after.getParent());
@@ -133,7 +133,7 @@
// Movement across MIME types is not okay; verify that original MIME
// type remains intact
final String name = "cts" + System.nanoTime() + ".png";
- assertTrue(updatePlacement(uri, Pair.create(MediaColumns.DISPLAY_NAME, name)));
+ assertTrue(updatePlacement(uri, null, Optional.of(name)));
final File after = ProviderTestUtils.getRelativeFile(uri);
assertTrue(after.getName().startsWith(name));
@@ -150,32 +150,31 @@
{
assertTrue(updatePlacement(uri,
- Pair.create(MediaColumns.PRIMARY_DIRECTORY, null)));
+ Optional.ofNullable(null), null));
final File after = ProviderTestUtils.getRelativeFile(uri);
assertEquals("Pictures", after.getParent());
}
{
assertTrue(updatePlacement(uri,
- Pair.create(MediaColumns.PRIMARY_DIRECTORY, Environment.DIRECTORY_DCIM),
- Pair.create(MediaColumns.SECONDARY_DIRECTORY, "Vacation")));
+ Optional.of("DCIM/Vacation"), null));
final File after = ProviderTestUtils.getRelativeFile(uri);
assertEquals("DCIM/Vacation", after.getParent());
}
{
assertTrue(updatePlacement(uri,
- Pair.create(MediaColumns.SECONDARY_DIRECTORY, "Misc")));
+ Optional.of("DCIM/Misc"), null));
final File after = ProviderTestUtils.getRelativeFile(uri);
assertEquals("DCIM/Misc", after.getParent());
}
{
assertTrue(updatePlacement(uri,
- Pair.create(MediaColumns.PRIMARY_DIRECTORY, Environment.DIRECTORY_PICTURES)));
+ Optional.of("Pictures/Misc"), null));
final File after = ProviderTestUtils.getRelativeFile(uri);
assertEquals("Pictures/Misc", after.getParent());
}
{
assertTrue(updatePlacement(uri,
- Pair.create(MediaColumns.SECONDARY_DIRECTORY, null)));
+ Optional.of("Pictures"), null));
final File after = ProviderTestUtils.getRelativeFile(uri);
assertEquals("Pictures", after.getParent());
}
@@ -187,19 +186,19 @@
mExternalImages, "image/jpeg");
assertFalse(updatePlacement(uri,
- Pair.create(MediaColumns.PRIMARY_DIRECTORY, "Random")));
+ Optional.of("Random"), null));
assertFalse(updatePlacement(uri,
- Pair.create(MediaColumns.PRIMARY_DIRECTORY, Environment.DIRECTORY_ALARMS)));
+ Optional.of(Environment.DIRECTORY_ALARMS), null));
}
- private boolean updatePlacement(Uri uri, Pair<?, ?>... args) throws Exception {
+ private boolean updatePlacement(Uri uri, Optional<String> path, Optional<String> displayName)
+ throws Exception {
final ContentValues values = new ContentValues();
- for (Pair<?, ?> arg : args) {
- if (arg.second != null) {
- values.put(String.valueOf(arg.first), String.valueOf(arg.second));
- } else {
- values.putNull(String.valueOf(arg.first));
- }
+ if (path != null) {
+ values.put(MediaColumns.RELATIVE_PATH, path.orElse(null));
+ }
+ if (displayName != null) {
+ values.put(MediaColumns.DISPLAY_NAME, displayName.orElse(null));
}
try {
return (mContentResolver.update(uri, values, null, null) == 1);
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStoreUtils.java b/tests/tests/provider/src/android/provider/cts/MediaStoreUtils.java
index cb73a63..70c6988 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStoreUtils.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStoreUtils.java
@@ -19,7 +19,6 @@
import android.content.ContentValues;
import android.content.Context;
import android.net.Uri;
-import android.os.Environment;
import android.os.ParcelFileDescriptor;
import android.provider.MediaStore;
import android.provider.MediaStore.DownloadColumns;
@@ -108,45 +107,11 @@
(System.currentTimeMillis() + DateUtils.DAY_IN_MILLIS) / 1000);
}
- /**
- * Optionally set the primary directory under which this pending item
- * should be persisted. Only specific well-defined directories from
- * {@link Environment} are allowed based on the media type being
- * inserted.
- * <p>
- * For example, when creating pending {@link MediaStore.Images.Media}
- * items, only {@link Environment#DIRECTORY_PICTURES} or
- * {@link Environment#DIRECTORY_DCIM} are allowed.
- * <p>
- * You may leave this value undefined to store the media in a default
- * location. For example, when this value is left undefined, pending
- * {@link MediaStore.Audio.Media} items are stored under
- * {@link Environment#DIRECTORY_MUSIC}.
- *
- * @see MediaColumns#PRIMARY_DIRECTORY
- */
- public void setPrimaryDirectory(@Nullable String primaryDirectory) {
- if (primaryDirectory == null) {
- this.insertValues.remove(MediaColumns.PRIMARY_DIRECTORY);
+ public void setPath(@Nullable String path) {
+ if (path == null) {
+ this.insertValues.remove(MediaColumns.RELATIVE_PATH);
} else {
- this.insertValues.put(MediaColumns.PRIMARY_DIRECTORY, primaryDirectory);
- }
- }
-
- /**
- * Optionally set the secondary directory under which this pending item
- * should be persisted. Any valid directory name is allowed.
- * <p>
- * You may leave this value undefined to store the media as a direct
- * descendant of the {@link #setPrimaryDirectory(String)} location.
- *
- * @see MediaColumns#SECONDARY_DIRECTORY
- */
- public void setSecondaryDirectory(@Nullable String secondaryDirectory) {
- if (secondaryDirectory == null) {
- this.insertValues.remove(MediaColumns.SECONDARY_DIRECTORY);
- } else {
- this.insertValues.put(MediaColumns.SECONDARY_DIRECTORY, secondaryDirectory);
+ this.insertValues.put(MediaColumns.RELATIVE_PATH, path);
}
}
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_MediaTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_MediaTest.java
index 00121de..e4430ed 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_MediaTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_MediaTest.java
@@ -20,6 +20,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import android.content.ContentResolver;
@@ -28,12 +29,11 @@
import android.database.Cursor;
import android.net.Uri;
import android.os.Environment;
+import android.provider.MediaStore;
import android.provider.MediaStore.Audio.Media;
import android.provider.cts.MediaStoreAudioTestHelper.Audio1;
import android.util.Log;
-import androidx.test.InstrumentationRegistry;
-
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -41,11 +41,17 @@
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
+import java.io.File;
+
+import androidx.test.InstrumentationRegistry;
+
@RunWith(Parameterized.class)
public class MediaStore_Audio_MediaTest {
private Context mContext;
private ContentResolver mContentResolver;
+ private Uri mExternalAudio;
+
@Parameter(0)
public String mVolumeName;
@@ -60,6 +66,7 @@
mContentResolver = mContext.getContentResolver();
Log.d(TAG, "Using volume " + mVolumeName);
+ mExternalAudio = MediaStore.Audio.Media.getContentUri(mVolumeName);
}
@Test
@@ -155,4 +162,39 @@
assertEquals(1, result);
}
}
+
+ @Test
+ public void testCanonicalize() throws Exception {
+ // Remove all audio left over from other tests
+ ProviderTestUtils.executeShellCommand(
+ "content delete --uri " + mExternalAudio,
+ InstrumentationRegistry.getInstrumentation().getUiAutomation());
+
+ // Publish some content
+ final File dir = ProviderTestUtils.stageDir(mVolumeName);
+ final Uri a = ProviderTestUtils.scanFile(
+ ProviderTestUtils.stageFile(R.raw.testmp3_2, new File(dir, "a.mp3")), true);
+ final Uri b = ProviderTestUtils.scanFile(
+ ProviderTestUtils.stageFile(R.raw.testmp3, new File(dir, "b.mp3")), true);
+ final Uri c = ProviderTestUtils.scanFile(
+ ProviderTestUtils.stageFile(R.raw.testmp3_2, new File(dir, "c.mp3")), true);
+
+ // Confirm we can canonicalize and recover it
+ final Uri canonicalized = mContentResolver.canonicalize(b);
+ assertNotNull(canonicalized);
+ assertEquals(b, mContentResolver.uncanonicalize(canonicalized));
+
+ // Delete all items above
+ mContentResolver.delete(a, null, null);
+ mContentResolver.delete(b, null, null);
+ mContentResolver.delete(c, null, null);
+
+ // Confirm canonical item isn't found
+ assertNull(mContentResolver.uncanonicalize(canonicalized));
+
+ // Publish data again and confirm we can recover it
+ final Uri d = ProviderTestUtils.scanFile(
+ ProviderTestUtils.stageFile(R.raw.testmp3, new File(dir, "d.mp3")), true);
+ assertEquals(d, mContentResolver.uncanonicalize(canonicalized));
+ }
}
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_DownloadsTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_DownloadsTest.java
index 57b3a64..504a8ae 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_DownloadsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_DownloadsTest.java
@@ -185,7 +185,7 @@
cursor.moveToNext();
assertEquals(mimeType,
cursor.getString(cursor.getColumnIndex(Downloads.MIME_TYPE)));
- assertEquals(displayName,
+ assertEquals(displayName + ".html",
cursor.getString(cursor.getColumnIndex(Downloads.DISPLAY_NAME)));
assertEquals(downloadUri.toString(),
cursor.getString(cursor.getColumnIndex(Downloads.DOWNLOAD_URI)));
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java
index 75bcdb9..af76080 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java
@@ -20,6 +20,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -265,7 +266,7 @@
assertEquals(1, c.getInt(c.getColumnIndex(Media.IS_PRIVATE)));
assertEquals(0, c.getLong(c.getColumnIndex(Media.MINI_THUMB_MAGIC)));
assertEquals(externalPath, c.getString(c.getColumnIndex(Media.DATA)));
- assertEquals("testimage", c.getString(c.getColumnIndex(Media.DISPLAY_NAME)));
+ assertEquals("testimage.jpg", c.getString(c.getColumnIndex(Media.DISPLAY_NAME)));
assertEquals("image/jpeg", c.getString(c.getColumnIndex(Media.MIME_TYPE)));
assertEquals("testimage", c.getString(c.getColumnIndex(Media.TITLE)));
assertEquals(numBytes, c.getInt(c.getColumnIndex(Media.SIZE)));
@@ -399,4 +400,39 @@
assertTrue(c.isNull(1));
}
}
+
+ @Test
+ public void testCanonicalize() throws Exception {
+ // Remove all audio left over from other tests
+ ProviderTestUtils.executeShellCommand(
+ "content delete --uri " + mExternalImages,
+ InstrumentationRegistry.getInstrumentation().getUiAutomation());
+
+ // Publish some content
+ final File dir = ProviderTestUtils.stageDir(mVolumeName);
+ final Uri a = ProviderTestUtils.scanFile(
+ ProviderTestUtils.stageFile(R.raw.scenery, new File(dir, "a.jpg")), true);
+ final Uri b = ProviderTestUtils.scanFile(
+ ProviderTestUtils.stageFile(R.raw.lg_g4_iso_800_jpg, new File(dir, "b.jpg")), true);
+ final Uri c = ProviderTestUtils.scanFile(
+ ProviderTestUtils.stageFile(R.raw.scenery, new File(dir, "c.jpg")), true);
+
+ // Confirm we can canonicalize and recover it
+ final Uri canonicalized = mContentResolver.canonicalize(b);
+ assertNotNull(canonicalized);
+ assertEquals(b, mContentResolver.uncanonicalize(canonicalized));
+
+ // Delete all items above
+ mContentResolver.delete(a, null, null);
+ mContentResolver.delete(b, null, null);
+ mContentResolver.delete(c, null, null);
+
+ // Confirm canonical item isn't found
+ assertNull(mContentResolver.uncanonicalize(canonicalized));
+
+ // Publish data again and confirm we can recover it
+ final Uri d = ProviderTestUtils.scanFile(
+ ProviderTestUtils.stageFile(R.raw.lg_g4_iso_800_jpg, new File(dir, "d.jpg")), true);
+ assertEquals(d, mContentResolver.uncanonicalize(canonicalized));
+ }
}
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Video_MediaTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Video_MediaTest.java
index b5f6677..77b061e 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Video_MediaTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Video_MediaTest.java
@@ -118,7 +118,7 @@
values.put(Media.RESOLUTION, "176x144");
values.put(Media.TAGS, "cts, test");
values.put(Media.DATA, externalVideoPath);
- values.put(Media.DISPLAY_NAME, "testvideo");
+ values.put(Media.DISPLAY_NAME, "testvideo.3gp");
values.put(Media.MIME_TYPE, "video/3gpp");
values.put(Media.SIZE, numBytes);
values.put(Media.TITLE, "testvideo");
@@ -151,7 +151,7 @@
assertEquals("176x144", c.getString(c.getColumnIndex(Media.RESOLUTION)));
assertEquals("cts, test", c.getString(c.getColumnIndex(Media.TAGS)));
assertEquals(externalVideoPath, c.getString(c.getColumnIndex(Media.DATA)));
- assertEquals("testvideo", c.getString(c.getColumnIndex(Media.DISPLAY_NAME)));
+ assertEquals("testvideo.3gp", c.getString(c.getColumnIndex(Media.DISPLAY_NAME)));
assertEquals("video/3gpp", c.getString(c.getColumnIndex(Media.MIME_TYPE)));
assertEquals("testvideo", c.getString(c.getColumnIndex(Media.TITLE)));
assertEquals(numBytes, c.getInt(c.getColumnIndex(Media.SIZE)));
diff --git a/tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java b/tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java
index aa1d59a..71aa629 100644
--- a/tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java
+++ b/tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java
@@ -180,7 +180,7 @@
"android.provider.cts");
}
- static void stageFile(int resId, File file) throws IOException {
+ static File stageFile(int resId, File file) throws IOException {
// The caller may be trying to stage into a location only available to
// the shell user, so we need to perform the entire copy as the shell
if (FileUtils.contains(Environment.getStorageDirectory(), file)) {
@@ -210,6 +210,7 @@
FileUtils.copy(source, target);
}
}
+ return file;
}
static Uri stageMedia(int resId, Uri collectionUri) throws IOException {
diff --git a/tests/tests/rcs/AndroidManifest.xml b/tests/tests/rcs/AndroidManifest.xml
index 3b46edc..15a4038 100755
--- a/tests/tests/rcs/AndroidManifest.xml
+++ b/tests/tests/rcs/AndroidManifest.xml
@@ -28,7 +28,7 @@
<uses-library android:name="android.test.runner" />
<!-- Required to be default SMS app -->
- <receiver android:name="android.telephony.ims.SmsApplicationReceiver"
+ <receiver android:name="android.telephony.ims.SmsApplicationSmsDeliverReceiver"
android:permission="android.permission.BROADCAST_SMS">
<intent-filter>
@@ -38,7 +38,7 @@
</receiver>
<!-- Required to be default SMS app -->
- <receiver android:name="android.telephony.ims.SmsApplicationReceiver"
+ <receiver android:name="android.telephony.ims.SmsApplicationWapPushDeliverReceiver"
android:permission="android.permission.BROADCAST_WAP_PUSH">
<intent-filter>
diff --git a/tests/tests/rcs/src/android/telephony/ims/SmsApplicationReceiver.java b/tests/tests/rcs/src/android/telephony/ims/SmsApplicationSmsDeliverReceiver.java
similarity index 92%
rename from tests/tests/rcs/src/android/telephony/ims/SmsApplicationReceiver.java
rename to tests/tests/rcs/src/android/telephony/ims/SmsApplicationSmsDeliverReceiver.java
index 85692bc..8bcc9bc 100644
--- a/tests/tests/rcs/src/android/telephony/ims/SmsApplicationReceiver.java
+++ b/tests/tests/rcs/src/android/telephony/ims/SmsApplicationSmsDeliverReceiver.java
@@ -24,7 +24,7 @@
* This receiver is used to provide the interface required for a default SMS application. It
* intentionally has no custom behavior.
*/
-public class SmsApplicationReceiver extends BroadcastReceiver {
+public class SmsApplicationSmsDeliverReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// Do nothing
diff --git a/tests/tests/rcs/src/android/telephony/ims/SmsApplicationReceiver.java b/tests/tests/rcs/src/android/telephony/ims/SmsApplicationWapPushDeliverReceiver.java
similarity index 92%
copy from tests/tests/rcs/src/android/telephony/ims/SmsApplicationReceiver.java
copy to tests/tests/rcs/src/android/telephony/ims/SmsApplicationWapPushDeliverReceiver.java
index 85692bc..5f6ea5b 100644
--- a/tests/tests/rcs/src/android/telephony/ims/SmsApplicationReceiver.java
+++ b/tests/tests/rcs/src/android/telephony/ims/SmsApplicationWapPushDeliverReceiver.java
@@ -24,7 +24,7 @@
* This receiver is used to provide the interface required for a default SMS application. It
* intentionally has no custom behavior.
*/
-public class SmsApplicationReceiver extends BroadcastReceiver {
+public class SmsApplicationWapPushDeliverReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// Do nothing
diff --git a/tests/tests/rcs/src/android/telephony/ims/cts/DefaultSmsAppHelper.java b/tests/tests/rcs/src/android/telephony/ims/cts/DefaultSmsAppHelper.java
index abecadc..a26cd05 100644
--- a/tests/tests/rcs/src/android/telephony/ims/cts/DefaultSmsAppHelper.java
+++ b/tests/tests/rcs/src/android/telephony/ims/cts/DefaultSmsAppHelper.java
@@ -21,26 +21,10 @@
import androidx.test.InstrumentationRegistry;
class DefaultSmsAppHelper {
- static void setDefaultSmsApp(boolean setToSmsApp) {
+ static void ensureDefaultSmsApp() {
String packageName =
InstrumentationRegistry.getInstrumentation().getContext().getPackageName();
-
- setDefaultSmsAppSetting(setToSmsApp, packageName);
-
- // FIXME: Required because setting default SMS app to a given package adds appops WRITE_SMS
- // permissions to the given package, but changing away from a given package seem to remove
- // the appops permission from the given package. This is a known issue and should be fixed
- // for Q.
- setSmsWritePermission(setToSmsApp, packageName);
- }
-
- private static void setDefaultSmsAppSetting(boolean setToSmsApp, String packageName) {
- runShellCommand(String.format("settings put secure sms_default_application %s",
- setToSmsApp ? packageName : "default"));
- }
-
- private static void setSmsWritePermission(boolean setToSmsApp, String packageName) {
- runShellCommand(String.format("appops set %s WRITE_SMS %s", packageName,
- setToSmsApp ? "allow" : "default"));
+ runShellCommand(
+ String.format("settings put secure sms_default_application %s", packageName));
}
}
diff --git a/tests/tests/rcs/src/android/telephony/ims/cts/Rcs1To1ThreadTest.java b/tests/tests/rcs/src/android/telephony/ims/cts/Rcs1To1ThreadTest.java
index 038c925..18dee5f 100644
--- a/tests/tests/rcs/src/android/telephony/ims/cts/Rcs1To1ThreadTest.java
+++ b/tests/tests/rcs/src/android/telephony/ims/cts/Rcs1To1ThreadTest.java
@@ -16,7 +16,6 @@
package android.telephony.ims.cts;
import static android.provider.Telephony.RcsColumns.IS_RCS_TABLE_SCHEMA_CODE_COMPLETE;
-import static android.telephony.ims.cts.DefaultSmsAppHelper.setDefaultSmsApp;
import static com.google.common.truth.Truth.assertThat;
@@ -32,12 +31,18 @@
import org.junit.AfterClass;
import org.junit.Assume;
import org.junit.Before;
+import org.junit.BeforeClass;
import org.junit.Test;
public class Rcs1To1ThreadTest {
private RcsMessageStore mRcsMessageStore;
private Context mContext;
+ @BeforeClass
+ public static void ensureDefaultSmsApp() {
+ DefaultSmsAppHelper.ensureDefaultSmsApp();
+ }
+
@Before
public void setupTestEnvironment() {
// Used to skip tests for production builds without RCS tables, will be removed when
@@ -53,9 +58,7 @@
@AfterClass
public static void cleanup() {
- setDefaultSmsApp(true);
// TODO(b/123997749) should clean RCS message store here
- setDefaultSmsApp(false);
}
@Test
diff --git a/tests/tests/rcs/src/android/telephony/ims/cts/RcsEventTest.java b/tests/tests/rcs/src/android/telephony/ims/cts/RcsEventTest.java
index 375ea4f..97a40936 100644
--- a/tests/tests/rcs/src/android/telephony/ims/cts/RcsEventTest.java
+++ b/tests/tests/rcs/src/android/telephony/ims/cts/RcsEventTest.java
@@ -17,7 +17,6 @@
package android.telephony.ims.cts;
import static android.provider.Telephony.RcsColumns.IS_RCS_TABLE_SCHEMA_CODE_COMPLETE;
-import static android.telephony.ims.cts.DefaultSmsAppHelper.setDefaultSmsApp;
import static com.google.common.truth.Truth.assertWithMessage;
@@ -45,6 +44,7 @@
import org.junit.AfterClass;
import org.junit.Assume;
import org.junit.Before;
+import org.junit.BeforeClass;
import org.junit.Test;
import java.util.function.Predicate;
@@ -57,6 +57,12 @@
private RcsParticipant mParticipant2;
private RcsGroupThread mGroupThread;
+ @BeforeClass
+ public static void ensureDefaultSmsApp() {
+ DefaultSmsAppHelper.ensureDefaultSmsApp();
+ }
+
+
@Before
public void setupTestEnvironment() throws RcsMessageStoreException {
// Used to skip tests for production builds without RCS tables, will be removed when
@@ -79,16 +85,12 @@
@AfterClass
public static void cleanup() {
- setDefaultSmsApp(true);
// TODO(b/123997749) should clean RCS message store here
- setDefaultSmsApp(false);
}
@Test
public void testCreateRcsEvent_canSaveAndQueryGroupThreadParticipantJoinedEvent()
throws RcsMessageStoreException {
- setDefaultSmsApp(true);
-
RcsGroupThreadParticipantJoinedEvent rcsGroupThreadParticipantJoinedEvent =
new RcsGroupThreadParticipantJoinedEvent(
mTimestamp, mGroupThread, mParticipant1, mParticipant2);
@@ -103,8 +105,6 @@
@Test
public void testCreateRcsEvent_canSaveAndQueryGroupThreadNameChangedEvent()
throws RcsMessageStoreException {
- setDefaultSmsApp(true);
-
RcsGroupThreadNameChangedEvent rcsGroupThreadNameChangedEvent =
new RcsGroupThreadNameChangedEvent(
mTimestamp, mGroupThread, mParticipant1, "newName");
@@ -119,8 +119,6 @@
@Test
public void testCreateRcsEvent_canSaveAndQueryParticipantAliasChangedEvent()
throws RcsMessageStoreException {
- setDefaultSmsApp(true);
-
RcsParticipantAliasChangedEvent rcsParticipantAliasChangedEvent
= new RcsParticipantAliasChangedEvent(mTimestamp, mParticipant1, "newAlias");
@@ -134,8 +132,6 @@
@Test
public void testCreateRcsEvent_canSaveAndQueryGroupThreadParticipantLeftEvent()
throws RcsMessageStoreException {
- setDefaultSmsApp(true);
-
RcsGroupThreadParticipantLeftEvent rcsGroupThreadParticipantLeftEvent =
new RcsGroupThreadParticipantLeftEvent(
mTimestamp, mGroupThread, mParticipant1, mParticipant2);
@@ -150,8 +146,6 @@
@Test
public void testCreateRcsEvent_canSaveAndQueryGroupThreadIconChangedEvent()
throws RcsMessageStoreException {
- setDefaultSmsApp(true);
-
Uri newIcon = Uri.parse("cool/new/icon");
RcsGroupThreadIconChangedEvent rcsGroupThreadIconChangedEvent =
diff --git a/tests/tests/rcs/src/android/telephony/ims/cts/RcsParticipantTest.java b/tests/tests/rcs/src/android/telephony/ims/cts/RcsParticipantTest.java
index 6dab877..0a3fd5c 100644
--- a/tests/tests/rcs/src/android/telephony/ims/cts/RcsParticipantTest.java
+++ b/tests/tests/rcs/src/android/telephony/ims/cts/RcsParticipantTest.java
@@ -17,7 +17,6 @@
package android.telephony.ims.cts;
import static android.provider.Telephony.RcsColumns.IS_RCS_TABLE_SCHEMA_CODE_COMPLETE;
-import static android.telephony.ims.cts.DefaultSmsAppHelper.setDefaultSmsApp;
import static com.google.common.truth.Truth.assertThat;
@@ -32,12 +31,18 @@
import org.junit.AfterClass;
import org.junit.Assume;
import org.junit.Before;
+import org.junit.BeforeClass;
import org.junit.Test;
public class RcsParticipantTest {
RcsMessageStore mRcsMessageStore;
Context mContext;
+ @BeforeClass
+ public static void ensureDefaultSmsApp() {
+ DefaultSmsAppHelper.ensureDefaultSmsApp();
+ }
+
@Before
public void setupTestEnvironment() {
// Used to skip tests for production builds without RCS tables, will be removed when
@@ -53,15 +58,11 @@
@AfterClass
public static void cleanup() {
- setDefaultSmsApp(true);
// TODO(b/123997749) should clean RCS message store here
- setDefaultSmsApp(false);
}
@Test
public void testCreateRcsParticipant_returnsValidParticipant() throws RcsMessageStoreException {
- setDefaultSmsApp(true);
-
String expectedCanonicalAddress = "+12223334444";
String expectedAlias = "test_alias";
@@ -71,8 +72,6 @@
@Test
public void testCreateRcsParticipant_shouldNotCrashForExistingCanonicalAddress()
throws RcsMessageStoreException {
- setDefaultSmsApp(true);
-
String expectedCanonicalAddress = "+12223334444";
String expectedAlias1 = "test_alias_1";
String expectedAlias2 = "test_alias_2";
diff --git a/tests/tests/renderscript/AndroidTest.xml b/tests/tests/renderscript/AndroidTest.xml
index 2c13a5f..22a20cf 100644
--- a/tests/tests/renderscript/AndroidTest.xml
+++ b/tests/tests/renderscript/AndroidTest.xml
@@ -16,7 +16,7 @@
<configuration description="Configuration for Renderscript Tests">
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="renderscript" />
- <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+ <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
<option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
diff --git a/tests/tests/role/OWNERS b/tests/tests/role/OWNERS
new file mode 100644
index 0000000..904ef0b
--- /dev/null
+++ b/tests/tests/role/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 137825
+zhanghai@google.com
+svetoslavganov@google.com
+moltmann@google.com
+eugenesusla@google.com
diff --git a/tests/tests/role/src/android/app/role/cts/RoleManagerTest.java b/tests/tests/role/src/android/app/role/cts/RoleManagerTest.java
index 3430397..4fb39cb 100644
--- a/tests/tests/role/src/android/app/role/cts/RoleManagerTest.java
+++ b/tests/tests/role/src/android/app/role/cts/RoleManagerTest.java
@@ -171,6 +171,15 @@
private void respondToRoleRequest(boolean ok, boolean expectResultOk)
throws InterruptedException, IOException {
wakeUpScreen();
+ if (ok) {
+ UiObject2 item = sUiDevice.wait(Until.findObject(By.text(APP_PACKAGE_NAME)),
+ TIMEOUT_MILLIS);
+ if (item == null) {
+ dumpWindowHierarchy();
+ fail("Cannot find item to click");
+ }
+ item.click();
+ }
String buttonId = ok ? "android:id/button1" : "android:id/button2";
UiObject2 button = sUiDevice.wait(Until.findObject(By.res(buttonId)), TIMEOUT_MILLIS);
if (button == null) {
diff --git a/tests/tests/security/jni/Android.bp b/tests/tests/security/jni/Android.bp
new file mode 100644
index 0000000..7c960c4
--- /dev/null
+++ b/tests/tests/security/jni/Android.bp
@@ -0,0 +1,46 @@
+// 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.
+
+cc_library {
+ name: "libctssecurity_jni",
+ srcs: [
+ "CtsSecurityJniOnLoad.cpp",
+ "android_security_cts_CharDeviceTest.cpp",
+ "android_security_cts_KernelSettingsTest.cpp",
+ "android_security_cts_LinuxRngTest.cpp",
+ "android_security_cts_NativeCodeTest.cpp",
+ "android_security_cts_SELinuxTest.cpp",
+ "android_security_cts_MMapExecutableTest.cpp",
+ "android_security_cts_EncryptionTest.cpp",
+ ],
+ shared_libs: [
+ "liblog",
+ "libcrypto",
+ "libselinux",
+ "libc++",
+ "libpcre2",
+ "libpackagelistparser",
+ "libnativehelper_compat_libc++",
+ ],
+ static_libs: [
+ "cpufeatures",
+ "libcutils",
+ ],
+ cflags: [
+ "-Wno-unused-parameter",
+ "-Wno-sign-compare",
+ "-Wno-unused-label",
+ "-Wno-unused-variable",
+ ],
+}
diff --git a/tests/tests/security/jni/Android.mk b/tests/tests/security/jni/Android.mk
deleted file mode 100644
index 363ed47..0000000
--- a/tests/tests/security/jni/Android.mk
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright (C) 2012 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 := libctssecurity_jni
-
-# Don't include this package in any configuration by default.
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := \
- CtsSecurityJniOnLoad.cpp \
- android_security_cts_CharDeviceTest.cpp \
- android_security_cts_KernelSettingsTest.cpp \
- android_security_cts_LinuxRngTest.cpp \
- android_security_cts_NativeCodeTest.cpp \
- android_security_cts_SELinuxTest.cpp \
- android_security_cts_MMapExecutableTest.cpp \
- android_security_cts_EncryptionTest.cpp \
-
-LOCAL_SHARED_LIBRARIES := \
- libnativehelper \
- liblog \
- libcutils \
- libcrypto \
- libselinux \
- libc++ \
- libpcre2 \
- libpackagelistparser
-
-LOCAL_C_INCLUDES += ndk/sources/cpufeatures
-LOCAL_STATIC_LIBRARIES := cpufeatures
-
-LOCAL_CFLAGS := -Wall -Werror -Wno-unused-parameter
-LOCAL_CFLAGS += -Wno-sign-compare -Wno-unused-label -Wno-unused-variable
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/tests/systemintents/AndroidTest.xml b/tests/tests/systemintents/AndroidTest.xml
index 4f0cc36..a270dcd 100644
--- a/tests/tests/systemintents/AndroidTest.xml
+++ b/tests/tests/systemintents/AndroidTest.xml
@@ -17,6 +17,8 @@
<configuration description="Config for CTS system intent test cases">
<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="not-shardable" value="true" />
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
diff --git a/tests/tests/telecom/CallScreeningServiceTestApp/aidl/android/telecom/cts/screeningtestapp/ICallScreeningControl.aidl b/tests/tests/telecom/CallScreeningServiceTestApp/aidl/android/telecom/cts/screeningtestapp/ICallScreeningControl.aidl
index 63c4b23..8f59902 100644
--- a/tests/tests/telecom/CallScreeningServiceTestApp/aidl/android/telecom/cts/screeningtestapp/ICallScreeningControl.aidl
+++ b/tests/tests/telecom/CallScreeningServiceTestApp/aidl/android/telecom/cts/screeningtestapp/ICallScreeningControl.aidl
@@ -24,7 +24,7 @@
void setProviderCallIdentification(CharSequence name, CharSequence description,
CharSequence details, in Icon icon, int confidence);
- void setCallResponse(boolean shouldDisallowCall, boolean shouldRejectCall,
+ void setCallResponse(boolean shouldDisallowCall, boolean shouldRejectCall, boolean shouldSkipCall,
boolean shouldSkipCallLog, boolean shouldSkipNotification);
void waitForNuisanceReport(long timeoutMillis);
boolean getIsNuisance();
diff --git a/tests/tests/telecom/CallScreeningServiceTestApp/src/android/telecom/cts/screeningtestapp/CallScreeningServiceControl.java b/tests/tests/telecom/CallScreeningServiceTestApp/src/android/telecom/cts/screeningtestapp/CallScreeningServiceControl.java
index 6d9174e..99bb90c 100644
--- a/tests/tests/telecom/CallScreeningServiceTestApp/src/android/telecom/cts/screeningtestapp/CallScreeningServiceControl.java
+++ b/tests/tests/telecom/CallScreeningServiceTestApp/src/android/telecom/cts/screeningtestapp/CallScreeningServiceControl.java
@@ -76,6 +76,7 @@
@Override
public void setCallResponse(boolean shouldDisallowCall,
boolean shouldRejectCall,
+ boolean shouldSilenceCall,
boolean shouldSkipCallLog,
boolean shouldSkipNotification) {
Log.i(TAG, "setCallResponse");
@@ -84,6 +85,7 @@
.setSkipCallLog(shouldSkipCallLog)
.setDisallowCall(shouldDisallowCall)
.setRejectCall(shouldRejectCall)
+ .setSilenceCall(shouldSilenceCall)
.build();
}
@@ -127,6 +129,7 @@
new CallScreeningService.CallResponse.Builder()
.setDisallowCall(false)
.setRejectCall(false)
+ .setSilenceCall(false)
.setSkipCallLog(false)
.setSkipNotification(false)
.build();
diff --git a/tests/tests/telecom/src/android/telecom/cts/CallScreeningServiceTest.java b/tests/tests/telecom/src/android/telecom/cts/CallScreeningServiceTest.java
index 85f9b65..d959196 100644
--- a/tests/tests/telecom/src/android/telecom/cts/CallScreeningServiceTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/CallScreeningServiceTest.java
@@ -124,6 +124,7 @@
new CallScreeningService.CallResponse.Builder()
.setDisallowCall(true)
.setRejectCall(true)
+ .setSilenceCall(false)
.setSkipCallLog(true)
.setSkipNotification(true)
.build();
diff --git a/tests/tests/telecom/src/android/telecom/cts/ThirdPartyCallScreeningServiceTest.java b/tests/tests/telecom/src/android/telecom/cts/ThirdPartyCallScreeningServiceTest.java
index d797318..4875901 100644
--- a/tests/tests/telecom/src/android/telecom/cts/ThirdPartyCallScreeningServiceTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/ThirdPartyCallScreeningServiceTest.java
@@ -202,7 +202,7 @@
// Tell the test app to block the call.
mCallScreeningControl.setCallResponse(true /* shouldDisallowCall */,
- true /* shouldRejectCall */, false /* shouldSkipCallLog */,
+ true /* shouldRejectCall */, false /* shouldSilenceCall */, false /* shouldSkipCallLog */,
true /* shouldSkipNotification */);
addIncomingAndVerifyBlocked();
@@ -222,12 +222,46 @@
// Tell the test app to block the call; also try to skip logging the call.
mCallScreeningControl.setCallResponse(true /* shouldDisallowCall */,
- true /* shouldRejectCall */, true /* shouldSkipCallLog */,
+ true /* shouldRejectCall */, false /* shouldSilenceCall */, true /* shouldSkipCallLog */,
true /* shouldSkipNotification */);
addIncomingAndVerifyBlocked();
}
+ /**
+ * Verifies that a {@link android.telecom.CallScreeningService} set the extra to silence a call.
+ * @throws Exception
+ */
+ public void testIncomingCallHasSilenceExtra() throws Exception {
+ if (!shouldTestTelecom(mContext)) {
+ return;
+ }
+
+ // Tell the test app to silence the call.
+ mCallScreeningControl.setCallResponse(false /* shouldDisallowCall */,
+ false /* shouldRejectCall */, true /* shouldSilenceCall */,
+ false /* shouldSkipCallLog */, false /* shouldSkipNotification */);
+
+ addIncomingAndVerifyCallExtraForSilence(true);
+ }
+
+ /**
+ * Verifies that a {@link android.telecom.CallScreeningService} did not set the extra to silence an incoming call.
+ * @throws Exception
+ */
+ public void testIncomingCallDoesNotHaveHaveSilenceExtra() throws Exception {
+ if (!shouldTestTelecom(mContext)) {
+ return;
+ }
+
+ // Tell the test app to not silence the call.
+ mCallScreeningControl.setCallResponse(false /* shouldDisallowCall */,
+ false /* shouldRejectCall */, false /* shouldSilenceCall */,
+ false /* shouldSkipCallLog */, false /* shouldSkipNotification */);
+
+ addIncomingAndVerifyCallExtraForSilence(false);
+ }
+
public void testProvideCallIdentificationForOutgoing() throws Exception {
if (!shouldTestTelecom(mContext)) {
return;
@@ -416,6 +450,30 @@
}
}
+ private void addIncomingAndVerifyCallExtraForSilence(boolean expectedIsSilentRingingExtraSet) throws Exception {
+ Uri testNumber = addIncoming(false);
+
+ waitUntilConditionIsTrueOrTimeout(
+ new Condition() {
+ @Override
+ public Object expected() {
+ return true;
+ }
+
+ @Override
+ public Object actual() {
+ // Verify that the call extra matches expectation
+ Call call = mInCallCallbacks.getService().getLastCall();
+ return expectedIsSilentRingingExtraSet ==
+ call.getDetails().getExtras().getBoolean(Call.EXTRA_SILENT_RINGING_REQUESTED);
+ }
+ },
+ TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+ "Call extra - verification failed, expected the extra " +
+ "EXTRA_SILENT_RINGING_REQUESTED to be set:" + expectedIsSilentRingingExtraSet
+ );
+ }
+
private CountDownLatch getCallLogEntryLatch() {
CountDownLatch changeLatch = new CountDownLatch(1);
mContext.getContentResolver().registerContentObserver(
diff --git a/tests/tests/telecom2/AndroidTest.xml b/tests/tests/telecom2/AndroidTest.xml
index d38f24b..ad80dcf 100644
--- a/tests/tests/telecom2/AndroidTest.xml
+++ b/tests/tests/telecom2/AndroidTest.xml
@@ -16,6 +16,8 @@
<configuration description="Configuration for Telecom2 Tests">
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="telecom" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
<option name="not-shardable" value="true" />
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
diff --git a/tests/tests/telecom3/AndroidTest.xml b/tests/tests/telecom3/AndroidTest.xml
index 75b1d0d..7e8fcfd 100644
--- a/tests/tests/telecom3/AndroidTest.xml
+++ b/tests/tests/telecom3/AndroidTest.xml
@@ -16,6 +16,8 @@
<configuration description="Configuration for Telecom3 Tests">
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="telecom" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
<option name="not-shardable" value="true" />
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
diff --git a/tests/tests/telephony/current/AndroidManifest.xml b/tests/tests/telephony/current/AndroidManifest.xml
index 949cff1..d3926f7 100644
--- a/tests/tests/telephony/current/AndroidManifest.xml
+++ b/tests/tests/telephony/current/AndroidManifest.xml
@@ -107,7 +107,6 @@
<intent-filter>
<action android:name="android.telephony.VisualVoicemailService"/>
</intent-filter>
-
</service>
<service
@@ -129,6 +128,15 @@
</intent-filter>
</service>
+ <service
+ android:name="android.telephony.euicc.cts.MockEuiccService"
+ android:permission="android.permission.BIND_EUICC_SERVICE"
+ android:exported="true">
+ <intent-filter android:priority="100">
+ <action android:name="android.service.euicc.EuiccService"/>
+ </intent-filter>
+ </service>
+
<activity android:name="android.telephony.cts.StubDialerActvity">
<intent-filter>
<action android:name="android.intent.action.DIAL"/>
diff --git a/tests/tests/telephony/current/OWNERS b/tests/tests/telephony/current/OWNERS
index 9bc5122..7c8e7d8 100644
--- a/tests/tests/telephony/current/OWNERS
+++ b/tests/tests/telephony/current/OWNERS
@@ -1,2 +1,5 @@
# Bug component: 20868
-rgreenwalt@google.com
\ No newline at end of file
+rgreenwalt@google.com
+jackyu@google.com
+tgunn@google.com
+amitmahajan@google.com
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/ServiceStateTest.java b/tests/tests/telephony/current/src/android/telephony/cts/ServiceStateTest.java
index 39c35ef..b394052 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/ServiceStateTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/ServiceStateTest.java
@@ -18,6 +18,9 @@
import static android.telephony.ServiceState.DUPLEX_MODE_FDD;
import static android.telephony.ServiceState.DUPLEX_MODE_TDD;
import static android.telephony.ServiceState.DUPLEX_MODE_UNKNOWN;
+import static android.telephony.ServiceState.STATE_IN_SERVICE;
+import static android.telephony.ServiceState.STATE_OUT_OF_SERVICE;
+import static android.telephony.ServiceState.STATE_POWER_OFF;
import static org.junit.Assert.assertNotEquals;
@@ -36,45 +39,76 @@
private static final int CHANNEL_NUMBER_BAND_33 = 36000;
private static final int[] CELL_BANDWIDTH = {1, 2, 3};
- public void testServiceState() {
+ public void testDescribeContents() {
ServiceState serviceState = new ServiceState();
-
assertEquals(0, serviceState.describeContents());
+ }
+ public void testSetStateOff() {
+ ServiceState serviceState = new ServiceState();
serviceState.setStateOff();
- assertEquals(ServiceState.STATE_POWER_OFF, serviceState.getState());
+ assertEquals(STATE_POWER_OFF, serviceState.getState());
checkOffStatus(serviceState);
+ }
+ public void testSetStateOutOfService() {
+ ServiceState serviceState = new ServiceState();
serviceState.setStateOutOfService();
- assertEquals(ServiceState.STATE_OUT_OF_SERVICE, serviceState.getState());
+ assertEquals(STATE_OUT_OF_SERVICE, serviceState.getState());
checkOffStatus(serviceState);
+ }
+ public void testSetState() {
+ ServiceState serviceState = new ServiceState();
serviceState.setState(ServiceState.STATE_IN_SERVICE);
assertEquals(ServiceState.STATE_IN_SERVICE, serviceState.getState());
+ }
+ public void testGetRoaming() {
+ ServiceState serviceState = new ServiceState();
+ serviceState.setRoaming(false);
assertFalse(serviceState.getRoaming());
serviceState.setRoaming(true);
assertTrue(serviceState.getRoaming());
+ }
+ public void testGetIsManualSelection() {
+ ServiceState serviceState = new ServiceState();
+ serviceState.setIsManualSelection(false);
assertFalse(serviceState.getIsManualSelection());
serviceState.setIsManualSelection(true);
assertTrue(serviceState.getIsManualSelection());
+ }
+ public void testGetOperator() {
+ ServiceState serviceState = new ServiceState();
serviceState.setOperatorName(OPERATOR_ALPHA_LONG, OPERATOR_ALPHA_SHORT, OPERATOR_NUMERIC);
assertEquals(OPERATOR_ALPHA_LONG, serviceState.getOperatorAlphaLong());
assertEquals(OPERATOR_ALPHA_SHORT, serviceState.getOperatorAlphaShort());
assertEquals(OPERATOR_NUMERIC, serviceState.getOperatorNumeric());
+ }
+ public void testGetCdma() {
+ ServiceState serviceState = new ServiceState();
serviceState.setCdmaSystemAndNetworkId(SYSTEM_ID, NETWORK_ID);
assertEquals(SYSTEM_ID, serviceState.getCdmaSystemId());
assertEquals(NETWORK_ID, serviceState.getCdmaNetworkId());
+ }
+ public void testGetChannelNumber() {
+ ServiceState serviceState = new ServiceState();
serviceState.setChannelNumber(CHANNEL_NUMBER_BAND_66);
assertEquals(CHANNEL_NUMBER_BAND_66, serviceState.getChannelNumber());
+ }
+ public void testGetCellBandwidths() {
+ ServiceState serviceState = new ServiceState();
serviceState.setCellBandwidths(CELL_BANDWIDTH);
assertEquals(CELL_BANDWIDTH, serviceState.getCellBandwidths());
+ }
+ public void testGetDuplexMode() {
+ ServiceState serviceState = new ServiceState();
serviceState.setRilDataRadioTechnology(ServiceState.RIL_RADIO_TECHNOLOGY_GSM);
assertEquals(DUPLEX_MODE_UNKNOWN, serviceState.getDuplexMode());
@@ -83,21 +117,24 @@
serviceState.setChannelNumber(CHANNEL_NUMBER_BAND_33);
assertEquals(DUPLEX_MODE_TDD, serviceState.getDuplexMode());
+ }
+ public void testToString() {
+ ServiceState serviceState = new ServiceState();
assertNotNull(serviceState.toString());
+ }
- ServiceState tempServiceState = new ServiceState(serviceState);
- assertTrue(tempServiceState.equals(serviceState));
+ public void testCopyConstructor() {
+ ServiceState serviceState = getServiceStateWithOperatorName("name", "numeric");
+ assertEquals(serviceState, new ServiceState(serviceState));
+ }
+ public void testParcelConstructor() {
+ ServiceState serviceState = getServiceStateWithOperatorName("name", "numeric");
Parcel stateParcel = Parcel.obtain();
serviceState.writeToParcel(stateParcel, 0);
stateParcel.setDataPosition(0);
- tempServiceState = new ServiceState(stateParcel);
- assertTrue(tempServiceState.equals(serviceState));
-
- MockServiceState mockServiceState = new MockServiceState();
- mockServiceState.copyFrom(serviceState);
- assertTrue(mockServiceState.equals(serviceState));
+ assertEquals(serviceState, new ServiceState(stateParcel));
}
public void testHashCode() {
@@ -136,11 +173,4 @@
assertNull(s.getOperatorNumeric());
assertFalse(s.getIsManualSelection());
}
-
- private class MockServiceState extends ServiceState {
- @Override
- protected void copyFrom(ServiceState s) {
- super.copyFrom(s);
- }
- }
}
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/SignalStrengthTest.java b/tests/tests/telephony/current/src/android/telephony/cts/SignalStrengthTest.java
index 66a91da..0d42a82 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/SignalStrengthTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/SignalStrengthTest.java
@@ -15,15 +15,9 @@
*/
package android.telephony.cts;
-import static android.telephony.NetworkRegistrationState.NR_STATUS_CONNECTED;
+import static android.telephony.NetworkRegistrationInfo.NR_STATE_CONNECTED;
import android.content.Context;
import android.content.pm.PackageManager;
-import android.net.ConnectivityManager;
-import android.os.Parcel;
-import android.telephony.CellInfoCdma;
-import android.telephony.CellInfoGsm;
-import android.telephony.CellInfoLte;
-import android.telephony.CellInfoWcdma;
import android.telephony.CellSignalStrengthCdma;
import android.telephony.CellSignalStrengthGsm;
import android.telephony.CellSignalStrengthLte;
@@ -40,7 +34,6 @@
import java.util.HashSet;
import java.util.List;
-import java.util.Objects;
import java.util.Set;
@@ -123,7 +116,7 @@
/** Check whether the device is LTE + NR dual connected */
private boolean isUsingEnDc() {
ServiceState ss = mTm.getServiceState();
- return ss != null && ss.getNrStatus() == NR_STATUS_CONNECTED;
+ return ss != null && ss.getNrState() == NR_STATE_CONNECTED;
}
/** Get the CellSignalStrength class type that should be returned when using a network type */
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java
index 0a1410b..bbe0c0a 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java
@@ -36,14 +36,12 @@
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
+import android.os.ParcelUuid;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.SubscriptionPlan;
import android.telephony.TelephonyManager;
-import androidx.test.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
import com.android.compatibility.common.util.ShellIdentityUtils;
import com.android.compatibility.common.util.SystemUtil;
import com.android.internal.util.ArrayUtils;
@@ -56,12 +54,16 @@
import java.time.Period;
import java.time.ZonedDateTime;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
@RunWith(AndroidJUnit4.class)
public class SubscriptionManagerTest {
private SubscriptionManager mSm;
@@ -359,23 +361,25 @@
// Set subscription group with current sub Id. This should fail
// because we don't have MODIFY_PHONE_STATE or carrier privilege permission.
- int[] subGroup = new int[] {mSubId};
+ List<Integer> subGroup = new ArrayList();
+ subGroup.add(mSubId);
try {
- mSm.setSubscriptionGroup(subGroup);
+ mSm.createSubscriptionGroup(subGroup);
fail();
} catch (SecurityException expected) {
}
// Getting subscriptions in group should return null as setSubscriptionGroup
// should fail.
- assertNull(mSm.getSubscriptionsInGroup(mSubId));
+ SubscriptionInfo info = mSm.getActiveSubscriptionInfo(mSubId);
+ assertNull(info.getGroupUuid());
// Remove from subscription group with current sub Id. This should fail
// because we don't have MODIFY_PHONE_STATE or carrier privilege permission.
try {
- mSm.removeSubscriptionsFromGroup(subGroup);
+ mSm.removeSubscriptionsFromGroup(subGroup, null);
fail();
- } catch (SecurityException expected) {
+ } catch (NullPointerException expected) {
}
}
@@ -384,20 +388,20 @@
if (!isSupported()) return;
// Set subscription group with current sub Id.
- int[] subGroup = new int[] {mSubId};
- String uuid = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm,
- (sm) -> sm.setSubscriptionGroup(subGroup));
+ List<Integer> subGroup = new ArrayList();
+ subGroup.add(mSubId);
+ ParcelUuid uuid = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm,
+ (sm) -> sm.createSubscriptionGroup(subGroup));
// Getting subscriptions in group.
- List<SubscriptionInfo> infoList = mSm.getSubscriptionsInGroup(mSubId);
+ List<SubscriptionInfo> infoList = mSm.getSubscriptionsInGroup(uuid);
assertNotNull(infoList);
assertEquals(1, infoList.size());
assertEquals(uuid, infoList.get(0).getGroupUuid());
// Remove from subscription group with current sub Id.
- boolean success = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm,
- (sm) -> sm.removeSubscriptionsFromGroup(subGroup));
- assertTrue(success);
+ ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm,
+ (sm) -> sm.removeSubscriptionsFromGroup(subGroup, uuid));
}
@Test
@@ -438,23 +442,6 @@
}
@Test
- public void testSettingSubscriptionMeteredNess() throws Exception {
- if (!isSupported()) return;
-
- // Set subscription to be un-metered. This should fail
- // because we don't have MODIFY_PHONE_STATE or carrier privilege permission.
- try {
- mSm.setMetered(false, mSubId);
- fail();
- } catch (SecurityException expected) {
- }
-
- // Shouldn't crash.
- SubscriptionInfo info = mSm.getActiveSubscriptionInfo(mSubId);
- info.isMetered();
- }
-
- @Test
public void testGetOpportunisticSubscriptions() throws Exception {
if (!isSupported()) return;
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
index 23705f2..6ff311b 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
@@ -46,7 +46,7 @@
import android.telephony.AccessNetworkConstants;
import android.telephony.AvailableNetworkInfo;
import android.telephony.CellLocation;
-import android.telephony.NetworkRegistrationState;
+import android.telephony.NetworkRegistrationInfo;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
import android.telephony.SubscriptionInfo;
@@ -425,8 +425,8 @@
private void assertServiceStateSanitization(ServiceState state, boolean sanitizedForFineOnly) {
if (state == null) return;
- if (state.getNetworkRegistrationStates() != null) {
- for (NetworkRegistrationState nrs : state.getNetworkRegistrationStates()) {
+ if (state.getNetworkRegistrationInfoList() != null) {
+ for (NetworkRegistrationInfo nrs : state.getNetworkRegistrationInfoList()) {
assertNull(nrs.getCellIdentity());
}
}
@@ -987,35 +987,35 @@
}
/**
- * Basic test to ensure {@link NetworkRegistrationState#isRoaming()} does not throw any
+ * Basic test to ensure {@link NetworkRegistrationInfo#isRoaming()} does not throw any
* exception.
*/
@Test
- public void testNetworkRegistrationStateIsRoaming() {
+ public void testNetworkRegistrationInfoIsRoaming() {
if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
return;
}
// get NetworkRegistration object
- NetworkRegistrationState nwReg = mTelephonyManager.getServiceState()
- .getNetworkRegistrationState(NetworkRegistrationState.DOMAIN_CS,
+ NetworkRegistrationInfo nwReg = mTelephonyManager.getServiceState()
+ .getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_CS,
AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
assertThat(nwReg).isNotNull();
nwReg.isRoaming();
}
/**
- * Basic test to ensure {@link NetworkRegistrationState#getRoamingType()} ()} does not throw any
+ * Basic test to ensure {@link NetworkRegistrationInfo#getRoamingType()} ()} does not throw any
* exception and returns valid result
* @see ServiceState.RoamingType
*/
@Test
- public void testNetworkRegistrationStateGetRoamingType() {
+ public void testNetworkRegistrationInfoGetRoamingType() {
if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
return;
}
// get NetworkRegistration object for voice
- NetworkRegistrationState nwReg = mTelephonyManager.getServiceState()
- .getNetworkRegistrationState(NetworkRegistrationState.DOMAIN_CS,
+ NetworkRegistrationInfo nwReg = mTelephonyManager.getServiceState()
+ .getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_CS,
AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
assertNotNull(nwReg);
assertThat(nwReg.getRoamingType()).isIn(ROAMING_TYPES);
@@ -1023,14 +1023,14 @@
// getNetworkRegistration object for data
// get NetworkRegistration object for voice
nwReg = mTelephonyManager.getServiceState()
- .getNetworkRegistrationState(NetworkRegistrationState.DOMAIN_PS,
+ .getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS,
AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
assertThat(nwReg).isNotNull();
assertThat(nwReg.getRoamingType()).isIn(ROAMING_TYPES);
}
/**
- * Basic test to ensure {@link NetworkRegistrationState#getAccessNetworkTechnology()} not
+ * Basic test to ensure {@link NetworkRegistrationInfo#getAccessNetworkTechnology()} not
* throw any exception and returns valid result
* @see TelephonyManager.NetworkType
*/
@@ -1040,15 +1040,15 @@
return;
}
// get NetworkRegistration object for voice
- NetworkRegistrationState nwReg = mTelephonyManager.getServiceState()
- .getNetworkRegistrationState(NetworkRegistrationState.DOMAIN_CS,
+ NetworkRegistrationInfo nwReg = mTelephonyManager.getServiceState()
+ .getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_CS,
AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
assertThat(nwReg).isNotNull();
assertThat(nwReg.getAccessNetworkTechnology()).isIn(NETWORK_TYPES);
// get NetworkRegistation object for data
nwReg = mTelephonyManager.getServiceState()
- .getNetworkRegistrationState(NetworkRegistrationState.DOMAIN_PS,
+ .getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS,
AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
assertThat(nwReg).isNotNull();
assertThat(nwReg.getAccessNetworkTechnology()).isIn(NETWORK_TYPES);
@@ -1281,7 +1281,7 @@
}
private static void assertSetOpportunisticInvalidParameter(int value) {
- assertThat(value).isEqualTo(TelephonyManager.SET_OPPORTUNISTIC_SUB_INVALID_PARAMETER);
+ assertThat(value).isEqualTo(TelephonyManager.SET_OPPORTUNISTIC_SUB_INACTIVE_SUBSCRIPTION);
}
/**
diff --git a/tests/tests/telephony/current/src/android/telephony/euicc/cts/EuiccServiceTest.java b/tests/tests/telephony/current/src/android/telephony/euicc/cts/EuiccServiceTest.java
new file mode 100644
index 0000000..c2b92c5
--- /dev/null
+++ b/tests/tests/telephony/current/src/android/telephony/euicc/cts/EuiccServiceTest.java
@@ -0,0 +1,115 @@
+/*
+ * 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.telephony.euicc.cts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.IBinder;
+import android.service.euicc.IEuiccService;
+import android.service.euicc.IGetEidCallback;
+import android.telephony.euicc.cts.MockEuiccService.IMockEuiccServiceCallback;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.rule.ServiceTestRule;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+public class EuiccServiceTest {
+ private static final int CALLBACK_TIMEOUT_MILLIS = 2000 /* 2 sec */;
+
+ private IEuiccService mEuiccServiceBinder;
+ private IMockEuiccServiceCallback mCallback;
+
+ private CountDownLatch mCountDownLatch;
+
+ @Rule public ServiceTestRule mServiceTestRule = new ServiceTestRule();
+
+ @Before
+ public void setUp() throws Exception {
+ mCallback = new MockEuiccServiceCallback();
+ MockEuiccService.setCallback(mCallback);
+
+ Intent mockServiceIntent = new Intent(getContext(), MockEuiccService.class);
+ IBinder binder = mServiceTestRule.bindService(mockServiceIntent);
+ mEuiccServiceBinder = IEuiccService.Stub.asInterface(binder);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ mServiceTestRule.unbindService();
+ mCallback.reset();
+ }
+
+ static class MockEuiccServiceCallback implements IMockEuiccServiceCallback {
+ private boolean mMethodCalled;
+
+ @Override
+ public void setMethodCalled() {
+ mMethodCalled = true;
+ }
+
+ @Override
+ public boolean isMethodCalled() {
+ return mMethodCalled;
+ }
+
+ @Override
+ public void reset() {
+ mMethodCalled = false;
+ }
+ }
+
+ private Context getContext() {
+ return InstrumentationRegistry.getContext();
+ }
+
+ @Test
+ public void testOnGetEid() throws Exception {
+ mCountDownLatch = new CountDownLatch(1);
+
+ mEuiccServiceBinder.getEid(
+ 1 /*cardId*/,
+ new IGetEidCallback.Stub() {
+ @Override
+ public void onSuccess(String eid) {
+ assertEquals(MockEuiccService.MOCK_EID, eid);
+ mCountDownLatch.countDown();
+ }
+ });
+
+ try {
+ mCountDownLatch.await(CALLBACK_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ fail(e.toString());
+ }
+
+ assertTrue(mCallback.isMethodCalled());
+ }
+}
diff --git a/tests/tests/telephony/current/src/android/telephony/euicc/cts/MockEuiccService.java b/tests/tests/telephony/current/src/android/telephony/euicc/cts/MockEuiccService.java
new file mode 100644
index 0000000..de931f2
--- /dev/null
+++ b/tests/tests/telephony/current/src/android/telephony/euicc/cts/MockEuiccService.java
@@ -0,0 +1,144 @@
+/*
+ * 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.telephony.euicc.cts;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Bundle;
+import android.service.euicc.DownloadSubscriptionResult;
+import android.service.euicc.EuiccService;
+import android.service.euicc.GetDefaultDownloadableSubscriptionListResult;
+import android.service.euicc.GetDownloadableSubscriptionMetadataResult;
+import android.service.euicc.GetEuiccProfileInfoListResult;
+import android.telephony.euicc.DownloadableSubscription;
+import android.telephony.euicc.EuiccInfo;
+import android.telephony.euicc.EuiccManager.OtaStatus;
+
+/** Dummy implementation of {@link EuiccService} for testing. */
+public class MockEuiccService extends EuiccService {
+ static String MOCK_EID = "89000000000000000000000000000000";
+
+ interface IMockEuiccServiceCallback {
+ void setMethodCalled();
+
+ boolean isMethodCalled();
+
+ void reset();
+ }
+
+ private static IMockEuiccServiceCallback sMockEuiccServiceCallback;
+
+ static void setCallback(IMockEuiccServiceCallback callback) {
+ sMockEuiccServiceCallback = callback;
+ }
+
+ @Override
+ public String onGetEid(int slotId) {
+ sMockEuiccServiceCallback.setMethodCalled();
+ return MOCK_EID;
+ }
+
+ @Override
+ public @OtaStatus int onGetOtaStatus(int slotId) {
+ sMockEuiccServiceCallback.setMethodCalled();
+ // TODO: Return meaningful value.
+ return 0;
+ }
+
+ @Override
+ public void onStartOtaIfNecessary(int slotId, OtaStatusChangedCallback statusChangedCallback) {
+ sMockEuiccServiceCallback.setMethodCalled();
+ }
+
+ @Override
+ public GetDownloadableSubscriptionMetadataResult onGetDownloadableSubscriptionMetadata(
+ int slotId, DownloadableSubscription subscription, boolean forceDeactivateSim) {
+ sMockEuiccServiceCallback.setMethodCalled();
+ // TODO: Return meaningful value.
+ return null;
+ }
+
+ @Override
+ public GetDefaultDownloadableSubscriptionListResult onGetDefaultDownloadableSubscriptionList(
+ int slotId, boolean forceDeactivateSim) {
+ sMockEuiccServiceCallback.setMethodCalled();
+ // TODO: Return meaningful value.
+ return null;
+ }
+
+ @Override
+ public DownloadSubscriptionResult onDownloadSubscription(
+ int slotId,
+ @NonNull DownloadableSubscription subscription,
+ boolean switchAfterDownload,
+ boolean forceDeactivateSim,
+ @Nullable Bundle resolvedBundle) {
+ sMockEuiccServiceCallback.setMethodCalled();
+ // TODO: Return meaningful value.
+ return null;
+ }
+
+ @Override
+ public @NonNull GetEuiccProfileInfoListResult onGetEuiccProfileInfoList(int slotId) {
+ sMockEuiccServiceCallback.setMethodCalled();
+ // TODO: Return meaningful value.
+ return null;
+ }
+
+ @Override
+ public @NonNull EuiccInfo onGetEuiccInfo(int slotId) {
+ sMockEuiccServiceCallback.setMethodCalled();
+ // TODO: Return meaningful value.
+ return null;
+ }
+
+ @Override
+ public @Result int onDeleteSubscription(int slotId, String iccid) {
+ sMockEuiccServiceCallback.setMethodCalled();
+ // TODO: Return meaningful value.
+ return 0;
+ }
+
+ @Override
+ public @Result int onSwitchToSubscription(
+ int slotId, @Nullable String iccid, boolean forceDeactivateSim) {
+ sMockEuiccServiceCallback.setMethodCalled();
+ // TODO: Return meaningful value.
+ return 0;
+ }
+
+ @Override
+ public int onUpdateSubscriptionNickname(int slotId, String iccid, String nickname) {
+ sMockEuiccServiceCallback.setMethodCalled();
+ // TODO: Return meaningful value.
+ return 0;
+ }
+
+ @Override
+ public int onEraseSubscriptions(int slotId) {
+ sMockEuiccServiceCallback.setMethodCalled();
+ // TODO: Return meaningful value.
+ return 0;
+ }
+
+ @Override
+ public int onRetainSubscriptionsForFactoryReset(int slotId) {
+ sMockEuiccServiceCallback.setMethodCalled();
+ // TODO: Return meaningful value.
+ return 0;
+ }
+}
diff --git a/tests/tests/telephony2/OWNERS b/tests/tests/telephony2/OWNERS
index 9bc5122..7c8e7d8 100644
--- a/tests/tests/telephony2/OWNERS
+++ b/tests/tests/telephony2/OWNERS
@@ -1,2 +1,5 @@
# Bug component: 20868
-rgreenwalt@google.com
\ No newline at end of file
+rgreenwalt@google.com
+jackyu@google.com
+tgunn@google.com
+amitmahajan@google.com
diff --git a/tests/tests/telephony4/OWNERS b/tests/tests/telephony4/OWNERS
new file mode 100644
index 0000000..5617896
--- /dev/null
+++ b/tests/tests/telephony4/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 20868
+yinxu@google.com
\ No newline at end of file
diff --git a/tests/tests/telephonyprovider/AndroidManifest.xml b/tests/tests/telephonyprovider/AndroidManifest.xml
index 949920b..9a9e618 100755
--- a/tests/tests/telephonyprovider/AndroidManifest.xml
+++ b/tests/tests/telephonyprovider/AndroidManifest.xml
@@ -28,7 +28,7 @@
<uses-library android:name="android.test.runner" />
<!-- Required to be default SMS app -->
- <receiver android:name="android.telephonyprovider.TelephonyProviderReceiver"
+ <receiver android:name="android.telephonyprovider.TelephonyProviderSmsDeliverReceiver"
android:permission="android.permission.BROADCAST_SMS">
<intent-filter>
@@ -38,7 +38,7 @@
</receiver>
<!-- Required to be default SMS app -->
- <receiver android:name="android.telephonyprovider.TelephonyProviderReceiver"
+ <receiver android:name="android.telephonyprovider.TelephonyProviderWapPushDeliverReceiver"
android:permission="android.permission.BROADCAST_WAP_PUSH">
<intent-filter>
diff --git a/tests/tests/telephonyprovider/TEST_MAPPING b/tests/tests/telephonyprovider/TEST_MAPPING
new file mode 100644
index 0000000..ee02cd3
--- /dev/null
+++ b/tests/tests/telephonyprovider/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+ "presubmit": [
+ {
+ "name": "CtsTelephonyProviderTestCases"
+ }
+ ]
+}
diff --git a/tests/tests/telephonyprovider/src/android/telephonyprovider/TelephonyProviderReceiver.java b/tests/tests/telephonyprovider/src/android/telephonyprovider/TelephonyProviderSmsDeliverReceiver.java
similarity index 92%
copy from tests/tests/telephonyprovider/src/android/telephonyprovider/TelephonyProviderReceiver.java
copy to tests/tests/telephonyprovider/src/android/telephonyprovider/TelephonyProviderSmsDeliverReceiver.java
index c139cec..f8b5a17 100644
--- a/tests/tests/telephonyprovider/src/android/telephonyprovider/TelephonyProviderReceiver.java
+++ b/tests/tests/telephonyprovider/src/android/telephonyprovider/TelephonyProviderSmsDeliverReceiver.java
@@ -24,7 +24,7 @@
* This receiver is used to provide the interface required for a default SMS application. It
* intentionally has no custom behavior.
*/
-public class TelephonyProviderReceiver extends BroadcastReceiver {
+public class TelephonyProviderSmsDeliverReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// Do nothing
diff --git a/tests/tests/telephonyprovider/src/android/telephonyprovider/TelephonyProviderReceiver.java b/tests/tests/telephonyprovider/src/android/telephonyprovider/TelephonyProviderWapPushDeliverReceiver.java
similarity index 92%
rename from tests/tests/telephonyprovider/src/android/telephonyprovider/TelephonyProviderReceiver.java
rename to tests/tests/telephonyprovider/src/android/telephonyprovider/TelephonyProviderWapPushDeliverReceiver.java
index c139cec..210eae9 100644
--- a/tests/tests/telephonyprovider/src/android/telephonyprovider/TelephonyProviderReceiver.java
+++ b/tests/tests/telephonyprovider/src/android/telephonyprovider/TelephonyProviderWapPushDeliverReceiver.java
@@ -24,7 +24,7 @@
* This receiver is used to provide the interface required for a default SMS application. It
* intentionally has no custom behavior.
*/
-public class TelephonyProviderReceiver extends BroadcastReceiver {
+public class TelephonyProviderWapPushDeliverReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// Do nothing
diff --git a/tests/tests/text/OWNERS b/tests/tests/text/OWNERS
index 7f78c31..a163bf7 100644
--- a/tests/tests/text/OWNERS
+++ b/tests/tests/text/OWNERS
@@ -1,3 +1,4 @@
+# Bug component: 25699
set noparent
siyamed@google.com
diff --git a/tests/tests/text/src/android/text/cts/TextPaintTest.java b/tests/tests/text/src/android/text/cts/TextPaintTest.java
index 2834268..b9e770a 100644
--- a/tests/tests/text/src/android/text/cts/TextPaintTest.java
+++ b/tests/tests/text/src/android/text/cts/TextPaintTest.java
@@ -27,7 +27,7 @@
*/
public class TextPaintTest extends AndroidTestCase {
private static final int DEFAULT_PAINT_FLAGS = TextPaint.DEV_KERN_TEXT_FLAG
- | TextPaint.EMBEDDED_BITMAP_TEXT_FLAG;
+ | TextPaint.EMBEDDED_BITMAP_TEXT_FLAG | TextPaint.FILTER_BITMAP_FLAG;
public void testConstructor() {
TextPaint textPaint;
diff --git a/tests/tests/tools/processors/view_inspector/src/android/processor/view/inspector/cts/PlatformInspectableProcessorTest.java b/tests/tests/tools/processors/view_inspector/src/android/processor/view/inspector/cts/PlatformInspectableProcessorTest.java
index acb37bc..7941ca8 100644
--- a/tests/tests/tools/processors/view_inspector/src/android/processor/view/inspector/cts/PlatformInspectableProcessorTest.java
+++ b/tests/tests/tools/processors/view_inspector/src/android/processor/view/inspector/cts/PlatformInspectableProcessorTest.java
@@ -25,10 +25,8 @@
import android.R;
import android.content.res.Resources;
import android.graphics.Color;
-import android.view.inspector.InspectableNodeName;
import android.view.inspector.InspectableProperty;
-import android.view.inspector.InspectableProperty.EnumMap;
-import android.view.inspector.InspectableProperty.FlagMap;
+import android.view.inspector.InspectableProperty.EnumEntry;
import android.view.inspector.InspectableProperty.ValueType;
import android.view.inspector.InspectionCompanion;
@@ -84,17 +82,6 @@
mPropertyReader = new TestPropertyReader(mPropertyMapper);
}
- @InspectableNodeName("my_node")
- class NodeNameTest {
- }
-
-
- @Test
- public void testNodeName() {
- assertEquals("my_node", loadCompanion(NodeNameTest.class).getNodeName());
- assertNull(loadCompanion(IntPropertyTest.class).getNodeName());
- }
-
class IntPropertyTest {
private final int mValue;
@@ -442,8 +429,8 @@
private int mValue;
@InspectableProperty(enumMapping = {
- @EnumMap(name = "ONE", value = 1),
- @EnumMap(name = "TWO", value = 2)})
+ @InspectableProperty.EnumEntry(name = "ONE", value = 1),
+ @EnumEntry(name = "TWO", value = 2)})
public int getValue() {
return mValue;
}
@@ -476,10 +463,10 @@
private int mValue;
@InspectableProperty(flagMapping = {
- @FlagMap(name = "ONE", target = 0x1, mask = 0x3),
- @FlagMap(name = "TWO", target = 0x2, mask = 0x3),
- @FlagMap(name = "THREE", target = 0x3, mask = 0x3),
- @FlagMap(name = "FOUR", target = 0x4)})
+ @InspectableProperty.FlagEntry(name = "ONE", target = 0x1, mask = 0x3),
+ @InspectableProperty.FlagEntry(name = "TWO", target = 0x2, mask = 0x3),
+ @InspectableProperty.FlagEntry(name = "THREE", target = 0x3, mask = 0x3),
+ @InspectableProperty.FlagEntry(name = "FOUR", target = 0x4)})
public int getValue() {
return mValue;
}
diff --git a/tests/tests/transition/AndroidTest.xml b/tests/tests/transition/AndroidTest.xml
index cac2338..043ac02 100644
--- a/tests/tests/transition/AndroidTest.xml
+++ b/tests/tests/transition/AndroidTest.xml
@@ -19,6 +19,7 @@
<!-- There is no difference between instant apps and installed apps with
respect to transition tests, so don't run these in instant apps. -->
<option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
<option name="test-file-name" value="CtsTransitionTestCases.apk" />
diff --git a/tests/tests/uirendering/OWNERS b/tests/tests/uirendering/OWNERS
new file mode 100644
index 0000000..fe5d8ba
--- /dev/null
+++ b/tests/tests/uirendering/OWNERS
@@ -0,0 +1,6 @@
+# Bug component: 59572
+jreck@google.com
+njawad@google.com
+djsollen@google.com
+stani@google.com
+scroggo@google.com
diff --git a/tests/tests/view/Android.mk b/tests/tests/view/Android.mk
index 28a6b3e..ee792d0 100644
--- a/tests/tests/view/Android.mk
+++ b/tests/tests/view/Android.mk
@@ -37,7 +37,8 @@
mockito-target-minus-junit4 \
platform-test-annotations \
ub-uiautomator \
- truth-prebuilt
+ truth-prebuilt \
+ CtsSurfaceValidatorLib
LOCAL_JNI_SHARED_LIBRARIES := libctsview_jni libnativehelper_compat_libc++
diff --git a/tests/tests/view/AndroidManifest.xml b/tests/tests/view/AndroidManifest.xml
index 023998b..5c814ab 100644
--- a/tests/tests/view/AndroidManifest.xml
+++ b/tests/tests/view/AndroidManifest.xml
@@ -304,6 +304,15 @@
</intent-filter>
</activity>
+ <activity android:name="android.view.cts.surfacevalidator.CapturedActivityWithResource"
+ android:screenOrientation="locked"
+ android:theme="@style/WhiteBackgroundTheme">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
<activity android:name="android.view.cts.HoverCtsActivity"
android:screenOrientation="locked">
<intent-filter>
diff --git a/tests/tests/view/res/values/styles.xml b/tests/tests/view/res/values/styles.xml
index 20f9a57..9a551df 100644
--- a/tests/tests/view/res/values/styles.xml
+++ b/tests/tests/view/res/values/styles.xml
@@ -159,7 +159,7 @@
<style name="Theme_OverrideView">
<item name="themeType">5</item>
</style>
-
+
<style name="Theme_ThemedDrawableTest">
<item name="themeBoolean">true</item>
<item name="themeColor">@android:color/black</item>
diff --git a/tests/tests/view/src/android/view/cts/PointerCaptureTest.java b/tests/tests/view/src/android/view/cts/PointerCaptureTest.java
index 96e9717..9cb1524 100644
--- a/tests/tests/view/src/android/view/cts/PointerCaptureTest.java
+++ b/tests/tests/view/src/android/view/cts/PointerCaptureTest.java
@@ -89,9 +89,13 @@
}
private void requestCaptureSync(View view) throws Throwable {
- mActivityRule.runOnUiThread(view::requestPointerCapture);
- PollingCheck.waitFor(TIMEOUT_DELTA,
- () -> view.hasPointerCapture() && mActivity.hasPointerCapture());
+ PollingCheck.waitFor(TIMEOUT_DELTA, () -> {
+ try {
+ mActivityRule.runOnUiThread(view::requestPointerCapture);
+ } catch (Throwable e) {
+ }
+ return view.hasPointerCapture() && mActivity.hasPointerCapture();
+ });
}
private void requestCaptureSync() throws Throwable {
diff --git a/tests/tests/view/src/android/view/cts/SurfaceViewSyncTest.java b/tests/tests/view/src/android/view/cts/SurfaceViewSyncTest.java
index c7a58e4..a2b01f4 100644
--- a/tests/tests/view/src/android/view/cts/SurfaceViewSyncTest.java
+++ b/tests/tests/view/src/android/view/cts/SurfaceViewSyncTest.java
@@ -32,7 +32,7 @@
import android.view.animation.LinearInterpolator;
import android.view.cts.surfacevalidator.AnimationFactory;
import android.view.cts.surfacevalidator.AnimationTestCase;
-import android.view.cts.surfacevalidator.CapturedActivity;
+import android.view.cts.surfacevalidator.CapturedActivityWithResource;
import android.view.cts.surfacevalidator.PixelChecker;
import android.view.cts.surfacevalidator.ViewFactory;
import android.widget.FrameLayout;
@@ -57,13 +57,13 @@
private static final String TAG = "SurfaceViewSyncTests";
@Rule
- public ActivityTestRule<CapturedActivity> mActivityRule =
- new ActivityTestRule<>(CapturedActivity.class);
+ public ActivityTestRule<CapturedActivityWithResource> mActivityRule =
+ new ActivityTestRule<>(CapturedActivityWithResource.class);
@Rule
public TestName mName = new TestName();
- private CapturedActivity mActivity;
+ private CapturedActivityWithResource mActivity;
private MediaPlayer mMediaPlayer;
@Before
diff --git a/tests/tests/view/src/android/view/cts/surfacevalidator/CapturedActivityWithResource.java b/tests/tests/view/src/android/view/cts/surfacevalidator/CapturedActivityWithResource.java
new file mode 100644
index 0000000..89ca108
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/surfacevalidator/CapturedActivityWithResource.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2016 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.view.cts.surfacevalidator;
+
+import android.media.MediaPlayer;
+import android.os.Bundle;
+import android.view.cts.R;
+
+public class CapturedActivityWithResource extends CapturedActivity {
+ private MediaPlayer mMediaPlayer;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mMediaPlayer = MediaPlayer.create(this, R.raw.colors_video);
+ mMediaPlayer.setLooping(true);
+ }
+
+ /**
+ * MediaPlayer pre-loaded with a video with no black pixels. Be kind, rewind.
+ */
+ public MediaPlayer getMediaPlayer() {
+ return mMediaPlayer;
+ }
+}
diff --git a/tests/tests/view/surfacevalidator/Android.mk b/tests/tests/view/surfacevalidator/Android.mk
new file mode 100644
index 0000000..fbb6894
--- /dev/null
+++ b/tests/tests/view/surfacevalidator/Android.mk
@@ -0,0 +1,30 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := CtsSurfaceValidatorLib
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SDK_VERSION := test_current
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ androidx.test.rules \
+ ub-uiautomator
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/tests/tests/view/src/android/view/cts/surfacevalidator/AnimationFactory.java b/tests/tests/view/surfacevalidator/src/android/view/cts/surfacevalidator/AnimationFactory.java
similarity index 100%
rename from tests/tests/view/src/android/view/cts/surfacevalidator/AnimationFactory.java
rename to tests/tests/view/surfacevalidator/src/android/view/cts/surfacevalidator/AnimationFactory.java
diff --git a/tests/tests/view/src/android/view/cts/surfacevalidator/AnimationTestCase.java b/tests/tests/view/surfacevalidator/src/android/view/cts/surfacevalidator/AnimationTestCase.java
similarity index 100%
rename from tests/tests/view/src/android/view/cts/surfacevalidator/AnimationTestCase.java
rename to tests/tests/view/surfacevalidator/src/android/view/cts/surfacevalidator/AnimationTestCase.java
diff --git a/tests/tests/view/src/android/view/cts/surfacevalidator/CapturedActivity.java b/tests/tests/view/surfacevalidator/src/android/view/cts/surfacevalidator/CapturedActivity.java
similarity index 96%
rename from tests/tests/view/src/android/view/cts/surfacevalidator/CapturedActivity.java
rename to tests/tests/view/surfacevalidator/src/android/view/cts/surfacevalidator/CapturedActivity.java
index b4b178f..25155bd 100644
--- a/tests/tests/view/src/android/view/cts/surfacevalidator/CapturedActivity.java
+++ b/tests/tests/view/surfacevalidator/src/android/view/cts/surfacevalidator/CapturedActivity.java
@@ -27,7 +27,6 @@
import android.graphics.Rect;
import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
-import android.media.MediaPlayer;
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.os.Bundle;
@@ -44,7 +43,6 @@
import android.view.Display;
import android.view.PointerIcon;
import android.view.View;
-import android.view.cts.R;
import android.widget.FrameLayout;
import androidx.test.InstrumentationRegistry;
@@ -79,8 +77,6 @@
private static final String ACCEPT_RESOURCE_ID = "android:id/button1";
- private MediaPlayer mMediaPlayer;
-
private final Handler mHandler = new Handler(Looper.getMainLooper());
private volatile boolean mOnEmbedded;
private volatile boolean mOnWatch;
@@ -110,10 +106,6 @@
mCountDownLatch = new CountDownLatch(1);
startActivityForResult(mProjectionManager.createScreenCaptureIntent(), PERMISSION_CODE);
-
- mMediaPlayer = MediaPlayer.create(this, R.raw.colors_video);
- mMediaPlayer.setLooping(true);
-
}
public void dismissPermissionDialog() {
@@ -127,13 +119,6 @@
}
}
- /**
- * MediaPlayer pre-loaded with a video with no black pixels. Be kind, rewind.
- */
- public MediaPlayer getMediaPlayer() {
- return mMediaPlayer;
- }
-
@Override
public void onDestroy() {
super.onDestroy();
@@ -315,7 +300,7 @@
if (testCase.hasAnimation()) {
float framesPerSecond = 1.0f * result.passFrames
- / TimeUnit.MILLISECONDS.toSeconds(getCaptureDurationMs());
+ / TimeUnit.MILLISECONDS.toSeconds(getCaptureDurationMs());
assertTrue("Error, only " + result.passFrames
+ " frames observed, virtual display only capturing at "
+ framesPerSecond + " frames per second",
diff --git a/tests/tests/view/src/android/view/cts/surfacevalidator/ISurfaceValidatorTestCase.java b/tests/tests/view/surfacevalidator/src/android/view/cts/surfacevalidator/ISurfaceValidatorTestCase.java
similarity index 100%
rename from tests/tests/view/src/android/view/cts/surfacevalidator/ISurfaceValidatorTestCase.java
rename to tests/tests/view/surfacevalidator/src/android/view/cts/surfacevalidator/ISurfaceValidatorTestCase.java
diff --git a/tests/tests/view/src/android/view/cts/surfacevalidator/PixelChecker.java b/tests/tests/view/surfacevalidator/src/android/view/cts/surfacevalidator/PixelChecker.java
similarity index 100%
rename from tests/tests/view/src/android/view/cts/surfacevalidator/PixelChecker.java
rename to tests/tests/view/surfacevalidator/src/android/view/cts/surfacevalidator/PixelChecker.java
diff --git a/tests/tests/view/src/android/view/cts/surfacevalidator/PixelColor.java b/tests/tests/view/surfacevalidator/src/android/view/cts/surfacevalidator/PixelColor.java
similarity index 100%
rename from tests/tests/view/src/android/view/cts/surfacevalidator/PixelColor.java
rename to tests/tests/view/surfacevalidator/src/android/view/cts/surfacevalidator/PixelColor.java
diff --git a/tests/tests/view/src/android/view/cts/surfacevalidator/PixelCounter.rs b/tests/tests/view/surfacevalidator/src/android/view/cts/surfacevalidator/PixelCounter.rs
similarity index 100%
rename from tests/tests/view/src/android/view/cts/surfacevalidator/PixelCounter.rs
rename to tests/tests/view/surfacevalidator/src/android/view/cts/surfacevalidator/PixelCounter.rs
diff --git a/tests/tests/view/src/android/view/cts/surfacevalidator/SurfaceControlTestCase.java b/tests/tests/view/surfacevalidator/src/android/view/cts/surfacevalidator/SurfaceControlTestCase.java
similarity index 93%
rename from tests/tests/view/src/android/view/cts/surfacevalidator/SurfaceControlTestCase.java
rename to tests/tests/view/surfacevalidator/src/android/view/cts/surfacevalidator/SurfaceControlTestCase.java
index 6550e28..80671a7 100644
--- a/tests/tests/view/src/android/view/cts/surfacevalidator/SurfaceControlTestCase.java
+++ b/tests/tests/view/surfacevalidator/src/android/view/cts/surfacevalidator/SurfaceControlTestCase.java
@@ -29,15 +29,16 @@
private final FrameLayout.LayoutParams mLayoutParams;
private final AnimationFactory mAnimationFactory;
private final PixelChecker mPixelChecker;
-
+
private final int mBufferWidth;
private final int mBufferHeight;
private FrameLayout mParent;
private ValueAnimator mAnimator;
- public static abstract class ParentSurfaceConsumer {
- abstract public void addChildren(SurfaceControl parent);
+ private boolean mOnTop;
+ public abstract static class ParentSurfaceConsumer {
+ public abstract void addChildren(SurfaceControl parent);
};
private static class ParentSurfaceHolder implements SurfaceHolder.Callback {
@@ -80,11 +81,16 @@
return mPixelChecker;
}
+ public void setOnTop(boolean onTop) {
+ mOnTop = onTop;
+ }
+
public void start(Context context, FrameLayout parent) {
View view = mViewFactory.createView(context);
if (mViewFactory.mCallback instanceof ParentSurfaceHolder) {
ParentSurfaceHolder psh = (ParentSurfaceHolder) mViewFactory.mCallback;
psh.mSurfaceView = (SurfaceView) view;
+ psh.mSurfaceView.setZOrderOnTop(mOnTop);
}
mParent = parent;
diff --git a/tests/tests/view/src/android/view/cts/surfacevalidator/SurfacePixelValidator.java b/tests/tests/view/surfacevalidator/src/android/view/cts/surfacevalidator/SurfacePixelValidator.java
similarity index 96%
rename from tests/tests/view/src/android/view/cts/surfacevalidator/SurfacePixelValidator.java
rename to tests/tests/view/surfacevalidator/src/android/view/cts/surfacevalidator/SurfacePixelValidator.java
index c2fb007..f1a1660 100644
--- a/tests/tests/view/src/android/view/cts/surfacevalidator/SurfacePixelValidator.java
+++ b/tests/tests/view/surfacevalidator/src/android/view/cts/surfacevalidator/SurfacePixelValidator.java
@@ -61,7 +61,7 @@
private SparseArray<Bitmap> mFirstFailures = new SparseArray<>(MAX_CAPTURED_FAILURES);
private Runnable mConsumeRunnable = new Runnable() {
- int numSkipped = 0;
+ int mNumSkipped = 0;
@Override
public void run() {
Trace.beginSection("consume buffer");
@@ -74,9 +74,9 @@
boolean success = mPixelChecker.checkPixels(blackishPixelCount, mWidth, mHeight);
synchronized (mResultLock) {
- if (numSkipped < NUM_FIRST_FRAMES_SKIPPED) {
- numSkipped++;
- Log.d(TAG, "skipped frame nr " + numSkipped + ", success = " + success);
+ if (mNumSkipped < NUM_FIRST_FRAMES_SKIPPED) {
+ mNumSkipped++;
+ Log.d(TAG, "skipped frame nr " + mNumSkipped + ", success = " + success);
} else {
if (success) {
mResultSuccessFrames++;
diff --git a/tests/tests/view/src/android/view/cts/surfacevalidator/SurfacePixelValidator2.java b/tests/tests/view/surfacevalidator/src/android/view/cts/surfacevalidator/SurfacePixelValidator2.java
similarity index 98%
rename from tests/tests/view/src/android/view/cts/surfacevalidator/SurfacePixelValidator2.java
rename to tests/tests/view/surfacevalidator/src/android/view/cts/surfacevalidator/SurfacePixelValidator2.java
index 3dedf3b..88a8b17 100644
--- a/tests/tests/view/src/android/view/cts/surfacevalidator/SurfacePixelValidator2.java
+++ b/tests/tests/view/surfacevalidator/src/android/view/cts/surfacevalidator/SurfacePixelValidator2.java
@@ -122,7 +122,7 @@
// error, worth looking at...
Bitmap capture = Bitmap.wrapHardwareBuffer(
image.getHardwareBuffer(), null)
- .copy(Bitmap.Config.ARGB_8888, false);
+ .copy(Bitmap.Config.ARGB_8888, false);
mFirstFailures.put(totalFramesSeen, capture);
}
}
diff --git a/tests/tests/view/src/android/view/cts/surfacevalidator/ViewFactory.java b/tests/tests/view/surfacevalidator/src/android/view/cts/surfacevalidator/ViewFactory.java
similarity index 100%
rename from tests/tests/view/src/android/view/cts/surfacevalidator/ViewFactory.java
rename to tests/tests/view/surfacevalidator/src/android/view/cts/surfacevalidator/ViewFactory.java
diff --git a/tests/tests/widget/TEST_MAPPING b/tests/tests/widget/TEST_MAPPING
new file mode 100644
index 0000000..97625ed
--- /dev/null
+++ b/tests/tests/widget/TEST_MAPPING
@@ -0,0 +1,15 @@
+{
+ "presubmit": [
+ {
+ "name": "CtsWidgetTestCases",
+ "options": [
+ {
+ "instrumentation-arg": "size:=small"
+ },
+ {
+ "instrumentation-arg": "notAnnotation:=androidx.test.filters.FlakyTest"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/tests/tests/widget/src/android/widget/cts/MagnifierTest.java b/tests/tests/widget/src/android/widget/cts/MagnifierTest.java
index 9efdb58..62506c9b 100644
--- a/tests/tests/widget/src/android/widget/cts/MagnifierTest.java
+++ b/tests/tests/widget/src/android/widget/cts/MagnifierTest.java
@@ -25,14 +25,12 @@
import android.app.Activity;
import android.content.Context;
-import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Insets;
import android.graphics.Point;
import android.graphics.PointF;
-import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.util.DisplayMetrics;
@@ -75,12 +73,13 @@
private static final String TIME_LIMIT_EXCEEDED =
"Completing the magnifier operation took too long";
private static final float PIXEL_COMPARISON_DELTA = 1f;
+ private static final float WINDOW_ELEVATION = 10f;
private Activity mActivity;
private LinearLayout mLayout;
private View mView;
- private int[] mViewLocationInSurface;
private Magnifier mMagnifier;
+ private DisplayMetrics mDisplayMetrics;
@Rule
public ActivityTestRule<MagnifierCtsActivity> mActivityRule =
@@ -90,6 +89,8 @@
public void setup() throws Throwable {
mActivity = mActivityRule.getActivity();
PollingCheck.waitFor(mActivity::hasWindowFocus);
+
+ mDisplayMetrics = mActivity.getResources().getDisplayMetrics();
// Do not run the tests, unless the device screen is big enough to fit a magnifier
// having the default size.
assumeTrue(isScreenBigEnough());
@@ -98,18 +99,19 @@
mView = mActivity.findViewById(R.id.magnifier_centered_view);
WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mLayout, null);
- mViewLocationInSurface = new int[2];
- mView.getLocationInSurface(mViewLocationInSurface);
mMagnifier = new Magnifier.Builder(mView)
.setSize(mView.getWidth() / 2, mView.getHeight() / 2)
.build();
+ mActivityRule.runOnUiThread(() -> {
+ // Elevate the application window to have non-zero insets inside surface.
+ mActivityRule.getActivity().getWindow().setElevation(WINDOW_ELEVATION);
+ });
}
private boolean isScreenBigEnough() {
// Get the size of the screen in dp.
- final DisplayMetrics displayMetrics = mActivity.getResources().getDisplayMetrics();
- final float dpScreenWidth = displayMetrics.widthPixels / displayMetrics.density;
- final float dpScreenHeight = displayMetrics.heightPixels / displayMetrics.density;
+ final float dpScreenWidth = mDisplayMetrics.widthPixels / mDisplayMetrics.density;
+ final float dpScreenHeight = mDisplayMetrics.heightPixels / mDisplayMetrics.density;
// Get the size of the magnifier window in dp.
final PointF dpMagnifier = Magnifier.getMagnifierDefaultSize();
@@ -206,30 +208,29 @@
//***** Tests for default parameters *****//
+ private int dpToPixelSize(float dp) {
+ return (int) Math.ceil(dp * mDisplayMetrics.density);
+ }
+
+ private float dpToPixel(float dp) {
+ return dp * mDisplayMetrics.density;
+ }
+
@Test
public void testMagnifierDefaultParameters_withDeprecatedConstructor() {
final Magnifier magnifier = new Magnifier(mView);
- final Context context = mView.getContext();
- final TypedArray a = context.obtainStyledAttributes(
- null, com.android.internal.R.styleable.Magnifier,
- com.android.internal.R.attr.magnifierStyle, 0);
- final int width = a.getDimensionPixelSize(
- com.android.internal.R.styleable.Magnifier_magnifierWidth, 0);
+ final int width = dpToPixelSize(100f);
assertEquals(width, magnifier.getWidth());
- final int height = a.getDimensionPixelSize(
- com.android.internal.R.styleable.Magnifier_magnifierHeight, 0);
+ final int height = dpToPixelSize(48f);
assertEquals(height, magnifier.getHeight());
- final float elevation = a.getDimension(
- com.android.internal.R.styleable.Magnifier_magnifierElevation, 0f);
+ final float elevation = dpToPixel(4f);
assertEquals(elevation, magnifier.getElevation(), 0.01f);
- final float zoom = a.getFloat(com.android.internal.R.styleable.Magnifier_magnifierZoom, 0f);
+ final float zoom = 1.25f;
assertEquals(zoom, magnifier.getZoom(), 0.01f);
- final int verticalOffset = a.getDimensionPixelSize(
- com.android.internal.R.styleable.Magnifier_magnifierVerticalOffset, 0);
+ final int verticalOffset = dpToPixelSize(-42f);
assertEquals(verticalOffset, magnifier.getDefaultVerticalSourceToMagnifierOffset());
- final int horizontalOffset = a.getDimensionPixelSize(
- com.android.internal.R.styleable.Magnifier_magnifierHorizontalOffset, 0);
+ final int horizontalOffset = dpToPixelSize(0f);
assertEquals(horizontalOffset, magnifier.getDefaultHorizontalSourceToMagnifierOffset());
final Context deviceDefaultContext = new ContextThemeWrapper(mView.getContext(),
android.R.style.Theme_DeviceDefault);
@@ -240,9 +241,7 @@
assertEquals(dialogCornerRadius, magnifier.getCornerRadius(), 0.01f);
final boolean isClippingEnabled = true;
assertEquals(isClippingEnabled, magnifier.isClippingEnabled());
- final int overlayColor = a.getColor(
- com.android.internal.R.styleable.Magnifier_magnifierColorOverlay,
- Color.TRANSPARENT);
+ final int overlayColor = 0x0EFFFFFF;
assertEquals(overlayColor, ((ColorDrawable) magnifier.getOverlay()).getColor());
}
@@ -250,31 +249,23 @@
public void testMagnifierDefaultParameters_withBuilder() {
final Magnifier magnifier = new Magnifier.Builder(mView).build();
- final Resources resources = mView.getContext().getResources();
- final int width = resources.getDimensionPixelSize(
- com.android.internal.R.dimen.default_magnifier_width);
+ final int width = dpToPixelSize(100f);
assertEquals(width, magnifier.getWidth());
- final int height = resources.getDimensionPixelSize(
- com.android.internal.R.dimen.default_magnifier_height);
+ final int height = dpToPixelSize(48f);
assertEquals(height, magnifier.getHeight());
- final float elevation = resources.getDimension(
- com.android.internal.R.dimen.default_magnifier_elevation);
+ final float elevation = dpToPixel(4f);
assertEquals(elevation, magnifier.getElevation(), 0.01f);
- final float zoom = resources.getFloat(com.android.internal.R.dimen.default_magnifier_zoom);
+ final float zoom = 1.25f;
assertEquals(zoom, magnifier.getZoom(), 0.01f);
- final int verticalOffset = resources.getDimensionPixelSize(
- com.android.internal.R.dimen.default_magnifier_vertical_offset);
+ final int verticalOffset = dpToPixelSize(-42f);
assertEquals(verticalOffset, magnifier.getDefaultVerticalSourceToMagnifierOffset());
- final int horizontalOffset = resources.getDimensionPixelSize(
- com.android.internal.R.dimen.default_magnifier_horizontal_offset);
+ final int horizontalOffset = dpToPixelSize(0f);
assertEquals(horizontalOffset, magnifier.getDefaultHorizontalSourceToMagnifierOffset());
- final float dialogCornerRadius = resources.getDimension(
- com.android.internal.R.dimen.default_magnifier_corner_radius);
+ final float dialogCornerRadius = dpToPixel(2f);
assertEquals(dialogCornerRadius, magnifier.getCornerRadius(), 0.01f);
final boolean isClippingEnabled = true;
assertEquals(isClippingEnabled, magnifier.isClippingEnabled());
- final int overlayColor = resources.getColor(
- com.android.internal.R.color.default_magnifier_color_overlay, null);
+ final int overlayColor = 0x00FFFFFF;
assertEquals(overlayColor, ((ColorDrawable) magnifier.getOverlay()).getColor());
}
@@ -301,12 +292,15 @@
final float yCenter = mView.getHeight() / 2f;
showMagnifier(xCenter, yCenter);
+ final int[] viewLocationInWindow = new int[2];
+ mView.getLocationInWindow(viewLocationInWindow);
+
// Check the coordinates of the content being copied.
final Point sourcePosition = mMagnifier.getSourcePosition();
assertNotNull(sourcePosition);
- assertEquals(xCenter + mViewLocationInSurface[0],
+ assertEquals(xCenter + viewLocationInWindow[0],
sourcePosition.x + mMagnifier.getSourceWidth() / 2f, PIXEL_COMPARISON_DELTA);
- assertEquals(yCenter + mViewLocationInSurface[1],
+ assertEquals(yCenter + viewLocationInWindow[1],
sourcePosition.y + mMagnifier.getSourceHeight() / 2f, PIXEL_COMPARISON_DELTA);
// Check the coordinates of the magnifier.
@@ -337,13 +331,15 @@
final int yMagnifier = -10;
showMagnifier(xCenter, yCenter, xMagnifier, yMagnifier);
+ final int[] viewLocationInWindow = new int[2];
+ mView.getLocationInWindow(viewLocationInWindow);
final Point magnifierPosition = mMagnifier.getPosition();
assertNotNull(magnifierPosition);
assertEquals(
- mViewLocationInSurface[0] + xMagnifier - mMagnifier.getWidth() / 2,
+ viewLocationInWindow[0] + xMagnifier - mMagnifier.getWidth() / 2,
magnifierPosition.x, PIXEL_COMPARISON_DELTA);
assertEquals(
- mViewLocationInSurface[1] + yMagnifier - mMagnifier.getHeight() / 2,
+ viewLocationInWindow[1] + yMagnifier - mMagnifier.getHeight() / 2,
magnifierPosition.y, PIXEL_COMPARISON_DELTA);
}
@@ -422,13 +418,10 @@
// The window should have been positioned to the top left of the activity,
// such that it does not overlap system insets.
final Insets systemInsets = mLayout.getRootWindowInsets().getSystemWindowInsets();
- final Rect surfaceInsets = mLayout.getViewRootImpl().mWindowAttributes.surfaceInsets;
final Point magnifierCoords = mMagnifier.getPosition();
assertNotNull(magnifierCoords);
- assertEquals(systemInsets.left + surfaceInsets.left, magnifierCoords.x,
- PIXEL_COMPARISON_DELTA);
- assertEquals(systemInsets.top + surfaceInsets.top, magnifierCoords.y,
- PIXEL_COMPARISON_DELTA);
+ assertEquals(systemInsets.left, magnifierCoords.x, PIXEL_COMPARISON_DELTA);
+ assertEquals(systemInsets.top, magnifierCoords.y, PIXEL_COMPARISON_DELTA);
}
@Test
@@ -438,19 +431,18 @@
// Magnify the center of the activity in a magnifier outside bounds.
showMagnifier(mLayout.getWidth() / 2, mLayout.getHeight() / 2,
- mLayout.getViewRootImpl().getWidth() + mMagnifier.getWidth(),
- mLayout.getViewRootImpl().getHeight() + mMagnifier.getHeight());
+ mLayout.getRootView().getWidth() + mMagnifier.getWidth(),
+ mLayout.getRootView().getHeight() + mMagnifier.getHeight());
// The window should have been positioned to the bottom right of the activity.
final Insets systemInsets = mLayout.getRootWindowInsets().getSystemWindowInsets();
- final Rect surfaceInsets = mLayout.getViewRootImpl().mWindowAttributes.surfaceInsets;
final Point magnifierCoords = mMagnifier.getPosition();
assertNotNull(magnifierCoords);
- assertEquals(mLayout.getViewRootImpl().getWidth()
- - systemInsets.right - mMagnifier.getWidth() + surfaceInsets.left,
+ assertEquals(mLayout.getRootView().getWidth()
+ - systemInsets.right - mMagnifier.getWidth(),
magnifierCoords.x, PIXEL_COMPARISON_DELTA);
- assertEquals(mLayout.getViewRootImpl().getHeight()
- - systemInsets.bottom - mMagnifier.getHeight() + surfaceInsets.top,
+ assertEquals(mLayout.getRootView().getHeight()
+ - systemInsets.bottom - mMagnifier.getHeight(),
magnifierCoords.y, PIXEL_COMPARISON_DELTA);
}
@@ -468,7 +460,7 @@
// The window should have not been clamped.
final Point magnifierCoords = mMagnifier.getPosition();
final int[] magnifiedViewPosition = new int[2];
- mLayout.getLocationInSurface(magnifiedViewPosition);
+ mLayout.getLocationInWindow(magnifiedViewPosition);
assertNotNull(magnifierCoords);
assertEquals(magnifiedViewPosition[0] - 3 * mMagnifier.getWidth() / 2, magnifierCoords.x,
PIXEL_COMPARISON_DELTA);
@@ -487,17 +479,17 @@
// Magnify the center of the activity in a magnifier outside bounds.
showMagnifier(mLayout.getWidth() / 2, mLayout.getHeight() / 2,
- mLayout.getViewRootImpl().getWidth() + mMagnifier.getWidth(),
- mLayout.getViewRootImpl().getHeight() + mMagnifier.getHeight());
+ mLayout.getRootView().getWidth() + mMagnifier.getWidth(),
+ mLayout.getRootView().getHeight() + mMagnifier.getHeight());
// The window should have not been clamped.
final Point magnifierCoords = mMagnifier.getPosition();
final int[] magnifiedViewPosition = new int[2];
- mLayout.getLocationInSurface(magnifiedViewPosition);
+ mLayout.getLocationInWindow(magnifiedViewPosition);
assertNotNull(magnifierCoords);
- assertEquals(magnifiedViewPosition[0] + mLayout.getViewRootImpl().getWidth()
+ assertEquals(magnifiedViewPosition[0] + mLayout.getRootView().getWidth()
+ mMagnifier.getWidth() / 2, magnifierCoords.x, PIXEL_COMPARISON_DELTA);
- assertEquals(magnifiedViewPosition[1] + mLayout.getViewRootImpl().getHeight()
+ assertEquals(magnifiedViewPosition[1] + mLayout.getRootView().getHeight()
+ mMagnifier.getHeight() / 2, magnifierCoords.y, PIXEL_COMPARISON_DELTA);
}
@@ -587,7 +579,7 @@
});
final int[] containerPosition = new int[2];
- container.getLocationInSurface(containerPosition);
+ container.getLocationInWindow(containerPosition);
// Try to copy from an x to the left of the currently visible region.
showMagnifier(view.getWidth() / 4, 0);
@@ -629,7 +621,7 @@
});
final int[] containerPosition = new int[2];
- container.getLocationInSurface(containerPosition);
+ container.getLocationInWindow(containerPosition);
// Try to copy from an y above the currently visible region.
showMagnifier(0, view.getHeight() / 4);
@@ -664,7 +656,7 @@
runOnUiThreadAndWaitForCompletion(() -> mMagnifier = builder.build());
final int[] viewPosition = new int[2];
- view.getLocationInSurface(viewPosition);
+ view.getLocationInWindow(viewPosition);
// Copy content centered on relative position (0, 0) and expect the top left
// corner of the source NOT to have been pulled to coincide with (0, 0) of the view.
@@ -686,29 +678,30 @@
assertEquals(viewPosition[1] + view.getHeight() - mMagnifier.getSourceHeight() / 2,
sourcePosition.y, PIXEL_COMPARISON_DELTA);
+ final int[] viewPositionInSurface = new int[2];
+ view.getLocationInSurface(viewPositionInSurface);
// Copy content centered on the top left corner of the main app surface and expect the top
// left corner of the source to have been pulled to the top left corner of the surface.
- showMagnifier(-viewPosition[0], -viewPosition[1]);
+ showMagnifier(-viewPositionInSurface[0], -viewPositionInSurface[1]);
sourcePosition = mMagnifier.getSourcePosition();
assertNotNull(sourcePosition);
- assertEquals(0, sourcePosition.x, PIXEL_COMPARISON_DELTA);
- assertEquals(0, sourcePosition.y, PIXEL_COMPARISON_DELTA);
+ assertEquals(0, sourcePosition.x - viewPosition[0] + viewPositionInSurface[0],
+ PIXEL_COMPARISON_DELTA);
+ assertEquals(0, sourcePosition.y - viewPosition[1] + viewPositionInSurface[1],
+ PIXEL_COMPARISON_DELTA);
- // Copy content centered on the bottom right corner of the main app surface and expect the
- // source to have been pulled inside the surface at its bottom right.
- final Rect surfaceInsets = view.getViewRootImpl().mWindowAttributes.surfaceInsets;
- final int surfaceWidth = view.getViewRootImpl().getWidth() + surfaceInsets.left
- + surfaceInsets.right;
- final int surfaceHeight = view.getViewRootImpl().getHeight() + surfaceInsets.top
- + surfaceInsets.bottom;
- showMagnifier(surfaceWidth - viewPosition[0] + view.getWidth(),
- surfaceHeight - viewPosition[1] + view.getHeight());
+ // Copy content below and to the right of the bottom right corner of the main app surface
+ // and expect the source to have been pulled inside the surface at its bottom right.
+ showMagnifier(2 * view.getRootView().getWidth(), 2 * view.getRootView().getHeight());
sourcePosition = mMagnifier.getSourcePosition();
assertNotNull(sourcePosition);
- assertEquals(surfaceWidth - mMagnifier.getSourceWidth(), sourcePosition.x,
- PIXEL_COMPARISON_DELTA);
- assertEquals(surfaceHeight - mMagnifier.getSourceHeight(), sourcePosition.y,
- PIXEL_COMPARISON_DELTA);
+ assertTrue(
+ sourcePosition.x < 2 * view.getRootView().getWidth() - mMagnifier.getSourceWidth());
+ assertTrue(sourcePosition.x > view.getRootView().getWidth() - mMagnifier.getSourceWidth());
+ assertTrue(sourcePosition.y
+ < 2 * view.getRootView().getHeight() - mMagnifier.getSourceHeight());
+ assertTrue(sourcePosition.y
+ > view.getRootView().getHeight() - mMagnifier.getSourceHeight());
}
@Test
@@ -777,7 +770,7 @@
runOnUiThreadAndWaitForCompletion(() -> mMagnifier = builder.build());
final int[] viewPosition = new int[2];
- view.getLocationInSurface(viewPosition);
+ view.getLocationInWindow(viewPosition);
// Make sure that the left and top bounds are respected, since this is possible
// for this source size, when the view is centered.
@@ -794,7 +787,7 @@
layout.setGravity(Gravity.TOP | Gravity.LEFT);
});
WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, view, null);
- view.getLocationInSurface(viewPosition);
+ view.getLocationInWindow(viewPosition);
showMagnifier(0, 0);
sourcePosition = mMagnifier.getSourcePosition();
diff --git a/tests/tests/widget/src/android/widget/cts/TextViewTest.java b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
index ddcee27..eba4fcd 100644
--- a/tests/tests/widget/src/android/widget/cts/TextViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
@@ -898,7 +898,7 @@
public void testAccessPaintFlags() {
mTextView = new TextView(mActivity);
assertEquals(Paint.DEV_KERN_TEXT_FLAG | Paint.EMBEDDED_BITMAP_TEXT_FLAG
- | Paint.ANTI_ALIAS_FLAG, mTextView.getPaintFlags());
+ | Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG, mTextView.getPaintFlags());
mTextView.setPaintFlags(Paint.UNDERLINE_TEXT_FLAG | Paint.FAKE_BOLD_TEXT_FLAG);
assertEquals(Paint.UNDERLINE_TEXT_FLAG | Paint.FAKE_BOLD_TEXT_FLAG,
diff --git a/tests/video/OWNERS b/tests/video/OWNERS
new file mode 100644
index 0000000..ecaa5dd
--- /dev/null
+++ b/tests/video/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 1344
+include platform/frameworks/av:/media/OWNERS
\ No newline at end of file
diff --git a/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiClass.java b/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiClass.java
index 9eeb907..5870a91 100644
--- a/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiClass.java
+++ b/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiClass.java
@@ -19,7 +19,10 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
/** Representation of a class in the API with constructors and methods. */
class ApiClass implements Comparable<ApiClass>, HasCoverage {
@@ -40,6 +43,8 @@
private ApiClass mSuperClass;
+ private Map<String, ApiClass> mInterfaceMap = new HashMap<String, ApiClass>();
+
/**
* @param name The name of the class
* @param deprecated true iff the class is marked as deprecated
@@ -81,11 +86,22 @@
public void setSuperClass(ApiClass superClass) { mSuperClass = superClass; }
+ public void addInterface(String interfaceName) {
+ mInterfaceMap.put(interfaceName, null);
+ }
+
+ public void resolveInterface(String interfaceName, ApiClass apiInterface) {
+ mInterfaceMap.replace(interfaceName, apiInterface);
+ }
+
+ public Set<String> getInterfaceNames() {
+ return mInterfaceMap.keySet();
+ }
+
public void addConstructor(ApiConstructor constructor) {
mApiConstructors.add(constructor);
}
-
public Collection<ApiConstructor> getConstructors() {
return Collections.unmodifiableList(mApiConstructors);
}
@@ -114,6 +130,15 @@
// Mark matching methods in the super class
mSuperClass.markMethodCovered(name, parameterTypes, returnType, coveredbyApk);
}
+ if (!mInterfaceMap.isEmpty()) {
+ // Mark matching methods in the interfaces
+ for (String interfaceName : mInterfaceMap.keySet()) {
+ ApiClass mInterface = mInterfaceMap.get(interfaceName);
+ if (mInterface != null) {
+ mInterface.markMethodCovered(name, parameterTypes, returnType, coveredbyApk);
+ }
+ }
+ }
ApiMethod apiMethod = getMethod(name, parameterTypes, returnType);
if (apiMethod != null) {
apiMethod.setCovered(coveredbyApk);
diff --git a/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiPackage.java b/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiPackage.java
index 7be7e3c..e242355 100644
--- a/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiPackage.java
+++ b/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiPackage.java
@@ -98,6 +98,20 @@
}
}
}
+ for (String interfaceName : apiClass.getInterfaceNames()) {
+ // Split the fully qualified interface name into package and interface name.
+ String packageName = interfaceName.substring(0, interfaceName.lastIndexOf('.'));
+ String className = interfaceName.substring(
+ interfaceName.lastIndexOf('.') + 1, interfaceName.length());
+ if (packageMap.containsKey(packageName)) {
+ ApiPackage apiPackage = packageMap.get(packageName);
+ ApiClass apiInterface = apiPackage.getClass(className);
+ if (apiInterface != null) {
+ // Add the interface
+ apiClass.resolveInterface(interfaceName, apiInterface);
+ }
+ }
+ }
}
}
}
diff --git a/tools/cts-api-coverage/src/com/android/cts/apicoverage/CurrentXmlHandler.java b/tools/cts-api-coverage/src/com/android/cts/apicoverage/CurrentXmlHandler.java
index de9f5d5..de96063 100644
--- a/tools/cts-api-coverage/src/com/android/cts/apicoverage/CurrentXmlHandler.java
+++ b/tools/cts-api-coverage/src/com/android/cts/apicoverage/CurrentXmlHandler.java
@@ -32,6 +32,8 @@
private String mCurrentClassName;
+ private String mCurrentInterfaceName;
+
private boolean mIgnoreCurrentClass;
private String mCurrentMethodName;
@@ -67,7 +69,8 @@
ApiPackage apiPackage = new ApiPackage(mCurrentPackageName);
mApiCoverage.addPackage(apiPackage);
- } else if ("class".equalsIgnoreCase(localName)) {
+ } else if ("class".equalsIgnoreCase(localName) ||
+ "interface".equalsIgnoreCase(localName)) {
if (isEnum(attributes)) {
mIgnoreCurrentClass = true;
return;
@@ -80,9 +83,8 @@
mCurrentClassName, mDeprecated, is(attributes, "abstract"), superClass);
ApiPackage apiPackage = mApiCoverage.getPackage(mCurrentPackageName);
apiPackage.addClass(apiClass);
- } else if ("interface".equalsIgnoreCase(localName)) {
- // don't add interface
- mIgnoreCurrentClass = true;
+ } else if ("implements".equalsIgnoreCase(localName)) {
+ mCurrentInterfaceName = attributes.getValue("name");
} else if ("constructor".equalsIgnoreCase(localName)) {
mDeprecated = isDeprecated(attributes);
mCurrentParameterTypes.clear();
@@ -104,20 +106,20 @@
public void endElement(String uri, String localName, String name) throws SAXException {
super.endElement(uri, localName, name);
if (mIgnoreCurrentClass) {
- // do not add anything for interface
+ // do not add anything for enum
return;
}
if ("constructor".equalsIgnoreCase(localName)) {
- if (mCurrentParameterTypes.isEmpty()) {
- // Don't add empty default constructors...
- return;
- }
ApiConstructor apiConstructor = new ApiConstructor(mCurrentClassName,
mCurrentParameterTypes, mDeprecated);
ApiPackage apiPackage = mApiCoverage.getPackage(mCurrentPackageName);
ApiClass apiClass = apiPackage.getClass(mCurrentClassName);
apiClass.addConstructor(apiConstructor);
- } else if ("method".equalsIgnoreCase(localName)) {
+ } else if ("implements".equalsIgnoreCase(localName)) {
+ ApiPackage apiPackage = mApiCoverage.getPackage(mCurrentPackageName);
+ ApiClass apiClass = apiPackage.getClass(mCurrentClassName);
+ apiClass.addInterface(mCurrentInterfaceName);
+ } else if ("method".equalsIgnoreCase(localName)) {
ApiMethod apiMethod = new ApiMethod(
mCurrentMethodName,
mCurrentParameterTypes,