Merge "CTS tests for android.app.job" into lmp-dev
diff --git a/CtsBuild.mk b/CtsBuild.mk
index 12a9047..dbe93c7 100644
--- a/CtsBuild.mk
+++ b/CtsBuild.mk
@@ -47,7 +47,7 @@
endef
define cts-get-native-paths
- $(foreach exe,$(1),$(call intermediates-dir-for,EXECUTABLES,$(exe))/$(exe))
+ $(foreach exe,$(1),$(call intermediates-dir-for,EXECUTABLES,$(exe),,,$(3))/$(exe)$(2))
endef
define cts-get-package-paths
diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
index 8894409..721b9d4 100644
--- a/CtsTestCaseList.mk
+++ b/CtsTestCaseList.mk
@@ -69,6 +69,7 @@
CtsDeviceTaskswitchingControl \
CtsDeviceUi \
CtsIntentReceiverApp \
+ CtsIntentSenderApp \
CtsManagedProfileApp \
CtsMonkeyApp \
CtsMonkeyApp2 \
@@ -178,13 +179,16 @@
CtsSecurityHostTestCases \
CtsUsbTests
-# Native test executables that need to have associated test XMLs.
-cts_native_exes := \
+# List of native tests. For 32 bit targets, assumes that there will be
+# one test executable, and it will end in 32. For 64 bit targets, assumes
+# that there will be two executables, one that ends in 32 for the 32
+# bit executable and one that ends in 64 for the 64 bit executable.
+cts_native_tests := \
NativeMediaTest_SL \
NativeMediaTest_XA \
ifeq ($(HOST_OS)-$(HOST_ARCH),$(filter $(HOST_OS)-$(HOST_ARCH),linux-x86 linux-x86_64))
-cts_native_exes += bionic-unit-tests-cts
+cts_native_tests += bionic-unit-tests-cts
endif
cts_ui_tests := \
@@ -208,17 +212,27 @@
# directory of the final CTS distribution.
CTS_TEST_CASES := $(call cts-get-lib-paths,$(cts_host_libraries)) \
$(call cts-get-package-paths,$(cts_test_packages)) \
- $(call cts-get-native-paths,$(cts_native_exes)) \
$(call cts-get-ui-lib-paths,$(cts_ui_tests)) \
$(call cts-get-ui-lib-paths,$(cts_device_jars)) \
$(call cts-get-ui-lib-paths,$(cts_target_junit_tests)) \
$(call cts-get-executable-paths,$(cts_device_executables))
+# NOTE: If compiling on a 64 bit target, TARGET_2ND_ARCH will be non-empty
+# and will cause the function to expand to the secondary arch object
+# directory. If compiling on a 32 bit target, TARGET_2ND_ARCH will be
+# empty and will cause the function to expand to the primary arch object
+# directory.
+CTS_TEST_CASES += $(call cts-get-native-paths,$(cts_native_tests),32,$(TARGET_2ND_ARCH))
+
+ifeq ($(TARGET_IS_64_BIT),true)
+CTS_TEST_CASES += $(call cts-get-native-paths,$(cts_native_tests),64)
+endif
+
# All the XMLs that will end up under the repository/testcases
# and that need to be created before making the final CTS distribution.
CTS_TEST_XMLS := $(call cts-get-test-xmls,$(cts_host_libraries)) \
$(call cts-get-test-xmls,$(cts_test_packages)) \
- $(call cts-get-test-xmls,$(cts_native_exes)) \
+ $(call cts-get-test-xmls,$(cts_native_tests)) \
$(call cts-get-test-xmls,$(cts_target_junit_tests)) \
$(call cts-get-test-xmls,$(cts_ui_tests)) \
$(call cts-get-deqp-test-xmls,$(cts_deqp_test_apis))
diff --git a/apps/CtsVerifier/res/layout/pa_main.xml b/apps/CtsVerifier/res/layout/pa_main.xml
index b6b8e4b..76cb7d4 100644
--- a/apps/CtsVerifier/res/layout/pa_main.xml
+++ b/apps/CtsVerifier/res/layout/pa_main.xml
@@ -17,11 +17,15 @@
android:layout_width="match_parent"
android:layout_height="match_parent" >
+ <include
+ android:id="@+id/pass_fail_buttons"
+ android:layout_gravity="top"
+ layout="@layout/pass_fail_buttons" />
+
<TextureView
android:id="@+id/texture_view"
android:layout_width="match_parent"
- android:layout_height="match_parent" />
-
- <include layout="@layout/pass_fail_buttons" />
+ android:layout_height="match_parent"
+ android:layout_below="@id/pass_fail_buttons" />
</RelativeLayout>
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index b203326..558a86d 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -482,7 +482,8 @@
<string name="snsr_wait_to_begin">Press \'Next\' to begin.</string>
<string name="snsr_on_complete_return">After completing the task, go back to this test.</string>
<string name="snsr_movement_expected">Movement was expected during the test. Found=%1$b.</string>
- <string name="snsr_sensor_feature_deactivation">Additionally, turn off any other features installed in the device, that register for sensors. Once you are done, you can continue the test.</string>
+ <string name="snsr_sensor_feature_deactivation">Turn off any special features installed in the
+ device that register for sensors. Once you are done, you can begin the test.</string>
<string name="snsr_setting_mode_request">You will be redirected to set \'%1$s\' to: %2$s.</string>
<string name="snsr_setting_mode_set">\'%1$s\' set to: %2$s.</string>
<string name="snsr_setting_mode_not_set">\'%1$s\' not set to: %2$s.</string>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/projection/offscreen/ProjectionOffscreenActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/projection/offscreen/ProjectionOffscreenActivity.java
index f992618..510a03b 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/projection/offscreen/ProjectionOffscreenActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/projection/offscreen/ProjectionOffscreenActivity.java
@@ -26,6 +26,9 @@
import android.graphics.PixelFormat;
import android.media.Image;
import android.media.ImageReader;
+import android.media.Ringtone;
+import android.media.RingtoneManager;
+import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
@@ -68,7 +71,7 @@
protected TestStatus mTestStatus = TestStatus.RUNNING;
private final Runnable sendKeyEventRunnable = new Runnable() {
- @Override
+ @Override
public void run() {
try {
mService.onKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_DOWN));
@@ -79,15 +82,28 @@
}
};
+ private final Runnable playNotificationRunnable = new Runnable() {
+
+ @Override
+ public void run() {
+ Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
+ Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), notification);
+ r.play();
+ }
+ };
+
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
- new Handler(Looper.getMainLooper()).postDelayed(
+ Handler handler = new Handler(Looper.getMainLooper());
+ handler.postDelayed(
sendKeyEventRunnable, DELAYED_RUNNABLE_TIME);
mStatusView.setText("Running test...");
mTimeScreenTurnedOff = SystemClock.uptimeMillis();
+ // Notify user its safe to turn screen back on after 5s + fudge factor
+ handler.postDelayed(playNotificationRunnable, TIME_SCREEN_OFF + 500);
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
if (SystemClock.uptimeMillis() - mTimeScreenTurnedOff < TIME_SCREEN_OFF) {
mStatusView.setText("ERROR: Turned on screen too early");
@@ -121,8 +137,9 @@
filter.addAction(Intent.ACTION_SCREEN_ON);
registerReceiver(mReceiver, filter);
- mStatusView.setText(
- "Please turn off your screen and turn it back on after 5 seconds");
+ mStatusView.setText("Please turn off your screen and turn it back on after " +
+ "5 seconds. A sound will be played when it is safe to turn the " +
+ "screen back on");
}
});
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/helpers/SensorFeaturesDeactivator.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/helpers/SensorFeaturesDeactivator.java
index 65a3a4d..82f8ae9 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/helpers/SensorFeaturesDeactivator.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/helpers/SensorFeaturesDeactivator.java
@@ -32,8 +32,6 @@
*/
public class SensorFeaturesDeactivator {
- private boolean mInitialStateCaptured;
-
private final ISensorTestStateContainer mStateContainer;
private final SensorSettingContainer mAirplaneMode = new AirplaneModeSettingContainer();
@@ -64,10 +62,6 @@
}
public synchronized void requestToRestoreFeatures() throws InterruptedException {
- if (!isInitialStateCaptured()) {
- return;
- }
-
if (Thread.currentThread().isInterrupted()) {
// TODO: in the future, if the thread is interrupted, we might need to serialize the
// intermediate state we acquired so we can restore when we have a chance
@@ -82,21 +76,11 @@
}
private void captureInitialState() {
- if (mInitialStateCaptured) {
- return;
- }
-
mAirplaneMode.captureInitialState();
mScreenBrightnessMode.captureInitialState();
mAutoRotateScreenMode.captureInitialState();
mLocationMode.captureInitialState();
mKeepScreenOnMode.captureInitialState();
-
- mInitialStateCaptured = true;
- }
-
- private boolean isInitialStateCaptured() {
- return mInitialStateCaptured;
}
private class AirplaneModeSettingContainer extends SensorSettingContainer {
@@ -105,13 +89,15 @@
}
@Override
- protected int getSettingMode() {
+ protected int getSettingMode(int defaultValue) {
ContentResolver contentResolver = mStateContainer.getContentResolver();
// Settings.System.AIRPLANE_MODE_ON is deprecated in API 17
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
- return Settings.System.getInt(contentResolver, Settings.System.AIRPLANE_MODE_ON, 0);
+ return Settings.System
+ .getInt(contentResolver, Settings.System.AIRPLANE_MODE_ON, defaultValue);
} else {
- return Settings.Global.getInt(contentResolver, Settings.Global.AIRPLANE_MODE_ON, 0);
+ return Settings.Global
+ .getInt(contentResolver, Settings.Global.AIRPLANE_MODE_ON, defaultValue);
}
}
}
@@ -122,11 +108,11 @@
}
@Override
- public int getSettingMode() {
+ public int getSettingMode(int defaultValue) {
return Settings.System.getInt(
mStateContainer.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS_MODE,
- Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
+ defaultValue);
}
}
@@ -137,11 +123,11 @@
}
@Override
- protected int getSettingMode() {
+ protected int getSettingMode(int defaultValue) {
return Settings.System.getInt(
mStateContainer.getContentResolver(),
Settings.System.ACCELEROMETER_ROTATION,
- 0 /* default */);
+ defaultValue);
}
}
@@ -152,11 +138,11 @@
}
@Override
- protected int getSettingMode() {
+ protected int getSettingMode(int defaultValue) {
return Settings.Global.getInt(
mStateContainer.getContentResolver(),
Settings.Global.STAY_ON_WHILE_PLUGGED_IN,
- 0);
+ defaultValue);
}
}
@@ -166,11 +152,11 @@
}
@Override
- protected int getSettingMode() {
+ protected int getSettingMode(int defaultValue) {
return Settings.Secure.getInt(
mStateContainer.getContentResolver(),
Settings.Secure.LOCATION_MODE,
- Settings.Secure.LOCATION_MODE_OFF);
+ defaultValue);
}
}
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/helpers/SensorSettingContainer.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/helpers/SensorSettingContainer.java
index 82df502..2d44d8d 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/helpers/SensorSettingContainer.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/helpers/SensorSettingContainer.java
@@ -24,12 +24,18 @@
* A helper class for {@link SensorFeaturesDeactivator}. It abstracts the responsibility of handling
* device settings that affect sensors.
*
- * This class is not thread safe. It is meant to be used only by {@link SensorFeaturesDeactivator}.
+ * This class is meant to be used only by {@link SensorFeaturesDeactivator}.
+ * To keep things simple, this class synchronizes access to its internal state on public methods.
+ * This approach is fine, because there is no need for concurrent access.
*/
abstract class SensorSettingContainer {
+ private static final int DEFAULT_SETTING_VALUE = -1;
+
private final String mAction;
private final int mSettingNameResId;
+ private boolean mInitialized;
+ private boolean mSettingAvailable;
private boolean mCapturedModeOn;
public SensorSettingContainer(String action, int settingNameResId) {
@@ -37,13 +43,21 @@
mSettingNameResId = settingNameResId;
}
- public void captureInitialState() {
+ public synchronized void captureInitialState() {
+ if (mInitialized) {
+ return;
+ }
+ mSettingAvailable = getSettingMode(DEFAULT_SETTING_VALUE) != DEFAULT_SETTING_VALUE;
mCapturedModeOn = getCurrentSettingMode();
+ mInitialized = true;
}
public synchronized void requestToSetMode(
ISensorTestStateContainer stateContainer,
- boolean modeOn) throws InterruptedException {
+ boolean modeOn) throws InterruptedException {
+ if (!isSettingAvailable()) {
+ return;
+ }
trySetMode(stateContainer, modeOn);
if (getCurrentSettingMode() != modeOn) {
String message = stateContainer.getString(
@@ -56,6 +70,9 @@
public synchronized void requestToResetMode(ISensorTestStateContainer stateContainer)
throws InterruptedException {
+ if (!isSettingAvailable()) {
+ return;
+ }
trySetMode(stateContainer, mCapturedModeOn);
}
@@ -75,12 +92,20 @@
}
private boolean getCurrentSettingMode() {
- return getSettingMode() != 0;
+ return getSettingMode(DEFAULT_SETTING_VALUE) != 0;
}
private String getSettingName(ISensorTestStateContainer stateContainer) {
return stateContainer.getString(mSettingNameResId);
}
- protected abstract int getSettingMode();
+ private boolean isSettingAvailable() {
+ if (!mInitialized) {
+ throw new IllegalStateException(
+ "Object must be initialized first by invoking #captureInitialState.");
+ }
+ return mSettingAvailable;
+ }
+
+ protected abstract int getSettingMode(int defaultValue);
}
diff --git a/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java
index 83187c7..6720dff 100644
--- a/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java
+++ b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java
@@ -54,6 +54,7 @@
mDevice = UiDevice.getInstance(getInstrumentation());
mActivity = launchActivity(getInstrumentation().getTargetContext().getPackageName(),
MyActivity.class, null);
+ mDevice.waitForIdle();
}
@Override
@@ -78,6 +79,7 @@
mActivity.startActivityForResult(intent, 42);
// Ensure that we see both of our roots
+ mDevice.waitForIdle();
assertTrue("CtsLocal root", new UiObject(new UiSelector().text("CtsLocal")).exists());
assertTrue("CtsCreate root", new UiObject(new UiSelector().text("CtsCreate")).exists());
assertFalse("CtsGetContent", new UiObject(new UiSelector().text("CtsGetContent")).exists());
@@ -86,8 +88,6 @@
mDevice.waitForIdle();
new UiObject(new UiSelector().text("CtsLocal")).click();
- // make sure drawer is expanded?
-
mDevice.waitForIdle();
new UiObject(new UiSelector().text("FILE1")).click();
@@ -148,6 +148,7 @@
mDevice.waitForIdle();
new UiObject(new UiSelector().text("FILE1")).click();
+ mDevice.waitForIdle();
new UiObject(new UiSelector().resourceId("com.android.documentsui:id/container_save")
.childSelector(new UiSelector().resourceId("android:id/button1"))).click();
@@ -237,16 +238,15 @@
intent.setType("*/*");
mActivity.startActivityForResult(intent, 42);
- mDevice.waitForIdle();
-
// Look around, we should be able to see both DocumentsProviders and
// other GET_CONTENT sources.
+ mDevice.waitForIdle();
assertTrue("CtsLocal root", new UiObject(new UiSelector().text("CtsLocal")).exists());
assertTrue("CtsCreate root", new UiObject(new UiSelector().text("CtsCreate")).exists());
assertTrue("CtsGetContent", new UiObject(new UiSelector().text("CtsGetContent")).exists());
- new UiObject(new UiSelector().text("CtsGetContent")).click();
mDevice.waitForIdle();
+ new UiObject(new UiSelector().text("CtsGetContent")).click();
final Result result = mActivity.getResult();
assertEquals("ReSuLt", result.data.getAction());
diff --git a/hostsidetests/devicepolicy/app/IntentReceiver/src/com/android/cts/intent/receiver/IntentReceiverActivity.java b/hostsidetests/devicepolicy/app/IntentReceiver/src/com/android/cts/intent/receiver/IntentReceiverActivity.java
index 17dc3f1..59f0752 100644
--- a/hostsidetests/devicepolicy/app/IntentReceiver/src/com/android/cts/intent/receiver/IntentReceiverActivity.java
+++ b/hostsidetests/devicepolicy/app/IntentReceiver/src/com/android/cts/intent/receiver/IntentReceiverActivity.java
@@ -22,12 +22,11 @@
import android.util.Log;
import java.io.BufferedReader;
+import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
-import java.io.IOException;
import java.io.OutputStreamWriter;
-
/**
* Class to receive intents sent across profile boundaries, and read/write to content uri specified
* in these intents to test cross-profile content uris.
diff --git a/hostsidetests/devicepolicy/app/IntentSender/Android.mk b/hostsidetests/devicepolicy/app/IntentSender/Android.mk
new file mode 100644
index 0000000..e45ec31
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/IntentSender/Android.mk
@@ -0,0 +1,33 @@
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsIntentSenderApp
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/IntentSender/AndroidManifest.xml b/hostsidetests/devicepolicy/app/IntentSender/AndroidManifest.xml
new file mode 100644
index 0000000..070ef40
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/IntentSender/AndroidManifest.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.cts.intent.sender">
+
+ <uses-sdk android:minSdkVersion="19" />
+
+ <permission
+ android:name="com.android.cts.intent.sender.permission.SAMPLE"
+ android:label="Sample Permission" />
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+
+ <activity android:name=".IntentSenderActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ </intent-filter>
+ </activity>
+
+ <provider
+ android:name="android.support.v4.content.FileProvider"
+ android:authorities="com.android.cts.intent.sender.fileprovider"
+ android:grantUriPermissions="true"
+ android:exported="false">
+ <meta-data
+ android:name="android.support.FILE_PROVIDER_PATHS"
+ android:resource="@xml/filepaths" />
+ </provider>
+
+ <provider
+ android:name=".BasicContentProvider"
+ android:authorities="com.android.cts.intent.sender.provider"
+ android:grantUriPermissions="true"
+ android:exported="true"
+ android:permission="com.android.cts.intent.sender.permission.SAMPLE" />
+
+ </application>
+
+ <instrumentation
+ android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.android.cts.intent.sender"
+ android:label="Intent Sender CTS Tests" />
+
+</manifest>
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/res/xml/filepaths.xml b/hostsidetests/devicepolicy/app/IntentSender/res/xml/filepaths.xml
similarity index 100%
rename from hostsidetests/devicepolicy/app/ManagedProfile/res/xml/filepaths.xml
rename to hostsidetests/devicepolicy/app/IntentSender/res/xml/filepaths.xml
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofilecontent/BasicContentProvider.java b/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/BasicContentProvider.java
similarity index 96%
rename from hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofilecontent/BasicContentProvider.java
rename to hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/BasicContentProvider.java
index f91d404..183ab9f 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofilecontent/BasicContentProvider.java
+++ b/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/BasicContentProvider.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.cts.managedprofile.crossprofilecontent;
+package com.android.cts.intent.sender;
import android.content.ContentProvider;
import android.content.ContentValues;
@@ -69,4 +69,3 @@
new File("/dev/null"), ParcelFileDescriptor.MODE_READ_ONLY);
}
}
-
diff --git a/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/IntentSenderActivity.java b/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/IntentSenderActivity.java
new file mode 100644
index 0000000..00fa6b7
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/IntentSenderActivity.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2014 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.intent.sender;
+
+import android.app.Activity;
+import android.content.Intent;
+
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.TimeUnit;
+
+public class IntentSenderActivity extends Activity {
+
+ private final SynchronousQueue<Result> mResult = new SynchronousQueue<>();
+
+ public static class Result {
+ public final int resultCode;
+ public final Intent data;
+
+ public Result(int resultCode, Intent data) {
+ this.resultCode = resultCode;
+ this.data = data;
+ }
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (resultCode == Activity.RESULT_OK) {
+ try {
+ mResult.offer(new Result(resultCode, data), 5, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ public Intent getResult(Intent intent) throws Exception {
+ startActivityForResult(intent, 42);
+ final Result result = mResult.poll(30, TimeUnit.SECONDS);
+ return (result != null) ? result.data : null;
+ }
+}
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofilecontent/CrossProfileContentTest.java b/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/IntentSenderTest.java
similarity index 76%
rename from hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofilecontent/CrossProfileContentTest.java
rename to hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/IntentSenderTest.java
index 85e7d1b..47de0da 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofilecontent/CrossProfileContentTest.java
+++ b/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/IntentSenderTest.java
@@ -13,30 +13,26 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.cts.managedprofile.crossprofilecontent;
-import static com.android.cts.managedprofile.BaseManagedProfileTest.ADMIN_RECEIVER_COMPONENT;
+package com.android.cts.intent.sender;
-import android.app.admin.DevicePolicyManager;
import android.content.ClipData;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
-import android.content.IntentFilter;
import android.net.Uri;
import android.support.v4.content.FileProvider;
-import android.test.ActivityInstrumentationTestCase2;
+import android.test.InstrumentationTestCase;
import android.util.Log;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
+import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
-import java.io.IOException;
-public class CrossProfileContentTest extends
- ActivityInstrumentationTestCase2<IntentSenderActivity> {
+public class IntentSenderTest extends InstrumentationTestCase {
private static final String MESSAGE = "Sample Message";
@@ -49,35 +45,20 @@
private static final String TAG = "CrossProfileContentTest";
- private static final String BASIC_CONTENT_PROVIDER_AUTHORITY =
- "com.android.cts.managedprofile.basiccontentProvider";
-
-
- private DevicePolicyManager mDpm;
-
private Context mContext;
-
- public CrossProfileContentTest() {
- super(IntentSenderActivity.class);
- }
+ private IntentSenderActivity mActivity;
@Override
protected void setUp() throws Exception {
super.setUp();
mContext = getInstrumentation().getTargetContext();
- mDpm = (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
- IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction(ACTION_READ_FROM_URI);
- intentFilter.addAction(ACTION_WRITE_TO_URI);
- intentFilter.addAction(ACTION_TAKE_PERSISTABLE_URI_PERMISSION);
- mDpm.addCrossProfileIntentFilter(ADMIN_RECEIVER_COMPONENT, intentFilter,
- DevicePolicyManager.FLAG_PARENT_CAN_ACCESS_MANAGED);
+ mActivity = launchActivity(mContext.getPackageName(), IntentSenderActivity.class, null);
}
@Override
- protected void tearDown() throws Exception {
- mDpm.clearCrossProfileIntentFilters(ADMIN_RECEIVER_COMPONENT);
+ public void tearDown() throws Exception {
super.tearDown();
+ mActivity.finish();
}
/**
@@ -85,14 +66,15 @@
* This intent will have, in the ClipData, a uri whose associated file stores a message.
* The receiver will read the message from the uri, and put it inside the result intent.
*/
- public void testReceiverCanRead() {
+ public void testReceiverCanRead() throws Exception {
Uri uri = getUriWithTextInFile("reading_test", MESSAGE);
assertTrue(uri != null);
Intent intent = new Intent(ACTION_READ_FROM_URI);
intent.setClipData(ClipData.newRawUri("", uri));
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- Intent result = getActivity().getResultForIntent(intent);
- assertTrue(result != null);
+
+ final Intent result = mActivity.getResult(intent);
+ assertNotNull(result);
assertEquals(MESSAGE, result.getStringExtra("extra_response"));
}
@@ -102,7 +84,7 @@
* The receiver will read the message from the extra, and write it to the uri in
* the ClipData.
*/
- public void testReceiverCanWrite() {
+ public void testReceiverCanWrite() throws Exception {
// It's the receiver of the intent that should write to the uri, not us. So, for now, we
// write an empty string.
Uri uri = getUriWithTextInFile("writing_test", "");
@@ -112,19 +94,21 @@
intent.putExtra("extra_message", MESSAGE);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION
| Intent.FLAG_GRANT_READ_URI_PERMISSION);
- getActivity().getResultForIntent(intent);
+
+ mActivity.getResult(intent);
assertEquals(MESSAGE, getFirstLineFromUri(uri));
}
- public void testPersistablePermission() {
+ public void testPersistablePermission() throws Exception {
Uri uri = getUriWithTextInFile("persistable_test", MESSAGE);
grantPersistableReadPermission(uri);
// Now checking if the receiver can read this uri, without re-granting the read permission.
Intent intent = new Intent(ACTION_READ_FROM_URI);
intent.setClipData(ClipData.newRawUri("", uri));
- Intent result = getActivity().getResultForIntent(intent);
- assertTrue(result != null);
+
+ final Intent result = mActivity.getResult(intent);
+ assertNotNull(result);
assertEquals(MESSAGE, result.getStringExtra("extra_response"));
}
@@ -138,7 +122,7 @@
* uriNotGranted), to enforce that even if an app has permission to one uri of a
* ContentProvider, it still cannot access a uri it does not have access to.
*/
- public void testAppPermissionsDontWorkAcrossProfiles() {
+ public void testAppPermissionsDontWorkAcrossProfiles() throws Exception {
// The FileProvider does not allow to use app permissions. So we need to use another
// ContentProvider.
Uri uriGranted = getBasicContentProviderUri("uri_granted");
@@ -152,19 +136,41 @@
Intent notGrant = new Intent(ACTION_READ_FROM_URI);
notGrant.setClipData(ClipData.newRawUri("", uriNotGranted));
- Intent result = getActivity().getResultForIntent(notGrant);
- assertTrue(result != null);
+ final Intent result = mActivity.getResult(notGrant);
+ assertNotNull(result);
// The receiver did not have permission to read the uri. So it should have caught a security
// exception.
assertTrue(result.getBooleanExtra("extra_caught_security_exception", false));
}
- private void grantPersistableReadPermission(Uri uri) {
+ /**
+ * Ensure that sender is only able to send data that it has access to.
+ */
+ public void testSecurity() throws Exception {
+ // Pick a URI that neither of us have access to; it doens't matter if
+ // its missing, since we expect a SE before a FNFE.
+ final Uri uri = Uri.parse("content://media/external/images/media/10240");
+ final Intent intent = new Intent(ACTION_READ_FROM_URI);
+ intent.setClipData(ClipData.newRawUri("", uri));
+ intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+
+ // We're expecting to run into a security exception
+ final Intent result = mActivity.getResult(intent);
+ if (result == null) {
+ // This is fine; probably of a SecurityException when off in the
+ // system somewhere.
+ } else {
+ // But if we somehow came through, make sure they threw.
+ assertTrue(result.getBooleanExtra("extra_caught_security_exception", false));
+ }
+ }
+
+ private void grantPersistableReadPermission(Uri uri) throws Exception {
Intent grantPersistable = new Intent(ACTION_TAKE_PERSISTABLE_URI_PERMISSION);
grantPersistable.setClipData(ClipData.newRawUri("", uri));
grantPersistable.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
- getActivity().getResultForIntent(grantPersistable);
+ mActivity.getResult(grantPersistable);
}
private Uri getBasicContentProviderUri(String path) {
@@ -172,7 +178,7 @@
// granting these uris to other apps, or these apps from trying to access these uris.
return new Uri.Builder()
.scheme(ContentResolver.SCHEME_CONTENT)
- .authority(BASIC_CONTENT_PROVIDER_AUTHORITY)
+ .authority("com.android.cts.intent.sender.provider")
.path(path)
.build();
}
@@ -191,7 +197,7 @@
Log.e(TAG, "Could not create file " + filename + " with text " + text);
return null;
}
- return FileProvider.getUriForFile(mContext, "com.android.cts.managedprofile.fileprovider",
+ return FileProvider.getUriForFile(mContext, "com.android.cts.intent.sender.fileprovider",
file);
}
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml b/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml
index 56b3671..008ed38 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml
@@ -19,9 +19,6 @@
<uses-sdk android:minSdkVersion="20"/>
- <permission android:name="com.android.cts.managedprofile.permission.SAMPLE"
- android:label="Sample Permission"/>
-
<application>
<uses-library android:name="android.test.runner" />
<receiver
@@ -65,11 +62,6 @@
<action android:name="com.android.cts.managedprofile.ACTION_TEST_ALL_ACTIVITY" />
</intent-filter>
</activity>
- <activity android:name=".crossprofilecontent.IntentSenderActivity">
- <intent-filter>
- <action android:name="android.intent.action.MAIN"/>
- </intent-filter>
- </activity>
<activity android:name=".UserRestrictionActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@@ -77,22 +69,6 @@
</intent-filter>
</activity>
<activity android:name=".TestActivity" />
- <provider
- android:name="android.support.v4.content.FileProvider"
- android:authorities="com.android.cts.managedprofile.fileprovider"
- android:grantUriPermissions="true"
- android:exported="false">
- <meta-data
- android:name="android.support.FILE_PROVIDER_PATHS"
- android:resource="@xml/filepaths" />
- </provider>
- <provider
- android:name="com.android.cts.managedprofile.crossprofilecontent.BasicContentProvider"
- android:authorities="com.android.cts.managedprofile.basiccontentProvider"
- android:grantUriPermissions="true"
- android:exported="true"
- android:permission="com.android.cts.managedprofile.permission.SAMPLE"
- />
</application>
<instrumentation android:name="android.test.InstrumentationTestRunner"
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofileintentfilters/AllUsersActivity.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/AllUsersActivity.java
similarity index 100%
rename from hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofileintentfilters/AllUsersActivity.java
rename to hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/AllUsersActivity.java
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofileintentfilters/ComponentDisablingActivity.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ComponentDisablingActivity.java
similarity index 100%
rename from hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofileintentfilters/ComponentDisablingActivity.java
rename to hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ComponentDisablingActivity.java
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileUtils.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileUtils.java
new file mode 100644
index 0000000..9615991
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileUtils.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2014 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.managedprofile;
+
+import static com.android.cts.managedprofile.BaseManagedProfileTest.ADMIN_RECEIVER_COMPONENT;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.content.IntentFilter;
+import android.test.AndroidTestCase;
+
+public class CrossProfileUtils extends AndroidTestCase {
+ private static final String ACTION_READ_FROM_URI = "com.android.cts.action.READ_FROM_URI";
+
+ private static final String ACTION_WRITE_TO_URI = "com.android.cts.action.WRITE_TO_URI";
+
+ private static final String ACTION_TAKE_PERSISTABLE_URI_PERMISSION =
+ "com.android.cts.action.TAKE_PERSISTABLE_URI_PERMISSION";
+
+ public void addParentCanAccessManagedFilters() {
+ removeAllFilters();
+
+ final DevicePolicyManager dpm = (DevicePolicyManager) getContext().getSystemService(
+ Context.DEVICE_POLICY_SERVICE);
+ IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(ACTION_READ_FROM_URI);
+ intentFilter.addAction(ACTION_WRITE_TO_URI);
+ intentFilter.addAction(ACTION_TAKE_PERSISTABLE_URI_PERMISSION);
+ dpm.addCrossProfileIntentFilter(ADMIN_RECEIVER_COMPONENT, intentFilter,
+ DevicePolicyManager.FLAG_PARENT_CAN_ACCESS_MANAGED);
+ }
+
+ public void addManagedCanAccessParentFilters() {
+ removeAllFilters();
+
+ final DevicePolicyManager dpm = (DevicePolicyManager) getContext().getSystemService(
+ Context.DEVICE_POLICY_SERVICE);
+ IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(ACTION_READ_FROM_URI);
+ intentFilter.addAction(ACTION_WRITE_TO_URI);
+ intentFilter.addAction(ACTION_TAKE_PERSISTABLE_URI_PERMISSION);
+ dpm.addCrossProfileIntentFilter(ADMIN_RECEIVER_COMPONENT, intentFilter,
+ DevicePolicyManager.FLAG_MANAGED_CAN_ACCESS_PARENT);
+ }
+
+ public void removeAllFilters() {
+ final DevicePolicyManager dpm = (DevicePolicyManager) getContext().getSystemService(
+ Context.DEVICE_POLICY_SERVICE);
+ dpm.clearCrossProfileIntentFilters(ADMIN_RECEIVER_COMPONENT);
+ }
+}
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofileintentfilters/ManagedProfileActivity.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ManagedProfileActivity.java
similarity index 100%
rename from hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofileintentfilters/ManagedProfileActivity.java
rename to hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ManagedProfileActivity.java
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofileintentfilters/ManagedProfileTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ManagedProfileTest.java
similarity index 100%
rename from hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofileintentfilters/ManagedProfileTest.java
rename to hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ManagedProfileTest.java
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofileintentfilters/PrimaryUserActivity.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PrimaryUserActivity.java
similarity index 99%
rename from hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofileintentfilters/PrimaryUserActivity.java
rename to hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PrimaryUserActivity.java
index 35f70be..b0e84ae 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofileintentfilters/PrimaryUserActivity.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PrimaryUserActivity.java
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package com.android.cts.managedprofile;
import android.app.Activity;
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofileintentfilters/PrimaryUserFilterSetterActivity.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PrimaryUserFilterSetterActivity.java
similarity index 100%
rename from hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofileintentfilters/PrimaryUserFilterSetterActivity.java
rename to hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PrimaryUserFilterSetterActivity.java
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofileintentfilters/PrimaryUserTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PrimaryUserTest.java
similarity index 99%
rename from hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofileintentfilters/PrimaryUserTest.java
rename to hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PrimaryUserTest.java
index 7098d9e..40ff6c5 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofileintentfilters/PrimaryUserTest.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PrimaryUserTest.java
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package com.android.cts.managedprofile;
import android.app.admin.DevicePolicyManager;
@@ -55,7 +56,7 @@
public void testAddCrossProfileIntentFilter_all() {
assertEquals(2, mPackageManager.queryIntentActivities(
new Intent(AllUsersActivity.ACTION), /* flags = */ 0).size());
-
+
// If we used startActivity(), the user would have a disambiguation dialog presented which
// requires human intervention, so we won't be testing like that
}
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofileintentfilters/TestActivity.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/TestActivity.java
similarity index 100%
rename from hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofileintentfilters/TestActivity.java
rename to hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/TestActivity.java
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofilecontent/IntentSenderActivity.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofilecontent/IntentSenderActivity.java
deleted file mode 100644
index e4c8ddf..0000000
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofilecontent/IntentSenderActivity.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2014 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.managedprofile.crossprofilecontent;
-
-import static com.android.cts.managedprofile.BaseManagedProfileTest.ADMIN_RECEIVER_COMPONENT;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.util.Log;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-public class IntentSenderActivity extends Activity {
-
- private CountDownLatch mLatch;
-
- private static final int WAIT_FOR_RESPONSE_TIMEOUT_SECONDS = 5;
-
- private Intent mResult;
-
- Intent getResultForIntent(Intent intent) {
- mLatch = new CountDownLatch(1);
- mResult = null;
- startActivityForResult(intent, 0);
- try {
- mLatch.await(WAIT_FOR_RESPONSE_TIMEOUT_SECONDS, TimeUnit.SECONDS);
- } catch (InterruptedException e) {
- }
- return mResult;
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent result) {
- if (resultCode == Activity.RESULT_OK) {
- mResult = result;
- }
- mLatch.countDown();
- }
-}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
index 15c7725..544ddff 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
@@ -17,6 +17,7 @@
package com.android.cts.devicepolicy;
import com.android.cts.tradefed.build.CtsBuildHelper;
+import com.android.cts.util.AbiUtils;
import com.android.ddmlib.Log.LogLevel;
import com.android.ddmlib.testrunner.InstrumentationResultParser;
import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
@@ -26,11 +27,13 @@
import com.android.ddmlib.testrunner.TestRunResult;
import com.android.tradefed.build.IBuildInfo;
import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.result.CollectingTestListener;
import com.android.tradefed.testtype.DeviceTestCase;
import com.android.tradefed.testtype.IBuildReceiver;
+import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.HashSet;
@@ -74,6 +77,21 @@
installResult);
}
+ protected void installAppAsUser(String appFileName, int userId) throws FileNotFoundException,
+ DeviceNotAvailableException {
+ final ITestDevice device = getDevice();
+
+ final File apk = mCtsBuild.getTestApp(appFileName);
+ final String remotePath = "/data/local/tmp/" + apk.getName();
+ if (!device.pushFile(apk, remotePath)) {
+ throw new IllegalStateException("Failed to push " + apk);
+ }
+
+ final String result = device.executeShellCommand(
+ "pm install --user " + userId + " " + remotePath);
+ assertTrue(result, result.contains("\nSuccess"));
+ }
+
/** Initializes the user with the given id. This is required so that apps can run on it. */
protected void startUser(int userId) throws DeviceNotAvailableException {
String command = "am start-user " + userId;
@@ -135,7 +153,17 @@
protected boolean runDeviceTestsAsUser(
String pkgName, @Nullable String testClassName, int userId)
throws DeviceNotAvailableException {
- return runDeviceTests(pkgName, testClassName, null /*testMethodName*/, userId);
+ return runDeviceTestsAsUser(pkgName, testClassName, null, userId);
+ }
+
+ /** Returns true if the specified tests passed. Tests are run as given user. */
+ protected boolean runDeviceTestsAsUser(
+ String pkgName, @Nullable String testClassName, String testMethodName, int userId)
+ throws DeviceNotAvailableException {
+ if (testClassName.startsWith(".")) {
+ testClassName = pkgName + testClassName;
+ }
+ return runDeviceTests(pkgName, testClassName, testMethodName, userId);
}
private boolean runDeviceTests(String pkgName, @Nullable String testClassName,
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
index 88a3b70..6ece85c 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
@@ -28,6 +28,9 @@
private static final String MANAGED_PROFILE_PKG = "com.android.cts.managedprofile";
private static final String MANAGED_PROFILE_APK = "CtsManagedProfileApp.apk";
+ private static final String INTENT_SENDER_PKG = "com.android.cts.intent.sender";
+ private static final String INTENT_SENDER_APK = "CtsIntentSenderApp.apk";
+
private static final String INTENT_RECEIVER_PKG = "com.android.cts.intent.receiver";
private static final String INTENT_RECEIVER_APK = "CtsIntentReceiverApp.apk";
@@ -110,16 +113,30 @@
if (!mHasFeature) {
return;
}
+
try {
- installApp(INTENT_RECEIVER_APK);
+ getDevice().uninstallPackage(INTENT_SENDER_PKG);
+ getDevice().uninstallPackage(INTENT_RECEIVER_PKG);
+ installAppAsUser(INTENT_SENDER_APK, 0);
+ installAppAsUser(INTENT_RECEIVER_APK, mUserId);
- String command = "pm uninstall --user " + mUserId + " " + INTENT_RECEIVER_PKG;
- CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": "
- + getDevice().executeShellCommand(command));
+ // Test from parent to managed
+ assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
+ "addManagedCanAccessParentFilters", mUserId));
+ assertTrue(runDeviceTestsAsUser(INTENT_SENDER_PKG, ".IntentSenderTest", 0));
- assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG,
- MANAGED_PROFILE_PKG + ".crossprofilecontent.CrossProfileContentTest", mUserId));
+ getDevice().uninstallPackage(INTENT_SENDER_PKG);
+ getDevice().uninstallPackage(INTENT_RECEIVER_PKG);
+ installAppAsUser(INTENT_SENDER_APK, mUserId);
+ installAppAsUser(INTENT_RECEIVER_APK, 0);
+
+ // Test from managed to parent
+ assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
+ "addParentCanAccessManagedFilters", mUserId));
+ assertTrue(runDeviceTestsAsUser(INTENT_SENDER_PKG, ".IntentSenderTest", mUserId));
+
} finally {
+ getDevice().uninstallPackage(INTENT_SENDER_PKG);
getDevice().uninstallPackage(INTENT_RECEIVER_PKG);
}
}
diff --git a/libs/commonutil/Android.mk b/libs/commonutil/Android.mk
new file mode 100644
index 0000000..9c131b0
--- /dev/null
+++ b/libs/commonutil/Android.mk
@@ -0,0 +1,27 @@
+#
+# Copyright (C) 2014 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 $(call all-subdir-makefiles)
+
+# ======================================================
+# Build a static host library for the AbiUtils
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := src/com/android/cts/util/AbiUtils.java
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE := ctsabiutilslib
+include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/libs/commonutil/src/com/android/cts/util/AbiUtils.java b/libs/commonutil/src/com/android/cts/util/AbiUtils.java
index 4a34c6f..6f47d52 100644
--- a/libs/commonutil/src/com/android/cts/util/AbiUtils.java
+++ b/libs/commonutil/src/com/android/cts/util/AbiUtils.java
@@ -163,4 +163,22 @@
public static String getBitness(String name) {
return ABIS_32BIT.contains(name) ? "32" : "64";
}
+
+ /**
+ * @param abilistString A comma separated string containing abis.
+ * @return A List of Strings containing valid ABIs.
+ */
+ public static Set<String> parseAbiList(String unsupportedAbiDescription) {
+ Set<String> abiSet = new HashSet<>();
+ String[] descSegments = unsupportedAbiDescription.split(":");
+ if (descSegments.length == 2) {
+ for (String abi : descSegments[1].split(",")) {
+ String trimmedAbi = abi.trim();
+ if (isAbiSupportedByCts(trimmedAbi)) {
+ abiSet.add(trimmedAbi);
+ }
+ }
+ }
+ return abiSet;
+ }
}
diff --git a/suite/cts/deviceTests/browserbench/src/com/android/cts/browser/BrowserBenchTest.java b/suite/cts/deviceTests/browserbench/src/com/android/cts/browser/BrowserBenchTest.java
index 997f730..d74ddb2 100644
--- a/suite/cts/deviceTests/browserbench/src/com/android/cts/browser/BrowserBenchTest.java
+++ b/suite/cts/deviceTests/browserbench/src/com/android/cts/browser/BrowserBenchTest.java
@@ -17,6 +17,7 @@
package com.android.cts.browser;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.cts.util.WatchDog;
import android.net.Uri;
import android.provider.Browser;
@@ -70,10 +71,12 @@
private volatile int mRunIndex;
/** stores results for each runs. last entry will be the final score. */
private LinkedHashMap<String, double[]> mResultsMap;
+ private PackageManager mPackageManager;
@Override
protected void setUp() throws Exception {
super.setUp();
+ mPackageManager = getInstrumentation().getContext().getPackageManager();
mWebServer = new CtsTestServer(getContext()) {
@Override
protected HttpResponse onPost(HttpRequest request) throws Exception {
@@ -124,6 +127,10 @@
@TimeoutReq(minutes = 60)
public void testOctane() throws InterruptedException {
+ if (!isBrowserSupported()) {
+ Log.i(TAG, "Skipping test for device with no supported browser");
+ return;
+ }
String url = mWebServer.getAssetUrl(OCTANE_START_FILE) + "?auto=1";
final int kRepeat = 5;
doTest(url, ResultType.LOWER_BETTER, ResultUnit.MS,
@@ -167,4 +174,13 @@
numberToProcess++;
}
}
+
+ /**
+ * @return true iff this device is has a working browser.
+ */
+ private boolean isBrowserSupported() {
+ return !(mPackageManager.hasSystemFeature("android.hardware.type.television")
+ || mPackageManager.hasSystemFeature("android.software.leanback")
+ || mPackageManager.hasSystemFeature("android.hardware.type.watch"));
+ }
}
diff --git a/tests/expectations/knownfailures.txt b/tests/expectations/knownfailures.txt
index 8adf345..9ae041c 100644
--- a/tests/expectations/knownfailures.txt
+++ b/tests/expectations/knownfailures.txt
@@ -1,5 +1,13 @@
[
{
+ description: "tests a fragile by nature as they rely on hardcoded behavior",
+ names: [
+ "android.accessibilityservice.cts.AccessibilityTextTraversalTest#testActionNextAndPreviousAtGranularityPageOverText",
+ "android.accessibilityservice.cts.AccessibilityTextTraversalTest#testActionNextAndPreviousAtGranularityPageOverTextExtend"
+ ],
+ bug: 17595050
+},
+{
description: "signature test stil needs more work",
names: [
"android.signature.cts.SignatureTest#testSignature"
@@ -37,6 +45,26 @@
bug: 16720689
},
{
+ description: "test can only run properly on a user build device when the bug is resolved",
+ names: [
+ "android.appwidget.cts.AppWidgetTest#testAppWidgetProviderCallbacks",
+ "android.appwidget.cts.AppWidgetTest#testBindAppWidget",
+ "android.appwidget.cts.AppWidgetTest#testCollectionWidgets",
+ "android.appwidget.cts.AppWidgetTest#testDeleteHost",
+ "android.appwidget.cts.AppWidgetTest#testDeleteHosts",
+ "android.appwidget.cts.AppWidgetTest#testGetAppWidgetIds",
+ "android.appwidget.cts.AppWidgetTest#testGetAppWidgetInfo",
+ "android.appwidget.cts.AppWidgetTest#testGetAppWidgetOptions",
+ "android.appwidget.cts.AppWidgetTest#testPartiallyUpdateAppWidgetViaWidgetId",
+ "android.appwidget.cts.AppWidgetTest#testPartiallyUpdateAppWidgetViaWidgetIds",
+ "android.appwidget.cts.AppWidgetTest#testTwoAppWidgetProviderCallbacks",
+ "android.appwidget.cts.AppWidgetTest#testUpdateAppWidgetViaComponentName",
+ "android.appwidget.cts.AppWidgetTest#testUpdateAppWidgetViaWidgetId",
+ "android.appwidget.cts.AppWidgetTest#testUpdateAppWidgetViaWidgetIds"
+ ],
+ bug: 17993121
+},
+{
description: "A few WebGL tests are known to fail in WebView",
names: [
"android.webgl.cts.WebGLTest#test_conformance_extensions_oes_texture_float_with_video_html",
@@ -74,6 +102,13 @@
bug: 17530117
},
{
+ description: "this test removes the stay-awake option, causing the screen to turn off during the execution of subsequent tests",
+ names: [
+ "android.admin.cts.DevicePolicyManagerTest#testMaximumTimeToLock"
+ ],
+ bug: 18002490
+},
+{
description: "these tests locks the screen with an emtpy password or swipe-to-unlock, blocking subsequent test to dismiss keyguard",
names: [
"android.admin.cts.DevicePolicyManagerTest#testPasswordQuality_something",
diff --git a/tests/expectations/unsupportedabis.txt b/tests/expectations/unsupportedabis.txt
index 520d750..817179b 100644
--- a/tests/expectations/unsupportedabis.txt
+++ b/tests/expectations/unsupportedabis.txt
@@ -2,6 +2,14 @@
{
description: "Tests not supporting: arm64-v8a, x86_64, mips64",
names: [
+ "android.bionic.malloc#pvalloc_overflow",
+ "android.bionic.malloc#pvalloc_std",
+ "android.bionic.malloc#valloc_overflow",
+ "android.bionic.malloc#valloc_std",
+ "android.renderscriptlegacy.cts.LeakTest",
+ "android.renderscriptlegacy.cts.RSBase",
+ "android.renderscriptlegacy.cts.RSBaseCompute",
+ "android.renderscriptlegacy.cts.VersionTest",
"android.sample.cts.SampleDeviceResultTest",
"android.sample.cts.SampleDeviceTest",
"android.sample.cts.SampleHostResultTest",
diff --git a/tests/tests/bionic/Android.mk b/tests/tests/bionic/Android.mk
index 1a048c6..e1afd50 100644
--- a/tests/tests/bionic/Android.mk
+++ b/tests/tests/bionic/Android.mk
@@ -8,6 +8,9 @@
LOCAL_MODULE := $(test_executable)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/nativetest
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
LOCAL_ADDITION_DEPENDENCIES := \
$(LOCAL_PATH)/Android.mk \
@@ -31,6 +34,10 @@
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := $(list_executable)
+LOCAL_MULTILIB := both
+# Use the 32 bit list executable since it will include some 32 bit only tests.
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
LOCAL_ADDITION_DEPENDENCIES := \
$(LOCAL_PATH)/Android.mk \
diff --git a/tests/tests/graphics/res/drawable/vector_icon_delete.xml b/tests/tests/graphics/res/drawable/vector_icon_delete.xml
index 7b8f2aa..8d9c21c 100644
--- a/tests/tests/graphics/res/drawable/vector_icon_delete.xml
+++ b/tests/tests/graphics/res/drawable/vector_icon_delete.xml
@@ -24,6 +24,6 @@
<path
android:fillColor="#FF000000"
- android:pathData="M6.0,19.0c0.0,1.104 896e-3,2.0 2.0,2.0l8.0,0.0c1.104,0.0 2.0-896e-3 2.0-2.0l0.0-12.0L6.0,7.0L6.0,19.0zM18.0,4.0l-2.5,0.0l-1.0-1.0l-5.0,0.0l-1.0,1.0L6.0,4.0C5.4469986,4.0 5.0,4.4469986 5.0,5.0l0.0,1.0l14.0,0.0l0.0-1.0C19.0,4.4469986 18.552002,4.0 18.0,4.0z" />
+ android:pathData="M6.0,19.0c0.0,1.104 0.896,2.0 2.0,2.0l8.0,0.0c1.104,0.0 2.0-0.896 2.0-2.0l0.0-12.0L6.0,7.0L6.0,19.0zM18.0,4.0l-2.5,0.0l-1.0-1.0l-5.0,0.0l-1.0,1.0L6.0,4.0C5.4469986,4.0 5.0,4.4469986 5.0,5.0l0.0,1.0l14.0,0.0l0.0-1.0C19.0,4.4469986 18.552002,4.0 18.0,4.0z" />
</vector>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/drawable/vector_icon_heart.xml b/tests/tests/graphics/res/drawable/vector_icon_heart.xml
index ad991c9..ff55fe5 100644
--- a/tests/tests/graphics/res/drawable/vector_icon_heart.xml
+++ b/tests/tests/graphics/res/drawable/vector_icon_heart.xml
@@ -24,6 +24,6 @@
<path
android:fillColor="#FF000000"
- android:pathData="M16.0,5.0c-1.955.0 -3.83,1.268 -4.5,3.0c-0.67-1.732 -2.547-3.0 -4.5-3.0C4.4570007,5.0 2.5,6.931999 2.5,9.5c0.0,3.529 3.793,6.258 9.0,11.5c5.207-5.242 9.0-7.971 9.0-11.5C20.5,6.931999 18.543,5.0 16.0,5.0z" />
+ android:pathData="M16.0,5.0c-1.955,0.0 -3.83,1.268 -4.5,3.0c-0.67-1.732 -2.547-3.0 -4.5-3.0C4.4570007,5.0 2.5,6.931999 2.5,9.5c0.0,3.529 3.793,6.258 9.0,11.5c5.207-5.242 9.0-7.971 9.0-11.5C20.5,6.931999 18.543,5.0 16.0,5.0z" />
</vector>
\ No newline at end of file
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java
index ea15c19..27becef 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java
@@ -548,6 +548,8 @@
*/
private void videoSnapshotTestByCamera(boolean burstTest)
throws Exception {
+ final int NUM_SINGLE_SHOT_TEST = 5;
+ final int FRAMEDROP_TOLERANCE = 8;
for (int profileId : mCamcorderProfileList) {
int cameraId = Integer.valueOf(mCamera.getId());
if (!CamcorderProfile.hasProfile(cameraId, profileId) ||
@@ -603,70 +605,89 @@
+ videoSz.toString() + ".mp4";
}
- prepareRecordingWithProfile(profile);
+ int numTestIterations = burstTest ? 1 : NUM_SINGLE_SHOT_TEST;
+ int totalDroppedFrames = 0;
- // prepare video snapshot
- SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
- SimpleImageReaderListener imageListener = new SimpleImageReaderListener();
- CaptureRequest.Builder videoSnapshotRequestBuilder =
- mCamera.createCaptureRequest((mStaticInfo.isHardwareLevelLegacy()) ?
- CameraDevice.TEMPLATE_RECORD : CameraDevice.TEMPLATE_VIDEO_SNAPSHOT);
+ for (int numTested = 0; numTested < numTestIterations; numTested++) {
+ prepareRecordingWithProfile(profile);
- // prepare preview surface by using video size.
- updatePreviewSurfaceWithVideoSize(videoSz);
+ // prepare video snapshot
+ SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
+ SimpleImageReaderListener imageListener = new SimpleImageReaderListener();
+ CaptureRequest.Builder videoSnapshotRequestBuilder =
+ mCamera.createCaptureRequest((mStaticInfo.isHardwareLevelLegacy()) ?
+ CameraDevice.TEMPLATE_RECORD :
+ CameraDevice.TEMPLATE_VIDEO_SNAPSHOT);
- prepareVideoSnapshot(videoSnapshotRequestBuilder, imageListener);
+ // prepare preview surface by using video size.
+ updatePreviewSurfaceWithVideoSize(videoSz);
- // Start recording
- startRecording(/* useMediaRecorder */true, resultListener);
- long startTime = SystemClock.elapsedRealtime();
+ prepareVideoSnapshot(videoSnapshotRequestBuilder, imageListener);
+ CaptureRequest request = videoSnapshotRequestBuilder.build();
- // Record certain duration.
- SystemClock.sleep(RECORDING_DURATION_MS / 2);
+ // Start recording
+ startRecording(/* useMediaRecorder */true, resultListener);
+ long startTime = SystemClock.elapsedRealtime();
- // take a video snapshot
- CaptureRequest request = videoSnapshotRequestBuilder.build();
- if (burstTest) {
- List<CaptureRequest> requests =
- new ArrayList<CaptureRequest>(BURST_VIDEO_SNAPSHOT_NUM);
- for (int i = 0; i < BURST_VIDEO_SNAPSHOT_NUM; i++) {
- requests.add(request);
+ // Record certain duration.
+ SystemClock.sleep(RECORDING_DURATION_MS / 2);
+
+ // take video snapshot
+ if (burstTest) {
+ List<CaptureRequest> requests =
+ new ArrayList<CaptureRequest>(BURST_VIDEO_SNAPSHOT_NUM);
+ for (int i = 0; i < BURST_VIDEO_SNAPSHOT_NUM; i++) {
+ requests.add(request);
+ }
+ mSession.captureBurst(requests, resultListener, mHandler);
+ } else {
+ mSession.capture(request, resultListener, mHandler);
}
- mSession.captureBurst(requests, resultListener, mHandler);
- } else {
- mSession.capture(request, resultListener, mHandler);
- }
- // make sure recording is still going after video snapshot
- SystemClock.sleep(RECORDING_DURATION_MS / 2);
+ // make sure recording is still going after video snapshot
+ SystemClock.sleep(RECORDING_DURATION_MS / 2);
- // Stop recording and preview
- stopRecording(/* useMediaRecorder */true);
- int duration = (int) (SystemClock.elapsedRealtime() - startTime);
+ // Stop recording and preview
+ stopRecording(/* useMediaRecorder */true);
+ int duration = (int) (SystemClock.elapsedRealtime() - startTime);
- // Validation recorded video
- validateRecording(videoSz, duration);
+ // Validation recorded video
+ validateRecording(videoSz, duration);
- if (burstTest) {
- for (int i = 0; i < BURST_VIDEO_SNAPSHOT_NUM; i++) {
+ if (burstTest) {
+ for (int i = 0; i < BURST_VIDEO_SNAPSHOT_NUM; i++) {
+ Image image = imageListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
+ validateVideoSnapshotCapture(image, videoSnapshotSz);
+ image.close();
+ }
+ } else {
+ // validate video snapshot image
Image image = imageListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
validateVideoSnapshotCapture(image, videoSnapshotSz);
+
+ // validate if there is framedrop around video snapshot
+ totalDroppedFrames += validateFrameDropAroundVideoSnapshot(
+ resultListener, image.getTimestamp());
+
+ //TODO: validate jittering. Should move to PTS
+ //validateJittering(resultListener);
+
image.close();
}
- } else {
- // validate video snapshot image
- Image image = imageListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
- validateVideoSnapshotCapture(image, videoSnapshotSz);
-
- // validate if there is framedrop around video snapshot
- validateFrameDropAroundVideoSnapshot(resultListener, image.getTimestamp());
-
- //TODO: validate jittering. Should move to PTS
- //validateJittering(resultListener);
-
- image.close();
}
+ if (!burstTest) {
+ Log.w(TAG, String.format("Camera %d Video size %s: Number of dropped frames " +
+ "detected in %d trials is %d frames.", cameraId, videoSz.toString(),
+ numTestIterations, totalDroppedFrames));
+ mCollector.expectLessOrEqual(
+ String.format(
+ "Camera %d Video size %s: Number of dropped frames %d must not"
+ + " be larger than %d",
+ cameraId, videoSz.toString(), totalDroppedFrames,
+ FRAMEDROP_TOLERANCE),
+ FRAMEDROP_TOLERANCE, totalDroppedFrames);
+ }
closeImageReader();
}
}
@@ -867,8 +888,9 @@
/**
* Validate if video snapshot causes frame drop.
* Here frame drop is defined as frame duration >= 2 * expected frame duration.
+ * Return the estimated number of frames dropped during video snapshot
*/
- private void validateFrameDropAroundVideoSnapshot(
+ private int validateFrameDropAroundVideoSnapshot(
SimpleCaptureCallback resultListener, long imageTimeStamp) {
int expectedDurationMs = 1000 / mVideoFrameRate;
CaptureResult prevResult = resultListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
@@ -883,6 +905,7 @@
resultListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
long nextTS = getValueNotNull(nextResult, CaptureResult.SENSOR_TIMESTAMP);
int durationMs = (int) (currentTS - prevTS) / 1000000;
+ int totalFramesDropped = 0;
// Snapshots in legacy mode pause the preview briefly. Skip the duration
// requirements for legacy mode unless this is fixed.
@@ -925,8 +948,18 @@
durationMs, expectedDurationMs
));
}
+
+ int totalDurationMs = (int) (nextTS - prevTS) / 1000000;
+ // Rounding and minus 2 for the expected 2 frames interval
+ totalFramesDropped =
+ (totalDurationMs + expectedDurationMs / 2) /expectedDurationMs - 2;
+ if (totalFramesDropped < 0) {
+ Log.w(TAG, "totalFrameDropped is " + totalFramesDropped +
+ ". Video frame rate might be too fast.");
+ }
+ totalFramesDropped = Math.max(0, totalFramesDropped);
}
- return;
+ return totalFramesDropped;
}
prevTS = currentTS;
}
diff --git a/tests/tests/nativemedia/sl/Android.mk b/tests/tests/nativemedia/sl/Android.mk
index 5b34b3d..48b816c 100644
--- a/tests/tests/nativemedia/sl/Android.mk
+++ b/tests/tests/nativemedia/sl/Android.mk
@@ -10,6 +10,9 @@
LOCAL_MODULE := $(test_executable)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/nativetest
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
LOCAL_C_INCLUDES := \
bionic \
diff --git a/tests/tests/nativemedia/xa/Android.mk b/tests/tests/nativemedia/xa/Android.mk
index 6995bc0..ace315a 100644
--- a/tests/tests/nativemedia/xa/Android.mk
+++ b/tests/tests/nativemedia/xa/Android.mk
@@ -10,6 +10,9 @@
LOCAL_MODULE:= $(test_executable)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/nativetest
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
LOCAL_C_INCLUDES := \
bionic \
diff --git a/tests/tests/widget/res/layout/popupwindow.xml b/tests/tests/widget/res/layout/popupwindow.xml
index 2508115..f93f965 100644
--- a/tests/tests/widget/res/layout/popupwindow.xml
+++ b/tests/tests/widget/res/layout/popupwindow.xml
@@ -14,37 +14,36 @@
limitations under the License.
-->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
- <TextView android:id="@+id/anchor_upper"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/text_view_hint" />
+ <View android:id="@+id/anchor_upper"
+ android:layout_width="10dp"
+ android:layout_height="10dp"
+ android:layout_alignParentTop="true"
+ android:layout_centerHorizontal="true"
+ android:background="#f00" />
- <LinearLayout android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1">
+ <View android:id="@+id/anchor_lower"
+ android:layout_width="10dp"
+ android:layout_height="10dp"
+ android:layout_alignParentBottom="true"
+ android:layout_centerHorizontal="true"
+ android:background="#0f0" />
- <TextView android:id="@+id/anchor_middle_left"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:text="@string/text_view_hint"
- android:layout_weight="1"/>
+ <View android:id="@+id/anchor_middle_left"
+ android:layout_width="10dp"
+ android:layout_height="10dp"
+ android:layout_alignParentLeft="true"
+ android:layout_centerVertical="true"
+ android:background="#00f" />
- <TextView android:id="@+id/anchor_middle_right"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:text="@string/text_view_hint"
- android:layout_weight="1"/>
+ <View android:id="@+id/anchor_middle_right"
+ android:layout_width="10dp"
+ android:layout_height="10dp"
+ android:layout_alignParentRight="true"
+ android:layout_centerVertical="true"
+ android:background="#ff0" />
- </LinearLayout>
-
- <TextView android:id="@+id/anchor_lower"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/text_view_hint" />
-
-</LinearLayout>
+</RelativeLayout>
diff --git a/tests/tests/widget/src/android/widget/cts/PopupWindowTest.java b/tests/tests/widget/src/android/widget/cts/PopupWindowTest.java
index 4a14d2b..e1742c8 100644
--- a/tests/tests/widget/src/android/widget/cts/PopupWindowTest.java
+++ b/tests/tests/widget/src/android/widget/cts/PopupWindowTest.java
@@ -25,6 +25,7 @@
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
+import android.os.Debug;
import android.os.SystemClock;
import android.test.ActivityInstrumentationTestCase2;
import android.test.UiThreadTest;
@@ -580,7 +581,8 @@
assertEquals(50, mPopupWindow.getHeight());
mPopupWindow.getContentView().getLocationOnScreen(viewXY);
- // the position should be changed
+
+ // The popup should appear below and to right with an offset.
assertEquals(anchorXY[0] + 20 + viewInWindowOff[0], viewXY[0]);
assertEquals(anchorXY[1] + anchorView.getHeight() + 50 + viewInWindowOff[1], viewXY[1]);
@@ -597,14 +599,15 @@
assertEquals(50, mPopupWindow.getHeight());
mPopupWindow.getContentView().getLocationOnScreen(viewXY);
- // the position should be changed
+
+ // The popup should appear below and to right with an offset.
assertEquals(anchorXY[0] + 10 + viewInWindowOff[0], viewXY[0]);
assertEquals(anchorXY[1] + anchorView.getHeight() + 50 + viewInWindowOff[1], viewXY[1]);
- final View anthoterView = mActivity.findViewById(R.id.anchor_middle_right);
+ final View anotherView = mActivity.findViewById(R.id.anchor_middle_left);
mInstrumentation.runOnMainSync(new Runnable() {
public void run() {
- mPopupWindow.update(anthoterView, 0, 0, 60, 60);
+ mPopupWindow.update(anotherView, 0, 0, 60, 60);
}
});
mInstrumentation.waitForIdleSync();
@@ -614,11 +617,12 @@
assertEquals(60, mPopupWindow.getHeight());
int[] newXY = new int[2];
- anthoterView.getLocationOnScreen(newXY);
+ anotherView.getLocationOnScreen(newXY);
mPopupWindow.getContentView().getLocationOnScreen(viewXY);
- // the position should be changed
+
+ // The popup should appear below and to the right.
assertEquals(newXY[0] + viewInWindowOff[0], viewXY[0]);
- assertEquals(newXY[1] + anthoterView.getHeight() + viewInWindowOff[1], viewXY[1]);
+ assertEquals(newXY[1] + anotherView.getHeight() + viewInWindowOff[1], viewXY[1]);
dismissPopup();
}
@@ -815,8 +819,7 @@
}
private View createPopupContent() {
- TextView popupView = new TextView(mActivity);
- popupView.setText("Popup");
+ View popupView = new View(mActivity);
popupView.setLayoutParams(new ViewGroup.LayoutParams(50, 50));
popupView.setBackgroundColor(Color.WHITE);
diff --git a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/XmlGenerator.java b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/XmlGenerator.java
index 1680cae..833bf69 100644
--- a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/XmlGenerator.java
+++ b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/XmlGenerator.java
@@ -205,7 +205,8 @@
String className = nameCollector.toString();
nameCollector.append('#').append(test.getName());
writer.append("<Test name=\"").append(test.getName()).append("\"");
- String abis = getSupportedAbis(mUnsupportedAbis, mArchitecture, className).toString();
+ String abis = getSupportedAbis(mUnsupportedAbis, mArchitecture,
+ className, nameCollector.toString()).toString();
writer.append(" abis=\"" + abis.substring(1, abis.length() - 1) + "\"");
if (isKnownFailure(mKnownFailures, nameCollector.toString())) {
writer.append(" expectation=\"failure\"");
@@ -232,23 +233,36 @@
// Returns the list of ABIs supported by this TestCase on this architecture.
public static Set<String> getSupportedAbis(ExpectationStore expectationStore,
- String architecture, String className) {
+ String architecture, String className, String testName) {
Set<String> supportedAbis = AbiUtils.getAbisForArch(architecture);
- Expectation e = (expectationStore == null) ? null : expectationStore.get(className);
- if (e != null && !e.getDescription().isEmpty()) {
- // Description should be written in the form "blah blah: abi1, abi2..."
- String description = e.getDescription().split(":")[1];
- String[] unsupportedAbis = description.split(",");
- for (String a : unsupportedAbis) {
- String abi = a.trim();
- if (!AbiUtils.isAbiSupportedByCts(abi)) {
- throw new RuntimeException(
- String.format("Unrecognised ABI %s in %s", abi, e.getDescription()));
- }
- supportedAbis.remove(abi);
- }
+ if (expectationStore == null) {
+ return supportedAbis;
}
+
+ removeUnsupportedAbis(expectationStore.get(className), supportedAbis);
+ removeUnsupportedAbis(expectationStore.get(testName), supportedAbis);
return supportedAbis;
}
+ public static void removeUnsupportedAbis(Expectation expectation, Set<String> supportedAbis) {
+ if (expectation == null) {
+ return;
+ }
+
+ String description = expectation.getDescription();
+ if (description.isEmpty()) {
+ return;
+ }
+
+ String[] unsupportedAbis = description.split(":")[1].split(",");
+ for (String a : unsupportedAbis) {
+ String abi = a.trim();
+ if (!AbiUtils.isAbiSupportedByCts(abi)) {
+ throw new RuntimeException(
+ String.format("Unrecognised ABI %s in %s", abi, description));
+ }
+ supportedAbis.remove(abi);
+ }
+ }
+
}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java
index 6d617ea..7aed84d 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java
@@ -762,15 +762,26 @@
*/
private void installPrerequisiteApks(Collection<String> prerequisiteApks)
throws DeviceNotAvailableException {
+ Log.logAndDisplay(LogLevel.INFO, LOG_TAG, "Installing prerequisites");
+ Set<String> supportedAbiSet = getAbis();
for (String apkName : prerequisiteApks) {
try {
File apkFile = mCtsBuild.getTestApp(apkName);
- String errorCode = null;
- String abi = AbiFormatter.getDefaultAbi(getDevice(), mForceAbi);
- String[] options = {AbiUtils.createAbiFlag(abi)};
- errorCode = getDevice().installPackage(apkFile, true, options);
- if (errorCode != null) {
- CLog.e("Failed to install %s. Reason: %s", apkName, errorCode);
+ // As a workaround for multi arch support, try to install the APK
+ // for all device supported ABIs. This will generate warning messages
+ // until the above FIXME is resolved.
+ int installFailCount = 0;
+ for (String abi : supportedAbiSet) {
+ String[] options = {AbiUtils.createAbiFlag(abi)};
+ String errorCode = getDevice().installPackage(apkFile, true, options);
+ if (errorCode != null) {
+ installFailCount++;
+ CLog.w("Failed to install %s. Reason: %s", apkName, errorCode);
+ }
+
+ }
+ if (installFailCount >= supportedAbiSet.size()) {
+ CLog.e("Failed to install %s. See warning messages.", apkName);
}
} catch (FileNotFoundException e) {
CLog.e("Could not find test apk %s", apkName);
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/GeeTest.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/GeeTest.java
index 9bfe151..6c2ed65 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/GeeTest.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/GeeTest.java
@@ -49,9 +49,9 @@
private CtsBuildHelper mCtsBuild;
private ITestDevice mDevice;
private IAbi mAbi;
+ private String mExeName;
private final String mPackageName;
- private final String mExeName;
public GeeTest(String packageName, String exeName) {
mPackageName = packageName;
@@ -63,6 +63,7 @@
*/
public void setAbi(IAbi abi) {
mAbi = abi;
+ mExeName += mAbi.getBitness();
}
@Override
diff --git a/tools/utils/Android.mk b/tools/utils/Android.mk
index 36081ca..0ba5cf4 100644
--- a/tools/utils/Android.mk
+++ b/tools/utils/Android.mk
@@ -25,6 +25,6 @@
LOCAL_CLASSPATH := $(HOST_JDK_TOOLS_JAR)
LOCAL_JAVA_LIBRARIES := junit
-LOCAL_STATIC_JAVA_LIBRARIES := vogarexpectlib
+LOCAL_STATIC_JAVA_LIBRARIES := ctsabiutilslib vogarexpectlib
include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tools/utils/CollectAllTests.java b/tools/utils/CollectAllTests.java
index 367fb93..ed74824 100644
--- a/tools/utils/CollectAllTests.java
+++ b/tools/utils/CollectAllTests.java
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+import com.android.cts.util.AbiUtils;
import org.junit.runner.RunWith;
import org.w3c.dom.Document;
@@ -20,6 +21,7 @@
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
+import vogar.Expectation;
import vogar.ExpectationStore;
import java.io.BufferedReader;
@@ -61,9 +63,9 @@
private static final String TEST_TYPE = "LOCAL_TEST_TYPE :";
public static void main(String[] args) {
- if (args.length < 4 || args.length > 6) {
+ if (args.length < 5 || args.length > 7) {
System.err.println("usage: CollectAllTests <output-file> <manifest-file> <jar-file> "
- + "<java-package> [expectation-dir [makefile-file]]");
+ + "<java-package> <architecture> [expectation-dir [makefile-file]]");
if (args.length != 0) {
System.err.println("received:");
for (String arg : args) {
@@ -86,8 +88,14 @@
return;
}
}
- String libcoreExpectationDir = (args.length > 4) ? args[4] : null;
- String androidMakeFile = (args.length > 5) ? args[5] : null;
+ String architecture = args[4];
+ if (architecture == null || architecture.equals("")) {
+ System.err.println("Invalid architecture");
+ System.exit(1);
+ return;
+ }
+ String libcoreExpectationDir = (args.length > 5) ? args[5] : null;
+ String androidMakeFile = (args.length > 6) ? args[6] : null;
final TestType testType = TestType.getTestType(androidMakeFile);
@@ -207,7 +215,7 @@
try {
klass.getConstructor(new Class<?>[] { String.class } );
- addToTests(expectations, testCases, klass);
+ addToTests(expectations, architecture, testCases, klass);
continue;
} catch (NoSuchMethodException e) {
} catch (SecurityException e) {
@@ -218,7 +226,7 @@
try {
klass.getConstructor(new Class<?>[0]);
- addToTests(expectations, testCases, klass);
+ addToTests(expectations, architecture, testCases, klass);
continue;
} catch (NoSuchMethodException e) {
} catch (SecurityException e) {
@@ -356,6 +364,7 @@
}
private static void addToTests(ExpectationStore[] expectations,
+ String architecture,
Map<String,TestClass> testCases,
Class<?> testClass) {
Set<String> testNames = new HashSet<String>();
@@ -386,11 +395,12 @@
}
testNames.add(testName);
- addToTests(expectations, testCases, testClass, testName);
+ addToTests(expectations, architecture, testCases, testClass, testName);
}
}
private static void addToTests(ExpectationStore[] expectations,
+ String architecture,
Map<String,TestClass> testCases,
Class<?> test,
String testName) {
@@ -412,6 +422,10 @@
return;
}
+ Set<String> supportedAbis = VogarUtils.extractSupportedAbis(architecture,
+ expectations,
+ testClassName,
+ testName);
TestClass testClass;
if (testCases.containsKey(testClassName)) {
testClass = testCases.get(testClassName);
@@ -420,7 +434,8 @@
testCases.put(testClassName, testClass);
}
- testClass.mCases.add(new TestMethod(testName, "", "", knownFailure, false, false));
+ testClass.mCases.add(new TestMethod(testName, "", "", supportedAbis,
+ knownFailure, false, false));
}
private static boolean isJunit3Test(Class<?> klass) {
diff --git a/tools/utils/DescriptionGenerator.java b/tools/utils/DescriptionGenerator.java
index 607d2e5..09e1118 100644
--- a/tools/utils/DescriptionGenerator.java
+++ b/tools/utils/DescriptionGenerator.java
@@ -22,6 +22,7 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
+import java.util.Set;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
@@ -38,6 +39,7 @@
import org.w3c.dom.NodeList;
import vogar.ExpectationStore;
+import vogar.Expectation;
import com.sun.javadoc.AnnotationDesc;
import com.sun.javadoc.AnnotationTypeDoc;
@@ -82,11 +84,13 @@
static final String ATTRIBUTE_VALUE_FRAMEWORK = "Android 1.0";
static final String ATTRIBUTE_NAME = "name";
+ static final String ATTRIBUTE_ABIS = "abis";
static final String ATTRIBUTE_HOST_CONTROLLER = "HostController";
static final String XML_OUTPUT_PATH = "./description.xml";
static final String OUTPUT_PATH_OPTION = "-o";
+ static final String ARCHITECTURE_OPTION = "-a";
/**
* Start to parse the classes passed in by javadoc, and generate
@@ -103,12 +107,21 @@
}
String outputPath = XML_OUTPUT_PATH;
+ String architecture = null;
String[][] options = root.options();
for (String[] option : options) {
- if (option.length == 2 && option[0].equals(OUTPUT_PATH_OPTION)) {
- outputPath = option[1];
+ if (option.length == 2) {
+ if (option[0].equals(OUTPUT_PATH_OPTION)) {
+ outputPath = option[1];
+ } else if (option[0].equals(ARCHITECTURE_OPTION)) {
+ architecture = option[1];
+ }
}
}
+ if (architecture == null || architecture.equals("")) {
+ Log.e("Missing architecture!", null);
+ return false;
+ }
XMLGenerator xmlGenerator = null;
try {
@@ -128,7 +141,7 @@
for (ClassDoc clazz : classes) {
if ((!clazz.isAbstract()) && (isValidJUnitTestCase(clazz))) {
- xmlGenerator.addTestClass(new TestClass(clazz, ctsExpectationStore));
+ xmlGenerator.addTestClass(new TestClass(clazz, ctsExpectationStore, architecture));
}
}
@@ -420,6 +433,8 @@
Node caseNode = elem.appendChild(mDoc.createElement(TAG_TEST));
setAttribute(caseNode, ATTRIBUTE_NAME, caze.mName);
+ String abis = caze.mAbis.toString();
+ setAttribute(caseNode, ATTRIBUTE_ABIS, abis.substring(1, abis.length() - 1));
if ((caze.mController != null) && (caze.mController.length() != 0)) {
setAttribute(caseNode, ATTRIBUTE_HOST_CONTROLLER, caze.mController);
}
@@ -509,9 +524,9 @@
*
* @param clazz The specified ClassDoc.
*/
- TestClass(ClassDoc clazz, ExpectationStore expectationStore) {
+ TestClass(ClassDoc clazz, ExpectationStore expectationStore, String architecture) {
mName = clazz.toString();
- mCases = getTestMethods(expectationStore, clazz);
+ mCases = getTestMethods(expectationStore, architecture, clazz);
}
/**
@@ -520,7 +535,8 @@
* @param clazz The specified ClassDoc.
* @return A collection of TestMethod.
*/
- Collection<TestMethod> getTestMethods(ExpectationStore expectationStore, ClassDoc clazz) {
+ Collection<TestMethod> getTestMethods(ExpectationStore expectationStore,
+ String architecture, ClassDoc clazz) {
Collection<MethodDoc> methods = getAllMethods(clazz);
ArrayList<TestMethod> cases = new ArrayList<TestMethod>();
@@ -553,8 +569,13 @@
}
if (name.startsWith("test")) {
- cases.add(new TestMethod(name, method.commentText(), controller, knownFailure,
- isBroken, isSuppressed));
+ Expectation expectation = expectationStore.get(
+ VogarUtils.buildFullTestName(clazz.toString(), name));
+ Set<String> supportedAbis =
+ VogarUtils.extractSupportedAbis(architecture, expectation);
+ cases.add(new TestMethod(
+ name, method.commentText(), controller, supportedAbis,
+ knownFailure, isBroken, isSuppressed));
}
}
@@ -610,6 +631,7 @@
String mName;
String mDescription;
String mController;
+ Set<String> mAbis;
String mKnownFailure;
boolean mIsBroken;
boolean mIsSuppressed;
@@ -621,11 +643,12 @@
* @param description The description of the test case.
* @param knownFailure The reason of known failure.
*/
- TestMethod(String name, String description, String controller, String knownFailure,
- boolean isBroken, boolean isSuppressed) {
+ TestMethod(String name, String description, String controller, Set<String> abis,
+ String knownFailure, boolean isBroken, boolean isSuppressed) {
mName = name;
mDescription = description;
mController = controller;
+ mAbis = abis;
mKnownFailure = knownFailure;
mIsBroken = isBroken;
mIsSuppressed = isSuppressed;
diff --git a/tools/utils/VogarUtils.java b/tools/utils/VogarUtils.java
index c7070a5..5e8b944 100644
--- a/tools/utils/VogarUtils.java
+++ b/tools/utils/VogarUtils.java
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+import com.android.cts.util.AbiUtils;
+
import vogar.Expectation;
import vogar.ExpectationStore;
import vogar.ModeId;
@@ -38,12 +40,26 @@
return false;
}
+ /**
+ * @return true iff the class/name is found in the vogar known failure list and it is not
+ * a known failure that is a result of an unsupported abi.
+ */
public static boolean isVogarKnownFailure(ExpectationStore expectationStore,
final String testClassName,
final String testMethodName) {
- String fullTestName = String.format("%s#%s", testClassName, testMethodName);
- return expectationStore != null
- && expectationStore.get(fullTestName) != Expectation.SUCCESS;
+ if (expectationStore == null) {
+ return false;
+ }
+ String fullTestName = buildFullTestName(testClassName, testMethodName);
+ Expectation expectation = expectationStore.get(fullTestName);
+ if (expectation == Expectation.SUCCESS) {
+ return false;
+ }
+
+ String description = expectation.getDescription();
+ boolean foundAbi = AbiUtils.parseAbiList(description).size() > 0;
+
+ return expectation != Expectation.SUCCESS && !foundAbi;
}
public static ExpectationStore provideExpectationStore(String dir) throws IOException {
@@ -67,4 +83,49 @@
}
return expectSet;
}
+
+ /** @return the test name in the form of com.android.myclass.TestClass#testMyMethod */
+ public static String buildFullTestName(String testClass, String testMethodName) {
+ return String.format("%s#%s", testClass, testMethodName);
+ }
+
+ /**
+ * This method looks in the description field of the Vogar entry for the ABI_LIST_MARKER
+ * and returns the list of abis found there.
+ *
+ * @return The Set of supported abis parsed from the {@code expectation}'s description.
+ */
+ public static Set<String> extractSupportedAbis(String architecture, Expectation expectation) {
+ Set<String> supportedAbiSet = AbiUtils.getAbisForArch(architecture);
+ if (expectation == null || expectation.getDescription().isEmpty()) {
+ // Include all abis since there was no limitation found in the description
+ return supportedAbiSet;
+ }
+
+ // Remove any abis that are not supported for the test.
+ supportedAbiSet.removeAll(AbiUtils.parseAbiList(expectation.getDescription()));
+
+ return supportedAbiSet;
+ }
+
+ /**
+ * Determine the correct set of ABIs for the given className/testName.
+ *
+ * @return the set of ABIs that can be expected to pass for the given combination of
+ * {@code architecture}, {@code className} and {@code testName}.
+ */
+ public static Set<String> extractSupportedAbis(String architecture,
+ ExpectationStore[] expectationStores,
+ String className,
+ String testName) {
+
+ String fullTestName = VogarUtils.buildFullTestName(className, testName);
+ Set<String> supportedAbiSet = AbiUtils.getAbisForArch(architecture);
+ for (ExpectationStore expectationStore : expectationStores) {
+ Expectation expectation = expectationStore.get(fullTestName);
+ supportedAbiSet.retainAll(extractSupportedAbis(architecture, expectation));
+ }
+
+ return supportedAbiSet;
+ }
}