Merge "CTS for user restriction layering"
diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
index 1644ce6..c4b3e04 100644
--- a/CtsTestCaseList.mk
+++ b/CtsTestCaseList.mk
@@ -96,6 +96,7 @@
CtsDeviceTaskSwitchingAppA \
CtsDeviceTaskSwitchingAppB \
CtsDeviceTaskSwitchingControl \
+ CtsExternalServiceService \
CtsHostsideNetworkTestsApp \
CtsIntentReceiverApp \
CtsIntentSenderApp \
@@ -160,6 +161,7 @@
CtsDreamsTestCases \
CtsDrmTestCases \
CtsEffectTestCases \
+ CtsExternalServiceTestCases \
CtsFileSystemTestCases \
CtsGestureTestCases \
CtsGraphicsTestCases \
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/MockConditionProvider.java b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/MockConditionProvider.java
index 4b90d9a..99ecd0c 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/MockConditionProvider.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/MockConditionProvider.java
@@ -144,11 +144,6 @@
}
@Override
- public void onRequestConditions(int relevance) {
-
- }
-
- @Override
public void onSubscribe(Uri conditionId) {
Log.d(TAG, "subscribed to " + conditionId);
mSubscriptions.add(conditionId);
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/build/CompatibilityBuildHelper.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/build/CompatibilityBuildHelper.java
index 9427805..e21f98e 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/build/CompatibilityBuildHelper.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/build/CompatibilityBuildHelper.java
@@ -130,8 +130,11 @@
* @throws FileNotFoundException if the directory does not exist
*/
public File getRootDir() throws FileNotFoundException {
- File dir = ((IFolderBuildInfo) mBuildInfo).getRootDir();
- if (!dir.exists()) {
+ File dir = null;
+ if (mBuildInfo instanceof IFolderBuildInfo) {
+ dir = ((IFolderBuildInfo) mBuildInfo).getRootDir();
+ }
+ if (dir == null || !dir.exists()) {
dir = new File(mBuildInfo.getBuildAttributes().get(ROOT_DIR));
if (!dir.exists()) {
dir = new File(mBuildInfo.getBuildAttributes().get(ROOT_DIR2));
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/DeviceLoggingTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/DeviceLoggingTest.java
new file mode 100644
index 0000000..642915f
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/DeviceLoggingTest.java
@@ -0,0 +1,76 @@
+/*
+ * 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.deviceowner;
+
+import android.auditing.SecurityLog.SecurityEvent;
+import android.os.UserHandle;
+
+import java.util.List;
+
+public class DeviceLoggingTest extends BaseDeviceOwnerTest {
+
+ private static final String MESSAGE_ONLY_ONE_MANAGED_USER_ALLOWED =
+ "There should only be one user, managed by Device Owner";
+
+ /**
+ * Test: setting device logging can only be done if there's one user on the device.
+ */
+ public void testSetDeviceLoggingEnabledNotPossibleIfMoreThanOneUserPresent() {
+ try {
+ mDevicePolicyManager.setDeviceLoggingEnabled(getWho(), true);
+ fail("did not throw expected SecurityException");
+ } catch (SecurityException e) {
+ assertEquals(e.getMessage(), MESSAGE_ONLY_ONE_MANAGED_USER_ALLOWED);
+ }
+ }
+
+ /**
+ * Test: retrieving device logs can only be done if there's one user on the device.
+ */
+ public void testRetrievingDeviceLogsNotPossibleIfMoreThanOneUserPresent() {
+ try {
+ mDevicePolicyManager.retrieveDeviceLogs(getWho());
+ fail("did not throw expected SecurityException");
+ } catch (SecurityException e) {
+ assertEquals(e.getMessage(), MESSAGE_ONLY_ONE_MANAGED_USER_ALLOWED);
+ }
+ }
+
+ /**
+ * Test: retrieving previous device logs can only be done if there's one user on the device.
+ */
+ public void testRetrievingPreviousDeviceLogsNotPossibleIfMoreThanOneUserPresent() {
+ try {
+ mDevicePolicyManager.retrievePreviousDeviceLogs(getWho());
+ fail("did not throw expected SecurityException");
+ } catch (SecurityException e) {
+ assertEquals(e.getMessage(), MESSAGE_ONLY_ONE_MANAGED_USER_ALLOWED);
+ }
+ }
+
+ /**
+ * Test: retrieving device logs should be rate limited - subsequent attempts should return null.
+ * TODO(mkarpinski): consider how we can test that the rate limiting is set to 2 hours.
+ */
+ public void testRetrievingDeviceLogsNotPossibleImmediatelyAfterPreviousSuccessfulRetrieval() {
+ List<SecurityEvent> logs = mDevicePolicyManager.retrieveDeviceLogs(getWho());
+ // if logs is null it means that that attempt was rate limited => test PASS
+ if (logs != null) {
+ assertNull(mDevicePolicyManager.retrieveDeviceLogs(getWho()));
+ assertNull(mDevicePolicyManager.retrieveDeviceLogs(getWho()));
+ }
+ }
+}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
index 35c14d9..2d235f5 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
@@ -222,6 +222,29 @@
assertEquals("Ephemeral flag must be set", FLAG_EPHEMERAL, flags & FLAG_EPHEMERAL);
}
+ public void testDeviceLoggingWithTwoUsers() throws Exception {
+ if (!mHasFeature || getMaxNumberOfUsersSupported() < 2) {
+ return;
+ }
+ int userId = -1;
+ try {
+ userId = createUser();
+ executeDeviceTestMethod(".DeviceLoggingTest",
+ "testSetDeviceLoggingEnabledNotPossibleIfMoreThanOneUserPresent");
+ executeDeviceTestMethod(".DeviceLoggingTest",
+ "testRetrievingDeviceLogsNotPossibleIfMoreThanOneUserPresent");
+ executeDeviceTestMethod(".DeviceLoggingTest",
+ "testRetrievingPreviousDeviceLogsNotPossibleIfMoreThanOneUserPresent");
+ } finally {
+ removeUser(userId);
+ }
+ }
+
+ public void testDeviceLoggingWithSingleUser() throws Exception {
+ executeDeviceTestMethod(".DeviceLoggingTest",
+ "testRetrievingDeviceLogsNotPossibleImmediatelyAfterPreviousSuccessfulRetrieval");
+ }
+
public void testLockTask() throws Exception {
try {
installApp(INTENT_RECEIVER_APK);
@@ -273,7 +296,7 @@
private void executeDeviceTestMethod(String className, String testName) throws Exception {
assertTrue(runDeviceTestsAsUser(DEVICE_OWNER_PKG, className, testName,
- /* deviceOwnerUserId */0));
+ /* deviceOwnerUserId */ 0));
}
private void executeDeviceOwnerTestAsUser(String testClassName, int userId) throws Exception {
diff --git a/hostsidetests/services/activitymanager/app/AndroidManifest.xml b/hostsidetests/services/activitymanager/app/AndroidManifest.xml
index 84bbd42..ed3cece 100755
--- a/hostsidetests/services/activitymanager/app/AndroidManifest.xml
+++ b/hostsidetests/services/activitymanager/app/AndroidManifest.xml
@@ -24,6 +24,11 @@
android:resizeable="true"
android:exported="true"
/>
+ <activity android:name=".DockedActivity"
+ android:resizeable="true"
+ android:exported="true"
+ android:taskAffinity="nobody.but.DockedActivity"
+ />
<activity android:name=".NoRelaunchActivity"
android:resizeable="true"
android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
diff --git a/hostsidetests/services/activitymanager/app/src/android/server/app/AutoEnterPipActivity.java b/hostsidetests/services/activitymanager/app/src/android/server/app/AutoEnterPipActivity.java
index 97bc041..dbd92b5 100644
--- a/hostsidetests/services/activitymanager/app/src/android/server/app/AutoEnterPipActivity.java
+++ b/hostsidetests/services/activitymanager/app/src/android/server/app/AutoEnterPipActivity.java
@@ -22,6 +22,6 @@
@Override
protected void onResume() {
super.onResume();
- enterPictureInPictureMode();
+ enterPictureInPicture();
}
}
diff --git a/hostsidetests/services/activitymanager/app/src/android/server/app/DockedActivity.java b/hostsidetests/services/activitymanager/app/src/android/server/app/DockedActivity.java
new file mode 100644
index 0000000..427fd29
--- /dev/null
+++ b/hostsidetests/services/activitymanager/app/src/android/server/app/DockedActivity.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.server.app;
+
+import android.app.Activity;
+
+public class DockedActivity extends Activity {
+}
diff --git a/hostsidetests/services/activitymanager/app/src/android/server/app/LaunchPipOnPipActivity.java b/hostsidetests/services/activitymanager/app/src/android/server/app/LaunchPipOnPipActivity.java
index b328a09..dba7cde 100644
--- a/hostsidetests/services/activitymanager/app/src/android/server/app/LaunchPipOnPipActivity.java
+++ b/hostsidetests/services/activitymanager/app/src/android/server/app/LaunchPipOnPipActivity.java
@@ -20,8 +20,8 @@
public class LaunchPipOnPipActivity extends Activity {
@Override
- public void onPictureInPictureModeChanged(boolean pictureInPictureMode) {
- super.onPictureInPictureModeChanged(pictureInPictureMode);
+ public void onPictureInPictureChanged(boolean inPictureInPicture) {
+ super.onPictureInPictureChanged(inPictureInPicture);
AlwaysFocusablePipActivity.launchAlwaysFocusablePipActivity(this);
}
}
diff --git a/hostsidetests/services/activitymanager/app/src/android/server/app/LaunchToSideActivity.java b/hostsidetests/services/activitymanager/app/src/android/server/app/LaunchToSideActivity.java
index 388c9a6..9714393 100644
--- a/hostsidetests/services/activitymanager/app/src/android/server/app/LaunchToSideActivity.java
+++ b/hostsidetests/services/activitymanager/app/src/android/server/app/LaunchToSideActivity.java
@@ -1,12 +1,11 @@
package android.server.app;
-import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_TO_SIDE;
+import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
-import android.util.Log;
public class LaunchToSideActivity extends Activity {
@Override
@@ -15,7 +14,7 @@
final Bundle extras = intent.getExtras();
if (extras != null && extras.getBoolean("launch_to_the_side")) {
Intent newIntent = new Intent(this, TestActivity.class);
- newIntent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_LAUNCH_TO_SIDE);
+ newIntent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_LAUNCH_ADJACENT);
startActivity(newIntent);
}
}
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerDockedStackTests.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerDockedStackTests.java
index 731ff47..92be4b8 100644
--- a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerDockedStackTests.java
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerDockedStackTests.java
@@ -16,17 +16,23 @@
package android.server.cts;
-import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.log.LogUtil.CLog;
-import java.lang.Exception;
-import java.lang.String;
+import java.awt.Rectangle;
+
+import static com.android.ddmlib.Log.LogLevel.*;
public class ActivityManagerDockedStackTests extends ActivityManagerTestBase {
private static final String TEST_ACTIVITY_NAME = "TestActivity";
+ private static final String DOCKED_ACTIVITY_NAME = "DockedActivity";
private static final String LAUNCH_TO_SIDE_ACTIVITY_NAME = "LaunchToSideActivity";
private static final String AM_MOVE_TASK = "am stack movetask ";
+ private static final String AM_RESIZE_DOCKED_STACK = "am stack resize-docked-stack ";
+
+ private static final int TASK_SIZE = 600;
+ private static final int STACK_SIZE = 300;
// TODO: Add test for non-resizeable activity.
@@ -140,6 +146,27 @@
mDevice.executeShellCommand(cmd);
}
+ public void testResizeDockedStack() throws Exception {
+ mDevice.executeShellCommand(getAmStartCmd(TEST_ACTIVITY_NAME));
+ mDevice.executeShellCommand(getAmStartCmd(DOCKED_ACTIVITY_NAME));
+ mDevice.executeShellCommand(AM_MOVE_TASK + getActivityTaskId(DOCKED_ACTIVITY_NAME) + " "
+ + DOCKED_STACK_ID + " true");
+ mDevice.executeShellCommand(AM_RESIZE_DOCKED_STACK
+ + "0 0 " + STACK_SIZE + " " + STACK_SIZE
+ + " 0 0 " + TASK_SIZE + " " + TASK_SIZE);
+ mAmWmState.computeState(mDevice);
+ mAmWmState.assertSanity();
+ mAmWmState.assertContainsStack("Must contain docked stack", DOCKED_STACK_ID);
+ mAmWmState.assertContainsStack("Must contain fullscreen stack",
+ FULLSCREEN_WORKSPACE_STACK_ID);
+ assertEquals(new Rectangle(0, 0, STACK_SIZE, STACK_SIZE),
+ mAmWmState.getAmState().getStackById(DOCKED_STACK_ID).getBounds());
+ assertEquals(new Rectangle(0, 0, TASK_SIZE, TASK_SIZE),
+ mAmWmState.getAmState().getTaskByActivityName(DOCKED_ACTIVITY_NAME).getBounds());
+ mAmWmState.assertVisibility(DOCKED_ACTIVITY_NAME, true);
+ mAmWmState.assertVisibility(TEST_ACTIVITY_NAME, true);
+ }
+
private void launchActivityToSide(String activityName) throws Exception {
mDevice.executeShellCommand(
getAmStartCmd(activityName) + " -f 0x20000000 --ez launch_to_the_side true");
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerReplaceWindowTests.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerReplaceWindowTests.java
index 785e487..88fcc97 100644
--- a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerReplaceWindowTests.java
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerReplaceWindowTests.java
@@ -77,11 +77,8 @@
CLog.logAndDisplay(INFO, "==========After Docking========");
final String newToken = getFocusedWindowToken(windowName, false);
- if (relaunch) {
- Assert.assertFalse("Window not replaced after relaunch.", oldToken.equals(newToken));
- } else {
- Assert.assertEquals("Window replaced without relaunch.", oldToken, newToken);
- }
+ // For both relaunch and not relaunch case, we'd like the window to be kept.
+ Assert.assertEquals("Window replaced while docking.", oldToken, newToken);
}
private String getFocusedWindowToken(String windowName, boolean visibleOnly)
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerState.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerState.java
index 003d8e6..fcee898 100644
--- a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerState.java
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerState.java
@@ -174,6 +174,15 @@
return false;
}
+ ActivityStack getStackById(int stackId) {
+ for (ActivityStack stack : mStacks) {
+ if (stackId == stack.mStackId) {
+ return stack;
+ }
+ }
+ return null;
+ }
+
List<ActivityStack> getStacks() {
return new ArrayList(mStacks);
}
@@ -195,6 +204,20 @@
return false;
}
+ ActivityTask getTaskByActivityName(String activityName) {
+ String fullName = ActivityManagerTestBase.getActivityComponentName(activityName);
+ for (ActivityStack stack : mStacks) {
+ for (ActivityTask task : stack.mTasks) {
+ for (Activity activity : task.mActivities) {
+ if (activity.name.equals(fullName)) {
+ return task;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
static class ActivityStack extends ActivityContainer {
private static final Pattern TASK_ID_PATTERN = Pattern.compile("Task id #(\\d+)");
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerTestBase.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerTestBase.java
index d0cd178..ceb2b63 100644
--- a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerTestBase.java
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerTestBase.java
@@ -187,7 +187,7 @@
"settings put system accelerometer_rotation " + rotation);
}
- private String runCommandAndPrintOutput(String command) throws DeviceNotAvailableException {
+ protected String runCommandAndPrintOutput(String command) throws DeviceNotAvailableException {
final String output = mDevice.executeShellCommand(command);
CLog.logAndDisplay(LogLevel.INFO, command);
CLog.logAndDisplay(LogLevel.INFO, output);
diff --git a/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java b/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
index fc9267a..17caccb 100644
--- a/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
+++ b/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
@@ -567,6 +567,58 @@
}
}
+ public void testSetDeviceLoggingEnabled_failIfNotDeviceOwner() {
+ if (!mDeviceAdmin) {
+ Log.w(TAG, "Skipping testSetDeviceLoggingEnabled_failIfNotDeviceOwner");
+ return;
+ }
+ try {
+ mDevicePolicyManager.setDeviceLoggingEnabled(mComponent, true);
+ fail("did not throw expected SecurityException");
+ } catch (SecurityException e) {
+ assertDeviceOwnerMessage(e.getMessage());
+ }
+ }
+
+ public void testGetDeviceLoggingEnabled_failIfNotDeviceOwner() {
+ if (!mDeviceAdmin) {
+ Log.w(TAG, "Skipping testGetDeviceLoggingEnabled_failIfNotDeviceOwner");
+ return;
+ }
+ try {
+ mDevicePolicyManager.getDeviceLoggingEnabled(mComponent);
+ fail("did not throw expected SecurityException");
+ } catch (SecurityException e) {
+ assertDeviceOwnerMessage(e.getMessage());
+ }
+ }
+
+ public void testRetrieveDeviceLogs_failIfNotDeviceOwner() {
+ if (!mDeviceAdmin) {
+ Log.w(TAG, "Skipping testRetrieveDeviceLogs_failIfNotDeviceOwner");
+ return;
+ }
+ try {
+ mDevicePolicyManager.retrieveDeviceLogs(mComponent);
+ fail("did not throw expected SecurityException");
+ } catch (SecurityException e) {
+ assertDeviceOwnerMessage(e.getMessage());
+ }
+ }
+
+ public void testRetrievePreviousDeviceLogs_failIfNotDeviceOwner() {
+ if (!mDeviceAdmin) {
+ Log.w(TAG, "Skipping testRetrievePreviousDeviceLogs_failIfNotDeviceOwner");
+ return;
+ }
+ try {
+ mDevicePolicyManager.retrievePreviousDeviceLogs(mComponent);
+ fail("did not throw expected SecurityException");
+ } catch (SecurityException e) {
+ assertDeviceOwnerMessage(e.getMessage());
+ }
+ }
+
public void testCreateUser_failIfNotDeviceOwner() {
if (!mDeviceAdmin) {
Log.w(TAG, "Skipping testCreateUser_failIfNotDeviceOwner");
diff --git a/tests/app/src/android/app/cts/DownloadManagerTest.java b/tests/app/src/android/app/cts/DownloadManagerTest.java
index 21a227b..50eb96b 100644
--- a/tests/app/src/android/app/cts/DownloadManagerTest.java
+++ b/tests/app/src/android/app/cts/DownloadManagerTest.java
@@ -474,9 +474,9 @@
}
private boolean hasInternetConnection() {
- // TODO: expand this to include devices with ethernet
final PackageManager pm = getContext().getPackageManager();
return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
- || pm.hasSystemFeature(PackageManager.FEATURE_WIFI);
+ || pm.hasSystemFeature(PackageManager.FEATURE_WIFI)
+ || pm.hasSystemFeature(PackageManager.FEATURE_ETHERNET);
}
}
diff --git a/tests/app/src/android/app/cts/PipActivityTest.java b/tests/app/src/android/app/cts/PipActivityTest.java
index a553169..3f053cb 100644
--- a/tests/app/src/android/app/cts/PipActivityTest.java
+++ b/tests/app/src/android/app/cts/PipActivityTest.java
@@ -44,20 +44,20 @@
final boolean supportsPip =
mActivity.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
if (supportsPip) {
- mActivity.enterPictureInPictureMode();
- assertTrue(mActivity.inMultiWindowMode());
- assertTrue(mActivity.inPictureInPictureMode());
+ mActivity.enterPictureInPicture();
+ assertTrue(mActivity.inMultiWindow());
+ assertTrue(mActivity.inPictureInPicture());
} else {
boolean pipSupportDisabled = false;
try {
- mActivity.enterPictureInPictureMode();
+ mActivity.enterPictureInPicture();
} catch (IllegalStateException e) {
// Pip not supported
pipSupportDisabled = true;
}
assertTrue(pipSupportDisabled);
- assertFalse(mActivity.inMultiWindowMode());
- assertFalse(mActivity.inPictureInPictureMode());
+ assertFalse(mActivity.inMultiWindow());
+ assertFalse(mActivity.inPictureInPicture());
}
}
});
diff --git a/tests/app/src/android/app/cts/PipNotResizeableActivityTest.java b/tests/app/src/android/app/cts/PipNotResizeableActivityTest.java
index 4f7f63e..e2908cd 100644
--- a/tests/app/src/android/app/cts/PipNotResizeableActivityTest.java
+++ b/tests/app/src/android/app/cts/PipNotResizeableActivityTest.java
@@ -42,7 +42,7 @@
public void run() {
boolean pipSupportDisabled = false;
try {
- mActivity.enterPictureInPictureMode();
+ mActivity.enterPictureInPicture();
} catch (IllegalStateException e) {
// Pip not supported
pipSupportDisabled = true;
@@ -51,8 +51,8 @@
pipSupportDisabled = true;
}
assertTrue(pipSupportDisabled);
- assertFalse(mActivity.inMultiWindowMode());
- assertFalse(mActivity.inPictureInPictureMode());
+ assertFalse(mActivity.inMultiWindow());
+ assertFalse(mActivity.inPictureInPicture());
}
});
mInstrumentation.waitForIdleSync();
diff --git a/tests/app/src/android/app/cts/PipNotSupportedActivityTest.java b/tests/app/src/android/app/cts/PipNotSupportedActivityTest.java
index 245421a..c9ce69c 100644
--- a/tests/app/src/android/app/cts/PipNotSupportedActivityTest.java
+++ b/tests/app/src/android/app/cts/PipNotSupportedActivityTest.java
@@ -42,7 +42,7 @@
public void run() {
boolean pipSupportDisabled = false;
try {
- mActivity.enterPictureInPictureMode();
+ mActivity.enterPictureInPicture();
} catch (IllegalStateException e) {
// Pip not supported
pipSupportDisabled = true;
@@ -51,8 +51,8 @@
pipSupportDisabled = true;
}
assertTrue(pipSupportDisabled);
- assertFalse(mActivity.inMultiWindowMode());
- assertFalse(mActivity.inPictureInPictureMode());
+ assertFalse(mActivity.inMultiWindow());
+ assertFalse(mActivity.inPictureInPicture());
}
});
mInstrumentation.waitForIdleSync();
diff --git a/tests/camera/Android.mk b/tests/camera/Android.mk
index 62cdf25..4d653a6 100644
--- a/tests/camera/Android.mk
+++ b/tests/camera/Android.mk
@@ -20,6 +20,9 @@
LOCAL_MODULE_TAGS := tests
+# Include both the 32 and 64 bit versions
+LOCAL_MULTILIB := both
+
LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil \
ctstestrunner \
mockito-target \
diff --git a/tests/camera/src/android/hardware/camera2/cts/CameraDeviceTest.java b/tests/camera/src/android/hardware/camera2/cts/CameraDeviceTest.java
index 337aab6..cf36b05 100644
--- a/tests/camera/src/android/hardware/camera2/cts/CameraDeviceTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/CameraDeviceTest.java
@@ -1597,14 +1597,16 @@
CaptureRequest.NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG);
} else if (template == CameraDevice.TEMPLATE_PREVIEW ||
template == CameraDevice.TEMPLATE_RECORD){
- List<Integer> availableEdgeModes =
- Arrays.asList(toObject(mStaticInfo.getAvailableEdgeModesChecked()));
- if (availableEdgeModes.contains(CaptureRequest.EDGE_MODE_FAST)) {
- mCollector.expectKeyValueEquals(request, EDGE_MODE,
- CaptureRequest.EDGE_MODE_FAST);
- } else {
- mCollector.expectKeyValueEquals(request, EDGE_MODE,
- CaptureRequest.EDGE_MODE_OFF);
+ if (mStaticInfo.areKeysAvailable(EDGE_MODE)) {
+ List<Integer> availableEdgeModes =
+ Arrays.asList(toObject(mStaticInfo.getAvailableEdgeModesChecked()));
+ if (availableEdgeModes.contains(CaptureRequest.EDGE_MODE_FAST)) {
+ mCollector.expectKeyValueEquals(request, EDGE_MODE,
+ CaptureRequest.EDGE_MODE_FAST);
+ } else {
+ mCollector.expectKeyValueEquals(request, EDGE_MODE,
+ CaptureRequest.EDGE_MODE_OFF);
+ }
}
if (mStaticInfo.areKeysAvailable(NOISE_REDUCTION_MODE)) {
diff --git a/tests/camera/src/android/hardware/camera2/cts/CameraTestUtils.java b/tests/camera/src/android/hardware/camera2/cts/CameraTestUtils.java
index 1633c1e..0da92a6 100644
--- a/tests/camera/src/android/hardware/camera2/cts/CameraTestUtils.java
+++ b/tests/camera/src/android/hardware/camera2/cts/CameraTestUtils.java
@@ -36,6 +36,7 @@
import android.hardware.camera2.TotalCaptureResult;
import android.hardware.cts.helpers.CameraUtils;
import android.hardware.camera2.params.MeteringRectangle;
+import android.hardware.camera2.params.OutputConfiguration;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.location.Location;
import android.location.LocationManager;
@@ -721,6 +722,26 @@
}
/**
+ * Configure a new camera session with output configurations.
+ *
+ * @param camera The CameraDevice to be configured.
+ * @param outputs The OutputConfiguration list that is used for camera output.
+ * @param listener The callback CameraDevice will notify when capture results are available.
+ */
+ public static CameraCaptureSession configureCameraSessionWithConfig(CameraDevice camera,
+ List<OutputConfiguration> outputs,
+ CameraCaptureSession.StateCallback listener, Handler handler)
+ throws CameraAccessException {
+ BlockingSessionCallback sessionListener = new BlockingSessionCallback(listener);
+ camera.createCaptureSessionByOutputConfiguration(outputs, sessionListener, handler);
+ CameraCaptureSession session =
+ sessionListener.waitAndGetSession(SESSION_CONFIGURE_TIMEOUT_MS);
+ assertFalse("Camera session should not be a reprocessable session",
+ session.isReprocessable());
+ return session;
+ }
+
+ /**
* Configure a new camera session with output surfaces.
*
* @param camera The CameraDevice to be configured.
@@ -759,6 +780,40 @@
return session;
}
+ /**
+ * Create a reprocessable camera session with input and output configurations.
+ *
+ * @param camera The CameraDevice to be configured.
+ * @param inputConfiguration The input configuration used to create this session.
+ * @param outputs The output configurations used to create this session.
+ * @param listener The callback CameraDevice will notify when capture results are available.
+ * @param handler The handler used to notify callbacks.
+ * @return The session ready to use.
+ * @throws CameraAccessException
+ */
+ public static CameraCaptureSession configureReprocCameraSessionWithConfig(CameraDevice camera,
+ InputConfiguration inputConfiguration, List<OutputConfiguration> outputs,
+ CameraCaptureSession.StateCallback listener, Handler handler)
+ throws CameraAccessException {
+ BlockingSessionCallback sessionListener = new BlockingSessionCallback(listener);
+ camera.createReprocessableCaptureSessionWithConfigurations(inputConfiguration, outputs,
+ sessionListener, handler);
+
+ Integer[] sessionStates = {BlockingSessionCallback.SESSION_READY,
+ BlockingSessionCallback.SESSION_CONFIGURE_FAILED};
+ int state = sessionListener.getStateWaiter().waitForAnyOfStates(
+ Arrays.asList(sessionStates), SESSION_CONFIGURE_TIMEOUT_MS);
+
+ assertTrue("Creating a reprocessable session failed.",
+ state == BlockingSessionCallback.SESSION_READY);
+
+ CameraCaptureSession session =
+ sessionListener.waitAndGetSession(SESSION_CONFIGURE_TIMEOUT_MS);
+ assertTrue("Camera session should be a reprocessable session", session.isReprocessable());
+
+ return session;
+ }
+
public static <T> void assertArrayNotEmpty(T arr, String message) {
assertTrue(message, arr != null && Array.getLength(arr) > 0);
}
diff --git a/tests/camera/src/android/hardware/camera2/cts/DngCreatorTest.java b/tests/camera/src/android/hardware/camera2/cts/DngCreatorTest.java
index bddbd52..4259882 100644
--- a/tests/camera/src/android/hardware/camera2/cts/DngCreatorTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/DngCreatorTest.java
@@ -46,13 +46,16 @@
import android.view.Surface;
import java.io.ByteArrayOutputStream;
+import java.io.File;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Calendar;
import java.util.Collections;
import java.util.List;
+import java.util.TimeZone;
import static android.hardware.camera2.cts.helpers.AssertHelpers.*;
@@ -68,6 +71,19 @@
private static final int DEFAULT_PATCH_DIMEN = 512;
private static final int AE_TIMEOUT_MS = 2000;
+ // Constants used for GPS testing.
+ private static final double GPS_DIFFERENCE_TOLERANCE = 0.0001;
+ private static final double GPS_LATITUDE = 37.420016;
+ private static final double GPS_LONGITUDE = -122.081987;
+ private static final String GPS_DATESTAMP = "2015:01:27";
+ private static final String GPS_TIMESTAMP = "02:12:01";
+ private static final Calendar GPS_CALENDAR =
+ Calendar.getInstance(TimeZone.getTimeZone("GMT+0"));
+
+ static {
+ GPS_CALENDAR.set(2015, 0, 27, 2, 12, 01);
+ }
+
@Override
protected void setUp() throws Exception {
super.setUp();
@@ -165,8 +181,8 @@
*
* <p>
* For each camera, capture a single RAW16 image at the first capture size reported for
- * the raw format on that device, and save that image as a DNG file. No further validation
- * is done.
+ * the raw format on that device, and save that image as a DNG file. GPS information validation
+ * is done via ExifInterface.
* </p>
*
* <p>
@@ -222,9 +238,9 @@
DngCreator dngCreator = new DngCreator(characteristics, resultPair.second);
Location l = new Location("test");
l.reset();
- l.setLatitude(37.420016);
- l.setLongitude(-122.081987);
- l.setTime(System.currentTimeMillis());
+ l.setLatitude(GPS_LATITUDE);
+ l.setLongitude(GPS_LONGITUDE);
+ l.setTime(GPS_CALENDAR.getTimeInMillis());
dngCreator.setLocation(l);
dngCreator.setDescription("helloworld");
@@ -233,16 +249,38 @@
outputStream = new ByteArrayOutputStream();
dngCreator.writeImage(outputStream, resultPair.first.get(0));
+ String filePath = DEBUG_FILE_NAME_BASE + "/camera_thumb_" + deviceId + "_" +
+ DEBUG_DNG_FILE;
+ // Write out captured DNG file for the first camera device if setprop is enabled
+ fileStream = new FileOutputStream(filePath);
+ fileStream.write(outputStream.toByteArray());
+ fileStream.flush();
+ fileStream.close();
if (VERBOSE) {
- String filePath = DEBUG_FILE_NAME_BASE + "/camera_thumb_" + deviceId + "_" +
- DEBUG_DNG_FILE;
- // Write out captured DNG file for the first camera device if setprop is enabled
- fileStream = new FileOutputStream(filePath);
- fileStream.write(outputStream.toByteArray());
- fileStream.flush();
- fileStream.close();
Log.v(TAG, "Test DNG file for camera " + deviceId + " saved to " + filePath);
}
+
+ ExifInterface exifInterface = new ExifInterface(filePath);
+ // Verify GPS data.
+ float[] latLong = new float[2];
+ assertTrue(exifInterface.getLatLong(latLong));
+ assertEquals(GPS_LATITUDE, latLong[0], GPS_DIFFERENCE_TOLERANCE);
+ assertEquals(GPS_LONGITUDE, latLong[1], GPS_DIFFERENCE_TOLERANCE);
+ assertEquals(GPS_DATESTAMP,
+ exifInterface.getAttribute(ExifInterface.TAG_GPS_DATESTAMP));
+ assertEquals(GPS_TIMESTAMP,
+ exifInterface.getAttribute(ExifInterface.TAG_GPS_TIMESTAMP));
+
+ // Verify the orientation.
+ assertEquals(ExifInterface.ORIENTATION_FLIP_VERTICAL,
+ exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
+ ExifInterface.ORIENTATION_UNDEFINED));
+
+ if (!VERBOSE) {
+ // Delete the captured DNG file.
+ File dngFile = new File(filePath);
+ assertTrue(dngFile.delete());
+ }
} finally {
closeDevice(deviceId);
for (ImageReader r : captureReaders) {
diff --git a/tests/camera/src/android/hardware/camera2/cts/PerformanceTest.java b/tests/camera/src/android/hardware/camera2/cts/PerformanceTest.java
index 666292c..f0f8f66 100644
--- a/tests/camera/src/android/hardware/camera2/cts/PerformanceTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/PerformanceTest.java
@@ -652,7 +652,7 @@
// 2. Create camera output ImageReaders.
// YUV/Opaque output, camera should support output with input size/format
mCameraZslImageListener = new SimpleImageReaderListener(
- /*asyncMode*/true, MAX_ZSL_IMAGES / 2);
+ /*asyncMode*/true, MAX_ZSL_IMAGES - MAX_REPROCESS_IMAGES);
mCameraZslReader = CameraTestUtils.makeImageReader(
maxInputSize, inputFormat, MAX_ZSL_IMAGES, mCameraZslImageListener, mHandler);
// Jpeg reprocess output
diff --git a/tests/camera/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java b/tests/camera/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java
index 057cb18..9dd02ce 100644
--- a/tests/camera/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java
@@ -20,6 +20,9 @@
import android.graphics.ImageFormat;
import android.view.Surface;
+
+import com.android.ex.camera2.blocking.BlockingSessionCallback;
+
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCaptureSession.CaptureCallback;
import android.hardware.camera2.CameraDevice;
@@ -30,6 +33,7 @@
import android.util.Size;
import android.hardware.camera2.cts.CameraTestUtils.SimpleCaptureCallback;
import android.hardware.camera2.cts.testcases.Camera2SurfaceViewTestCase;
+import android.hardware.camera2.params.OutputConfiguration;
import android.util.Log;
import android.util.Pair;
import android.util.Range;
@@ -53,6 +57,7 @@
private static final int NUM_FRAMES_VERIFIED = 30;
private static final int NUM_TEST_PATTERN_FRAMES_VERIFIED = 60;
private static final float FRAME_DURATION_ERROR_MARGIN = 0.005f; // 0.5 percent error margin.
+ private static final int PREPARE_TIMEOUT_MS = 10000; // 10 s
@Override
protected void setUp() throws Exception {
@@ -133,6 +138,31 @@
}
/**
+ * Test surface set streaming use cases.
+ *
+ * <p>
+ * The test sets output configuration with increasing surface set IDs for preview and YUV
+ * streams. The max supported preview size is selected for preview stream, and the max
+ * supported YUV size (depending on hw supported level) is selected for YUV stream. This test
+ * also exercises the prepare API.
+ * </p>
+ */
+ public void testSurfaceSet() throws Exception {
+ for (String id : mCameraIds) {
+ try {
+ openDevice(id);
+ if (!mStaticInfo.isColorOutputSupported()) {
+ Log.i(TAG, "Camera " + id + " does not support color outputs, skipping");
+ continue;
+ }
+ surfaceSetTestByCamera(id);
+ } finally {
+ closeDevice();
+ }
+ }
+ }
+
+ /**
* Test to verify the {@link CameraCaptureSession#prepare} method works correctly, and has the
* expected effects on performance.
*
@@ -163,7 +193,6 @@
final int UNKNOWN_LATENCY_RESULT_WAIT = 5;
final int MAX_RESULTS_TO_WAIT = 10;
final int FRAMES_FOR_AVERAGING = 100;
- final int PREPARE_TIMEOUT_MS = 10000; // 10 s
final float PREPARE_FRAME_RATE_BOUNDS = 0.05f; // fraction allowed difference
final float PREPARE_PEAK_RATE_BOUNDS = 0.5f; // fraction allowed difference
@@ -330,7 +359,6 @@
* validated.
*/
private void previewFpsRangeTestByCamera() throws Exception {
- final int FPS_RANGE_SIZE = 2;
Size maxPreviewSz = mOrderedPreviewSizes.get(0);
Range<Integer>[] fpsRanges = mStaticInfo.getAeAvailableTargetFpsRangesChecked();
boolean antiBandingOffIsSupported = mStaticInfo.isAntiBandingOffModeSupported();
@@ -450,6 +478,72 @@
stopPreview();
}
+ private void surfaceSetTestByCamera(String cameraId) throws Exception {
+ final int MAX_SURFACE_SET_ID = 10;
+ Size maxPreviewSz = mOrderedPreviewSizes.get(0);
+ Size yuvSizeBound = maxPreviewSz; // Default case: legacy device
+ if (mStaticInfo.isHardwareLevelLimited()) {
+ yuvSizeBound = mOrderedVideoSizes.get(0);
+ } else if (mStaticInfo.isHardwareLevelAtLeastFull()) {
+ yuvSizeBound = null;
+ }
+ Size maxYuvSize = getSupportedPreviewSizes(cameraId, mCameraManager, yuvSizeBound).get(0);
+
+ CaptureRequest.Builder requestBuilder =
+ mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+ ImageDropperListener imageListener = new ImageDropperListener();
+
+ updatePreviewSurface(maxPreviewSz);
+ createImageReader(maxYuvSize, ImageFormat.YUV_420_888, MAX_READER_IMAGES, imageListener);
+ List<OutputConfiguration> outputConfigs = new ArrayList<OutputConfiguration>();
+ OutputConfiguration previewConfig = new OutputConfiguration(mPreviewSurface);
+ OutputConfiguration yuvConfig = new OutputConfiguration(mReaderSurface);
+ assertEquals(OutputConfiguration.SURFACE_SET_ID_INVALID, previewConfig.getSurfaceSetId());
+ assertEquals(OutputConfiguration.SURFACE_SET_ID_INVALID, yuvConfig.getSurfaceSetId());
+ assertEquals(mPreviewSurface, previewConfig.getSurface());
+ assertEquals(mReaderSurface, yuvConfig.getSurface());
+ outputConfigs.add(previewConfig);
+ outputConfigs.add(yuvConfig);
+ requestBuilder.addTarget(mPreviewSurface);
+ requestBuilder.addTarget(mReaderSurface);
+
+ // Test different stream set ID.
+ for (int surfaceSetId = OutputConfiguration.SURFACE_SET_ID_INVALID;
+ surfaceSetId < MAX_SURFACE_SET_ID; surfaceSetId++) {
+ if (VERBOSE) {
+ Log.v(TAG, "test preview with surface set id: ");
+ }
+ for (OutputConfiguration config : outputConfigs) {
+ config.setSurfaceSetId(surfaceSetId);
+ assertEquals(surfaceSetId, config.getSurfaceSetId());
+ }
+
+ CameraCaptureSession.StateCallback mockSessionListener =
+ mock(CameraCaptureSession.StateCallback.class);
+
+ mSession = configureCameraSessionWithConfig(mCamera, outputConfigs,
+ mockSessionListener, mHandler);
+
+
+ mSession.prepare(mPreviewSurface);
+ verify(mockSessionListener,
+ timeout(PREPARE_TIMEOUT_MS).times(1)).
+ onSurfacePrepared(eq(mSession), eq(mPreviewSurface));
+
+ mSession.prepare(mReaderSurface);
+ verify(mockSessionListener,
+ timeout(PREPARE_TIMEOUT_MS).times(1)).
+ onSurfacePrepared(eq(mSession), eq(mReaderSurface));
+
+ CaptureRequest request = requestBuilder.build();
+ CaptureCallback mockCaptureCallback =
+ mock(CameraCaptureSession.CaptureCallback.class);
+ mSession.setRepeatingRequest(request, mockCaptureCallback, mHandler);
+ verifyCaptureResults(mSession, mockCaptureCallback, NUM_FRAMES_VERIFIED,
+ NUM_FRAMES_VERIFIED * FRAME_TIMEOUT_MS);
+ }
+ }
+
private class IsCaptureResultValid extends ArgumentMatcher<TotalCaptureResult> {
@Override
public boolean matches(Object obj) {
diff --git a/tests/tests/content/src/android/content/cts/ContextTest.java b/tests/tests/content/src/android/content/cts/ContextTest.java
index cf27bda..c988f77 100644
--- a/tests/tests/content/src/android/content/cts/ContextTest.java
+++ b/tests/tests/content/src/android/content/cts/ContextTest.java
@@ -27,11 +27,14 @@
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
import android.test.AndroidTestCase;
import android.util.AttributeSet;
import android.util.Xml;
import android.view.WindowManager;
+import java.io.File;
import java.io.IOException;
public class ContextTest extends AndroidTestCase {
@@ -81,6 +84,108 @@
}
}
+ /**
+ * Ensure that default and device encrypted storage areas are stored
+ * separately on disk. All devices must support these storage areas, even if
+ * they don't have file-based encryption, so that apps can go through a
+ * backup/restore cycle between FBE and non-FBE devices.
+ */
+ public void testCreateDeviceEncryptedStorageContext() throws Exception {
+ final Context deviceContext = mContext.createDeviceEncryptedStorageContext();
+
+ assertFalse(mContext.isDeviceEncryptedStorage());
+ assertTrue(deviceContext.isDeviceEncryptedStorage());
+
+ final File defaultFile = new File(mContext.getFilesDir(), "test");
+ final File deviceFile = new File(deviceContext.getFilesDir(), "test");
+
+ assertFalse(deviceFile.equals(defaultFile));
+
+ deviceFile.createNewFile();
+
+ // Make sure storage areas are mutually exclusive
+ assertFalse(defaultFile.exists());
+ assertTrue(deviceFile.exists());
+ }
+
+ public void testMigrateSharedPreferencesFrom() throws Exception {
+ final Context deviceContext = mContext.createDeviceEncryptedStorageContext();
+
+ mContext.getSharedPreferences("test", Context.MODE_PRIVATE).edit().putInt("answer", 42)
+ .commit();
+
+ // Verify that we can migrate
+ assertTrue(deviceContext.migrateSharedPreferencesFrom(mContext, "test"));
+ assertEquals(0, mContext.getSharedPreferences("test", Context.MODE_PRIVATE)
+ .getInt("answer", 0));
+ assertEquals(42, deviceContext.getSharedPreferences("test", Context.MODE_PRIVATE)
+ .getInt("answer", 0));
+
+ // Trying to migrate again when already done is a no-op
+ assertTrue(deviceContext.migrateSharedPreferencesFrom(mContext, "test"));
+ assertEquals(0, mContext.getSharedPreferences("test", Context.MODE_PRIVATE)
+ .getInt("answer", 0));
+ assertEquals(42, deviceContext.getSharedPreferences("test", Context.MODE_PRIVATE)
+ .getInt("answer", 0));
+
+ // Add a new value and verify that we can migrate back
+ deviceContext.getSharedPreferences("test", Context.MODE_PRIVATE).edit()
+ .putInt("question", 24).commit();
+
+ assertTrue(mContext.migrateSharedPreferencesFrom(deviceContext, "test"));
+ assertEquals(42, mContext.getSharedPreferences("test", Context.MODE_PRIVATE)
+ .getInt("answer", 0));
+ assertEquals(24, mContext.getSharedPreferences("test", Context.MODE_PRIVATE)
+ .getInt("question", 0));
+ assertEquals(0, deviceContext.getSharedPreferences("test", Context.MODE_PRIVATE)
+ .getInt("answer", 0));
+ assertEquals(0, deviceContext.getSharedPreferences("test", Context.MODE_PRIVATE)
+ .getInt("question", 0));
+ }
+
+ public void testMigrateDatabaseFrom() throws Exception {
+ final Context deviceContext = mContext.createDeviceEncryptedStorageContext();
+
+ SQLiteDatabase db = mContext.openOrCreateDatabase("test.db",
+ Context.MODE_PRIVATE | Context.MODE_ENABLE_WRITE_AHEAD_LOGGING, null);
+ db.execSQL("CREATE TABLE list(item TEXT);");
+ db.execSQL("INSERT INTO list VALUES ('cat')");
+ db.execSQL("INSERT INTO list VALUES ('dog')");
+ db.close();
+
+ // Verify that we can migrate
+ assertTrue(deviceContext.migrateDatabaseFrom(mContext, "test.db"));
+ db = deviceContext.openOrCreateDatabase("test.db",
+ Context.MODE_PRIVATE | Context.MODE_ENABLE_WRITE_AHEAD_LOGGING, null);
+ Cursor c = db.query("list", null, null, null, null, null, null);
+ assertEquals(2, c.getCount());
+ assertTrue(c.moveToFirst());
+ assertEquals("cat", c.getString(0));
+ assertTrue(c.moveToNext());
+ assertEquals("dog", c.getString(0));
+ c.close();
+ db.execSQL("INSERT INTO list VALUES ('mouse')");
+ db.close();
+
+ // Trying to migrate again when already done is a no-op
+ assertTrue(deviceContext.migrateDatabaseFrom(mContext, "test.db"));
+
+ // Verify that we can migrate back
+ assertTrue(mContext.migrateDatabaseFrom(deviceContext, "test.db"));
+ db = mContext.openOrCreateDatabase("test.db",
+ Context.MODE_PRIVATE | Context.MODE_ENABLE_WRITE_AHEAD_LOGGING, null);
+ c = db.query("list", null, null, null, null, null, null);
+ assertEquals(3, c.getCount());
+ assertTrue(c.moveToFirst());
+ assertEquals("cat", c.getString(0));
+ assertTrue(c.moveToNext());
+ assertEquals("dog", c.getString(0));
+ assertTrue(c.moveToNext());
+ assertEquals("mouse", c.getString(0));
+ c.close();
+ db.close();
+ }
+
public void testAccessTheme() {
mContext.setTheme(R.style.Test_Theme);
final Theme testTheme = mContext.getTheme();
diff --git a/tests/tests/draganddrop/dragsource/src/android/dnd/cts/dragsource/DragSource.java b/tests/tests/draganddrop/dragsource/src/android/dnd/cts/dragsource/DragSource.java
index 7b29720..bbba70d 100644
--- a/tests/tests/draganddrop/dragsource/src/android/dnd/cts/dragsource/DragSource.java
+++ b/tests/tests/draganddrop/dragsource/src/android/dnd/cts/dragsource/DragSource.java
@@ -18,9 +18,11 @@
import android.app.Activity;
import android.content.ClipData;
+import android.content.ClipDescription;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
+import android.os.PersistableBundle;
import android.view.View;
public class DragSource extends Activity{
@@ -65,8 +67,14 @@
findViewById(resourceId).setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(final View v) {
+ final ClipDescription clipDescription = new ClipDescription("", new String[] {
+ ClipDescription.MIMETYPE_TEXT_URILIST });
+ PersistableBundle extras = new PersistableBundle(1);
+ extras.putString("extraKey", "extraValue");
+ clipDescription.setExtras(extras);
+ final ClipData clipData = new ClipData(clipDescription, new ClipData.Item(uri));
v.startDragAndDrop(
- ClipData.newUri(getContentResolver(), "", uri),
+ clipData,
new View.DragShadowBuilder(v),
null,
flags);
diff --git a/tests/tests/draganddrop/droptarget/res/layout/main_activity.xml b/tests/tests/draganddrop/droptarget/res/layout/main_activity.xml
index 2af6375..4a5a5b1 100644
--- a/tests/tests/draganddrop/droptarget/res/layout/main_activity.xml
+++ b/tests/tests/draganddrop/droptarget/res/layout/main_activity.xml
@@ -92,6 +92,14 @@
</TextView>
<TextView
+ android:id="@+id/extra_value"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="10dp"
+ android:text="@string/not_available_label">
+ </TextView>
+
+ <TextView
android:id="@+id/details"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/tests/tests/draganddrop/droptarget/src/android/dnd/cts/droptarget/DropTarget.java b/tests/tests/draganddrop/droptarget/src/android/dnd/cts/droptarget/DropTarget.java
index 82aaf93..2be57d4 100644
--- a/tests/tests/draganddrop/droptarget/src/android/dnd/cts/droptarget/DropTarget.java
+++ b/tests/tests/draganddrop/droptarget/src/android/dnd/cts/droptarget/DropTarget.java
@@ -22,6 +22,7 @@
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
+import android.os.PersistableBundle;
import android.view.DragEvent;
import android.view.DropPermissions;
import android.view.View;
@@ -50,6 +51,19 @@
findViewById(targetResourceId).setOnDragListener(listener);
}
+ private String checkExtraValue(DragEvent event) {
+ PersistableBundle extras = event.getClipDescription().getExtras();
+ if (extras == null) {
+ return "Null";
+ }
+
+ final String value = extras.getString("extraKey");
+ if ("extraValue".equals(value)) {
+ return RESULT_OK;
+ }
+ return value;
+ }
+
private abstract class OnDragUriListener implements View.OnDragListener {
private final boolean requestPermissions;
@@ -62,6 +76,7 @@
switch (event.getAction()) {
case DragEvent.ACTION_DRAG_STARTED:
((TextView) findViewById(R.id.drag_started)).setText("DRAG_STARTED");
+ ((TextView) findViewById(R.id.extra_value)).setText(checkExtraValue(event));
return true;
case DragEvent.ACTION_DRAG_ENTERED:
diff --git a/tests/tests/draganddrop/src/android/dnd/cts/DragAndDropTest.java b/tests/tests/draganddrop/src/android/dnd/cts/DragAndDropTest.java
index 71e1827..78b85f5 100644
--- a/tests/tests/draganddrop/src/android/dnd/cts/DragAndDropTest.java
+++ b/tests/tests/draganddrop/src/android/dnd/cts/DragAndDropTest.java
@@ -111,19 +111,27 @@
assertEquals(expectedResult, drag_started.getText());
}
+ private void assertExtraValue(String expectedResult) {
+ UiObject2 extra_value = findObject(DROP_TARGET_PKG, "extra_value");
+ assertEquals(expectedResult, extra_value.getText());
+ }
+
public void testLocal() {
doCrossAppDrag("disallow_global", "dont_request", "N/A");
assertDragStarted("N/A");
+ assertExtraValue("N/A");
}
public void testCancel() {
doCrossAppDrag("cancel_soon", "dont_request", "N/A");
assertDragStarted("DRAG_STARTED");
+ assertExtraValue("OK");
}
public void testDontGrantDontRequest() {
doCrossAppDrag("dont_grant", "dont_request", "Exception");
assertDragStarted("DRAG_STARTED");
+ assertExtraValue("OK");
}
public void testDontGrantRequestRead() {
diff --git a/tests/tests/externalservice/Android.mk b/tests/tests/externalservice/Android.mk
new file mode 100644
index 0000000..4fa4666
--- /dev/null
+++ b/tests/tests/externalservice/Android.mk
@@ -0,0 +1,42 @@
+# 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)
+
+# Don't include this package in any target
+LOCAL_MODULE_TAGS := tests
+# When built, explicitly put it in the data partition.
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_DEX_PREOPT := false
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+LOCAL_STATIC_JAVA_LIBRARIES := CtsExternalServiceCommon ctsdeviceutil ctstestrunner
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+# Tag this module as a cts_v2 test artifact
+LOCAL_COMPATIBILITY_SUITE := cts_v2
+
+LOCAL_CTS_MODULE_CONFIG := $(LOCAL_PATH)/Old$(CTS_MODULE_TEST_CONFIG)
+
+LOCAL_PACKAGE_NAME := CtsExternalServiceTestCases
+
+LOCAL_SDK_VERSION := system_current
+
+include $(BUILD_CTS_PACKAGE)
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/externalservice/AndroidManifest.xml b/tests/tests/externalservice/AndroidManifest.xml
new file mode 100644
index 0000000..0c5ea5d
--- /dev/null
+++ b/tests/tests/externalservice/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?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.externalservice.cts">
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation
+ android:name="android.support.test.runner.AndroidJUnitRunner"
+ android:label="CTS external service tests"
+ android:targetPackage="android.externalservice.cts" >
+ </instrumentation>
+</manifest>
+
diff --git a/tests/tests/externalservice/AndroidTest.xml b/tests/tests/externalservice/AndroidTest.xml
new file mode 100644
index 0000000..b07f248
--- /dev/null
+++ b/tests/tests/externalservice/AndroidTest.xml
@@ -0,0 +1,25 @@
+<?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 External Service test cases">
+ <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+ <option name="cleanup-apks" value="true" />
+ <option name="test-file-name" value="CtsExternalServiceService.apk" />
+ <option name="test-file-name" value="CtsExternalServiceTestCases.apk" />
+ </target_preparer>
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+ <option name="package" value="android.externalservice.cts" />
+ </test>
+</configuration>
diff --git a/tests/tests/externalservice/OldAndroidTest.xml b/tests/tests/externalservice/OldAndroidTest.xml
new file mode 100644
index 0000000..838db60
--- /dev/null
+++ b/tests/tests/externalservice/OldAndroidTest.xml
@@ -0,0 +1,20 @@
+<?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 External Service test cases">
+ <include name="common-config" />
+ <option name="cts-apk-installer:test-file-name" value="CtsExternalServiceService.apk" />
+ <option name="cts-apk-installer:test-file-name" value="CtsExternalServiceTestCases.apk" />
+</configuration>
diff --git a/tests/tests/externalservice/common/Android.mk b/tests/tests/externalservice/common/Android.mk
new file mode 100644
index 0000000..1ebf149
--- /dev/null
+++ b/tests/tests/externalservice/common/Android.mk
@@ -0,0 +1,30 @@
+# 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)
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := optional
+# and when built explicitly put it in the data partition
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_MODULE := CtsExternalServiceCommon
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/tests/tests/externalservice/common/src/android/externalservice/common/ServiceMessages.java b/tests/tests/externalservice/common/src/android/externalservice/common/ServiceMessages.java
new file mode 100644
index 0000000..8d23bc0
--- /dev/null
+++ b/tests/tests/externalservice/common/src/android/externalservice/common/ServiceMessages.java
@@ -0,0 +1,37 @@
+/*
+ * 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.externalservice.common;
+
+import android.os.IBinder;
+
+public class ServiceMessages {
+ // No arguments. Gets the UID and PID of the service.
+ public static final int MSG_IDENTIFY = IBinder.FIRST_CALL_TRANSACTION + 1;
+ // Response to MSG_IDENTIFY. arg1 is the UID, arg2 is the PID.
+ public static final int MSG_IDENTIFY_RESPONSE = MSG_IDENTIFY + 100;
+
+ // Bundle key in MSG_IDENTIFY_RESPONSE containing the package name.
+ public static final String IDENTIFY_PACKAGE = "packageName";
+
+ // No arguments. Starts an external service.
+ public static final int MSG_CREATE_EXTERNAL_SERVICE = IBinder.FIRST_CALL_TRANSACTION + 2;
+ // Responds to MSG_CREATE_EXTERNAL_SERVICE. obj is the IBinder on success, null on failure.
+ public static final int MSG_CREATE_EXTERNAL_SERVICE_RESPONSE =
+ MSG_CREATE_EXTERNAL_SERVICE + 100;
+
+ private ServiceMessages() {}
+}
diff --git a/tests/tests/externalservice/service/Android.mk b/tests/tests/externalservice/service/Android.mk
new file mode 100644
index 0000000..ca19202
--- /dev/null
+++ b/tests/tests/externalservice/service/Android.mk
@@ -0,0 +1,35 @@
+# 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)
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := optional
+# and when built explicitly put it in the data partition
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_STATIC_JAVA_LIBRARIES := CtsExternalServiceCommon ctstestrunner ctsdeviceutil
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsExternalServiceService
+
+# Tag this module as a cts_v2 test artifact
+LOCAL_COMPATIBILITY_SUITE := cts_v2
+
+LOCAL_SDK_VERSION := system_current
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/tests/externalservice/service/AndroidManifest.xml b/tests/tests/externalservice/service/AndroidManifest.xml
new file mode 100644
index 0000000..06fa80e
--- /dev/null
+++ b/tests/tests/externalservice/service/AndroidManifest.xml
@@ -0,0 +1,53 @@
+<?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.externalservice.service">
+
+ <application android:label="External Service Host">
+ <!-- Service used to start .ExternalService from this package. -->
+ <service android:name=".ServiceCreator"
+ android:isolatedProcess="false"
+ android:externalService="false"
+ android:exported="true" />
+
+ <!-- These services only respond to MSG_IDENTIFY for testing bindService(). -->
+ <service android:name=".IsolatedService"
+ android:isolatedProcess="true"
+ android:externalService="false"
+ android:exported="false"/>
+ <service android:name=".ExportedService"
+ android:isolatedProcess="true"
+ android:externalService="false"
+ android:exported="true"/>
+ <service android:name=".ExternalNonExportedService"
+ android:isolatedProcess="true"
+ android:externalService="true"
+ android:exported="false"/>
+ <service android:name=".ExternalNonIsolatedService"
+ android:isolatedProcess="false"
+ android:externalService="true"
+ android:exported="true"/>
+
+ <!-- The only valid, externalService entry. -->
+ <service android:name=".ExternalService"
+ android:isolatedProcess="true"
+ android:externalService="true"
+ android:exported="true"/>
+ </application>
+
+</manifest>
diff --git a/tests/tests/externalservice/service/src/android/externalservice/service/BaseService.java b/tests/tests/externalservice/service/src/android/externalservice/service/BaseService.java
new file mode 100644
index 0000000..a14adbe
--- /dev/null
+++ b/tests/tests/externalservice/service/src/android/externalservice/service/BaseService.java
@@ -0,0 +1,70 @@
+/*
+ * 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.externalservice.service;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.os.IBinder;
+import android.os.Handler;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.Process;
+import android.os.RemoteException;
+import android.util.Log;
+
+import android.externalservice.common.ServiceMessages;
+
+public class BaseService extends Service {
+ private static final String TAG = "ExternalServiceTest.Service";
+
+ private final Handler mHandler = new BaseHandler(this);
+ private final Messenger mMessenger = new Messenger(mHandler);
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ Log.d(TAG, "onBind " + intent);
+ return mMessenger.getBinder();
+ }
+
+ static class BaseHandler extends Handler {
+ private Context mContext;
+
+ public BaseHandler(Context context) {
+ mContext = context;
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ Log.d(TAG, "Received message: " + msg);
+ switch (msg.what) {
+ case ServiceMessages.MSG_IDENTIFY:
+ Message reply = Message.obtain(null, ServiceMessages.MSG_IDENTIFY_RESPONSE,
+ Process.myUid(), Process.myPid());
+ reply.getData().putString(ServiceMessages.IDENTIFY_PACKAGE,
+ mContext.getPackageName());
+ try {
+ msg.replyTo.send(reply);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error sending MSG_IDENTIFY_RESPONSE", e);
+ }
+ break;
+ }
+ super.handleMessage(msg);
+ }
+ }
+}
diff --git a/tests/tests/externalservice/service/src/android/externalservice/service/ExportedService.java b/tests/tests/externalservice/service/src/android/externalservice/service/ExportedService.java
new file mode 100644
index 0000000..faee786
--- /dev/null
+++ b/tests/tests/externalservice/service/src/android/externalservice/service/ExportedService.java
@@ -0,0 +1,20 @@
+/*
+ * 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.externalservice.service;
+
+public class ExportedService extends BaseService {
+}
diff --git a/tests/tests/externalservice/service/src/android/externalservice/service/ExternalNonExportedService.java b/tests/tests/externalservice/service/src/android/externalservice/service/ExternalNonExportedService.java
new file mode 100644
index 0000000..91ab426
--- /dev/null
+++ b/tests/tests/externalservice/service/src/android/externalservice/service/ExternalNonExportedService.java
@@ -0,0 +1,20 @@
+/*
+ * 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.externalservice.service;
+
+public class ExternalNonExportedService extends BaseService {
+}
diff --git a/tests/tests/externalservice/service/src/android/externalservice/service/ExternalNonIsolatedService.java b/tests/tests/externalservice/service/src/android/externalservice/service/ExternalNonIsolatedService.java
new file mode 100644
index 0000000..c8f4a50
--- /dev/null
+++ b/tests/tests/externalservice/service/src/android/externalservice/service/ExternalNonIsolatedService.java
@@ -0,0 +1,20 @@
+/*
+ * 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.externalservice.service;
+
+public class ExternalNonIsolatedService extends BaseService {
+}
diff --git a/tests/tests/externalservice/service/src/android/externalservice/service/ExternalService.java b/tests/tests/externalservice/service/src/android/externalservice/service/ExternalService.java
new file mode 100644
index 0000000..50b475a
--- /dev/null
+++ b/tests/tests/externalservice/service/src/android/externalservice/service/ExternalService.java
@@ -0,0 +1,20 @@
+/*
+ * 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.externalservice.service;
+
+public class ExternalService extends BaseService {
+}
diff --git a/tests/tests/externalservice/service/src/android/externalservice/service/IsolatedService.java b/tests/tests/externalservice/service/src/android/externalservice/service/IsolatedService.java
new file mode 100644
index 0000000..94db76f
--- /dev/null
+++ b/tests/tests/externalservice/service/src/android/externalservice/service/IsolatedService.java
@@ -0,0 +1,20 @@
+/*
+ * 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.externalservice.service;
+
+public class IsolatedService extends BaseService {
+}
diff --git a/tests/tests/externalservice/service/src/android/externalservice/service/ServiceCreator.java b/tests/tests/externalservice/service/src/android/externalservice/service/ServiceCreator.java
new file mode 100644
index 0000000..3af5c98
--- /dev/null
+++ b/tests/tests/externalservice/service/src/android/externalservice/service/ServiceCreator.java
@@ -0,0 +1,114 @@
+/*
+ * 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.externalservice.service;
+
+import android.app.Service;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.Process;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.ArrayList;
+
+import android.externalservice.common.ServiceMessages;
+
+public class ServiceCreator extends Service {
+ private static final String TAG = "ExternalServiceTest.ServiceCreator";
+
+ private final ArrayList<CreatorConnection> mConnections = new ArrayList<>();
+
+ private final Handler mHandler = new BaseService.BaseHandler(this) {
+ @Override
+ public void handleMessage(Message msg) {
+ Log.d(TAG, "Received message: " + msg);
+ switch (msg.what) {
+ case ServiceMessages.MSG_CREATE_EXTERNAL_SERVICE:
+ final Context context = ServiceCreator.this;
+ final String pkgName = context.getPackageName();
+ Intent intent = new Intent();
+ intent.setComponent(new ComponentName(pkgName, pkgName+".ExternalService"));
+ CreatorConnection conn = new CreatorConnection(msg.replyTo);
+ boolean result = context.bindService(intent, conn,
+ Context.BIND_AUTO_CREATE | Context.BIND_EXTERNAL_SERVICE);
+ if (result) {
+ mConnections.add(conn);
+ } else {
+ Message reply = Message.obtain();
+ reply.what = ServiceMessages.MSG_CREATE_EXTERNAL_SERVICE_RESPONSE;
+ try {
+ msg.replyTo.send(reply);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to send MSG_CREATE_EXTERNAL_SERVICE_RESPONSE", e);
+ }
+ }
+ }
+ super.handleMessage(msg);
+ }
+ };
+
+ private final Messenger mMessenger = new Messenger(mHandler);
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ Log.d(TAG, "onBind " + intent);
+ return mMessenger.getBinder();
+ }
+
+ @Override
+ public void onDestroy() {
+ for (final CreatorConnection conn : mConnections) {
+ unbindService(conn);
+ }
+ super.onDestroy();
+ }
+
+ private class CreatorConnection implements ServiceConnection {
+ private IBinder mService = null;
+ private Messenger mReplyTo = null;
+
+ public CreatorConnection(Messenger replyTo) {
+ mReplyTo = replyTo;
+ }
+
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ Log.d(TAG, "onServiceConnected " + name);
+ Message msg =
+ Message.obtain(null, ServiceMessages.MSG_CREATE_EXTERNAL_SERVICE_RESPONSE);
+ msg.obj = new Messenger(service);
+ try {
+ mReplyTo.send(msg);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to send MSG_CREATE_EXTERNAL_SERVICE_RESPONSE", e);
+ }
+ mReplyTo = null;
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ Log.d(TAG, "onServiceDisconnected " + name);
+ mService = null;
+ }
+ }
+}
diff --git a/tests/tests/externalservice/src/android/externalservice/cts/ExternalServiceTest.java b/tests/tests/externalservice/src/android/externalservice/cts/ExternalServiceTest.java
new file mode 100644
index 0000000..b80b2ff
--- /dev/null
+++ b/tests/tests/externalservice/src/android/externalservice/cts/ExternalServiceTest.java
@@ -0,0 +1,358 @@
+/*
+ * 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.externalservice.cts;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.ConditionVariable;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.Parcel;
+import android.os.Process;
+import android.os.RemoteException;
+import android.test.AndroidTestCase;
+import android.util.Log;
+import android.util.MutableInt;
+
+import android.externalservice.common.ServiceMessages;
+
+public class ExternalServiceTest extends AndroidTestCase {
+ private static final String TAG = "ExternalServiceTest";
+
+ static final String sServicePackage = "android.externalservice.service";
+
+ private Connection mConnection = new Connection();
+
+ private ConditionVariable mCondition = new ConditionVariable(false);
+
+ static final int CONDITION_TIMEOUT = 10 * 1000 /* 10 seconds */;
+
+ public void tearDown() {
+ if (mConnection.service != null)
+ getContext().unbindService(mConnection);
+ }
+
+ /** Tests that an isolatedProcess service cannot be bound to by an external package. */
+ public void testFailBindIsolated() {
+ Intent intent = new Intent();
+ intent.setComponent(new ComponentName(sServicePackage, sServicePackage+".IsolatedService"));
+ try {
+ getContext().bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
+ fail("Should not be able to bind to non-exported, non-external service");
+ } catch (SecurityException e) {
+ }
+ }
+
+ /** Tests that BIND_EXTERNAL_SERVICE does not work with plain isolatedProcess services. */
+ public void testFailBindExternalIsolated() {
+ Intent intent = new Intent();
+ intent.setComponent(new ComponentName(sServicePackage, sServicePackage+".IsolatedService"));
+ try {
+ getContext().bindService(intent, mConnection,
+ Context.BIND_AUTO_CREATE | Context.BIND_EXTERNAL_SERVICE);
+ fail("Should not be able to BIND_EXTERNAL_SERVICE to non-exported, non-external service");
+ } catch (SecurityException e) {
+ }
+ }
+
+ /** Tests that BIND_EXTERNAL_SERVICE does not work with exported, isolatedProcess services (
+ * requires externalService as well). */
+ public void testFailBindExternalExported() {
+ Intent intent = new Intent();
+ intent.setComponent(new ComponentName(sServicePackage, sServicePackage+".ExportedService"));
+ try {
+ getContext().bindService(intent, mConnection,
+ Context.BIND_AUTO_CREATE | Context.BIND_EXTERNAL_SERVICE);
+ fail("Should not be able to BIND_EXTERNAL_SERVICE to non-external service");
+ } catch (SecurityException e) {
+ }
+ }
+
+ /** Tests that BIND_EXTERNAL_SERVICE requires that an externalService be exported. */
+ public void testFailBindExternalNonExported() {
+ Intent intent = new Intent();
+ intent.setComponent(
+ new ComponentName(sServicePackage, sServicePackage+".ExternalNonExportedService"));
+ try {
+ getContext().bindService(intent, mConnection,
+ Context.BIND_AUTO_CREATE | Context.BIND_EXTERNAL_SERVICE);
+ fail("Should not be able to BIND_EXTERNAL_SERVICE to non-exported service");
+ } catch (SecurityException e) {
+ }
+ }
+
+ /** Tests that BIND_EXTERNAL_SERVICE requires the service be an isolatedProcess. */
+ public void testFailBindExternalNonIsolated() {
+ Intent intent = new Intent();
+ intent.setComponent(
+ new ComponentName(sServicePackage, sServicePackage+".ExternalNonIsolatedService"));
+ try {
+ getContext().bindService(intent, mConnection,
+ Context.BIND_AUTO_CREATE | Context.BIND_EXTERNAL_SERVICE);
+ fail("Should not be able to BIND_EXTERNAL_SERVICE to non-isolated service");
+ } catch (SecurityException e) {
+ }
+ }
+
+ /** Tests that an externalService can only be bound with BIND_EXTERNAL_SERVICE. */
+ public void testFailBindWithoutBindExternal() {
+ Intent intent = new Intent();
+ intent.setComponent(new ComponentName(sServicePackage, sServicePackage+".ExternalService"));
+ try {
+ getContext().bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
+ fail("Should not be able to bind to an external service without BIND_EXTERNAL_SERVICE");
+ } catch (SecurityException e) {
+ }
+ }
+
+ /** Tests that an external service can be bound, and that it runs as a different principal. */
+ public void testBindExternalService() {
+ // Start the service and wait for connection.
+ Intent intent = new Intent();
+ intent.setComponent(new ComponentName(sServicePackage, sServicePackage+".ExternalService"));
+
+ mCondition.close();
+ assertTrue(getContext().bindService(intent, mConnection,
+ Context.BIND_AUTO_CREATE | Context.BIND_EXTERNAL_SERVICE));
+
+ assertTrue(mCondition.block(CONDITION_TIMEOUT));
+ assertEquals(getContext().getPackageName(), mConnection.name.getPackageName());
+ assertNotSame(sServicePackage, mConnection.name.getPackageName());
+
+ // Check the identity of the service.
+ Messenger remote = new Messenger(mConnection.service);
+ MutableInt uid = new MutableInt(0);
+ MutableInt pid = new MutableInt(0);
+ StringBuilder pkg = new StringBuilder();
+ assertTrue(identifyService(remote, uid, pid, pkg));
+
+ assertFalse(uid.value == 0 || pid.value == 0);
+ assertNotEquals(Process.myUid(), uid.value);
+ assertNotEquals(Process.myPid(), pid.value);
+ assertEquals(getContext().getPackageName(), pkg.toString());
+ }
+
+ /** Tests that the APK providing the externalService can bind the service itself, and that
+ * other APKs bind to a different instance of it. */
+ public void testBindExternalServiceWithRunningOwn() {
+ // Start the service that will create the externalService.
+ final Connection creatorConnection = new Connection();
+ Intent intent = new Intent();
+ intent.setComponent(new ComponentName(sServicePackage, sServicePackage+".ServiceCreator"));
+
+ mCondition.close();
+ assertTrue(getContext().bindService(intent, creatorConnection, Context.BIND_AUTO_CREATE));
+ assertTrue(mCondition.block(CONDITION_TIMEOUT));
+
+ // Get the identity of the creator.
+ Messenger remoteCreator = new Messenger(creatorConnection.service);
+ MutableInt creatorUid = new MutableInt(0);
+ MutableInt creatorPid = new MutableInt(0);
+ StringBuilder creatorPkg = new StringBuilder();
+ assertTrue(identifyService(remoteCreator, creatorUid, creatorPid, creatorPkg));
+ assertFalse(creatorUid.value == 0 || creatorPid.value == 0);
+
+ // Have the creator actually start its service.
+ final Message creatorMsg =
+ Message.obtain(null, ServiceMessages.MSG_CREATE_EXTERNAL_SERVICE);
+ Handler creatorHandler = new Handler(Looper.getMainLooper()) {
+ @Override
+ public void handleMessage(Message msg) {
+ Log.d(TAG, "Received message: " + msg);
+ switch (msg.what) {
+ case ServiceMessages.MSG_CREATE_EXTERNAL_SERVICE_RESPONSE:
+ creatorMsg.copyFrom(msg);
+ mCondition.open();
+ break;
+ }
+ super.handleMessage(msg);
+ }
+ };
+ Messenger localCreator = new Messenger(creatorHandler);
+ creatorMsg.replyTo = localCreator;
+ try {
+ mCondition.close();
+ remoteCreator.send(creatorMsg);
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception" + e);
+ return;
+ }
+ assertTrue(mCondition.block(CONDITION_TIMEOUT));
+
+ // Get the connection to the creator's service.
+ assertNotNull(creatorMsg.obj);
+ Messenger remoteCreatorService = (Messenger) creatorMsg.obj;
+ MutableInt creatorServiceUid = new MutableInt(0);
+ MutableInt creatorServicePid = new MutableInt(0);
+ StringBuilder creatorServicePkg = new StringBuilder();
+ assertTrue(identifyService(remoteCreatorService, creatorServiceUid, creatorServicePid,
+ creatorServicePkg));
+ assertFalse(creatorServiceUid.value == 0 || creatorPid.value == 0);
+
+ // Create an external service from this (the test) process.
+ intent = new Intent();
+ intent.setComponent(new ComponentName(sServicePackage, sServicePackage+".ExternalService"));
+
+ mCondition.close();
+ assertTrue(getContext().bindService(intent, mConnection,
+ Context.BIND_AUTO_CREATE | Context.BIND_EXTERNAL_SERVICE));
+ assertTrue(mCondition.block(CONDITION_TIMEOUT));
+ MutableInt serviceUid = new MutableInt(0);
+ MutableInt servicePid = new MutableInt(0);
+ StringBuilder servicePkg = new StringBuilder();
+ assertTrue(identifyService(new Messenger(mConnection.service), serviceUid, servicePid,
+ servicePkg));
+ assertFalse(serviceUid.value == 0 || servicePid.value == 0);
+
+ // Make sure that all the processes are unique.
+ int myUid = Process.myUid();
+ int myPid = Process.myPid();
+ String myPkg = getContext().getPackageName();
+
+ assertNotEquals(myUid, creatorUid.value);
+ assertNotEquals(myUid, creatorServiceUid.value);
+ assertNotEquals(myUid, serviceUid.value);
+ assertNotEquals(myPid, creatorPid.value);
+ assertNotEquals(myPid, creatorServicePid.value);
+ assertNotEquals(myPid, servicePid.value);
+
+ assertNotEquals(creatorUid.value, creatorServiceUid.value);
+ assertNotEquals(creatorUid.value, serviceUid.value);
+ assertNotEquals(creatorPid.value, creatorServicePid.value);
+ assertNotEquals(creatorPid.value, servicePid.value);
+
+ assertNotEquals(creatorServiceUid.value, serviceUid.value);
+ assertNotEquals(creatorServicePid.value, servicePid.value);
+
+ assertNotEquals(myPkg, creatorPkg.toString());
+ assertNotEquals(myPkg, creatorServicePkg.toString());
+ assertEquals(creatorPkg.toString(), creatorServicePkg.toString());
+ assertEquals(myPkg, servicePkg.toString());
+
+ getContext().unbindService(creatorConnection);
+ }
+
+ /** Tests that the binding to an externalService can be changed. */
+ public void testBindExternalAboveClient() {
+ // Start the service and wait for connection.
+ Intent intent = new Intent();
+ intent.setComponent(new ComponentName(sServicePackage, sServicePackage+".ExternalService"));
+
+ mCondition.close();
+ Connection initialConn = new Connection();
+ assertTrue(getContext().bindService(intent, initialConn,
+ Context.BIND_AUTO_CREATE | Context.BIND_EXTERNAL_SERVICE));
+
+ assertTrue(mCondition.block(CONDITION_TIMEOUT));
+
+ MutableInt uidOne = new MutableInt(0);
+ MutableInt pidOne = new MutableInt(0);
+ StringBuilder pkgOne = new StringBuilder();
+ assertTrue(identifyService(new Messenger(initialConn.service), uidOne, pidOne, pkgOne));
+ assertFalse(uidOne.value == 0 || pidOne.value == 0);
+
+ // Bind the service with a different priority.
+ mCondition.close();
+ Connection prioConn = new Connection();
+ assertTrue(getContext().bindService(intent, prioConn,
+ Context.BIND_AUTO_CREATE | Context.BIND_EXTERNAL_SERVICE |
+ Context.BIND_ABOVE_CLIENT));
+
+ assertTrue(mCondition.block(CONDITION_TIMEOUT));
+
+ MutableInt uidTwo = new MutableInt(0);
+ MutableInt pidTwo = new MutableInt(0);
+ StringBuilder pkgTwo = new StringBuilder();
+ Messenger prioMessenger = new Messenger(prioConn.service);
+ assertTrue(identifyService(prioMessenger, uidTwo, pidTwo, pkgTwo));
+ assertFalse(uidTwo.value == 0 || pidTwo.value == 0);
+
+ assertEquals(uidOne.value, uidTwo.value);
+ assertEquals(pidOne.value, pidTwo.value);
+ assertEquals(pkgOne.toString(), pkgTwo.toString());
+ assertNotEquals(Process.myUid(), uidOne.value);
+ assertNotEquals(Process.myPid(), pidOne.value);
+ assertEquals(getContext().getPackageName(), pkgOne.toString());
+
+ getContext().unbindService(prioConn);
+ getContext().unbindService(initialConn);
+ }
+
+ /** Given a Messenger, this will message the service to retrieve its UID, PID, and package name,
+ * storing the results in the mutable parameters. */
+ private boolean identifyService(Messenger service, final MutableInt uid, final MutableInt pid,
+ final StringBuilder packageName) {
+ Handler handler = new Handler(Looper.getMainLooper()) {
+ @Override
+ public void handleMessage(Message msg) {
+ Log.d(TAG, "Received message: " + msg);
+ switch (msg.what) {
+ case ServiceMessages.MSG_IDENTIFY_RESPONSE:
+ uid.value = msg.arg1;
+ pid.value = msg.arg2;
+ packageName.append(
+ msg.getData().getString(ServiceMessages.IDENTIFY_PACKAGE));
+ mCondition.open();
+ break;
+ }
+ super.handleMessage(msg);
+ }
+ };
+ Messenger local = new Messenger(handler);
+
+ Message msg = Message.obtain(null, ServiceMessages.MSG_IDENTIFY);
+ msg.replyTo = local;
+ try {
+ mCondition.close();
+ service.send(msg);
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception: " + e);
+ return false;
+ }
+
+ return mCondition.block(CONDITION_TIMEOUT);
+ }
+
+ private class Connection implements ServiceConnection {
+ IBinder service = null;
+ ComponentName name = null;
+ boolean disconnected = false;
+
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ Log.d(TAG, "onServiceConnected " + name);
+ this.service = service;
+ this.name = name;
+ mCondition.open();
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ Log.d(TAG, "onServiceDisconnected " + name);
+ }
+ }
+
+ private <T> void assertNotEquals(T expected, T actual) {
+ assertFalse("Expected <" + expected + "> should not be equal to actual <" + actual + ">",
+ expected.equals(actual));
+ }
+}
diff --git a/tests/tests/graphics/res/color/fill_gradient_linear.xml b/tests/tests/graphics/res/color/fill_gradient_linear.xml
new file mode 100644
index 0000000..e0e3f03
--- /dev/null
+++ b/tests/tests/graphics/res/color/fill_gradient_linear.xml
@@ -0,0 +1,29 @@
+<?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.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+ android:angle="90"
+ android:startColor="?android:attr/colorPrimary"
+ android:endColor="?android:attr/colorControlActivated"
+ android:centerColor="#00ff0000"
+ android:startX="0"
+ android:startY="0"
+ android:endX="100"
+ android:endY="100"
+ android:type="linear">
+</gradient>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/color/fill_gradient_linear_item.xml b/tests/tests/graphics/res/color/fill_gradient_linear_item.xml
new file mode 100644
index 0000000..cfb1236
--- /dev/null
+++ b/tests/tests/graphics/res/color/fill_gradient_linear_item.xml
@@ -0,0 +1,32 @@
+<?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.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+ android:angle="90"
+ android:startColor="?android:attr/colorPrimary"
+ android:endColor="?android:attr/colorControlActivated"
+ android:centerColor="#f00"
+ android:startX="0"
+ android:startY="0"
+ android:endX="100"
+ android:endY="100"
+ android:type="linear">
+ <item android:offset="0.1" android:color="?android:attr/colorPrimary"/>
+ <item android:offset="0.4" android:color="#fff"/>
+ <item android:offset="0.9" android:color="?android:attr/colorControlActivated"/>
+</gradient>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/color/fill_gradient_linear_item_overlap.xml b/tests/tests/graphics/res/color/fill_gradient_linear_item_overlap.xml
new file mode 100644
index 0000000..18274b9
--- /dev/null
+++ b/tests/tests/graphics/res/color/fill_gradient_linear_item_overlap.xml
@@ -0,0 +1,33 @@
+<?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.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+ android:angle="90"
+ android:startColor="?android:attr/colorPrimary"
+ android:endColor="?android:attr/colorControlActivated"
+ android:centerColor="#f00"
+ android:startX="0"
+ android:startY="0"
+ android:endX="100"
+ android:endY="100"
+ android:type="linear">
+ <item android:offset="0.1" android:color="?android:attr/colorPrimary"/>
+ <item android:offset="0.4" android:color="#f00"/>
+ <item android:offset="0.4" android:color="#fff"/>
+ <item android:offset="0.9" android:color="?android:attr/colorControlActivated"/>
+</gradient>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/color/fill_gradient_radial.xml b/tests/tests/graphics/res/color/fill_gradient_radial.xml
new file mode 100644
index 0000000..ef6fd70
--- /dev/null
+++ b/tests/tests/graphics/res/color/fill_gradient_radial.xml
@@ -0,0 +1,27 @@
+<?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.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+ android:centerColor="#ff0000"
+ android:endColor="?android:attr/colorControlActivated"
+ android:centerX="300"
+ android:centerY="300"
+ android:gradientRadius="100"
+ android:startColor="?android:attr/colorPrimary"
+ android:type="radial">
+</gradient>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/color/fill_gradient_radial_item.xml b/tests/tests/graphics/res/color/fill_gradient_radial_item.xml
new file mode 100644
index 0000000..c6cea7c
--- /dev/null
+++ b/tests/tests/graphics/res/color/fill_gradient_radial_item.xml
@@ -0,0 +1,30 @@
+<?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.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+ android:centerColor="#ff0000"
+ android:endColor="#ff0000ff"
+ android:centerX="300"
+ android:centerY="300"
+ android:gradientRadius="100"
+ android:startColor="#ffffffff"
+ android:type="radial">
+ <item android:offset="0.1" android:color="?android:attr/colorPrimary"/>
+ <item android:offset="0.4" android:color="#fff"/>
+ <item android:offset="0.9" android:color="?android:attr/colorControlActivated"/>
+</gradient>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/color/fill_gradient_radial_item_short.xml b/tests/tests/graphics/res/color/fill_gradient_radial_item_short.xml
new file mode 100644
index 0000000..fefbe9f
--- /dev/null
+++ b/tests/tests/graphics/res/color/fill_gradient_radial_item_short.xml
@@ -0,0 +1,26 @@
+<?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.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+ android:centerX="300"
+ android:centerY="300"
+ android:gradientRadius="100"
+ android:type="radial">
+ <item android:offset="0.1" android:color="?android:attr/colorPrimary"/>
+ <item android:offset="0.9" android:color="?android:attr/colorControlActivated"/>
+</gradient>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/color/fill_gradient_sweep.xml b/tests/tests/graphics/res/color/fill_gradient_sweep.xml
new file mode 100644
index 0000000..e1fbd10
--- /dev/null
+++ b/tests/tests/graphics/res/color/fill_gradient_sweep.xml
@@ -0,0 +1,27 @@
+<?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.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+ android:centerColor="#ff0000"
+ android:endColor="#ff0000ff"
+ android:centerX="500"
+ android:centerY="500"
+ android:gradientRadius="10"
+ android:startColor="#ffffffff"
+ android:type="sweep">
+</gradient>
diff --git a/tests/tests/graphics/res/color/fill_gradient_sweep_item.xml b/tests/tests/graphics/res/color/fill_gradient_sweep_item.xml
new file mode 100644
index 0000000..332b9389
--- /dev/null
+++ b/tests/tests/graphics/res/color/fill_gradient_sweep_item.xml
@@ -0,0 +1,30 @@
+<?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.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+ android:centerColor="#ff0000"
+ android:endColor="#ff0000ff"
+ android:centerX="500"
+ android:centerY="500"
+ android:gradientRadius="10"
+ android:startColor="#ffffffff"
+ android:type="sweep">
+ <item android:offset="0.1" android:color="?android:attr/colorPrimary"/>
+ <item android:offset="0.4" android:color="#fff"/>
+ <item android:offset="0.9" android:color="?android:attr/colorControlActivated"/>
+</gradient>
diff --git a/tests/tests/graphics/res/color/fill_gradient_sweep_item_long.xml b/tests/tests/graphics/res/color/fill_gradient_sweep_item_long.xml
new file mode 100644
index 0000000..3931288
--- /dev/null
+++ b/tests/tests/graphics/res/color/fill_gradient_sweep_item_long.xml
@@ -0,0 +1,30 @@
+<?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.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+ android:centerX="500"
+ android:centerY="500"
+ android:gradientRadius="10"
+ android:type="sweep">
+ <item android:offset="-0.3" android:color="#f00"/>
+ <item android:offset="0.1" android:color="?android:attr/colorPrimary"/>
+ <item android:offset="0.4" android:color="#0f0"/>
+ <item android:offset="0.6" android:color="#00f"/>
+ <item android:offset="0.7" android:color="?android:attr/colorControlActivated"/>
+ <item android:offset="1.5" android:color="#00f"/>
+</gradient>
diff --git a/tests/tests/graphics/res/color/stroke_gradient.xml b/tests/tests/graphics/res/color/stroke_gradient.xml
new file mode 100644
index 0000000..cb324c9
--- /dev/null
+++ b/tests/tests/graphics/res/color/stroke_gradient.xml
@@ -0,0 +1,29 @@
+<?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.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+ android:angle="90"
+ android:centerColor="#7f7f7f"
+ android:endColor="#ffffff"
+ android:startColor="#000000"
+ android:startX="0"
+ android:endX="100"
+ android:startY="0"
+ android:endY="0"
+ android:type="linear">
+</gradient>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/color/stroke_gradient_item.xml b/tests/tests/graphics/res/color/stroke_gradient_item.xml
new file mode 100644
index 0000000..15d948c
--- /dev/null
+++ b/tests/tests/graphics/res/color/stroke_gradient_item.xml
@@ -0,0 +1,32 @@
+<?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.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+ android:angle="90"
+ android:centerColor="#7f7f7f"
+ android:endColor="#ffffff"
+ android:startColor="#000000"
+ android:startX="0"
+ android:endX="100"
+ android:startY="0"
+ android:endY="0"
+ android:type="linear">
+ <item android:offset="0.1" android:color="#f00"/>
+ <item android:offset="0.2" android:color="#f0f"/>
+ <item android:offset="0.9" android:color="#f00f"/>
+</gradient>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/color/stroke_gradient_item_alpha.xml b/tests/tests/graphics/res/color/stroke_gradient_item_alpha.xml
new file mode 100644
index 0000000..fda2b88
--- /dev/null
+++ b/tests/tests/graphics/res/color/stroke_gradient_item_alpha.xml
@@ -0,0 +1,28 @@
+<?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.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+ android:startX="0"
+ android:endX="100"
+ android:startY="0"
+ android:endY="0"
+ android:type="linear">
+ <item android:offset="0.1" android:color="#f00"/>
+ <item android:offset="0.2" android:color="#2f0f"/>
+ <item android:offset="0.9" android:color="#f00f"/>
+</gradient>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_1_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_1_golden.png
new file mode 100644
index 0000000..638802f
--- /dev/null
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_1_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_2_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_2_golden.png
new file mode 100644
index 0000000..1f248e3
--- /dev/null
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_2_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_3_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_3_golden.png
new file mode 100644
index 0000000..085e72a
--- /dev/null
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_3_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable/vector_icon_gradient_1.xml b/tests/tests/graphics/res/drawable/vector_icon_gradient_1.xml
new file mode 100644
index 0000000..d67aca7
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/vector_icon_gradient_1.xml
@@ -0,0 +1,91 @@
+<?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.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="64dp"
+ android:width="64dp"
+ android:viewportHeight="400"
+ android:viewportWidth="400" >
+
+<group android:name="backgroundGroup"
+ android:scaleX="0.5"
+ android:scaleY="0.5">
+ <path
+ android:name="background1"
+ android:fillColor="@color/fill_gradient_linear"
+ android:pathData="M 0,0 l 200,0 l 0, 200 l -200, 0 z" />
+ <path
+ android:name="background2"
+ android:fillColor="@color/fill_gradient_radial"
+ android:pathData="M 200,200 l 200,0 l 0, 200 l -200, 0 z" />
+ <path
+ android:name="background3"
+ android:fillColor="@color/fill_gradient_sweep"
+ android:pathData="M 400,400 l 200,0 l 0, 200 l -200, 0 z" />
+</group>
+<group
+ android:name="translateToCenterGroup"
+ android:translateX="50.0"
+ android:translateY="90.0" >
+ <path
+ android:name="twoLines"
+ android:pathData="@string/twoLinePathData"
+ android:strokeColor="@color/stroke_gradient"
+ android:strokeWidth="20" />
+
+ <group
+ android:name="rotationGroup"
+ android:pivotX="0.0"
+ android:pivotY="0.0"
+ android:rotation="-45.0">
+ <path
+ android:name="twoLines1"
+ android:pathData="@string/twoLinePathData"
+ android:strokeColor="@color/stroke_gradient"
+ android:strokeWidth="20" />
+
+ <group
+ android:name="translateGroup"
+ android:translateX="130.0"
+ android:translateY="160.0">
+ <group android:name="scaleGroup" >
+ <path
+ android:name="twoLines3"
+ android:pathData="@string/twoLinePathData"
+ android:strokeColor="@color/stroke_gradient"
+ android:strokeWidth="20" />
+ </group>
+ </group>
+
+ <group
+ android:name="translateGroupHalf"
+ android:translateX="65.0"
+ android:translateY="80.0">
+ <group android:name="scaleGroup" >
+ <path
+ android:name="twoLines2"
+ android:pathData="@string/twoLinePathData"
+ android:fillColor="@color/fill_gradient_linear"
+ android:strokeColor="@color/stroke_gradient"
+ android:strokeWidth="20" />
+ </group>
+ </group>
+ </group>
+</group>
+
+</vector>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/drawable/vector_icon_gradient_2.xml b/tests/tests/graphics/res/drawable/vector_icon_gradient_2.xml
new file mode 100644
index 0000000..abf3c7a
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/vector_icon_gradient_2.xml
@@ -0,0 +1,90 @@
+<?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.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="64dp"
+ android:width="64dp"
+ android:viewportHeight="400"
+ android:viewportWidth="400" >
+
+<group android:name="backgroundGroup"
+ android:scaleX="0.5"
+ android:scaleY="0.5">
+ <path
+ android:name="background1"
+ android:fillColor="@color/fill_gradient_linear_item"
+ android:pathData="M 0,0 l 200,0 l 0, 200 l -200, 0 z" />
+ <path
+ android:name="background2"
+ android:fillColor="@color/fill_gradient_radial_item"
+ android:pathData="M 200,200 l 200,0 l 0, 200 l -200, 0 z" />
+ <path
+ android:name="background3"
+ android:fillColor="@color/fill_gradient_sweep_item"
+ android:pathData="M 400,400 l 200,0 l 0, 200 l -200, 0 z" />
+</group>
+<group
+ android:name="translateToCenterGroup"
+ android:translateX="50.0"
+ android:translateY="90.0" >
+ <path
+ android:name="twoLines"
+ android:pathData="@string/twoLinePathData"
+ android:strokeColor="@color/stroke_gradient_item"
+ android:strokeWidth="20" />
+
+ <group
+ android:name="rotationGroup"
+ android:pivotX="0.0"
+ android:pivotY="0.0"
+ android:rotation="-45.0">
+ <path
+ android:name="twoLines1"
+ android:pathData="@string/twoLinePathData"
+ android:strokeColor="@color/stroke_gradient_item"
+ android:strokeWidth="20" />
+
+ <group
+ android:name="translateGroup"
+ android:translateX="130.0"
+ android:translateY="160.0">
+ <group android:name="scaleGroup" >
+ <path
+ android:name="twoLines3"
+ android:pathData="@string/twoLinePathData"
+ android:strokeColor="@color/stroke_gradient_item"
+ android:strokeWidth="20" />
+ </group>
+ </group>
+
+ <group
+ android:name="translateGroupHalf"
+ android:translateX="65.0"
+ android:translateY="80.0">
+ <group android:name="scaleGroup" >
+ <path
+ android:name="twoLines2"
+ android:pathData="@string/twoLinePathData"
+ android:strokeColor="@color/stroke_gradient_item"
+ android:strokeWidth="20" />
+ </group>
+ </group>
+ </group>
+</group>
+
+</vector>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/drawable/vector_icon_gradient_3.xml b/tests/tests/graphics/res/drawable/vector_icon_gradient_3.xml
new file mode 100644
index 0000000..5f9726f
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/vector_icon_gradient_3.xml
@@ -0,0 +1,90 @@
+<?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.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="64dp"
+ android:width="64dp"
+ android:viewportHeight="400"
+ android:viewportWidth="400" >
+
+<group android:name="backgroundGroup"
+ android:scaleX="0.5"
+ android:scaleY="0.5">
+ <path
+ android:name="background1"
+ android:fillColor="@color/fill_gradient_linear_item_overlap"
+ android:pathData="M 0,0 l 200,0 l 0, 200 l -200, 0 z" />
+ <path
+ android:name="background2"
+ android:fillColor="@color/fill_gradient_radial_item_short"
+ android:pathData="M 200,200 l 200,0 l 0, 200 l -200, 0 z" />
+ <path
+ android:name="background3"
+ android:fillColor="@color/fill_gradient_sweep_item_long"
+ android:pathData="M 400,400 l 200,0 l 0, 200 l -200, 0 z" />
+</group>
+<group
+ android:name="translateToCenterGroup"
+ android:translateX="50.0"
+ android:translateY="90.0" >
+ <path
+ android:name="twoLines"
+ android:pathData="@string/twoLinePathData"
+ android:strokeColor="@color/stroke_gradient_item_alpha"
+ android:strokeWidth="20" />
+
+ <group
+ android:name="rotationGroup"
+ android:pivotX="0.0"
+ android:pivotY="0.0"
+ android:rotation="-45.0">
+ <path
+ android:name="twoLines1"
+ android:pathData="@string/twoLinePathData"
+ android:strokeColor="@color/stroke_gradient_item_alpha"
+ android:strokeWidth="20" />
+
+ <group
+ android:name="translateGroup"
+ android:translateX="130.0"
+ android:translateY="160.0">
+ <group android:name="scaleGroup" >
+ <path
+ android:name="twoLines3"
+ android:pathData="@string/twoLinePathData"
+ android:strokeColor="@color/stroke_gradient_item_alpha"
+ android:strokeWidth="20" />
+ </group>
+ </group>
+
+ <group
+ android:name="translateGroupHalf"
+ android:translateX="65.0"
+ android:translateY="80.0">
+ <group android:name="scaleGroup" >
+ <path
+ android:name="twoLines2"
+ android:pathData="@string/twoLinePathData"
+ android:strokeColor="@color/stroke_gradient_item_alpha"
+ android:strokeWidth="20" />
+ </group>
+ </group>
+ </group>
+</group>
+
+</vector>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/values/strings.xml b/tests/tests/graphics/res/values/strings.xml
index c167278..8208b19 100644
--- a/tests/tests/graphics/res/values/strings.xml
+++ b/tests/tests/graphics/res/values/strings.xml
@@ -176,4 +176,5 @@
text, I would love to see the kind of devices you guys now use! Guys, maybe some devices need longer string!
I think so, so how about double this string, like copy and paste! </string>
<string name="rectangle200">"M 0,0 l 200,0 l 0, 200 l -200, 0 z"</string>
+ <string name="twoLinePathData">"M 0,0 v 100 M 0,0 h 100"</string>
</resources>
diff --git a/tests/tests/graphics/src/android/graphics/cts/VulkanReservedTest.java b/tests/tests/graphics/src/android/graphics/cts/VulkanReservedTest.java
deleted file mode 100644
index bfd520e..0000000
--- a/tests/tests/graphics/src/android/graphics/cts/VulkanReservedTest.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.graphics.cts;
-
-import android.cts.util.FileUtils;
-
-import junit.framework.TestCase;
-
-import java.io.File;
-
-public class VulkanReservedTest extends TestCase {
-
- /**
- * Assert that file with given path does not exist.
- */
- private static void assertNoFile(String filename) {
- assertFalse(filename + " must not exist", new File(filename).exists());
- }
-
- /**
- * Test that no vendor ships libvulkan.so before ratification and
- * appropriate CTS coverage.
- */
- public void testNoVulkan() {
- assertNoFile("/system/lib/libvulkan.so");
- assertNoFile("/system/lib64/libvulkan.so");
- assertNoFile("/vendor/lib/libvulkan.so");
- assertNoFile("/vendor/lib64/libvulkan.so");
- }
-}
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/VectorDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/VectorDrawableTest.java
index 8944d63..e5903d0 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/VectorDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/VectorDrawableTest.java
@@ -103,6 +103,18 @@
R.drawable.vector_icon_arcto_golden,
};
+ private static final int[] GRADIENT_ICON_RES_IDS = new int[] {
+ R.drawable.vector_icon_gradient_1,
+ R.drawable.vector_icon_gradient_2,
+ R.drawable.vector_icon_gradient_3,
+ };
+
+ private static final int[] GRADIENT_GOLDEN_IMAGES = new int[] {
+ R.drawable.vector_icon_gradient_1_golden,
+ R.drawable.vector_icon_gradient_2_golden,
+ R.drawable.vector_icon_gradient_3_golden,
+ };
+
private static final int[] STATEFUL_RES_IDS = new int[] {
R.drawable.vector_icon_state_list
};
@@ -151,6 +163,10 @@
verifyVectorDrawables(ICON_RES_IDS, GOLDEN_IMAGES, null);
}
+ public void testVectorDrawableGradient() throws XmlPullParserException, IOException {
+ verifyVectorDrawables(GRADIENT_ICON_RES_IDS, GRADIENT_GOLDEN_IMAGES, null);
+ }
+
public void testColorStateList() throws XmlPullParserException, IOException {
for (int i = 0; i < STATEFUL_STATE_SETS.length; i++) {
verifyVectorDrawables(
@@ -175,7 +191,7 @@
throw new XmlPullParserException("No start tag found");
}
- mVectorDrawable.inflate(mResources, parser, attrs);
+ mVectorDrawable.inflate(mResources, parser, attrs, mContext.getTheme());
if (stateSet != null) {
mVectorDrawable.setState(stateSet);
diff --git a/tests/tests/media/res/raw/image_exif_byte_order_ii.jpg b/tests/tests/media/res/raw/image_exif_byte_order_ii.jpg
new file mode 100644
index 0000000..477cd3a
--- /dev/null
+++ b/tests/tests/media/res/raw/image_exif_byte_order_ii.jpg
Binary files differ
diff --git a/tests/tests/media/res/raw/image_exif_byte_order_mm.jpg b/tests/tests/media/res/raw/image_exif_byte_order_mm.jpg
new file mode 100644
index 0000000..78ac703
--- /dev/null
+++ b/tests/tests/media/res/raw/image_exif_byte_order_mm.jpg
Binary files differ
diff --git a/tests/tests/media/res/raw/lg_g4_iso_800.dng b/tests/tests/media/res/raw/lg_g4_iso_800.dng
new file mode 100644
index 0000000..5fcc720
--- /dev/null
+++ b/tests/tests/media/res/raw/lg_g4_iso_800.dng
Binary files differ
diff --git a/tests/tests/media/res/raw/okgoogle123_good.wav b/tests/tests/media/res/raw/okgoogle123_good.wav
new file mode 100644
index 0000000..ffd5a7f
--- /dev/null
+++ b/tests/tests/media/res/raw/okgoogle123_good.wav
Binary files differ
diff --git a/tests/tests/media/res/values/exifinterface.xml b/tests/tests/media/res/values/exifinterface.xml
new file mode 100644
index 0000000..8fc6adc
--- /dev/null
+++ b/tests/tests/media/res/values/exifinterface.xml
@@ -0,0 +1,108 @@
+<?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.
+-->
+
+<resources>
+ <array name="exifbyteorderii_jpg">
+ <item>true</item>
+ <item>512</item>
+ <item>288</item>
+ <item>false</item>
+ <item>0.0</item>
+ <item>0.0</item>
+ <item>0.0</item>
+ <item>SAMSUNG</item>
+ <item>SM-N900S</item>
+ <item>2.200</item>
+ <item>2016:01:29 18:32:27</item>
+ <item>0.033</item>
+ <item>0</item>
+ <item>413/100</item>
+ <item />
+ <item />
+ <item />
+ <item />
+ <item />
+ <item />
+ <item />
+ <item />
+ <item />
+ <item>480</item>
+ <item>640</item>
+ <item>50</item>
+ <item>6</item>
+ <item>0</item>
+ </array>
+ <array name="exifbyteordermm_jpg">
+ <item>false</item>
+ <item>0</item>
+ <item>0</item>
+ <item>true</item>
+ <item>0.0</item>
+ <item>0.0</item>
+ <item>0.0</item>
+ <item>LGE</item>
+ <item>Nexus 5</item>
+ <item>2.400</item>
+ <item>2016:01:29 15:44:58</item>
+ <item>0.017</item>
+ <item>0</item>
+ <item>3970/1000</item>
+ <item>0/1000</item>
+ <item>0</item>
+ <item>1970:01:01</item>
+ <item>0/1,0/1,0/10000</item>
+ <item>N</item>
+ <item>0/1,0/1,0/10000</item>
+ <item>E</item>
+ <item>GPS</item>
+ <item>00:00:00</item>
+ <item>176</item>
+ <item>144</item>
+ <item>146</item>
+ <item>0</item>
+ <item>0</item>
+ </array>
+ <array name="lg_g4_iso_800_dng">
+ <item>false</item>
+ <item>0</item>
+ <item>0</item>
+ <item>true</item>
+ <item>53.834507</item>
+ <item>10.69585</item>
+ <item>0.0</item>
+ <item>LGE</item>
+ <item>LG-H815</item>
+ <item>1.800</item>
+ <item>2015:11:12 16:46:18</item>
+ <item>0.0040</item>
+ <item>0.0</item>
+ <item>442/100</item>
+ <item>0/1</item>
+ <item>0</item>
+ <item>1970:01:17</item>
+ <item>53/1,50/1,423/100</item>
+ <item>N</item>
+ <item>10/1,41/1,4506/100</item>
+ <item>E</item>
+ <item />
+ <item>18:08:10</item>
+ <item>337</item>
+ <item>600</item>
+ <item>800</item>
+ <item>1</item>
+ <item />
+ </array>
+</resources>
diff --git a/tests/tests/media/src/android/media/cts/EncoderTest.java b/tests/tests/media/src/android/media/cts/EncoderTest.java
index c8cea22..50ea672 100644
--- a/tests/tests/media/src/android/media/cts/EncoderTest.java
+++ b/tests/tests/media/src/android/media/cts/EncoderTest.java
@@ -23,9 +23,12 @@
import android.media.MediaCodecInfo;
import android.media.MediaCodecList;
import android.media.MediaFormat;
+import android.media.MediaMuxer;
import android.test.AndroidTestCase;
import android.util.Log;
+import java.io.File;
+import java.io.InputStream;
import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
import java.util.LinkedList;
@@ -42,6 +45,20 @@
private static final int kNumInputBytes = 512 * 1024;
private static final long kTimeoutUs = 100;
+ // not all combinations are valid
+ private static final int MODE_SILENT = 0;
+ private static final int MODE_RANDOM = 1;
+ private static final int MODE_RESOURCE = 2;
+ private static final int MODE_QUIET = 4;
+ private static final int MODE_SILENTLEAD = 8;
+
+ /*
+ * Set this to true to save the encoding results to /data/local/tmp
+ * You will need to make /data/local/tmp writeable, run "setenforce 0",
+ * and remove files left from a previous run.
+ */
+ private static boolean sSaveResults = false;
+
@Override
public void setContext(Context context) {
super.setContext(context);
@@ -172,13 +189,26 @@
private int queueInputBuffer(
MediaCodec codec, ByteBuffer[] inputBuffers, int index,
- boolean random, boolean zeroLead) {
+ InputStream istream, int mode) {
ByteBuffer buffer = inputBuffers[index];
buffer.rewind();
int size = buffer.limit();
- if (random) {
- if (zeroLead) {
+ if ((mode & MODE_RESOURCE) != 0 && istream != null) {
+ while (buffer.hasRemaining()) {
+ try {
+ int next = istream.read();
+ if (next < 0) {
+ break;
+ }
+ buffer.put((byte) next);
+ } catch (Exception ex) {
+ Log.i(TAG, "caught exception writing: " + ex);
+ break;
+ }
+ }
+ } else if ((mode & MODE_RANDOM) != 0) {
+ if ((mode & MODE_SILENTLEAD) != 0) {
buffer.putInt(0);
buffer.putInt(0);
buffer.putInt(0);
@@ -186,6 +216,7 @@
}
while (true) {
try {
+ int next = mRandom.nextInt();
buffer.putInt(mRandom.nextInt());
} catch (BufferOverflowException ex) {
break;
@@ -196,6 +227,15 @@
buffer.put(zeroes);
}
+ if ((mode & MODE_QUIET) != 0) {
+ int n = buffer.limit();
+ for (int i = 0; i < n; i += 2) {
+ short s = buffer.getShort(i);
+ s /= 8;
+ buffer.putShort(i, s);
+ }
+ }
+
codec.queueInputBuffer(index, 0 /* offset */, size, 0 /* timeUs */, 0);
return size;
@@ -224,17 +264,47 @@
private void testEncoder(String componentName, MediaFormat format) {
Log.i(TAG, "testEncoder " + componentName + "/" + format);
// test with all zeroes/silence
- testEncoder(componentName, format, false, 0, false);
+ testEncoder(componentName, format, 0, -1, MODE_SILENT);
+
+ // test with pcm input file
+ testEncoder(componentName, format, 0, R.raw.okgoogle123_good, MODE_RESOURCE);
+ testEncoder(componentName, format, 0, R.raw.okgoogle123_good, MODE_RESOURCE | MODE_QUIET);
// test with random data, with and without a few leading zeroes
for (int i = 0; i < mBadSeeds.length; i++) {
- testEncoder(componentName, format, true, mBadSeeds[i], false);
- testEncoder(componentName, format, true, mBadSeeds[i], true);
+ testEncoder(componentName, format, mBadSeeds[i], -1, MODE_RANDOM);
+ testEncoder(componentName, format, mBadSeeds[i], -1, MODE_RANDOM | MODE_SILENTLEAD);
}
}
- private void testEncoder(String componentName, MediaFormat format, boolean random,
- long startSeed, boolean zeroLead) {
+ private void testEncoder(String componentName, MediaFormat format,
+ long startSeed, int resid, int mode) {
+
+ int sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);
+ int channelCount = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
+ int inBitrate = sampleRate * channelCount * 16; // bit/sec
+ int outBitrate = format.getInteger(MediaFormat.KEY_BIT_RATE);
+
+ MediaMuxer muxer = null;
+ int muxidx = -1;
+ if (sSaveResults) {
+ try {
+ String outFile = "/data/local/tmp/transcoded-" + componentName + "-" + outBitrate +
+ "-" + mode + "-" + startSeed + ".mp4";
+ new File("outFile").delete();
+ muxer = new MediaMuxer(outFile, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
+ muxidx = muxer.addTrack(format);
+ muxer.start();
+ } catch (Exception e) {
+ Log.i(TAG, "couldn't create muxer: " + e);
+ }
+ }
+
+ InputStream istream = null;
+ if ((mode & MODE_RESOURCE) != 0) {
+ istream = mContext.getResources().openRawResource(resid);
+ }
+
mRandom.setSeed(startSeed);
MediaCodec codec;
try {
@@ -283,7 +353,7 @@
doneSubmittingInput = true;
} else {
int size = queueInputBuffer(
- codec, codecInputBuffers, index, random, zeroLead);
+ codec, codecInputBuffers, index, istream, mode);
numBytesSubmitted += size;
@@ -302,6 +372,10 @@
} else if (index == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
codecOutputBuffers = codec.getOutputBuffers();
} else {
+ if (muxer != null) {
+ muxer.writeSampleData(muxidx, codec.getOutputBuffer(index), info);
+ }
+
dequeueOutputBuffer(codec, codecOutputBuffers, index, info);
numBytesDequeued += info.size;
@@ -324,11 +398,6 @@
+ "dequeued " + numBytesDequeued + " bytes.");
}
- int sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);
- int channelCount = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
- int inBitrate = sampleRate * channelCount * 16; // bit/sec
- int outBitrate = format.getInteger(MediaFormat.KEY_BIT_RATE);
-
float desiredRatio = (float)outBitrate / (float)inBitrate;
float actualRatio = (float)numBytesDequeued / (float)numBytesSubmitted;
@@ -339,6 +408,11 @@
codec.release();
codec = null;
+ if (muxer != null) {
+ muxer.stop();
+ muxer.release();
+ muxer = null;
+ }
}
}
diff --git a/tests/tests/media/src/android/media/cts/ExifInterfaceTest.java b/tests/tests/media/src/android/media/cts/ExifInterfaceTest.java
new file mode 100644
index 0000000..a51dd3d
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/ExifInterfaceTest.java
@@ -0,0 +1,333 @@
+/*
+ * 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.media.cts;
+
+import android.content.res.TypedArray;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.media.ExifInterface;
+import android.os.Environment;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.lang.reflect.Type;
+
+public class ExifInterfaceTest extends AndroidTestCase {
+ private static final String TAG = ExifInterface.class.getSimpleName();
+ private static final boolean VERBOSE = false; // lots of logging
+
+ private static final double DIFFERENCE_TOLERANCE = .0001;
+ private static final int BUFFER_SIZE = 32768;
+
+ // List of files.
+ private static final String EXIF_BYTE_ORDER_II_JPEG = "ExifByteOrderII.jpg";
+ private static final String EXIF_BYTE_ORDER_MM_JPEG = "ExifByteOrderMM.jpg";
+ private static final String LG_G4_ISO_800_DNG = "lg_g4_iso_800.dng";
+ private static final int[] IMAGE_RESOURCES = new int[] {
+ R.raw.image_exif_byte_order_ii, R.raw.image_exif_byte_order_mm, R.raw.lg_g4_iso_800 };
+ private static final String[] IMAGE_FILENAMES = new String[] {
+ EXIF_BYTE_ORDER_II_JPEG, EXIF_BYTE_ORDER_MM_JPEG, LG_G4_ISO_800_DNG };
+
+ private static final String[] EXIF_TAGS = {
+ ExifInterface.TAG_MAKE,
+ ExifInterface.TAG_MODEL,
+ ExifInterface.TAG_APERTURE,
+ ExifInterface.TAG_DATETIME,
+ ExifInterface.TAG_EXPOSURE_TIME,
+ ExifInterface.TAG_FLASH,
+ ExifInterface.TAG_FOCAL_LENGTH,
+ ExifInterface.TAG_GPS_ALTITUDE,
+ ExifInterface.TAG_GPS_ALTITUDE_REF,
+ ExifInterface.TAG_GPS_DATESTAMP,
+ ExifInterface.TAG_GPS_LATITUDE,
+ ExifInterface.TAG_GPS_LATITUDE_REF,
+ ExifInterface.TAG_GPS_LONGITUDE,
+ ExifInterface.TAG_GPS_LONGITUDE_REF,
+ ExifInterface.TAG_GPS_PROCESSING_METHOD,
+ ExifInterface.TAG_GPS_TIMESTAMP,
+ ExifInterface.TAG_IMAGE_LENGTH,
+ ExifInterface.TAG_IMAGE_WIDTH,
+ ExifInterface.TAG_ISO,
+ ExifInterface.TAG_ORIENTATION,
+ ExifInterface.TAG_WHITE_BALANCE
+ };
+
+ private static class ExpectedValue {
+ // Thumbnail information.
+ public final boolean hasThumbnail;
+ public final int thumbnailWidth;
+ public final int thumbnailHeight;
+
+ // GPS information.
+ public final boolean hasLatLong;
+ public final float latitude;
+ public final float longitude;
+ public final float altitude;
+
+ // Values.
+ public final String make;
+ public final String model;
+ public final float aperture;
+ public final String datetime;
+ public final float exposureTime;
+ public final float flash;
+ public final String focalLength;
+ public final String gpsAltitude;
+ public final String gpsAltitudeRef;
+ public final String gpsDatestamp;
+ public final String gpsLatitude;
+ public final String gpsLatitudeRef;
+ public final String gpsLongitude;
+ public final String gpsLongitudeRef;
+ public final String gpsProcessingMethod;
+ public final String gpsTimestamp;
+ public final String imageLength;
+ public final String imageWidth;
+ public final String iso;
+ public final String whiteBalance;
+ public final String orientation;
+
+ private static String getString(TypedArray typedArray, int index) {
+ String stringValue = typedArray.getString(index);
+ if (stringValue == null || stringValue.equals("")) {
+ return null;
+ }
+ return stringValue.trim();
+ }
+
+ public ExpectedValue(TypedArray typedArray) {
+ // Reads thumbnail information.
+ hasThumbnail = typedArray.getBoolean(0, false);
+ thumbnailWidth = typedArray.getInt(1, 0);
+ thumbnailHeight = typedArray.getInt(2, 0);
+
+ // Reads GPS information.
+ hasLatLong = typedArray.getBoolean(3, false);
+ latitude = typedArray.getFloat(4, 0f);
+ longitude = typedArray.getFloat(5, 0f);
+ altitude = typedArray.getFloat(6, 0f);
+
+ // Read values.
+ make = getString(typedArray, 7);
+ model = getString(typedArray, 8);
+ aperture = typedArray.getFloat(9, 0f);
+ datetime = getString(typedArray, 10);
+ exposureTime = typedArray.getFloat(11, 0f);
+ flash = typedArray.getFloat(12, 0f);
+ focalLength = getString(typedArray, 13);
+ gpsAltitude = getString(typedArray, 14);
+ gpsAltitudeRef = getString(typedArray, 15);
+ gpsDatestamp = getString(typedArray, 16);
+ gpsLatitude = getString(typedArray, 17);
+ gpsLatitudeRef = getString(typedArray, 18);
+ gpsLongitude = getString(typedArray, 19);
+ gpsLongitudeRef = getString(typedArray, 20);
+ gpsProcessingMethod = getString(typedArray, 21);
+ gpsTimestamp = getString(typedArray, 22);
+ imageLength = getString(typedArray, 23);
+ imageWidth = getString(typedArray, 24);
+ iso = getString(typedArray, 25);
+ orientation = getString(typedArray, 26);
+ whiteBalance = getString(typedArray, 27);
+
+ typedArray.recycle();
+ }
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ byte[] buffer = new byte[BUFFER_SIZE];
+
+ for (int i = 0; i < IMAGE_RESOURCES.length; ++i) {
+ String outputPath = new File(Environment.getExternalStorageDirectory(),
+ IMAGE_FILENAMES[i]).getAbsolutePath();
+ try (InputStream inputStream = getContext().getResources().openRawResource(
+ IMAGE_RESOURCES[i])) {
+ try (FileOutputStream outputStream = new FileOutputStream(outputPath)) {
+ int amount;
+ while ((amount = inputStream.read(buffer)) > 0) {
+ outputStream.write(buffer, 0, amount);
+ }
+ }
+ }
+ }
+ super.setUp();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ for (int i = 0; i < IMAGE_RESOURCES.length; ++i) {
+ String imageFilePath = new File(Environment.getExternalStorageDirectory(),
+ IMAGE_FILENAMES[i]).getAbsolutePath();
+ File imageFile = new File(imageFilePath);
+ if (imageFile.exists()) {
+ imageFile.delete();
+ }
+ }
+
+ super.tearDown();
+ }
+
+ private void printExifTagsAndValues(String fileName, ExifInterface exifInterface) {
+ // Prints thumbnail information.
+ if (exifInterface.hasThumbnail()) {
+ byte[] thumbnailBytes = exifInterface.getThumbnail();
+ if (thumbnailBytes != null) {
+ Log.v(TAG, fileName + " Thumbnail size = " + thumbnailBytes.length);
+ Bitmap bitmap = BitmapFactory.decodeByteArray(
+ thumbnailBytes, 0, thumbnailBytes.length);
+ if (bitmap == null) {
+ Log.e(TAG, fileName + " Corrupted thumbnail!");
+ } else {
+ Log.v(TAG, fileName + " Thumbnail size: " + bitmap.getWidth() + ", "
+ + bitmap.getHeight());
+ }
+ } else {
+ Log.e(TAG, fileName + " Corrupted image (no thumbnail)");
+ }
+ } else {
+ if (exifInterface.getThumbnail() != null) {
+ Log.e(TAG, fileName + " Corrupted image (a thumbnail exists)");
+ } else {
+ Log.v(TAG, fileName + " No thumbnail");
+ }
+ }
+
+ // Prints GPS information.
+ Log.v(TAG, fileName + " Altitude = " + exifInterface.getAltitude(.0));
+
+ float[] latLong = new float[2];
+ if (exifInterface.getLatLong(latLong)) {
+ Log.v(TAG, fileName + " Latitude = " + latLong[0]);
+ Log.v(TAG, fileName + " Longitude = " + latLong[1]);
+ } else {
+ Log.v(TAG, fileName + "No latlong data");
+ }
+
+ // Prints values.
+ for (String tagKey : EXIF_TAGS) {
+ String tagValue = exifInterface.getAttribute(tagKey);
+ Log.v(TAG, fileName + "Key{" + tagKey + "} = '" + tagValue + "'");
+ }
+ }
+
+ private void compareFloatTag(ExifInterface exifInterface, String tag, float expectedValue) {
+ String stringValue = exifInterface.getAttribute(tag);
+ float floatValue = 0f;
+
+ if (stringValue != null) {
+ floatValue = Float.parseFloat(stringValue);
+ }
+
+ assertEquals(expectedValue, floatValue, DIFFERENCE_TOLERANCE);
+ }
+
+ private void compareStringTag(ExifInterface exifInterface, String tag, String expectedValue) {
+ String stringValue = exifInterface.getAttribute(tag);
+ if (stringValue != null) {
+ stringValue = stringValue.trim();
+ }
+
+ assertEquals(expectedValue, stringValue);
+ }
+
+ private void compareWithExpectedValue(ExifInterface exifInterface,
+ ExpectedValue expectedValue) {
+ // Checks a thumbnail image.
+ assertEquals(expectedValue.hasThumbnail, exifInterface.hasThumbnail());
+ if (expectedValue.hasThumbnail) {
+ byte[] thumbnailBytes = exifInterface.getThumbnail();
+ assertNotNull(thumbnailBytes);
+ Bitmap thumbnailBitmap =
+ BitmapFactory.decodeByteArray(thumbnailBytes, 0, thumbnailBytes.length);
+ assertNotNull(thumbnailBitmap);
+ assertEquals(expectedValue.thumbnailWidth, thumbnailBitmap.getWidth());
+ assertEquals(expectedValue.thumbnailHeight, thumbnailBitmap.getHeight());
+ } else {
+ assertNull(exifInterface.getThumbnail());
+ }
+
+ // Checks GPS information.
+ float[] latLong = new float[2];
+ assertEquals(expectedValue.hasLatLong, exifInterface.getLatLong(latLong));
+ if (expectedValue.hasLatLong) {
+ assertEquals(expectedValue.latitude, latLong[0], DIFFERENCE_TOLERANCE);
+ assertEquals(expectedValue.longitude, latLong[1], DIFFERENCE_TOLERANCE);
+ }
+ assertEquals(expectedValue.altitude, exifInterface.getAltitude(.0), DIFFERENCE_TOLERANCE);
+
+ // Checks values.
+ compareStringTag(exifInterface, ExifInterface.TAG_MAKE, expectedValue.make);
+ compareStringTag(exifInterface, ExifInterface.TAG_MODEL, expectedValue.model);
+ compareFloatTag(exifInterface, ExifInterface.TAG_APERTURE, expectedValue.aperture);
+ compareStringTag(exifInterface, ExifInterface.TAG_DATETIME, expectedValue.datetime);
+ compareFloatTag(exifInterface, ExifInterface.TAG_EXPOSURE_TIME, expectedValue.exposureTime);
+ compareFloatTag(exifInterface, ExifInterface.TAG_FLASH, expectedValue.flash);
+ compareStringTag(exifInterface, ExifInterface.TAG_FOCAL_LENGTH, expectedValue.focalLength);
+ compareStringTag(exifInterface, ExifInterface.TAG_GPS_ALTITUDE, expectedValue.gpsAltitude);
+ compareStringTag(exifInterface, ExifInterface.TAG_GPS_ALTITUDE_REF,
+ expectedValue.gpsAltitudeRef);
+ compareStringTag(exifInterface, ExifInterface.TAG_GPS_DATESTAMP,
+ expectedValue.gpsDatestamp);
+ compareStringTag(exifInterface, ExifInterface.TAG_GPS_LATITUDE, expectedValue.gpsLatitude);
+ compareStringTag(exifInterface, ExifInterface.TAG_GPS_LATITUDE_REF,
+ expectedValue.gpsLatitudeRef);
+ compareStringTag(exifInterface, ExifInterface.TAG_GPS_LONGITUDE,
+ expectedValue.gpsLongitude);
+ compareStringTag(exifInterface, ExifInterface.TAG_GPS_LONGITUDE_REF,
+ expectedValue.gpsLongitudeRef);
+ compareStringTag(exifInterface, ExifInterface.TAG_GPS_PROCESSING_METHOD,
+ expectedValue.gpsProcessingMethod);
+ compareStringTag(exifInterface, ExifInterface.TAG_GPS_TIMESTAMP,
+ expectedValue.gpsTimestamp);
+ compareStringTag(exifInterface, ExifInterface.TAG_IMAGE_LENGTH, expectedValue.imageLength);
+ compareStringTag(exifInterface, ExifInterface.TAG_IMAGE_WIDTH, expectedValue.imageWidth);
+ compareStringTag(exifInterface, ExifInterface.TAG_ISO, expectedValue.iso);
+ compareStringTag(exifInterface, ExifInterface.TAG_ORIENTATION, expectedValue.orientation);
+ compareStringTag(exifInterface, ExifInterface.TAG_WHITE_BALANCE,
+ expectedValue.whiteBalance);
+ }
+
+ private void testExifInterface(String fileName, int typedArrayResourceId) throws IOException {
+ ExifInterface exifInterface = new ExifInterface(new File(Environment
+ .getExternalStorageDirectory(), fileName).getAbsolutePath());
+
+ assertNotNull(exifInterface);
+ if (VERBOSE) {
+ printExifTagsAndValues(fileName, exifInterface);
+ }
+
+ compareWithExpectedValue(exifInterface, new ExpectedValue(
+ getContext().getResources().obtainTypedArray(typedArrayResourceId)));
+ }
+
+ public void testReadExifDataFromExifByteOrderIIJpeg() throws Throwable {
+ testExifInterface(EXIF_BYTE_ORDER_II_JPEG, R.array.exifbyteorderii_jpg);
+ }
+
+ public void testReadExifDataFromExifByteOrderMMJpeg() throws Throwable {
+ testExifInterface(EXIF_BYTE_ORDER_MM_JPEG, R.array.exifbyteordermm_jpg);
+ }
+
+ public void testReadExifDataFromLgG4Iso800Dng() throws Throwable {
+ testExifInterface(LG_G4_ISO_800_DNG, R.array.lg_g4_iso_800_dng);
+ }
+}
diff --git a/tests/tests/net/src/android/net/wifi/cts/ConcurrencyTest.java b/tests/tests/net/src/android/net/wifi/cts/ConcurrencyTest.java
index 343c1e6..a066ba8 100644
--- a/tests/tests/net/src/android/net/wifi/cts/ConcurrencyTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/ConcurrencyTest.java
@@ -20,12 +20,20 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.net.ConnectivityManager;
+import android.net.ConnectivityManager.NetworkCallback;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkRequest;
import android.net.wifi.WifiManager;
import android.net.wifi.p2p.WifiP2pManager;
import static android.net.wifi.p2p.WifiP2pManager.WIFI_P2P_STATE_DISABLED;
import static android.net.wifi.p2p.WifiP2pManager.WIFI_P2P_STATE_ENABLED;
import android.test.AndroidTestCase;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
public class ConcurrencyTest extends AndroidTestCase {
private class MySync {
int expectedWifiState;
@@ -94,10 +102,7 @@
}
mContext.unregisterReceiver(mReceiver);
- if (!mWifiManager.isWifiEnabled()) {
- assertTrue(mWifiManager.setWifiEnabled(true));
- Thread.sleep(DURATION);
- }
+ enableWifi();
super.tearDown();
}
@@ -114,6 +119,33 @@
}
}
+ /*
+ * Enables Wifi and block until connection is established.
+ */
+ private void enableWifi() throws InterruptedException {
+ if (!mWifiManager.isWifiEnabled()) {
+ assertTrue(mWifiManager.setWifiEnabled(true));
+ }
+
+ ConnectivityManager cm =
+ (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
+ NetworkRequest request =
+ new NetworkRequest.Builder().addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+ .build();
+ final CountDownLatch latch = new CountDownLatch(1);
+ NetworkCallback networkCallback = new NetworkCallback() {
+ @Override
+ public void onAvailable(Network network) {
+ latch.countDown();
+ }
+ };
+ cm.registerNetworkCallback(request, networkCallback);
+ latch.await(DURATION, TimeUnit.MILLISECONDS);
+
+ cm.unregisterNetworkCallback(networkCallback);
+ }
+
public void testConcurrency() {
// Cannot support p2p alone
if (!WifiFeature.isWifiSupported(getContext())) {
diff --git a/tests/tests/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java b/tests/tests/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java
index 2cc5951..f3eb4e9 100644
--- a/tests/tests/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java
@@ -25,6 +25,10 @@
import android.net.wifi.WifiManager;
import android.test.AndroidTestCase;
+import java.io.ByteArrayInputStream;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+
public class WifiEnterpriseConfigTest extends AndroidTestCase {
private WifiManager mWifiManager;
@@ -39,6 +43,396 @@
private static final String ANON_IDENTITY = "anonidentity";
private static final int ENABLE_DELAY = 10000;
+ /*
+ * The keys and certificates below are generated with:
+ *
+ * openssl req -new -x509 -days 3650 -extensions v3_ca -keyout cakey.pem -out cacert.pem
+ * openssl ecparam -name prime256v1 -out ecparam.pem
+ * openssl req -newkey ec:ecparam.pem -keyout userkey.pem -nodes -days 3650 -out userkey.req
+ * mkdir -p demoCA/newcerts
+ * touch demoCA/index.txt
+ * echo "01" > demoCA/serial
+ * openssl ca -out usercert.pem -in userkey.req -cert cacert.pem -keyfile cakey.pem -days 3650
+ */
+
+ /**
+ * Generated from above and converted with:
+ *
+ * openssl x509 -outform d -in cacert.pem | xxd -i | sed 's/0x/(byte) 0x/g'
+ */
+
+ private static final byte[] FAKE_EC_1 = {
+ (byte) 0x30, (byte) 0x82, (byte) 0x04, (byte) 0x2f, (byte) 0x30, (byte) 0x82,
+ (byte) 0x03, (byte) 0x17, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01,
+ (byte) 0x02, (byte) 0x02, (byte) 0x09, (byte) 0x00, (byte) 0xa7, (byte) 0xe4,
+ (byte) 0x70, (byte) 0x50, (byte) 0x9b, (byte) 0xd2, (byte) 0x68, (byte) 0x68,
+ (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86,
+ (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
+ (byte) 0x0b, (byte) 0x05, (byte) 0x00, (byte) 0x30, (byte) 0x81, (byte) 0xad,
+ (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03,
+ (byte) 0x55, (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x41,
+ (byte) 0x55, (byte) 0x31, (byte) 0x13, (byte) 0x30, (byte) 0x11, (byte) 0x06,
+ (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x0a,
+ (byte) 0x53, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53,
+ (byte) 0x74, (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x31, (byte) 0x12,
+ (byte) 0x30, (byte) 0x10, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
+ (byte) 0x07, (byte) 0x0c, (byte) 0x09, (byte) 0x53, (byte) 0x6f, (byte) 0x6d,
+ (byte) 0x65, (byte) 0x2d, (byte) 0x43, (byte) 0x69, (byte) 0x74, (byte) 0x79,
+ (byte) 0x31, (byte) 0x15, (byte) 0x30, (byte) 0x13, (byte) 0x06, (byte) 0x03,
+ (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x0c, (byte) 0x0c, (byte) 0x53,
+ (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x43, (byte) 0x6f,
+ (byte) 0x6d, (byte) 0x70, (byte) 0x61, (byte) 0x6e, (byte) 0x79, (byte) 0x31,
+ (byte) 0x10, (byte) 0x30, (byte) 0x0e, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+ (byte) 0x04, (byte) 0x0b, (byte) 0x0c, (byte) 0x07, (byte) 0x53, (byte) 0x65,
+ (byte) 0x63, (byte) 0x74, (byte) 0x69, (byte) 0x6f, (byte) 0x6e, (byte) 0x31,
+ (byte) 0x21, (byte) 0x30, (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+ (byte) 0x04, (byte) 0x03, (byte) 0x0c, (byte) 0x18, (byte) 0x57, (byte) 0x69,
+ (byte) 0x66, (byte) 0x69, (byte) 0x45, (byte) 0x6e, (byte) 0x74, (byte) 0x65,
+ (byte) 0x72, (byte) 0x70, (byte) 0x72, (byte) 0x69, (byte) 0x73, (byte) 0x65,
+ (byte) 0x43, (byte) 0x6f, (byte) 0x6e, (byte) 0x66, (byte) 0x69, (byte) 0x67,
+ (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x31, (byte) 0x29,
+ (byte) 0x30, (byte) 0x27, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86,
+ (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x09,
+ (byte) 0x01, (byte) 0x16, (byte) 0x1a, (byte) 0x61, (byte) 0x6e, (byte) 0x2d,
+ (byte) 0x65, (byte) 0x6d, (byte) 0x61, (byte) 0x69, (byte) 0x6c, (byte) 0x2d,
+ (byte) 0x61, (byte) 0x64, (byte) 0x72, (byte) 0x65, (byte) 0x73, (byte) 0x73,
+ (byte) 0x40, (byte) 0x64, (byte) 0x6f, (byte) 0x6d, (byte) 0x61, (byte) 0x69,
+ (byte) 0x6e, (byte) 0x2e, (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x30,
+ (byte) 0x1e, (byte) 0x17, (byte) 0x0d, (byte) 0x31, (byte) 0x36, (byte) 0x30,
+ (byte) 0x31, (byte) 0x31, (byte) 0x35, (byte) 0x31, (byte) 0x31, (byte) 0x31,
+ (byte) 0x38, (byte) 0x35, (byte) 0x31, (byte) 0x5a, (byte) 0x17, (byte) 0x0d,
+ (byte) 0x32, (byte) 0x36, (byte) 0x30, (byte) 0x31, (byte) 0x31, (byte) 0x32,
+ (byte) 0x31, (byte) 0x31, (byte) 0x31, (byte) 0x38, (byte) 0x35, (byte) 0x31,
+ (byte) 0x5a, (byte) 0x30, (byte) 0x81, (byte) 0xad, (byte) 0x31, (byte) 0x0b,
+ (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
+ (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x41, (byte) 0x55, (byte) 0x31,
+ (byte) 0x13, (byte) 0x30, (byte) 0x11, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+ (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x0a, (byte) 0x53, (byte) 0x6f,
+ (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53, (byte) 0x74, (byte) 0x61,
+ (byte) 0x74, (byte) 0x65, (byte) 0x31, (byte) 0x12, (byte) 0x30, (byte) 0x10,
+ (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x07, (byte) 0x0c,
+ (byte) 0x09, (byte) 0x53, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d,
+ (byte) 0x43, (byte) 0x69, (byte) 0x74, (byte) 0x79, (byte) 0x31, (byte) 0x15,
+ (byte) 0x30, (byte) 0x13, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
+ (byte) 0x0a, (byte) 0x0c, (byte) 0x0c, (byte) 0x53, (byte) 0x6f, (byte) 0x6d,
+ (byte) 0x65, (byte) 0x2d, (byte) 0x43, (byte) 0x6f, (byte) 0x6d, (byte) 0x70,
+ (byte) 0x61, (byte) 0x6e, (byte) 0x79, (byte) 0x31, (byte) 0x10, (byte) 0x30,
+ (byte) 0x0e, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0b,
+ (byte) 0x0c, (byte) 0x07, (byte) 0x53, (byte) 0x65, (byte) 0x63, (byte) 0x74,
+ (byte) 0x69, (byte) 0x6f, (byte) 0x6e, (byte) 0x31, (byte) 0x21, (byte) 0x30,
+ (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x03,
+ (byte) 0x0c, (byte) 0x18, (byte) 0x57, (byte) 0x69, (byte) 0x66, (byte) 0x69,
+ (byte) 0x45, (byte) 0x6e, (byte) 0x74, (byte) 0x65, (byte) 0x72, (byte) 0x70,
+ (byte) 0x72, (byte) 0x69, (byte) 0x73, (byte) 0x65, (byte) 0x43, (byte) 0x6f,
+ (byte) 0x6e, (byte) 0x66, (byte) 0x69, (byte) 0x67, (byte) 0x54, (byte) 0x65,
+ (byte) 0x73, (byte) 0x74, (byte) 0x31, (byte) 0x29, (byte) 0x30, (byte) 0x27,
+ (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86,
+ (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x09, (byte) 0x01, (byte) 0x16,
+ (byte) 0x1a, (byte) 0x61, (byte) 0x6e, (byte) 0x2d, (byte) 0x65, (byte) 0x6d,
+ (byte) 0x61, (byte) 0x69, (byte) 0x6c, (byte) 0x2d, (byte) 0x61, (byte) 0x64,
+ (byte) 0x72, (byte) 0x65, (byte) 0x73, (byte) 0x73, (byte) 0x40, (byte) 0x64,
+ (byte) 0x6f, (byte) 0x6d, (byte) 0x61, (byte) 0x69, (byte) 0x6e, (byte) 0x2e,
+ (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x30, (byte) 0x82, (byte) 0x01,
+ (byte) 0x22, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a,
+ (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01,
+ (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x82,
+ (byte) 0x01, (byte) 0x0f, (byte) 0x00, (byte) 0x30, (byte) 0x82, (byte) 0x01,
+ (byte) 0x0a, (byte) 0x02, (byte) 0x82, (byte) 0x01, (byte) 0x01, (byte) 0x00,
+ (byte) 0xb4, (byte) 0x6e, (byte) 0x66, (byte) 0x24, (byte) 0xe7, (byte) 0x5c,
+ (byte) 0xd8, (byte) 0x6f, (byte) 0x08, (byte) 0xd3, (byte) 0x80, (byte) 0xa3,
+ (byte) 0xb9, (byte) 0xaf, (byte) 0x90, (byte) 0xef, (byte) 0x1c, (byte) 0x2a,
+ (byte) 0x5f, (byte) 0x39, (byte) 0x0b, (byte) 0xbd, (byte) 0x75, (byte) 0x0d,
+ (byte) 0x3e, (byte) 0x19, (byte) 0x2e, (byte) 0x47, (byte) 0x1e, (byte) 0x14,
+ (byte) 0xc2, (byte) 0x1a, (byte) 0x59, (byte) 0xcc, (byte) 0x1b, (byte) 0xb6,
+ (byte) 0x9b, (byte) 0x46, (byte) 0x1f, (byte) 0x7f, (byte) 0x71, (byte) 0xdd,
+ (byte) 0x38, (byte) 0xbe, (byte) 0x89, (byte) 0x30, (byte) 0xba, (byte) 0x88,
+ (byte) 0xfb, (byte) 0x3f, (byte) 0x57, (byte) 0x35, (byte) 0xe7, (byte) 0xa7,
+ (byte) 0x2f, (byte) 0x2c, (byte) 0x8d, (byte) 0x7c, (byte) 0xe2, (byte) 0xd8,
+ (byte) 0x0c, (byte) 0x0a, (byte) 0xe6, (byte) 0x62, (byte) 0x46, (byte) 0x8c,
+ (byte) 0xf4, (byte) 0x51, (byte) 0xfc, (byte) 0x6a, (byte) 0x79, (byte) 0xdd,
+ (byte) 0x0a, (byte) 0x41, (byte) 0x23, (byte) 0xd3, (byte) 0xe9, (byte) 0x5e,
+ (byte) 0x91, (byte) 0xcd, (byte) 0xbd, (byte) 0x55, (byte) 0x28, (byte) 0x71,
+ (byte) 0xec, (byte) 0x52, (byte) 0x19, (byte) 0x85, (byte) 0x0c, (byte) 0x1b,
+ (byte) 0xfa, (byte) 0xbf, (byte) 0xfe, (byte) 0xae, (byte) 0x5c, (byte) 0x3b,
+ (byte) 0x99, (byte) 0x42, (byte) 0xd4, (byte) 0xe7, (byte) 0x17, (byte) 0xec,
+ (byte) 0x41, (byte) 0x22, (byte) 0x2c, (byte) 0x1e, (byte) 0x7b, (byte) 0x53,
+ (byte) 0xad, (byte) 0x02, (byte) 0xfd, (byte) 0xf6, (byte) 0x4a, (byte) 0xb1,
+ (byte) 0x6e, (byte) 0x6c, (byte) 0x87, (byte) 0xf5, (byte) 0x7d, (byte) 0x9b,
+ (byte) 0x34, (byte) 0x0e, (byte) 0x3b, (byte) 0x0e, (byte) 0xaa, (byte) 0xc5,
+ (byte) 0xc4, (byte) 0xef, (byte) 0xf2, (byte) 0x5a, (byte) 0xa9, (byte) 0xac,
+ (byte) 0x19, (byte) 0xce, (byte) 0x5f, (byte) 0xc5, (byte) 0xcc, (byte) 0x0d,
+ (byte) 0xee, (byte) 0x7f, (byte) 0x32, (byte) 0xb4, (byte) 0xfe, (byte) 0xc1,
+ (byte) 0xca, (byte) 0x9b, (byte) 0x3f, (byte) 0xad, (byte) 0x2c, (byte) 0x7a,
+ (byte) 0xc5, (byte) 0x8d, (byte) 0x48, (byte) 0xa1, (byte) 0xc9, (byte) 0x74,
+ (byte) 0xfe, (byte) 0x8a, (byte) 0xe3, (byte) 0xb0, (byte) 0x92, (byte) 0xee,
+ (byte) 0x73, (byte) 0x09, (byte) 0x0a, (byte) 0xbc, (byte) 0xc8, (byte) 0x63,
+ (byte) 0xba, (byte) 0x0e, (byte) 0x26, (byte) 0xab, (byte) 0x1e, (byte) 0xff,
+ (byte) 0xbc, (byte) 0x24, (byte) 0x12, (byte) 0x26, (byte) 0x11, (byte) 0xe0,
+ (byte) 0x04, (byte) 0xcb, (byte) 0x96, (byte) 0x7d, (byte) 0x41, (byte) 0xf7,
+ (byte) 0x79, (byte) 0x32, (byte) 0x05, (byte) 0x33, (byte) 0x19, (byte) 0x6e,
+ (byte) 0xb9, (byte) 0x75, (byte) 0xf3, (byte) 0x50, (byte) 0xa4, (byte) 0xc3,
+ (byte) 0x55, (byte) 0x9d, (byte) 0x8f, (byte) 0xb6, (byte) 0xab, (byte) 0x97,
+ (byte) 0xe7, (byte) 0xe2, (byte) 0xe8, (byte) 0x15, (byte) 0xfc, (byte) 0x35,
+ (byte) 0xbd, (byte) 0xce, (byte) 0x17, (byte) 0xbe, (byte) 0xe3, (byte) 0x73,
+ (byte) 0xd4, (byte) 0x88, (byte) 0x39, (byte) 0x27, (byte) 0x7e, (byte) 0x6d,
+ (byte) 0xa2, (byte) 0x27, (byte) 0xfa, (byte) 0x96, (byte) 0xe3, (byte) 0x38,
+ (byte) 0xc0, (byte) 0xa1, (byte) 0x55, (byte) 0xc6, (byte) 0xf3, (byte) 0x20,
+ (byte) 0xea, (byte) 0x50, (byte) 0x8d, (byte) 0x6c, (byte) 0x94, (byte) 0x9a,
+ (byte) 0x43, (byte) 0x74, (byte) 0xc0, (byte) 0xfa, (byte) 0xef, (byte) 0xe0,
+ (byte) 0xb1, (byte) 0x1c, (byte) 0x6d, (byte) 0x5e, (byte) 0x44, (byte) 0x08,
+ (byte) 0xef, (byte) 0xd5, (byte) 0x80, (byte) 0xad, (byte) 0x02, (byte) 0x03,
+ (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0xa3, (byte) 0x50, (byte) 0x30,
+ (byte) 0x4e, (byte) 0x30, (byte) 0x1d, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+ (byte) 0x1d, (byte) 0x0e, (byte) 0x04, (byte) 0x16, (byte) 0x04, (byte) 0x14,
+ (byte) 0xe9, (byte) 0xd0, (byte) 0x9e, (byte) 0x0e, (byte) 0x62, (byte) 0x31,
+ (byte) 0x02, (byte) 0x9a, (byte) 0x33, (byte) 0xd7, (byte) 0x4a, (byte) 0x93,
+ (byte) 0x0d, (byte) 0xf3, (byte) 0xd6, (byte) 0x74, (byte) 0xce, (byte) 0x69,
+ (byte) 0xe1, (byte) 0xef, (byte) 0x30, (byte) 0x1f, (byte) 0x06, (byte) 0x03,
+ (byte) 0x55, (byte) 0x1d, (byte) 0x23, (byte) 0x04, (byte) 0x18, (byte) 0x30,
+ (byte) 0x16, (byte) 0x80, (byte) 0x14, (byte) 0xe9, (byte) 0xd0, (byte) 0x9e,
+ (byte) 0x0e, (byte) 0x62, (byte) 0x31, (byte) 0x02, (byte) 0x9a, (byte) 0x33,
+ (byte) 0xd7, (byte) 0x4a, (byte) 0x93, (byte) 0x0d, (byte) 0xf3, (byte) 0xd6,
+ (byte) 0x74, (byte) 0xce, (byte) 0x69, (byte) 0xe1, (byte) 0xef, (byte) 0x30,
+ (byte) 0x0c, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x13,
+ (byte) 0x04, (byte) 0x05, (byte) 0x30, (byte) 0x03, (byte) 0x01, (byte) 0x01,
+ (byte) 0xff, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a,
+ (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01,
+ (byte) 0x01, (byte) 0x0b, (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x82,
+ (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x52, (byte) 0x70, (byte) 0xb6,
+ (byte) 0x10, (byte) 0x7f, (byte) 0xaa, (byte) 0x86, (byte) 0x8f, (byte) 0x02,
+ (byte) 0xb0, (byte) 0x97, (byte) 0x89, (byte) 0xb9, (byte) 0x04, (byte) 0x1d,
+ (byte) 0x79, (byte) 0xa3, (byte) 0x74, (byte) 0x7c, (byte) 0xdf, (byte) 0xad,
+ (byte) 0x87, (byte) 0xe4, (byte) 0x00, (byte) 0xd3, (byte) 0x3a, (byte) 0x5c,
+ (byte) 0x48, (byte) 0x3b, (byte) 0xfe, (byte) 0x77, (byte) 0xfd, (byte) 0xbe,
+ (byte) 0xce, (byte) 0x5b, (byte) 0xd2, (byte) 0xea, (byte) 0x3e, (byte) 0x7f,
+ (byte) 0xef, (byte) 0x20, (byte) 0x0d, (byte) 0x0b, (byte) 0xc7, (byte) 0xc4,
+ (byte) 0x25, (byte) 0x20, (byte) 0xe1, (byte) 0x8f, (byte) 0xc5, (byte) 0x19,
+ (byte) 0x37, (byte) 0x9c, (byte) 0xa0, (byte) 0x9d, (byte) 0x02, (byte) 0x30,
+ (byte) 0x5f, (byte) 0x49, (byte) 0x4e, (byte) 0x56, (byte) 0xc4, (byte) 0xab,
+ (byte) 0xcb, (byte) 0x5c, (byte) 0xe6, (byte) 0x40, (byte) 0x93, (byte) 0x92,
+ (byte) 0xee, (byte) 0xa1, (byte) 0x69, (byte) 0x7d, (byte) 0x10, (byte) 0x6b,
+ (byte) 0xd4, (byte) 0xf7, (byte) 0xec, (byte) 0xd9, (byte) 0xa5, (byte) 0x29,
+ (byte) 0x63, (byte) 0x29, (byte) 0xd9, (byte) 0x27, (byte) 0x2d, (byte) 0x5e,
+ (byte) 0x34, (byte) 0x37, (byte) 0xa9, (byte) 0xba, (byte) 0x0a, (byte) 0x7b,
+ (byte) 0x99, (byte) 0x1a, (byte) 0x7d, (byte) 0xa7, (byte) 0xa7, (byte) 0xf0,
+ (byte) 0xbf, (byte) 0x40, (byte) 0x29, (byte) 0x5d, (byte) 0x2f, (byte) 0x2e,
+ (byte) 0x0f, (byte) 0x35, (byte) 0x90, (byte) 0xb5, (byte) 0xc3, (byte) 0xfd,
+ (byte) 0x1e, (byte) 0xe2, (byte) 0xb3, (byte) 0xae, (byte) 0xf9, (byte) 0xde,
+ (byte) 0x9d, (byte) 0x76, (byte) 0xe1, (byte) 0x20, (byte) 0xf5, (byte) 0x1c,
+ (byte) 0x30, (byte) 0x42, (byte) 0x80, (byte) 0x2a, (byte) 0x4f, (byte) 0x85,
+ (byte) 0x5c, (byte) 0xb4, (byte) 0x49, (byte) 0x68, (byte) 0x6c, (byte) 0x7c,
+ (byte) 0x2a, (byte) 0xc8, (byte) 0xbc, (byte) 0x15, (byte) 0xed, (byte) 0x88,
+ (byte) 0xfd, (byte) 0x8a, (byte) 0x63, (byte) 0xe0, (byte) 0x93, (byte) 0xfd,
+ (byte) 0x86, (byte) 0xab, (byte) 0xa9, (byte) 0xf6, (byte) 0x63, (byte) 0xa5,
+ (byte) 0x29, (byte) 0xaf, (byte) 0xdc, (byte) 0x8f, (byte) 0xca, (byte) 0xc2,
+ (byte) 0x28, (byte) 0xe7, (byte) 0x26, (byte) 0x89, (byte) 0x75, (byte) 0xf1,
+ (byte) 0x3e, (byte) 0x2e, (byte) 0x86, (byte) 0x11, (byte) 0x8b, (byte) 0xfa,
+ (byte) 0xf5, (byte) 0xb4, (byte) 0xb4, (byte) 0x04, (byte) 0x02, (byte) 0xa3,
+ (byte) 0x85, (byte) 0x81, (byte) 0xad, (byte) 0xb3, (byte) 0xec, (byte) 0x2d,
+ (byte) 0x4b, (byte) 0x40, (byte) 0x59, (byte) 0x61, (byte) 0x0d, (byte) 0x59,
+ (byte) 0x09, (byte) 0x09, (byte) 0xee, (byte) 0xc7, (byte) 0x51, (byte) 0xef,
+ (byte) 0x6f, (byte) 0xd6, (byte) 0x9a, (byte) 0xa5, (byte) 0x45, (byte) 0xa2,
+ (byte) 0x89, (byte) 0xc2, (byte) 0x97, (byte) 0x93, (byte) 0xbc, (byte) 0x5b,
+ (byte) 0x37, (byte) 0x55, (byte) 0x73, (byte) 0x55, (byte) 0x0c, (byte) 0x9c,
+ (byte) 0xcb, (byte) 0x10, (byte) 0xec, (byte) 0x76, (byte) 0xfe, (byte) 0xa7,
+ (byte) 0x70, (byte) 0x4e, (byte) 0x9a, (byte) 0xa2, (byte) 0xf9, (byte) 0x40,
+ (byte) 0xdd, (byte) 0x96, (byte) 0x7d, (byte) 0x67, (byte) 0x5c, (byte) 0x8e,
+ (byte) 0x43, (byte) 0x1a, (byte) 0x26, (byte) 0xaa, (byte) 0xee, (byte) 0x38,
+ (byte) 0x11, (byte) 0x26, (byte) 0x3d, (byte) 0x69, (byte) 0xc7, (byte) 0x6a,
+ (byte) 0xe7, (byte) 0xbd, (byte) 0x67, (byte) 0x70, (byte) 0x35, (byte) 0xff,
+ (byte) 0x72, (byte) 0x2c, (byte) 0x87, (byte) 0x82, (byte) 0x68, (byte) 0x3f,
+ (byte) 0x8d
+ };
+
+ private static final byte[] FAKE_EC_2 = {
+ (byte) 0x30, (byte) 0x82, (byte) 0x04, (byte) 0x4f, (byte) 0x30, (byte) 0x82,
+ (byte) 0x03, (byte) 0x37, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01,
+ (byte) 0x02, (byte) 0x02, (byte) 0x09, (byte) 0x00, (byte) 0xd9, (byte) 0xc4,
+ (byte) 0xe1, (byte) 0xfc, (byte) 0x3d, (byte) 0x02, (byte) 0x21, (byte) 0x1f,
+ (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86,
+ (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
+ (byte) 0x0b, (byte) 0x05, (byte) 0x00, (byte) 0x30, (byte) 0x81, (byte) 0xbd,
+ (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03,
+ (byte) 0x55, (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x41,
+ (byte) 0x55, (byte) 0x31, (byte) 0x13, (byte) 0x30, (byte) 0x11, (byte) 0x06,
+ (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x0a,
+ (byte) 0x53, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53,
+ (byte) 0x74, (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x31, (byte) 0x12,
+ (byte) 0x30, (byte) 0x10, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
+ (byte) 0x07, (byte) 0x0c, (byte) 0x09, (byte) 0x53, (byte) 0x6f, (byte) 0x6d,
+ (byte) 0x65, (byte) 0x2d, (byte) 0x43, (byte) 0x69, (byte) 0x74, (byte) 0x79,
+ (byte) 0x31, (byte) 0x1b, (byte) 0x30, (byte) 0x19, (byte) 0x06, (byte) 0x03,
+ (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x0c, (byte) 0x12, (byte) 0x53,
+ (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x4f, (byte) 0x74,
+ (byte) 0x68, (byte) 0x65, (byte) 0x72, (byte) 0x2d, (byte) 0x43, (byte) 0x6f,
+ (byte) 0x6d, (byte) 0x70, (byte) 0x61, (byte) 0x6e, (byte) 0x79, (byte) 0x31,
+ (byte) 0x15, (byte) 0x30, (byte) 0x13, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+ (byte) 0x04, (byte) 0x0b, (byte) 0x0c, (byte) 0x0c, (byte) 0x53, (byte) 0x6f,
+ (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53, (byte) 0x65, (byte) 0x63,
+ (byte) 0x74, (byte) 0x69, (byte) 0x6f, (byte) 0x6e, (byte) 0x31, (byte) 0x21,
+ (byte) 0x30, (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
+ (byte) 0x03, (byte) 0x0c, (byte) 0x18, (byte) 0x57, (byte) 0x69, (byte) 0x66,
+ (byte) 0x69, (byte) 0x45, (byte) 0x6e, (byte) 0x74, (byte) 0x65, (byte) 0x72,
+ (byte) 0x70, (byte) 0x72, (byte) 0x69, (byte) 0x73, (byte) 0x65, (byte) 0x43,
+ (byte) 0x6f, (byte) 0x6e, (byte) 0x66, (byte) 0x69, (byte) 0x67, (byte) 0x54,
+ (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x31, (byte) 0x2e, (byte) 0x30,
+ (byte) 0x2c, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48,
+ (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x09, (byte) 0x01,
+ (byte) 0x16, (byte) 0x1f, (byte) 0x61, (byte) 0x6e, (byte) 0x2d, (byte) 0x65,
+ (byte) 0x6d, (byte) 0x61, (byte) 0x69, (byte) 0x6c, (byte) 0x2d, (byte) 0x61,
+ (byte) 0x64, (byte) 0x72, (byte) 0x65, (byte) 0x73, (byte) 0x73, (byte) 0x40,
+ (byte) 0x73, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x64,
+ (byte) 0x6f, (byte) 0x6d, (byte) 0x61, (byte) 0x69, (byte) 0x6e, (byte) 0x2e,
+ (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x30, (byte) 0x1e, (byte) 0x17,
+ (byte) 0x0d, (byte) 0x31, (byte) 0x36, (byte) 0x30, (byte) 0x31, (byte) 0x31,
+ (byte) 0x35, (byte) 0x31, (byte) 0x31, (byte) 0x33, (byte) 0x32, (byte) 0x34,
+ (byte) 0x36, (byte) 0x5a, (byte) 0x17, (byte) 0x0d, (byte) 0x32, (byte) 0x36,
+ (byte) 0x30, (byte) 0x31, (byte) 0x31, (byte) 0x32, (byte) 0x31, (byte) 0x31,
+ (byte) 0x33, (byte) 0x32, (byte) 0x34, (byte) 0x36, (byte) 0x5a, (byte) 0x30,
+ (byte) 0x81, (byte) 0xbd, (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09,
+ (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06, (byte) 0x13,
+ (byte) 0x02, (byte) 0x41, (byte) 0x55, (byte) 0x31, (byte) 0x13, (byte) 0x30,
+ (byte) 0x11, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08,
+ (byte) 0x0c, (byte) 0x0a, (byte) 0x53, (byte) 0x6f, (byte) 0x6d, (byte) 0x65,
+ (byte) 0x2d, (byte) 0x53, (byte) 0x74, (byte) 0x61, (byte) 0x74, (byte) 0x65,
+ (byte) 0x31, (byte) 0x12, (byte) 0x30, (byte) 0x10, (byte) 0x06, (byte) 0x03,
+ (byte) 0x55, (byte) 0x04, (byte) 0x07, (byte) 0x0c, (byte) 0x09, (byte) 0x53,
+ (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x43, (byte) 0x69,
+ (byte) 0x74, (byte) 0x79, (byte) 0x31, (byte) 0x1b, (byte) 0x30, (byte) 0x19,
+ (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x0c,
+ (byte) 0x12, (byte) 0x53, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d,
+ (byte) 0x4f, (byte) 0x74, (byte) 0x68, (byte) 0x65, (byte) 0x72, (byte) 0x2d,
+ (byte) 0x43, (byte) 0x6f, (byte) 0x6d, (byte) 0x70, (byte) 0x61, (byte) 0x6e,
+ (byte) 0x79, (byte) 0x31, (byte) 0x15, (byte) 0x30, (byte) 0x13, (byte) 0x06,
+ (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0b, (byte) 0x0c, (byte) 0x0c,
+ (byte) 0x53, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53,
+ (byte) 0x65, (byte) 0x63, (byte) 0x74, (byte) 0x69, (byte) 0x6f, (byte) 0x6e,
+ (byte) 0x31, (byte) 0x21, (byte) 0x30, (byte) 0x1f, (byte) 0x06, (byte) 0x03,
+ (byte) 0x55, (byte) 0x04, (byte) 0x03, (byte) 0x0c, (byte) 0x18, (byte) 0x57,
+ (byte) 0x69, (byte) 0x66, (byte) 0x69, (byte) 0x45, (byte) 0x6e, (byte) 0x74,
+ (byte) 0x65, (byte) 0x72, (byte) 0x70, (byte) 0x72, (byte) 0x69, (byte) 0x73,
+ (byte) 0x65, (byte) 0x43, (byte) 0x6f, (byte) 0x6e, (byte) 0x66, (byte) 0x69,
+ (byte) 0x67, (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x31,
+ (byte) 0x2e, (byte) 0x30, (byte) 0x2c, (byte) 0x06, (byte) 0x09, (byte) 0x2a,
+ (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01,
+ (byte) 0x09, (byte) 0x01, (byte) 0x16, (byte) 0x1f, (byte) 0x61, (byte) 0x6e,
+ (byte) 0x2d, (byte) 0x65, (byte) 0x6d, (byte) 0x61, (byte) 0x69, (byte) 0x6c,
+ (byte) 0x2d, (byte) 0x61, (byte) 0x64, (byte) 0x72, (byte) 0x65, (byte) 0x73,
+ (byte) 0x73, (byte) 0x40, (byte) 0x73, (byte) 0x6f, (byte) 0x6d, (byte) 0x65,
+ (byte) 0x2d, (byte) 0x64, (byte) 0x6f, (byte) 0x6d, (byte) 0x61, (byte) 0x69,
+ (byte) 0x6e, (byte) 0x2e, (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x30,
+ (byte) 0x82, (byte) 0x01, (byte) 0x22, (byte) 0x30, (byte) 0x0d, (byte) 0x06,
+ (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7,
+ (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00,
+ (byte) 0x03, (byte) 0x82, (byte) 0x01, (byte) 0x0f, (byte) 0x00, (byte) 0x30,
+ (byte) 0x82, (byte) 0x01, (byte) 0x0a, (byte) 0x02, (byte) 0x82, (byte) 0x01,
+ (byte) 0x01, (byte) 0x00, (byte) 0xa9, (byte) 0xa3, (byte) 0x21, (byte) 0xfd,
+ (byte) 0xa6, (byte) 0xc1, (byte) 0x04, (byte) 0x48, (byte) 0xc2, (byte) 0xc8,
+ (byte) 0x44, (byte) 0x50, (byte) 0xc4, (byte) 0x6d, (byte) 0x35, (byte) 0x24,
+ (byte) 0xf0, (byte) 0x6d, (byte) 0x69, (byte) 0xfb, (byte) 0xd1, (byte) 0xfc,
+ (byte) 0xde, (byte) 0xe9, (byte) 0xdb, (byte) 0xca, (byte) 0xee, (byte) 0x24,
+ (byte) 0x3d, (byte) 0x85, (byte) 0x8d, (byte) 0x84, (byte) 0xb4, (byte) 0x73,
+ (byte) 0xd1, (byte) 0x09, (byte) 0x37, (byte) 0x16, (byte) 0x80, (byte) 0x70,
+ (byte) 0x6b, (byte) 0x61, (byte) 0xcc, (byte) 0xf2, (byte) 0x98, (byte) 0xbd,
+ (byte) 0x53, (byte) 0x3a, (byte) 0x68, (byte) 0x60, (byte) 0x02, (byte) 0xba,
+ (byte) 0x0c, (byte) 0x53, (byte) 0x96, (byte) 0xfb, (byte) 0x80, (byte) 0xd1,
+ (byte) 0x5b, (byte) 0xc3, (byte) 0xcb, (byte) 0x7a, (byte) 0x81, (byte) 0x00,
+ (byte) 0x5d, (byte) 0x20, (byte) 0x72, (byte) 0xc0, (byte) 0xe4, (byte) 0x48,
+ (byte) 0x0e, (byte) 0xa2, (byte) 0xcd, (byte) 0xa2, (byte) 0x63, (byte) 0x8c,
+ (byte) 0x05, (byte) 0x7c, (byte) 0x63, (byte) 0x5b, (byte) 0xda, (byte) 0x0e,
+ (byte) 0xa7, (byte) 0x05, (byte) 0x09, (byte) 0x6d, (byte) 0xd5, (byte) 0xe4,
+ (byte) 0x3a, (byte) 0x4e, (byte) 0xa1, (byte) 0xf5, (byte) 0xfd, (byte) 0x47,
+ (byte) 0xee, (byte) 0x7b, (byte) 0xa3, (byte) 0x4c, (byte) 0x8c, (byte) 0xd3,
+ (byte) 0xbb, (byte) 0x58, (byte) 0x0f, (byte) 0x1c, (byte) 0x56, (byte) 0x80,
+ (byte) 0x80, (byte) 0xb5, (byte) 0xf9, (byte) 0x80, (byte) 0xc2, (byte) 0xd1,
+ (byte) 0x1d, (byte) 0x3f, (byte) 0xe8, (byte) 0x2a, (byte) 0x63, (byte) 0x0b,
+ (byte) 0x54, (byte) 0x5f, (byte) 0xd4, (byte) 0xcb, (byte) 0xb7, (byte) 0x94,
+ (byte) 0xe2, (byte) 0x35, (byte) 0x65, (byte) 0x59, (byte) 0xd1, (byte) 0x72,
+ (byte) 0xa4, (byte) 0xb8, (byte) 0xee, (byte) 0x82, (byte) 0x11, (byte) 0x7a,
+ (byte) 0x4c, (byte) 0x26, (byte) 0x66, (byte) 0x9b, (byte) 0x27, (byte) 0x3d,
+ (byte) 0x14, (byte) 0x4b, (byte) 0x4b, (byte) 0xc8, (byte) 0xf0, (byte) 0x6e,
+ (byte) 0x43, (byte) 0x8f, (byte) 0xee, (byte) 0x1f, (byte) 0xeb, (byte) 0x20,
+ (byte) 0xe2, (byte) 0x4c, (byte) 0x79, (byte) 0xbf, (byte) 0x21, (byte) 0x0d,
+ (byte) 0x36, (byte) 0xed, (byte) 0x5f, (byte) 0xcc, (byte) 0x70, (byte) 0x68,
+ (byte) 0x8a, (byte) 0x05, (byte) 0x7c, (byte) 0x2f, (byte) 0x1b, (byte) 0xe9,
+ (byte) 0xec, (byte) 0x83, (byte) 0x6e, (byte) 0x9a, (byte) 0x78, (byte) 0x31,
+ (byte) 0x3d, (byte) 0xf4, (byte) 0xde, (byte) 0x1b, (byte) 0xd2, (byte) 0x76,
+ (byte) 0x32, (byte) 0x6c, (byte) 0x1e, (byte) 0xc9, (byte) 0x90, (byte) 0x7f,
+ (byte) 0xc4, (byte) 0x30, (byte) 0xc0, (byte) 0xae, (byte) 0xab, (byte) 0x70,
+ (byte) 0x08, (byte) 0x78, (byte) 0xbf, (byte) 0x2e, (byte) 0x8b, (byte) 0x07,
+ (byte) 0xab, (byte) 0x8f, (byte) 0x03, (byte) 0xc5, (byte) 0xd3, (byte) 0xeb,
+ (byte) 0x98, (byte) 0x19, (byte) 0x50, (byte) 0x83, (byte) 0x52, (byte) 0xf7,
+ (byte) 0xff, (byte) 0xf5, (byte) 0x89, (byte) 0xe6, (byte) 0xe7, (byte) 0xa7,
+ (byte) 0xcb, (byte) 0xdf, (byte) 0x96, (byte) 0x9d, (byte) 0x14, (byte) 0x04,
+ (byte) 0x5e, (byte) 0x45, (byte) 0x82, (byte) 0xf7, (byte) 0x23, (byte) 0x1a,
+ (byte) 0xb6, (byte) 0x64, (byte) 0x57, (byte) 0xe8, (byte) 0x7e, (byte) 0xa1,
+ (byte) 0xaf, (byte) 0x58, (byte) 0x68, (byte) 0x70, (byte) 0xc5, (byte) 0x0f,
+ (byte) 0x8d, (byte) 0x54, (byte) 0xf3, (byte) 0x49, (byte) 0xa3, (byte) 0x97,
+ (byte) 0x32, (byte) 0xa7, (byte) 0x2a, (byte) 0x79, (byte) 0xbe, (byte) 0xcd,
+ (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0xa3,
+ (byte) 0x50, (byte) 0x30, (byte) 0x4e, (byte) 0x30, (byte) 0x1d, (byte) 0x06,
+ (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x0e, (byte) 0x04, (byte) 0x16,
+ (byte) 0x04, (byte) 0x14, (byte) 0xac, (byte) 0xf3, (byte) 0x73, (byte) 0x9a,
+ (byte) 0x25, (byte) 0x08, (byte) 0x01, (byte) 0x07, (byte) 0x86, (byte) 0x8b,
+ (byte) 0xc4, (byte) 0xed, (byte) 0xb1, (byte) 0x6b, (byte) 0x53, (byte) 0xa3,
+ (byte) 0x21, (byte) 0xb4, (byte) 0xb4, (byte) 0x46, (byte) 0x30, (byte) 0x1f,
+ (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x23, (byte) 0x04,
+ (byte) 0x18, (byte) 0x30, (byte) 0x16, (byte) 0x80, (byte) 0x14, (byte) 0xac,
+ (byte) 0xf3, (byte) 0x73, (byte) 0x9a, (byte) 0x25, (byte) 0x08, (byte) 0x01,
+ (byte) 0x07, (byte) 0x86, (byte) 0x8b, (byte) 0xc4, (byte) 0xed, (byte) 0xb1,
+ (byte) 0x6b, (byte) 0x53, (byte) 0xa3, (byte) 0x21, (byte) 0xb4, (byte) 0xb4,
+ (byte) 0x46, (byte) 0x30, (byte) 0x0c, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+ (byte) 0x1d, (byte) 0x13, (byte) 0x04, (byte) 0x05, (byte) 0x30, (byte) 0x03,
+ (byte) 0x01, (byte) 0x01, (byte) 0xff, (byte) 0x30, (byte) 0x0d, (byte) 0x06,
+ (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7,
+ (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x0b, (byte) 0x05, (byte) 0x00,
+ (byte) 0x03, (byte) 0x82, (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x16,
+ (byte) 0xf6, (byte) 0xd0, (byte) 0xe1, (byte) 0x14, (byte) 0x2d, (byte) 0x52,
+ (byte) 0x47, (byte) 0xa2, (byte) 0x89, (byte) 0xe6, (byte) 0x7f, (byte) 0xac,
+ (byte) 0x88, (byte) 0x04, (byte) 0x15, (byte) 0x21, (byte) 0x00, (byte) 0x72,
+ (byte) 0xf9, (byte) 0xee, (byte) 0xb2, (byte) 0x1b, (byte) 0x8e, (byte) 0x46,
+ (byte) 0x8b, (byte) 0x90, (byte) 0x20, (byte) 0x4f, (byte) 0xa7, (byte) 0xae,
+ (byte) 0x30, (byte) 0xb6, (byte) 0x24, (byte) 0xc5, (byte) 0x54, (byte) 0xaf,
+ (byte) 0x6c, (byte) 0x1e, (byte) 0xd6, (byte) 0x73, (byte) 0x22, (byte) 0x48,
+ (byte) 0x07, (byte) 0xb5, (byte) 0x13, (byte) 0x35, (byte) 0xbb, (byte) 0x9e,
+ (byte) 0xd9, (byte) 0x19, (byte) 0x79, (byte) 0xda, (byte) 0x76, (byte) 0x7f,
+ (byte) 0xf7, (byte) 0x87, (byte) 0xc9, (byte) 0xc3, (byte) 0x0b, (byte) 0x38,
+ (byte) 0x20, (byte) 0x26, (byte) 0xfc, (byte) 0x7f, (byte) 0x32, (byte) 0x2a,
+ (byte) 0xd5, (byte) 0x09, (byte) 0x87, (byte) 0xda, (byte) 0x23, (byte) 0x1f,
+ (byte) 0x71, (byte) 0x83, (byte) 0x00, (byte) 0x17, (byte) 0xf6, (byte) 0xb9,
+ (byte) 0x57, (byte) 0x21, (byte) 0xdf, (byte) 0x29, (byte) 0xcc, (byte) 0xdb,
+ (byte) 0xe9, (byte) 0x2c, (byte) 0xba, (byte) 0x86, (byte) 0x34, (byte) 0x53,
+ (byte) 0x29, (byte) 0x09, (byte) 0xc7, (byte) 0x3c, (byte) 0x8e, (byte) 0xa3,
+ (byte) 0x86, (byte) 0x81, (byte) 0x26, (byte) 0x7b, (byte) 0xa1, (byte) 0xbe,
+ (byte) 0xbc, (byte) 0xc9, (byte) 0x83, (byte) 0xb5, (byte) 0x36, (byte) 0x65,
+ (byte) 0x51, (byte) 0xb4, (byte) 0x41, (byte) 0xf0, (byte) 0x05, (byte) 0x78,
+ (byte) 0x3a, (byte) 0xa6, (byte) 0xad, (byte) 0x4b, (byte) 0x08, (byte) 0xd1,
+ (byte) 0xe4, (byte) 0xf1, (byte) 0x2e, (byte) 0xc7, (byte) 0x23, (byte) 0x6d,
+ (byte) 0xf0, (byte) 0x9d, (byte) 0x60, (byte) 0x6d, (byte) 0xe7, (byte) 0x11,
+ (byte) 0xaf, (byte) 0x41, (byte) 0x68, (byte) 0xee, (byte) 0x06, (byte) 0x76,
+ (byte) 0x82, (byte) 0x48, (byte) 0xee, (byte) 0x41, (byte) 0xc4, (byte) 0xf8,
+ (byte) 0xe1, (byte) 0x83, (byte) 0xbc, (byte) 0xa8, (byte) 0xbd, (byte) 0x9c,
+ (byte) 0x17, (byte) 0x45, (byte) 0xf4, (byte) 0x36, (byte) 0x67, (byte) 0x47,
+ (byte) 0x0e, (byte) 0x32, (byte) 0x13, (byte) 0x6e, (byte) 0xc1, (byte) 0x1e,
+ (byte) 0x08, (byte) 0xef, (byte) 0x10, (byte) 0xdf, (byte) 0x45, (byte) 0xbf,
+ (byte) 0x5a, (byte) 0xc4, (byte) 0x44, (byte) 0x4c, (byte) 0xd0, (byte) 0xd5,
+ (byte) 0x23, (byte) 0xde, (byte) 0xd7, (byte) 0x83, (byte) 0x1e, (byte) 0xb0,
+ (byte) 0x27, (byte) 0x4d, (byte) 0x57, (byte) 0xa3, (byte) 0xe8, (byte) 0x36,
+ (byte) 0x52, (byte) 0x1c, (byte) 0x48, (byte) 0x0a, (byte) 0xc4, (byte) 0xd8,
+ (byte) 0x32, (byte) 0xfc, (byte) 0xd0, (byte) 0x26, (byte) 0x6f, (byte) 0xa4,
+ (byte) 0x61, (byte) 0x2c, (byte) 0x3a, (byte) 0xa9, (byte) 0xfe, (byte) 0xa4,
+ (byte) 0x7a, (byte) 0x58, (byte) 0x54, (byte) 0x58, (byte) 0x96, (byte) 0x2b,
+ (byte) 0x6e, (byte) 0x9c, (byte) 0xc9, (byte) 0x00, (byte) 0xda, (byte) 0xc6,
+ (byte) 0xbb, (byte) 0x97, (byte) 0xc4, (byte) 0x95, (byte) 0x32, (byte) 0x6b,
+ (byte) 0x03, (byte) 0x6f, (byte) 0x33, (byte) 0x59, (byte) 0xd4, (byte) 0xa4,
+ (byte) 0x4a, (byte) 0x29, (byte) 0x29, (byte) 0x9a, (byte) 0xf4, (byte) 0x87,
+ (byte) 0x26, (byte) 0xe6, (byte) 0xee, (byte) 0x5c, (byte) 0x0b, (byte) 0xe9,
+ (byte) 0x98, (byte) 0x5d, (byte) 0xab, (byte) 0x31, (byte) 0xa1, (byte) 0x63,
+ (byte) 0xaa, (byte) 0x1a, (byte) 0xea, (byte) 0x61, (byte) 0x27, (byte) 0x5e,
+ (byte) 0x9e, (byte) 0x34, (byte) 0x73
+ };
+
+
private boolean hasWifi() {
return getContext().getPackageManager().hasSystemFeature(
PackageManager.FEATURE_WIFI);
@@ -57,7 +451,7 @@
}
}
- public void testSettersAndGetters() {
+ public void testSettersAndGetters() throws Exception {
if (!hasWifi()) {
return;
}
@@ -87,7 +481,17 @@
assertTrue(config.getAnonymousIdentity().equals(ANON_IDENTITY));
config.setPassword(PASSWORD);
assertTrue(config.getPassword().equals(PASSWORD));
- config.setCaCertificate(null);
+ CertificateFactory factory = CertificateFactory.getInstance("X.509");
+ X509Certificate cert1 = (X509Certificate) factory.generateCertificate(
+ new ByteArrayInputStream(FAKE_EC_1));
+ X509Certificate cert2 = (X509Certificate) factory.generateCertificate(
+ new ByteArrayInputStream(FAKE_EC_2));
+ config.setCaCertificate(cert1);
+ assertTrue(config.getCaCertificate().getSerialNumber().equals(cert1.getSerialNumber()));
+ config.setCaCertificates(new X509Certificate[]{cert1, cert2});
+ X509Certificate[] certs = config.getCaCertificates();
+ assertTrue(cert1.getSerialNumber().equals(certs[0].getSerialNumber()));
+ assertTrue(cert2.getSerialNumber().equals(certs[1].getSerialNumber()));
config.setClientKeyEntry(null, null);
config.setSubjectMatch(SUBJECT_MATCH);
assertTrue(config.getSubjectMatch().equals(SUBJECT_MATCH));
diff --git a/tests/tests/os/src/android/os/cts/StrictModeTest.java b/tests/tests/os/src/android/os/cts/StrictModeTest.java
index 2407309..a345256 100644
--- a/tests/tests/os/src/android/os/cts/StrictModeTest.java
+++ b/tests/tests/os/src/android/os/cts/StrictModeTest.java
@@ -108,9 +108,9 @@
}
private boolean hasInternetConnection() {
- // TODO: expand this to include devices with ethernet
final PackageManager pm = getContext().getPackageManager();
return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
- || pm.hasSystemFeature(PackageManager.FEATURE_WIFI);
+ || pm.hasSystemFeature(PackageManager.FEATURE_WIFI)
+ || pm.hasSystemFeature(PackageManager.FEATURE_ETHERNET);
}
}
diff --git a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
index d20e550..14d5343 100644
--- a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
@@ -541,6 +541,7 @@
"/data/misc/bluetooth",
"/data/misc/dhcp",
"/data/misc/lockscreen",
+ "/data/misc/sensor",
"/data/misc/webwidgets",
"/data/misc/webwidgets/chess",
"/data/misc/widgets",
diff --git a/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java b/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
index fb3ef64..d1a102f 100644
--- a/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
+++ b/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
@@ -124,7 +124,7 @@
List<PermissionInfo> permissions = new ArrayList<>();
try (
InputStream in = getContext().getResources()
- .openRawResource(com.android.cts.permission2.R.raw.android_manifest)
+ .openRawResource(android.permission2.cts.R.raw.android_manifest)
) {
XmlPullParser parser = Xml.newPullParser();
parser.setInput(in, null);
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStoreIntentsTest.java b/tests/tests/provider/src/android/provider/cts/MediaStoreIntentsTest.java
index a94e7f4..529b176 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStoreIntentsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStoreIntentsTest.java
@@ -71,7 +71,10 @@
final String[] schemes = new String[] {
"file", "http", "https", "content" };
final String[] mimes = new String[] {
- "image/bmp", "image/jpeg", "image/png", "image/gif", "image/webp" };
+ "image/bmp", "image/jpeg", "image/png", "image/gif", "image/webp",
+ "image/x-adobe-dng", "image/x-canon-cr2", "image/x-nikon-nef", "image/x-nikon-nrw",
+ "image/x-sony-arw", "image/x-panasonic-rw2", "image/x-olympus-orf",
+ "image/x-fuji-raf", "image/x-pentax-pef", "image/x-samsung-srw" };
for (String scheme : schemes) {
for (String mime : mimes) {
diff --git a/tests/tests/security/src/android/security/cts/EncryptionTest.java b/tests/tests/security/src/android/security/cts/EncryptionTest.java
index bd9a458..b2e3991 100644
--- a/tests/tests/security/src/android/security/cts/EncryptionTest.java
+++ b/tests/tests/security/src/android/security/cts/EncryptionTest.java
@@ -76,8 +76,9 @@
public void testConfig() throws Exception {
if (cpuHasAes()) {
// If CPU has AES CE, it must be enabled in kernel
- assertTrue(crypto + " is missing xts-aes-ce",
- hasKernelCrypto("xts-aes-ce"));
+ assertTrue(crypto + " is missing xts-aes-ce or xts-aes-aesni",
+ hasKernelCrypto("xts-aes-ce") ||
+ hasKernelCrypto("xts-aes-aesni"));
} else if (cpuHasNeon()) {
// Otherwise, if CPU has NEON, it must be enabled
assertTrue(crypto + " is missing xts-aes-neon (or xts-aes-neonbs)",
diff --git a/tests/tests/tv/src/android/media/tv/cts/TvInputServiceTest.java b/tests/tests/tv/src/android/media/tv/cts/TvInputServiceTest.java
index 2a3a713..4afb851 100644
--- a/tests/tests/tv/src/android/media/tv/cts/TvInputServiceTest.java
+++ b/tests/tests/tv/src/android/media/tv/cts/TvInputServiceTest.java
@@ -25,9 +25,11 @@
import android.media.tv.TvContract;
import android.media.tv.TvInputInfo;
import android.media.tv.TvInputManager;
+import android.media.tv.TvRecordingClient;
import android.media.tv.TvTrackInfo;
import android.media.tv.TvView;
import android.media.tv.cts.TvInputServiceTest.CountingTvInputService.CountingSession;
+import android.media.tv.cts.TvInputServiceTest.CountingTvInputService.CountingRecordingSession;
import android.net.Uri;
import android.os.SystemClock;
import android.test.ActivityInstrumentationTestCase2;
@@ -57,6 +59,7 @@
.setVideoWidth(1920).setVideoHeight(1080).setLanguage("und").build();
private TvView mTvView;
+ private TvRecordingClient mTvRecordingClient;
private Activity mActivity;
private Instrumentation mInstrumentation;
private TvInputManager mManager;
@@ -64,6 +67,7 @@
private final StubCallback mCallback = new StubCallback();
private final StubTimeShiftPositionCallback mTimeShiftPositionCallback =
new StubTimeShiftPositionCallback();
+ private final StubRecordingCallback mRecordingCallback = new StubRecordingCallback();
private static class StubCallback extends TvView.TvInputCallback {
private int mChannelRetunedCount;
@@ -166,6 +170,8 @@
mActivity = getActivity();
mInstrumentation = getInstrumentation();
mTvView = (TvView) mActivity.findViewById(R.id.tvview);
+ mTvRecordingClient = new TvRecordingClient(mActivity, "TvInputServiceTest",
+ mRecordingCallback, null);
mManager = (TvInputManager) mActivity.getSystemService(Context.TV_INPUT_SERVICE);
for (TvInputInfo info : mManager.getTvInputList()) {
if (info.getServiceInfo().name.equals(CountingTvInputService.class.getName())) {
@@ -179,7 +185,7 @@
CountingTvInputService.sSession = null;
}
- public void testTvInputService() throws Throwable {
+ public void testTvInputServiceSession() throws Throwable {
if (!Utils.hasTvInputFramework(getActivity())) {
return;
}
@@ -218,7 +224,117 @@
mInstrumentation.waitForIdleSync();
}
+ public void testTvInputServiceRecordingSession() throws Throwable {
+ if (!Utils.hasTvInputFramework(getActivity())) {
+ return;
+ }
+ verifyCommandConnect();
+ }
+
+ public void verifyCommandConnect() {
+ resetCounts();
+ Uri fakeChannelUri = TvContract.buildChannelUri(0);
+ mTvRecordingClient.connect(mStubInfo.getId(), fakeChannelUri);
+ new PollingCheck(TIME_OUT) {
+ @Override
+ protected boolean check() {
+ CountingRecordingSession session = CountingTvInputService.sRecordingSession;
+ return session != null && session.mConnectCount > 0;
+ }
+ }.run();
+ }
+
+ public void verifyCommandDisconnect() {
+ resetCounts();
+ mTvRecordingClient.disconnect();
+ new PollingCheck(TIME_OUT) {
+ @Override
+ protected boolean check() {
+ CountingRecordingSession session = CountingTvInputService.sRecordingSession;
+ return session != null && session.mDisconnectCount > 0;
+ }
+ }.run();
+ }
+
+ public void verifyCommandStartRecording() {
+ resetCounts();
+ mTvRecordingClient.startRecording();
+ new PollingCheck(TIME_OUT) {
+ @Override
+ protected boolean check() {
+ CountingRecordingSession session = CountingTvInputService.sRecordingSession;
+ return session != null && session.mStartRecordingCount> 0;
+ }
+ }.run();
+ }
+
+ public void verifyCommandStopRecording() {
+ resetCounts();
+ mTvRecordingClient.stopRecording();
+ new PollingCheck(TIME_OUT) {
+ @Override
+ protected boolean check() {
+ CountingRecordingSession session = CountingTvInputService.sRecordingSession;
+ return session != null && session.mStopRecordingCount > 0;
+ }
+ }.run();
+ }
+
+ public void verifyCallbackConnected() {
+ resetCounts();
+ CountingRecordingSession session = CountingTvInputService.sRecordingSession;
+ assertNotNull(session);
+ session.notifyConnected();
+ new PollingCheck(TIME_OUT) {
+ @Override
+ protected boolean check() {
+ return mRecordingCallback.mConnectedCount > 0;
+ }
+ }.run();
+ }
+
+ public void verifyCallbackError() {
+ resetCounts();
+ CountingRecordingSession session = CountingTvInputService.sRecordingSession;
+ assertNotNull(session);
+ session.notifyError(TvInputManager.RECORDING_ERROR_UNKNOWN);
+ new PollingCheck(TIME_OUT) {
+ @Override
+ protected boolean check() {
+ return mRecordingCallback.mErrorCount > 0;
+ }
+ }.run();
+ }
+
+ public void verifyCallbackRecordingStarted() {
+ resetCounts();
+ CountingRecordingSession session = CountingTvInputService.sRecordingSession;
+ assertNotNull(session);
+ session.notifyRecordingStarted();
+ new PollingCheck(TIME_OUT) {
+ @Override
+ protected boolean check() {
+ return mRecordingCallback.mRecordingStartedCount > 0;
+ }
+ }.run();
+ }
+
+ public void verifyCallbackRecordingStopped() {
+ resetCounts();
+ CountingRecordingSession session = CountingTvInputService.sRecordingSession;
+ assertNotNull(session);
+ Uri fakeChannelUri = TvContract.buildChannelUri(0);
+ session.notifyRecordingStopped(fakeChannelUri);
+ new PollingCheck(TIME_OUT) {
+ @Override
+ protected boolean check() {
+ return mRecordingCallback.mRecordingStoppedCount > 0;
+ }
+ }.run();
+ }
+
public void verifyCommandTune() {
+ resetCounts();
Uri fakeChannelUri = TvContract.buildChannelUri(0);
mTvView.tune(mStubInfo.getId(), fakeChannelUri);
mInstrumentation.waitForIdleSync();
@@ -596,12 +712,17 @@
if (CountingTvInputService.sSession != null) {
CountingTvInputService.sSession.resetCounts();
}
+ if (CountingTvInputService.sRecordingSession!= null) {
+ CountingTvInputService.sRecordingSession.resetCounts();
+ }
mCallback.resetCounts();
mTimeShiftPositionCallback.resetCounts();
+ mRecordingCallback.resetCounts();
}
public static class CountingTvInputService extends StubTvInputService {
static CountingSession sSession;
+ static CountingRecordingSession sRecordingSession;
@Override
public Session onCreateSession(String inputId) {
@@ -610,6 +731,12 @@
return sSession;
}
+ @Override
+ public RecordingSession onCreateRecordingSession(String inputId) {
+ sRecordingSession = new CountingRecordingSession(this);
+ return sRecordingSession;
+ }
+
public static class CountingSession extends Session {
public volatile int mTuneCount;
public volatile int mSetStreamVolumeCount;
@@ -771,5 +898,84 @@
mOverlayViewSizeChangedCount++;
}
}
+
+ public static class CountingRecordingSession extends RecordingSession {
+ public volatile int mConnectCount;
+ public volatile int mDisconnectCount;
+ public volatile int mStartRecordingCount;
+ public volatile int mStopRecordingCount;
+
+ CountingRecordingSession(Context context) {
+ super(context);
+ }
+
+ public void resetCounts() {
+ mConnectCount = 0;
+ mDisconnectCount = 0;
+ mStartRecordingCount = 0;
+ mStopRecordingCount = 0;
+ }
+
+ @Override
+ public void onConnect(Uri recordedProgramUri) {
+ mConnectCount++;
+ }
+
+ @Override
+ public void onDisconnect() {
+ mDisconnectCount++;
+ }
+
+ @Override
+ public void onStartRecording() {
+ mStartRecordingCount++;
+ }
+
+ @Override
+ public void onStopRecording() {
+ mStopRecordingCount++;
+ }
+ }
+ }
+
+ private static class StubRecordingCallback extends TvRecordingClient.RecordingCallback {
+ private int mConnectedCount;
+ private int mDisconnectedCount;
+ private int mRecordingStartedCount;
+ private int mRecordingStoppedCount;
+ private int mErrorCount;
+
+ @Override
+ public void onConnected() {
+ mConnectedCount++;
+ }
+
+ @Override
+ public void onDisconnected() {
+ mDisconnectedCount++;
+ }
+
+ @Override
+ public void onRecordingStarted() {
+ mRecordingStartedCount++;
+ }
+
+ @Override
+ public void onRecordingStopped(Uri recordedProgramUri) {
+ mRecordingStoppedCount++;
+ }
+
+ @Override
+ public void onError(int error) {
+ mErrorCount++;
+ }
+
+ public void resetCounts() {
+ mConnectedCount = 0;
+ mDisconnectedCount = 0;
+ mRecordingStartedCount = 0;
+ mRecordingStoppedCount = 0;
+ mErrorCount = 0;
+ }
}
}
diff --git a/tests/tests/view/Android.mk b/tests/tests/view/Android.mk
index e57e10e..1a290ac 100644
--- a/tests/tests/view/Android.mk
+++ b/tests/tests/view/Android.mk
@@ -24,12 +24,18 @@
# Tag this module as a cts_v2 test artifact
LOCAL_COMPATIBILITY_SUITE := cts_v2
+LOCAL_MULTILIB := both
+
LOCAL_JAVA_LIBRARIES := android.test.runner
LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner mockito-target
+LOCAL_JNI_SHARED_LIBRARIES := libctsview_jni libnativehelper_compat_libc++
+
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_PACKAGE_NAME := CtsViewTestCases
include $(BUILD_CTS_PACKAGE)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/view/jni/Android.mk b/tests/tests/view/jni/Android.mk
new file mode 100644
index 0000000..ac7b844
--- /dev/null
+++ b/tests/tests/view/jni/Android.mk
@@ -0,0 +1,35 @@
+# 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 := libctsview_jni
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := \
+ CtsViewJniOnLoad.cpp \
+ android_view_cts_ChoreographerNativeTest.cpp
+
+LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
+
+LOCAL_SHARED_LIBRARIES := libandroid libnativehelper_compat_libc++ liblog
+
+LOCAL_CXX_STL := libc++_static
+
+LOCAL_CLANG := true
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/tests/view/jni/CtsViewJniOnLoad.cpp b/tests/tests/view/jni/CtsViewJniOnLoad.cpp
new file mode 100644
index 0000000..2c1e643
--- /dev/null
+++ b/tests/tests/view/jni/CtsViewJniOnLoad.cpp
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ *
+ */
+#include <jni.h>
+
+#include <utils/Log.h>
+#define LOG_TAG "CtsViewJniOnLoad"
+
+extern int register_android_view_cts_ChoreographerNativeTest(JNIEnv* env);
+
+jint JNI_OnLoad(JavaVM *vm, void *) {
+ JNIEnv *env = NULL;
+ if (vm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK) {
+ return JNI_ERR;
+ }
+ if (register_android_view_cts_ChoreographerNativeTest(env)) {
+ return JNI_ERR;
+ }
+ return JNI_VERSION_1_4;
+}
diff --git a/tests/tests/view/jni/android_view_cts_ChoreographerNativeTest.cpp b/tests/tests/view/jni/android_view_cts_ChoreographerNativeTest.cpp
new file mode 100644
index 0000000..45b82d6
--- /dev/null
+++ b/tests/tests/view/jni/android_view_cts_ChoreographerNativeTest.cpp
@@ -0,0 +1,162 @@
+/*
+ * 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.
+ *
+ */
+
+#include <android/choreographer.h>
+
+#include <jni.h>
+#include <sys/time.h>
+#include <time.h>
+
+#include <chrono>
+#include <cstdlib>
+#include <cstring>
+#include <mutex>
+#include <thread>
+
+#define LOG_TAG "ChoreographerNative"
+
+#define ASSERT(condition, format, args...) \
+ if (!(condition)) { \
+ fail(env, format, ## args); \
+ return; \
+ }
+
+
+using namespace std::chrono_literals;
+
+static constexpr std::chrono::nanoseconds NOMINAL_VSYNC_PERIOD{16ms};
+static constexpr std::chrono::nanoseconds DELAY_PERIOD{NOMINAL_VSYNC_PERIOD * 5};
+
+static std::mutex gLock;
+struct Callback {
+ int count{0};
+ std::chrono::nanoseconds frameTime{0};
+};
+
+static void frameCallback(long frameTimeNanos, void* data) {
+ std::lock_guard<std::mutex> _l(gLock);
+ Callback* cb = static_cast<Callback*>(data);
+ cb->count++;
+ cb->frameTime = std::chrono::nanoseconds{frameTimeNanos};
+}
+
+static std::chrono::nanoseconds now() {
+ return std::chrono::steady_clock::now().time_since_epoch();
+}
+
+static void fail(JNIEnv* env, const char* format, ...) {
+ va_list args;
+
+ va_start(args, format);
+ char *msg;
+ int rc = vasprintf(&msg, format, args);
+ va_end(args);
+
+ jclass exClass;
+ const char *className = "java/lang/AssertionError";
+ exClass = env->FindClass(className);
+ env->ThrowNew(exClass, msg);
+ free(msg);
+}
+
+static jlong android_view_cts_ChoreographerNativeTest_getChoreographer(JNIEnv*, jclass) {
+ std::lock_guard<std::mutex> _l{gLock};
+ return reinterpret_cast<jlong>(AChoreographer_getInstance());
+}
+
+static jboolean android_view_cts_ChoreographerNativeTest_prepareChoreographerTests(JNIEnv*, jclass,
+ jlong choreographerPtr) {
+ std::lock_guard<std::mutex> _l{gLock};
+ AChoreographer* choreographer = reinterpret_cast<AChoreographer*>(choreographerPtr);
+ return choreographer != nullptr;
+}
+
+static void android_view_cts_ChoreographerNativeTest_testPostCallbackWithoutDelayEventuallyRunsCallback(
+ JNIEnv* env, jclass, jlong choreographerPtr) {
+ AChoreographer* choreographer = reinterpret_cast<AChoreographer*>(choreographerPtr);
+ Callback* cb1 = new Callback();
+ Callback* cb2 = new Callback();
+ auto start = now();
+
+ AChoreographer_postFrameCallback(choreographer, frameCallback, cb1);
+ AChoreographer_postFrameCallback(choreographer, frameCallback, cb2);
+ std::this_thread::sleep_for(NOMINAL_VSYNC_PERIOD * 3);
+ {
+ std::lock_guard<std::mutex> _l{gLock};
+ ASSERT(cb1->count == 1, "Choreographer failed to invoke callback 1");
+ ASSERT(cb1->frameTime - start < NOMINAL_VSYNC_PERIOD * 3,
+ "Callback 1 has incorect frame time on first invokation");
+ ASSERT(cb2->count == 1, "Choreographer failed to invoke callback 2");
+ ASSERT(cb2->frameTime - start < NOMINAL_VSYNC_PERIOD * 3,
+ "Callback 2 has incorect frame time on first invokation");
+ auto delta = cb2->frameTime - cb1->frameTime;
+ ASSERT(delta == delta.zero() || delta > delta.zero() && delta < NOMINAL_VSYNC_PERIOD * 2,
+ "Callback 1 and 2 have frame times too large of a delta in frame times");
+ }
+
+ AChoreographer_postFrameCallback(choreographer, frameCallback, cb1);
+ start = now();
+ std::this_thread::sleep_for(NOMINAL_VSYNC_PERIOD * 3);
+ {
+ std::lock_guard<std::mutex> _l{gLock};
+ ASSERT(cb1->count == 2, "Choreographer failed to invoke callback 1 a second time");
+ ASSERT(cb1->frameTime - start < NOMINAL_VSYNC_PERIOD * 3,
+ "Callback 1 has incorect frame time on second invokation");
+ ASSERT(cb2->count == 1, "Choreographer invoked callback 2 when not posted");
+ }
+}
+
+static void android_view_cts_ChoreographerNativeTest_testPostCallbackWithDelayEventuallyRunsCallback(
+ JNIEnv* env, jclass, jlong choreographerPtr) {
+ AChoreographer* choreographer = reinterpret_cast<AChoreographer*>(choreographerPtr);
+ Callback* cb1 = new Callback();
+ auto start = now();
+
+ auto delay = std::chrono::duration_cast<std::chrono::milliseconds>(DELAY_PERIOD).count();
+ AChoreographer_postFrameCallbackDelayed(choreographer, frameCallback, cb1, delay);
+ std::this_thread::sleep_for(NOMINAL_VSYNC_PERIOD * 3);
+ {
+ std::lock_guard<std::mutex> _l{gLock};
+ ASSERT(cb1->count == 0,
+ "Choreographer failed to delay callback for a sufficient period of time");
+ }
+ std::this_thread::sleep_for(DELAY_PERIOD);
+ {
+ std::lock_guard<std::mutex> _l{gLock};
+ ASSERT(cb1->count == 1, "Choreographer failed to invoke delayed callback");
+ ASSERT(cb1->frameTime - start < DELAY_PERIOD + NOMINAL_VSYNC_PERIOD * 3,
+ "Frametime on callback is incorrect")
+ }
+}
+
+static JNINativeMethod gMethods[] = {
+ { "nativeGetChoreographer", "()J",
+ (void *) android_view_cts_ChoreographerNativeTest_getChoreographer},
+ { "nativePrepareChoreographerTests", "(J)Z",
+ (void *) android_view_cts_ChoreographerNativeTest_prepareChoreographerTests},
+ { "nativeTestPostCallbackWithoutDelayEventuallyRunsCallbacks", "(J)V",
+ (void *) android_view_cts_ChoreographerNativeTest_testPostCallbackWithoutDelayEventuallyRunsCallback},
+ { "nativeTestPostCallbackWithDelayEventuallyRunsCallbacks", "(J)V",
+ (void *) android_view_cts_ChoreographerNativeTest_testPostCallbackWithDelayEventuallyRunsCallback},
+};
+
+int register_android_view_cts_ChoreographerNativeTest(JNIEnv* env)
+{
+ jclass clazz = env->FindClass("android/view/cts/ChoreographerNativeTest");
+ return env->RegisterNatives(clazz, gMethods,
+ sizeof(gMethods) / sizeof(JNINativeMethod));
+}
diff --git a/tests/tests/view/src/android/view/cts/ChoreographerNativeTest.java b/tests/tests/view/src/android/view/cts/ChoreographerNativeTest.java
new file mode 100644
index 0000000..38f351c
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/ChoreographerNativeTest.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.cts;
+
+import android.test.InstrumentationTestCase;
+import android.view.Choreographer;
+
+public class ChoreographerNativeTest extends InstrumentationTestCase {
+ private long mChoreographerPtr;
+ private Choreographer mChoreographer;
+
+ private static native long nativeGetChoreographer();
+ private static native boolean nativePrepareChoreographerTests(long ptr);
+ private static native void nativeTestPostCallbackWithoutDelayEventuallyRunsCallbacks(long ptr);
+ private static native void nativeTestPostCallbackWithDelayEventuallyRunsCallbacks(long ptr);
+
+ static {
+ System.loadLibrary("ctsview_jni");
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ mChoreographerPtr = nativeGetChoreographer();
+ }
+ });
+ if (!nativePrepareChoreographerTests(mChoreographerPtr)) {
+ fail("Failed to setup choreographer tests");
+ }
+ }
+
+ public void testPostCallbackWithoutDelayEventuallyRunsCallbacks() {
+ nativeTestPostCallbackWithoutDelayEventuallyRunsCallbacks(mChoreographerPtr);
+ }
+
+ public void testPostCallbackWithDelayEventuallyRunsCallbacks() {
+ nativeTestPostCallbackWithDelayEventuallyRunsCallbacks(mChoreographerPtr);
+ }
+}
diff --git a/tests/tests/view/src/android/view/cts/ViewTest.java b/tests/tests/view/src/android/view/cts/ViewTest.java
index 6e8c2a3..c3fe030 100644
--- a/tests/tests/view/src/android/view/cts/ViewTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewTest.java
@@ -1435,6 +1435,8 @@
public void testPerformLongClickXY_WithListener() {
OnLongClickListener listener = mock(OnLongClickListener.class);
+ when(listener.onLongClick(any(View.class))).thenReturn(true);
+
MockViewParent parent = new MockViewParent(mActivity);
MockView view = new MockView(mActivity);
diff --git a/tests/tests/view/src/android/view/cts/WindowTest.java b/tests/tests/view/src/android/view/cts/WindowTest.java
index a897af4..0e67c3e 100644
--- a/tests/tests/view/src/android/view/cts/WindowTest.java
+++ b/tests/tests/view/src/android/view/cts/WindowTest.java
@@ -1046,7 +1046,7 @@
}
@Override
- public void onMultiWindowModeChanged() {
+ public void onMultiWindowChanged() {
}
@Override
diff --git a/tools/cts-tradefed/res/config/cts-preconditions.xml b/tools/cts-tradefed/res/config/cts-preconditions.xml
new file mode 100644
index 0000000..9f0a8c9
--- /dev/null
+++ b/tools/cts-tradefed/res/config/cts-preconditions.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<configuration description="CTS precondition configs">
+
+ <option name="compatibility:plan" value="cts-preconditions" />
+
+ <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher">
+ <option name="target" value="host" />
+ <option name="module-name" value="cts_v2"/>
+ <option name="version-name" value="1.0"/>
+ </target_preparer>
+
+ <target_preparer class="com.android.compatibility.common.tradefed.targetprep.StayAwakePreparer" />
+
+ <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkPreconditionCheck">
+ <option name="apk" value="CtsPreconditions.apk"/>
+ <option name="package" value="com.android.preconditions.cts"/>
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+ <option name="run-command" value="rm -rf /sdcard/device-info-files" />
+ </target_preparer>
+
+ <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DeviceInfoCollector">
+ <option name="apk" value="CtsDeviceInfo.apk"/>
+ <option name="package" value="com.android.compatibility.common.deviceinfo"/>
+ <option name="src-dir" value="/sdcard/device-info-files/"/>
+ <option name="dest-dir" value="device-info-files/"/>
+ </target_preparer>
+
+</configuration>
diff --git a/tools/cts-tradefed/res/config/cts.xml b/tools/cts-tradefed/res/config/cts.xml
index e6a75a0..8e34297 100644
--- a/tools/cts-tradefed/res/config/cts.xml
+++ b/tools/cts-tradefed/res/config/cts.xml
@@ -16,6 +16,7 @@
<configuration description="Runs CTS from a pre-existing CTS installation">
<include name="everything" />
+ <include name="cts-preconditions" />
<option name="compatibility:plan" value="cts" />
@@ -24,17 +25,10 @@
<!-- Exclude sample test cases -->
<option name="compatibility:exclude-filter" value="CtsSampleDeviceTestCases" />
<option name="compatibility:exclude-filter" value="CtsSampleHostTestCases" />
+
<!-- Exclude automotive only test cases for now -->
<option name="compatibility:exclude-filter" value="CtsAutomotiveTestCases" />
- <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher">
- <option name="target" value="host" />
- <option name="module-name" value="cts_v2"/>
- <option name="version-name" value="1.0"/>
- </target_preparer>
-
- <target_preparer class="com.android.compatibility.common.tradefed.targetprep.StayAwakePreparer" />
-
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.PropertyCheck">
<option name="property-name" value="ro.build.type" />
<option name="expected-value" value="user"/> <!-- Device should have user build -->
@@ -47,20 +41,4 @@
<option name="throw-error" value="false"/> <!-- Only print warning if not en-US -->
</target_preparer>
- <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkPreconditionCheck">
- <option name="apk" value="CtsPreconditions.apk"/>
- <option name="package" value="com.android.preconditions.cts"/>
- </target_preparer>
-
- <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
- <option name="run-command" value="rm -rf /sdcard/device-info-files" />
- </target_preparer>
-
- <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DeviceInfoCollector">
- <option name="apk" value="CtsDeviceInfo.apk"/>
- <option name="package" value="com.android.compatibility.common.deviceinfo"/>
- <option name="src-dir" value="/sdcard/device-info-files/"/>
- <option name="dest-dir" value="device-info-files/"/>
- </target_preparer>
-
</configuration>