Merge "Revert "Revert "CTS: Tests for DISALLOW_CONFIG_VPN""" into marshmallow-cts-dev
diff --git a/apps/CtsVerifier/Android.mk b/apps/CtsVerifier/Android.mk
index 34246cc..c40d981 100644
--- a/apps/CtsVerifier/Android.mk
+++ b/apps/CtsVerifier/Android.mk
@@ -53,6 +53,32 @@
include $(BUILD_PACKAGE)
+# Build CTS verifier framework as a libary.
+
+include $(CLEAR_VARS)
+
+define java-files-in
+$(sort $(patsubst ./%,%, \
+ $(shell cd $(LOCAL_PATH) ; \
+ find -L $(1) -maxdepth 1 -name *.java -and -not -name ".*") \
+ ))
+endef
+
+LOCAL_MODULE := cts-verifier-framework
+LOCAL_AAPT_FLAGS := --auto-add-overlay --extra-packages android.support.v4
+LOCAL_SDK_VERSION := current
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+LOCAL_SRC_FILES := \
+ $(call java-files-in, src/com/android/cts/verifier) \
+ $(call java-files-in, src/com/android/cts/verifier/backup) \
+ $(call all-java-files-under, src/android) \
+ $(call all-Iaidl-files-under, src)
+
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4 \
+ compatibility-common-util-devicesidelib_v2 \
+ compatibility-device-util_v2 \
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
# opencv library
include $(CLEAR_VARS)
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index b7c54cd..a93334e 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -17,7 +17,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.cts.verifier"
- android:versionCode="5">
+ android:versionCode="5"
+ android:versionName="6.0_r2">
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="23"/>
@@ -1443,6 +1444,7 @@
<action android:name="com.android.cts.verifier.managedprovisioning.TEST_NFC_BEAM" />
<action android:name="com.android.cts.verifier.managedprovisioning.action.TEST_CROSS_PROFILE_INTENTS_DIALOG" />
<action android:name="com.android.cts.verifier.managedprovisioning.action.TEST_APP_LINKING_DIALOG" />
+ <action android:name="com.android.cts.verifier.managedprovisioning.BYOD_SET_LOCATION_AND_CHECK" />
<category android:name="android.intent.category.DEFAULT"></category>
</intent-filter>
</activity>
diff --git a/apps/CtsVerifier/res/layout/js_idle.xml b/apps/CtsVerifier/res/layout/js_idle.xml
index 4277173..5289b98 100644
--- a/apps/CtsVerifier/res/layout/js_idle.xml
+++ b/apps/CtsVerifier/res/layout/js_idle.xml
@@ -15,13 +15,6 @@
android:layout_height="wrap_content"
android:text="@string/js_test_description"
android:layout_margin="@dimen/js_padding"/>
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/js_idle_description_1"
- android:layout_margin="@dimen/js_padding"
- android:textStyle="bold"/>
-
<Button
android:id="@+id/js_idle_start_test_button"
android:layout_width="wrap_content"
@@ -30,6 +23,14 @@
android:text="@string/js_start_test_text"
android:onClick="startTest"
android:enabled="false"/>
+ <TextView
+ android:id="@+id/js_idle_continue_instruction_view"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/js_idle_continue_instruction"
+ android:layout_margin="@dimen/js_padding"
+ android:textStyle="bold"
+ android:visibility="gone"/>
<LinearLayout
android:layout_width="wrap_content"
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index ea45c40..20fa197 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -339,8 +339,7 @@
<string name="hifi_ultrasound_test_default_false_string">false</string>
<string name="hifi_ultrasound_test_mic_no_support">
Device does not support near-ultrasound recording.\n
- All new phones and tablets MUST support near-ultrasound recording.\n
- Report FAIL if this is a new device, report PASS if this is an updating device.\n</string>
+ Please report PASS.\n</string>
<string name="hifi_ultrasound_test_spkr_no_support">
Device does not support near-ultrasound playback.\n
If this is your reference device, please use a different reference device.\n</string>
@@ -360,8 +359,7 @@
If this is your reference device, please use a different reference device.\n</string>
<string name="hifi_ultrasound_speaker_test_spkr_no_support">
Device does not support near-ultrasound playback.\n
- All new phones and tablets MUST support near-ultrasound playback.\n
- Report FAIL if this is a new device, report PASS if this is an updating device.\n</string>
+ Please report PASS.\n</string>
<string name="hifi_ultrasound_speaker_test_test_side">
Please wait for the result on the reference device then report here.</string>
<string name="hifi_ultrasound_speaker_test_reference_side">
@@ -1686,6 +1684,27 @@
<string name="provisioning_button_finish">Finish</string>
<string name="provisioning_cross_profile_chooser">Choose an app to complete action</string>
+ <string name="provisioning_byod_no_gps_location_feature">No GPS feature present. Skip test.</string>
+ <string name="provisioning_byod_location_mode_enable">Enable location</string>
+ <string name="provisioning_byod_location_mode_enable_toast_location_change">Location changed</string>
+ <string name="provisioning_byod_location_mode_enable_instruction">
+ This test verifies that the location updates can be enabled for the managed profile apps.\n
+ 1. Press the go button to go to the location settings page, set the location switch enabled.\n
+ 2. Move your position a little bit, verify that location updates toast comes up.\n
+ Please wait until the location updates or timeout toast message shows up before going back to the cts-verifier tests.\n
+ 3. Go back to the cts-verifier tests using the back button, then mark the test accordingly.\n
+ </string>
+
+ <string name="provisioning_byod_location_mode_disable">Disable location</string>
+ <string name="provisioning_byod_location_mode_time_out_toast">Timeout waiting for gps location change</string>
+ <string name="provisioning_byod_location_mode_disable_instruction">
+ This test verifies that the location updates can be disabled for the managed profile apps.\n
+ 1. Press the go button to go to the location settings page, set the location switch disabled.\n
+ 2. Move your position a little bit, verify that no location updates toast come up and that the timeout message show up after around 15 seconds.
+ Please wait until the timeout or location updates toast message shows up before going back to the cts-verifier tests.\n
+ 3. Go back to the cts-verifier tests using the back button, then mark the test accordingly.\n
+ </string>
+
<!-- Strings for DeviceOwnerProvisioningTest -->
<string name="provisioning_device_owner">Device Owner Provisioning</string>
<string name="device_owner_provisioning_tests">Device Owner provisioning tests</string>
@@ -1897,6 +1916,9 @@
<string name="js_start_test_text">Start test</string>
<string name="js_idle_instructions">Verify the behaviour of the JobScheduler API for when the device is in idle mode. Simply follow the on-screen instructions.</string>
<string name="js_idle_description_1">Turn the screen off and then back on in order to begin.</string>
+ <string name="js_idle_continue_instruction">
+ Switch off screen and wait for it to turn on to continue.
+ </string>
<string name="js_idle_item_idle_off">Idle job does not execute when device is not idle.</string>
<string name="js_idle_item_idle_on">Idle job does execute when device is forced into idle.</string>
@@ -2118,6 +2140,10 @@
<string name="audio_general_headset_port_exists">Does this device have a headset port?</string>
<string name="audio_general_headset_no">No</string>
<string name="audio_general_headset_yes">Yes</string>
+ <string name="audio_general_deficiency_found">WARNING: Some results show potential deficiencies on the system.
+ Please consider addressing them for a future release.</string>
+ <string name="audio_general_test_passed">Test Successful</string>
+ <string name="audio_general_test_failed">Test Failed</string>
<!-- Audio Loopback Latency Test -->
<string name="audio_loopback_test">Audio Loopback Latency Test</string>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/DialogTestListActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/DialogTestListActivity.java
index 91b8d93..7212609 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/DialogTestListActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/DialogTestListActivity.java
@@ -98,11 +98,6 @@
*/
protected abstract void setupTests(ArrayTestListAdapter adapter);
- // Enable Pass Button when all tests passed.
- private void updatePassButton() {
- getPassButton().setEnabled(mAdapter.allTestsPassed());
- }
-
public class DefaultTestCallback implements DialogTestListItem.TestCallback {
final private DialogTestListItem mTest;
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java b/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java
index 5a08558..2c3d35d 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java
@@ -262,6 +262,10 @@
@Override
public ReportLog getReportLog() { return reportLog; }
+
+ public void updatePassButton() {
+ getPassButton().setEnabled(mAdapter.allTestsPassed());
+ }
}
private static <T extends android.app.Activity & PassFailActivity>
@@ -399,16 +403,14 @@
private static void setTestResultAndFinish(android.app.Activity activity, String testId,
String testDetails, ReportLog reportLog, View target) {
boolean passed;
- switch (target.getId()) {
- case R.id.pass_button:
- passed = true;
- break;
- case R.id.fail_button:
- passed = false;
- break;
- default:
- throw new IllegalArgumentException("Unknown id: " + target.getId());
+ if (target.getId() == R.id.pass_button) {
+ passed = true;
+ } else if (target.getId() == R.id.fail_button) {
+ passed = false;
+ } else {
+ throw new IllegalArgumentException("Unknown id: " + target.getId());
}
+
setTestResultAndFinishHelper(activity, testId, testDetails, passed, reportLog);
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/TestListActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/TestListActivity.java
index 976ff32..6a96961 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/TestListActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/TestListActivity.java
@@ -19,7 +19,9 @@
import android.Manifest;
import android.app.ListActivity;
import android.content.Intent;
+import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
@@ -33,19 +35,6 @@
/** Top-level {@link ListActivity} for launching tests and managing results. */
public class TestListActivity extends AbstractTestListActivity implements View.OnClickListener {
-
- private static final String [] RUNTIME_PERMISSIONS = {
- Manifest.permission.ACCESS_FINE_LOCATION,
- Manifest.permission.BODY_SENSORS,
- Manifest.permission.READ_EXTERNAL_STORAGE,
- Manifest.permission.READ_PHONE_STATE,
- Manifest.permission.CALL_PHONE,
- Manifest.permission.WRITE_CONTACTS,
- Manifest.permission.CAMERA,
- Manifest.permission.WRITE_EXTERNAL_STORAGE,
- Manifest.permission.RECORD_AUDIO,
- Manifest.permission.READ_CONTACTS
- };
private static final int CTS_VERIFIER_PERMISSION_REQUEST = 1;
private static final String TAG = TestListActivity.class.getSimpleName();
@@ -59,15 +48,25 @@
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- for (String runtimePermission : RUNTIME_PERMISSIONS) {
- Log.v(TAG, "Checking permissions for: " + runtimePermission);
- if (checkSelfPermission(runtimePermission) != PackageManager.PERMISSION_GRANTED) {
- requestPermissions(RUNTIME_PERMISSIONS, CTS_VERIFIER_PERMISSION_REQUEST);
- return;
- }
+ try {
+ PackageInfo packageInfo = getPackageManager().getPackageInfo(
+ getApplicationInfo().packageName, PackageManager.GET_PERMISSIONS);
+ if (packageInfo.requestedPermissions != null) {
+ for (String permission : packageInfo.requestedPermissions) {
+ Log.v(TAG, "Checking permissions for: " + permission);
+ if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
+ requestPermissions(packageInfo.requestedPermissions,
+ CTS_VERIFIER_PERMISSION_REQUEST);
+ return;
+ }
+ }
+ }
+ createContinue();
+ } catch (NameNotFoundException e) {
+ Log.e(TAG, "Unable to load package's permissions", e);
+ Toast.makeText(this, R.string.runtime_permissions_error, Toast.LENGTH_SHORT).show();
}
- createContinue();
}
private void createContinue() {
@@ -137,21 +136,16 @@
}
private boolean handleMenuItemSelected(int id) {
- switch (id) {
- case R.id.clear:
- handleClearItemSelected();
- return true;
-
- case R.id.view:
- handleViewItemSelected();
- return true;
-
- case R.id.export:
- handleExportItemSelected();
- return true;
-
- default:
- return false;
+ if (id == R.id.clear) {
+ handleClearItemSelected();
+ } else if (id == R.id.view) {
+ handleViewItemSelected();
+ } else if (id == R.id.export) {
+ handleExportItemSelected();
+ } else {
+ return false;
}
+
+ return true;
}
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyLineActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyLineActivity.java
index 508fae0..edb3bf0 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyLineActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyLineActivity.java
@@ -22,8 +22,8 @@
import com.android.compatibility.common.util.ReportLog;
import com.android.compatibility.common.util.ResultType;
import com.android.compatibility.common.util.ResultUnit;
-import android.content.Context;
+import android.content.Context;
import android.media.AudioDeviceCallback;
import android.media.AudioDeviceInfo;
import android.media.AudioFormat;
@@ -31,17 +31,13 @@
import android.media.AudioTrack;
import android.media.AudioRecord;
import android.media.MediaRecorder;
-
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
-
import android.util.Log;
-
import android.view.View;
import android.view.View.OnClickListener;
-
import android.widget.Button;
import android.widget.TextView;
import android.widget.SeekBar;
@@ -391,9 +387,15 @@
Results resultsRight = new Results("Right");
computeResultsForVector(mFreqAverage1, resultsRight);
if (resultsLeft.testAll() && resultsRight.testAll()) {
- //enable button
- getPassButton().setEnabled(true);
+ String strSuccess = getResources().getString(R.string.audio_general_test_passed);
+ appendResultsToScreen(strSuccess);
+ } else {
+ String strFailed = getResources().getString(R.string.audio_general_test_failed);
+ appendResultsToScreen(strFailed + "\n");
+ String strWarning = getResources().getString(R.string.audio_general_deficiency_found);
+ appendResultsToScreen(strWarning);
}
+ getPassButton().setEnabled(true); //Everybody passes! (for now...)
}
private void computeResultsForVector(VectorAverage freqAverage,Results results) {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencySpeakerActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencySpeakerActivity.java
index f9334b3..ba7b86d 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencySpeakerActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencySpeakerActivity.java
@@ -416,8 +416,15 @@
computeResultsForVector(mFreqAverageRight, resultsRight, false, bandSpecsArray);
if (resultsLeft.testAll() && resultsRight.testAll() && resultsBase.testAll()) {
//enable button
- getPassButton().setEnabled(true);
+ String strSuccess = getResources().getString(R.string.audio_general_test_passed);
+ appendResultsToScreen(strSuccess);
+ } else {
+ String strFailed = getResources().getString(R.string.audio_general_test_failed);
+ appendResultsToScreen(strFailed + "\n");
+ String strWarning = getResources().getString(R.string.audio_general_deficiency_found);
+ appendResultsToScreen(strWarning);
}
+ getPassButton().setEnabled(true); //Everybody passes! (for now...)
}
private void computeResultsForVector(VectorAverage freqAverage,Results results, boolean isBase,
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/Correlation.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/Correlation.java
index 75b04eb..98d1365 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/Correlation.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/Correlation.java
@@ -30,6 +30,8 @@
public double mEstimatedLatencyMs = 0;
public double mEstimatedLatencyConfidence = 0.0;
+ private double mAmplitudeThreshold = 0.001; // 0.001 = -60 dB noise
+
public void init(int blockSize, int samplingRate) {
mBlockSize = blockSize;
mSamplingRate = samplingRate;
@@ -40,7 +42,7 @@
log("Started Auto Correlation for data with " + data.length + " points");
mSamplingRate = samplingRate;
- downsampleData(data, mDataDownsampled);
+ downsampleData(data, mDataDownsampled, mAmplitudeThreshold);
//correlation vector
autocorrelation(mDataDownsampled, mDataAutocorrelated);
@@ -95,7 +97,7 @@
return status;
}
- private boolean downsampleData(double [] data, double [] dataDownsampled) {
+ private boolean downsampleData(double [] data, double [] dataDownsampled, double threshold) {
boolean status = false;
// mDataDownsampled = new double[mBlockSize];
@@ -106,6 +108,8 @@
int N = data.length; //all samples available
double groupSize = (double) N / mBlockSize;
+ int ignored = 0;
+
int currentIndex = 0;
double nextGroup = groupSize;
for (int i = 0; i<N && currentIndex<mBlockSize; i++) {
@@ -118,9 +122,18 @@
if (currentIndex>=mBlockSize) {
break;
}
- dataDownsampled[currentIndex] += Math.abs(data[i]);
+
+ double value = Math.abs(data[i]);
+ if (value >= threshold) {
+ dataDownsampled[currentIndex] += value;
+ } else {
+ ignored++;
+ }
}
+ log(String.format(" Threshold: %.3f, ignored:%d/%d (%%.2f)", threshold, ignored, N,
+ (double) ignored/(double)N));
+
status = true;
return status;
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/deskclock/DeskClockTestsActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/deskclock/DeskClockTestsActivity.java
index fcd88d1..aaea279 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/deskclock/DeskClockTestsActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/deskclock/DeskClockTestsActivity.java
@@ -165,13 +165,6 @@
}
}
- /**
- * Enable Pass Button when the all tests passed.
- */
- private void updatePassButton() {
- getPassButton().setEnabled(mAdapter.allTestsPassed());
- }
-
public static class DeskClockIntentFactory implements IntentFactory {
@Override
public Intent[] createIntents(String testId, int buttonText) {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/jobscheduler/IdleConstraintTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/jobscheduler/IdleConstraintTestActivity.java
index a8bd993..05c1a2e 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/jobscheduler/IdleConstraintTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/jobscheduler/IdleConstraintTestActivity.java
@@ -26,15 +26,17 @@
import android.content.IntentFilter;
import android.os.AsyncTask;
import android.os.Bundle;
+import android.os.PowerManager;
import android.util.Log;
+import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
+import android.widget.TextView;
/**
* Idle constraints:
- * The framework doesn't support turning idle mode off. Use the manual tester to ensure that
- * the device is not in idle mode (by turning the screen off and then back on) before running
- * the tests.
+ * The framework doesn't support turning the screen off. Use the manual tester to
+ * turn off the screen to run to run tests that require idle mode to be on.
*/
@TargetApi(21)
public class IdleConstraintTestActivity extends ConstraintTestActivity {
@@ -57,22 +59,35 @@
*/
private static final int IDLE_ON_JOB_ID = IdleConstraintTestActivity.class.hashCode() + 1;
+ private static final int IDLE_ON_TEST_STATE_NOT_IN_PROGRESS = 0;
+ private static final int IDLE_ON_TEST_STATE_WAITING_FOR_SCREEN_OFF = 1;
+
/**
- * Listens for idle mode off/on events, namely {@link #ACTION_EXPEDITE_IDLE_MODE} and
- * {@link Intent#ACTION_SCREEN_ON}.
- * On ACTION_EXPEDITE_IDLE_MODE, we will disable the {@link #mStartButton}, and on
- * ACTION_SCREEN_ON we enable it. This is to avoid the start button being clicked when the
- * device is in idle mode.
+ * mTestState stores the state of the tests. It is used to ensure that we only run
+ * the 'idle on' test if screen is turned off after the user has started tests.
*/
- private BroadcastReceiver mIdleChangedReceiver = new BroadcastReceiver() {
+ private int mTestState = IDLE_ON_TEST_STATE_NOT_IN_PROGRESS;
+
+ private PowerManager mPowerManager;
+ private TextView mContinueInstructionTextView;
+
+ /**
+ * Listens for screen off event. Starts an async task to force device into
+ * idle mode and run the 'idle on' test.
+ */
+ private BroadcastReceiver mScreenOffReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- if (Intent.ACTION_SCREEN_ON.equals(intent.getAction())) {
- mStartButton.setEnabled(true);
- } else if (ACTION_EXPEDITE_IDLE_MODE.equals(intent.getAction())) {
- mStartButton.setEnabled(false);
+ if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) {
+ if (mTestState == IDLE_ON_TEST_STATE_WAITING_FOR_SCREEN_OFF) {
+ mContinueInstructionTextView.setVisibility(View.GONE);
+ PowerManager.WakeLock wl = mPowerManager.newWakeLock(
+ PowerManager.PARTIAL_WAKE_LOCK, TAG);
+ wl.acquire();
+ new TestIdleModeTaskIdle().execute(wl);
+ }
} else {
- Log.e(TAG, "Invalid broadcast received, was expecting SCREEN_ON");
+ Log.e(TAG, "Invalid broadcast received, was expecting SCREEN_OFF");
}
}
};
@@ -86,47 +101,88 @@
setPassFailButtonClickListeners();
setInfoResources(R.string.js_idle_test, R.string.js_idle_instructions, -1);
mStartButton = (Button) findViewById(R.id.js_idle_start_test_button);
+ mContinueInstructionTextView = (TextView) findViewById(
+ R.id.js_idle_continue_instruction_view);
- // Register receiver for idle off/on events.
+ // Register receiver for screen off event.
IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction(Intent.ACTION_SCREEN_ON);
- intentFilter.addAction(ACTION_EXPEDITE_IDLE_MODE);
+ intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
- registerReceiver(mIdleChangedReceiver, intentFilter);
+ mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
+
+ registerReceiver(mScreenOffReceiver, intentFilter);
+
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ // Enable start button only if tests are not in progress.
+ if (mTestState == IDLE_ON_TEST_STATE_NOT_IN_PROGRESS) {
+ mStartButton.setEnabled(true);
+ mContinueInstructionTextView.setVisibility(View.GONE);
+ }
}
@Override
protected void onDestroy() {
super.onDestroy();
- unregisterReceiver(mIdleChangedReceiver);
+ unregisterReceiver(mScreenOffReceiver);
}
@Override
protected void startTestImpl() {
- new TestIdleModeTask().execute();
+ mStartButton.setEnabled(false);
+ new TestIdleModeTaskNotIdle().execute();
}
- /** Background task that will run the actual test. */
- private class TestIdleModeTask extends AsyncTask<Void, Void, Void> {
-
+ /** Background task that will run the 'not idle' test. */
+ private class TestIdleModeTaskNotIdle extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... voids) {
testIdleConstraintFails_notIdle();
+ return null;
+ }
+ @Override
+ protected void onPostExecute(Void result) {
+ mTestState = IDLE_ON_TEST_STATE_WAITING_FOR_SCREEN_OFF;
+ mContinueInstructionTextView.setVisibility(View.VISIBLE);
+ }
+ }
- // Send the {@link #ACTION_EXPEDITE_IDLE_MODE} broadcast as an ordered broadcast, this
- // function will block until all receivers have processed the broadcast.
+ /** Background task that will run the 'idle' test. */
+ private class TestIdleModeTaskIdle extends AsyncTask<PowerManager.WakeLock, Void, Void> {
+
+ private PowerManager.WakeLock mPartialWakeLock;
+
+ @Override
+ protected Void doInBackground(PowerManager.WakeLock... wakeLocks) {
+ mPartialWakeLock = wakeLocks[0];
+
if (!sendBroadcastAndBlockForResult(new Intent(ACTION_EXPEDITE_IDLE_MODE))) {
- // Fail the test if the broadcast wasn't processed.
runOnUiThread(new IdleTestResultRunner(IDLE_ON_JOB_ID, false));
+ } else {
+ testIdleConstraintExecutes_onIdle();
}
-
- testIdleConstraintExecutes_onIdle();
-
notifyTestCompleted();
return null;
}
+ @Override
+ protected void onPostExecute(Void result) {
+ // Reset test state
+ mTestState = IDLE_ON_TEST_STATE_NOT_IN_PROGRESS;
+
+ PowerManager.WakeLock fullWakeLock = mPowerManager.newWakeLock(
+ PowerManager.FULL_WAKE_LOCK
+ | PowerManager.ACQUIRE_CAUSES_WAKEUP
+ | PowerManager.ON_AFTER_RELEASE, TAG);
+ // Turn on screen and release both locks
+ fullWakeLock.acquire();
+ fullWakeLock.release();
+ mPartialWakeLock.release();
+ }
}
/**
@@ -154,6 +210,10 @@
runOnUiThread(new IdleTestResultRunner(IDLE_OFF_JOB_ID, testPassed));
}
+ /**
+ * Called after screen is switched off and device is forced into idle mode.
+ * Schedule a job with an idle constraint and verify that it executes.
+ */
private void testIdleConstraintExecutes_onIdle() {
mTestEnvironment.setUp();
mJobScheduler.cancelAll();
@@ -172,6 +232,7 @@
// We'll just indicate that it failed, not why.
testPassed = false;
}
+
runOnUiThread(new IdleTestResultRunner(IDLE_ON_JOB_ID, testPassed));
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
index b129665..2df6407d 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
@@ -82,6 +82,8 @@
private TestListItem mKeyguardDisabledFeaturesTest;
private DialogTestListItem mDisableNfcBeamTest;
private TestListItem mAuthenticationBoundKeyTest;
+ private DialogTestListItem mEnableLocationModeTest;
+ private DialogTestListItem mDisableLocationModeTest;
public ByodFlowTestActivity() {
super(R.layout.provisioning_byod,
@@ -347,6 +349,9 @@
adapter.add(mKeyguardDisabledFeaturesTest);
adapter.add(mAuthenticationBoundKeyTest);
+ /* If there is an application that handles ACTION_IMAGE_CAPTURE, test that it handles it
+ * well.
+ */
if (canResolveIntent(ByodHelperActivity.getCaptureImageIntent())) {
// Capture image intent can be resolved in primary profile, so test.
mCrossProfileImageCaptureSupportTest = new DialogTestListItem(this,
@@ -362,6 +367,9 @@
.show();
}
+ /* If there is an application that handles ACTION_VIDEO_CAPTURE, test that it handles it
+ * well.
+ */
if (canResolveIntent(ByodHelperActivity.getCaptureVideoIntent())) {
// Capture video intent can be resolved in primary profile, so test.
mCrossProfileVideoCaptureSupportTest = new DialogTestListItem(this,
@@ -409,7 +417,9 @@
adapter.add(mDisableNfcBeamTest);
}
- /* TODO: reinstate when bug b/20131958 is fixed
+ /* If there is an application that handles RECORD_SOUND_ACTION, test that it handles it
+ * well.
+ */
if (canResolveIntent(ByodHelperActivity.getCaptureAudioIntent())) {
// Capture audio intent can be resolved in primary profile, so test.
mCrossProfileAudioCaptureSupportTest = new DialogTestListItem(this,
@@ -424,7 +434,27 @@
R.string.provisioning_byod_no_audio_capture_resolver, Toast.LENGTH_SHORT)
.show();
}
- */
+
+ if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_LOCATION_GPS)) {
+ mEnableLocationModeTest = new DialogTestListItem(this,
+ R.string.provisioning_byod_location_mode_enable,
+ "BYOD_LocationModeEnableTest",
+ R.string.provisioning_byod_location_mode_enable_instruction,
+ new Intent(ByodHelperActivity.ACTION_SET_LOCATION_AND_CHECK_UPDATES));
+ mDisableLocationModeTest = new DialogTestListItem(this,
+ R.string.provisioning_byod_location_mode_disable,
+ "BYOD_LocationModeDisableTest",
+ R.string.provisioning_byod_location_mode_disable_instruction,
+ new Intent(ByodHelperActivity.ACTION_SET_LOCATION_AND_CHECK_UPDATES));
+
+ adapter.add(mEnableLocationModeTest);
+ adapter.add(mDisableLocationModeTest);
+ } else {
+ // The system does not support GPS feature, so skip test.
+ Toast.makeText(ByodFlowTestActivity.this,
+ R.string.provisioning_byod_no_gps_location_feature, Toast.LENGTH_SHORT)
+ .show();
+ }
}
// Return whether the intent can be resolved in the current profile
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java
index 9ea5061..bfac469 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java
@@ -25,8 +25,13 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
+import android.location.Location;
+import android.location.LocationListener;
+import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
import android.os.UserManager;
import android.provider.MediaStore;
import android.provider.Settings;
@@ -51,7 +56,7 @@
*
* Note: We have to use a dummy activity because cross-profile intents only work for activities.
*/
-public class ByodHelperActivity extends Activity implements DialogCallback {
+public class ByodHelperActivity extends Activity implements DialogCallback, Handler.Callback {
static final String TAG = "ByodHelperActivity";
// Primary -> managed intent: query if the profile owner has been set up.
@@ -97,18 +102,30 @@
public static final String ACTION_TEST_APP_LINKING_DIALOG =
"com.android.cts.verifier.managedprovisioning.action.TEST_APP_LINKING_DIALOG";
+ // Primary -> managed intent: request to goto the location settings page and listen to updates.
+ public static final String ACTION_SET_LOCATION_AND_CHECK_UPDATES =
+ "com.android.cts.verifier.managedprovisioning.BYOD_SET_LOCATION_AND_CHECK";
+
public static final int RESULT_FAILED = RESULT_FIRST_USER;
private static final int REQUEST_INSTALL_PACKAGE = 1;
private static final int REQUEST_IMAGE_CAPTURE = 2;
private static final int REQUEST_VIDEO_CAPTURE = 3;
private static final int REQUEST_AUDIO_CAPTURE = 4;
+ private static final int REQUEST_LOCATION_UPDATE = 5;
private static final String ORIGINAL_SETTINGS_NAME = "original settings";
private Bundle mOriginalSettings;
+ private static final int MSG_TIMEOUT = 1;
+
+ private static final long MSG_TIMEOUT_MILLISEC = 15 * 1000;
+
private ComponentName mAdminReceiverComponent;
private DevicePolicyManager mDevicePolicyManager;
+ private LocationManager mLocationManager;
+ private Handler mHandler;
+ private boolean mIsLocationUpdated;
private Uri mImageUri;
private Uri mVideoUri;
@@ -128,6 +145,9 @@
mAdminReceiverComponent = new ComponentName(this, DeviceAdminTestReceiver.class.getName());
mDevicePolicyManager = (DevicePolicyManager) getSystemService(
Context.DEVICE_POLICY_SERVICE);
+ mLocationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
+ mHandler = new Handler(this);
+ mIsLocationUpdated = false;
Intent intent = getIntent();
String action = intent.getAction();
Log.d(TAG, "ByodHelperActivity.onCreate: " + action);
@@ -234,6 +254,22 @@
Intent toSend = new Intent(Intent.ACTION_VIEW);
toSend.setData(Uri.parse("http://com.android.cts.verifier"));
sendIntentInsideChooser(toSend);
+ } else if (action.equals(ACTION_SET_LOCATION_AND_CHECK_UPDATES)) {
+ // Grant the locaiton permission to the provile owner on cts-verifier.
+ // The permission state does not have to be reverted at the end since the profile onwer
+ // is going to be deleted when BYOD tests ends.
+ grantLocationPermissionToSelf();
+ Intent locationSettingsIntent = getLocationSettingsIntent();
+ if (locationSettingsIntent.resolveActivity(getPackageManager()) != null) {
+ startActivityForResult(locationSettingsIntent, REQUEST_LOCATION_UPDATE);
+ scheduleTimeout();
+ } else {
+ Log.e(TAG, "BYOD settings could not be resolved in managed profile");
+ finish();
+ }
+ mLocationManager.requestLocationUpdates(
+ LocationManager.GPS_PROVIDER, 0, 0, mLocationListener);
+ return;
}
// This activity has no UI and is only used to respond to CtsVerifier in the primary side.
finish();
@@ -289,6 +325,13 @@
}
break;
}
+ case REQUEST_LOCATION_UPDATE: {
+ Log.d(TAG, "BYOD exit location settings:OK");
+ mLocationManager.removeUpdates(mLocationListener);
+ mHandler.removeMessages(MSG_TIMEOUT);
+ finish();
+ break;
+ }
default: {
Log.wtf(TAG, "Unknown requestCode " + requestCode + "; data = " + data);
break;
@@ -314,6 +357,10 @@
return new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
}
+ public static Intent getLocationSettingsIntent() {
+ return new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
+ }
+
public static Intent createLockIntent() {
return new Intent(ACTION_LOCKNOW);
}
@@ -376,8 +423,49 @@
startActivity(chooser);
}
+ private void grantLocationPermissionToSelf() {
+ mDevicePolicyManager.setPermissionGrantState(mAdminReceiverComponent, getPackageName(),
+ android.Manifest.permission.ACCESS_FINE_LOCATION,
+ DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED);
+ }
+
+ private final LocationListener mLocationListener = new LocationListener() {
+ @Override
+ public void onLocationChanged(Location location) {
+ if (mIsLocationUpdated) return;
+ showToast(R.string.provisioning_byod_location_mode_enable_toast_location_change);
+ mIsLocationUpdated = true;
+ }
+
+ @Override
+ public void onProviderDisabled(String provider) {
+ }
+
+ @Override
+ public void onProviderEnabled(String provider) {
+ }
+
+ @Override
+ public void onStatusChanged(String provider, int status, Bundle extras) {
+ }
+ };
+
+ private void scheduleTimeout() {
+ mHandler.removeMessages(MSG_TIMEOUT);
+ mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_TIMEOUT), MSG_TIMEOUT_MILLISEC);
+ }
+
@Override
public void onDialogClose() {
finish();
}
+
+ @Override
+ public boolean handleMessage(Message msg) {
+ if (msg.what == MSG_TIMEOUT) {
+ if (mIsLocationUpdated) return true;
+ showToast(R.string.provisioning_byod_location_mode_time_out_toast);
+ }
+ return true;
+ }
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java
index ed6b5eb..db3c58c 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java
@@ -22,6 +22,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.provider.Settings;
import android.util.Log;
/**
@@ -75,6 +76,7 @@
filter.addAction(
PermissionLockdownTestActivity.ACTION_MANAGED_PROFILE_CHECK_PERMISSION_LOCKDOWN);
filter.addAction(AuthenticationBoundKeyTestActivity.ACTION_AUTH_BOUND_KEY_TEST);
+ filter.addAction(ByodHelperActivity.ACTION_SET_LOCATION_AND_CHECK_UPDATES);
dpm.addCrossProfileIntentFilter(getWho(context), filter,
DevicePolicyManager.FLAG_MANAGED_CAN_ACCESS_PARENT);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerNegativeTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerNegativeTestActivity.java
index c7e785c..3c0955d 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerNegativeTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerNegativeTestActivity.java
@@ -81,12 +81,5 @@
setTestListAdapter(adapter);
}
-
- /**
- * Enable Pass Button when the all tests passed.
- */
- private void updatePassButton() {
- getPassButton().setEnabled(mAdapter.allTestsPassed());
- }
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
index 2a411f8..72361c1 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
@@ -126,13 +126,6 @@
super.finish();
}
- /**
- * Enable Pass Button when all tests passed.
- */
- private void updatePassButton() {
- getPassButton().setEnabled(mAdapter.allTestsPassed());
- }
-
private void addTestsToAdapter(final ArrayTestListAdapter adapter) {
adapter.add(createTestItem(this, CHECK_DEVICE_OWNER_TEST_ID,
R.string.device_owner_check_device_owner_test,
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/WifiLockdownTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/WifiLockdownTestActivity.java
index 4a292eb..3babb8f 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/WifiLockdownTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/WifiLockdownTestActivity.java
@@ -126,13 +126,6 @@
});
}
- /**
- * Enable Pass Button when all tests passed.
- */
- private void updatePassButton() {
- getPassButton().setEnabled(mAdapter.allTestsPassed());
- }
-
private void addTestsToAdapter(final ArrayTestListAdapter adapter) {
adapter.add(DeviceOwnerPositiveTestActivity.createInteractiveTestItem(this,
CONFIG_MODIFIABLE_WHEN_UNLOCKED_TEST_ID,
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/p2p/P2pTestListActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/p2p/P2pTestListActivity.java
index 920c9ae..5985be6 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/p2p/P2pTestListActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/p2p/P2pTestListActivity.java
@@ -153,13 +153,6 @@
}
/**
- * Enable Pass Button when the all tests passed.
- */
- private void updatePassButton() {
- getPassButton().setEnabled(mAdapter.allTestsPassed());
- }
-
- /**
* Receive the WIFI_P2P_STATE_CHANGED_ACTION action.
*/
class P2pBroadcastReceiver extends BroadcastReceiver {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/p2p/RequesterTestListActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/p2p/RequesterTestListActivity.java
index e6f94af..dd53d33 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/p2p/RequesterTestListActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/p2p/RequesterTestListActivity.java
@@ -103,11 +103,4 @@
adapter.add(TestListItem.newTest(testcase.getTestName(), testcase.getTestId(),
intent, null));
}
-
- /**
- * Enable Pass Button when the all tests passed.
- */
- private void updatePassButton() {
- getPassButton().setEnabled(mAdapter.allTestsPassed());
- }
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/streamquality/StreamingVideoActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/streamquality/StreamingVideoActivity.java
index 9684d97..9370ca8 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/streamquality/StreamingVideoActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/streamquality/StreamingVideoActivity.java
@@ -220,10 +220,6 @@
i, null));
}
- private void updatePassButton() {
- getPassButton().setEnabled(mAdapter.allTestsPassed());
- }
-
/** @returns the appropriate RTSP url, or null in case of failure */
private String lookupRtspUrl(int itag, String signature) {
String rtspLookupUri = String.format(RTSP_LOOKUP_URI_TEMPLATE, itag, signature);
diff --git a/build/test_host_java_library.mk b/build/test_host_java_library.mk
index 7fdefb5..b4c7e63 100644
--- a/build/test_host_java_library.mk
+++ b/build/test_host_java_library.mk
@@ -29,6 +29,11 @@
cts_src_dirs := $(addprefix -s , $(cts_src_dirs))
cts_library_xml := $(CTS_TESTCASES_OUT)/$(LOCAL_MODULE).xml
+ifeq ($(cts_runtime_hint),)
+$(cts_library_xml): PRIVATE_CTS_RUNTIME_HINT := "0"
+else
+$(cts_library_xml): PRIVATE_CTS_RUNTIME_HINT := $(cts_runtime_hint)
+endif
$(cts_library_xml): PRIVATE_SRC_DIRS := $(cts_src_dirs)
$(cts_library_xml): PRIVATE_TEST_PACKAGE := $(LOCAL_CTS_TEST_PACKAGE)
$(cts_library_xml): PRIVATE_LIBRARY := $(LOCAL_MODULE)
@@ -44,6 +49,7 @@
-j $(PRIVATE_JAR_PATH) \
-n $(PRIVATE_LIBRARY) \
-p $(PRIVATE_TEST_PACKAGE) \
+ -x "runtimeHint->$(PRIVATE_CTS_RUNTIME_HINT)" \
-e $(CTS_EXPECTATIONS) \
-b $(CTS_UNSUPPORTED_ABIS) \
-a $(CTS_TARGET_ARCH) \
diff --git a/hostsidetests/devicepolicy/Android.mk b/hostsidetests/devicepolicy/Android.mk
index 6708c3d..dc5e117 100644
--- a/hostsidetests/devicepolicy/Android.mk
+++ b/hostsidetests/devicepolicy/Android.mk
@@ -26,6 +26,8 @@
LOCAL_CTS_TEST_PACKAGE := android.adminhostside
+cts_runtime_hint := 70
+
include $(BUILD_CTS_HOST_JAVA_LIBRARY)
# Build the test APKs using their own makefiles
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/KeyManagementTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/KeyManagementTest.java
old mode 100644
new mode 100755
index 5774b0c..27fd36f
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/KeyManagementTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/KeyManagementTest.java
@@ -47,7 +47,7 @@
public class KeyManagementTest extends
ActivityInstrumentationTestCase2<KeyManagementActivity> {
- private static final int KEYCHAIN_TIMEOUT_MS = 8000;
+ private static final int KEYCHAIN_TIMEOUT_MS = 6 * 60 * 1000;
private DevicePolicyManager mDevicePolicyManager;
public KeyManagementTest() {
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
index 214131f..6dc47e6 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
@@ -205,13 +205,9 @@
// Now there's only the browser in the managed profile left
assertAppLinkResult("testReceivedByBrowserActivityInManaged");
- changeVerificationStatus(USER_OWNER, INTENT_RECEIVER_PKG, "always");
- changeVerificationStatus(mUserId, INTENT_RECEIVER_PKG, "ask");
- // We've set the receiver in the primary user to always: only this one should receive the
- // intent.
- assertAppLinkResult("testReceivedByAppLinkActivityInPrimary");
changeVerificationStatus(mUserId, INTENT_RECEIVER_PKG, "always");
+ changeVerificationStatus(USER_OWNER, INTENT_RECEIVER_PKG, "always");
// We have one always in the primary user and one always in the managed profile: the managed
// profile one should have precedence.
assertAppLinkResult("testReceivedByAppLinkActivityInManaged");
diff --git a/suite/cts/deviceTests/tvproviderperf/src/com/android/cts/tvproviderperf/TvProviderPerfTest.java b/suite/cts/deviceTests/tvproviderperf/src/com/android/cts/tvproviderperf/TvProviderPerfTest.java
index f9daa3c..8eef86d 100644
--- a/suite/cts/deviceTests/tvproviderperf/src/com/android/cts/tvproviderperf/TvProviderPerfTest.java
+++ b/suite/cts/deviceTests/tvproviderperf/src/com/android/cts/tvproviderperf/TvProviderPerfTest.java
@@ -157,12 +157,12 @@
// Query a channel
try (final Cursor cursor = mContentResolver.query(Channels.CONTENT_URI,
projection, null, null, null)) {
- final Uri channelUri = TvContract.buildChannelUri(cursor.getLong(0));
applyBatchTimes = MeasureTime.measure(QUERY_RUNS, new MeasureRun() {
@Override
public void run(int i) {
assertTrue(cursor.moveToNext());
- try (Cursor c = mContentResolver.query(channelUri, null, null, null, null)) {
+ try (Cursor c = mContentResolver.query(TvContract.buildChannelUri(
+ cursor.getLong(0)), null, null, null, null)) {
while (c.moveToNext()) {
// Do nothing. Just iterate all the items.
}
@@ -321,12 +321,12 @@
// Query a program
try (final Cursor cursor = mContentResolver.query(Programs.CONTENT_URI,
projection, null, null, null)) {
- final Uri programUri = TvContract.buildProgramUri(cursor.getLong(0));
applyBatchTimes = MeasureTime.measure(QUERY_RUNS, new MeasureRun() {
@Override
public void run(int i) {
assertTrue(cursor.moveToNext());
- try (Cursor c = mContentResolver.query(programUri, null, null, null, null)) {
+ try (Cursor c = mContentResolver.query(TvContract.buildProgramUri(
+ cursor.getLong(0)), null, null, null, null)) {
while (c.moveToNext()) {
// Do nothing. Just iterate all the items.
}
diff --git a/tests/expectations/knownfailures.txt b/tests/expectations/knownfailures.txt
index 01f64b5..385c055 100644
--- a/tests/expectations/knownfailures.txt
+++ b/tests/expectations/knownfailures.txt
@@ -361,5 +361,19 @@
"android.permission2.cts.ProtectedBroadcastsTest#testSendProtectedBroadcasts"
],
bug: 23192492
+},
+{
+ description: "restricted network is not working",
+ names: [
+ "android.net.cts.ConnectivityManagerTest#testRestrictedNetworks"
+ ],
+ bug: 25651805
+},
+{
+ description: "Read from invalid parcel not working",
+ names: [
+ "android.view.cts.MotionEventTest#testReadFromParcelWithInvalidSampleSize"
+ ],
+ bug: 25652250
}
]
diff --git a/tests/tests/app/src/android/app/cts/ActivityManagerMemoryClassTest.java b/tests/tests/app/src/android/app/cts/ActivityManagerMemoryClassTest.java
index c8ef253..639741d 100644
--- a/tests/tests/app/src/android/app/cts/ActivityManagerMemoryClassTest.java
+++ b/tests/tests/app/src/android/app/cts/ActivityManagerMemoryClassTest.java
@@ -71,8 +71,8 @@
expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_TV, 48);
expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_HIGH, 48);
expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_280, 48);
- expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_XHIGH, 48);
- expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_360, 64);
+ expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_XHIGH, 80);
+ expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_360, 80);
expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_400, 96);
expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_420, 112);
expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_XXHIGH, 128);
diff --git a/tests/tests/assist/src/android/assist/cts/AssistStructureTest.java b/tests/tests/assist/src/android/assist/cts/AssistStructureTest.java
index 4c1b1f3..c21bc9c 100644
--- a/tests/tests/assist/src/android/assist/cts/AssistStructureTest.java
+++ b/tests/tests/assist/src/android/assist/cts/AssistStructureTest.java
@@ -80,6 +80,10 @@
}
public void testAssistStructure() throws Exception {
+ if (mActivityManager.isLowRamDevice()) {
+ Log.d(TAG, "Not running assist tests on low-RAM device.");
+ return;
+ }
mTestActivity.start3pApp(TEST_CASE_TYPE);
mTestActivity.startTest(TEST_CASE_TYPE);
waitForAssistantToBeReady(mReadyLatch);
diff --git a/tests/tests/assist/src/android/assist/cts/AssistTestBase.java b/tests/tests/assist/src/android/assist/cts/AssistTestBase.java
index 46fb8d9..29b35c5 100644
--- a/tests/tests/assist/src/android/assist/cts/AssistTestBase.java
+++ b/tests/tests/assist/src/android/assist/cts/AssistTestBase.java
@@ -19,6 +19,7 @@
import android.assist.cts.TestStartActivity;
import android.assist.common.Utils;
+import android.app.ActivityManager;
import android.app.assist.AssistContent;
import android.app.assist.AssistStructure;
import android.app.assist.AssistStructure.ViewNode;
@@ -57,6 +58,7 @@
public class AssistTestBase extends ActivityInstrumentationTestCase2<TestStartActivity> {
private static final String TAG = "AssistTestBase";
+ protected ActivityManager mActivityManager;
protected TestStartActivity mTestActivity;
protected AssistContent mAssistContent;
protected AssistStructure mAssistStructure;
@@ -123,6 +125,7 @@
intent.putExtra(Utils.TESTCASE_TYPE, testName);
setActivityIntent(intent);
mTestActivity = getActivity();
+ mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
}
/**
diff --git a/tests/tests/assist/src/android/assist/cts/AssistantContentViewTest.java b/tests/tests/assist/src/android/assist/cts/AssistantContentViewTest.java
index 557134b..c6ac3a6 100644
--- a/tests/tests/assist/src/android/assist/cts/AssistantContentViewTest.java
+++ b/tests/tests/assist/src/android/assist/cts/AssistantContentViewTest.java
@@ -83,6 +83,10 @@
}
public void testAssistantContentViewDimens() throws Exception {
+ if (mActivityManager.isLowRamDevice()) {
+ Log.d(TAG, "Not running assist tests on low-RAM device.");
+ return;
+ }
mTestActivity.startTest(Utils.VERIFY_CONTENT_VIEW);
waitForAssistantToBeReady(mReadyLatch);
startSession();
diff --git a/tests/tests/assist/src/android/assist/cts/DisableContextTest.java b/tests/tests/assist/src/android/assist/cts/DisableContextTest.java
index 5c8aa19..ea4cd3d 100644
--- a/tests/tests/assist/src/android/assist/cts/DisableContextTest.java
+++ b/tests/tests/assist/src/android/assist/cts/DisableContextTest.java
@@ -63,6 +63,10 @@
}
public void testContextAndScreenshotOff() throws Exception {
+ if (mActivityManager.isLowRamDevice()) {
+ Log.d(TAG, "Not running assist tests on low-RAM device.");
+ return;
+ }
// Both settings off
Log.i(TAG, "DisableContext: Screenshot OFF, Context OFF");
SystemUtil.runShellCommand(getInstrumentation(),
diff --git a/tests/tests/assist/src/android/assist/cts/ExtraAssistDataTest.java b/tests/tests/assist/src/android/assist/cts/ExtraAssistDataTest.java
index 28b2af2..1154179 100644
--- a/tests/tests/assist/src/android/assist/cts/ExtraAssistDataTest.java
+++ b/tests/tests/assist/src/android/assist/cts/ExtraAssistDataTest.java
@@ -66,6 +66,10 @@
}
public void testAssistContentAndAssistData() throws Exception {
+ if (mActivityManager.isLowRamDevice()) {
+ Log.d(TAG, "Not running assist tests on low-RAM device.");
+ return;
+ }
mTestActivity.startTest(TEST_CASE_TYPE);
waitForAssistantToBeReady(mReadyLatch);
mTestActivity.start3pApp(TEST_CASE_TYPE);
diff --git a/tests/tests/assist/src/android/assist/cts/FlagSecureTest.java b/tests/tests/assist/src/android/assist/cts/FlagSecureTest.java
index 35f95a4..fc7c8fb3 100644
--- a/tests/tests/assist/src/android/assist/cts/FlagSecureTest.java
+++ b/tests/tests/assist/src/android/assist/cts/FlagSecureTest.java
@@ -77,6 +77,10 @@
}
public void testSecureActivity() throws Exception {
+ if (mActivityManager.isLowRamDevice()) {
+ Log.d(TAG, "Not running assist tests on low-RAM device.");
+ return;
+ }
mTestActivity.startTest(TEST_CASE_TYPE);
waitForAssistantToBeReady(mReadyLatch);
mTestActivity.start3pApp(TEST_CASE_TYPE);
diff --git a/tests/tests/assist/src/android/assist/cts/FocusChangeTest.java b/tests/tests/assist/src/android/assist/cts/FocusChangeTest.java
index f6b90b9..621361e 100644
--- a/tests/tests/assist/src/android/assist/cts/FocusChangeTest.java
+++ b/tests/tests/assist/src/android/assist/cts/FocusChangeTest.java
@@ -86,6 +86,10 @@
}
public void testLayerCausesUnderlyingActivityToLoseFocus() throws Exception {
+ if (mActivityManager.isLowRamDevice()) {
+ Log.d(TAG, "Not running assist tests on low-RAM device.");
+ return;
+ }
mTestActivity.startTest(Utils.FOCUS_CHANGE);
waitForAssistantToBeReady(mReadyLatch);
mTestActivity.start3pApp(Utils.FOCUS_CHANGE);
diff --git a/tests/tests/assist/src/android/assist/cts/LargeViewHierarchyTest.java b/tests/tests/assist/src/android/assist/cts/LargeViewHierarchyTest.java
index bc2ab80..25f36b7 100644
--- a/tests/tests/assist/src/android/assist/cts/LargeViewHierarchyTest.java
+++ b/tests/tests/assist/src/android/assist/cts/LargeViewHierarchyTest.java
@@ -79,6 +79,10 @@
}
public void testTextView() throws Exception {
+ if (mActivityManager.isLowRamDevice()) {
+ Log.d(TAG, "Not running assist tests on low-RAM device.");
+ return;
+ }
mTestActivity.start3pApp(TEST_CASE_TYPE);
mTestActivity.startTest(TEST_CASE_TYPE);
waitForAssistantToBeReady(mReadyLatch);
@@ -102,4 +106,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/tests/tests/assist/src/android/assist/cts/LifecycleTest.java b/tests/tests/assist/src/android/assist/cts/LifecycleTest.java
index c886b74..3ed26d1 100644
--- a/tests/tests/assist/src/android/assist/cts/LifecycleTest.java
+++ b/tests/tests/assist/src/android/assist/cts/LifecycleTest.java
@@ -98,6 +98,10 @@
}
public void testLayerDoesNotTriggerLifecycleMethods() throws Exception {
+ if (mActivityManager.isLowRamDevice()) {
+ Log.d(TAG, "Not running assist tests on low-RAM device.");
+ return;
+ }
mTestActivity.startTest(Utils.LIFECYCLE);
waitForAssistantToBeReady(mReadyLatch);
mTestActivity.start3pApp(Utils.LIFECYCLE);
diff --git a/tests/tests/assist/src/android/assist/cts/ScreenshotTest.java b/tests/tests/assist/src/android/assist/cts/ScreenshotTest.java
index 45082ae..b84e334 100644
--- a/tests/tests/assist/src/android/assist/cts/ScreenshotTest.java
+++ b/tests/tests/assist/src/android/assist/cts/ScreenshotTest.java
@@ -70,6 +70,10 @@
}
public void testRedScreenshot() throws Exception {
+ if (mActivityManager.isLowRamDevice()) {
+ Log.d(TAG, "Not running assist tests on low-RAM device.");
+ return;
+ }
Log.i(TAG, "Starting screenshot test");
mTestActivity.startTest(TEST_CASE_TYPE);
Log.i(TAG, "start waitForAssistantToBeReady()");
@@ -81,6 +85,10 @@
}
public void testGreenScreenshot() throws Exception {
+ if (mActivityManager.isLowRamDevice()) {
+ Log.d(TAG, "Not running assist tests on low-RAM device.");
+ return;
+ }
Log.i(TAG, "Starting screenshot test");
mTestActivity.startTest(TEST_CASE_TYPE);
Log.i(TAG, "start waitForAssistantToBeReady()");
@@ -92,6 +100,10 @@
}
public void testBlueScreenshot() throws Exception {
+ if (mActivityManager.isLowRamDevice()) {
+ Log.d(TAG, "Not running assist tests on low-RAM device.");
+ return;
+ }
Log.i(TAG, "Starting screenshot test");
mTestActivity.startTest(TEST_CASE_TYPE);
Log.i(TAG, "start waitForAssistantToBeReady()");
diff --git a/tests/tests/assist/src/android/assist/cts/TextViewTest.java b/tests/tests/assist/src/android/assist/cts/TextViewTest.java
index e4390bc..089993d 100644
--- a/tests/tests/assist/src/android/assist/cts/TextViewTest.java
+++ b/tests/tests/assist/src/android/assist/cts/TextViewTest.java
@@ -79,6 +79,10 @@
}
public void testTextView() throws Exception {
+ if (mActivityManager.isLowRamDevice()) {
+ Log.d(TAG, "Not running assist tests on low-RAM device.");
+ return;
+ }
mTestActivity.start3pApp(TEST_CASE_TYPE);
scrollTestApp(0, 0, true, false);
@@ -130,4 +134,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/tests/tests/assist/src/android/assist/cts/WebViewTest.java b/tests/tests/assist/src/android/assist/cts/WebViewTest.java
index e367e22..4e05494 100644
--- a/tests/tests/assist/src/android/assist/cts/WebViewTest.java
+++ b/tests/tests/assist/src/android/assist/cts/WebViewTest.java
@@ -90,6 +90,10 @@
}
public void testWebView() throws Exception {
+ if (mActivityManager.isLowRamDevice()) {
+ Log.d(TAG, "Not running assist tests on low-RAM device.");
+ return;
+ }
if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {
return;
}
@@ -118,4 +122,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/tests/tests/content/src/android/content/cts/ContextWrapperTest.java b/tests/tests/content/src/android/content/cts/ContextWrapperTest.java
index 672d3ed..edc9538 100644
--- a/tests/tests/content/src/android/content/cts/ContextWrapperTest.java
+++ b/tests/tests/content/src/android/content/cts/ContextWrapperTest.java
@@ -157,6 +157,7 @@
registerBroadcastReceiver(lowPriorityReceiver, filterLowPriority);
final Intent broadcastIntent = new Intent(ResultReceiver.MOCK_ACTION);
+ broadcastIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
mContextWrapper.sendOrderedBroadcast(broadcastIntent, null);
new PollingCheck(BROADCAST_TIMEOUT) {
@Override
@@ -186,8 +187,10 @@
Bundle bundle = new Bundle();
bundle.putString(KEY_KEPT, VALUE_KEPT);
bundle.putString(KEY_REMOVED, VALUE_REMOVED);
- mContextWrapper.sendOrderedBroadcast(new Intent(ResultReceiver.MOCK_ACTION),
- null, broadcastReceiver, null, 1, INTIAL_RESULT, bundle);
+ Intent intent = new Intent(ResultReceiver.MOCK_ACTION);
+ intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+ mContextWrapper.sendOrderedBroadcast(intent, null, broadcastReceiver, null, 1,
+ INTIAL_RESULT, bundle);
synchronized (mLockObj) {
try {
@@ -216,13 +219,13 @@
// Test unwanted intent(action = MOCK_ACTION2)
broadcastReceiver.reset();
- waitForFilteredIntent(mContextWrapper, broadcastReceiver, MOCK_ACTION2);
+ waitForFilteredIntent(mContextWrapper, MOCK_ACTION2);
assertFalse(broadcastReceiver.hadReceivedBroadCast1());
assertFalse(broadcastReceiver.hadReceivedBroadCast2());
// Send wanted intent(action = MOCK_ACTION1)
broadcastReceiver.reset();
- waitForFilteredIntent(mContextWrapper, broadcastReceiver, MOCK_ACTION1);
+ waitForFilteredIntent(mContextWrapper, MOCK_ACTION1);
assertTrue(broadcastReceiver.hadReceivedBroadCast1());
assertFalse(broadcastReceiver.hadReceivedBroadCast2());
@@ -235,13 +238,13 @@
// Test unwanted intent(action = MOCK_ACTION2)
broadcastReceiver2.reset();
- waitForFilteredIntent(mContextWrapper, broadcastReceiver2, MOCK_ACTION2);
+ waitForFilteredIntent(mContextWrapper, MOCK_ACTION2);
assertFalse(broadcastReceiver2.hadReceivedBroadCast1());
assertFalse(broadcastReceiver2.hadReceivedBroadCast2());
// Send wanted intent(action = MOCK_ACTION1), but the receiver is unregistered.
broadcastReceiver2.reset();
- waitForFilteredIntent(mContextWrapper, broadcastReceiver2, MOCK_ACTION1);
+ waitForFilteredIntent(mContextWrapper, MOCK_ACTION1);
assertFalse(broadcastReceiver2.hadReceivedBroadCast1());
assertFalse(broadcastReceiver2.hadReceivedBroadCast2());
}
@@ -256,13 +259,13 @@
// Test unwanted intent(action = MOCK_ACTION2)
broadcastReceiver.reset();
- waitForFilteredIntent(mContextWrapper, broadcastReceiver, MOCK_ACTION2);
+ waitForFilteredIntent(mContextWrapper, MOCK_ACTION2);
assertFalse(broadcastReceiver.hadReceivedBroadCast1());
assertFalse(broadcastReceiver.hadReceivedBroadCast2());
// Send wanted intent(action = MOCK_ACTION1)
broadcastReceiver.reset();
- waitForFilteredIntent(mContextWrapper, broadcastReceiver, MOCK_ACTION1);
+ waitForFilteredIntent(mContextWrapper, MOCK_ACTION1);
assertTrue(broadcastReceiver.hadReceivedBroadCast1());
assertFalse(broadcastReceiver.hadReceivedBroadCast2());
@@ -792,9 +795,9 @@
waitForCondition(con);
}
- private void waitForFilteredIntent(ContextWrapper contextWrapper,
- final FilteredReceiver receiver, final String action) throws InterruptedException {
- contextWrapper.sendOrderedBroadcast(new Intent(action), null);
+ private void waitForFilteredIntent(ContextWrapper contextWrapper, final String action)
+ throws InterruptedException {
+ contextWrapper.sendBroadcast(new Intent(action), null);
synchronized (mLockObj) {
mLockObj.wait(BROADCAST_TIMEOUT);
@@ -849,7 +852,6 @@
private class FilteredReceiver extends BroadcastReceiver {
private boolean mHadReceivedBroadCast1 = false;
-
private boolean mHadReceivedBroadCast2 = false;
public void onReceive(Context context, Intent intent) {
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/AllocationTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/AllocationTest.java
index 229185d..0476477 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/AllocationTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/AllocationTest.java
@@ -97,7 +97,6 @@
assertNotNull("Can't connect to camera manager!", mCameraManager);
RenderScriptSingleton.setContext(context);
- // TODO: call clearContext
}
@Override
@@ -117,11 +116,7 @@
@Override
protected void tearDown() throws Exception {
MaybeNull.close(mCamera);
-
- // TODO: Clean up RenderScript context in a static test run finished method.
- // Or alternatively count the # of test methods that are in this test,
- // once we reach that count, it's time to call the last tear down
-
+ RenderScriptSingleton.clearContext();
mHandlerThread.quitSafely();
mHandler = null;
super.tearDown();
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/CameraManagerTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/CameraManagerTest.java
index 77a0c8e..67c08fe 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/CameraManagerTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/CameraManagerTest.java
@@ -149,7 +149,8 @@
assertNotNull("Can't get lens facing info", lensFacing);
if (lensFacing == CameraCharacteristics.LENS_FACING_FRONT) {
assertTrue("System doesn't have front camera feature",
- mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT));
+ mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT) ||
+ mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_EXTERNAL));
} else if (lensFacing == CameraCharacteristics.LENS_FACING_BACK) {
assertTrue("System doesn't have back camera feature",
mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA));
@@ -534,7 +535,7 @@
java.util.concurrent.TimeUnit.MILLISECONDS);
assertTrue(String.format("Received unavailability notice for wrong ID " +
"(expected %s, got %s)", id, candidateId),
- id == candidateId);
+ id.equals(candidateId));
assertTrue("Availability events received unexpectedly",
availableEventQueue.size() == 0);
@@ -549,7 +550,7 @@
java.util.concurrent.TimeUnit.MILLISECONDS);
assertTrue(String.format("Received availability notice for wrong ID " +
"(expected %s, got %s)", id, candidateId),
- id == candidateId);
+ id.equals(candidateId));
assertTrue("Unavailability events received unexpectedly",
unavailableEventQueue.size() == 0);
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/DngCreatorTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/DngCreatorTest.java
index 0da0ce7..bddbd52 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/DngCreatorTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/DngCreatorTest.java
@@ -75,6 +75,8 @@
@Override
protected void tearDown() throws Exception {
+ RenderScriptSingleton.clearContext();
+
super.tearDown();
}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/ImageReaderTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/ImageReaderTest.java
index f1115c4..9c783e0 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/ImageReaderTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/ImageReaderTest.java
@@ -41,8 +41,11 @@
import android.util.Size;
import android.view.Surface;
+import com.android.ex.camera2.blocking.BlockingSessionCallback;
+
import java.nio.ByteBuffer;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import static android.hardware.camera2.cts.CameraTestUtils.CAPTURE_RESULT_TIMEOUT_MS;
@@ -275,6 +278,8 @@
* resolution and format supported.
*/
public void testAllOutputYUVResolutions() throws Exception {
+ Integer[] sessionStates = {BlockingSessionCallback.SESSION_READY,
+ BlockingSessionCallback.SESSION_CONFIGURE_FAILED};
for (String id : mCameraIds) {
try {
Log.v(TAG, "Testing all YUV image resolutions for camera " + id);
@@ -309,6 +314,7 @@
", at least one JPEG output is required.", jpegSizes.length == 0);
Size maxJpegSize = CameraTestUtils.getMaxSize(jpegSizes);
+ Size maxPreviewSize = mOrderedPreviewSizes.get(0);
for (int format : supportedYUVFormats) {
Size[] targetCaptureSizes =
@@ -343,6 +349,27 @@
outputSurfaces.add(jpegSurface);
createSession(outputSurfaces);
+ int state = mCameraSessionListener.getStateWaiter().waitForAnyOfStates(
+ Arrays.asList(sessionStates),
+ CameraTestUtils.SESSION_CONFIGURE_TIMEOUT_MS);
+
+ if (state == BlockingSessionCallback.SESSION_CONFIGURE_FAILED) {
+ if (captureSz.getWidth() > maxPreviewSize.getWidth() ||
+ captureSz.getHeight() > maxPreviewSize.getHeight()) {
+ Log.v(TAG, "Skip testing {yuv:" + captureSz
+ + " ,jpeg:" + maxJpegSize + "} for camera "
+ + mCamera.getId() +
+ " because full size jpeg + yuv larger than "
+ + "max preview size (" + maxPreviewSize
+ + ") is not supported");
+ continue;
+ } else {
+ fail("Camera " + mCamera.getId() +
+ ":session configuration failed for {jpeg: " +
+ maxJpegSize + ", yuv: " + captureSz + "}");
+ }
+ }
+
// Warm up camera preview (mainly to give legacy devices time to do 3A).
CaptureRequest.Builder warmupRequest =
mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/rs/RenderScriptSingleton.java b/tests/tests/hardware/src/android/hardware/camera2/cts/rs/RenderScriptSingleton.java
index 8e4c8e9..211dd0d 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/rs/RenderScriptSingleton.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/rs/RenderScriptSingleton.java
@@ -70,7 +70,7 @@
sCache.close();
sCache = null;
- sRS.destroy();
+ sRS.releaseAllContexts();
sRS = null;
sContext = null;
}
diff --git a/tests/tests/hardware/src/android/hardware/cts/SensorBatchingFifoTest.java b/tests/tests/hardware/src/android/hardware/cts/SensorBatchingFifoTest.java
index 4c6362a..328b5cd 100644
--- a/tests/tests/hardware/src/android/hardware/cts/SensorBatchingFifoTest.java
+++ b/tests/tests/hardware/src/android/hardware/cts/SensorBatchingFifoTest.java
@@ -114,7 +114,7 @@
sensor,
false,
sensor.getMinDelay(),
- Integer.MAX_VALUE);
+ Integer.MAX_VALUE /*maxReportLatencyUs*/);
TestSensorOperation op = TestSensorOperation.createOperation(environment,
sensor.getFifoReservedEventCount() * 2);
diff --git a/tests/tests/hardware/src/android/hardware/cts/SensorTest.java b/tests/tests/hardware/src/android/hardware/cts/SensorTest.java
index cffafdc..2bbf053 100644
--- a/tests/tests/hardware/src/android/hardware/cts/SensorTest.java
+++ b/tests/tests/hardware/src/android/hardware/cts/SensorTest.java
@@ -168,8 +168,8 @@
}
sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
- // orientation sensor is required if the device can physically implement it
- if (hasCompass && hasAccelerometer) {
+ // Note: orientation sensor is deprecated.
+ if (sensor != null) {
assertEquals(Sensor.TYPE_ORIENTATION, sensor.getType());
assertSensorValues(sensor);
}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventGapVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventGapVerification.java
index 76f1594..c64810b 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventGapVerification.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventGapVerification.java
@@ -28,15 +28,16 @@
// Number of events to truncate (discard) from the initial events received
private static final int TRUNCATE_EVENTS_COUNT = 1;
- // Number of event gaps to tolerate is the minimum of 1% of total events received or 10.
- private static final int EVENT_GAP_TOLERANCE_COUNT = 10;
- private static final double EVENT_GAP_TOLERANCE_PERCENT = 0.01;
+ // Number of event gaps to tolerate is 2% of total number of events received rounded up to next
+ // integer or 20, whichever is smaller.
+ private static final int EVENT_GAP_THRESHOLD_MAX = 20;
+ private static final double EVENT_GAP_TOLERANCE = 0.02;
private final int mExpectedDelayUs;
private final List<IndexedEventPair> mEventGaps = new LinkedList<IndexedEventPair>();
private TestSensorEvent mPreviousEvent = null;
- private int mIndex = 0;
+ private int mEventCount = 0;
/**
* Construct a {@link EventGapVerification}
@@ -72,14 +73,16 @@
}
final int count = mEventGaps.size();
- // Ensure that eventGapTolerance is at least 1.
- int eventGapTolerance = (int)Math.max(1, Math.min(EVENT_GAP_TOLERANCE_COUNT,
- EVENT_GAP_TOLERANCE_PERCENT * mIndex));
- stats.addValue(PASSED_KEY, count <= eventGapTolerance);
+ // Ensure the threshold is rounded up.
+ double eventGapThreshold =
+ Math.ceil(Math.min(EVENT_GAP_THRESHOLD_MAX, mEventCount * EVENT_GAP_TOLERANCE));
+ boolean pass = count <= eventGapThreshold;
+
+ stats.addValue(PASSED_KEY, pass);
stats.addValue(SensorStats.EVENT_GAP_COUNT_KEY, count);
stats.addValue(SensorStats.EVENT_GAP_POSITIONS_KEY, getIndexArray(mEventGaps));
- if (count > eventGapTolerance) {
+ if (!pass) {
StringBuilder sb = new StringBuilder();
sb.append(count).append(" events gaps: ");
for (int i = 0; i < Math.min(count, TRUNCATE_MESSAGE_LENGTH); i++) {
@@ -109,16 +112,16 @@
*/
@Override
protected void addSensorEventInternal(TestSensorEvent event) {
- if (mIndex >= TRUNCATE_EVENTS_COUNT) {
+ if (mEventCount >= TRUNCATE_EVENTS_COUNT) {
if (mPreviousEvent != null) {
long deltaNs = event.timestamp - mPreviousEvent.timestamp;
long deltaUs = TimeUnit.MICROSECONDS.convert(deltaNs, TimeUnit.NANOSECONDS);
if (deltaUs > mExpectedDelayUs * THRESHOLD) {
- mEventGaps.add(new IndexedEventPair(mIndex, event, mPreviousEvent));
+ mEventGaps.add(new IndexedEventPair(mEventCount, event, mPreviousEvent));
}
}
mPreviousEvent = event;
}
- mIndex++;
+ mEventCount++;
}
}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/FifoLengthVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/FifoLengthVerification.java
index 09bbdc8..51811a7 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/FifoLengthVerification.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/FifoLengthVerification.java
@@ -105,7 +105,7 @@
// Any event that arrives within before 0.5*expectedReportLatency is considered
// to be in the same batch of events, else it is considered as the beginning of a new
// batch.
- if (timestampDiff < 0.5 * mExpectedReportLatencyUs/1000) {
+ if (timestampDiff < mExpectedReportLatencyUs/1000/2) {
batchCount++;
} else {
endofbatch = true;
diff --git a/tests/tests/keystore/src/android/keystore/cts/BlockCipherTestBase.java b/tests/tests/keystore/src/android/keystore/cts/BlockCipherTestBase.java
index 197adc2..66e8093 100644
--- a/tests/tests/keystore/src/android/keystore/cts/BlockCipherTestBase.java
+++ b/tests/tests/keystore/src/android/keystore/cts/BlockCipherTestBase.java
@@ -30,6 +30,7 @@
import java.security.Key;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
import java.security.Provider;
import java.security.SecureRandom;
import java.security.Security;
@@ -50,6 +51,8 @@
abstract class BlockCipherTestBase extends AndroidTestCase {
+ private static final String EXPECTED_PROVIDER_NAME = TestUtils.EXPECTED_CRYPTO_OP_PROVIDER_NAME;
+
private KeyStore mAndroidKeyStore;
private int mNextKeyId;
@@ -121,7 +124,7 @@
public void testGetProvider() throws Exception {
createCipher();
- Provider expectedProvider = Security.getProvider("AndroidKeyStoreBCWorkaround");
+ Provider expectedProvider = Security.getProvider(EXPECTED_PROVIDER_NAME);
assertSame(expectedProvider, mCipher.getProvider());
}
@@ -1247,8 +1250,8 @@
}
protected void createCipher() throws NoSuchAlgorithmException,
- NoSuchPaddingException {
- mCipher = Cipher.getInstance(getTransformation());
+ NoSuchPaddingException, NoSuchProviderException {
+ mCipher = Cipher.getInstance(getTransformation(), EXPECTED_PROVIDER_NAME);
}
private String getKeyAlgorithm() {
diff --git a/tests/tests/media/res/raw/video_176x144_mp4_mpeg4_300kbps_25fps_aac_stereo_128kbps_44100hz.mp4 b/tests/tests/media/res/raw/video_176x144_mp4_mpeg4_300kbps_25fps_aac_stereo_128kbps_44100hz.mp4
new file mode 100644
index 0000000..6b6040f
--- /dev/null
+++ b/tests/tests/media/res/raw/video_176x144_mp4_mpeg4_300kbps_25fps_aac_stereo_128kbps_44100hz.mp4
Binary files differ
diff --git a/tests/tests/media/src/android/media/cts/CodecState.java b/tests/tests/media/src/android/media/cts/CodecState.java
index 6fdbd86..de0bdf8 100644
--- a/tests/tests/media/src/android/media/cts/CodecState.java
+++ b/tests/tests/media/src/android/media/cts/CodecState.java
@@ -220,8 +220,12 @@
mSawInputEOS = true;
// FIX-ME: in tunneled mode we currently use input EOS as output EOS indicator
// we should stream duration
- if (mTunneled && !mIsAudio) {
- mSawOutputEOS = true;
+ if (mTunneled) {
+ if (!mIsAudio) {
+ mSawOutputEOS = true;
+ } else if (mAudioTrack != null) {
+ mAudioTrack.stop();
+ }
}
return false;
}
@@ -260,6 +264,10 @@
index, 0 /* offset */, 0 /* sampleSize */,
0 /* sampleTime */, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
+ if (mTunneled && mAudioTrack != null) {
+ mAudioTrack.stop();
+ }
+
mAvailableInputBufferIndices.removeFirst();
}
@@ -271,7 +279,9 @@
// b/9250789
Log.d(TAG, "CodecState::onOutputFormatChanged " + mime);
+ mIsAudio = false;
if (mime.startsWith("audio/")) {
+ mIsAudio = true;
int sampleRate =
mOutputFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE);
@@ -315,6 +325,9 @@
mSawOutputEOS = true;
+ if (mAudioTrack != null && !mTunneled) {
+ mAudioTrack.stop();
+ }
return false;
}
diff --git a/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java b/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java
index 7c4d1fb..b875719 100644
--- a/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java
+++ b/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java
@@ -575,7 +575,8 @@
ByteBuffer[] encoderOutputBuffers = encoder.getOutputBuffers();
ByteBuffer[] decoderInputBuffers = null;
ByteBuffer[] decoderOutputBuffers = null;
- MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
+ MediaCodec.BufferInfo decoderInfo = new MediaCodec.BufferInfo();
+ MediaCodec.BufferInfo encoderInfo = new MediaCodec.BufferInfo();
MediaFormat decoderOutputFormat = null;
int generateIndex = 0;
int checkIndex = 0;
@@ -614,9 +615,11 @@
boolean inputDone = false;
boolean encoderDone = false;
boolean outputDone = false;
+ int encoderStatus = -1;
while (!outputDone) {
if (VERBOSE) Log.d(TAG, "loop");
+
// If we're not done submitting frames, generate a new one and submit it. By
// doing this on every loop we're working to ensure that the encoder always has
// work to do.
@@ -662,7 +665,10 @@
//
// Once we get EOS from the encoder, we don't need to do this anymore.
if (!encoderDone) {
- int encoderStatus = encoder.dequeueOutputBuffer(info, TIMEOUT_USEC);
+ MediaCodec.BufferInfo info = encoderInfo;
+ if (encoderStatus < 0) {
+ encoderStatus = encoder.dequeueOutputBuffer(info, TIMEOUT_USEC);
+ }
if (encoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) {
// no output available yet
if (VERBOSE) Log.d(TAG, "no output from encoder available");
@@ -686,18 +692,7 @@
encodedData.position(info.offset);
encodedData.limit(info.offset + info.size);
- encodedSize += info.size;
- if (outputStream != null) {
- byte[] data = new byte[info.size];
- encodedData.get(data);
- encodedData.position(info.offset);
- try {
- outputStream.write(data);
- } catch (IOException ioe) {
- Log.w(TAG, "failed writing debug data to file");
- throw new RuntimeException(ioe);
- }
- }
+ boolean releaseBuffer = false;
if (!decoderConfigured) {
// Codec config info. Only expected on first packet. One way to
// handle this is to manually stuff the data into the MediaFormat
@@ -719,21 +714,41 @@
if (VERBOSE) Log.d(TAG, "decoder configured (" + info.size + " bytes)");
}
if ((info.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) == 0) {
- // Get a decoder input buffer, blocking until it's available.
+ // Get a decoder input buffer
assertTrue(decoderConfigured);
- int inputBufIndex = decoder.dequeueInputBuffer(-1);
- ByteBuffer inputBuf = decoderInputBuffers[inputBufIndex];
- inputBuf.clear();
- inputBuf.put(encodedData);
- decoder.queueInputBuffer(inputBufIndex, 0, info.size,
- info.presentationTimeUs, info.flags);
+ int inputBufIndex = decoder.dequeueInputBuffer(TIMEOUT_USEC);
+ if (inputBufIndex >= 0) {
+ ByteBuffer inputBuf = decoderInputBuffers[inputBufIndex];
+ inputBuf.clear();
+ inputBuf.put(encodedData);
+ decoder.queueInputBuffer(inputBufIndex, 0, info.size,
+ info.presentationTimeUs, info.flags);
- encoderDone = (info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0;
- if (VERBOSE) Log.d(TAG, "passed " + info.size + " bytes to decoder"
- + (encoderDone ? " (EOS)" : ""));
+ encoderDone = (info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0;
+ if (VERBOSE) Log.d(TAG, "passed " + info.size + " bytes to decoder"
+ + (encoderDone ? " (EOS)" : ""));
+ releaseBuffer = true;
+ }
+ } else {
+ releaseBuffer = true;
+ }
+ if (releaseBuffer) {
+ encodedSize += info.size;
+ if (outputStream != null) {
+ byte[] data = new byte[info.size];
+ encodedData.position(info.offset);
+ encodedData.get(data);
+ try {
+ outputStream.write(data);
+ } catch (IOException ioe) {
+ Log.w(TAG, "failed writing debug data to file");
+ throw new RuntimeException(ioe);
+ }
+ }
+ encoder.releaseOutputBuffer(encoderStatus, false);
+ encoderStatus = -1;
}
- encoder.releaseOutputBuffer(encoderStatus, false);
}
}
@@ -744,6 +759,7 @@
// If we're decoding to a Surface, we'll get notified here as usual but the
// ByteBuffer references will be null. The data is sent to Surface instead.
if (decoderConfigured) {
+ MediaCodec.BufferInfo info = decoderInfo;
int decoderStatus = decoder.dequeueOutputBuffer(info, TIMEOUT_USEC);
if (decoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) {
// no output available yet
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecCencPlayer.java b/tests/tests/media/src/android/media/cts/MediaCodecCencPlayer.java
index 2473078..f5856ed 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecCencPlayer.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecCencPlayer.java
@@ -54,7 +54,7 @@
private boolean mEncryptedAudio;
private boolean mEncryptedVideo;
- private boolean mThreadStarted = false;
+ private volatile boolean mThreadStarted = false;
private byte[] mSessionId;
private CodecState mAudioTrackState;
private int mMediaFormatHeight;
@@ -304,7 +304,7 @@
CodecState state;
if (isVideo) {
state = new CodecState((MediaTimeProvider)this, mVideoExtractor,
- trackIndex, format, codec, true, false,
+ trackIndex, format, codec, true, false,
AudioManager.AUDIO_SESSION_ID_GENERATE);
mVideoCodecStates.put(Integer.valueOf(trackIndex), state);
} else {
diff --git a/tests/tests/media/src/android/media/cts/NonBlockingAudioTrack.java b/tests/tests/media/src/android/media/cts/NonBlockingAudioTrack.java
index 3847252..4a4e807 100644
--- a/tests/tests/media/src/android/media/cts/NonBlockingAudioTrack.java
+++ b/tests/tests/media/src/android/media/cts/NonBlockingAudioTrack.java
@@ -43,6 +43,7 @@
private int mSampleRate;
private int mNumBytesQueued = 0;
private LinkedList<QueueElement> mQueue = new LinkedList<QueueElement>();
+ private boolean mStopped;
public NonBlockingAudioTrack(int sampleRate, int channelCount, boolean hwAvSync,
int audioSessionId) {
@@ -107,14 +108,17 @@
}
public void play() {
+ mStopped = false;
mAudioTrack.play();
}
public void stop() {
- mAudioTrack.stop();
-
- mQueue.clear();
- mNumBytesQueued = 0;
+ if (mQueue.isEmpty()) {
+ mAudioTrack.stop();
+ mNumBytesQueued = 0;
+ } else {
+ mStopped = true;
+ }
}
public void pause() {
@@ -128,6 +132,7 @@
mAudioTrack.flush();
mQueue.clear();
mNumBytesQueued = 0;
+ mStopped = false;
}
public void release() {
@@ -135,6 +140,7 @@
mNumBytesQueued = 0;
mAudioTrack.release();
mAudioTrack = null;
+ mStopped = false;
}
public void process() {
@@ -153,6 +159,11 @@
}
mQueue.removeFirst();
}
+ if (mStopped) {
+ mAudioTrack.stop();
+ mNumBytesQueued = 0;
+ mStopped = false;
+ }
}
public int getPlayState() {
diff --git a/tests/tests/media/src/android/media/cts/VideoDecoderPerfTest.java b/tests/tests/media/src/android/media/cts/VideoDecoderPerfTest.java
index f5680f6..8797b9b 100644
--- a/tests/tests/media/src/android/media/cts/VideoDecoderPerfTest.java
+++ b/tests/tests/media/src/android/media/cts/VideoDecoderPerfTest.java
@@ -61,6 +61,7 @@
private MediaFormat mDecOutputFormat;
private double[] mMeasuredFps;
private String[] mResultRawData;
+ private boolean mVerifyResults;
private Resources mResources;
private DeviceReportLog mReportLog;
@@ -68,6 +69,7 @@
@Override
protected void setUp() throws Exception {
super.setUp();
+ mVerifyResults = true;
mResources = mContext.getResources();
mReportLog = new DeviceReportLog();
}
@@ -298,6 +300,10 @@
mResultRawData[round] = result;
}
+ if (!mVerifyResults) {
+ return true;
+ }
+
return MediaUtils.verifyResults(name, mime, w, h, fps);
}
@@ -541,6 +547,20 @@
352, 288, true /* isGoog */);
}
+ public void testMPEG40176x0144Other() throws Exception {
+ mVerifyResults = false;
+ decode(VIDEO_MPEG4,
+ R.raw.video_176x144_mp4_mpeg4_300kbps_25fps_aac_stereo_128kbps_44100hz,
+ 176, 144, false /* isGoog */);
+ }
+
+ public void testMPEG40176x0144Goog() throws Exception {
+ mVerifyResults = false;
+ decode(VIDEO_MPEG4,
+ R.raw.video_176x144_mp4_mpeg4_300kbps_25fps_aac_stereo_128kbps_44100hz,
+ 176, 144, true /* isGoog */);
+ }
+
public void testMPEG40480x0360Other() throws Exception {
decode(VIDEO_MPEG4,
R.raw.video_480x360_mp4_mpeg4_860kbps_25fps_aac_stereo_128kbps_44100hz,
diff --git a/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
index 152789c..4478bd4 100644
--- a/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
@@ -21,6 +21,8 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.location.LocationManager;
import android.net.NetworkInfo;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
@@ -29,6 +31,7 @@
import android.net.wifi.WifiManager.TxPacketCountListener;
import android.net.wifi.WifiManager.WifiLock;
import android.os.SystemClock;
+import android.provider.Settings;
import android.test.AndroidTestCase;
import android.util.Log;
@@ -278,6 +281,14 @@
Log.d(TAG, "Skipping test as WiFi is not supported");
return;
}
+ if (!hasLocationFeature()) {
+ Log.d(TAG, "Skipping test as location is not supported");
+ return;
+ }
+ if (!isLocationEnabled()) {
+ fail("Please enable location for this test - since Marshmallow WiFi scan results are"
+ + " empty when location is disabled!");
+ }
if (!mWifiManager.isWifiEnabled()) {
setWifiEnabled(true);
}
@@ -307,6 +318,18 @@
}
}
+ // Return true if location is enabled.
+ private boolean isLocationEnabled() {
+ return Settings.Secure.getInt(getContext().getContentResolver(),
+ Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF) !=
+ Settings.Secure.LOCATION_MODE_OFF;
+ }
+
+ // Returns true if the device has location feature.
+ private boolean hasLocationFeature() {
+ return getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_LOCATION);
+ }
+
/**
* test point of wifiManager NetWork:
* 1.add NetWork
diff --git a/tests/tests/os/jni/seccomp-tests/README.android b/tests/tests/os/jni/seccomp-tests/README.android
index 4c5bb83..8b1ac9a 100644
--- a/tests/tests/os/jni/seccomp-tests/README.android
+++ b/tests/tests/os/jni/seccomp-tests/README.android
@@ -11,3 +11,7 @@
- Add get_seccomp_test_list()
The diff of modifications can be found in local-modifications-android.diff.
+
+Additional modification is to backport fixes for Android Native Bridge:
+https://patchwork.kernel.org/patch/7537891/. This is not found in the above
+diff file. The patch is located in local-modifications-strict-args-fd88d16.diff.
diff --git a/tests/tests/os/jni/seccomp-tests/local-modifications-strict-args-fd88d16.diff b/tests/tests/os/jni/seccomp-tests/local-modifications-strict-args-fd88d16.diff
new file mode 100644
index 0000000..a289147
--- /dev/null
+++ b/tests/tests/os/jni/seccomp-tests/local-modifications-strict-args-fd88d16.diff
@@ -0,0 +1,102 @@
+diff --git a/tests/tests/os/jni/seccomp-tests/tests/seccomp_bpf_tests.c b/tests/tests/os/jni/seccomp-tests/tests/seccomp_bpf_tests.c
+index 98b0231..3c238e6 100644
+--- a/tests/tests/os/jni/seccomp-tests/tests/seccomp_bpf_tests.c
++++ b/tests/tests/os/jni/seccomp-tests/tests/seccomp_bpf_tests.c
+@@ -28,6 +28,9 @@
+ #include <string.h>
+ #include <linux/elf.h>
+ #include <sys/uio.h>
++#include <fcntl.h> // ANDROID
++#include <sys/mman.h>
++#include <sys/times.h>
+
+ #define _GNU_SOURCE
+ #include <unistd.h>
+@@ -386,14 +389,16 @@ TEST_SIGNAL(KILL_one, SIGSYS) {
+ }
+
+ TEST_SIGNAL(KILL_one_arg_one, SIGSYS) {
++ void *fatal_address;
+ struct sock_filter filter[] = {
+ BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
+ offsetof(struct seccomp_data, nr)),
+- BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 1, 0),
++ BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_times, 1, 0),
+ BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+ /* Only both with lower 32-bit for now. */
+ BPF_STMT(BPF_LD|BPF_W|BPF_ABS, syscall_arg(0)),
+- BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 0x0C0FFEE, 0, 1),
++ BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K,
++ (unsigned long)&fatal_address, 0, 1),
+ BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL),
+ BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+ };
+@@ -403,23 +408,29 @@ TEST_SIGNAL(KILL_one_arg_one, SIGSYS) {
+ };
+ long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+ pid_t parent = getppid();
+- pid_t pid = getpid();
++ struct tms timebuf;
++ clock_t clock = times(&timebuf);
+ ASSERT_EQ(0, ret);
+
+ ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
+ ASSERT_EQ(0, ret);
+
+ EXPECT_EQ(parent, syscall(__NR_getppid));
+- EXPECT_EQ(pid, syscall(__NR_getpid));
+- /* getpid() should never return. */
+- EXPECT_EQ(0, syscall(__NR_getpid, 0x0C0FFEE));
++ EXPECT_LE(clock, syscall(__NR_times, &timebuf));
++ /* times() should never return. */
++ EXPECT_EQ(0, syscall(__NR_times, &fatal_address));
+ }
+
+ TEST_SIGNAL(KILL_one_arg_six, SIGSYS) {
++#ifndef __NR_mmap2
++ int sysno = __NR_mmap;
++#else
++ int sysno = __NR_mmap2;
++#endif
+ struct sock_filter filter[] = {
+ BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
+ offsetof(struct seccomp_data, nr)),
+- BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 1, 0),
++ BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, sysno, 1, 0),
+ BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+ /* Only both with lower 32-bit for now. */
+ BPF_STMT(BPF_LD|BPF_W|BPF_ABS, syscall_arg(5)),
+@@ -433,16 +444,29 @@ TEST_SIGNAL(KILL_one_arg_six, SIGSYS) {
+ };
+ long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+ pid_t parent = getppid();
+- pid_t pid = getpid();
++ int fd;
++ void *map1, *map2;
+ ASSERT_EQ(0, ret);
+
+ ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
+ ASSERT_EQ(0, ret);
+
++ fd = open("/dev/zero", O_RDONLY);
++ ASSERT_NE(-1, fd);
++
+ EXPECT_EQ(parent, syscall(__NR_getppid));
+- EXPECT_EQ(pid, syscall(__NR_getpid));
+- /* getpid() should never return. */
+- EXPECT_EQ(0, syscall(__NR_getpid, 1, 2, 3, 4, 5, 0x0C0FFEE));
++ map1 = (void *)syscall(sysno,
++ NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, fd, PAGE_SIZE);
++ EXPECT_NE(MAP_FAILED, map1);
++ /* mmap2() should never return. */
++ map2 = (void *)syscall(sysno,
++ NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, fd, 0x0C0FFEE);
++ EXPECT_EQ(MAP_FAILED, map2);
++
++ /* The test failed, so clean up the resources. */
++ munmap(map1, PAGE_SIZE);
++ munmap(map2, PAGE_SIZE);
++ close(fd);
+ }
+
+ /* TODO(wad) add 64-bit versus 32-bit arg tests. */
diff --git a/tests/tests/os/jni/seccomp-tests/tests/seccomp_bpf_tests.c b/tests/tests/os/jni/seccomp-tests/tests/seccomp_bpf_tests.c
index 98b0231..3c238e6 100644
--- a/tests/tests/os/jni/seccomp-tests/tests/seccomp_bpf_tests.c
+++ b/tests/tests/os/jni/seccomp-tests/tests/seccomp_bpf_tests.c
@@ -28,6 +28,9 @@
#include <string.h>
#include <linux/elf.h>
#include <sys/uio.h>
+#include <fcntl.h> // ANDROID
+#include <sys/mman.h>
+#include <sys/times.h>
#define _GNU_SOURCE
#include <unistd.h>
@@ -386,14 +389,16 @@
}
TEST_SIGNAL(KILL_one_arg_one, SIGSYS) {
+ void *fatal_address;
struct sock_filter filter[] = {
BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
offsetof(struct seccomp_data, nr)),
- BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 1, 0),
+ BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_times, 1, 0),
BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
/* Only both with lower 32-bit for now. */
BPF_STMT(BPF_LD|BPF_W|BPF_ABS, syscall_arg(0)),
- BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 0x0C0FFEE, 0, 1),
+ BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K,
+ (unsigned long)&fatal_address, 0, 1),
BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL),
BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
};
@@ -403,23 +408,29 @@
};
long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
pid_t parent = getppid();
- pid_t pid = getpid();
+ struct tms timebuf;
+ clock_t clock = times(&timebuf);
ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
ASSERT_EQ(0, ret);
EXPECT_EQ(parent, syscall(__NR_getppid));
- EXPECT_EQ(pid, syscall(__NR_getpid));
- /* getpid() should never return. */
- EXPECT_EQ(0, syscall(__NR_getpid, 0x0C0FFEE));
+ EXPECT_LE(clock, syscall(__NR_times, &timebuf));
+ /* times() should never return. */
+ EXPECT_EQ(0, syscall(__NR_times, &fatal_address));
}
TEST_SIGNAL(KILL_one_arg_six, SIGSYS) {
+#ifndef __NR_mmap2
+ int sysno = __NR_mmap;
+#else
+ int sysno = __NR_mmap2;
+#endif
struct sock_filter filter[] = {
BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
offsetof(struct seccomp_data, nr)),
- BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 1, 0),
+ BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, sysno, 1, 0),
BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
/* Only both with lower 32-bit for now. */
BPF_STMT(BPF_LD|BPF_W|BPF_ABS, syscall_arg(5)),
@@ -433,16 +444,29 @@
};
long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
pid_t parent = getppid();
- pid_t pid = getpid();
+ int fd;
+ void *map1, *map2;
ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
ASSERT_EQ(0, ret);
+ fd = open("/dev/zero", O_RDONLY);
+ ASSERT_NE(-1, fd);
+
EXPECT_EQ(parent, syscall(__NR_getppid));
- EXPECT_EQ(pid, syscall(__NR_getpid));
- /* getpid() should never return. */
- EXPECT_EQ(0, syscall(__NR_getpid, 1, 2, 3, 4, 5, 0x0C0FFEE));
+ map1 = (void *)syscall(sysno,
+ NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, fd, PAGE_SIZE);
+ EXPECT_NE(MAP_FAILED, map1);
+ /* mmap2() should never return. */
+ map2 = (void *)syscall(sysno,
+ NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, fd, 0x0C0FFEE);
+ EXPECT_EQ(MAP_FAILED, map2);
+
+ /* The test failed, so clean up the resources. */
+ munmap(map1, PAGE_SIZE);
+ munmap(map2, PAGE_SIZE);
+ close(fd);
}
/* TODO(wad) add 64-bit versus 32-bit arg tests. */
diff --git a/tests/tests/os/src/android/os/cts/BuildVersionTest.java b/tests/tests/os/src/android/os/cts/BuildVersionTest.java
index af60139..75ad865 100644
--- a/tests/tests/os/src/android/os/cts/BuildVersionTest.java
+++ b/tests/tests/os/src/android/os/cts/BuildVersionTest.java
@@ -29,7 +29,7 @@
private static final String LOG_TAG = "BuildVersionTest";
private static final Set<String> EXPECTED_RELEASES =
- new HashSet<String>(Arrays.asList("6.0"));
+ new HashSet<String>(Arrays.asList("6.0.1", "6.0"));
private static final int EXPECTED_SDK = 23;
private static final String EXPECTED_BUILD_VARIANT = "user";
private static final String EXPECTED_TAG = "release-keys";
diff --git a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
index 0962bbd..1d0cfe6 100644
--- a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
@@ -785,7 +785,9 @@
new File("/dev/ashmem"),
new File("/dev/binder"),
new File("/dev/card0"), // b/13159510
+ new File("/dev/renderD128"),
new File("/dev/dri/card0"), // b/13159510
+ new File("/dev/dri/renderD128"),
new File("/dev/felica"), // b/11142586
new File("/dev/felica_ant"), // b/11142586
new File("/dev/felica_cen"), // b/11142586
diff --git a/tests/tests/security/src/android/security/cts/ServicePermissionsTest.java b/tests/tests/security/src/android/security/cts/ServicePermissionsTest.java
index 00cbfd8..fdc3058 100644
--- a/tests/tests/security/src/android/security/cts/ServicePermissionsTest.java
+++ b/tests/tests/security/src/android/security/cts/ServicePermissionsTest.java
@@ -17,6 +17,7 @@
package android.security.cts;
import android.os.IBinder;
+import android.os.DeadObjectException;
import android.os.TransactionTooLargeException;
import android.test.AndroidTestCase;
import android.util.Log;
@@ -108,7 +109,7 @@
// probably not checking for DUMP.
throw e;
}
- } catch (TransactionTooLargeException e) {
+ } catch (TransactionTooLargeException | DeadObjectException e) {
// SELinux likely prevented the dump - assume safe
continue;
} finally {
diff --git a/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java b/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
index d7fe239..1a2b415 100644
--- a/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
+++ b/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
@@ -246,7 +246,8 @@
mTelecomManager.addNewIncomingCall(TEST_PHONE_ACCOUNT_HANDLE, extras);
try {
- if (!mInCallCallbacks.lock.tryAcquire(3, TimeUnit.SECONDS)) {
+ if (!mInCallCallbacks.lock.tryAcquire(TestUtils.WAIT_FOR_CALL_ADDED_TIMEOUT_S,
+ TimeUnit.SECONDS)) {
fail("No call added to InCallService.");
}
} catch (InterruptedException e) {
@@ -297,7 +298,8 @@
placeNewCallWithPhoneAccount(extras, videoState);
try {
- if (!mInCallCallbacks.lock.tryAcquire(3, TimeUnit.SECONDS)) {
+ if (!mInCallCallbacks.lock.tryAcquire(TestUtils.WAIT_FOR_CALL_ADDED_TIMEOUT_S,
+ TimeUnit.SECONDS)) {
fail("No call added to InCallService.");
}
} catch (InterruptedException e) {
diff --git a/tests/tests/telecom/src/android/telecom/cts/BasicInCallServiceTest.java b/tests/tests/telecom/src/android/telecom/cts/BasicInCallServiceTest.java
index 0b5fe61..eda193d 100644
--- a/tests/tests/telecom/src/android/telecom/cts/BasicInCallServiceTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/BasicInCallServiceTest.java
@@ -77,7 +77,8 @@
mContext.startActivity(intent);
try {
- if (callbacks.lock.tryAcquire(3, TimeUnit.SECONDS)) {
+ if (callbacks.lock.tryAcquire(TestUtils.WAIT_FOR_CALL_ADDED_TIMEOUT_S,
+ TimeUnit.SECONDS)) {
return;
}
} catch (InterruptedException e) {
diff --git a/tests/tests/telecom/src/android/telecom/cts/TestUtils.java b/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
index 4936209..d1a9723 100644
--- a/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
+++ b/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
@@ -33,6 +33,7 @@
static final String TAG = "TelecomCTSTests";
static final boolean HAS_TELECOM = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
static final long WAIT_FOR_STATE_CHANGE_TIMEOUT_MS = 10000;
+ static final long WAIT_FOR_CALL_ADDED_TIMEOUT_S = 15;
// Non-final to allow modification by tests not in this package (e.g. permission-related
// tests in the Telecom2 test package.
diff --git a/tests/tests/telephony/src/android/telephony/cts/SmsMessageTest.java b/tests/tests/telephony/src/android/telephony/cts/SmsMessageTest.java
index d90e394..2db9ba1 100644
--- a/tests/tests/telephony/src/android/telephony/cts/SmsMessageTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/SmsMessageTest.java
@@ -301,11 +301,19 @@
int[] result = SmsMessage.calculateLength(LONG_TEXT_WITH_32BIT_CHARS, false);
assertEquals(3, result[0]);
assertEquals(LONG_TEXT_WITH_32BIT_CHARS.length(), result[1]);
+ // 3 parts, each with (SmsMessage.MAX_USER_DATA_BYTES_WITH_HEADER / 2) 16-bit
+ // characters. We need to subtract one because a 32-bit character crosses the
+ // boundary of 2 parts.
+ int preMaxChars = 3 * SmsMessage.MAX_USER_DATA_BYTES_WITH_HEADER / 2 - 1;
+ // If EMS is not supported, break down EMS into single segment SMS
+ // and add page info "x/y".
+ // In the case of UCS2 encoding type, we need 8 bytes for this
+ // but we only have 6 bytes from UDH, so truncate the limit for
+ // each segment by 2 bytes (1 char). This log sms has three segments,
+ // so truncate the limit by 3 char in total
+ int maxChars = SmsMessage.hasEmsSupport() ? preMaxChars : preMaxChars - 3;
assertRemaining(LONG_TEXT_WITH_32BIT_CHARS.length(), result[2],
- // 3 parts, each with (SmsMessage.MAX_USER_DATA_BYTES_WITH_HEADER / 2) 16-bit
- // characters. We need to subtract one because a 32-bit character crosses the
- // boundary of 2 parts.
- 3 * SmsMessage.MAX_USER_DATA_BYTES_WITH_HEADER / 2 - 1);
+ maxChars);
assertEquals(SmsMessage.ENCODING_16BIT, result[3]);
}
diff --git a/tests/tests/text/src/android/text/method/cts/PasswordTransformationMethodTest.java b/tests/tests/text/src/android/text/method/cts/PasswordTransformationMethodTest.java
index 4262a31..72a8e72 100644
--- a/tests/tests/text/src/android/text/method/cts/PasswordTransformationMethodTest.java
+++ b/tests/tests/text/src/android/text/method/cts/PasswordTransformationMethodTest.java
@@ -19,6 +19,7 @@
import android.cts.util.PollingCheck;
import android.graphics.Rect;
+import android.os.ParcelFileDescriptor;
import android.provider.Settings.SettingNotFoundException;
import android.provider.Settings.System;
import android.test.ActivityInstrumentationTestCase2;
@@ -31,6 +32,10 @@
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.util.Scanner;
+
/**
* Test {@link PasswordTransformationMethod}.
*/
@@ -97,10 +102,39 @@
mEditText = (EditText) getActivity().findViewById(EDIT_TXT_ID);
assertTrue(mEditText.isFocused());
+ enableAppOps();
savePasswordPref();
switchShowPassword(true);
}
+ private void enableAppOps() {
+ StringBuilder cmd = new StringBuilder();
+ cmd.append("appops set ");
+ cmd.append(getInstrumentation().getContext().getPackageName());
+ cmd.append(" android:write_settings allow");
+ getInstrumentation().getUiAutomation().executeShellCommand(cmd.toString());
+
+ StringBuilder query = new StringBuilder();
+ query.append("appops get ");
+ query.append(getInstrumentation().getContext().getPackageName());
+ query.append(" android:write_settings");
+ String queryStr = query.toString();
+
+ String result = "No operations.";
+ while (result.contains("No operations")) {
+ ParcelFileDescriptor pfd = getInstrumentation().getUiAutomation().executeShellCommand(
+ queryStr);
+ InputStream inputStream = new FileInputStream(pfd.getFileDescriptor());
+ result = convertStreamToString(inputStream);
+ }
+ }
+
+ private String convertStreamToString(InputStream is) {
+ try (Scanner scanner = new Scanner(is).useDelimiter("\\A")) {
+ return scanner.hasNext() ? scanner.next() : "";
+ }
+ }
+
@Override
protected void tearDown() throws Exception {
resumePasswordPref();
diff --git a/tools/cts-media/get_achievable_rates.py b/tools/cts-media/get_achievable_rates.py
new file mode 100755
index 0000000..81412da
--- /dev/null
+++ b/tools/cts-media/get_achievable_rates.py
@@ -0,0 +1,396 @@
+#!/usr/bin/python
+# 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.
+#
+
+import argparse, math, re, sys
+import xml.etree.ElementTree as ET
+from collections import defaultdict, namedtuple
+import itertools
+
+
+def createLookup(values, key):
+ """Creates a lookup table for a collection of values based on keys.
+
+ Arguments:
+ values: a collection of arbitrary values. Must be iterable.
+ key: a function of one argument that returns the key for a value.
+
+ Returns:
+ A dict mapping keys (as generated by the key argument) to lists of
+ values. All values in the lists have the same key, and are in the order
+ they appeared in the collection.
+ """
+ lookup = defaultdict(list)
+ for v in values:
+ lookup[key(v)].append(v)
+ return lookup
+
+
+def _intify(value):
+ """Returns a value converted to int if possible, else the original value."""
+ try:
+ return int(value)
+ except ValueError:
+ return value
+
+
+class Size(namedtuple('Size', ['width', 'height'])):
+ """A namedtuple with width and height fields."""
+ def __str__(self):
+ return '%dx%d' % (self.width, self.height)
+
+
+class _VideoResultBase(object):
+ """Helper methods for results. Not for use by applications.
+
+ Attributes:
+ codec: The name of the codec (string) or None
+ size: Size representing the video size or None
+ mime: The mime-type of the codec (string) or None
+ rates: The measured achievable frame rates
+ is_decoder: True iff codec is a decoder.
+ """
+
+ def __init__(self, is_decoder):
+ self.codec = None
+ self.mime = None
+ self.size = None
+ self._rates_from_failure = []
+ self._rates_from_message = []
+ self.is_decoder = is_decoder
+
+ def _inited(self):
+ """Returns true iff codec, mime and size was set."""
+ return None not in (self.codec, self.mime, self.size)
+
+ def __len__(self):
+ # don't report any result if codec name, mime type and size is unclear
+ if not self._inited():
+ return 0
+ return len(self.rates)
+
+ @property
+ def rates(self):
+ return self._rates_from_failure or self._rates_from_message
+
+ def _parseDict(self, value):
+ """Parses a MediaFormat from its string representation sans brackets."""
+ return dict((k, _intify(v))
+ for k, v in re.findall(r'([^ =]+)=([^ [=]+(?:|\[[^\]]+\]))(?:, |$)', value))
+
+ def _cleanFormat(self, format):
+ """Removes internal fields from a parsed MediaFormat."""
+ format.pop('what', None)
+ format.pop('image-data', None)
+
+ MESSAGE_PATTERN = r'(?P<key>\w+)=(?P<value>\{[^}]*\}|[^ ,{}]+)'
+
+ def _parsePartialResult(self, message_match):
+ """Parses a partial test result conforming to the message pattern.
+
+ Returns:
+ A tuple of string key and int, string or dict value, where dict has
+ string keys mapping to int or string values.
+ """
+ key, value = message_match.group('key', 'value')
+ if value.startswith('{'):
+ value = self._parseDict(value[1:-1])
+ if key.endswith('Format'):
+ self._cleanFormat(value)
+ else:
+ value = _intify(value)
+ return key, value
+
+ def _parseValuesFromBracket(self, line):
+ """Returns the values enclosed in brackets without the brackets.
+
+ Parses a line matching the pattern "<tag>: [<values>]" and returns <values>.
+
+ Raises:
+ ValueError: if the line does not match the pattern.
+ """
+ try:
+ return re.match(r'^[^:]+: *\[(?P<values>.*)\]\.$', line).group('values')
+ except AttributeError:
+ raise ValueError('line does not match "tag: [value]": %s' % line)
+
+ def _parseRawData(self, line):
+ """Parses the raw data line for video performance tests.
+
+ Yields:
+ Dict objects corresponding to parsed results, mapping string keys to
+ int, string or dict values.
+ """
+ try:
+ values = self._parseValuesFromBracket(line)
+ result = {}
+ for m in re.finditer(self.MESSAGE_PATTERN + r'(?P<sep>,? +|$)', values):
+ key, value = self._parsePartialResult(m)
+ result[key] = value
+ if m.group('sep') != ' ':
+ yield result
+ result = {}
+ except ValueError:
+ print >> sys.stderr, 'could not parse line %s' % repr(line)
+
+ def _tryParseMeasuredFrameRate(self, line):
+ """Parses a line starting with 'Measured frame rate:'."""
+ if line.startswith('Measured frame rate: '):
+ try:
+ values = self._parseValuesFromBracket(line)
+ values = re.split(r' *, *', values)
+ self._rates_from_failure = list(map(float, values))
+ except ValueError:
+ print >> sys.stderr, 'could not parse line %s' % repr(line)
+
+ def parse(self, test):
+ """Parses the ValueArray and FailedScene lines of a test result.
+
+ Arguments:
+ test: An ElementTree <Test> element.
+ """
+ failure = test.find('FailedScene')
+ if failure is not None:
+ trace = failure.find('StackTrace')
+ if trace is not None:
+ for line in re.split(r'[\r\n]+', trace.text):
+ self._parseFailureLine(line)
+ details = test.find('Details')
+ if details is not None:
+ for array in details.iter('ValueArray'):
+ message = array.get('message')
+ self._parseMessage(message, array)
+
+ def _parseFailureLine(self, line):
+ raise NotImplementedError
+
+ def _parseMessage(self, message, array):
+ raise NotImplementedError
+
+ def getData(self):
+ """Gets the parsed test result data.
+
+ Yields:
+ Result objects containing at least codec, size, mime and rates attributes."""
+ yield self
+
+
+class VideoEncoderDecoderTestResult(_VideoResultBase):
+ """Represents a result from a VideoEncoderDecoderTest performance case."""
+
+ def __init__(self, unused_m):
+ super(VideoEncoderDecoderTestResult, self).__init__(is_decoder=False)
+
+ # If a VideoEncoderDecoderTest succeeds, it provides the results in the
+ # message of a ValueArray. If fails, it provides the results in the failure
+ # using raw data. (For now it also includes some data in the ValueArrays even
+ # if it fails, which we ignore.)
+
+ def _parseFailureLine(self, line):
+ """Handles parsing a line from the failure log."""
+ self._tryParseMeasuredFrameRate(line)
+
+ def _parseMessage(self, message, array):
+ """Handles parsing a message from ValueArrays."""
+ if message.startswith('codec='):
+ result = dict(self._parsePartialResult(m)
+ for m in re.finditer(self.MESSAGE_PATTERN + '(?: |$)', message))
+ if 'EncInputFormat' in result:
+ self.codec = result['codec']
+ fmt = result['EncInputFormat']
+ self.size = Size(fmt['width'], fmt['height'])
+ self.mime = result['EncOutputFormat']['mime']
+ self._rates_from_message.append(1000000./result['min'])
+
+
+class VideoDecoderPerfTestResult(_VideoResultBase):
+ """Represents a result from a VideoDecoderPerfTest performance case."""
+
+ # If a VideoDecoderPerfTest succeeds, it provides the results in the message
+ # of a ValueArray. If fails, it provides the results in the failure only
+ # using raw data.
+
+ def __init__(self, unused_m):
+ super(VideoDecoderPerfTestResult, self).__init__(is_decoder=True)
+
+ def _parseFailureLine(self, line):
+ """Handles parsing a line from the failure log."""
+ self._tryParseMeasuredFrameRate(line)
+ # if the test failed, we can only get the codec/size/mime from the raw data.
+ if line.startswith('Raw data: '):
+ for result in self._parseRawData(line):
+ fmt = result['DecOutputFormat']
+ self.size = Size(fmt['width'], fmt['height'])
+ self.codec = result['codec']
+ self.mime = result['mime']
+
+ def _parseMessage(self, message, array):
+ """Handles parsing a message from ValueArrays."""
+ if message.startswith('codec='):
+ result = dict(self._parsePartialResult(m)
+ for m in re.finditer(self.MESSAGE_PATTERN + '(?: |$)', message))
+ if result.get('decodeto') == 'surface':
+ self.codec = result['codec']
+ fmt = result['DecOutputFormat']
+ self.size = Size(fmt['width'], fmt['height'])
+ self.mime = result['mime']
+ self._rates_from_message.append(1000000. / result['min'])
+
+
+class Results(object):
+ """Container that keeps all test results."""
+ def __init__(self):
+ self._results = [] # namedtuples
+ self._device = None
+
+ VIDEO_ENCODER_DECODER_TEST_REGEX = re.compile(
+ 'test(.*)(\d{4})x(\d{4})(Goog|Other)$')
+
+ VIDEO_DECODER_PERF_TEST_REGEX = re.compile(
+ 'test(VP[89]|H26[34]|MPEG4|HEVC)(\d+)x(\d+)(.*)$')
+
+ TestCaseSpec = namedtuple('TestCaseSpec', 'package path class_ regex result_class')
+
+ def _getTestCases(self):
+ return [
+ self.TestCaseSpec(package='CtsDeviceVideoPerf',
+ path='TestSuite/TestSuite/TestSuite/TestSuite/TestCase',
+ class_='VideoEncoderDecoderTest',
+ regex=self.VIDEO_ENCODER_DECODER_TEST_REGEX,
+ result_class=VideoEncoderDecoderTestResult),
+ self.TestCaseSpec(package='CtsMediaTestCases',
+ path='TestSuite/TestSuite/TestSuite/TestCase',
+ class_='VideoDecoderPerfTest',
+ regex=self.VIDEO_DECODER_PERF_TEST_REGEX,
+ result_class=VideoDecoderPerfTestResult)
+ ]
+
+ def _verifyDeviceInfo(self, device):
+ assert self._device in (None, device), "expected %s device" % self._device
+ self._device = device
+
+ def importXml(self, xml):
+ self._verifyDeviceInfo(xml.find('DeviceInfo/BuildInfo').get('buildName'))
+
+ packages = createLookup(self._getTestCases(), lambda tc: tc.package)
+
+ for pkg in xml.iter('TestPackage'):
+ tests_in_package = packages.get(pkg.get('name'))
+ if not tests_in_package:
+ continue
+ paths = createLookup(tests_in_package, lambda tc: tc.path)
+ for path, tests_in_path in paths.items():
+ classes = createLookup(tests_in_path, lambda tc: tc.class_)
+ for tc in pkg.iterfind(path):
+ tests_in_class = classes.get(tc.get('name'))
+ if not tests_in_class:
+ continue
+ for test in tc.iter('Test'):
+ for tc in tests_in_class:
+ m = tc.regex.match(test.get('name'))
+ if m:
+ result = tc.result_class(m)
+ result.parse(test)
+ self._results.append(result)
+
+ def importFile(self, path):
+ print >> sys.stderr, 'Importing "%s"...' % path
+ try:
+ return self.importXml(ET.parse(path))
+ except ET.ParseError:
+ raise ValueError('not a valid XML file')
+
+ def getData(self):
+ for result in self._results:
+ for data in result.getData():
+ yield data
+
+ def dumpXml(self, results):
+ yield '<?xml version="1.0" encoding="utf-8" ?>'
+ yield '<!-- Copyright 2015 The Android Open Source Project'
+ yield ''
+ yield ' Licensed under the Apache License, Version 2.0 (the "License");'
+ yield ' you may not use this file except in compliance with the License.'
+ yield ' You may obtain a copy of the License at'
+ yield ''
+ yield ' http://www.apache.org/licenses/LICENSE-2.0'
+ yield ''
+ yield ' Unless required by applicable law or agreed to in writing, software'
+ yield ' distributed under the License is distributed on an "AS IS" BASIS,'
+ yield ' WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.'
+ yield ' See the License for the specific language governing permissions and'
+ yield ' limitations under the License.'
+ yield '-->'
+ yield ''
+ yield '<MediaCodecs>'
+ last_section = None
+ Comp = namedtuple('Comp', 'is_decoder google mime name')
+ by_comp = createLookup(results,
+ lambda e: Comp(is_decoder=e.is_decoder, google='.google.' in e.codec, mime=e.mime, name=e.codec))
+ for comp in sorted(by_comp):
+ section = 'Decoders' if comp.is_decoder else 'Encoders'
+ if section != last_section:
+ if last_section:
+ yield ' </%s>' % last_section
+ yield ' <%s>' % section
+ last_section = section
+ yield ' <MediaCodec name="%s" type="%s" update="true">' % (comp.name, comp.mime)
+ by_size = createLookup(by_comp[comp], lambda e: e.size)
+ for size in sorted(by_size):
+ values = list(itertools.chain(*(e.rates for e in by_size[size])))
+ min_, max_ = min(values), max(values)
+ med_ = int(math.sqrt(min_ * max_))
+ yield ' <Limit name="measured-frame-rate-%s" range="%d-%d" />' % (size, med_, med_)
+ yield ' </MediaCodec>'
+ if last_section:
+ yield ' </%s>' % last_section
+ yield '</MediaCodecs>'
+
+
+class Main(object):
+ """Executor of this utility."""
+
+ def __init__(self):
+ self._result = Results()
+
+ self._parser = argparse.ArgumentParser('get_achievable_framerates')
+ self._parser.add_argument('result_xml', nargs='+')
+
+ def _parseArgs(self):
+ self._args = self._parser.parse_args()
+
+ def _importXml(self, xml):
+ self._result.importFile(xml)
+
+ def _report(self):
+ for line in self._result.dumpXml(r for r in self._result.getData() if r):
+ print line
+
+ def run(self):
+ self._parseArgs()
+ try:
+ for xml in self._args.result_xml:
+ try:
+ self._importXml(xml)
+ except (ValueError, IOError, AssertionError) as e:
+ print >> sys.stderr, e
+ raise KeyboardInterrupt
+ self._report()
+ except KeyboardInterrupt:
+ print >> sys.stderr, 'Interrupted.'
+
+if __name__ == '__main__':
+ Main().run()
+
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildProvider.java b/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildProvider.java
index 782e6ab..a39d8b6 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildProvider.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildProvider.java
@@ -31,7 +31,7 @@
@Option(name="cts-install-path", description="the path to the cts installation to use")
private String mCtsRootDirPath = System.getProperty("CTS_ROOT");
- public static final String CTS_BUILD_VERSION = "6.0_r1";
+ public static final String CTS_BUILD_VERSION = "6.0_r2";
public static final String CTS_PACKAGE = "com.android.cts.tradefed.testtype";
/**
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/result/CtsXmlResultReporter.java b/tools/tradefed-host/src/com/android/cts/tradefed/result/CtsXmlResultReporter.java
index 51b457d..3efc7fc 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/result/CtsXmlResultReporter.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/result/CtsXmlResultReporter.java
@@ -432,6 +432,9 @@
serializer.attribute(ns, "endtime", endTime);
serializer.attribute(ns, "version", CTS_RESULT_FILE_VERSION);
serializer.attribute(ns, "suite", mSuiteName);
+ if (mReferenceUrl != null) {
+ serializer.attribute(ns, "referenceUrl", mReferenceUrl);
+ }
mResults.serialize(serializer, mBuildInfo.getBuildId());
// TODO: not sure why, but the serializer doesn't like this statement
//serializer.endTag(ns, RESULT_TAG);
diff --git a/tools/tradefed-host/tests/src/com/android/cts/tradefed/result/CtsXmlResultReporterTest.java b/tools/tradefed-host/tests/src/com/android/cts/tradefed/result/CtsXmlResultReporterTest.java
index 51a6153..958dbe4 100644
--- a/tools/tradefed-host/tests/src/com/android/cts/tradefed/result/CtsXmlResultReporterTest.java
+++ b/tools/tradefed-host/tests/src/com/android/cts/tradefed/result/CtsXmlResultReporterTest.java
@@ -48,8 +48,9 @@
*/
public class CtsXmlResultReporterTest extends TestCase {
+ private static final String TEST_SUMMARY_URL = "http://www.google.com?q=android";
private static final List<TestSummary> SUMMARY_LIST =
- new ArrayList<>(Arrays.asList(new TestSummary("TEST_SUMMARY_URL")));
+ new ArrayList<>(Arrays.asList(new TestSummary(TEST_SUMMARY_URL)));
private CtsXmlResultReporter mResultReporter;
private ByteArrayOutputStream mOutputStream;
private File mBuildDir;
@@ -116,7 +117,7 @@
"<?xml-stylesheet type=\"text/xsl\" href=\"cts_result.xsl\"?>";
final String expectedTestOutput = String.format(
"<TestResult testPlan=\"NA\" starttime=\"ignore\" endtime=\"ignore\" " +
- "version=\"%s\" suite=\"%s\"> ", CTS_RESULT_FILE_VERSION, "CTS" );
+ "version=\"%s\" suite=\"%s\"> ", CTS_RESULT_FILE_VERSION, "CTS");
final String expectedSummaryOutput =
"<Summary failed=\"0\" notExecuted=\"0\" timeout=\"0\" pass=\"0\" />";
final String expectedEndTag = "</TestResult>";
@@ -128,7 +129,7 @@
assertTrue(String.format("test output did not contain expected test result [%s]. Got %s",
expectedTestOutput, actualOutput), actualOutput.contains(expectedTestOutput));
assertTrue(String.format("test output did not contain expected test summary [%s]. Got %s",
- expectedTestOutput, actualOutput), actualOutput.contains(expectedSummaryOutput));
+ expectedSummaryOutput, actualOutput), actualOutput.contains(expectedSummaryOutput));
assertTrue(String.format("test output did not contain expected TestResult end tag. Got %s",
actualOutput), actualOutput.endsWith(expectedEndTag));
EasyMock.verify(mMockBuild);
@@ -146,10 +147,15 @@
mResultReporter.testStarted(testId);
mResultReporter.testEnded(testId, emptyMap);
mResultReporter.testRunEnded(3000, emptyMap);
- mResultReporter.invocationEnded(1);
mResultReporter.putSummary(SUMMARY_LIST);
+ mResultReporter.invocationEnded(1);
String output = getOutput();
// TODO: consider doing xml based compare
+ final String expectedTestOutput = String.format(
+ "<TestResult testPlan=\"NA\" starttime=\"ignore\" endtime=\"ignore\" " +
+ "version=\"%s\" suite=\"%s\" referenceUrl=\"%s\"> ",
+ CTS_RESULT_FILE_VERSION, "CTS", TEST_SUMMARY_URL);
+ assertTrue("Found output: " + output, output.contains(expectedTestOutput));
assertTrue(output.contains(
"<Summary failed=\"0\" notExecuted=\"0\" timeout=\"0\" pass=\"1\" />"));
assertTrue(output.contains("<TestPackage name=\"\" appPackageName=\"run\" abi=\"" +