Merge "EDI: Add feature version to FeatureDeviceInfo" into nyc-dev
diff --git a/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py b/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
index 7733c5d..a5fc819 100644
--- a/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
+++ b/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
@@ -68,7 +68,7 @@
# Todo: test for radial distortion enabled devices has not yet been
# implemented
its.caps.skip_unless(not its.caps.radial_distortion_correction(props))
- full_device = its.caps.full(props)
+ full_device = its.caps.full_or_better(props)
limited_device = its.caps.limited(props)
its.caps.skip_unless(full_device or limited_device)
level3_device = its.caps.level3(props)
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hcef/HceFEmulatorActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hcef/HceFEmulatorActivity.java
index 89f040b..7118ae3 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hcef/HceFEmulatorActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hcef/HceFEmulatorActivity.java
@@ -61,7 +61,7 @@
registerReceiver(mReceiver, filter);
ComponentName hceFService = new ComponentName("com.android.cts.verifier",
MyHostFelicaService.class.getName());
- mNfcFCardEmulation.enableNfcFForegroundService(this, hceFService);
+ mNfcFCardEmulation.enableService(this, hceFService);
}
@Override
diff --git a/tests/tests/shortcutmanager/packages/packagemanifest_nonshared/Android.mk b/hostsidetests/compilation/Android.mk
similarity index 65%
copy from tests/tests/shortcutmanager/packages/packagemanifest_nonshared/Android.mk
copy to hostsidetests/compilation/Android.mk
index 4aebb74..40077f0 100644
--- a/tests/tests/shortcutmanager/packages/packagemanifest_nonshared/Android.mk
+++ b/hostsidetests/compilation/Android.mk
@@ -12,23 +12,21 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-LOCAL_PATH:= $(call my-dir)
+LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := CtsShortcutManagerLauncher4
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, ../src)
-
-LOCAL_SDK_VERSION := current
+LOCAL_MODULE_TAGS := tests
# tag this module as a cts test artifact
LOCAL_COMPATIBILITY_SUITE := cts
-LOCAL_AAPT_FLAGS += --rename-manifest-package android.content.pm.cts.shortcutmanager.packages.launcher4
+LOCAL_MODULE := CtsCompilationTestCases
-include $(BUILD_CTS_PACKAGE)
+LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt compatibility-host-util
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/compilation/AndroidTest.xml b/hostsidetests/compilation/AndroidTest.xml
new file mode 100644
index 0000000..4e5b0bd
--- /dev/null
+++ b/hostsidetests/compilation/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<configuration description="Config for CTS Compilation Test">
+ <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+ <option name="cleanup-apks" value="true" />
+ <option name="test-file-name" value="CtsCompilationApp.apk" />
+ </target_preparer>
+ <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
+ <option name="jar" value="CtsCompilationTestCases.jar" />
+ </test>
+</configuration>
diff --git a/tests/tests/shortcutmanager/packages/packagemanifest_nonshared/Android.mk b/hostsidetests/compilation/app/Android.mk
similarity index 70%
rename from tests/tests/shortcutmanager/packages/packagemanifest_nonshared/Android.mk
rename to hostsidetests/compilation/app/Android.mk
index 4aebb74..5bcf108 100644
--- a/tests/tests/shortcutmanager/packages/packagemanifest_nonshared/Android.mk
+++ b/hostsidetests/compilation/app/Android.mk
@@ -16,19 +16,16 @@
include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := CtsShortcutManagerLauncher4
+# Don't include this package in any target.
+LOCAL_MODULE_TAGS := tests
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, ../src)
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_SDK_VERSION := current
+LOCAL_PACKAGE_NAME := CtsCompilationApp
+
# tag this module as a cts test artifact
LOCAL_COMPATIBILITY_SUITE := cts
-LOCAL_AAPT_FLAGS += --rename-manifest-package android.content.pm.cts.shortcutmanager.packages.launcher4
-
-include $(BUILD_CTS_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/tests/shortcutmanager/packages/launchermanifest_nonshared/AndroidManifest.xml b/hostsidetests/compilation/app/AndroidManifest.xml
similarity index 79%
rename from tests/tests/shortcutmanager/packages/launchermanifest_nonshared/AndroidManifest.xml
rename to hostsidetests/compilation/app/AndroidManifest.xml
index 9808da4..99b13b2 100755
--- a/tests/tests/shortcutmanager/packages/launchermanifest_nonshared/AndroidManifest.xml
+++ b/hostsidetests/compilation/app/AndroidManifest.xml
@@ -16,17 +16,16 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.content.pm.cts.shortcutmanager.packages">
+ package="android.cts.compilation">
<application>
- <activity android:name="Launcher">
+ <activity android:name=".CompilationTargetActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.LAUNCHER" />
- <category android:name="android.intent.category.HOME" />
</intent-filter>
</activity>
</application>
+
</manifest>
diff --git a/tests/tests/shortcutmanager/packages/src/android/content/pm/cts/shortcutmanager/packages/Launcher.java b/hostsidetests/compilation/app/src/android/cts/compilation/CompilationTargetActivity.java
similarity index 66%
rename from tests/tests/shortcutmanager/packages/src/android/content/pm/cts/shortcutmanager/packages/Launcher.java
rename to hostsidetests/compilation/app/src/android/cts/compilation/CompilationTargetActivity.java
index 88db59a..37bbdab 100644
--- a/tests/tests/shortcutmanager/packages/src/android/content/pm/cts/shortcutmanager/packages/Launcher.java
+++ b/hostsidetests/compilation/app/src/android/cts/compilation/CompilationTargetActivity.java
@@ -13,9 +13,22 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.content.pm.cts.shortcutmanager.packages;
+
+package android.cts.compilation;
import android.app.Activity;
+import android.os.Bundle;
-public class Launcher extends Activity {
+import java.lang.Override;
+
+/**
+ * A simple activity which can be subjected to (dex to native) compilation.
+ */
+public class CompilationTargetActivity extends Activity {
+
+ @Override
+ public void onCreate(Bundle bundle) {
+ super.onCreate(bundle);
+ }
+
}
diff --git a/hostsidetests/compilation/src/android/cts/compilation/CompilationTest.java b/hostsidetests/compilation/src/android/cts/compilation/CompilationTest.java
new file mode 100644
index 0000000..3e673ea
--- /dev/null
+++ b/hostsidetests/compilation/src/android/cts/compilation/CompilationTest.java
@@ -0,0 +1,109 @@
+/*
+ * 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.cts.compilation;
+
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceTestCase;
+
+import java.util.Arrays;
+import java.util.Locale;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class CompilationTest extends DeviceTestCase {
+ private static final String APPLICATION_PACKAGE = "android.cts.compilation";
+
+ private ITestDevice mDevice;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mDevice = getDevice();
+ mDevice.executeAdbCommand("root");
+ }
+
+ /**
+ * Tests the case where no profile is available because the app has never run.
+ */
+ public void testForceCompile_noProfileAvailable() throws Exception {
+ String stdoutContents = mDevice.executeAdbCommand("shell", "cmd", "package", "compile",
+ "-m", "speed-profile", "-f", APPLICATION_PACKAGE);
+ assertEquals("Success\n", stdoutContents);
+
+ // Find location of the base.odex file
+ String odexFilePath = getOdexFilePath();
+
+ // Confirm the compiler-filter used in creating the odex file
+ String compilerFilter = getCompilerFilter(odexFilePath);
+
+ assertEquals("compiler-filter", "speed-profile", compilerFilter);
+ }
+
+ /**
+ * Parses the value for the key "compiler-filter" out of the output from
+ * {@code oatdump --header-only}.
+ */
+ private String getCompilerFilter(String odexFilePath) throws DeviceNotAvailableException {
+ String[] response = executeAdbCommand(
+ "shell", "oatdump", "--header-only", "--oat-file=" + odexFilePath);
+ String prefix = "compiler-filter =";
+ for (String line : response) {
+ line = line.trim();
+ if (line.startsWith(prefix)) {
+ return line.substring(prefix.length()).trim();
+ }
+ }
+ fail("No occurence of \"" + prefix + "\" in: " + Arrays.toString(response));
+ return null;
+ }
+
+ /**
+ * Returns the path to the application's base.odex file that should have
+ * been created by the compiler.
+ */
+ private String getOdexFilePath() throws DeviceNotAvailableException {
+ // Something like "package:/data/app/android.cts.compilation-1/base.apk"
+ String pathSpec = executeAdbCommand(1, "shell", "pm", "path", APPLICATION_PACKAGE)[0];
+ Matcher matcher = Pattern.compile("^package:(.+/)base\\.apk$").matcher(pathSpec);
+ boolean found = matcher.find();
+ assertTrue("Malformed spec: " + pathSpec, found);
+ String apkDir = matcher.group(1);
+ // E.g. /data/app/android.cts.compilation-1/oat/arm64/base.odex
+ String result = executeAdbCommand(1, "shell", "find", apkDir, "-name", "base.odex")[0];
+ assertTrue("odex file not found: " + result, mDevice.doesFileExist(result));
+ return result;
+ }
+
+ private String[] executeAdbCommand(int numLinesOutputExpected, String... command)
+ throws DeviceNotAvailableException {
+ String[] lines = executeAdbCommand(command);
+ assertEquals(
+ String.format(Locale.US, "Expected %d lines output, got %d running %s: %s",
+ numLinesOutputExpected, lines.length, Arrays.toString(command),
+ Arrays.toString(lines)),
+ numLinesOutputExpected, lines.length);
+ return lines;
+ }
+
+ private String[] executeAdbCommand(String... command) throws DeviceNotAvailableException {
+ String output = mDevice.executeAdbCommand(command);
+ // "".split() returns { "" }, but we want an empty array
+ String[] lines = output.equals("") ? new String[0] : output.split("\n");
+ return lines;
+ }
+}
diff --git a/hostsidetests/devicepolicy/app/WidgetProvider/src/com/android/cts/widgetprovider/SimpleAppWidgetHostService.java b/hostsidetests/devicepolicy/app/WidgetProvider/src/com/android/cts/widgetprovider/SimpleAppWidgetHostService.java
index b5b6003..6b9a2af 100644
--- a/hostsidetests/devicepolicy/app/WidgetProvider/src/com/android/cts/widgetprovider/SimpleAppWidgetHostService.java
+++ b/hostsidetests/devicepolicy/app/WidgetProvider/src/com/android/cts/widgetprovider/SimpleAppWidgetHostService.java
@@ -31,6 +31,7 @@
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
+import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Log;
@@ -58,6 +59,8 @@
private static final int RESULT_INTERRUPTED = 3;
private static final int RESULT_TIMEOUT = 4;
+ private static final long GET_PROVIDER_TIMEOUT_MILLIS = 30 * 1000; // 30 seconds
+
public static final String USER_EXTRA = "user-extra";
public static final String PACKAGE_EXTRA = "package-extra";
public static final String REPLY_EXTRA = "reply-extra";
@@ -213,8 +216,10 @@
}
public AppWidgetProviderInfo getProvider(Bundle params) throws InterruptedException {
+ final long startTime = SystemClock.elapsedRealtime();
+ long nextTimeout = GET_PROVIDER_TIMEOUT_MILLIS;
String packageName = params.getString(PACKAGE_EXTRA);
- while (mSemaphore.tryAcquire(30, TimeUnit.SECONDS)) {
+ while ((nextTimeout > 0) && mSemaphore.tryAcquire(nextTimeout, TimeUnit.MILLISECONDS)) {
mSemaphore.drainPermits();
Log.d(TAG, "checking for " + packageName + " " + mUserHandle);
synchronized (this) {
@@ -225,6 +230,8 @@
return providerInfo;
}
}
+ nextTimeout = startTime + GET_PROVIDER_TIMEOUT_MILLIS
+ - SystemClock.elapsedRealtime();
}
}
return null;
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
index 3ee2f68..f2a69f2 100644
--- a/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
@@ -176,34 +176,90 @@
assertNetworkAccess(true);
}
+ protected void assertForegroundServiceNetworkAccess() throws Exception {
+ assertForegroundServiceState(); // Sanity check.
+ assertNetworkAccess(true);
+ }
+
+ /**
+ * Asserts that an app always have access while on foreground or running a foreground service.
+ *
+ * <p>This method will launch an activity and a foreground service to make the assertion, but
+ * will finish the activity / stop the service afterwards.
+ */
+ protected void assertsForegroundAlwaysHasNetworkAccess() throws Exception{
+ // Checks foreground first.
+ launchActivity();
+ assertForegroundNetworkAccess();
+ finishActivity();
+
+ // Then foreground service
+ startForegroundService();
+ assertForegroundServiceNetworkAccess();
+ stopForegroundService();
+ }
+
protected final void assertBackgroundState() throws Exception {
- final ProcessState state = getProcessStateByUid(mUid);
- Log.v(TAG, "assertBackgroundState(): status for app2 (" + mUid + "): " + state);
- final boolean isBackground = isBackground(state.state);
- assertTrue("App2 is not on background state: " + state, isBackground);
+ final int maxTries = 30;
+ ProcessState state = null;
+ for (int i = 1; i <= maxTries; i++) {
+ state = getProcessStateByUid(mUid);
+ Log.v(TAG, "assertBackgroundState(): status for app2 (" + mUid + ") on attempt #" + i
+ + ": " + state);
+ if (isBackground(state.state)) {
+ return;
+ }
+ Log.d(TAG, "App not on background state on attempt #" + i
+ + "; sleeping 1s before trying again");
+ Thread.sleep(SECOND_IN_MS);
+ }
+ fail("App2 is not on background state after " + maxTries + " attempts: " + state );
}
protected final void assertForegroundState() throws Exception {
- final ProcessState state = getProcessStateByUid(mUid);
- Log.v(TAG, "assertForegroundState(): status for app2 (" + mUid + "): " + state);
- final boolean isForeground = !isBackground(state.state);
- assertTrue("App2 is not on foreground state: " + state, isForeground);
+ final int maxTries = 30;
+ ProcessState state = null;
+ for (int i = 1; i <= maxTries; i++) {
+ state = getProcessStateByUid(mUid);
+ Log.v(TAG, "assertForegroundState(): status for app2 (" + mUid + ") on attempt #" + i
+ + ": " + state);
+ if (!isBackground(state.state)) {
+ return;
+ }
+ Log.d(TAG, "App not on foreground state on attempt #" + i
+ + "; sleeping 1s before trying again");
+ Thread.sleep(SECOND_IN_MS);
+ }
+ fail("App2 is not on foreground state after " + maxTries + " attempts: " + state );
}
protected final void assertForegroundServiceState() throws Exception {
- final ProcessState state = getProcessStateByUid(mUid);
- Log.v(TAG, "assertForegroundServiceState(): status for app2 (" + mUid + "): " + state);
- assertEquals("App2 is not on foreground service state: " + state,
- PROCESS_STATE_FOREGROUND_SERVICE, state.state);
+ final int maxTries = 30;
+ ProcessState state = null;
+ for (int i = 1; i <= maxTries; i++) {
+ state = getProcessStateByUid(mUid);
+ Log.v(TAG, "assertForegroundServiceState(): status for app2 (" + mUid + ") on attempt #"
+ + i + ": " + state);
+ if (state.state == PROCESS_STATE_FOREGROUND_SERVICE) {
+ return;
+ }
+ Log.d(TAG, "App not on foreground service state on attempt #" + i
+ + "; sleeping 1s before trying again");
+ Thread.sleep(SECOND_IN_MS);
+ }
+ fail("App2 is not on foreground service state after " + maxTries + " attempts: " + state );
}
/**
* Returns whether an app state should be considered "background" for restriction purposes.
*/
protected boolean isBackground(int state) {
- return state >= PROCESS_STATE_FOREGROUND_SERVICE;
+ return state > PROCESS_STATE_FOREGROUND_SERVICE;
}
+ /**
+ * Asserts whether the active network is available or not.
+ */
private void assertNetworkAccess(boolean expectAvailable) throws Exception {
final Intent intent = new Intent(ACTION_CHECK_NETWORK);
@@ -495,13 +551,27 @@
"am startservice com.android.cts.net.hostside.app2/.MyForegroundService");
}
+ protected void stopForegroundService() throws Exception {
+ executeShellCommand(
+ "am stopservice com.android.cts.net.hostside.app2/.MyForegroundService");
+ }
+
/**
* Launches an activity on app2 so its process is elevated to foreground status.
*/
- protected void launchApp2Activity() throws Exception {
+ protected void launchActivity() throws Exception {
executeShellCommand("am start com.android.cts.net.hostside.app2/.MyActivity");
}
+ /**
+ * Finishes an activity on app2 so its process is demoted fromforeground status.
+ */
+ protected void finishActivity() throws Exception {
+ executeShellCommand("am broadcast -a "
+ + " com.android.cts.net.hostside.app2.action.FINISH_ACTIVITY "
+ + "--receiver-foreground --receiver-registered-only");
+ }
+
private String toString(int status) {
switch (status) {
case RESTRICT_BACKGROUND_STATUS_DISABLED:
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java
index 5f5f80b..d1db01c 100644
--- a/hostsidetests/net/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java
@@ -23,8 +23,10 @@
public void setUp() throws Exception {
super.setUp();
+ // Set initial state.
+ removePowerSaveModeWhitelist(TEST_APP2_PKG);
setPowerSaveMode(false);
- assertPowerSaveModeWhitelist(TEST_APP2_PKG, false); // Sanity check
+
registerBroadcastReceiver();
}
@@ -39,35 +41,46 @@
setPowerSaveMode(true);
assertBackgroundNetworkAccess(false);
- // Make sure app is allowed if running a foreground service.
- startForegroundService();
- assertForegroundServiceState();
- assertBackgroundNetworkAccess(true);
+ assertsForegroundAlwaysHasNetworkAccess();
+ assertBackgroundNetworkAccess(false);
- // Should always have access when running on foreground
- launchApp2Activity();
+ // Make sure foreground app doesn't lose access upon enabling it.
+ setPowerSaveMode(false);
+ launchActivity();
assertForegroundNetworkAccess();
+ setPowerSaveMode(true);
+ assertForegroundNetworkAccess();
+ finishActivity();
+ assertBackgroundNetworkAccess(false);
+
+ // Same for foreground service.
+ setPowerSaveMode(false);
+ startForegroundService();
+ assertForegroundNetworkAccess();
+ setPowerSaveMode(true);
+ assertForegroundNetworkAccess();
+ stopForegroundService();
+ assertBackgroundNetworkAccess(false);
}
public void testBackgroundNetworkAccess_whitelisted() throws Exception {
setPowerSaveMode(true);
assertBackgroundNetworkAccess(false);
+
addPowerSaveModeWhitelist(TEST_APP2_PKG);
assertBackgroundNetworkAccess(true);
+
removePowerSaveModeWhitelist(TEST_APP2_PKG);
assertBackgroundNetworkAccess(false);
- // Should always have access when running on foreground
- launchApp2Activity();
- assertForegroundNetworkAccess();
+ assertsForegroundAlwaysHasNetworkAccess();
+ assertBackgroundNetworkAccess(false);
}
public void testBackgroundNetworkAccess_disabled() throws Exception {
- setPowerSaveMode(false);
assertBackgroundNetworkAccess(true);
- // Should always have access when running on foreground
- launchApp2Activity();
- assertForegroundNetworkAccess();
+ assertsForegroundAlwaysHasNetworkAccess();
+ assertBackgroundNetworkAccess(true);
}
}
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java
index 539c598..22b876a 100644
--- a/hostsidetests/net/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java
@@ -23,9 +23,11 @@
public void setUp() throws Exception {
super.setUp();
+ // Set initial state.
setMeteredNetwork();
+ removePowerSaveModeWhitelist(TEST_APP2_PKG);
setPowerSaveMode(false);
- assertPowerSaveModeWhitelist(TEST_APP2_PKG, false); // Sanity check
+
registerBroadcastReceiver();
}
@@ -42,38 +44,48 @@
public void testBackgroundNetworkAccess_enabled() throws Exception {
setPowerSaveMode(true);
-
assertBackgroundNetworkAccess(false);
- // Make sure app is allowed if running a foreground service.
- startForegroundService();
- assertForegroundServiceState();
- assertBackgroundNetworkAccess(true);
+ assertsForegroundAlwaysHasNetworkAccess();
+ assertBackgroundNetworkAccess(false);
- // Should always have access when running on foreground
- launchApp2Activity();
+ // Make sure foreground app doesn't lose access upon enabling it.
+ setPowerSaveMode(false);
+ launchActivity();
assertForegroundNetworkAccess();
+ setPowerSaveMode(true);
+ assertForegroundNetworkAccess();
+ finishActivity();
+ assertBackgroundNetworkAccess(false);
+
+ // Same for foreground service.
+ setPowerSaveMode(false);
+ startForegroundService();
+ assertForegroundNetworkAccess();
+ setPowerSaveMode(true);
+ assertForegroundNetworkAccess();
+ stopForegroundService();
+ assertBackgroundNetworkAccess(false);
}
public void testBackgroundNetworkAccess_whitelisted() throws Exception {
setPowerSaveMode(true);
assertBackgroundNetworkAccess(false);
+
addPowerSaveModeWhitelist(TEST_APP2_PKG);
assertBackgroundNetworkAccess(true);
+
removePowerSaveModeWhitelist(TEST_APP2_PKG);
assertBackgroundNetworkAccess(false);
- // Should always have access when running on foreground
- launchApp2Activity();
- assertForegroundNetworkAccess();
+ assertsForegroundAlwaysHasNetworkAccess();
+ assertBackgroundNetworkAccess(false);
}
public void testBackgroundNetworkAccess_disabled() throws Exception {
- setPowerSaveMode(false);
assertBackgroundNetworkAccess(true);
- // Should always have access when running on foreground
- launchApp2Activity();
- assertForegroundNetworkAccess();
+ assertsForegroundAlwaysHasNetworkAccess();
+ assertBackgroundNetworkAccess(true);
}
}
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/DataSaverModeTest.java
index 0971770..1895156 100644
--- a/hostsidetests/net/app/src/com/android/cts/net/hostside/DataSaverModeTest.java
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/DataSaverModeTest.java
@@ -20,15 +20,6 @@
import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED;
import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED;
-/*
- * TODO: need to add more scenarios:
- * - test access on foreground app
- * - test access on foreground service app
- * - make sure it works when app is on foreground and state is transitioned:
- * - data saver is enabled
- * - app is added/removed to blacklist
- *
- */
public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase {
private static final String[] REQUIRED_WHITELISTED_PACKAGES = {
@@ -39,9 +30,14 @@
public void setUp() throws Exception {
super.setUp();
+ // Set initial state.
setMeteredNetwork();
setRestrictBackground(false);
+ removeRestrictBackgroundWhitelist(mUid);
+ removeRestrictBackgroundBlacklist(mUid);
+
registerBroadcastReceiver();
+ assertRestrictBackgroundChangedReceived(0);
}
@Override
@@ -56,8 +52,6 @@
}
public void testGetRestrictBackgroundStatus_disabled() throws Exception {
- removeRestrictBackgroundWhitelist(mUid);
- assertRestrictBackgroundChangedReceived(0);
assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_DISABLED);
// Sanity check: make sure status is always disabled, never whitelisted
@@ -65,14 +59,14 @@
assertRestrictBackgroundChangedReceived(0);
assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_DISABLED);
- // Should always have access when running on foreground
- launchApp2Activity();
- assertForegroundNetworkAccess();
+ assertsForegroundAlwaysHasNetworkAccess();
+ assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_DISABLED);
}
public void testGetRestrictBackgroundStatus_whitelisted() throws Exception {
setRestrictBackground(true);
assertRestrictBackgroundChangedReceived(1);
+ assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED);
addRestrictBackgroundWhitelist(mUid);
assertRestrictBackgroundChangedReceived(2);
@@ -80,11 +74,10 @@
removeRestrictBackgroundWhitelist(mUid);
assertRestrictBackgroundChangedReceived(3);
- assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_ENABLED);
+ assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED);
- // Should always have access when running on foreground
- launchApp2Activity();
- assertForegroundNetworkAccess();
+ assertsForegroundAlwaysHasNetworkAccess();
+ assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED);
}
public void testGetRestrictBackgroundStatus_enabled() throws Exception {
@@ -92,19 +85,26 @@
assertRestrictBackgroundChangedReceived(1);
assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED);
- removeRestrictBackgroundWhitelist(mUid);
- assertRestrictBackgroundChangedReceived(1);
+ assertsForegroundAlwaysHasNetworkAccess();
assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED);
- // Make sure app is allowed if running a foreground service.
- assertBackgroundNetworkAccess(false);
- startForegroundService();
- assertForegroundServiceState();
- assertBackgroundNetworkAccess(true);
-
- // Should always have access when running on foreground
- launchApp2Activity();
+ // Make sure foreground app doesn't lose access upon enabling it.
+ setRestrictBackground(false);
+ launchActivity();
assertForegroundNetworkAccess();
+ setRestrictBackground(true);
+ assertForegroundNetworkAccess();
+ finishActivity();
+ assertBackgroundNetworkAccess(false);
+
+ // Same for foreground service.
+ setRestrictBackground(false);
+ startForegroundService();
+ assertForegroundNetworkAccess();
+ setRestrictBackground(true);
+ assertForegroundNetworkAccess();
+ stopForegroundService();
+ assertBackgroundNetworkAccess(false);
}
public void testGetRestrictBackgroundStatus_blacklisted() throws Exception {
@@ -112,6 +112,9 @@
assertRestrictBackgroundChangedReceived(1);
assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED);
+ assertsForegroundAlwaysHasNetworkAccess();
+ assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED);
+
// Make sure blacklist prevails over whitelist.
setRestrictBackground(true);
assertRestrictBackgroundChangedReceived(2);
@@ -128,12 +131,8 @@
assertRestrictBackgroundChangedReceived(5);
assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_DISABLED);
- // Should always have access when running on foreground
- addRestrictBackgroundBlacklist(mUid);
- assertRestrictBackgroundChangedReceived(6);
- assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED);
- launchApp2Activity();
- assertForegroundNetworkAccess();
+ assertsForegroundAlwaysHasNetworkAccess();
+ assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_DISABLED);
}
public void testGetRestrictBackgroundStatus_requiredWhitelistedPackages() throws Exception {
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/MixedModesTest.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/MixedModesTest.java
new file mode 100644
index 0000000..140d135
--- /dev/null
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/MixedModesTest.java
@@ -0,0 +1,179 @@
+/*
+ * 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 com.android.cts.net.hostside;
+
+import android.util.Log;
+
+/**
+ * Test cases for the more complex scenarios where multiple restrictions (like Battery Saver Mode
+ * and Data Saver Mode) are applied simultaneously.
+ * <p>
+ * <strong>NOTE: </strong>it might sound like the test methods on this class are testing too much,
+ * which would make it harder to diagnose individual failures, but the assumption is that such
+ * failure most likely will happen when the restriction is tested individually as well.
+ */
+public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase {
+ private static final String TAG = "MixedModesTest";
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+
+ // Set initial state.
+ removeRestrictBackgroundWhitelist(mUid);
+ removeRestrictBackgroundBlacklist(mUid);
+ removePowerSaveModeWhitelist(TEST_APP2_PKG);
+
+ registerBroadcastReceiver();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+
+ try {
+ setRestrictBackground(false);
+ } finally {
+ setPowerSaveMode(false);
+ }
+ }
+
+ /**
+ * Tests all DS ON and BS ON scenarios from network-policy-restrictions.md on metered networks.
+ */
+ public void testDataAndBatterySaverModes_meteredNetwork() throws Exception {
+ Log.i(TAG, "testDataAndBatterySaverModes_meteredNetwork() tests");
+ setMeteredNetwork();
+
+ try {
+ setRestrictBackground(true);
+ setPowerSaveMode(true);
+
+ Log.v(TAG, "Not whitelisted for any.");
+ assertBackgroundNetworkAccess(false);
+ assertsForegroundAlwaysHasNetworkAccess();
+ assertBackgroundNetworkAccess(false);
+
+ Log.v(TAG, "Whitelisted for Data Saver but not for Battery Saver.");
+ addRestrictBackgroundWhitelist(mUid);
+ removePowerSaveModeWhitelist(TEST_APP2_PKG);
+ assertBackgroundNetworkAccess(false);
+ assertsForegroundAlwaysHasNetworkAccess();
+ assertBackgroundNetworkAccess(false);
+ removeRestrictBackgroundWhitelist(mUid);
+
+ Log.v(TAG, "Whitelisted for Battery Saver but not for Data Saver.");
+ addPowerSaveModeWhitelist(TEST_APP2_PKG);
+ removeRestrictBackgroundWhitelist(mUid);
+ assertBackgroundNetworkAccess(false);
+ assertsForegroundAlwaysHasNetworkAccess();
+ assertBackgroundNetworkAccess(false);
+ removePowerSaveModeWhitelist(TEST_APP2_PKG);
+
+ Log.v(TAG, "Whitelisted for both.");
+ addRestrictBackgroundWhitelist(mUid);
+ addPowerSaveModeWhitelist(TEST_APP2_PKG);
+ assertBackgroundNetworkAccess(true);
+ assertsForegroundAlwaysHasNetworkAccess();
+ assertBackgroundNetworkAccess(true);
+ removePowerSaveModeWhitelist(TEST_APP2_PKG);
+ assertBackgroundNetworkAccess(false);
+ removeRestrictBackgroundWhitelist(mUid);
+
+ Log.v(TAG, "Blacklisted for Data Saver, not whitelisted for Battery Saver.");
+ addRestrictBackgroundBlacklist(mUid);
+ removePowerSaveModeWhitelist(TEST_APP2_PKG);
+ assertBackgroundNetworkAccess(false);
+ assertsForegroundAlwaysHasNetworkAccess();
+ assertBackgroundNetworkAccess(false);
+ removeRestrictBackgroundBlacklist(mUid);
+
+ Log.v(TAG, "Blacklisted for Data Saver, whitelisted for Battery Saver.");
+ addRestrictBackgroundBlacklist(mUid);
+ addPowerSaveModeWhitelist(TEST_APP2_PKG);
+ assertBackgroundNetworkAccess(false);
+ assertsForegroundAlwaysHasNetworkAccess();
+ assertBackgroundNetworkAccess(false);
+ removeRestrictBackgroundBlacklist(mUid);
+ removePowerSaveModeWhitelist(TEST_APP2_PKG);
+ } finally {
+ resetMeteredNetwork();
+ }
+ }
+
+ /**
+ * Tests all DS ON and BS ON scenarios from network-policy-restrictions.md on non-metered
+ * networks.
+ */
+ public void testDataAndBatterySaverModes_nonMeteredNetwork() throws Exception {
+ if (mCm.isActiveNetworkMetered()) {
+ Log.w(TAG, "testDataAndBatterySaverModes_nonMeteredNetwork() skipped because network"
+ + " is metered");
+ return;
+ }
+ Log.i(TAG, "testDataAndBatterySaverModes_nonMeteredNetwork() tests");
+ setRestrictBackground(true);
+ setPowerSaveMode(true);
+
+ Log.v(TAG, "Not whitelisted for any.");
+ assertBackgroundNetworkAccess(false);
+ assertsForegroundAlwaysHasNetworkAccess();
+ assertBackgroundNetworkAccess(false);
+
+ Log.v(TAG, "Whitelisted for Data Saver but not for Battery Saver.");
+ addRestrictBackgroundWhitelist(mUid);
+ removePowerSaveModeWhitelist(TEST_APP2_PKG);
+ assertBackgroundNetworkAccess(false);
+ assertsForegroundAlwaysHasNetworkAccess();
+ assertBackgroundNetworkAccess(false);
+ removeRestrictBackgroundWhitelist(mUid);
+
+ Log.v(TAG, "Whitelisted for Battery Saver but not for Data Saver.");
+ addPowerSaveModeWhitelist(TEST_APP2_PKG);
+ removeRestrictBackgroundWhitelist(mUid);
+ assertBackgroundNetworkAccess(true);
+ assertsForegroundAlwaysHasNetworkAccess();
+ assertBackgroundNetworkAccess(true);
+ removePowerSaveModeWhitelist(TEST_APP2_PKG);
+
+ Log.v(TAG, "Whitelisted for both.");
+ addRestrictBackgroundWhitelist(mUid);
+ addPowerSaveModeWhitelist(TEST_APP2_PKG);
+ assertBackgroundNetworkAccess(true);
+ assertsForegroundAlwaysHasNetworkAccess();
+ assertBackgroundNetworkAccess(true);
+ removePowerSaveModeWhitelist(TEST_APP2_PKG);
+ assertBackgroundNetworkAccess(false);
+ removeRestrictBackgroundWhitelist(mUid);
+
+ Log.v(TAG, "Blacklisted for Data Saver, not whitelisted for Battery Saver.");
+ addRestrictBackgroundBlacklist(mUid);
+ removePowerSaveModeWhitelist(TEST_APP2_PKG);
+ assertBackgroundNetworkAccess(false);
+ assertsForegroundAlwaysHasNetworkAccess();
+ assertBackgroundNetworkAccess(false);
+ removeRestrictBackgroundBlacklist(mUid);
+
+ Log.v(TAG, "Blacklisted for Data Saver, whitelisted for Battery Saver.");
+ addRestrictBackgroundBlacklist(mUid);
+ addPowerSaveModeWhitelist(TEST_APP2_PKG);
+ assertBackgroundNetworkAccess(true);
+ assertsForegroundAlwaysHasNetworkAccess();
+ assertBackgroundNetworkAccess(true);
+ removeRestrictBackgroundBlacklist(mUid);
+ removePowerSaveModeWhitelist(TEST_APP2_PKG);
+ }
+}
diff --git a/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/Common.java b/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/Common.java
index ed58184..d827921 100644
--- a/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/Common.java
+++ b/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/Common.java
@@ -34,10 +34,11 @@
"com.android.cts.net.hostside.app2.action.CHECK_NETWORK";
static final String ACTION_RECEIVER_READY =
"com.android.cts.net.hostside.app2.action.RECEIVER_READY";
+ static final String ACTION_FINISH_ACTIVITY =
+ "com.android.cts.net.hostside.app2.action.FINISH_ACTIVITY";
static final String EXTRA_ACTION = "com.android.cts.net.hostside.app2.extra.ACTION";
static final String EXTRA_RECEIVER_NAME =
"com.android.cts.net.hostside.app2.extra.RECEIVER_NAME";
- static final char RESULT_SEPARATOR = ';';
static int getUid(Context context) {
final String packageName = context.getPackageName();
diff --git a/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/MyActivity.java b/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/MyActivity.java
index 7c6b504..444b696 100644
--- a/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/MyActivity.java
+++ b/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/MyActivity.java
@@ -15,8 +15,15 @@
*/
package com.android.cts.net.hostside.app2;
+import static com.android.cts.net.hostside.app2.Common.ACTION_FINISH_ACTIVITY;
import static com.android.cts.net.hostside.app2.Common.TAG;
+
import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
import android.util.Log;
/**
@@ -25,6 +32,18 @@
public class MyActivity extends Activity {
@Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ registerReceiver(new BroadcastReceiver() {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Log.d(TAG, "Finishing MyActivity");
+ MyActivity.this.finish();
+ }}, new IntentFilter(ACTION_FINISH_ACTIVITY));
+ }
+
+ @Override
protected void onStart() {
super.onStart();
Log.d(TAG, "MyActivity.onStart()");
diff --git a/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java b/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java
index b876276..114d5c1 100644
--- a/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java
+++ b/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java
@@ -17,6 +17,7 @@
package com.android.cts.net.hostside.app2;
import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED;
+
import static com.android.cts.net.hostside.app2.Common.ACTION_CHECK_NETWORK;
import static com.android.cts.net.hostside.app2.Common.ACTION_GET_COUNTERS;
import static com.android.cts.net.hostside.app2.Common.ACTION_GET_RESTRICT_BACKGROUND_STATUS;
@@ -24,7 +25,6 @@
import static com.android.cts.net.hostside.app2.Common.EXTRA_ACTION;
import static com.android.cts.net.hostside.app2.Common.EXTRA_RECEIVER_NAME;
import static com.android.cts.net.hostside.app2.Common.MANIFEST_RECEIVER;
-import static com.android.cts.net.hostside.app2.Common.RESULT_SEPARATOR;
import static com.android.cts.net.hostside.app2.Common.TAG;
import static com.android.cts.net.hostside.app2.Common.getUid;
diff --git a/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/MyForegroundService.java b/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/MyForegroundService.java
index bbafd4c..1afc3d6 100644
--- a/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/MyForegroundService.java
+++ b/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/MyForegroundService.java
@@ -35,7 +35,7 @@
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
- Log.d(TAG, "MyForegroundService.onStartCommand: " + intent);
+ Log.d(TAG, "MyForegroundService.onStartCommand(): " + intent);
startForeground(42, new Notification.Builder(this)
.setSmallIcon(R.drawable.ic_dialog_alert) // any icon is fine
.build());
diff --git a/hostsidetests/net/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java b/hostsidetests/net/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java
index 38802d7..ec375d6 100644
--- a/hostsidetests/net/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java
+++ b/hostsidetests/net/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java
@@ -121,6 +121,16 @@
"testBackgroundNetworkAccess_enabled");
}
+ public void testDataAndBatterySaverModes_meteredNetwork() throws Exception {
+ runDeviceTests(TEST_PKG, TEST_PKG + ".MixedModesTest",
+ "testDataAndBatterySaverModes_meteredNetwork");
+ }
+
+ public void testDataAndBatterySaverModes_nonMeteredNetwork() throws Exception {
+ runDeviceTests(TEST_PKG, TEST_PKG + ".MixedModesTest",
+ "testDataAndBatterySaverModes_nonMeteredNetwork");
+ }
+
private void assertRestrictBackgroundWhitelist(int uid, boolean expected) throws Exception {
final int max_tries = 5;
boolean actual = false;
diff --git a/libs/deviceutil/src/android/cts/util/MediaUtils.java b/libs/deviceutil/src/android/cts/util/MediaUtils.java
index 721ff47..7ab806d 100755
--- a/libs/deviceutil/src/android/cts/util/MediaUtils.java
+++ b/libs/deviceutil/src/android/cts/util/MediaUtils.java
@@ -43,6 +43,9 @@
public class MediaUtils {
private static final String TAG = "MediaUtils";
+ /*
+ * ----------------------- HELPER METHODS FOR SKIPPING TESTS -----------------------
+ */
private static final int ALL_AV_TRACKS = -1;
private static final MediaCodecList sMCL = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
@@ -149,6 +152,10 @@
return result;
}
+ /*
+ * ------------------- HELPER METHODS FOR CHECKING CODEC SUPPORT -------------------
+ */
+
public static MediaCodec getDecoder(MediaFormat format) {
String decoder = sMCL.findDecoderForFormat(format);
if (decoder != null) {
@@ -423,6 +430,10 @@
return check(canDecode(format), "no decoder for " + format);
}
+ /*
+ * ----------------------- HELPER METHODS FOR MEDIA HANDLING -----------------------
+ */
+
public static MediaExtractor createMediaExtractorForMimeType(
Context context, int resourceId, String mimeTypePrefix)
throws IOException {
@@ -450,65 +461,172 @@
return extractor;
}
- /**
- * return the average value of the passed array.
+ /*
+ * ------------------ HELPER METHODS FOR STATISTICS AND REPORTING ------------------
*/
- public static double getAverage(double[] data) {
- int num = data.length;
- if (num == 0) {
- return 0;
+
+ // TODO: migrate this into com.android.compatibility.common.util.Stat
+ public static class Stats {
+ /** does not support NaN or Inf in |data| */
+ public Stats(double[] data) {
+ mData = data;
+ if (mData != null) {
+ mNum = mData.length;
+ }
}
- double sum = data[0];
- for (int i = 1; i < num; i++) {
- sum += data[i];
+ public int getNum() {
+ return mNum;
}
- return sum / num;
+
+ /** calculate mSumX and mSumXX */
+ private void analyze() {
+ if (mAnalyzed) {
+ return;
+ }
+
+ if (mData != null) {
+ for (double x : mData) {
+ if (!(x >= mMinX)) { // mMinX may be NaN
+ mMinX = x;
+ }
+ if (!(x <= mMaxX)) { // mMaxX may be NaN
+ mMaxX = x;
+ }
+ mSumX += x;
+ mSumXX += x * x;
+ }
+ }
+ mAnalyzed = true;
+ }
+
+ /** returns the maximum or NaN if it does not exist */
+ public double getMin() {
+ analyze();
+ return mMinX;
+ }
+
+ /** returns the minimum or NaN if it does not exist */
+ public double getMax() {
+ analyze();
+ return mMaxX;
+ }
+
+ /** returns the average or NaN if it does not exist. */
+ public double getAverage() {
+ analyze();
+ if (mNum == 0) {
+ return Double.NaN;
+ } else {
+ return mSumX / mNum;
+ }
+ }
+
+ /** returns the standard deviation or NaN if it does not exist. */
+ public double getStdev() {
+ analyze();
+ if (mNum == 0) {
+ return Double.NaN;
+ } else {
+ double average = mSumX / mNum;
+ return Math.sqrt(mSumXX / mNum - average * average);
+ }
+ }
+
+ /** returns the statistics for the moving average over n values */
+ public Stats movingAverage(int n) {
+ if (n < 1 || mNum < n) {
+ return new Stats(null);
+ } else if (n == 1) {
+ return this;
+ }
+
+ double[] avgs = new double[mNum - n + 1];
+ double sum = 0;
+ for (int i = 0; i < mNum; ++i) {
+ sum += mData[i];
+ if (i >= n - 1) {
+ avgs[i - n + 1] = sum / n;
+ sum -= mData[i - n + 1];
+ }
+ }
+ return new Stats(avgs);
+ }
+
+ /** calculate mSortedData */
+ private void sort() {
+ if (mSorted || mNum == 0) {
+ return;
+ }
+ mSortedData = Arrays.copyOf(mData, mNum);
+ Arrays.sort(mSortedData);
+ mSorted = true;
+ }
+
+ /** returns an array of percentiles for the points using nearest rank */
+ public double[] getPercentiles(double... points) {
+ sort();
+ double[] res = new double[points.length];
+ for (int i = 0; i < points.length; ++i) {
+ if (mNum < 1 || points[i] < 0 || points[i] > 100) {
+ res[i] = Double.NaN;
+ } else {
+ res[i] = mSortedData[(int)Math.round(points[i] / 100 * (mNum - 1))];
+ }
+ }
+ return res;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof Stats) {
+ Stats other = (Stats)o;
+ if (other.mNum != mNum) {
+ return false;
+ } else if (mNum == 0) {
+ return true;
+ }
+ return Arrays.equals(mData, other.mData);
+ }
+ return false;
+ }
+
+ private double[] mData;
+ private double mSumX = 0;
+ private double mSumXX = 0;
+ private double mMinX = Double.NaN;
+ private double mMaxX = Double.NaN;
+ private int mNum = 0;
+ private boolean mAnalyzed = false;
+ private double[] mSortedData;
+ private boolean mSorted = false;
}
+ /*
+ * ------------------ HELPER METHODS FOR ACHIEVABLE FRAME RATES ------------------
+ */
+
/**
- * return the standard deviation value of the passed array
+ * logs results for achievable frame rates test
*/
- public static double getStdev(double[] data) {
- double average = getAverage(data);
- int num = data.length;
- if (num == 0) {
- return 0;
- }
- double variance = 0;
- for (int i = 0; i < num; ++i) {
- variance += (data[i] - average) * (data[i] - average);
- }
- variance /= num;
- return Math.sqrt(variance);
- }
-
- public static double[] calculateMovingAverage(double[] array, int n) {
- int num = array.length;
- if (num < n) {
- return null;
- }
- int avgsNum = num - n + 1;
- double[] avgs = new double[avgsNum];
- double sum = array[0];
- for (int i = 1; i < n; ++i) {
- sum += array[i];
- }
- avgs[0] = sum / n;
-
- for (int i = n; i < num; ++i) {
- sum = sum - array[i - n] + array[i];
- avgs[i - n + 1] = sum / n;
- }
- return avgs;
- }
-
- public static String logResults(DeviceReportLog log, String prefix,
- double min, double max, double avg, double stdev) {
+ public static String logAchievableRatesResults(DeviceReportLog log, String prefix,
+ Stats stats) {
String msg = prefix;
- msg += " min=" + Math.round(min / 1000) + " max=" + Math.round(max / 1000) +
- " avg=" + Math.round(avg / 1000) + " stdev=" + Math.round(stdev / 1000);
- log.addValue(msg, 1000000000 / min, ResultType.HIGHER_BETTER, ResultUnit.FPS);
+ msg += " num=" + stats.getNum()
+ + " avg=" + Math.round(stats.getAverage() / 1000)
+ + " stdev=" + Math.round(stats.getStdev() / 1000);
+ String[] labels = {
+ "min", "p5", "p10", "p20", "p30", "p40", "p50", "p60", "p70", "p80", "p90", "p95",
+ "max" };
+ double[] percentiles = stats.getPercentiles(new double[] {
+ 0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 95, 100 });
+
+ for (int i = 0; i < labels.length; ++i) {
+ msg += " " + labels[i] + "=" + Math.round(percentiles[i] / 1000);
+ }
+
+ log.addValue(msg, 1000000000 / stats.getMin(), ResultType.HIGHER_BETTER, ResultUnit.FPS);
+ Log.i(TAG, msg);
return msg;
}
diff --git a/tests/camera/libctscamera2jni/native-camera-jni.cpp b/tests/camera/libctscamera2jni/native-camera-jni.cpp
index 90c34db..db687bf 100644
--- a/tests/camera/libctscamera2jni/native-camera-jni.cpp
+++ b/tests/camera/libctscamera2jni/native-camera-jni.cpp
@@ -1213,7 +1213,7 @@
ACameraDevice_request_template templateId =
static_cast<ACameraDevice_request_template>(t);
ret = ACameraDevice_createCaptureRequest(device, templateId, &request);
- if (ret == ACAMERA_ERROR_UNSUPPORTED) {
+ if (ret == ACAMERA_ERROR_INVALID_PARAMETER) {
// template not supported. skip
continue;
}
diff --git a/tests/core/runner/src/com/android/cts/core/runner/support/ExtendedAndroidAnnotatedBuilder.java b/tests/core/runner/src/com/android/cts/core/runner/support/ExtendedAndroidAnnotatedBuilder.java
deleted file mode 100644
index 05c6623..0000000
--- a/tests/core/runner/src/com/android/cts/core/runner/support/ExtendedAndroidAnnotatedBuilder.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * 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 com.android.cts.core.runner.support;
-
-import android.support.test.internal.runner.junit4.AndroidAnnotatedBuilder;
-import android.support.test.internal.util.AndroidRunnerParams;
-import android.support.test.runner.AndroidJUnit4;
-import junit.framework.TestCase;
-import org.junit.runner.RunWith;
-import org.junit.runner.Runner;
-import org.junit.runners.BlockJUnit4ClassRunner;
-import org.junit.runners.JUnit4;
-import org.junit.runners.model.RunnerBuilder;
-
-/**
- * Extends {@link AndroidAnnotatedBuilder} to add support for passing the
- * {@link AndroidRunnerParams} object to the constructor of any {@link RunnerBuilder}
- * implementation that is not a {@link BlockJUnit4ClassRunner}.
- *
- * <p>If {@link AndroidRunnerParams#isSkipExecution()} is {@code true} the super class will create
- * a {@link RunnerBuilder} that will fire appropriate events as if the tests are being run but will
- * not actually run the test. Unfortunately, when it does that it appears to assume that the runner
- * extends {@link BlockJUnit4ClassRunner}, returns a skipping {@link RunnerBuilder} appropriate for
- * that and ignores the actual {@code runnerClass}. That is a problem because it will not work for
- * custom {@link RunnerBuilder} instances that do not extend {@link BlockJUnit4ClassRunner}.
- *
- * <p>Therefore, when skipping execution this does some additional checks to make sure that the
- * {@code runnerClass} does extend {@link BlockJUnit4ClassRunner} before calling the overridden
- * method.
- *
- * <p>It then attempts to construct a {@link RunnerBuilder} by calling the constructor with the
- * signature {@code <init>(Class, AndroidRunnerParams)}. If that doesn't exist it falls back to
- * the overridden behavior.
- */
-class ExtendedAndroidAnnotatedBuilder extends AndroidAnnotatedBuilder {
-
- private final AndroidRunnerParams runnerParams;
-
- public ExtendedAndroidAnnotatedBuilder(RunnerBuilder suiteBuilder,
- AndroidRunnerParams runnerParams) {
- super(suiteBuilder, runnerParams);
- this.runnerParams = runnerParams;
- }
-
- @Override
- public Runner runnerForClass(Class<?> testClass) throws Exception {
-
- RunWith annotation = testClass.getAnnotation(RunWith.class);
- if (annotation != null) {
- Class<? extends Runner> runnerClass = annotation.value();
-
- // If the runner is expected to skip execution and it is a JUnit4, AndroidJUnit4 or
- // a JUnit3 test class then return a special skipping runner.
- if (runnerParams.isSkipExecution()) {
- if (runnerClass == AndroidJUnit4.class || runnerClass == JUnit4.class
- || TestCase.class.isAssignableFrom(testClass)) {
- return super.runnerForClass(testClass);
- }
- }
-
- try {
- // try to build an AndroidJUnit4 runner
- Runner runner = buildAndroidRunner(runnerClass, testClass);
- if (runner != null) {
- return runner;
- }
- } catch (NoSuchMethodException e) {
- // let the super class handle the error for us and throw an InitializationError
- // exception.
- return super.buildRunner(runnerClass, testClass);
- }
- }
-
- return null;
- }
-}
diff --git a/tests/core/runner/src/com/android/cts/core/runner/support/ExtendedAndroidLogOnlyBuilder.java b/tests/core/runner/src/com/android/cts/core/runner/support/ExtendedAndroidLogOnlyBuilder.java
new file mode 100644
index 0000000..956ebff
--- /dev/null
+++ b/tests/core/runner/src/com/android/cts/core/runner/support/ExtendedAndroidLogOnlyBuilder.java
@@ -0,0 +1,96 @@
+/*
+ * 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 com.android.cts.core.runner.support;
+
+import android.support.test.internal.runner.AndroidLogOnlyBuilder;
+import android.support.test.internal.util.AndroidRunnerParams;
+import android.support.test.runner.AndroidJUnit4;
+import junit.framework.TestCase;
+import org.junit.runner.RunWith;
+import org.junit.runner.Runner;
+import org.junit.runners.Parameterized;
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.JUnit4;
+import org.junit.runners.model.RunnerBuilder;
+import org.junit.runners.Suite;
+
+import static android.support.test.internal.util.AndroidRunnerBuilderUtil.isJUnit3Test;
+import static android.support.test.internal.util.AndroidRunnerBuilderUtil.isJUnit3TestSuite;
+
+/**
+ * Extends {@link AndroidLogOnlyBuilder} to add support for passing the
+ * {@link AndroidRunnerParams} object to the constructor of any {@link RunnerBuilder}
+ * implementation that is not a {@link BlockJUnit4ClassRunner}.
+ *
+ * <p>If {@link AndroidRunnerParams#isSkipExecution()} is {@code true} the super class will create
+ * a {@link RunnerBuilder} that will fire appropriate events as if the tests are being run but will
+ * not actually run the test. Unfortunately, when it does that it appears to assume that the runner
+ * extends {@link BlockJUnit4ClassRunner}, returns a skipping {@link RunnerBuilder} appropriate for
+ * that and ignores the actual {@code runnerClass}. That is a problem because it will not work for
+ * custom {@link RunnerBuilder} instances that do not extend {@link BlockJUnit4ClassRunner}.
+ *
+ * <p>Therefore, when skipping execution this does some additional checks to make sure that the
+ * {@code runnerClass} does extend {@link BlockJUnit4ClassRunner} before calling the overridden
+ * method.
+ *
+ * <p>It then attempts to construct a {@link RunnerBuilder} by calling the constructor with the
+ * signature {@code <init>(Class, AndroidRunnerParams)}. If that doesn't exist it falls back to
+ * the overridden behavior.
+ *
+ * <p>Another unfortunate behavior of the {@link AndroidLogOnlyBuilder} is that it assumes the
+ * {@link Parameterized} class has a field called DEFAULT_FACTORY. That field is only present
+ * in JUnit 4.12, and not JUnit 4.10 used by tests run by CoreTestRunner.
+ * Therefore these tests are actually skipped by this class and executed even though
+ * isSkipExecution is true.
+ */
+class ExtendedAndroidLogOnlyBuilder extends AndroidLogOnlyBuilder {
+
+ private final AndroidRunnerParams runnerParams;
+
+ public ExtendedAndroidLogOnlyBuilder(AndroidRunnerParams runnerParams) {
+ super(runnerParams);
+ this.runnerParams = runnerParams;
+ }
+
+ @Override
+ public Runner runnerForClass(Class<?> testClass) throws Throwable {
+ if (!runnerParams.isSkipExecution() ||
+ isJUnit3Test(testClass) || isJUnit3TestSuite(testClass)) {
+ return super.runnerForClass(testClass);
+ }
+
+ RunWith annotation = testClass.getAnnotation(RunWith.class);
+
+ if (annotation != null) {
+ Class<? extends Runner> runnerClass = annotation.value();
+ if (runnerClass == AndroidJUnit4.class || runnerClass == JUnit4.class
+ || TestCase.class.isAssignableFrom(testClass)) {
+ return super.runnerForClass(testClass);
+ }
+ try {
+ // b/28606746 try to build an AndroidJUnit4 runner to avoid BlockJUnit4ClassRunner
+ return runnerClass.getConstructor(Class.class, AndroidRunnerParams.class).newInstance(
+ testClass, runnerParams);
+ } catch (NoSuchMethodException e) {
+ // Let the super class handle the error for us and throw an InitializationError
+ // exception. Returning null means that this test will be executed.
+ // b/28606746 Some parameterized tests that cannot be skipped fall through this
+ return null;
+ }
+ }
+ return super.runnerForClass(testClass);
+ }
+}
diff --git a/tests/core/runner/src/com/android/cts/core/runner/support/ExtendedAndroidRunnerBuilder.java b/tests/core/runner/src/com/android/cts/core/runner/support/ExtendedAndroidRunnerBuilder.java
index 1f76922..527f9fd 100644
--- a/tests/core/runner/src/com/android/cts/core/runner/support/ExtendedAndroidRunnerBuilder.java
+++ b/tests/core/runner/src/com/android/cts/core/runner/support/ExtendedAndroidRunnerBuilder.java
@@ -15,10 +15,10 @@
*/
package com.android.cts.core.runner.support;
-import android.support.test.internal.runner.junit4.AndroidAnnotatedBuilder;
+import android.support.test.internal.runner.AndroidLogOnlyBuilder;
import android.support.test.internal.util.AndroidRunnerParams;
-import org.junit.internal.builders.AnnotatedBuilder;
import org.junit.runners.model.RunnerBuilder;
+import org.junit.runner.Runner;
/**
* Extends {@link AndroidRunnerBuilder} in order to provide alternate {@link RunnerBuilder}
@@ -26,18 +26,24 @@
*/
public class ExtendedAndroidRunnerBuilder extends AndroidRunnerBuilder {
- private final AndroidAnnotatedBuilder mAndroidAnnotatedBuilder;
+ private final ExtendedAndroidLogOnlyBuilder androidLogOnlyBuilder;
/**
* @param runnerParams {@link AndroidRunnerParams} that stores common runner parameters
*/
public ExtendedAndroidRunnerBuilder(AndroidRunnerParams runnerParams) {
super(runnerParams, false /* CTSv1 filtered out Test suite() classes. */);
- mAndroidAnnotatedBuilder = new ExtendedAndroidAnnotatedBuilder(this, runnerParams);
+ androidLogOnlyBuilder = new ExtendedAndroidLogOnlyBuilder(runnerParams);
}
@Override
- protected AnnotatedBuilder annotatedBuilder() {
- return mAndroidAnnotatedBuilder;
+ public Runner runnerForClass(Class<?> testClass) throws Throwable {
+ // Check if this is a dry-run with -e log true argument passed to the runner.
+ Runner runner = androidLogOnlyBuilder.runnerForClass(testClass);
+ if (runner != null) {
+ return runner;
+ }
+ // Otherwise use the default behaviour
+ return super.runnerForClass(testClass);
}
}
diff --git a/tests/leanbackjank/Android.mk b/tests/leanbackjank/Android.mk
index b762dc9..5a89666 100644
--- a/tests/leanbackjank/Android.mk
+++ b/tests/leanbackjank/Android.mk
@@ -34,6 +34,7 @@
ub-uiautomator \
ub-janktesthelper \
android-support-v17-leanback \
+ android-support-v7-recyclerview \
android-support-v4
LOCAL_CTS_MODULE_CONFIG := $(LOCAL_PATH)/Old$(CTS_MODULE_TEST_CONFIG)
diff --git a/tests/leanbackjank/AndroidManifest.xml b/tests/leanbackjank/AndroidManifest.xml
index 27cdbe6..35a2e2e 100644
--- a/tests/leanbackjank/AndroidManifest.xml
+++ b/tests/leanbackjank/AndroidManifest.xml
@@ -19,6 +19,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.leanbackjank.cts">
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
<application>
<uses-library android:name="android.test.runner"/>
</application>
diff --git a/tests/leanbackjank/app/res/layout/main.xml b/tests/leanbackjank/app/res/layout/main.xml
index 7a83b69..542c3e3 100644
--- a/tests/leanbackjank/app/res/layout/main.xml
+++ b/tests/leanbackjank/app/res/layout/main.xml
@@ -22,7 +22,7 @@
android:layout_height="match_parent">
<fragment
- android:name="android.cts.jank.leanback.ui.MainFragment"
+ android:name="android.leanbackjank.app.ui.MainFragment"
android:id="@+id/main_browse_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
diff --git a/tests/tests/media/src/android/media/cts/DecoderTest.java b/tests/tests/media/src/android/media/cts/DecoderTest.java
index 79bf8c7..24880e2 100755
--- a/tests/tests/media/src/android/media/cts/DecoderTest.java
+++ b/tests/tests/media/src/android/media/cts/DecoderTest.java
@@ -2497,5 +2497,182 @@
mMediaCodecPlayer.flush();
// mMediaCodecPlayer.reset() handled in TearDown();
}
+
+ /**
+ * Returns list of CodecCapabilities advertising support for the given MIME type.
+ */
+ private static List<CodecCapabilities> getCodecCapabilitiesForMimeType(String mimeType) {
+ int numCodecs = MediaCodecList.getCodecCount();
+ List<CodecCapabilities> caps = new ArrayList<CodecCapabilities>();
+ for (int i = 0; i < numCodecs; i++) {
+ MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
+ if (codecInfo.isEncoder()) {
+ continue;
+ }
+
+ String[] types = codecInfo.getSupportedTypes();
+ for (int j = 0; j < types.length; j++) {
+ if (types[j].equalsIgnoreCase(mimeType)) {
+ caps.add(codecInfo.getCapabilitiesForType(mimeType));
+ }
+ }
+ }
+ return caps;
+ }
+
+ /**
+ * Returns true if there exists a codec supporting the given MIME type that meets VR high
+ * performance requirements.
+ *
+ * The requirements are as follows:
+ * - At least 972000 blocks per second (where blocks are defined as 16x16 -- note this
+ * is equivalent to 3840x2160@30fps)
+ * - At least 4 concurrent instances
+ * - Feature adaptive-playback present
+ */
+ private static boolean doesMimeTypeHaveVrReadyCodec(String mimeType) {
+ List<CodecCapabilities> caps = getCodecCapabilitiesForMimeType(mimeType);
+ for (CodecCapabilities c : caps) {
+ if (c.getMaxSupportedInstances() < 4) {
+ continue;
+ }
+
+ if (!c.isFeatureSupported(CodecCapabilities.FEATURE_AdaptivePlayback)) {
+ continue;
+ }
+
+ if (!c.getVideoCapabilities().areSizeAndRateSupported(3840, 2160, 30.0)) {
+ continue;
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ private class DecodeRunnable implements Runnable {
+ private int video;
+ private int frames;
+ private long durationMillis;
+
+ public DecodeRunnable(int video) {
+ this.video = video;
+ this.frames = 0;
+ this.durationMillis = 0;
+ }
+
+ @Override
+ public void run() {
+ long start = System.currentTimeMillis();
+ int actual = 0;
+ try {
+ actual = countFrames(this.video, RESET_MODE_NONE, -1, null);
+ } catch (Exception e) {
+ actual = -1;
+ }
+ long durationMillis = System.currentTimeMillis() - start;
+
+ synchronized (this) {
+ this.frames = actual;
+ this.durationMillis = durationMillis;
+ }
+ }
+
+ public synchronized int getFrames() {
+ return this.frames;
+ }
+
+ public synchronized double getMeasuredFps() {
+ return this.frames / (this.durationMillis / 1000.0);
+ }
+ }
+
+ private void decodeInParallel(int video, int frames, int fps, int parallel) throws Exception {
+ DecodeRunnable[] runnables = new DecodeRunnable[parallel];
+ Thread[] threads = new Thread[parallel];
+
+ for (int i = 0; i < parallel; ++i) {
+ runnables[i] = new DecodeRunnable(video);
+ threads[i] = new Thread(runnables[i]);
+ threads[i].start();
+ }
+
+ for (Thread t : threads) {
+ t.join();
+ }
+
+ for (DecodeRunnable dr : runnables) {
+ assertTrue("Expected to decode " + frames + " frames, found " + dr.getFrames(),
+ frames == dr.getFrames());
+ }
+
+ for (DecodeRunnable dr : runnables) {
+ Log.d(TAG, "Decoded at " + dr.getMeasuredFps());
+ assertTrue("Expected to decode at " + fps + " fps, measured " + dr.getMeasuredFps(),
+ fps < dr.getMeasuredFps());
+ }
+ }
+
+ public void testVrHighPerformanceH264() throws Exception {
+ if (!supportsVrHighPerformance()) {
+ MediaUtils.skipTest(TAG, "FEATURE_VR_MODE_HIGH_PERFORMANCE not present");
+ return;
+ }
+
+ boolean h264IsReady = doesMimeTypeHaveVrReadyCodec(MediaFormat.MIMETYPE_VIDEO_AVC);
+ assertTrue("Did not find a VR ready H.264 decoder", h264IsReady);
+
+ // Test throughput by decoding 1920x1080 @ 30fps x 4 instances.
+ decodeInParallel(
+ R.raw.video_1920x1080_mp4_h264_20480kbps_30fps_aac_stereo_128kbps_44100hz, 299, 30,
+ 4);
+
+ // Test throughput by decoding 1920x1080 @ 60fps x 2 instances.
+ decodeInParallel(
+ R.raw.video_1920x1080_mp4_h264_20480kbps_60fps_aac_stereo_128kbps_44100hz, 596, 60,
+ 2);
+ }
+
+ public void testVrHighPerformanceHEVC() throws Exception {
+ if (!supportsVrHighPerformance()) {
+ MediaUtils.skipTest(TAG, "FEATURE_VR_MODE_HIGH_PERFORMANCE not present");
+ return;
+ }
+
+ boolean hevcIsReady = doesMimeTypeHaveVrReadyCodec(MediaFormat.MIMETYPE_VIDEO_HEVC);
+ if (!hevcIsReady) {
+ MediaUtils.skipTest(TAG, "HEVC isn't required to be VR ready");
+ return;
+ }
+
+ // Test throughput by decoding 1920x1080 @ 30fps x 4 instances.
+ decodeInParallel(
+ R.raw.video_1920x1080_mp4_hevc_10240kbps_30fps_aac_stereo_128kbps_44100hz, 299, 30,
+ 4);
+ }
+
+ public void testVrHighPerformanceVP9() throws Exception {
+ if (!supportsVrHighPerformance()) {
+ MediaUtils.skipTest(TAG, "FEATURE_VR_MODE_HIGH_PERFORMANCE not present");
+ return;
+ }
+
+ boolean vp9IsReady = doesMimeTypeHaveVrReadyCodec(MediaFormat.MIMETYPE_VIDEO_VP9);
+ if (!vp9IsReady) {
+ MediaUtils.skipTest(TAG, "VP9 isn't required to be VR ready");
+ return;
+ }
+
+ // Test throughput by decoding 1920x1080 @ 30fps x 4 instances.
+ decodeInParallel(
+ R.raw.video_1920x1080_webm_vp9_10240kbps_30fps_vorbis_stereo_128kbps_48000hz, 249,
+ 30, 4);
+ }
+
+ private boolean supportsVrHighPerformance() {
+ PackageManager pm = mContext.getPackageManager();
+ return pm.hasSystemFeature(PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE);
+ }
}
diff --git a/tests/tests/media/src/android/media/cts/VideoDecoderPerfTest.java b/tests/tests/media/src/android/media/cts/VideoDecoderPerfTest.java
index 7e56a22..7cd73fe 100644
--- a/tests/tests/media/src/android/media/cts/VideoDecoderPerfTest.java
+++ b/tests/tests/media/src/android/media/cts/VideoDecoderPerfTest.java
@@ -302,14 +302,11 @@
double fps = (double)outputNum / ((finish - start) / 1000.0);
mReportLog.addValue(message, fps, ResultType.HIGHER_BETTER, ResultUnit.FPS);
- double[] avgs = MediaUtils.calculateMovingAverage(frameTimeDiff, MOVING_AVERAGE_NUM);
- double decMin = Stat.getMin(avgs);
- double decMax = Stat.getMax(avgs);
- double decAvg = Stat.getAverage(avgs);
- double decStdev = MediaUtils.getStdev(avgs);
+ MediaUtils.Stats stats =
+ new MediaUtils.Stats(frameTimeDiff).movingAverage(MOVING_AVERAGE_NUM);
String result =
- MediaUtils.logResults(mReportLog, testConfig, decMin, decMax, decAvg, decStdev);
- fps = 1000000000 / decMin;
+ MediaUtils.logAchievableRatesResults(mReportLog, testConfig, stats);
+ fps = 1000000000 / stats.getMin();
if (surface != null) {
mMeasuredFps[round] = fps;
mResultRawData[round] = result;
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-attributes/res/xml/network_security_config.xml b/tests/tests/networksecurityconfig/networksecurityconfig-attributes/res/xml/network_security_config.xml
index 1e68b7d..698444c 100644
--- a/tests/tests/networksecurityconfig/networksecurityconfig-attributes/res/xml/network_security_config.xml
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-attributes/res/xml/network_security_config.xml
@@ -10,8 +10,8 @@
<domain-config>
<domain includeSubdomains="true">android.com</domain>
</domain-config>
- <!-- Cleartext traffic is explicitly permitted to google.com and all subdomains -->
+ <!-- Cleartext traffic is explicitly permitted to example.com and all subdomains -->
<domain-config cleartextTrafficPermitted="true">
- <domain includeSubdomains="true">google.com</domain>
+ <domain includeSubdomains="true">example.com</domain>
</domain-config>
</network-security-config>
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-attributes/src/android/security/net/config/cts/TestAttributes.java b/tests/tests/networksecurityconfig/networksecurityconfig-attributes/src/android/security/net/config/cts/TestAttributes.java
index 4d23e5b..f10d0da 100644
--- a/tests/tests/networksecurityconfig/networksecurityconfig-attributes/src/android/security/net/config/cts/TestAttributes.java
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-attributes/src/android/security/net/config/cts/TestAttributes.java
@@ -34,8 +34,8 @@
assertTrue(instance.isCleartextTrafficPermitted("android.com"));
assertTrue(instance.isCleartextTrafficPermitted("foo.android.com"));
// Domains in a domain-config that explicitly allow cleartext.
- assertTrue(instance.isCleartextTrafficPermitted("google.com"));
- assertTrue(instance.isCleartextTrafficPermitted("test.google.com"));
+ assertTrue(instance.isCleartextTrafficPermitted("example.com"));
+ assertTrue(instance.isCleartextTrafficPermitted("test.example.com"));
// Domain not specified in a domain-config, should use the base-config's value.
assertTrue(instance.isCleartextTrafficPermitted("example.com"));
}
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-basic-domain/src/android/security/net/config/cts/DomainConfigTest.java b/tests/tests/networksecurityconfig/networksecurityconfig-basic-domain/src/android/security/net/config/cts/DomainConfigTest.java
index 73ddd33..8e833b1 100644
--- a/tests/tests/networksecurityconfig/networksecurityconfig-basic-domain/src/android/security/net/config/cts/DomainConfigTest.java
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-basic-domain/src/android/security/net/config/cts/DomainConfigTest.java
@@ -30,7 +30,7 @@
public void testDefaultConfig() throws Exception {
// The default config in this case has no trusted CAs, so all connections should fail.
TestUtils.assertTlsConnectionFails("developer.android.com", 443);
- TestUtils.assertTlsConnectionFails("google.com", 443);
+ TestUtils.assertTlsConnectionFails("example.com", 443);
}
public void testHostnameAwareCheckServerTrustedRequired() throws Exception {
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-cleartext/src/android/security/net/config/cts/CleartextPermittedTest.java b/tests/tests/networksecurityconfig/networksecurityconfig-cleartext/src/android/security/net/config/cts/CleartextPermittedTest.java
index 401b5ac..db8e40f 100644
--- a/tests/tests/networksecurityconfig/networksecurityconfig-cleartext/src/android/security/net/config/cts/CleartextPermittedTest.java
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-cleartext/src/android/security/net/config/cts/CleartextPermittedTest.java
@@ -23,8 +23,8 @@
public class CleartextPermittedTest extends TestCase {
public void testDefaultAllowed() throws Exception {
- TestUtils.assertCleartextConnectionSucceeds("google.com", 80);
- TestUtils.assertTlsConnectionSucceeds("google.com", 443);
+ TestUtils.assertCleartextConnectionSucceeds("example.com", 80);
+ TestUtils.assertTlsConnectionSucceeds("example.com", 443);
}
public void testCleartextBlocked() throws Exception {
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-invalid-pin/src/android/security/net/config/cts/InvalidPinTest.java b/tests/tests/networksecurityconfig/networksecurityconfig-invalid-pin/src/android/security/net/config/cts/InvalidPinTest.java
index fb0444a..3826ba7 100644
--- a/tests/tests/networksecurityconfig/networksecurityconfig-invalid-pin/src/android/security/net/config/cts/InvalidPinTest.java
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-invalid-pin/src/android/security/net/config/cts/InvalidPinTest.java
@@ -25,7 +25,7 @@
}
public void testDefaultDomainUnaffected() throws Exception {
- TestUtils.assertTlsConnectionSucceeds("google.com", 443);
+ TestUtils.assertTlsConnectionSucceeds("example.com", 443);
TestUtils.assertTlsConnectionSucceeds("developer.android.com", 443);
}
}
diff --git a/tests/tests/security/src/android/security/cts/BannedFilesTest.java b/tests/tests/security/src/android/security/cts/BannedFilesTest.java
index 54709b4..95f4a70 100644
--- a/tests/tests/security/src/android/security/cts/BannedFilesTest.java
+++ b/tests/tests/security/src/android/security/cts/BannedFilesTest.java
@@ -150,4 +150,15 @@
assertTrue("File \"" + file + "\" is setUID", (fs.mode & FileUtils.S_ISUID) == 0);
assertTrue("File \"" + file + "\" is setGID", (fs.mode & FileUtils.S_ISGID) == 0);
}
+
+ /**
+ * Detect "rootmydevice" vulnerability
+ *
+ * References:
+ *
+ * http://www.theregister.co.uk/2016/05/09/allwinners_allloser_custom_kernel_has_a_nasty_root_backdoor/
+ */
+ public void testNoSunxiDebug() {
+ assertFalse("/proc/sunxi_debug/sunxi_debug", new File("/proc/sunxi_debug/sunxi_debug").exists());
+ }
}
diff --git a/tests/tests/shortcutmanager/Android.mk b/tests/tests/shortcutmanager/Android.mk
deleted file mode 100755
index 1f6bd27..0000000
--- a/tests/tests/shortcutmanager/Android.mk
+++ /dev/null
@@ -1,45 +0,0 @@
-# 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.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
- android-support-test \
- android-support-v4 \
- mockito-target \
- ctsdeviceutil \
- ctstestrunner \
- ub-uiautomator \
- ShortcutManagerTestUtils
-
-LOCAL_JAVA_LIBRARIES := android.test.runner
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := CtsShortcutManagerTestCases
-
-LOCAL_COMPATIBILITY_SUITE := cts
-
-LOCAL_SDK_VERSION := test_current
-
-include $(BUILD_CTS_PACKAGE)
-#include $(BUILD_PACKAGE)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/shortcutmanager/AndroidManifest.xml b/tests/tests/shortcutmanager/AndroidManifest.xml
deleted file mode 100755
index 19fe596..0000000
--- a/tests/tests/shortcutmanager/AndroidManifest.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.content.pm.cts.shortcutmanager"
- android:sharedUserId="android.content.pm.cts.shortcutmanager.packages">
-
- <application>
- <uses-library android:name="android.test.runner" />
- </application>
-
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
- android:targetPackage="android.content.pm.cts.shortcutmanager"
- android:label="CTS tests for ShortcutManager">
- <meta-data android:name="listener"
- android:value="com.android.cts.runner.CtsTestRunListener" />
- </instrumentation>
-
-</manifest>
-
diff --git a/tests/tests/shortcutmanager/AndroidTest.xml b/tests/tests/shortcutmanager/AndroidTest.xml
deleted file mode 100644
index 2955155..0000000
--- a/tests/tests/shortcutmanager/AndroidTest.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-<configuration description="Config for ShortcutManager CTS test cases">
- <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
- <option name="cleanup-apks" value="true" />
- <option name="test-file-name" value="CtsShortcutManagerTestCases.apk" />
- <option name="test-file-name" value="CtsShortcutManagerPackage1.apk" />
- <option name="test-file-name" value="CtsShortcutManagerPackage2.apk" />
- <option name="test-file-name" value="CtsShortcutManagerPackage3.apk" />
- <option name="test-file-name" value="CtsShortcutManagerPackage4.apk" />
- <option name="test-file-name" value="CtsShortcutManagerLauncher1.apk" />
- <option name="test-file-name" value="CtsShortcutManagerLauncher2.apk" />
- <option name="test-file-name" value="CtsShortcutManagerLauncher3.apk" />
- <option name="test-file-name" value="CtsShortcutManagerLauncher4.apk" />
- </target_preparer>
- <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
- <option name="package" value="android.content.pm.cts.shortcutmanager" />
- </test>
-</configuration>
\ No newline at end of file
diff --git a/tests/tests/shortcutmanager/packages/Android.mk b/tests/tests/shortcutmanager/packages/Android.mk
deleted file mode 100644
index 3d02f9c..0000000
--- a/tests/tests/shortcutmanager/packages/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-# 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.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/shortcutmanager/packages/launchermanifest/Android.mk b/tests/tests/shortcutmanager/packages/launchermanifest/Android.mk
deleted file mode 100644
index bacca5d..0000000
--- a/tests/tests/shortcutmanager/packages/launchermanifest/Android.mk
+++ /dev/null
@@ -1,75 +0,0 @@
-# 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.
-
-LOCAL_PATH:= $(call my-dir)
-
-#-----------------------------------------------------------
-include $(CLEAR_VARS)
-
-LOCAL_PACKAGE_NAME := CtsShortcutManagerPackage1
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, ../src)
-
-LOCAL_SDK_VERSION := current
-
-# tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts
-
-LOCAL_AAPT_FLAGS += --rename-manifest-package android.content.pm.cts.shortcutmanager.packages.package1
-
-include $(BUILD_CTS_PACKAGE)
-
-#-----------------------------------------------------------
-include $(CLEAR_VARS)
-
-LOCAL_PACKAGE_NAME := CtsShortcutManagerPackage2
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, ../src)
-
-LOCAL_SDK_VERSION := current
-
-# tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts
-
-LOCAL_AAPT_FLAGS += --rename-manifest-package android.content.pm.cts.shortcutmanager.packages.package2
-
-include $(BUILD_CTS_PACKAGE)
-
-#-----------------------------------------------------------
-include $(CLEAR_VARS)
-
-LOCAL_PACKAGE_NAME := CtsShortcutManagerPackage3
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, ../src)
-
-LOCAL_SDK_VERSION := current
-
-# tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts
-
-LOCAL_AAPT_FLAGS += --rename-manifest-package android.content.pm.cts.shortcutmanager.packages.package3
-
-include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/shortcutmanager/packages/launchermanifest/AndroidManifest.xml b/tests/tests/shortcutmanager/packages/launchermanifest/AndroidManifest.xml
deleted file mode 100755
index 039ed5c..0000000
--- a/tests/tests/shortcutmanager/packages/launchermanifest/AndroidManifest.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * 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.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.content.pm.cts.shortcutmanager.packages"
- android:sharedUserId="android.content.pm.cts.shortcutmanager.packages">
-
- <application>
- <activity android:name="Launcher">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.LAUNCHER" />
- <category android:name="android.intent.category.HOME" />
- </intent-filter>
- </activity>
- </application>
-</manifest>
-
diff --git a/tests/tests/shortcutmanager/packages/launchermanifest_nonshared/Android.mk b/tests/tests/shortcutmanager/packages/launchermanifest_nonshared/Android.mk
deleted file mode 100644
index 793fa66..0000000
--- a/tests/tests/shortcutmanager/packages/launchermanifest_nonshared/Android.mk
+++ /dev/null
@@ -1,34 +0,0 @@
-# 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.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_PACKAGE_NAME := CtsShortcutManagerPackage4
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, ../src)
-
-LOCAL_SDK_VERSION := current
-
-# tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts
-
-LOCAL_AAPT_FLAGS += --rename-manifest-package android.content.pm.cts.shortcutmanager.packages.package4
-
-include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/shortcutmanager/packages/packagemanifest/Android.mk b/tests/tests/shortcutmanager/packages/packagemanifest/Android.mk
deleted file mode 100644
index 8f9babd..0000000
--- a/tests/tests/shortcutmanager/packages/packagemanifest/Android.mk
+++ /dev/null
@@ -1,74 +0,0 @@
-# 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.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_PACKAGE_NAME := CtsShortcutManagerLauncher1
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, ../src)
-
-LOCAL_SDK_VERSION := current
-
-# tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts
-
-LOCAL_AAPT_FLAGS += --rename-manifest-package android.content.pm.cts.shortcutmanager.packages.launcher1
-
-include $(BUILD_CTS_PACKAGE)
-
-#-----------------------------------------------------------
-include $(CLEAR_VARS)
-
-LOCAL_PACKAGE_NAME := CtsShortcutManagerLauncher2
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, ../src)
-
-LOCAL_SDK_VERSION := current
-
-# tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts
-
-LOCAL_AAPT_FLAGS += --rename-manifest-package android.content.pm.cts.shortcutmanager.packages.launcher2
-
-include $(BUILD_CTS_PACKAGE)
-
-#-----------------------------------------------------------
-include $(CLEAR_VARS)
-
-LOCAL_PACKAGE_NAME := CtsShortcutManagerLauncher3
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, ../src)
-
-LOCAL_SDK_VERSION := current
-
-# tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts
-
-LOCAL_AAPT_FLAGS += --rename-manifest-package android.content.pm.cts.shortcutmanager.packages.launcher3
-
-include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/shortcutmanager/packages/packagemanifest/AndroidManifest.xml b/tests/tests/shortcutmanager/packages/packagemanifest/AndroidManifest.xml
deleted file mode 100755
index 463757d..0000000
--- a/tests/tests/shortcutmanager/packages/packagemanifest/AndroidManifest.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * 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.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.content.pm.cts.shortcutmanager.packages"
- android:sharedUserId="android.content.pm.cts.shortcutmanager.packages">
-
- <application>
- <activity android:name="android.content.pm.cts.shortcutmanager.packages.Launcher">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.LAUNCHER" />
- <category android:name="android.intent.category.HOME" />
- </intent-filter>
- </activity>
- </application>
-</manifest>
-
diff --git a/tests/tests/shortcutmanager/packages/packagemanifest_nonshared/AndroidManifest.xml b/tests/tests/shortcutmanager/packages/packagemanifest_nonshared/AndroidManifest.xml
deleted file mode 100755
index 05c9db7..0000000
--- a/tests/tests/shortcutmanager/packages/packagemanifest_nonshared/AndroidManifest.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * 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.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.content.pm.cts.shortcutmanager.packages">
-
- <application>
- </application>
-</manifest>
-
diff --git a/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerAidlCallPermissionTest.java b/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerAidlCallPermissionTest.java
deleted file mode 100644
index 30ef0cf..0000000
--- a/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerAidlCallPermissionTest.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * 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.content.pm.cts;
-
-/**
- * - Command line command permissions
- * - Internal AIDL call permissions.
- * - Faking parameter to the AIDL call (user-ID)
- */
-public class ShortcutManagerAidlCallPermissionTest {
-}
diff --git a/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerCtsTestsBase.java b/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerCtsTestsBase.java
deleted file mode 100644
index de725d6..0000000
--- a/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerCtsTestsBase.java
+++ /dev/null
@@ -1,338 +0,0 @@
-/*
- * 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.content.pm.cts;
-
-import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.*;
-
-import android.app.Activity;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.Intent;
-import android.content.pm.LauncherApps;
-import android.content.pm.ShortcutInfo;
-import android.content.pm.ShortcutManager;
-import android.graphics.drawable.Icon;
-import android.os.Bundle;
-import android.os.UserHandle;
-import android.support.annotation.NonNull;
-import android.test.InstrumentationTestCase;
-import android.text.TextUtils;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public abstract class ShortcutManagerCtsTestsBase extends InstrumentationTestCase {
-
- private static class SpoofingContext extends ContextWrapper {
- private final String mPackageName;
-
- public SpoofingContext(Context base, String packageName) {
- super(base);
- mPackageName = packageName;
- }
-
- @Override
- public String getPackageName() {
- return mPackageName;
- }
- }
-
- private Context mCurrentCallerPackage;
- private int mUserId;
- private UserHandle mUserHandle;
-
- private String mOriginalLauncher;
-
- protected Context mPackageContext1;
- protected Context mPackageContext2;
- protected Context mPackageContext3;
- protected Context mPackageContext4;
-
- protected Context mLauncherContext1;
- protected Context mLauncherContext2;
- protected Context mLauncherContext3;
- protected Context mLauncherContext4;
-
- protected LauncherApps mLauncherApps1;
- protected LauncherApps mLauncherApps2;
- protected LauncherApps mLauncherApps3;
- protected LauncherApps mLauncherApps4;
-
- private Map<Context, ShortcutManager> mManagers = new HashMap<>();
- private Map<Context, LauncherApps> mLauncherAppses = new HashMap<>();
-
- private ShortcutManager mCurrentManager;
- private LauncherApps mCurrentLauncherApps;
-
- private static class ShortcutActivity extends Activity {
- }
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
-
- mUserId = getTestContext().getUserId();
- mUserHandle = android.os.Process.myUserHandle();
-
- final String config = getOverrideConfig();
- if (config != null) {
- overrideConfig(getInstrumentation(), config);
- }
- mOriginalLauncher = getDefaultLauncher(getInstrumentation());
-
- mPackageContext1 = new SpoofingContext(getTestContext(),
- "android.content.pm.cts.shortcutmanager.packages.package1");
- mPackageContext2 = new SpoofingContext(getTestContext(),
- "android.content.pm.cts.shortcutmanager.packages.package2");
- mPackageContext3 = new SpoofingContext(getTestContext(),
- "android.content.pm.cts.shortcutmanager.packages.package3");
- mPackageContext4 = new SpoofingContext(getTestContext(),
- "android.content.pm.cts.shortcutmanager.packages.package4");
- mLauncherContext1 = new SpoofingContext(getTestContext(),
- "android.content.pm.cts.shortcutmanager.packages.launcher1");
- mLauncherContext2 = new SpoofingContext(getTestContext(),
- "android.content.pm.cts.shortcutmanager.packages.launcher2");
- mLauncherContext3 = new SpoofingContext(getTestContext(),
- "android.content.pm.cts.shortcutmanager.packages.launcher3");
- mLauncherContext4 = new SpoofingContext(getTestContext(),
- "android.content.pm.cts.shortcutmanager.packages.launcher4");
-
- mLauncherApps1 = new LauncherApps(mLauncherContext1);
- mLauncherApps2 = new LauncherApps(mLauncherContext2);
- mLauncherApps3 = new LauncherApps(mLauncherContext3);
- mLauncherApps4 = new LauncherApps(mLauncherContext4);
-
- clearShortcuts(getInstrumentation(), mUserId, mPackageContext1.getPackageName());
- clearShortcuts(getInstrumentation(), mUserId, mPackageContext2.getPackageName());
- clearShortcuts(getInstrumentation(), mUserId, mPackageContext3.getPackageName());
- clearShortcuts(getInstrumentation(), mUserId, mPackageContext4.getPackageName());
-
- setCurrentCaller(mPackageContext1);
-
- // Make sure shortcuts are removed.
- withCallers(getAllPublishers(), new Runnable() {
- @Override
- public void run() {
- assertEquals("for " + getCurrentCallingPackage(),
- 0, getManager().getDynamicShortcuts().size());
- assertEquals("for " + getCurrentCallingPackage(),
- 0, getManager().getPinnedShortcuts().size());
- }
- });
- // This was calling the wrong lambda.
-// withCallers(getAllPublishers(), () -> {
-// assertEquals("for " + getCurrentCallingPackage(),
-// 0, getManager().getDynamicShortcuts().size());
-// assertEquals("for " + getCurrentCallingPackage(),
-// 0, getManager().getPinnedShortcuts().size());
-// });
- }
-
- @Override
- protected void tearDown() throws Exception {
- resetConfig(getInstrumentation());
-
- if (!TextUtils.isEmpty(mOriginalLauncher)) {
- setDefaultLauncher(getInstrumentation(), mOriginalLauncher);
- }
-
- super.tearDown();
- }
-
- protected Context getTestContext() {
- return getInstrumentation().getContext();
- }
-
- protected UserHandle getUserHandle() {
- return mUserHandle;
- }
-
- protected List<Context> getAllPublishers() {
- // 4 has a different signature, so we can't call for it.
- return list(mPackageContext1, mPackageContext2, mPackageContext3);
- }
-
- protected List<Context> getAllLaunchers() {
- // 4 has a different signature, so we can't call for it.
- return list(mLauncherContext1, mLauncherContext2, mLauncherContext3);
- }
-
- protected List<Context> getAllCallers() {
- return list(
- mPackageContext1, mPackageContext2, mPackageContext3, mPackageContext4,
- mLauncherContext1, mLauncherContext2, mLauncherContext3, mLauncherContext4);
- }
-
- protected void withCallers(List<Context> callers, Runnable r) {
- for (Context c : callers) {
- runWithCaller(c, r);
- }
- }
-
- protected String getOverrideConfig() {
- return null;
- }
-
- protected void setCurrentCaller(Context callerContext) {
- mCurrentCallerPackage = callerContext;
-
- if (!mManagers.containsKey(mCurrentCallerPackage)) {
- mManagers.put(mCurrentCallerPackage, new ShortcutManager(mCurrentCallerPackage));
- }
- mCurrentManager = mManagers.get(mCurrentCallerPackage);
-
- if (!mLauncherAppses.containsKey(mCurrentCallerPackage)) {
- mLauncherAppses.put(mCurrentCallerPackage, new LauncherApps(mCurrentCallerPackage));
- }
- mCurrentLauncherApps = mLauncherAppses.get(mCurrentCallerPackage);
- }
-
- protected Context getCurrentCallerContext() {
- return mCurrentCallerPackage;
- }
-
- protected String getCurrentCallingPackage() {
- return getCurrentCallerContext().getPackageName();
- }
-
- protected ShortcutManager getManager() {
- return mCurrentManager;
- }
-
- protected LauncherApps getLauncherApps() {
- return mCurrentLauncherApps;
- }
-
- protected void runWithCaller(Context callerContext, Runnable r) {
- final Context prev = mCurrentCallerPackage;
-
- setCurrentCaller(callerContext);
-
- r.run();
-
- setCurrentCaller(prev);
- }
-
- public static Bundle makeBundle(Object... keysAndValues) {
- assertTrue((keysAndValues.length % 2) == 0);
-
- if (keysAndValues.length == 0) {
- return null;
- }
- final Bundle ret = new Bundle();
-
- for (int i = keysAndValues.length - 2; i >= 0; i -= 2) {
- final String key = keysAndValues[i].toString();
- final Object value = keysAndValues[i + 1];
-
- if (value == null) {
- ret.putString(key, null);
- } else if (value instanceof Integer) {
- ret.putInt(key, (Integer) value);
- } else if (value instanceof String) {
- ret.putString(key, (String) value);
- } else if (value instanceof Bundle) {
- ret.putBundle(key, (Bundle) value);
- } else {
- fail("Type not supported yet: " + value.getClass().getName());
- }
- }
- return ret;
- }
-
- /**
- * Make a shortcut with an ID.
- */
- protected ShortcutInfo makeShortcut(String id) {
- return makeShortcut(id, "Title-" + id);
- }
-
- /**
- * Make a shortcut with an ID and a title.
- */
- protected ShortcutInfo makeShortcut(String id, String title) {
- return makeShortcut(
- id, title, /* activity =*/ null, /* icon =*/ null,
- makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* weight =*/ 0);
- }
-
- /**
- * Make a shortcut with an ID and icon.
- */
- protected ShortcutInfo makeShortcutWithIcon(String id, Icon icon) {
- return makeShortcut(
- id, "Title-" + id, /* activity =*/ null, icon,
- makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* weight =*/ 0);
- }
-
- /**
- * Make multiple shortcuts with IDs.
- */
- protected List<ShortcutInfo> makeShortcuts(String... ids) {
- final ArrayList<ShortcutInfo> ret = new ArrayList();
- for (String id : ids) {
- ret.add(makeShortcut(id));
- }
- return ret;
- }
-
- protected ShortcutInfo.Builder makeShortcutBuilder() {
- return new ShortcutInfo.Builder(getCurrentCallerContext());
- }
-
- /**
- * Make a shortcut with details.
- */
- protected ShortcutInfo makeShortcut(String id, String title, ComponentName activity,
- Icon icon, Intent intent, int weight) {
- final ShortcutInfo.Builder b = new ShortcutInfo.Builder(getCurrentCallerContext())
- .setId(id)
- .setTitle(title)
- .setWeight(weight)
- .setIntent(intent);
- if (icon != null) {
- b.setIcon(icon);
- }
- if (activity != null) {
- b.setActivityComponent(activity);
- }
- final ShortcutInfo s = b.build();
-
- return s;
- }
-
- /**
- * Make an intent.
- */
- protected Intent makeIntent(String action, Class<?> clazz, Object... bundleKeysAndValues) {
- final Intent intent = new Intent(action);
- intent.setComponent(makeComponent(clazz));
- intent.replaceExtras(makeBundle(bundleKeysAndValues));
- return intent;
- }
-
- /**
- * Make an component name, with the client context.
- */
- @NonNull
- protected ComponentName makeComponent(Class<?> clazz) {
- return new ComponentName(getCurrentCallerContext(), clazz);
- }
-
-}
diff --git a/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerDynamicCountTest.java b/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerDynamicCountTest.java
deleted file mode 100644
index 110960a..0000000
--- a/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerDynamicCountTest.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.content.pm.cts;
-
-import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertDynamicShortcutCountExceeded;
-import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;
-
-public class ShortcutManagerDynamicCountTest extends ShortcutManagerCtsTestsBase {
-
- @Override
- protected String getOverrideConfig() {
- return "reset_interval_sec=999999,"
- + "max_updates_per_interval=999999,"
- + "max_shortcuts=3,"
- + "max_icon_dimension_dp=128,"
- + "max_icon_dimension_dp_lowram=32,"
- + "icon_format=PNG,"
- + "icon_quality=100";
- }
-
- public void testSetDynamicShortcuts() {
- runWithCaller(mPackageContext1, () -> {
- getManager().setDynamicShortcuts(list(makeShortcut("s1")));
- getManager().setDynamicShortcuts(list(
- makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3")));
-
- assertDynamicShortcutCountExceeded(() -> {
- getManager().setDynamicShortcuts(list(
- makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"),
- makeShortcut("s4")));
- });
- });
- }
-}
diff --git a/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerNoThrottlingTest.java b/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerNoThrottlingTest.java
deleted file mode 100644
index 92b1a46..0000000
--- a/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerNoThrottlingTest.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * 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.content.pm.cts;
-
-import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertCallbackNotReceived;
-import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertCallbackReceived;
-import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertExpectException;
-import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.checkAssertSuccess;
-import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;
-import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.resetAll;
-import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.setDefaultLauncher;
-import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.waitUntil;
-
-import static org.mockito.Mockito.mock;
-
-import android.content.pm.LauncherApps;
-import android.content.pm.ShortcutInfo;
-import android.content.pm.ShortcutManager;
-import android.os.Handler;
-import android.os.Looper;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import java.util.List;
-
-/**
- * Tests for {@link ShortcutManager} and {@link ShortcutInfo}.
- *
- * In this test, we tests the main functionalities of those, without throttling. We
- */
-@SmallTest
-public class ShortcutManagerNoThrottlingTest extends ShortcutManagerCtsTestsBase {
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- @Override
- protected String getOverrideConfig() {
- return "reset_interval_sec=999999,"
- + "max_updates_per_interval=999999,"
- + "max_shortcuts=10,"
- + "max_icon_dimension_dp=128,"
- + "max_icon_dimension_dp_lowram=32,"
- + "icon_format=PNG,"
- + "icon_quality=100";
- }
-
- public void testShortcutInfoMissingMandatoryFields() {
- assertExpectException(
- IllegalArgumentException.class,
- "ID must be provided",
- () -> new ShortcutInfo.Builder(getTestContext()).build());
- assertExpectException(
- IllegalArgumentException.class, "title must be provided", () -> {
- ShortcutInfo si = new ShortcutInfo.Builder(getTestContext()).setId("id").build();
- getManager().setDynamicShortcuts(list(si));
- });
- assertExpectException(
- NullPointerException.class, "Intent must be provided", () -> {
- ShortcutInfo si = new ShortcutInfo.Builder(getTestContext()).setId("id").setTitle("x")
- .build();
- getManager().setDynamicShortcuts(list(si));
- });
- }
-
- /**
- * Create shortcuts from different packages and make sure they're really different.
- */
- public void testSpoofingPublisher() {
- runWithCaller(mPackageContext1, () -> {
- ShortcutInfo s1 = makeShortcut("s1", "title1");
- getManager().setDynamicShortcuts(list(s1));
- });
- runWithCaller(mPackageContext2, () -> {
- ShortcutInfo s1 = makeShortcut("s1", "title2");
- getManager().setDynamicShortcuts(list(s1));
- });
- runWithCaller(mPackageContext3, () -> {
- ShortcutInfo s1 = makeShortcut("s1", "title3");
- getManager().setDynamicShortcuts(list(s1));
- });
-
- runWithCaller(mPackageContext1, () -> {
- final List<ShortcutInfo> list = getManager().getDynamicShortcuts();
- assertEquals(1, list.size());
- assertEquals("title1", list.get(0).getTitle());
- });
- runWithCaller(mPackageContext2, () -> {
- final List<ShortcutInfo> list = getManager().getDynamicShortcuts();
- assertEquals(1, list.size());
- assertEquals("title2", list.get(0).getTitle());
- });
- runWithCaller(mPackageContext3, () -> {
- final List<ShortcutInfo> list = getManager().getDynamicShortcuts();
- assertEquals(1, list.size());
- assertEquals("title3", list.get(0).getTitle());
- });
- }
-
- public void testSpoofingLauncher() {
- final LauncherApps.Callback c0_1 = mock(LauncherApps.Callback.class);
- final LauncherApps.Callback c0_2 = mock(LauncherApps.Callback.class);
- final LauncherApps.Callback c0_3 = mock(LauncherApps.Callback.class);
- final Handler h = new Handler(Looper.getMainLooper());
-
- runWithCaller(mLauncherContext1, () -> getLauncherApps().registerCallback(c0_1, h));
- runWithCaller(mLauncherContext2, () -> getLauncherApps().registerCallback(c0_2, h));
- runWithCaller(mLauncherContext3, () -> getLauncherApps().registerCallback(c0_3, h));
-
- // Change the default launcher
- setDefaultLauncher(getInstrumentation(), mLauncherContext2);
-
- runWithCaller(mLauncherContext1,
- () -> assertFalse(getLauncherApps().hasShortcutHostPermission()));
- runWithCaller(mLauncherContext2,
- () -> assertTrue(getLauncherApps().hasShortcutHostPermission()));
- runWithCaller(mLauncherContext3,
- () -> assertFalse(getLauncherApps().hasShortcutHostPermission()));
-
- // Call a publisher API and make sure only launcher2 gets it.
-
- resetAll(list(c0_1, c0_2, c0_3));
-
- runWithCaller(mPackageContext1, () -> {
- ShortcutInfo s1 = makeShortcut("s1", "title1");
- getManager().setDynamicShortcuts(list(s1));
- });
-
- // Because of the handlers, callback calls are not synchronous.
- waitUntil("Launcher 2 didn't receive message", () ->
- checkAssertSuccess(() ->
- assertCallbackReceived(c0_2, android.os.Process.myUserHandle(),
- mPackageContext1.getPackageName(), "s1")
- )
- );
-
- assertCallbackNotReceived(c0_1);
- assertCallbackNotReceived(c0_3);
- }
-}
diff --git a/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerSpoofDetectionTest.java b/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerSpoofDetectionTest.java
deleted file mode 100644
index 37658ae..0000000
--- a/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerSpoofDetectionTest.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * 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.content.pm.cts;
-
-import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertExpectException;
-import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;
-
-import static org.mockito.Mockito.mock;
-
-import android.content.Context;
-import android.content.pm.LauncherApps;
-import android.content.pm.LauncherApps.ShortcutQuery;
-import android.content.pm.ShortcutInfo;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.ParcelFileDescriptor;
-
-import java.io.IOException;
-
-public class ShortcutManagerSpoofDetectionTest extends ShortcutManagerCtsTestsBase {
-
- @Override
- protected String getOverrideConfig() {
- return "reset_interval_sec=999999,"
- + "max_updates_per_interval=999999,"
- + "max_shortcuts=10,"
- + "max_icon_dimension_dp=128,"
- + "max_icon_dimension_dp_lowram=32,"
- + "icon_format=PNG,"
- + "icon_quality=100";
- }
-
- public void assertCallingPackageMismatch(String method, Context callerContext, Runnable r) {
- assertExpectException(
- "Caller=" + callerContext.getPackageName() + ", method=" + method,
- SecurityException.class, "Calling package name mismatch",
- () -> runWithCaller(callerContext, () -> r.run())
- );
- }
-
- public void testPublisherSpoofing() {
- assertCallingPackageMismatch("setDynamicShortcuts", mPackageContext4, () -> {
- getManager().setDynamicShortcuts(list(makeShortcut("s1")));
- });
- assertCallingPackageMismatch("addDynamicShortcut", mPackageContext4, () -> {
- getManager().addDynamicShortcuts(list(makeShortcut("s1")));
- });
- assertCallingPackageMismatch("deleteDynamicShortcut", mPackageContext4, () -> {
- getManager().removeDynamicShortcuts(list("s1"));
- });
- assertCallingPackageMismatch("deleteAllDynamicShortcuts", mPackageContext4, () -> {
- getManager().removeAllDynamicShortcuts();
- });
- assertCallingPackageMismatch("getDynamicShortcuts", mPackageContext4, () -> {
- getManager().getDynamicShortcuts();
- });
- assertCallingPackageMismatch("getPinnedShortcuts", mPackageContext4, () -> {
- getManager().getPinnedShortcuts();
- });
- assertCallingPackageMismatch("updateShortcuts", mPackageContext4, () -> {
- getManager().updateShortcuts(list(makeShortcut("s1")));
- });
- assertCallingPackageMismatch("getMaxDynamicShortcutCount", mPackageContext4, () -> {
- getManager().getMaxDynamicShortcutCount();
- });
- assertCallingPackageMismatch("getRemainingCallCount", mPackageContext4, () -> {
- getManager().getRemainingCallCount();
- });
- assertCallingPackageMismatch("getRateLimitResetTime", mPackageContext4, () -> {
- getManager().getRateLimitResetTime();
- });
- assertCallingPackageMismatch("getIconMaxDimensions", mPackageContext4, () -> {
- getManager().getIconMaxDimensions();
- });
- }
-
- public void testLauncherSpoofing() {
- assertCallingPackageMismatch("hasShortcutHostPermission", mLauncherContext4, () -> {
- getLauncherApps().hasShortcutHostPermission();
- });
-
- assertCallingPackageMismatch("registerCallback", mLauncherContext4, () -> {
- final LauncherApps.Callback c = mock(LauncherApps.Callback.class);
- getLauncherApps().registerCallback(c, new Handler(Looper.getMainLooper()));
- });
-
- assertCallingPackageMismatch("getShortcuts", mLauncherContext4, () -> {
- ShortcutQuery q = new ShortcutQuery();
- getLauncherApps().getShortcuts(q, getUserHandle());
- });
-
- assertCallingPackageMismatch("pinShortcuts", mLauncherContext4, () -> {
- getLauncherApps().pinShortcuts(
- mPackageContext1.getPackageName(), list(), getUserHandle());
- });
-
- assertCallingPackageMismatch("getShortcutIconFd 1", mLauncherContext4, () -> {
- ParcelFileDescriptor pfd = getLauncherApps().getShortcutIconFd(makeShortcut("s"));
- try {
- pfd.close();
- } catch (IOException e) {
- }
- });
- assertCallingPackageMismatch("getShortcutIconFd 2", mLauncherContext4, () -> {
- ParcelFileDescriptor pfd = getLauncherApps().getShortcutIconFd(
- mPackageContext1.getPackageName(), "s1", getUserHandle());
- try {
- pfd.close();
- } catch (IOException e) {
- }
- });
-
- assertCallingPackageMismatch("startShortcut 1", mLauncherContext4, () -> {
- getLauncherApps().startShortcut(makeShortcut("s"), null, null);
- });
- assertCallingPackageMismatch("startShortcut 2", mLauncherContext4, () -> {
- getLauncherApps().startShortcut(mPackageContext1.getPackageName(), "s1",
- null, null, getUserHandle());
- });
- }
-}
diff --git a/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerThrottlingTest.java b/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerThrottlingTest.java
deleted file mode 100644
index 8347bc0..0000000
--- a/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerThrottlingTest.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * 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.content.pm.cts;
-
-import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.*;
-
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.Suppress;
-
-import java.util.List;
-import java.util.function.BooleanSupplier;
-
-public class ShortcutManagerThrottlingTest extends ShortcutManagerCtsTestsBase {
- private static final String CONFIG_BASE =
- "max_updates_per_interval=5,"
- + "max_shortcuts=10,"
- + "max_icon_dimension_dp=128,"
- + "max_icon_dimension_dp_lowram=32,"
- + "icon_format=PNG,"
- + "icon_quality=100";
-
- private static final String CONFIG_3SEC = CONFIG_BASE + ",reset_interval_sec=3";
-
- @Override
- protected String getOverrideConfig() {
- return CONFIG_3SEC;
- }
-
- private void resetThrottling() {
- resetAllThrottling(getInstrumentation());
- assertEquals(5, getManager().getRemainingCallCount());
- }
-
- private void waitUntilReset() {
- final long resetTime = getManager().getRateLimitResetTime();
- final long sleepTime = resetTime - System.currentTimeMillis();
-
- if (sleepTime > 0) {
- try {
- Thread.sleep(sleepTime);
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- }
- }
- }
-
- private void clearDynamicShortcuts() {
- getManager().removeAllDynamicShortcuts();
- assertEquals(0, getManager().getDynamicShortcuts().size());
- }
-
- /**
- * Run the given test, except for making it's okay to get an AssertionError, when the test took
- * longer and the reset has happened.
- */
- private void runButOkayIfItTakesLonger(Runnable r) {
- final long nextResetTime = getManager().getRateLimitResetTime();
-
- try {
- r.run();
- } catch (AssertionError e) {
- if (System.currentTimeMillis() < nextResetTime) {
- throw e;
- }
- }
- }
-
- private void checkThrottled(BooleanSupplier apiCall, Runnable nonThrottledAssert,
- Runnable throttledAssert) {
- resetThrottling();
-
- runButOkayIfItTakesLonger(() -> {
- // Can call 5 times successfully.
- assertTrue(apiCall.getAsBoolean());
- nonThrottledAssert.run();
- assertEquals(4, getManager().getRemainingCallCount());
-
- assertTrue(apiCall.getAsBoolean());
- nonThrottledAssert.run();
- assertEquals(3, getManager().getRemainingCallCount());
-
- assertTrue(apiCall.getAsBoolean());
- nonThrottledAssert.run();
- assertEquals(2, getManager().getRemainingCallCount());
-
- assertTrue(apiCall.getAsBoolean());
- nonThrottledAssert.run();
- assertEquals(1, getManager().getRemainingCallCount());
-
- assertTrue(apiCall.getAsBoolean());
- nonThrottledAssert.run();
- assertEquals(0, getManager().getRemainingCallCount());
-
- // Now throttled.
- assertFalse(apiCall.getAsBoolean());
- throttledAssert.run();
- assertEquals(0, getManager().getRemainingCallCount());
-
- // Still throttled.
- assertFalse(apiCall.getAsBoolean());
- throttledAssert.run();
-
- assertEquals(0, getManager().getRemainingCallCount());
- });
-
- // However, it shouldn't affect other packages.
- runWithCaller(mPackageContext3, () -> {
- assertEquals(5, getManager().getRemainingCallCount());
- });
-
- // Wait until reset, then retry.
- waitUntilReset();
- assertEquals(5, getManager().getRemainingCallCount());
-
- runButOkayIfItTakesLonger(() -> {
-
- assertTrue(apiCall.getAsBoolean());
- nonThrottledAssert.run();
- assertEquals(4, getManager().getRemainingCallCount());
- });
- }
-
- /**
- * Make sure {@link android.content.pm.ShortcutManager#setDynamicShortcuts(List)} correctly
- * throttles calls.
- *
- * <p>Suppressed for now -- because when an instrumentation test is running, the process
- * will be in the PROCESS_STATE_FOREGROUND_SERVICE state, so none of calls will be throttled.
- * Need a different way to verify this.
- */
- @Suppress
- @LargeTest
- public void testThrottled_setDynamicShortcuts() {
- runWithCaller(mPackageContext1, () -> {
- checkThrottled(
- () -> {
- clearDynamicShortcuts();
- return getManager().setDynamicShortcuts(list(makeShortcut("s1")));
- }, () -> { // Non-throttled assert.
- assertEquals(1, getManager().getDynamicShortcuts().size());
- }, () -> { // Throttled assert.
- assertEquals(0, getManager().getDynamicShortcuts().size());
- });
- });
- }
-
- private void checkNotThrottled(Runnable apiCall) {
- resetThrottling();
-
- // Can call more than 5 times.
- apiCall.run();
- assertEquals(5, getManager().getRemainingCallCount());
-
- apiCall.run();
- assertEquals(5, getManager().getRemainingCallCount());
-
- apiCall.run();
- assertEquals(5, getManager().getRemainingCallCount());
-
- apiCall.run();
- assertEquals(5, getManager().getRemainingCallCount());
-
- apiCall.run();
- assertEquals(5, getManager().getRemainingCallCount());
-
- apiCall.run();
- assertEquals(5, getManager().getRemainingCallCount());
-
- apiCall.run();
- assertEquals(5, getManager().getRemainingCallCount());
- }
-
- public void testNotThrottled_delete() {
- runWithCaller(mPackageContext1, () -> {
- checkNotThrottled(() -> getManager().removeAllDynamicShortcuts());
-
- checkNotThrottled(() -> getManager().removeDynamicShortcuts(list("s1")));
- });
- }
-
- public void testNotThrottled_getShortcuts() {
- // Preparation: Create some shortcuts, and pin some.
- runWithCaller(mPackageContext1, () -> {
- getManager().setDynamicShortcuts(list(makeShortcut("s1"), makeShortcut("s2")));
- });
-
- setDefaultLauncher(getInstrumentation(), mLauncherContext2);
- runWithCaller(mLauncherContext2, () -> {
- getLauncherApps().pinShortcuts(
- mPackageContext1.getPackageName(), list("s2"), getUserHandle());
- });
-
- // Then check.
- runWithCaller(mPackageContext1, () -> {
- resetThrottling();
- checkNotThrottled(() ->
- assertShortcutIds(getManager().getDynamicShortcuts(), "s1", "s2"));
-
- checkNotThrottled(() ->
- assertShortcutIds(getManager().getPinnedShortcuts(), "s2"));
- });
- }
-
- public void testNotThrottled_misc() {
- runWithCaller(mPackageContext1, () -> {
- checkNotThrottled(() -> getManager().getIconMaxDimensions());
-
- checkNotThrottled(() -> getManager().getRateLimitResetTime());
-
- checkNotThrottled(() ->
- assertEquals(10, getManager().getMaxDynamicShortcutCount()));
- });
- }
-}
diff --git a/tests/tests/view/src/android/view/cts/ViewTest.java b/tests/tests/view/src/android/view/cts/ViewTest.java
index 6a431a2..3f667f5 100644
--- a/tests/tests/view/src/android/view/cts/ViewTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewTest.java
@@ -85,13 +85,13 @@
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
+import android.widget.FrameLayout;
import android.widget.LinearLayout;
-import android.widget.ListView;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.List;
+import java.util.Collections;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -1131,6 +1131,69 @@
assertEquals(view, viewList.get(0));
}
+ public void testAddFocusablesWithoutTouchMode() {
+ View view = new View(mActivity);
+ assertFalse("test sanity", view.isInTouchMode());
+ focusableInTouchModeTest(view, false);
+ }
+
+ public void testAddFocusablesInTouchMode() {
+ View view = spy(new View(mActivity));
+ when(view.isInTouchMode()).thenReturn(true);
+ focusableInTouchModeTest(view, true);
+ }
+
+ private void focusableInTouchModeTest(View view, boolean inTouchMode) {
+ ArrayList<View> views = new ArrayList<View>();
+
+ view.setFocusableInTouchMode(false);
+ view.setFocusable(true);
+
+ view.addFocusables(views, View.FOCUS_FORWARD);
+ if (inTouchMode) {
+ assertEquals(Collections.emptyList(), views);
+ } else {
+ assertEquals(Collections.singletonList(view), views);
+ }
+
+
+ views.clear();
+ view.addFocusables(views, View.FOCUS_FORWARD, View.FOCUSABLES_ALL);
+ assertEquals(Collections.singletonList(view), views);
+
+ views.clear();
+ view.addFocusables(views, View.FOCUS_FORWARD, View.FOCUSABLES_TOUCH_MODE);
+ assertEquals(Collections.emptyList(), views);
+
+ view.setFocusableInTouchMode(true);
+
+ views.clear();
+ view.addFocusables(views, View.FOCUS_FORWARD);
+ assertEquals(Collections.singletonList(view), views);
+
+ views.clear();
+ view.addFocusables(views, View.FOCUS_FORWARD, View.FOCUSABLES_ALL);
+ assertEquals(Collections.singletonList(view), views);
+
+ views.clear();
+ view.addFocusables(views, View.FOCUS_FORWARD, View.FOCUSABLES_TOUCH_MODE);
+ assertEquals(Collections.singletonList(view), views);
+
+ view.setFocusable(false);
+
+ views.clear();
+ view.addFocusables(views, View.FOCUS_FORWARD);
+ assertEquals(Collections.emptyList(), views);
+
+ views.clear();
+ view.addFocusables(views, View.FOCUS_FORWARD, View.FOCUSABLES_ALL);
+ assertEquals(Collections.emptyList(), views);
+
+ views.clear();
+ view.addFocusables(views, View.FOCUS_FORWARD, View.FOCUSABLES_TOUCH_MODE);
+ assertEquals(Collections.emptyList(), views);
+ }
+
public void testGetRootView() {
MockView view = new MockView(mActivity);
diff --git a/tests/tests/widget/src/android/widget/cts/AttachDetachAwareView.java b/tests/tests/widget/src/android/widget/cts/AttachDetachAwareView.java
new file mode 100644
index 0000000..491e951
--- /dev/null
+++ b/tests/tests/widget/src/android/widget/cts/AttachDetachAwareView.java
@@ -0,0 +1,41 @@
+/*
+ * 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.widget.cts;
+
+import android.content.Context;
+import android.view.View;
+
+class AttachDetachAwareView extends View {
+ int mOnAttachCount = 0;
+ int mOnDetachCount = 0;
+
+ public AttachDetachAwareView(Context context) {
+ super(context);
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ mOnAttachCount++;
+ super.onAttachedToWindow();
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ mOnDetachCount++;
+ super.onDetachedFromWindow();
+ }
+}
diff --git a/tests/tests/widget/src/android/widget/cts/DummyAdapter.java b/tests/tests/widget/src/android/widget/cts/DummyAdapter.java
new file mode 100644
index 0000000..0e1a40c
--- /dev/null
+++ b/tests/tests/widget/src/android/widget/cts/DummyAdapter.java
@@ -0,0 +1,69 @@
+/*
+ * 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.widget.cts;
+
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+
+class DummyAdapter extends BaseAdapter {
+ int mCount;
+ // these are views w/ special types and are returned as requested
+ View[] mSpecialViews;
+
+ public DummyAdapter(int count, View... specialViews) {
+ mCount = count;
+ mSpecialViews = specialViews;
+ }
+
+ @Override
+ public int getCount() {
+ return mCount;
+ }
+
+ @Override
+ public Object getItem(int position) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return 0;
+ }
+
+ @Override
+ public int getViewTypeCount() {
+ return mSpecialViews.length + 1;
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return position < mSpecialViews.length ? position : mSpecialViews.length;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ if (position < mSpecialViews.length) {
+ return mSpecialViews[position];
+ }
+ if (convertView == null) {
+ convertView = new View(parent.getContext());
+ convertView.setMinimumHeight(200);
+ }
+ return convertView;
+ }
+}
\ No newline at end of file
diff --git a/tests/tests/widget/src/android/widget/cts/GridViewTest.java b/tests/tests/widget/src/android/widget/cts/GridViewTest.java
index 8698280..7b83416 100644
--- a/tests/tests/widget/src/android/widget/cts/GridViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/GridViewTest.java
@@ -16,6 +16,7 @@
package android.widget.cts;
+import android.test.suitebuilder.annotation.MediumTest;
import android.widget.cts.R;
@@ -47,6 +48,7 @@
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.AdapterView.OnItemClickListener;
+import android.widget.cts.util.ViewTestUtils;
/**
* Test {@link GridView}.
@@ -566,6 +568,81 @@
assertEquals(child0.getLeft(), child1.getLeft());
}
+ @MediumTest
+ public void testFullyDetachUnusedViewOnScroll() {
+ mGridView = findGridViewById(R.id.gridview);
+ final AttachDetachAwareView theView = new AttachDetachAwareView(mActivity);
+ ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mGridView, () -> {
+ mGridView.setAdapter(new DummyAdapter(1000, theView));
+ });
+ assertEquals("test sanity", 1, theView.mOnAttachCount);
+ assertEquals("test sanity", 0, theView.mOnDetachCount);
+ ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mGridView, () -> {
+ mGridView.scrollListBy(mGridView.getHeight() * 2);
+ });
+ assertNull("test sanity, unused view should be removed", theView.getParent());
+ assertEquals("unused view should be detached", 1, theView.mOnDetachCount);
+ assertFalse(theView.isTemporarilyDetached());
+ ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mGridView, () -> {
+ mGridView.scrollListBy(-mGridView.getHeight() * 2);
+ // listview limits scroll to 1 page which is why we call it twice here.
+ mGridView.scrollListBy(-mGridView.getHeight() * 2);
+ });
+ assertNotNull("test sanity, view should be re-added", theView.getParent());
+ assertEquals("view should receive another attach call", 2, theView.mOnAttachCount);
+ assertEquals("view should not receive a detach call", 1, theView.mOnDetachCount);
+ assertFalse(theView.isTemporarilyDetached());
+ }
+
+ @MediumTest
+ public void testFullyDetachUnusedViewOnReLayout() {
+ mGridView = findGridViewById(R.id.gridview);
+ final AttachDetachAwareView theView = new AttachDetachAwareView(mActivity);
+ ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mGridView, () -> {
+ mGridView.setAdapter(new DummyAdapter(1000, theView));
+ });
+ assertEquals("test sanity", 1, theView.mOnAttachCount);
+ assertEquals("test sanity", 0, theView.mOnDetachCount);
+ ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mGridView, () -> {
+ mGridView.setSelection(800);
+ });
+ assertNull("test sanity, unused view should be removed", theView.getParent());
+ assertEquals("unused view should be detached", 1, theView.mOnDetachCount);
+ assertFalse(theView.isTemporarilyDetached());
+ ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mGridView, () -> {
+ mGridView.setSelection(0);
+ });
+ assertNotNull("test sanity, view should be re-added", theView.getParent());
+ assertEquals("view should receive another attach call", 2, theView.mOnAttachCount);
+ assertEquals("view should not receive a detach call", 1, theView.mOnDetachCount);
+ assertFalse(theView.isTemporarilyDetached());
+ }
+
+ @MediumTest
+ public void testFullyDetachUnusedViewOnScrollForFocus() {
+ mGridView = findGridViewById(R.id.gridview);
+ final AttachDetachAwareView theView = new AttachDetachAwareView(mActivity);
+ ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mGridView, () -> {
+ mGridView.setAdapter(new DummyAdapter(1000, theView));
+ });
+ assertEquals("test sanity", 1, theView.mOnAttachCount);
+ assertEquals("test sanity", 0, theView.mOnDetachCount);
+ while(theView.getParent() != null) {
+ assertEquals("the view should NOT be detached", 0, theView.mOnDetachCount);
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mGridView, null);
+ }
+ assertEquals("the view should be detached", 1, theView.mOnDetachCount);
+ assertFalse(theView.isTemporarilyDetached());
+ while(theView.getParent() == null) {
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+ ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mGridView, null);
+ }
+ assertEquals("the view should be re-attached", 2, theView.mOnAttachCount);
+ assertEquals("the view should not recieve another detach", 1, theView.mOnDetachCount);
+ assertFalse(theView.isTemporarilyDetached());
+ }
+
private static class MockGridView extends GridView {
private boolean mCalledOnMeasure = false;
private boolean mCalledOnFocusChanged = false;
diff --git a/tests/tests/widget/src/android/widget/cts/ListViewTest.java b/tests/tests/widget/src/android/widget/cts/ListViewTest.java
index b5a92e9..13f5fe7 100644
--- a/tests/tests/widget/src/android/widget/cts/ListViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ListViewTest.java
@@ -16,6 +16,7 @@
package android.widget.cts;
+import android.widget.BaseAdapter;
import android.widget.cts.R;
import org.xmlpull.v1.XmlPullParser;
@@ -615,6 +616,130 @@
listView.layout(0, 0, 100, 100);
}
+ @MediumTest
+ public void testFullDetachHeaderViewOnScroll() {
+ final AttachDetachAwareView header = new AttachDetachAwareView(mActivity);
+ ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mListView, () -> {
+ mListView.setAdapter(new DummyAdapter(1000));
+ mListView.addHeaderView(header);
+ });
+ assertEquals("test sanity", 1, header.mOnAttachCount);
+ assertEquals("test sanity", 0, header.mOnDetachCount);
+ ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mListView, () -> {
+ mListView.scrollListBy(mListView.getHeight() * 3);
+ });
+ assertNull("test sanity, header should be removed", header.getParent());
+ assertEquals("header view should be detached", 1, header.mOnDetachCount);
+ assertFalse(header.isTemporarilyDetached());
+ }
+
+ @MediumTest
+ public void testFullDetachHeaderViewOnRelayout() {
+ final AttachDetachAwareView header = new AttachDetachAwareView(mActivity);
+ ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mListView, () -> {
+ mListView.setAdapter(new DummyAdapter(1000));
+ mListView.addHeaderView(header);
+ });
+ assertEquals("test sanity", 1, header.mOnAttachCount);
+ assertEquals("test sanity", 0, header.mOnDetachCount);
+ ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mListView, () -> {
+ mListView.setSelection(800);
+ });
+ assertNull("test sanity, header should be removed", header.getParent());
+ assertEquals("header view should be detached", 1, header.mOnDetachCount);
+ assertFalse(header.isTemporarilyDetached());
+ }
+
+ @MediumTest
+ public void testFullDetachHeaderViewOnScrollForFocus() {
+ final AttachDetachAwareView header = new AttachDetachAwareView(mActivity);
+ ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mListView, () -> {
+ mListView.setAdapter(new DummyAdapter(1000));
+ mListView.addHeaderView(header);
+ });
+ assertEquals("test sanity", 1, header.mOnAttachCount);
+ assertEquals("test sanity", 0, header.mOnDetachCount);
+ while(header.getParent() != null) {
+ assertEquals("header view should NOT be detached", 0, header.mOnDetachCount);
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mListView, null);
+ }
+ assertEquals("header view should be detached", 1, header.mOnDetachCount);
+ assertFalse(header.isTemporarilyDetached());
+ }
+
+ @MediumTest
+ public void testFullyDetachUnusedViewOnScroll() {
+ final AttachDetachAwareView theView = new AttachDetachAwareView(mActivity);
+ ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mListView, () -> {
+ mListView.setAdapter(new DummyAdapter(1000, theView));
+ });
+ assertEquals("test sanity", 1, theView.mOnAttachCount);
+ assertEquals("test sanity", 0, theView.mOnDetachCount);
+ ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mListView, () -> {
+ mListView.scrollListBy(mListView.getHeight() * 2);
+ });
+ assertNull("test sanity, unused view should be removed", theView.getParent());
+ assertEquals("unused view should be detached", 1, theView.mOnDetachCount);
+ assertFalse(theView.isTemporarilyDetached());
+ ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mListView, () -> {
+ mListView.scrollListBy(-mListView.getHeight() * 2);
+ // listview limits scroll to 1 page which is why we call it twice here.
+ mListView.scrollListBy(-mListView.getHeight() * 2);
+ });
+ assertNotNull("test sanity, view should be re-added", theView.getParent());
+ assertEquals("view should receive another attach call", 2, theView.mOnAttachCount);
+ assertEquals("view should not receive a detach call", 1, theView.mOnDetachCount);
+ assertFalse(theView.isTemporarilyDetached());
+ }
+
+ @MediumTest
+ public void testFullyDetachUnusedViewOnReLayout() {
+ final AttachDetachAwareView theView = new AttachDetachAwareView(mActivity);
+ ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mListView, () -> {
+ mListView.setAdapter(new DummyAdapter(1000, theView));
+ });
+ assertEquals("test sanity", 1, theView.mOnAttachCount);
+ assertEquals("test sanity", 0, theView.mOnDetachCount);
+ ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mListView, () -> {
+ mListView.setSelection(800);
+ });
+ assertNull("test sanity, unused view should be removed", theView.getParent());
+ assertEquals("unused view should be detached", 1, theView.mOnDetachCount);
+ assertFalse(theView.isTemporarilyDetached());
+ ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mListView, () -> {
+ mListView.setSelection(0);
+ });
+ assertNotNull("test sanity, view should be re-added", theView.getParent());
+ assertEquals("view should receive another attach call", 2, theView.mOnAttachCount);
+ assertEquals("view should not receive a detach call", 1, theView.mOnDetachCount);
+ assertFalse(theView.isTemporarilyDetached());
+ }
+
+ @MediumTest
+ public void testFullyDetachUnusedViewOnScrollForFocus() {
+ final AttachDetachAwareView theView = new AttachDetachAwareView(mActivity);
+ ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mListView, () -> {
+ mListView.setAdapter(new DummyAdapter(1000, theView));
+ });
+ assertEquals("test sanity", 1, theView.mOnAttachCount);
+ assertEquals("test sanity", 0, theView.mOnDetachCount);
+ while(theView.getParent() != null) {
+ assertEquals("the view should NOT be detached", 0, theView.mOnDetachCount);
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mListView, null);
+ }
+ assertEquals("the view should be detached", 1, theView.mOnDetachCount);
+ assertFalse(theView.isTemporarilyDetached());
+ while(theView.getParent() == null) {
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+ ViewTestUtils.runOnMainAndDrawSync(getInstrumentation(), mListView, null);
+ }
+ assertEquals("the view should be re-attached", 2, theView.mOnAttachCount);
+ assertEquals("the view should not recieve another detach", 1, theView.mOnDetachCount);
+ assertFalse(theView.isTemporarilyDetached());
+ }
+
private class MockView extends View {
public boolean onMeasureCalled = false;
diff --git a/tests/video/src/android/video/cts/VideoEncoderDecoderTest.java b/tests/video/src/android/video/cts/VideoEncoderDecoderTest.java
index dd1a3a0..a827813 100644
--- a/tests/video/src/android/video/cts/VideoEncoderDecoderTest.java
+++ b/tests/video/src/android/video/cts/VideoEncoderDecoderTest.java
@@ -591,18 +591,15 @@
}
if (mTestConfig.mTestResult) {
- double[] avgs = MediaUtils.calculateMovingAverage(
- mEncoderFrameTimeDiff[i], MOVING_AVERAGE_NUM);
- double encMin = Stat.getMin(avgs);
- double encMax = Stat.getMax(avgs);
- double encAvg = MediaUtils.getAverage(mEncoderFrameTimeDiff[i]);
- double encStdev = MediaUtils.getStdev(avgs);
+ MediaUtils.Stats encStats =
+ new MediaUtils.Stats(mEncoderFrameTimeDiff[i])
+ .movingAverage(MOVING_AVERAGE_NUM);
String prefix = "codec=" + encoderName + " round=" + i +
" EncInputFormat=" + mEncInputFormat +
" EncOutputFormat=" + mEncOutputFormat;
String result =
- MediaUtils.logResults(mReportLog, prefix, encMin, encMax, encAvg, encStdev);
- double measuredEncFps = 1000000000 / encMin;
+ MediaUtils.logAchievableRatesResults(mReportLog, prefix, encStats);
+ double measuredEncFps = 1000000000 / encStats.getMin();
resultRawData[i] = result;
measuredFps[i] = measuredEncFps;
if (!encTestPassed) {
@@ -610,16 +607,13 @@
encoderName, mimeType, w, h, measuredEncFps);
}
- avgs = MediaUtils.calculateMovingAverage(
- mDecoderFrameTimeDiff[i], MOVING_AVERAGE_NUM);
- double decMin = Stat.getMin(avgs);
- double decMax = Stat.getMax(avgs);
- double decAvg = MediaUtils.getAverage(mDecoderFrameTimeDiff[i]);
- double decStdev = MediaUtils.getStdev(avgs);
+ MediaUtils.Stats decStats =
+ new MediaUtils.Stats(mDecoderFrameTimeDiff[i])
+ .movingAverage(MOVING_AVERAGE_NUM);
prefix = "codec=" + decoderName + " size=" + w + "x" + h + " round=" + i +
" DecOutputFormat=" + mDecOutputFormat;
- MediaUtils.logResults(mReportLog, prefix, decMin, decMax, decAvg, decStdev);
- double measuredDecFps = 1000000000 / decMin;
+ MediaUtils.logAchievableRatesResults(mReportLog, prefix, decStats);
+ double measuredDecFps = 1000000000 / decStats.getMin();
if (!decTestPassed) {
decTestPassed = MediaUtils.verifyResults(
decoderName, mimeType, w, h, measuredDecFps);
diff --git a/tests/vr/src/android/vr/cts/VrDisplayTest.java b/tests/vr/src/android/vr/cts/VrDisplayTest.java
index 6b8b302..9dfdf96 100644
--- a/tests/vr/src/android/vr/cts/VrDisplayTest.java
+++ b/tests/vr/src/android/vr/cts/VrDisplayTest.java
@@ -95,4 +95,25 @@
assertTrue(displayWidth >= 1920);
assertTrue(displayHeight >= 1080);
}
+
+ /**
+ * Tests that the display dimensions are between 4.7" and 6".
+ */
+ public void testDisplayDimensions() {
+ mActivity = getGlEsActivity(1, 1);
+ if (!mActivity.supportsVrHighPerformance())
+ return;
+
+ WindowManager windowManager = (WindowManager)mActivity.getSystemService(
+ Context.WINDOW_SERVICE);
+ DisplayMetrics metrics = new DisplayMetrics();
+ windowManager.getDefaultDisplay().getRealMetrics(metrics);
+
+ double width = metrics.widthPixels / metrics.xdpi;
+ double height = metrics.heightPixels / metrics.ydpi;
+ double diagonalLength = Math.sqrt(width * width + height * height);
+
+ assertTrue(diagonalLength >= 4.7);
+ assertTrue(diagonalLength <= 6.);
+ }
}