Merge "CTS tests for accessibility importance API"
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/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/BaseDeviceAdminTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/BaseDeviceAdminTest.java
index 148d8a8..18b922e 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/BaseDeviceAdminTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/BaseDeviceAdminTest.java
@@ -19,6 +19,7 @@
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
+import android.os.UserManager;
import android.test.InstrumentationTestCase;
/**
@@ -37,6 +38,7 @@
PACKAGE_NAME, BasicAdminReceiver.class.getName());
protected DevicePolicyManager mDevicePolicyManager;
+ protected UserManager mUserManager;
protected Context mContext;
@Override
@@ -44,10 +46,12 @@
super.setUp();
mContext = getInstrumentation().getContext();
- mDevicePolicyManager = (DevicePolicyManager)
- mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+ mDevicePolicyManager = mContext.getSystemService(DevicePolicyManager.class);
assertNotNull(mDevicePolicyManager);
+ mUserManager = mContext.getSystemService(UserManager.class);
+ assertNotNull(mUserManager);
+
assertTrue(mDevicePolicyManager.isAdminActive(ADMIN_RECEIVER_COMPONENT));
assertTrue("App is neither device nor profile owner",
mDevicePolicyManager.isProfileOwnerApp(PACKAGE_NAME) ||
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ClearDeviceOwnerTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ClearDeviceOwnerTest.java
index 2fe0569..d70cd70 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ClearDeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ClearDeviceOwnerTest.java
@@ -30,13 +30,12 @@
mDevicePolicyManager = (DevicePolicyManager)
mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
if (mDevicePolicyManager != null) {
- removeActiveAdmin(BaseDeviceAdminTest.ADMIN_RECEIVER_COMPONENT);
if (mDevicePolicyManager.isDeviceOwnerApp(BaseDeviceAdminTest.PACKAGE_NAME)) {
mDevicePolicyManager.clearDeviceOwnerApp(BaseDeviceAdminTest.PACKAGE_NAME);
}
- assertFalse(mDevicePolicyManager.isAdminActive(
- BaseDeviceAdminTest.ADMIN_RECEIVER_COMPONENT));
assertFalse(mDevicePolicyManager.isDeviceOwnerApp(BaseDeviceAdminTest.PACKAGE_NAME));
+
+ Utils.removeActiveAdmin(getContext(), BaseDeviceAdminTest.ADMIN_RECEIVER_COMPONENT);
}
super.tearDown();
@@ -46,13 +45,4 @@
// side test once a test case is finished.
public void testClearDeviceOwner() {
}
-
- private void removeActiveAdmin(ComponentName cn) throws InterruptedException {
- if (mDevicePolicyManager.isAdminActive(cn)) {
- mDevicePolicyManager.removeActiveAdmin(cn);
- for (int i = 0; i < 1000 && mDevicePolicyManager.isAdminActive(cn); i++) {
- Thread.sleep(100);
- }
- }
- }
}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ClearProfileOwnerTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ClearProfileOwnerTest.java
index d41166f..93f5d44 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ClearProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ClearProfileOwnerTest.java
@@ -34,8 +34,9 @@
mDevicePolicyManager.clearProfileOwner(
BaseDeviceAdminTest.ADMIN_RECEIVER_COMPONENT);
}
- removeActiveAdmin(BaseDeviceAdminTest.ADMIN_RECEIVER_COMPONENT);
assertFalse(mDevicePolicyManager.isProfileOwnerApp(BaseDeviceAdminTest.PACKAGE_NAME));
+
+ Utils.removeActiveAdmin(getContext(), BaseDeviceAdminTest.ADMIN_RECEIVER_COMPONENT);
}
super.tearDown();
@@ -45,13 +46,4 @@
// side test once a test case is finished.
public void testClearProfileOwner() {
}
-
- private void removeActiveAdmin(ComponentName cn) throws InterruptedException {
- if (mDevicePolicyManager.isAdminActive(cn)) {
- mDevicePolicyManager.removeActiveAdmin(cn);
- for (int i = 0; i < 1000 && mDevicePolicyManager.isAdminActive(cn); i++) {
- Thread.sleep(100);
- }
- }
- }
}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/Utils.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/Utils.java
new file mode 100644
index 0000000..7390f76
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/Utils.java
@@ -0,0 +1,38 @@
+/*
+ * 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.deviceandprofileowner;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+
+import junit.framework.Assert;
+
+public class Utils {
+ private Utils() {
+ }
+
+ public static void removeActiveAdmin(Context context, ComponentName cn) throws Exception {
+ final DevicePolicyManager dpm = context.getSystemService(DevicePolicyManager.class);
+ if (dpm.isAdminActive(cn)) {
+ dpm.removeActiveAdmin(cn);
+ for (int i = 0; i < 1000 && dpm.isAdminActive(cn); i++) {
+ Thread.sleep(100);
+ }
+ Assert.assertFalse(dpm.isAdminActive(cn));
+ }
+ }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/BaseUserRestrictionsTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/BaseUserRestrictionsTest.java
new file mode 100644
index 0000000..a7d8110
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/BaseUserRestrictionsTest.java
@@ -0,0 +1,219 @@
+/*
+ * 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.deviceandprofileowner.userrestrictions;
+
+import android.os.UserManager;
+
+import com.android.cts.deviceandprofileowner.BaseDeviceAdminTest;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+public abstract class BaseUserRestrictionsTest extends BaseDeviceAdminTest {
+ protected static final String[] ALL_USER_RESTRICTIONS = new String[]{
+ UserManager.DISALLOW_CONFIG_WIFI,
+ UserManager.DISALLOW_MODIFY_ACCOUNTS,
+ UserManager.DISALLOW_INSTALL_APPS,
+ UserManager.DISALLOW_UNINSTALL_APPS,
+ UserManager.DISALLOW_SHARE_LOCATION,
+ UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
+ UserManager.DISALLOW_CONFIG_BLUETOOTH,
+ UserManager.DISALLOW_USB_FILE_TRANSFER,
+ UserManager.DISALLOW_CONFIG_CREDENTIALS,
+ UserManager.DISALLOW_REMOVE_USER,
+ UserManager.DISALLOW_DEBUGGING_FEATURES,
+ UserManager.DISALLOW_CONFIG_VPN,
+ UserManager.DISALLOW_CONFIG_TETHERING,
+ UserManager.DISALLOW_NETWORK_RESET,
+ UserManager.DISALLOW_FACTORY_RESET,
+ UserManager.DISALLOW_ADD_USER,
+ UserManager.ENSURE_VERIFY_APPS,
+ UserManager.DISALLOW_CONFIG_CELL_BROADCASTS,
+ UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS,
+ UserManager.DISALLOW_APPS_CONTROL,
+ UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA,
+ UserManager.DISALLOW_UNMUTE_MICROPHONE,
+ UserManager.DISALLOW_ADJUST_VOLUME,
+ UserManager.DISALLOW_OUTGOING_CALLS,
+ UserManager.DISALLOW_SMS,
+ UserManager.DISALLOW_FUN,
+ UserManager.DISALLOW_CREATE_WINDOWS,
+ UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE,
+ UserManager.DISALLOW_OUTGOING_BEAM,
+ UserManager.DISALLOW_SAFE_BOOT,
+ UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
+ UserManager.DISALLOW_DATA_ROAMING,
+ UserManager.DISALLOW_SET_USER_ICON
+ };
+
+ /**
+ * Restrictions that affect all users when DO sets.
+ */
+ protected static final String[] DO_GLOBAL_RESTRICTIONS = new String[] {
+ UserManager.DISALLOW_USB_FILE_TRANSFER,
+ UserManager.DISALLOW_CONFIG_TETHERING,
+ UserManager.DISALLOW_NETWORK_RESET,
+ UserManager.DISALLOW_FACTORY_RESET,
+ UserManager.DISALLOW_ADD_USER,
+ UserManager.DISALLOW_CONFIG_CELL_BROADCASTS,
+ UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS,
+ UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA,
+ UserManager.DISALLOW_SMS,
+ UserManager.DISALLOW_FUN,
+ UserManager.DISALLOW_SAFE_BOOT,
+ UserManager.DISALLOW_CREATE_WINDOWS,
+ // UserManager.DISALLOW_DATA_ROAMING, // Not set during CTS
+
+ // PO can set them too, but when DO sets them, they're global.
+ UserManager.DISALLOW_ADJUST_VOLUME,
+ UserManager.DISALLOW_UNMUTE_MICROPHONE
+ };
+
+ public static final String[] HIDDEN_AND_PROHIBITED = new String[] {
+ "no_record_audio",
+ "no_wallpaper"
+ };
+
+ protected void assertLayeredRestriction(String restriction, boolean expected) {
+ assertEquals("Restriction " + restriction + ": expected=" + expected,
+ expected, mUserManager.hasUserRestriction(restriction));
+ }
+
+ protected void assertOwnerRestriction(String restriction, boolean expected) {
+ assertEquals("Restriction " + restriction + ": expected=" + expected,
+ expected, mDevicePolicyManager.getUserRestrictions(ADMIN_RECEIVER_COMPONENT)
+ .getBoolean(restriction));
+ }
+
+ protected void assertRestrictions(Set<String> expected) {
+ for (String r : ALL_USER_RESTRICTIONS) {
+ assertLayeredRestriction(r, expected.contains(r));
+ }
+ }
+
+ /**
+ * Test that the given restriction can be set and cleared, then leave it set again.
+ */
+ protected void assertSetClearUserRestriction(String restriction) {
+ final boolean hadRestriction = mUserManager.hasUserRestriction(restriction);
+
+ assertOwnerRestriction(restriction, false);
+
+ // Set. Shouldn't throw.
+ mDevicePolicyManager.addUserRestriction(ADMIN_RECEIVER_COMPONENT, restriction);
+
+ assertOwnerRestriction(restriction, true);
+ assertLayeredRestriction(restriction, true);
+
+ // Then clear.
+ assertClearUserRestriction(restriction);
+
+ assertLayeredRestriction(restriction, hadRestriction);
+
+ // Then set again.
+ mDevicePolicyManager.addUserRestriction(ADMIN_RECEIVER_COMPONENT, restriction);
+ }
+
+ /**
+ * Test that the given restriction can be cleared. (and leave it cleared.)
+ */
+ protected void assertClearUserRestriction(String restriction) {
+ mDevicePolicyManager.clearUserRestriction(ADMIN_RECEIVER_COMPONENT, restriction);
+
+ assertOwnerRestriction(restriction, false);
+ }
+
+ /**
+ * Test that the given restriction *cannot* be set (or clear).
+ */
+ protected void assertCannotSetUserRestriction(String restriction) {
+ final boolean hadRestriction = mUserManager.hasUserRestriction(restriction);
+
+ assertOwnerRestriction(restriction, false);
+
+ // Set should fail.
+ try {
+ mDevicePolicyManager.addUserRestriction(ADMIN_RECEIVER_COMPONENT, restriction);
+ fail("Restriction=" + restriction);
+ } catch (SecurityException e) {
+ assertTrue("Restriction=" + restriction + " Message was: " + e.getMessage(),
+ e.getMessage().contains("cannot set user restriction"));
+ }
+
+ // Shouldn't have changed.
+ assertOwnerRestriction(restriction, false);
+ assertLayeredRestriction(restriction, hadRestriction);
+
+ // Clear should fail too.
+ try {
+ mDevicePolicyManager.clearUserRestriction(ADMIN_RECEIVER_COMPONENT, restriction);
+ fail("Restriction=" + restriction);
+ } catch (SecurityException e) {
+ assertTrue("Restriction=" + restriction + " Message was: " + e.getMessage(),
+ e.getMessage().contains("cannot set user restriction"));
+ }
+
+ // Shouldn't have changed.
+ assertOwnerRestriction(restriction, false);
+ assertLayeredRestriction(restriction, hadRestriction);
+ }
+
+ /** For {@link #testSetAllRestrictions} */
+ protected abstract String[] getAllowedRestrictions();
+
+ /** For {@link #testSetAllRestrictions} */
+ protected abstract String[] getDisallowedRestrictions();
+
+ /**
+ * Set only one restriction, and make sure only that's set, and then clear it.
+ */
+ public void testSetAllRestrictionsIndividually() {
+ for (String r : getAllowedRestrictions()) {
+ // Set it.
+ assertSetClearUserRestriction(r);
+
+ assertRestrictions(new HashSet<>(Arrays.asList(new String[]{r})));
+
+ // Then clear it.
+ assertClearUserRestriction(r);
+ }
+ }
+
+ /**
+ * Make sure all allowed restrictions can be set, and the others can't.
+ */
+ public void testSetAllRestrictions() {
+ for (String r : getAllowedRestrictions()) {
+ assertSetClearUserRestriction(r);
+ }
+ for (String r : getDisallowedRestrictions()) {
+ assertCannotSetUserRestriction(r);
+ }
+ for (String r : HIDDEN_AND_PROHIBITED) {
+ assertCannotSetUserRestriction(r);
+ }
+ }
+
+ /**
+ * Clear all allowed restrictions.
+ */
+ public void testClearAllRestrictions() {
+ for (String r : getAllowedRestrictions()) {
+ assertClearUserRestriction(r);
+ }
+ }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/CheckNoOwnerRestrictionsTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/CheckNoOwnerRestrictionsTest.java
new file mode 100644
index 0000000..14e5f84
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/CheckNoOwnerRestrictionsTest.java
@@ -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.
+ */
+package com.android.cts.deviceandprofileowner.userrestrictions;
+
+import android.os.UserManager;
+import android.test.AndroidTestCase;
+
+/**
+ * Used after after DO/PO are removed to make sure user restrictions set by them are no longer
+ * set.
+ */
+public class CheckNoOwnerRestrictionsTest extends AndroidTestCase {
+ public void testNoOwnerRestrictions() {
+ assertFalse(mContext.getSystemService(UserManager.class).hasUserRestriction(
+ UserManager.DISALLOW_UNMUTE_MICROPHONE));
+ }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/DeviceOwnerUserRestrictionsTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/DeviceOwnerUserRestrictionsTest.java
new file mode 100644
index 0000000..1ff9b6c
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/DeviceOwnerUserRestrictionsTest.java
@@ -0,0 +1,71 @@
+/*
+ * 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.deviceandprofileowner.userrestrictions;
+
+import android.os.UserManager;
+
+public class DeviceOwnerUserRestrictionsTest extends BaseUserRestrictionsTest {
+ public static final String[] ALLOWED = new String[] {
+ // UserManager.DISALLOW_CONFIG_WIFI, // Has unrecoverable side effects.
+ UserManager.DISALLOW_MODIFY_ACCOUNTS,
+ UserManager.DISALLOW_INSTALL_APPS,
+ UserManager.DISALLOW_UNINSTALL_APPS,
+ // UserManager.DISALLOW_SHARE_LOCATION, // Has unrecoverable side effects.
+ // UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, // Has unrecoverable side effects.
+ UserManager.DISALLOW_CONFIG_BLUETOOTH,
+ UserManager.DISALLOW_USB_FILE_TRANSFER,
+ UserManager.DISALLOW_CONFIG_CREDENTIALS,
+ UserManager.DISALLOW_REMOVE_USER,
+ // UserManager.DISALLOW_DEBUGGING_FEATURES, // Need for CTS
+ UserManager.DISALLOW_CONFIG_VPN,
+ UserManager.DISALLOW_CONFIG_TETHERING,
+ UserManager.DISALLOW_NETWORK_RESET,
+ UserManager.DISALLOW_FACTORY_RESET,
+ UserManager.DISALLOW_ADD_USER,
+ // UserManager.ENSURE_VERIFY_APPS, // Has unrecoverable side effects.
+ UserManager.DISALLOW_CONFIG_CELL_BROADCASTS,
+ UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS,
+ UserManager.DISALLOW_APPS_CONTROL,
+ UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA,
+ UserManager.DISALLOW_UNMUTE_MICROPHONE,
+ UserManager.DISALLOW_ADJUST_VOLUME,
+ UserManager.DISALLOW_OUTGOING_CALLS,
+ UserManager.DISALLOW_SMS,
+ UserManager.DISALLOW_FUN,
+ UserManager.DISALLOW_CREATE_WINDOWS,
+ UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE,
+ UserManager.DISALLOW_OUTGOING_BEAM,
+ UserManager.DISALLOW_SAFE_BOOT,
+ UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
+ // UserManager.DISALLOW_DATA_ROAMING, // Has unrecoverable side effects.
+ UserManager.DISALLOW_SET_USER_ICON
+ };
+
+ public static final String[] DISALLOWED = new String[] {
+ // DO can set all public restrictions.
+ };
+
+ @Override
+ protected String[] getAllowedRestrictions() {
+ return ALLOWED;
+ }
+
+ @Override
+ protected String[] getDisallowedRestrictions() {
+ return DISALLOWED;
+ }
+}
+
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/PrimaryProfileOwnerUserRestrictionsTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/PrimaryProfileOwnerUserRestrictionsTest.java
new file mode 100644
index 0000000..57c49cf
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/PrimaryProfileOwnerUserRestrictionsTest.java
@@ -0,0 +1,29 @@
+/*
+ * 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.deviceandprofileowner.userrestrictions;
+
+public class PrimaryProfileOwnerUserRestrictionsTest extends BaseUserRestrictionsTest {
+ @Override
+ protected String[] getAllowedRestrictions() {
+ // PO on user-0 can set DO user restrictions too. (for now?)
+ return DeviceOwnerUserRestrictionsTest.ALLOWED;
+ }
+
+ @Override
+ protected String[] getDisallowedRestrictions() {
+ return DeviceOwnerUserRestrictionsTest.DISALLOWED;
+ }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/SecondaryProfileOwnerUserRestrictionsTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/SecondaryProfileOwnerUserRestrictionsTest.java
new file mode 100644
index 0000000..8cd56bf
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/SecondaryProfileOwnerUserRestrictionsTest.java
@@ -0,0 +1,116 @@
+/*
+ * 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.deviceandprofileowner.userrestrictions;
+
+import android.os.UserManager;
+
+import java.util.Arrays;
+import java.util.HashSet;
+
+public class SecondaryProfileOwnerUserRestrictionsTest extends BaseUserRestrictionsTest {
+ public static final String[] ALLOWED = new String[] {
+ // UserManager.DISALLOW_CONFIG_WIFI, // Has unrecoverable side effects.
+ UserManager.DISALLOW_MODIFY_ACCOUNTS,
+ UserManager.DISALLOW_INSTALL_APPS,
+ UserManager.DISALLOW_UNINSTALL_APPS,
+ // UserManager.DISALLOW_SHARE_LOCATION, // Has unrecoverable side effects.
+ // UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, // Has unrecoverable side effects.
+ UserManager.DISALLOW_CONFIG_BLUETOOTH,
+ UserManager.DISALLOW_CONFIG_CREDENTIALS,
+ UserManager.DISALLOW_REMOVE_USER,
+ // UserManager.DISALLOW_DEBUGGING_FEATURES, // Need for CTS
+ UserManager.DISALLOW_CONFIG_VPN,
+ // UserManager.ENSURE_VERIFY_APPS, // Has unrecoverable side effects.
+ UserManager.DISALLOW_APPS_CONTROL,
+ UserManager.DISALLOW_UNMUTE_MICROPHONE,
+ UserManager.DISALLOW_ADJUST_VOLUME,
+ UserManager.DISALLOW_OUTGOING_CALLS,
+ UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE,
+ UserManager.DISALLOW_OUTGOING_BEAM,
+ UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
+ UserManager.DISALLOW_SET_USER_ICON
+ };
+
+ public static final String[] DISALLOWED = new String[] {
+ UserManager.DISALLOW_USB_FILE_TRANSFER,
+ UserManager.DISALLOW_CONFIG_TETHERING,
+ UserManager.DISALLOW_NETWORK_RESET,
+ UserManager.DISALLOW_FACTORY_RESET,
+ UserManager.DISALLOW_ADD_USER,
+ UserManager.DISALLOW_CONFIG_CELL_BROADCASTS,
+ UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS,
+ UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA,
+ UserManager.DISALLOW_SMS,
+ UserManager.DISALLOW_FUN,
+ UserManager.DISALLOW_SAFE_BOOT,
+ UserManager.DISALLOW_CREATE_WINDOWS,
+ UserManager.DISALLOW_DATA_ROAMING
+ };
+
+ @Override
+ protected String[] getAllowedRestrictions() {
+ return ALLOWED;
+ }
+
+ @Override
+ protected String[] getDisallowedRestrictions() {
+ return DISALLOWED;
+ }
+
+ /**
+ * This is called after DO setting all DO restrictions. Global restrictions should be
+ * visible on other users.
+ */
+ public void testHasGlobalRestrictions() {
+ assertRestrictions(new HashSet<>(Arrays.asList(DO_GLOBAL_RESTRICTIONS)));
+ }
+
+ /**
+ * This is called after DO setting all DO restrictions, and PO setting all PO restrictions.
+ * All global + local restrictions should be visible.
+ */
+ public void testHasBothGlobalAndLocalRestrictions() {
+ final HashSet<String> expected = new HashSet<>();
+
+ // Should see all global ones from DO.
+ expected.addAll(Arrays.asList(DO_GLOBAL_RESTRICTIONS));
+
+ // Should also see all global ones from itself.
+ expected.addAll(Arrays.asList(ALLOWED));
+
+ assertRestrictions(expected);
+ }
+
+ /**
+ * This is called after DO setting all DO restrictions, and PO setting all PO restrictions,
+ * then DO clearing all restrictions. Only PO restrictions should be set.
+ */
+ public void testLocalRestrictionsOnly() {
+ // Now should only see the ones that are set by this PO.
+ assertRestrictions(new HashSet<>(Arrays.asList(ALLOWED)));
+ }
+
+ /**
+ * Only the default restrictions should be set.
+ */
+ public void testDefaultRestrictionsOnly() {
+ final HashSet<String> expected = new HashSet<>(
+ // No restrictions.
+ );
+
+ assertRestrictions(expected);
+ }
+}
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/BaseDevicePolicyTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
index 450fbae..1114888 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
@@ -64,7 +64,13 @@
private String mPackageVerifier;
private HashSet<String> mAvailableFeatures;
+
+ /** Whether DPM is supported. */
protected boolean mHasFeature;
+
+ /** Whether multi-user is supported. */
+ protected boolean mSupportsMultiUser;
+
private ArrayList<Integer> mOriginalUsers;
@Override
@@ -78,6 +84,8 @@
assertNotNull(mCtsBuild); // ensure build has been set before test is run.
mHasFeature = getDevice().getApiLevel() >= 21 /* Build.VERSION_CODES.L */
&& hasDeviceFeature("android.software.device_admin");
+ mSupportsMultiUser = getMaxNumberOfUsersSupported() > 1;
+
// disable the package verifier to avoid the dialog when installing an app
mPackageVerifier = getDevice().executeShellCommand(
"settings get global package_verifier_enable");
@@ -204,8 +212,11 @@
stopUser(userId);
String removeUserCommand = "pm remove-user " + userId;
CLog.logAndDisplay(LogLevel.INFO, "starting command " + removeUserCommand);
+
+ String removeUserOutput = getDevice().executeShellCommand(removeUserCommand);
CLog.logAndDisplay(LogLevel.INFO, "Output for command " + removeUserCommand + ": "
- + getDevice().executeShellCommand(removeUserCommand));
+ + removeUserOutput);
+ assertTrue("Couldn't remove user", removeUserOutput.startsWith("Success:"));
}
protected void removeTestUsers() throws Exception {
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/devicepolicy/src/com/android/cts/devicepolicy/UserRestrictionsTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/UserRestrictionsTest.java
new file mode 100644
index 0000000..beef986
--- /dev/null
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/UserRestrictionsTest.java
@@ -0,0 +1,199 @@
+/*
+ * 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.devicepolicy;
+
+import com.android.tradefed.device.DeviceNotAvailableException;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+public class UserRestrictionsTest extends BaseDevicePolicyTest {
+ private static final String DEVICE_ADMIN_PKG = "com.android.cts.deviceandprofileowner";
+ private static final String DEVICE_ADMIN_APK = "CtsDeviceAndProfileOwnerApp.apk";
+ private static final String ADMIN_RECEIVER_TEST_CLASS
+ = ".BaseDeviceAdminTest$BasicAdminReceiver";
+
+ private boolean mRemoveDeviceOwnerInTearDown;
+ private boolean mRemovePrimaryProfileOwnerInTearDown;
+ private int mDeviceOwnerUserId = USER_SYSTEM;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mRemoveDeviceOwnerInTearDown = false;
+ mRemovePrimaryProfileOwnerInTearDown = false;
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ if (mHasFeature) {
+ if (mRemoveDeviceOwnerInTearDown) {
+ assertTrue("Failed to clear device owner",
+ runTests("ClearDeviceOwnerTest", mDeviceOwnerUserId));
+ }
+ if (mRemovePrimaryProfileOwnerInTearDown) {
+ assertTrue("Failed to clear profile owner",
+ runTests("ClearProfileOwnerTest", mDeviceOwnerUserId));
+ }
+ assertTrue("Some user restrictions are still set",
+ runTests("userrestrictions.CheckNoOwnerRestrictionsTest", mDeviceOwnerUserId));
+
+ // DO/PO might have set DISALLOW_REMOVE_USER, so it needs to be done after removing
+ // them.
+ removeTestUsers();
+ }
+ super.tearDown();
+ }
+
+ private boolean runTests(@Nonnull String className,
+ @Nullable String method, int userId) throws DeviceNotAvailableException {
+ return runDeviceTestsAsUser(DEVICE_ADMIN_PKG, "." + className, method, userId);
+ }
+
+ private boolean runTests(@Nonnull String className, int userId)
+ throws DeviceNotAvailableException {
+ return runTests(className, null, userId);
+ }
+
+ public void testUserRestrictions_deviceOwnerOnly() throws Exception {
+ if (!mHasFeature) {
+ return;
+ }
+ installApp(DEVICE_ADMIN_APK);
+ assertTrue("Failed to set device owner",
+ setDeviceOwner(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS));
+ mRemoveDeviceOwnerInTearDown = true;
+
+ runTests("userrestrictions.DeviceOwnerUserRestrictionsTest",
+ "testSetAllRestrictions", mDeviceOwnerUserId);
+ }
+
+ public void testUserRestrictions_primaryProfileOwnerOnly() throws Exception {
+ if (!mHasFeature) {
+ return;
+ }
+ if (hasUserSplit()) {
+ // Can't set PO on user-0 in this mode.
+ return;
+ }
+
+ installApp(DEVICE_ADMIN_APK);
+ assertTrue("Failed to set profile owner",
+ setProfileOwner(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS,
+ mDeviceOwnerUserId));
+ mRemovePrimaryProfileOwnerInTearDown = true;
+
+ runTests("userrestrictions.PrimaryProfileOwnerUserRestrictionsTest",
+ "testSetAllRestrictions", mDeviceOwnerUserId);
+ }
+
+ public void testUserRestrictions_secondaryProfileOwnerOnly() throws Exception {
+ if (!mHasFeature || !mSupportsMultiUser) {
+ return;
+ }
+ final int secondaryUserId = createUser();
+
+ installAppAsUser(DEVICE_ADMIN_APK, secondaryUserId);
+ assertTrue("Failed to set profile owner",
+ setProfileOwner(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS,
+ secondaryUserId));
+
+ runTests("userrestrictions.SecondaryProfileOwnerUserRestrictionsTest",
+ "testSetAllRestrictions", secondaryUserId);
+ }
+
+ /**
+ * DO + PO combination. Make sure global DO restrictions are visible on secondary users.
+ */
+ public void testUserRestrictions_layering() throws Exception {
+ if (!mHasFeature || !mSupportsMultiUser) {
+ return;
+ }
+ // Set DO
+ installApp(DEVICE_ADMIN_APK);
+ assertTrue("Failed to set device owner",
+ setDeviceOwner(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS));
+ mRemoveDeviceOwnerInTearDown = true;
+
+ // Create another user and set PO.
+ final int secondaryUserId = createUser();
+
+ installAppAsUser(DEVICE_ADMIN_APK, secondaryUserId);
+ assertTrue("Failed to set profile owner",
+ setProfileOwner(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS,
+ secondaryUserId));
+
+ // Let DO set all restrictions.
+ runTests("userrestrictions.DeviceOwnerUserRestrictionsTest",
+ "testSetAllRestrictions", mDeviceOwnerUserId);
+
+ // Make sure the global restrictions are visible to secondary users.
+ runTests("userrestrictions.SecondaryProfileOwnerUserRestrictionsTest",
+ "testHasGlobalRestrictions", secondaryUserId);
+
+ // Then let PO set all restrictions.
+ runTests("userrestrictions.SecondaryProfileOwnerUserRestrictionsTest",
+ "testSetAllRestrictions", secondaryUserId);
+
+ // Make sure both local and global restrictions are visible on secondary users.
+ runTests("userrestrictions.SecondaryProfileOwnerUserRestrictionsTest",
+ "testHasBothGlobalAndLocalRestrictions", secondaryUserId);
+
+ // Let DO clear all restrictions.
+ runTests("userrestrictions.DeviceOwnerUserRestrictionsTest",
+ "testClearAllRestrictions", mDeviceOwnerUserId);
+
+ // Now only PO restrictions should be set on the secondary user.
+ runTests("userrestrictions.SecondaryProfileOwnerUserRestrictionsTest",
+ "testLocalRestrictionsOnly", secondaryUserId);
+ }
+
+ /**
+ * PO on user-0. It can set DO restrictions too, but they shouldn't leak to other users.
+ */
+ public void testUserRestrictions_layering_profileOwnerNoLeaking() throws Exception {
+ if (!mHasFeature || !mSupportsMultiUser) {
+ return;
+ }
+ if (hasUserSplit()) {
+ // Can't set PO on user-0 in this mode.
+ return;
+ }
+ // Set DO on user 0
+ installApp(DEVICE_ADMIN_APK);
+ assertTrue("Failed to set device owner",
+ setProfileOwner(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS,
+ mDeviceOwnerUserId));
+ mRemovePrimaryProfileOwnerInTearDown = true;
+
+ // Create another user and set PO.
+ final int secondaryUserId = createUser();
+
+ installAppAsUser(DEVICE_ADMIN_APK, secondaryUserId);
+ assertTrue("Failed to set profile owner",
+ setProfileOwner(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS,
+ secondaryUserId));
+
+ // Let user-0 PO sets all restrictions.
+ runTests("userrestrictions.PrimaryProfileOwnerUserRestrictionsTest",
+ "testSetAllRestrictions", mDeviceOwnerUserId);
+
+ // Secondary users shouldn't see any of them.
+ runTests("userrestrictions.SecondaryProfileOwnerUserRestrictionsTest",
+ "testDefaultRestrictionsOnly", secondaryUserId);
+ }
+}
\ No newline at end of file
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/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/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/DngCreatorTest.java b/tests/camera/src/android/hardware/camera2/cts/DngCreatorTest.java
index 3826afd..4259882 100644
--- a/tests/camera/src/android/hardware/camera2/cts/DngCreatorTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/DngCreatorTest.java
@@ -261,6 +261,7 @@
}
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);
@@ -270,6 +271,11 @@
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);
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/text/src/android/text/style/cts/LocaleSpanTest.java b/tests/tests/text/src/android/text/style/cts/LocaleSpanTest.java
index 93e6cf9..80aa68e 100644
--- a/tests/tests/text/src/android/text/style/cts/LocaleSpanTest.java
+++ b/tests/tests/text/src/android/text/style/cts/LocaleSpanTest.java
@@ -25,7 +25,7 @@
public class LocaleSpanTest extends TestCase {
- public void testGetLocalesMain(@NonNull final LocaleList locales) {
+ private void checkGetLocales(@NonNull final LocaleList locales) {
final LocaleSpan span = new LocaleSpan(locales);
assertEquals(locales.getPrimary(), span.getLocale());
assertEquals(locales, span.getLocales());
@@ -36,10 +36,10 @@
}
public void testGetLocales() {
- testGetLocalesMain(LocaleList.getEmptyLocaleList());
- testGetLocalesMain(LocaleList.forLanguageTags("en"));
- testGetLocalesMain(LocaleList.forLanguageTags("en-GB,en"));
- testGetLocalesMain(LocaleList.forLanguageTags("de-DE-u-co-phonebk,en-GB,en"));
+ checkGetLocales(LocaleList.getEmptyLocaleList());
+ checkGetLocales(LocaleList.forLanguageTags("en"));
+ checkGetLocales(LocaleList.forLanguageTags("en-GB,en"));
+ checkGetLocales(LocaleList.forLanguageTags("de-DE-u-co-phonebk,en-GB,en"));
}
public void testConstructorWithLocaleList() {
diff --git a/tests/tests/text/src/android/text/style/cts/SuggestionSpanTest.java b/tests/tests/text/src/android/text/style/cts/SuggestionSpanTest.java
index ec51216..ff5167c 100644
--- a/tests/tests/text/src/android/text/style/cts/SuggestionSpanTest.java
+++ b/tests/tests/text/src/android/text/style/cts/SuggestionSpanTest.java
@@ -48,7 +48,7 @@
return original.toString();
}
- public void testGetLocaleObjectMain(final Locale locale) {
+ private void checkGetLocaleObject(final Locale locale) {
final SuggestionSpan span = new SuggestionSpan(locale, new String[0],
SuggestionSpan.FLAG_AUTO_CORRECTION);
// In the context of SuggestionSpan#getLocaleObject(), we do care only about subtags that
@@ -63,16 +63,16 @@
}
public void testGetLocaleObject() {
- testGetLocaleObjectMain(Locale.forLanguageTag("en"));
- testGetLocaleObjectMain(Locale.forLanguageTag("en-GB"));
- testGetLocaleObjectMain(Locale.forLanguageTag("EN-GB"));
- testGetLocaleObjectMain(Locale.forLanguageTag("en-gb"));
- testGetLocaleObjectMain(Locale.forLanguageTag("En-gB"));
- testGetLocaleObjectMain(Locale.forLanguageTag("und"));
- testGetLocaleObjectMain(Locale.forLanguageTag("de-DE-u-co-phonebk"));
- testGetLocaleObjectMain(Locale.forLanguageTag(""));
- testGetLocaleObjectMain(null);
- testGetLocaleObjectMain(new Locale(" an ", " i n v a l i d ", "data"));
+ checkGetLocaleObject(Locale.forLanguageTag("en"));
+ checkGetLocaleObject(Locale.forLanguageTag("en-GB"));
+ checkGetLocaleObject(Locale.forLanguageTag("EN-GB"));
+ checkGetLocaleObject(Locale.forLanguageTag("en-gb"));
+ checkGetLocaleObject(Locale.forLanguageTag("En-gB"));
+ checkGetLocaleObject(Locale.forLanguageTag("und"));
+ checkGetLocaleObject(Locale.forLanguageTag("de-DE-u-co-phonebk"));
+ checkGetLocaleObject(Locale.forLanguageTag(""));
+ checkGetLocaleObject(null);
+ checkGetLocaleObject(new Locale(" an ", " i n v a l i d ", "data"));
}
@NonNull
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