diff options
author | android-build-prod (mdb) <android-build-team-robot@google.com> | 2020-01-16 18:45:38 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2020-01-16 18:45:38 +0000 |
commit | 53d1cf3b69dc1f5359077e7a16876f97111ffb77 (patch) | |
tree | 3168bb34286ce78adaa94e4e89e300623999cddd | |
parent | ab0c808006e57a85b0a2d783d62f51c7fd61e3ad (diff) | |
parent | 3c5baeb57546866521bee61ad186790a4154733d (diff) | |
download | cts-sparse-6140869-L84700000457722352.tar.gz |
Merge "Snap for 6139873 from b7289dd883ad8cdcc0a5cf2f55e9348dc2dabdb8 to pie-cts-release" into pie-cts-releasesparse-6140869-L84700000457722352
74 files changed, 1345 insertions, 266 deletions
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml index ce2dc33d370..6895c5f134d 100644 --- a/apps/CtsVerifier/AndroidManifest.xml +++ b/apps/CtsVerifier/AndroidManifest.xml @@ -18,7 +18,7 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.cts.verifier" android:versionCode="5" - android:versionName="9.0_r10"> + android:versionName="9.0_r11"> <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="28"/> @@ -1625,6 +1625,8 @@ <meta-data android:name="test_category" android:value="@string/test_category_sensors"/> <meta-data android:name="test_required_features" android:value="android.hardware.sensor.accelerometer"/> + <meta-data android:name="test_excluded_features" + android:value="android.hardware.type.automotive"/> </activity> <activity android:name=".sensors.GyroscopeMeasurementTestActivity" @@ -1637,6 +1639,8 @@ <meta-data android:name="test_category" android:value="@string/test_category_sensors"/> <meta-data android:name="test_required_features" android:value="android.hardware.sensor.gyroscope"/> + <meta-data android:name="test_excluded_features" + android:value="android.hardware.type.automotive"/> </activity> <activity android:name=".sensors.HeartRateMonitorTestActivity" diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/AbstractTestListActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/AbstractTestListActivity.java index 3132219a0e9..937859638fd 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/AbstractTestListActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/AbstractTestListActivity.java @@ -31,6 +31,8 @@ public abstract class AbstractTestListActivity extends ListActivity { private static final int LAUNCH_TEST_REQUEST_CODE = 9001; protected TestListAdapter mAdapter; + // Start time of test item. + protected long mStartTime; protected void setTestListAdapter(TestListAdapter adapter) { mAdapter = adapter; @@ -74,6 +76,8 @@ public abstract class AbstractTestListActivity extends ListActivity { protected void handleLaunchTestResult(int resultCode, Intent data) { if (resultCode == RESULT_OK) { TestResult testResult = TestResult.fromActivityResult(resultCode, data); + testResult.getHistoryCollection().add( + testResult.getName(), mStartTime, System.currentTimeMillis()); mAdapter.setTestResult(testResult); } } @@ -82,6 +86,7 @@ public abstract class AbstractTestListActivity extends ListActivity { @Override protected final void onListItemClick(ListView listView, View view, int position, long id) { super.onListItemClick(listView, view, position, id); + mStartTime = System.currentTimeMillis(); handleItemClick(listView, view, position, id); } diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/DialogTestListActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/DialogTestListActivity.java index aa6eaba12a5..bed5a77598b 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/DialogTestListActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/DialogTestListActivity.java @@ -224,7 +224,7 @@ public abstract class DialogTestListActivity extends PassFailButtons.TestListAct // Bundle result in an intent to feed into handleLaunchTestResult Intent resultIntent = new Intent(); TestResult.addResultData(resultIntent, result, test.testName, /* testDetails */ null, - /* reportLog */ null); + /* reportLog */ null, null); handleLaunchTestResult(RESULT_OK, resultIntent); getListView().smoothScrollToPosition(mCurrentTestPosition + 1); } @@ -233,7 +233,7 @@ public abstract class DialogTestListActivity extends PassFailButtons.TestListAct // Bundle result in an intent to feed into handleLaunchTestResult Intent resultIntent = new Intent(); TestResult.addResultData(resultIntent, result, testName, /* testDetails */ null, - /* reportLog */ null); + /* reportLog */ null, null); handleLaunchTestResult(RESULT_OK, resultIntent); getListView().smoothScrollToPosition(mCurrentTestPosition + 1); } diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java b/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java index 4a8004a66b0..7776d27e010 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java @@ -36,6 +36,10 @@ import android.view.View.OnClickListener; import android.widget.ImageButton; import android.widget.Toast; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + /** * {@link Activity}s to handle clicks to the pass and fail buttons of the pass fail buttons layout. * @@ -99,14 +103,21 @@ public class PassFailButtons { /** @return A {@link ReportLog} that is used to record test metric data. */ ReportLog getReportLog(); + + /** + * @return A {@link TestResultHistoryCollection} that is used to record test execution time. + */ + TestResultHistoryCollection getHistoryCollection(); } public static class Activity extends android.app.Activity implements PassFailActivity { private WakeLock mWakeLock; private final ReportLog reportLog; + private final TestResultHistoryCollection mHistoryCollection; public Activity() { this.reportLog = new CtsVerifierReportLog(); + this.mHistoryCollection = new TestResultHistoryCollection(); } @Override @@ -160,19 +171,25 @@ public class PassFailButtons { @Override public void setTestResultAndFinish(boolean passed) { PassFailButtons.setTestResultAndFinishHelper( - this, getTestId(), getTestDetails(), passed, getReportLog()); + this, getTestId(), getTestDetails(), passed, getReportLog(), + getHistoryCollection()); } @Override public ReportLog getReportLog() { return reportLog; } + + @Override + public TestResultHistoryCollection getHistoryCollection() { return mHistoryCollection; } } public static class ListActivity extends android.app.ListActivity implements PassFailActivity { private final ReportLog reportLog; + private final TestResultHistoryCollection mHistoryCollection; public ListActivity() { this.reportLog = new CtsVerifierReportLog(); + this.mHistoryCollection = new TestResultHistoryCollection(); } @Override @@ -208,11 +225,15 @@ public class PassFailButtons { @Override public void setTestResultAndFinish(boolean passed) { PassFailButtons.setTestResultAndFinishHelper( - this, getTestId(), getTestDetails(), passed, getReportLog()); + this, getTestId(), getTestDetails(), passed, getReportLog(), + getHistoryCollection()); } @Override public ReportLog getReportLog() { return reportLog; } + + @Override + public TestResultHistoryCollection getHistoryCollection() { return mHistoryCollection; } } public static class TestListActivity extends AbstractTestListActivity @@ -257,12 +278,27 @@ public class PassFailButtons { @Override public void setTestResultAndFinish(boolean passed) { PassFailButtons.setTestResultAndFinishHelper( - this, getTestId(), getTestDetails(), passed, getReportLog()); + this, getTestId(), getTestDetails(), passed, getReportLog(), + getHistoryCollection()); } @Override public ReportLog getReportLog() { return reportLog; } + /** + * Get existing test history to aggregate. + */ + @Override + public TestResultHistoryCollection getHistoryCollection() { + List<TestResultHistoryCollection> histories = + IntStream.range(0, mAdapter.getCount()) + .mapToObj(mAdapter::getHistoryCollection) + .collect(Collectors.toList()); + TestResultHistoryCollection historyCollection = new TestResultHistoryCollection(); + historyCollection.merge(getTestId(), histories); + return historyCollection; + } + public void updatePassButton() { getPassButton().setEnabled(mAdapter.allTestsPassed()); } @@ -274,7 +310,7 @@ public class PassFailButtons { @Override public void onClick(View target) { setTestResultAndFinish(activity, activity.getTestId(), activity.getTestDetails(), - activity.getReportLog(), target); + activity.getReportLog(), activity.getHistoryCollection(), target); } }; @@ -399,7 +435,8 @@ public class PassFailButtons { /** Set the test result corresponding to the button clicked and finish the activity. */ protected static void setTestResultAndFinish(android.app.Activity activity, String testId, - String testDetails, ReportLog reportLog, View target) { + String testDetails, ReportLog reportLog, TestResultHistoryCollection historyCollection, + View target) { boolean passed; if (target.getId() == R.id.pass_button) { passed = true; @@ -409,16 +446,17 @@ public class PassFailButtons { throw new IllegalArgumentException("Unknown id: " + target.getId()); } - setTestResultAndFinishHelper(activity, testId, testDetails, passed, reportLog); + setTestResultAndFinishHelper(activity, testId, testDetails, passed, reportLog, historyCollection); } /** Set the test result and finish the activity. */ protected static void setTestResultAndFinishHelper(android.app.Activity activity, String testId, - String testDetails, boolean passed, ReportLog reportLog) { + String testDetails, boolean passed, ReportLog reportLog, + TestResultHistoryCollection historyCollection) { if (passed) { - TestResult.setPassedResult(activity, testId, testDetails, reportLog); + TestResult.setPassedResult(activity, testId, testDetails, reportLog, historyCollection); } else { - TestResult.setFailedResult(activity, testId, testDetails, reportLog); + TestResult.setFailedResult(activity, testId, testDetails, reportLog, historyCollection); } activity.finish(); diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/ReportExporter.java b/apps/CtsVerifier/src/com/android/cts/verifier/ReportExporter.java index 1629e1b0972..29136a51a1c 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/ReportExporter.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/ReportExporter.java @@ -59,14 +59,14 @@ class ReportExporter extends AsyncTask<Void, Void, String> { private static final String SUITE_PLAN = "verifier"; private static final String SUITE_BUILD = "0"; - private static final long START_MS = System.currentTimeMillis(); - private static final long END_MS = START_MS; - private static final String REPORT_DIRECTORY = "verifierReports"; private static final String ZIP_EXTENSION = ".zip"; protected static final Logger LOG = Logger.getLogger(ReportExporter.class.getName()); + private final long START_MS = System.currentTimeMillis(); + private final long END_MS = START_MS; + private final Context mContext; private final TestListAdapter mAdapter; diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/TestListAdapter.java b/apps/CtsVerifier/src/com/android/cts/verifier/TestListAdapter.java index d9ea84ff593..17efb22cb98 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/TestListAdapter.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/TestListAdapter.java @@ -17,6 +17,7 @@ package com.android.cts.verifier; import com.android.compatibility.common.util.ReportLog; +import com.android.compatibility.common.util.TestResultHistory; import android.content.ContentResolver; import android.content.Context; @@ -74,6 +75,9 @@ public abstract class TestListAdapter extends BaseAdapter { /** Map from test name to {@link ReportLog}. */ private final Map<String, ReportLog> mReportLogs = new HashMap<String, ReportLog>(); + /** Map from test name to {@link TestResultHistory}. */ + private final Map<String, TestResultHistoryCollection> mHistories = new HashMap<>(); + private final LayoutInflater mLayoutInflater; /** {@link ListView} row that is either a test category header or a test. */ @@ -192,8 +196,14 @@ public abstract class TestListAdapter extends BaseAdapter { } public void setTestResult(TestResult testResult) { - new SetTestResultTask(testResult.getName(), testResult.getResult(), - testResult.getDetails(), testResult.getReportLog()).execute(); + String name = testResult.getName(); + + // Append existing history + TestResultHistoryCollection histories = testResult.getHistoryCollection(); + histories.merge(null, mHistories.get(name)); + + new SetTestResultTask(name, testResult.getResult(), + testResult.getDetails(), testResult.getReportLog(), histories).execute(); } class RefreshTestResultsTask extends AsyncTask<Void, Void, RefreshResult> { @@ -214,6 +224,8 @@ public abstract class TestListAdapter extends BaseAdapter { mTestDetails.putAll(result.mDetails); mReportLogs.clear(); mReportLogs.putAll(result.mReportLogs); + mHistories.clear(); + mHistories.putAll(result.mHistories); notifyDataSetChanged(); } } @@ -223,16 +235,19 @@ public abstract class TestListAdapter extends BaseAdapter { Map<String, Integer> mResults; Map<String, String> mDetails; Map<String, ReportLog> mReportLogs; + Map<String, TestResultHistoryCollection> mHistories; RefreshResult( List<TestListItem> items, Map<String, Integer> results, Map<String, String> details, - Map<String, ReportLog> reportLogs) { + Map<String, ReportLog> reportLogs, + Map<String, TestResultHistoryCollection> histories) { mItems = items; mResults = results; mDetails = details; mReportLogs = reportLogs; + mHistories = histories; } } @@ -244,12 +259,14 @@ public abstract class TestListAdapter extends BaseAdapter { TestResultsProvider.COLUMN_TEST_RESULT, TestResultsProvider.COLUMN_TEST_DETAILS, TestResultsProvider.COLUMN_TEST_METRICS, + TestResultsProvider.COLUMN_TEST_RESULT_HISTORY, }; RefreshResult getRefreshResults(List<TestListItem> items) { Map<String, Integer> results = new HashMap<String, Integer>(); Map<String, String> details = new HashMap<String, String>(); Map<String, ReportLog> reportLogs = new HashMap<String, ReportLog>(); + Map<String, TestResultHistoryCollection> histories = new HashMap<>(); ContentResolver resolver = mContext.getContentResolver(); Cursor cursor = null; try { @@ -261,9 +278,12 @@ public abstract class TestListAdapter extends BaseAdapter { int testResult = cursor.getInt(2); String testDetails = cursor.getString(3); ReportLog reportLog = (ReportLog) deserialize(cursor.getBlob(4)); + TestResultHistoryCollection historyCollection = + (TestResultHistoryCollection) deserialize(cursor.getBlob(5)); results.put(testName, testResult); details.put(testName, testDetails); reportLogs.put(testName, reportLog); + histories.put(testName, historyCollection); } while (cursor.moveToNext()); } } finally { @@ -271,7 +291,7 @@ public abstract class TestListAdapter extends BaseAdapter { cursor.close(); } } - return new RefreshResult(items, results, details, reportLogs); + return new RefreshResult(items, results, details, reportLogs, histories); } class ClearTestResultsTask extends AsyncTask<Void, Void, Void> { @@ -287,27 +307,28 @@ public abstract class TestListAdapter extends BaseAdapter { class SetTestResultTask extends AsyncTask<Void, Void, Void> { private final String mTestName; - private final int mResult; - private final String mDetails; - private final ReportLog mReportLog; + private final TestResultHistoryCollection mHistoryCollection; SetTestResultTask( String testName, int result, String details, - ReportLog reportLog) { + ReportLog reportLog, + TestResultHistoryCollection historyCollection) { mTestName = testName; mResult = result; mDetails = details; mReportLog = reportLog; + mHistoryCollection = historyCollection; } @Override protected Void doInBackground(Void... params) { - TestResultsProvider.setTestResult(mContext, mTestName, mResult, mDetails, mReportLog); + TestResultsProvider.setTestResult( + mContext, mTestName, mResult, mDetails, mReportLog, mHistoryCollection); return null; } } @@ -382,6 +403,19 @@ public abstract class TestListAdapter extends BaseAdapter { : null; } + /** + * Get test result histories. + * + * @param position The position of test. + * @return A {@link TestResultHistoryCollection} object containing test result histories of tests. + */ + public TestResultHistoryCollection getHistoryCollection(int position) { + TestListItem item = getItem(position); + return mHistories.containsKey(item.testName) + ? mHistories.get(item.testName) + : null; + } + public boolean allTestsPassed() { for (TestListItem item : mRows) { if (item.isTest() && (!mTestResults.containsKey(item.testName) @@ -451,7 +485,7 @@ public abstract class TestListAdapter extends BaseAdapter { } } - private static Object deserialize(byte[] bytes) { + public static Object deserialize(byte[] bytes) { if (bytes == null || bytes.length == 0) { return null; } diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/TestResult.java b/apps/CtsVerifier/src/com/android/cts/verifier/TestResult.java index 07208dde319..9f867d55bd4 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/TestResult.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/TestResult.java @@ -17,6 +17,7 @@ package com.android.cts.verifier; import com.android.compatibility.common.util.ReportLog; +import com.android.compatibility.common.util.TestResultHistory; import android.app.Activity; import android.content.Intent; @@ -38,11 +39,13 @@ public class TestResult { private static final String TEST_RESULT = "result"; private static final String TEST_DETAILS = "details"; private static final String TEST_METRICS = "metrics"; + private static final String TEST_HISTORY_COLLECTION = "historyCollection"; private final String mName; private final int mResult; private final String mDetails; private final ReportLog mReportLog; + private final TestResultHistoryCollection mHistoryCollection; /** Sets the test activity's result to pass. */ public static void setPassedResult(Activity activity, String testId, String testDetails) { @@ -53,7 +56,14 @@ public class TestResult { public static void setPassedResult(Activity activity, String testId, String testDetails, ReportLog reportLog) { activity.setResult(Activity.RESULT_OK, createResult(activity, TEST_RESULT_PASSED, testId, - testDetails, reportLog)); + testDetails, reportLog, null /*history*/)); + } + + /** Sets the test activity's result to pass including a test report log result and history. */ + public static void setPassedResult(Activity activity, String testId, String testDetails, + ReportLog reportLog, TestResultHistoryCollection historyCollection) { + activity.setResult(Activity.RESULT_OK, createResult(activity, TEST_RESULT_PASSED, testId, + testDetails, reportLog, historyCollection)); } /** Sets the test activity's result to failed. */ @@ -65,22 +75,30 @@ public class TestResult { public static void setFailedResult(Activity activity, String testId, String testDetails, ReportLog reportLog) { activity.setResult(Activity.RESULT_OK, createResult(activity, TEST_RESULT_FAILED, testId, - testDetails, reportLog)); + testDetails, reportLog, null /*history*/)); + } + + /** Sets the test activity's result to failed including a test report log result and history. */ + public static void setFailedResult(Activity activity, String testId, String testDetails, + ReportLog reportLog, TestResultHistoryCollection historyCollection) { + activity.setResult(Activity.RESULT_OK, createResult(activity, TEST_RESULT_FAILED, testId, + testDetails, reportLog, historyCollection)); } public static Intent createResult(Activity activity, int testResult, String testName, - String testDetails, ReportLog reportLog) { + String testDetails, ReportLog reportLog, TestResultHistoryCollection historyCollection) { Intent data = new Intent(activity, activity.getClass()); - addResultData(data, testResult, testName, testDetails, reportLog); + addResultData(data, testResult, testName, testDetails, reportLog, historyCollection); return data; } public static void addResultData(Intent intent, int testResult, String testName, - String testDetails, ReportLog reportLog) { + String testDetails, ReportLog reportLog, TestResultHistoryCollection historyCollection) { intent.putExtra(TEST_NAME, testName); intent.putExtra(TEST_RESULT, testResult); intent.putExtra(TEST_DETAILS, testDetails); intent.putExtra(TEST_METRICS, reportLog); + intent.putExtra(TEST_HISTORY_COLLECTION, historyCollection); } /** @@ -92,15 +110,20 @@ public class TestResult { int result = data.getIntExtra(TEST_RESULT, TEST_RESULT_NOT_EXECUTED); String details = data.getStringExtra(TEST_DETAILS); ReportLog reportLog = (ReportLog) data.getSerializableExtra(TEST_METRICS); - return new TestResult(name, result, details, reportLog); + TestResultHistoryCollection historyCollection = + (TestResultHistoryCollection) data.getSerializableExtra(TEST_HISTORY_COLLECTION); + return new TestResult(name, result, details, reportLog, historyCollection); } private TestResult( - String name, int result, String details, ReportLog reportLog) { + String name, int result, String details, ReportLog reportLog, + TestResultHistoryCollection historyCollection) { this.mName = name; this.mResult = result; this.mDetails = details; this.mReportLog = reportLog; + this.mHistoryCollection = + historyCollection == null ? new TestResultHistoryCollection() : historyCollection; } /** Return the name of the test like "com.android.cts.verifier.foo.FooTest" */ @@ -122,4 +145,9 @@ public class TestResult { public ReportLog getReportLog() { return mReportLog; } + + /** @return the {@link TestResultHistoryCollection} containing test history */ + public TestResultHistoryCollection getHistoryCollection() { + return mHistoryCollection; + } } diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/TestResultHistoryCollection.java b/apps/CtsVerifier/src/com/android/cts/verifier/TestResultHistoryCollection.java new file mode 100644 index 00000000000..0e7160ce635 --- /dev/null +++ b/apps/CtsVerifier/src/com/android/cts/verifier/TestResultHistoryCollection.java @@ -0,0 +1,81 @@ +package com.android.cts.verifier; + +import com.android.compatibility.common.util.TestResultHistory; + +import java.io.Serializable; +import java.util.AbstractMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class TestResultHistoryCollection implements Serializable { + + private final Set<TestResultHistory> mHistoryCollection = new HashSet<>(); + + /** + * Covert object to set. + * + * @return A set of test result history. + */ + public Set<TestResultHistory> asSet() { + return mHistoryCollection; + } + + /** + * Add a test result history with test name, start time and end time. + * + * @param test a string of test name. + * @param start start time of a test. + * @param end end time of a test. + */ + public void add(String test, long start, long end) { + Set<Map.Entry> duration = new HashSet<>(); + duration.add(new AbstractMap.SimpleEntry<>(start, end)); + mHistoryCollection.add(new TestResultHistory(test, duration)); + } + + /** + * Add test result histories for tests containing test name and a set of execution time. + * + * @param test test name. + * @param durations set of start and end time. + */ + public void addAll(String test, Set<Map.Entry> durations) { + TestResultHistory history = new TestResultHistory(test, durations); + boolean match = false; + for (TestResultHistory resultHistory: mHistoryCollection) { + if (resultHistory.getTestName().equals(test)) { + resultHistory.getDurations().addAll(durations); + match = true; + break; + } + } + if (match == false) { + mHistoryCollection.add(history); + } + } + + /** + * Merge test with its sub-tests result histories. + * + * @param prefix optional test name prefix to apply. + * @param resultHistoryCollection a set of test result histories. + */ + public void merge(String prefix, TestResultHistoryCollection resultHistoryCollection) { + if (resultHistoryCollection != null) { + resultHistoryCollection.asSet().forEach(t-> addAll( + prefix != null ? prefix + ":" + t.getTestName() : t.getTestName(), t.getDurations())); + } + } + + /** + * Merge test with its sub-tests result histories. + * + * @param prefix optional test name prefix to apply. + * @param resultHistories a list of test result history collection. + */ + public void merge(String prefix, List<TestResultHistoryCollection> resultHistories) { + resultHistories.forEach(resultHistoryCollection -> merge(prefix, resultHistoryCollection)); + } +} diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsProvider.java b/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsProvider.java index 64c04eb8249..bdf32fa35e3 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsProvider.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsProvider.java @@ -78,6 +78,9 @@ public class TestResultsProvider extends ContentProvider { /** ReportLog containing the test result metrics. */ static final String COLUMN_TEST_METRICS = "testmetrics"; + /** TestResultHistory containing the test run histories. */ + static final String COLUMN_TEST_RESULT_HISTORY = "testresulthistory"; + private static final UriMatcher URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH); private static final int RESULTS_ALL = 1; private static final int RESULTS_ID = 2; @@ -120,7 +123,8 @@ public class TestResultsProvider extends ContentProvider { + COLUMN_TEST_RESULT + " INTEGER," + COLUMN_TEST_INFO_SEEN + " INTEGER DEFAULT 0," + COLUMN_TEST_DETAILS + " TEXT," - + COLUMN_TEST_METRICS + " BLOB);"); + + COLUMN_TEST_METRICS + " BLOB," + + COLUMN_TEST_RESULT_HISTORY + " BLOB);"); } @Override @@ -226,12 +230,13 @@ public class TestResultsProvider extends ContentProvider { } static void setTestResult(Context context, String testName, int testResult, - String testDetails, ReportLog reportLog) { + String testDetails, ReportLog reportLog, TestResultHistoryCollection historyCollection) { ContentValues values = new ContentValues(2); values.put(TestResultsProvider.COLUMN_TEST_RESULT, testResult); values.put(TestResultsProvider.COLUMN_TEST_NAME, testName); values.put(TestResultsProvider.COLUMN_TEST_DETAILS, testDetails); values.put(TestResultsProvider.COLUMN_TEST_METRICS, serialize(reportLog)); + values.put(TestResultsProvider.COLUMN_TEST_RESULT_HISTORY, serialize(historyCollection)); final Uri uri = getResultContentUri(context); ContentResolver resolver = context.getContentResolver(); diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsReport.java b/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsReport.java index 8893e0d4938..d9d63c26c2d 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsReport.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsReport.java @@ -29,6 +29,7 @@ import com.android.compatibility.common.util.InvocationResult; import com.android.compatibility.common.util.ITestResult; import com.android.compatibility.common.util.MetricsXmlSerializer; import com.android.compatibility.common.util.ReportLog; +import com.android.compatibility.common.util.TestResultHistory; import com.android.compatibility.common.util.TestStatus; import com.android.cts.verifier.TestListAdapter.TestListItem; @@ -38,9 +39,16 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.text.DateFormat; import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.ArrayList; import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.Map.Entry; +import java.util.Set; /** * Helper class for creating an {@code InvocationResult} for CTS result generation. @@ -135,6 +143,27 @@ class TestResultsReport { if (reportLog != null) { currentTestResult.setReportLog(reportLog); } + + TestResultHistoryCollection historyCollection = mAdapter.getHistoryCollection(i); + if (historyCollection != null) { + // Get non-terminal prefixes. + Set<String> prefixes = new HashSet<>(); + for (TestResultHistory history: historyCollection.asSet()) { + Arrays.stream(history.getTestName().split(":")).reduce( + (total, current) -> { prefixes.add(total); + return total + ":" + current; + }); + } + + // Filter out non-leaf test histories. + List<TestResultHistory> leafTestHistories = new ArrayList<TestResultHistory>(); + for (TestResultHistory history: historyCollection.asSet()) { + if (!prefixes.contains(history.getTestName())) { + leafTestHistories.add(history); + } + } + currentTestResult.setTestResultHistories(leafTestHistories); + } } } moduleResult.setDone(true); diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundSpeakerTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundSpeakerTestActivity.java index 87618b17399..01802a443a0 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundSpeakerTestActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundSpeakerTestActivity.java @@ -280,9 +280,9 @@ public class HifiUltrasoundSpeakerTestActivity extends PassFailButtons.Activity Arrays.asList(powerWrap), ""); LineAndPointFormatter seriesFormat = new LineAndPointFormatter(); + seriesFormat.setPointLabelFormatter(new PointLabelFormatter()); seriesFormat.configure(getApplicationContext(), R.xml.ultrasound_line_formatter_trials); - seriesFormat.setPointLabelFormatter(new PointLabelFormatter()); plot.addSeries(series, seriesFormat); } @@ -297,9 +297,9 @@ public class HifiUltrasoundSpeakerTestActivity extends PassFailButtons.Activity Arrays.asList(noiseDBWrap), "background noise"); LineAndPointFormatter noiseSeriesFormat = new LineAndPointFormatter(); + noiseSeriesFormat.setPointLabelFormatter(new PointLabelFormatter()); noiseSeriesFormat.configure(getApplicationContext(), R.xml.ultrasound_line_formatter_noise); - noiseSeriesFormat.setPointLabelFormatter(new PointLabelFormatter()); plot.addSeries(noiseSeries, noiseSeriesFormat); double[] dB = wavAnalyzerTask.getDB(); @@ -313,9 +313,9 @@ public class HifiUltrasoundSpeakerTestActivity extends PassFailButtons.Activity Arrays.asList(dBWrap), "median"); LineAndPointFormatter seriesFormat = new LineAndPointFormatter(); + seriesFormat.setPointLabelFormatter(new PointLabelFormatter()); seriesFormat.configure(getApplicationContext(), R.xml.ultrasound_line_formatter_median); - seriesFormat.setPointLabelFormatter(new PointLabelFormatter()); plot.addSeries(series, seriesFormat); Double[] passX = new Double[] {Common.MIN_FREQUENCY_HZ, Common.MAX_FREQUENCY_HZ}; @@ -323,9 +323,9 @@ public class HifiUltrasoundSpeakerTestActivity extends PassFailButtons.Activity XYSeries passSeries = new SimpleXYSeries( Arrays.asList(passX), Arrays.asList(passY), "passing"); LineAndPointFormatter passSeriesFormat = new LineAndPointFormatter(); + passSeriesFormat.setPointLabelFormatter(new PointLabelFormatter()); passSeriesFormat.configure(getApplicationContext(), R.xml.ultrasound_line_formatter_pass); - passSeriesFormat.setPointLabelFormatter(new PointLabelFormatter()); plot.addSeries(passSeries, passSeriesFormat); } } 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 67f82d0ddfd..71dce24894b 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java @@ -679,6 +679,8 @@ public class ByodFlowTestActivity extends DialogTestListActivity { private void queryProfileOwner(boolean showToast) { try { + // Set execution start time for counting test execution time. + mStartTime = System.currentTimeMillis(); Intent intent = new Intent(ByodHelperActivity.ACTION_QUERY_PROFILE_OWNER); startActivityForResult(intent, REQUEST_PROFILE_OWNER_STATUS); } 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 ff4f540e666..0cc57a806bc 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java @@ -478,6 +478,8 @@ public class DeviceOwnerPositiveTestActivity extends PassFailButtons.TestListAct } private Intent createCreateManagedUserIntent() { + // Set execution start time for counting test execution time. + mStartTime = System.currentTimeMillis(); return new Intent(this, CommandReceiverActivity.class) .putExtra(CommandReceiverActivity.EXTRA_COMMAND, CommandReceiverActivity.COMMAND_CREATE_MANAGED_USER); diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/RecentsRedactionActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/RecentsRedactionActivity.java index a49985db339..2f1c21e1829 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/RecentsRedactionActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/RecentsRedactionActivity.java @@ -67,7 +67,7 @@ public class RecentsRedactionActivity extends DialogTestListActivity { throw new IllegalArgumentException("Unknown id: " + target.getId()); } Intent resultIntent = TestResult.createResult(RecentsRedactionActivity.this, resultCode, - getTestId(), getTestDetails(), getReportLog()); + getTestId(), getTestDetails(), getReportLog(), getHistoryCollection()); new ByodFlowTestHelper(this).sendResultToPrimary(resultIntent); finish(); diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/TurnOffWorkActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/TurnOffWorkActivity.java index c0a16267839..ef2d7987563 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/TurnOffWorkActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/TurnOffWorkActivity.java @@ -65,10 +65,15 @@ public class TurnOffWorkActivity extends DialogTestListActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + // Set execution start time when start this activity for counting test execution time. + mStartTime = System.currentTimeMillis(); mPrepareTestButton.setText(R.string.provisioning_byod_turn_off_work_prepare_button); mPrepareTestButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { + // Set execution start time when users start to turn/off work profile for counting + // test execution time. + mStartTime = System.currentTimeMillis(); try { startActivity(new Intent(Settings.ACTION_SYNC_SETTINGS)); } catch (ActivityNotFoundException e) { diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/BroadcastTestBase.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/BroadcastTestBase.java index bf5dc391fa0..2dd54e6babd 100644 --- a/common/device-side/util-axt/src/com/android/compatibility/common/util/BroadcastTestBase.java +++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/BroadcastTestBase.java @@ -18,11 +18,15 @@ package com.android.compatibility.common.util; import android.content.BroadcastReceiver; import android.content.ComponentName; +import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; +import android.database.ContentObserver; +import android.net.Uri; import android.os.Bundle; +import android.os.Handler; import android.test.ActivityInstrumentationTestCase2; import android.util.Log; @@ -120,4 +124,36 @@ public class BroadcastTestBase extends ActivityInstrumentationTestCase2< } } } + + protected CountDownLatch registerForChanges(Uri uri) throws Exception { + final CountDownLatch latch = new CountDownLatch(1); + final ContentResolver resolver = mActivity.getContentResolver(); + mActivity.runOnUiThread(() -> { + resolver.registerContentObserver(uri, true, + new ContentObserver(new Handler()) { + @Override + public void onChange(boolean selfChange) { + latch.countDown(); + resolver.unregisterContentObserver(this); + } + }); + }); + return latch; + } + + protected boolean startTestAndWaitForChange(BroadcastUtils.TestcaseType testCaseType, Uri uri, + String pkg, String cls) + throws Exception { + Log.i(TAG, "Begin Testing: " + testCaseType); + registerBroadcastReceiver(testCaseType); + CountDownLatch latch = registerForChanges(uri); + mActivity.startTest(testCaseType.toString(), pkg, cls); + if (!mLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS) + || !latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)) { + fail("Failed to change in " + TIMEOUT_MS + "msec"); + return false; + } + return true; + } + } diff --git a/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTestCase.java b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTestCase.java index 61883033b6d..6be66127b2a 100644 --- a/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTestCase.java +++ b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTestCase.java @@ -147,7 +147,8 @@ abstract class DocumentsClientTestCase extends InstrumentationTestCase { protected boolean supportedHardwareForScopedDirectoryAccess() { final PackageManager pm = getInstrumentation().getContext().getPackageManager(); - if (pm.hasSystemFeature("android.hardware.type.watch") + if (pm.hasSystemFeature("android.hardware.type.television") + || pm.hasSystemFeature("android.hardware.type.watch") || pm.hasSystemFeature("android.hardware.type.automotive")) { return false; } diff --git a/hostsidetests/devicepolicy/app/TransferOwnerIncomingApp/src/com/android/cts/transferowner/TransferDeviceOwnerIncomingTest.java b/hostsidetests/devicepolicy/app/TransferOwnerIncomingApp/src/com/android/cts/transferowner/TransferDeviceOwnerIncomingTest.java index f39dbbe3c97..65c952f281a 100644 --- a/hostsidetests/devicepolicy/app/TransferOwnerIncomingApp/src/com/android/cts/transferowner/TransferDeviceOwnerIncomingTest.java +++ b/hostsidetests/devicepolicy/app/TransferOwnerIncomingApp/src/com/android/cts/transferowner/TransferDeviceOwnerIncomingTest.java @@ -38,7 +38,7 @@ public class TransferDeviceOwnerIncomingTest extends DeviceAndProfileOwnerTransf assertEquals(Collections.singletonList("test.package"), mDevicePolicyManager.getKeepUninstalledPackages(mIncomingComponentName)); assertEquals(123, mDevicePolicyManager.getPasswordMinimumLength(mIncomingComponentName)); - assertSystemPoliciesEqual(SystemUpdatePolicy.createWindowedInstallPolicy(123, 456), + assertSystemPoliciesEqual(SystemUpdatePolicy.createPostponeInstallPolicy(), mDevicePolicyManager.getSystemUpdatePolicy()); assertThrows(SecurityException.class, () -> { mDevicePolicyManager.getParentProfileInstance(mIncomingComponentName); diff --git a/hostsidetests/devicepolicy/app/TransferOwnerOutgoingApp/src/com/android/cts/transferowner/TransferDeviceOwnerOutgoingTest.java b/hostsidetests/devicepolicy/app/TransferOwnerOutgoingApp/src/com/android/cts/transferowner/TransferDeviceOwnerOutgoingTest.java index b42b2bd9cf6..ce8736f8686 100644 --- a/hostsidetests/devicepolicy/app/TransferOwnerOutgoingApp/src/com/android/cts/transferowner/TransferDeviceOwnerOutgoingTest.java +++ b/hostsidetests/devicepolicy/app/TransferOwnerOutgoingApp/src/com/android/cts/transferowner/TransferDeviceOwnerOutgoingTest.java @@ -47,7 +47,7 @@ public class TransferDeviceOwnerOutgoingTest extends DeviceAndProfileOwnerTransf mDevicePolicyManager.setKeepUninstalledPackages(mOutgoingComponentName, Collections.singletonList("test.package")); mDevicePolicyManager.setSystemUpdatePolicy(mOutgoingComponentName, - SystemUpdatePolicy.createWindowedInstallPolicy(123, 456)); + SystemUpdatePolicy.createPostponeInstallPolicy()); PersistableBundle b = new PersistableBundle(); mDevicePolicyManager.transferOwnership(mOutgoingComponentName, INCOMING_COMPONENT_NAME, b); diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java index eecf6dffe36..145cf9ba866 100644 --- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java +++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java @@ -46,6 +46,8 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.annotation.Nullable; @@ -579,21 +581,15 @@ public class BaseDevicePolicyTest extends DeviceTestCase implements IBuildReceiv protected int getUserSerialNumber(int userId) throws DeviceNotAvailableException{ // TODO: Move this logic to ITestDevice. - // dumpsys user return lines like "UserInfo{0:Owner:13} serialNo=0" - String commandOutput = getDevice().executeShellCommand("dumpsys user"); - String[] tokens = commandOutput.split("\\n"); - for (String token : tokens) { - token = token.trim(); - if (token.contains("UserInfo{" + userId + ":")) { - String[] split = token.split("serialNo="); - assertTrue(split.length == 2); - int serialNumber = Integer.parseInt(split[1]); - CLog.d("Serial number of user " + userId + ": " - + serialNumber); - return serialNumber; - } - } - fail("Couldn't find user " + userId); + // dumpsys user output contains lines like "UserInfo{0:Owner:13} serialNo=0 isPrimary=true" + final Pattern pattern = + Pattern.compile("UserInfo\\{" + userId + ":[^\\n]*\\sserialNo=(\\d+)\\s"); + final String commandOutput = getDevice().executeShellCommand("dumpsys user"); + final Matcher matcher = pattern.matcher(commandOutput); + if (matcher.find()) { + return Integer.parseInt(matcher.group(1)); + } + fail("Couldn't find serial number for user " + userId); return -1; } diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java index edc2ff63a9e..11353184066 100644 --- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java +++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java @@ -620,6 +620,11 @@ public abstract class DeviceAndProfileOwnerTest extends BaseDevicePolicyTest { return; } + if (!hasService("wallpaper")) { + CLog.d("testSetWallpaper_disallowed(): device does not support wallpapers"); + return; + } + installAppAsUser(CUSTOMIZATION_APP_APK, mUserId); try { changeUserRestrictionOrFail(DISALLOW_SET_WALLPAPER, true, mUserId); @@ -636,6 +641,10 @@ public abstract class DeviceAndProfileOwnerTest extends BaseDevicePolicyTest { if (!mHasFeature) { return; } + if (!hasService("wallpaper")) { + CLog.d("testDisallowSetWallpaper_allowed(): device does not support wallpapers"); + return; + } executeDeviceTestMethod(".CustomizationRestrictionsTest", "testDisallowSetWallpaper_allowed"); } @@ -1144,4 +1153,19 @@ public abstract class DeviceAndProfileOwnerTest extends BaseDevicePolicyTest { getDevice().executeShellCommand( restricted ? RESTRICT_BACKGROUND_ON_CMD : RESTRICT_BACKGROUND_OFF_CMD); } + + // TODO: copied from RequiredServiceRule, which is on compatibility-device-util + // (and we use compatibility-host-util) + public boolean hasService(String service) { + // TODO: ideally should call SystemServiceManager directly, but we would need to open + // some @Testing APIs for that. + String command = "service check " + service; + try { + String commandOutput = getDevice().executeShellCommand(command); + return !commandOutput.contains("not found"); + } catch (Exception e) { + CLog.w("Exception running '" + command + "': " + e); + return false; + } + } } diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java index 83e8de28276..09c7a4cbb4b 100644 --- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java +++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java @@ -623,7 +623,8 @@ public class DeviceOwnerTest extends BaseDevicePolicyTest { if (!mHasFeature) { return; } - executeDeviceOwnerTest("SystemUpdatePolicyTest"); + // Disabled due to 145932189 + // executeDeviceOwnerTest("SystemUpdatePolicyTest"); } public void testWifiConfigLockdown() throws Exception { diff --git a/hostsidetests/dumpsys/src/android/dumpsys/cts/BatteryStatsDumpsysTest.java b/hostsidetests/dumpsys/src/android/dumpsys/cts/BatteryStatsDumpsysTest.java index 0614db62658..0614db62658 100644..100755 --- a/hostsidetests/dumpsys/src/android/dumpsys/cts/BatteryStatsDumpsysTest.java +++ b/hostsidetests/dumpsys/src/android/dumpsys/cts/BatteryStatsDumpsysTest.java diff --git a/hostsidetests/gputools/src/android/gputools/cts/CtsRootlessGpuDebugHostTest.java b/hostsidetests/gputools/src/android/gputools/cts/CtsRootlessGpuDebugHostTest.java index c17436bbef7..cb35e633d4b 100644 --- a/hostsidetests/gputools/src/android/gputools/cts/CtsRootlessGpuDebugHostTest.java +++ b/hostsidetests/gputools/src/android/gputools/cts/CtsRootlessGpuDebugHostTest.java @@ -194,7 +194,7 @@ public class CtsRootlessGpuDebugHostTest implements IDeviceTest { mDevice.executeAdbCommand("shell", "settings", "delete", "global", "enable_gpu_debug_layers"); mDevice.executeAdbCommand("shell", "settings", "delete", "global", "gpu_debug_app"); mDevice.executeAdbCommand("shell", "settings", "delete", "global", "gpu_debug_layers"); - mDevice.executeAdbCommand("shell", "setprop", "debug.vulkan.layers", "\'\"\"\'"); + mDevice.executeAdbCommand("shell", "setprop", "debug.vulkan.layers", "\'\'"); } /** diff --git a/hostsidetests/incident/src/com/android/server/cts/GraphicsStatsValidationTest.java b/hostsidetests/incident/src/com/android/server/cts/GraphicsStatsValidationTest.java index 1041638f70f..dd7a448ae42 100644 --- a/hostsidetests/incident/src/com/android/server/cts/GraphicsStatsValidationTest.java +++ b/hostsidetests/incident/src/com/android/server/cts/GraphicsStatsValidationTest.java @@ -65,11 +65,9 @@ public class GraphicsStatsValidationTest extends ProtoDumpTestCase { int frameDelta = summaryAfter.getTotalFrames() - summaryBefore.getTotalFrames(); int jankyDelta = summaryAfter.getJankyFrames() - summaryBefore.getJankyFrames(); // We expect 11 frames to have been drawn (first frame + the 10 more explicitly requested) - assertTrue(frameDelta < 15); - assertTrue(jankyDelta < 5); + assertTrue(frameDelta >= 11); + assertTrue(jankyDelta >= 1); int veryJankyDelta = countFramesAbove(statsAfter, 40) - countFramesAbove(statsBefore, 40); - // The 1st frame could be >40ms, but nothing after that should be - assertTrue(veryJankyDelta <= 1); } public void testJankyDrawFrame() throws Exception { diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java b/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java index 23e2d6c9e3f..23355a6ac83 100644 --- a/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java +++ b/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java @@ -78,7 +78,7 @@ public class AtomTestCase extends BaseTestCase { /** ID of the config, which evaluates to -1572883457. */ public static final long CONFIG_ID = "cts_config".hashCode(); - protected static final int WAIT_TIME_SHORT = 500; + protected static final int WAIT_TIME_SHORT = 1000; protected static final int WAIT_TIME_LONG = 2_000; protected static final long SCREEN_STATE_CHANGE_TIMEOUT = 4000; diff --git a/hostsidetests/theme/app/Android.mk b/hostsidetests/theme/app/Android.mk index 1d5a6f0d262..90999f8556e 100644 --- a/hostsidetests/theme/app/Android.mk +++ b/hostsidetests/theme/app/Android.mk @@ -38,6 +38,6 @@ LOCAL_PACKAGE_NAME := CtsThemeDeviceApp # Tag this module as a cts test artifact LOCAL_COMPATIBILITY_SUITE := cts vts general-tests -LOCAL_SDK_VERSION := 23 +LOCAL_SDK_VERSION := test_current include $(BUILD_CTS_SUPPORT_PACKAGE) diff --git a/hostsidetests/theme/app/AndroidManifest.xml b/hostsidetests/theme/app/AndroidManifest.xml index 0f3c1de0436..a351a01a192 100755 --- a/hostsidetests/theme/app/AndroidManifest.xml +++ b/hostsidetests/theme/app/AndroidManifest.xml @@ -18,8 +18,6 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android.theme.app"> - <uses-sdk android:minSdkVersion="17" /> - <uses-permission android:name="android.permission.DISABLE_KEYGUARD" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> diff --git a/hostsidetests/theme/app/src/android/theme/app/LayoutModifier.java b/hostsidetests/theme/app/src/android/theme/app/LayoutModifier.java index 844c578c7b3..e0071292145 100644 --- a/hostsidetests/theme/app/src/android/theme/app/LayoutModifier.java +++ b/hostsidetests/theme/app/src/android/theme/app/LayoutModifier.java @@ -23,12 +23,19 @@ import android.view.View; */ public interface LayoutModifier { - /** Actions to take before inflating the view. */ - void prepare(); + /** + * Modifies the view before it has been added to a parent. Useful for avoiding animations in + * response to setter calls. + * + * @param view the view inflated by the test activity + */ + void modifyViewBeforeAdd(View view); /** - * @param view inflated by the test activity - * @return the same view or another view that will be snapshotted by the test + * Modifies the view after it has been added to a parent. Useful for running animations in + * response to setter calls. + * + * @param view the view inflated by the test activity */ - View modifyView(View view); + void modifyViewAfterAdd(View view); } diff --git a/hostsidetests/theme/app/src/android/theme/app/ReferenceImagesTest.java b/hostsidetests/theme/app/src/android/theme/app/ReferenceImagesTest.java index 6e0731d7478..3707bb13c83 100644 --- a/hostsidetests/theme/app/src/android/theme/app/ReferenceImagesTest.java +++ b/hostsidetests/theme/app/src/android/theme/app/ReferenceImagesTest.java @@ -16,26 +16,47 @@ package android.theme.app; -import android.test.ActivityInstrumentationTestCase2; +import static org.junit.Assert.assertTrue; + +import android.app.Instrumentation; + +import androidx.test.InstrumentationRegistry; +import androidx.test.rule.ActivityTestRule; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; import java.io.File; /** - * Activity test case used to instrument generation of reference images. + * Test used to instrument generation of reference images. */ -public class ReferenceImagesTest extends ActivityInstrumentationTestCase2<GenerateImagesActivity> { +@RunWith(AndroidJUnit4.class) +public class ReferenceImagesTest { + private Instrumentation mInstrumentation; + private GenerateImagesActivity mActivity; - /** Overall test timeout is 30 minutes. Should only take about 5. */ + // Overall test timeout is 30 minutes. Should only take about 5. private static final int TEST_RESULT_TIMEOUT = 30 * 60 * 1000; - public ReferenceImagesTest() { - super(GenerateImagesActivity.class); + @Rule + public ActivityTestRule<GenerateImagesActivity> mActivityRule = + new ActivityTestRule<>(GenerateImagesActivity.class); + + @Before + public void setup() { + mInstrumentation = InstrumentationRegistry.getInstrumentation(); + mInstrumentation.setInTouchMode(true); + + mActivity = mActivityRule.getActivity(); } + @Test public void testGenerateReferenceImages() throws Exception { - setActivityInitialTouchMode(true); - - final GenerateImagesActivity activity = getActivity(); + final GenerateImagesActivity activity = mActivity; assertTrue("Activity failed to complete within " + TEST_RESULT_TIMEOUT + " ms", activity.waitForCompletion(TEST_RESULT_TIMEOUT)); assertTrue(activity.getFinishReason(), activity.isFinishSuccess()); diff --git a/hostsidetests/theme/app/src/android/theme/app/ThemeDeviceActivity.java b/hostsidetests/theme/app/src/android/theme/app/ThemeDeviceActivity.java index 9469a0cb5fe..b30ffd3f45e 100644 --- a/hostsidetests/theme/app/src/android/theme/app/ThemeDeviceActivity.java +++ b/hostsidetests/theme/app/src/android/theme/app/ThemeDeviceActivity.java @@ -16,7 +16,9 @@ package android.theme.app; +import android.animation.ValueAnimator; import android.app.Activity; +import android.content.Context; import android.content.Intent; import android.content.res.Configuration; import android.os.Build; @@ -28,6 +30,7 @@ import android.theme.app.modifiers.TimePickerModifier; import android.theme.app.modifiers.ViewCheckedModifier; import android.theme.app.modifiers.ViewPressedModifier; import android.util.Log; +import android.view.LayoutInflater; import android.view.View; import android.view.WindowManager.LayoutParams; import android.widget.DatePicker; @@ -76,15 +79,20 @@ public class ThemeDeviceActivity extends Activity { mOutputDir = new File(outputDir); mTheme = THEMES[themeIndex]; - setTheme(mTheme.id); + // Disable animations. + ValueAnimator.setDurationScale(0); // Force text scaling to 1.0 regardless of system default. Configuration config = new Configuration(); config.fontScale = 1.0f; - getResources().updateConfiguration(config, null); - setContentView(R.layout.theme_test); - mViewGroup = (ReferenceViewGroup) findViewById(R.id.reference_view_group); + Context inflationContext = createConfigurationContext(config); + inflationContext.setTheme(mTheme.id); + + LayoutInflater layoutInflater = LayoutInflater.from(inflationContext); + setContentView(layoutInflater.inflate(R.layout.theme_test, null)); + + mViewGroup = findViewById(R.id.reference_view_group); getWindow().addFlags(LayoutParams.FLAG_KEEP_SCREEN_ON | LayoutParams.FLAG_TURN_SCREEN_ON @@ -139,24 +147,26 @@ public class ThemeDeviceActivity extends Activity { mViewGroup.removeAllViews(); final Layout layout = LAYOUTS[mLayoutIndex++]; + final LayoutModifier modifier = layout.modifier; final String layoutName = String.format("%s_%s", mTheme.name, layout.name); - final View view = getLayoutInflater().inflate(layout.id, mViewGroup, false); - if (layout.modifier != null) { - layout.modifier.modifyView(view); + final LayoutInflater layoutInflater = LayoutInflater.from(mViewGroup.getContext()); + final View view = layoutInflater.inflate(layout.id, mViewGroup, false); + if (modifier != null) { + modifier.modifyViewBeforeAdd(view); } + view.setFocusable(false); mViewGroup.addView(view); - view.setFocusable(false); + + if (modifier != null) { + modifier.modifyViewAfterAdd(view); + } Log.v(TAG, "Rendering layout " + layoutName + " (" + mLayoutIndex + "/" + LAYOUTS.length + ")"); - final Runnable generateBitmapRunnable = new Runnable() { - @Override - public void run() { - new BitmapTask(view, layoutName).execute(); - } - }; + final Runnable generateBitmapRunnable = () -> + new BitmapTask(view, layoutName, modifier).execute(); if (view instanceof DatePicker && mTheme.spec == Theme.HOLO) { // The Holo-styled DatePicker uses a CalendarView that has a @@ -168,8 +178,12 @@ public class ThemeDeviceActivity extends Activity { } private class BitmapTask extends GenerateBitmapTask { - public BitmapTask(View view, String name) { + private final LayoutModifier mLayoutModifier; + + public BitmapTask(View view, String name, LayoutModifier modifier) { super(view, mOutputDir, name); + + mLayoutModifier = modifier; } @Override @@ -205,6 +219,7 @@ public class ThemeDeviceActivity extends Activity { } // List of themes to verify. + @SuppressWarnings("deprecation") static final Theme[] THEMES = { // Holo new Theme(Theme.HOLO, android.R.style.Theme_Holo, diff --git a/hostsidetests/theme/app/src/android/theme/app/modifiers/AbstractLayoutModifier.java b/hostsidetests/theme/app/src/android/theme/app/modifiers/AbstractLayoutModifier.java index 5c945eff6b0..e9dca7a73be 100644 --- a/hostsidetests/theme/app/src/android/theme/app/modifiers/AbstractLayoutModifier.java +++ b/hostsidetests/theme/app/src/android/theme/app/modifiers/AbstractLayoutModifier.java @@ -17,13 +17,18 @@ package android.theme.app.modifiers; import android.theme.app.LayoutModifier; +import android.view.View; /** - * {@link LayoutModifier} that does nothing in {@link #prepare()}. + * {@link LayoutModifier} that does nothing. */ abstract class AbstractLayoutModifier implements LayoutModifier { @Override - public void prepare() { + public void modifyViewBeforeAdd(View view) { + } + + @Override + public void modifyViewAfterAdd(View view) { } } diff --git a/hostsidetests/theme/app/src/android/theme/app/modifiers/DatePickerModifier.java b/hostsidetests/theme/app/src/android/theme/app/modifiers/DatePickerModifier.java index 26ccd67c791..f155fcb3599 100644 --- a/hostsidetests/theme/app/src/android/theme/app/modifiers/DatePickerModifier.java +++ b/hostsidetests/theme/app/src/android/theme/app/modifiers/DatePickerModifier.java @@ -26,9 +26,8 @@ import android.widget.DatePicker; public class DatePickerModifier extends AbstractLayoutModifier { @Override - public View modifyView(View view) { + public void modifyViewAfterAdd(View view) { DatePicker tp = (DatePicker) view; tp.updateDate(2011, 4, 20); - return view; } } diff --git a/hostsidetests/theme/app/src/android/theme/app/modifiers/ProgressBarModifier.java b/hostsidetests/theme/app/src/android/theme/app/modifiers/ProgressBarModifier.java index 9849a649141..dcd8c893f2d 100644 --- a/hostsidetests/theme/app/src/android/theme/app/modifiers/ProgressBarModifier.java +++ b/hostsidetests/theme/app/src/android/theme/app/modifiers/ProgressBarModifier.java @@ -16,6 +16,7 @@ package android.theme.app.modifiers; +import android.animation.ValueAnimator; import android.view.View; import android.view.animation.Interpolator; import android.widget.ProgressBar; @@ -23,10 +24,9 @@ import android.widget.ProgressBar; public class ProgressBarModifier extends AbstractLayoutModifier { @Override - public View modifyView(View view) { + public void modifyViewBeforeAdd(View view) { ProgressBar pb = (ProgressBar) view; pb.setInterpolator(new ZeroInterpolator()); - return pb; } private static class ZeroInterpolator implements Interpolator { diff --git a/hostsidetests/theme/app/src/android/theme/app/modifiers/SearchViewModifier.java b/hostsidetests/theme/app/src/android/theme/app/modifiers/SearchViewModifier.java index 75dd20a5486..de341cea12e 100644 --- a/hostsidetests/theme/app/src/android/theme/app/modifiers/SearchViewModifier.java +++ b/hostsidetests/theme/app/src/android/theme/app/modifiers/SearchViewModifier.java @@ -34,7 +34,7 @@ public class SearchViewModifier extends AbstractLayoutModifier { } @Override - public View modifyView(View view) { + public void modifyViewBeforeAdd(View view) { SearchView searchView = (SearchView) view; Context context = view.getContext(); @@ -52,6 +52,5 @@ public class SearchViewModifier extends AbstractLayoutModifier { } searchView.setIconifiedByDefault(false); - return searchView; } } diff --git a/hostsidetests/theme/app/src/android/theme/app/modifiers/TimePickerModifier.java b/hostsidetests/theme/app/src/android/theme/app/modifiers/TimePickerModifier.java index b2ed4efcc20..8e06ad8099d 100644 --- a/hostsidetests/theme/app/src/android/theme/app/modifiers/TimePickerModifier.java +++ b/hostsidetests/theme/app/src/android/theme/app/modifiers/TimePickerModifier.java @@ -22,11 +22,10 @@ import android.widget.TimePicker; public class TimePickerModifier extends AbstractLayoutModifier { @Override - public View modifyView(View view) { + public void modifyViewBeforeAdd(View view) { TimePicker timePicker = (TimePicker) view; timePicker.setIs24HourView(true); timePicker.setCurrentHour(13); timePicker.setCurrentMinute(37); - return view; } } diff --git a/hostsidetests/theme/app/src/android/theme/app/modifiers/ViewCheckedModifier.java b/hostsidetests/theme/app/src/android/theme/app/modifiers/ViewCheckedModifier.java index f55f0570e84..78102192a9d 100644 --- a/hostsidetests/theme/app/src/android/theme/app/modifiers/ViewCheckedModifier.java +++ b/hostsidetests/theme/app/src/android/theme/app/modifiers/ViewCheckedModifier.java @@ -22,8 +22,7 @@ import android.widget.CheckBox; public class ViewCheckedModifier extends AbstractLayoutModifier { @Override - public View modifyView(View view) { + public void modifyViewBeforeAdd(View view) { ((CheckBox) view).setChecked(true); - return view; } } diff --git a/hostsidetests/theme/app/src/android/theme/app/modifiers/ViewPressedModifier.java b/hostsidetests/theme/app/src/android/theme/app/modifiers/ViewPressedModifier.java index a94962d3eed..78b329ca9a3 100644 --- a/hostsidetests/theme/app/src/android/theme/app/modifiers/ViewPressedModifier.java +++ b/hostsidetests/theme/app/src/android/theme/app/modifiers/ViewPressedModifier.java @@ -21,8 +21,7 @@ import android.view.View; public class ViewPressedModifier extends AbstractLayoutModifier { @Override - public View modifyView(View view) { + public void modifyViewBeforeAdd(View view) { view.setPressed(true); - return view; } } diff --git a/tests/app/src/android/app/cts/WallpaperManagerTest.java b/tests/app/src/android/app/cts/WallpaperManagerTest.java index a2a0e449b59..0f49281fedf 100644 --- a/tests/app/src/android/app/cts/WallpaperManagerTest.java +++ b/tests/app/src/android/app/cts/WallpaperManagerTest.java @@ -16,6 +16,7 @@ package android.app.cts; +import static org.junit.Assume.assumeTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.nullable; @@ -74,6 +75,7 @@ public class WallpaperManagerTest { MockitoAnnotations.initMocks(this); mContext = InstrumentationRegistry.getTargetContext(); mWallpaperManager = WallpaperManager.getInstance(mContext); + assumeTrue("Device does not support wallpapers", mWallpaperManager.isWallpaperSupported()); final HandlerThread handlerThread = new HandlerThread("TestCallbacks"); handlerThread.start(); mHandler = new Handler(handlerThread.getLooper()); @@ -466,4 +468,4 @@ public class WallpaperManagerTest { public void onColorsChanged(WallpaperColors colors, int which) { } } -}
\ No newline at end of file +} diff --git a/tests/framework/base/windowmanager/src/android/server/wm/DialogFrameTestActivity.java b/tests/framework/base/windowmanager/src/android/server/wm/DialogFrameTestActivity.java index b43b06d50d3..157a83a9705 100644 --- a/tests/framework/base/windowmanager/src/android/server/wm/DialogFrameTestActivity.java +++ b/tests/framework/base/windowmanager/src/android/server/wm/DialogFrameTestActivity.java @@ -25,6 +25,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; import android.app.Activity; import android.app.AlertDialog; import android.content.Intent; +import android.content.pm.PackageManager; import android.view.Gravity; import android.view.Window; import android.view.WindowManager.LayoutParams; @@ -56,7 +57,7 @@ public class DialogFrameTestActivity extends Activity { static final String TEST_WITH_MARGINS = "WithMargins"; private AlertDialog mDialog; - int mSize; + int mSize = 200; @Override protected void onStop() { @@ -72,7 +73,9 @@ public class DialogFrameTestActivity extends Activity { private void setupTest(Intent intent) { final String testCase = intent.getStringExtra(EXTRA_TEST_CASE); - mSize = getSize(); + if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH)) { + mSize = getSize(); + } switch (testCase) { case TEST_MATCH_PARENT: testMatchParent(); diff --git a/tests/framework/base/windowmanager/src/android/server/wm/DialogFrameTests.java b/tests/framework/base/windowmanager/src/android/server/wm/DialogFrameTests.java index 00eb590ae93..7fd635e930d 100644 --- a/tests/framework/base/windowmanager/src/android/server/wm/DialogFrameTests.java +++ b/tests/framework/base/windowmanager/src/android/server/wm/DialogFrameTests.java @@ -35,6 +35,7 @@ import static org.hamcrest.Matchers.greaterThan; import static org.junit.Assert.assertEquals; import android.content.ComponentName; +import android.content.pm.PackageManager; import android.graphics.Rect; import android.platform.test.annotations.AppModeFull; import android.server.am.WaitForValidActivityState; @@ -74,7 +75,10 @@ public class DialogFrameTests extends ParentChildTestBase<DialogFrameTestActivit super.setUp(); } catch (Exception ex) { } - mSize = getSize(); + PackageManager packageManager = InstrumentationRegistry.getContext().getPackageManager(); + if (!packageManager.hasSystemFeature(PackageManager.FEATURE_WATCH)) { + mSize = getSize(); + } } @Override diff --git a/tests/tests/app.usage/res/xml/network_security_config.xml b/tests/tests/app.usage/res/xml/network_security_config.xml index 341cc7bb17b..12ed6580a4c 100644 --- a/tests/tests/app.usage/res/xml/network_security_config.xml +++ b/tests/tests/app.usage/res/xml/network_security_config.xml @@ -15,6 +15,6 @@ --> <network-security-config> <domain-config cleartextTrafficPermitted="true"> - <domain includeSubdomains="true">www.265.com</domain> + <domain includeSubdomains="true">www.developer.android.com</domain> </domain-config> </network-security-config> diff --git a/tests/tests/app.usage/src/android/app/usage/cts/NetworkUsageStatsTest.java b/tests/tests/app.usage/src/android/app/usage/cts/NetworkUsageStatsTest.java index fe8cd6e8956..f1711f4ece9 100644 --- a/tests/tests/app.usage/src/android/app/usage/cts/NetworkUsageStatsTest.java +++ b/tests/tests/app.usage/src/android/app/usage/cts/NetworkUsageStatsTest.java @@ -71,7 +71,12 @@ public class NetworkUsageStatsTest extends InstrumentationTestCase { private static final long MINUTE = 1000 * 60; private static final int TIMEOUT_MILLIS = 15000; - private static final String CHECK_CONNECTIVITY_URL = "http://www.265.com/"; + // The URL needs to return >61KB of data, since the tagged bytes are compared to total bytes + // and they need to be within +/-10% of each other. There is a ~6.1KB constant difference + // between the total and the tagged byte counts. + // This URL in particular was chosen, as it is accessible from inside PRoC, and is not blocked + // by our partners' firewalls. + private static final String CHECK_CONNECTIVITY_URL = "https://developer.android.com/guide"; private static final String CHECK_CALLBACK_URL = CHECK_CONNECTIVITY_URL; private static final int NETWORK_TAG = 0xf00d; diff --git a/tests/tests/car/src/android/car/cts/PermissionTest.java b/tests/tests/car/src/android/car/cts/PermissionTest.java new file mode 100644 index 00000000000..1ab0a8a512b --- /dev/null +++ b/tests/tests/car/src/android/car/cts/PermissionTest.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.car.cts; + +import static android.car.Car.PERMISSION_CAR_TEST_SERVICE; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeTrue; + +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.os.Build; +import android.platform.test.annotations.RequiresDevice; +import android.test.suitebuilder.annotation.SmallTest; + +import androidx.test.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; + +import com.android.compatibility.common.util.FeatureUtil; + +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@SmallTest +@RequiresDevice +@RunWith(AndroidJUnit4.class) +public class PermissionTest { + @Before + public void setUp() { + assumeTrue(FeatureUtil.isAutomotive()); + } + + @Test + public void testNoCarTestServicePermission() { + // This test is valid only in user build. + assumeTrue(Build.TYPE.equals("user")); + + PackageManager pm = InstrumentationRegistry.getContext().getPackageManager(); + List<PackageInfo> holders = pm.getPackagesHoldingPermissions(new String[] { + PERMISSION_CAR_TEST_SERVICE + }, PackageManager.MATCH_UNINSTALLED_PACKAGES); + + assertTrue("No pre-installed packages can have PERMISSION_CAR_TEST_SERVICE: " + holders, + holders.size() == 0); + } +} diff --git a/tests/tests/content/src/android/content/cts/ContextWrapperTest.java b/tests/tests/content/src/android/content/cts/ContextWrapperTest.java index a01e9e02ad4..b2b57538929 100644 --- a/tests/tests/content/src/android/content/cts/ContextWrapperTest.java +++ b/tests/tests/content/src/android/content/cts/ContextWrapperTest.java @@ -18,6 +18,7 @@ package android.content.cts; import android.content.cts.R; +import android.app.WallpaperManager; import android.content.ActivityNotFoundException; import android.content.BroadcastReceiver; import android.content.ComponentName; @@ -265,6 +266,8 @@ public class ContextWrapperTest extends AndroidTestCase { } public void testAccessWallpaper() throws IOException, InterruptedException { + if (!isWallpaperSupported()) return; + // set Wallpaper by contextWrapper#setWallpaper(Bitmap) Bitmap bitmap = Bitmap.createBitmap(20, 30, Bitmap.Config.RGB_565); // Test getWallpaper @@ -499,6 +502,8 @@ public class ContextWrapperTest extends AndroidTestCase { } public void testGetWallpaperDesiredMinimumHeightAndWidth() { + if (!isWallpaperSupported()) return; + int height = mContextWrapper.getWallpaperDesiredMinimumHeight(); int width = mContextWrapper.getWallpaperDesiredMinimumWidth(); @@ -832,6 +837,10 @@ public class ContextWrapperTest extends AndroidTestCase { } } + private boolean isWallpaperSupported() { + return WallpaperManager.getInstance(mContext).isWallpaperSupported(); + } + private static final class MockContextWrapper extends ContextWrapper { public MockContextWrapper(Context base) { super(base); diff --git a/tests/tests/database/src/android/database/sqlite/cts/SQLiteQueryBuilderTest.java b/tests/tests/database/src/android/database/sqlite/cts/SQLiteQueryBuilderTest.java index 97b0b8f5475..4479a5d393c 100644 --- a/tests/tests/database/src/android/database/sqlite/cts/SQLiteQueryBuilderTest.java +++ b/tests/tests/database/src/android/database/sqlite/cts/SQLiteQueryBuilderTest.java @@ -18,6 +18,7 @@ package android.database.sqlite.cts; import android.content.Context; +import android.content.ContentValues; import android.database.Cursor; import android.database.sqlite.SQLiteCursor; import android.database.sqlite.SQLiteCursorDriver; @@ -28,12 +29,15 @@ import android.os.CancellationSignal; import android.os.OperationCanceledException; import android.test.AndroidTestCase; +import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.concurrent.Semaphore; public class SQLiteQueryBuilderTest extends AndroidTestCase { private SQLiteDatabase mDatabase; + private SQLiteQueryBuilder mStrictBuilder; + private final String TEST_TABLE_NAME = "test"; private final String EMPLOYEE_TABLE_NAME = "employee"; private static final String DATABASE_FILE = "database_test.db"; @@ -45,6 +49,9 @@ public class SQLiteQueryBuilderTest extends AndroidTestCase { getContext().deleteDatabase(DATABASE_FILE); mDatabase = getContext().openOrCreateDatabase(DATABASE_FILE, Context.MODE_PRIVATE, null); assertNotNull(mDatabase); + + createEmployeeTable(); + createStrictQueryBuilder(); } @Override @@ -202,8 +209,6 @@ public class SQLiteQueryBuilderTest extends AndroidTestCase { } public void testQuery() { - createEmployeeTable(); - SQLiteQueryBuilder sqliteQueryBuilder = new SQLiteQueryBuilder(); sqliteQueryBuilder.setTables("Employee"); Cursor cursor = sqliteQueryBuilder.query(mDatabase, @@ -276,8 +281,6 @@ public class SQLiteQueryBuilderTest extends AndroidTestCase { } public void testCancelableQuery_WhenNotCanceled_ReturnsResultSet() { - createEmployeeTable(); - CancellationSignal cancellationSignal = new CancellationSignal(); SQLiteQueryBuilder sqliteQueryBuilder = new SQLiteQueryBuilder(); sqliteQueryBuilder.setTables("Employee"); @@ -289,8 +292,6 @@ public class SQLiteQueryBuilderTest extends AndroidTestCase { } public void testCancelableQuery_WhenCanceledBeforeQuery_ThrowsImmediately() { - createEmployeeTable(); - CancellationSignal cancellationSignal = new CancellationSignal(); SQLiteQueryBuilder sqliteQueryBuilder = new SQLiteQueryBuilder(); sqliteQueryBuilder.setTables("Employee"); @@ -307,8 +308,6 @@ public class SQLiteQueryBuilderTest extends AndroidTestCase { } public void testCancelableQuery_WhenCanceledAfterQuery_ThrowsWhenExecuted() { - createEmployeeTable(); - CancellationSignal cancellationSignal = new CancellationSignal(); SQLiteQueryBuilder sqliteQueryBuilder = new SQLiteQueryBuilder(); sqliteQueryBuilder.setTables("Employee"); @@ -327,8 +326,6 @@ public class SQLiteQueryBuilderTest extends AndroidTestCase { } public void testCancelableQuery_WhenCanceledDueToContention_StopsWaitingAndThrows() { - createEmployeeTable(); - for (int i = 0; i < 5; i++) { final CancellationSignal cancellationSignal = new CancellationSignal(); final Semaphore barrier1 = new Semaphore(0); @@ -460,6 +457,152 @@ public class SQLiteQueryBuilderTest extends AndroidTestCase { fail("Could not prove that the query actually canceled midway during execution."); } + public void testStrictQuery() throws Exception { + final SQLiteQueryBuilder qb = mStrictBuilder; + + // Should normally only be able to see one row + try (Cursor c = qb.query(mDatabase, null, null, null, null, null, null)) { + assertEquals(1, c.getCount()); + } + + // Trying sneaky queries should fail; even if they somehow succeed, we + // shouldn't get to see any other data. + try (Cursor c = qb.query(mDatabase, null, "1=1", null, null, null, null)) { + assertEquals(1, c.getCount()); + } catch (Exception tolerated) { + } + try (Cursor c = qb.query(mDatabase, null, "1=1 --", null, null, null, null)) { + assertEquals(1, c.getCount()); + } catch (Exception tolerated) { + } + try (Cursor c = qb.query(mDatabase, null, "1=1) OR (1=1", null, null, null, null)) { + assertEquals(1, c.getCount()); + } catch (Exception tolerated) { + } + try (Cursor c = qb.query(mDatabase, null, "1=1)) OR ((1=1", null, null, null, null)) { + assertEquals(1, c.getCount()); + } catch (Exception tolerated) { + } + } + + private static final String[] COLUMNS_VALID = new String[] { + "_id", + }; + + private static final String[] COLUMNS_INVALID = new String[] { + "salary", + "MAX(salary)", + "undefined", + "(secret_column IN secret_table)", + "(SELECT secret_column FROM secret_table)", + }; + + public void testStrictQueryProjection() throws Exception { + for (String column : COLUMNS_VALID) { + assertStrictQueryValid( + new String[] { column }, null, null, null, null, null, null); + } + for (String column : COLUMNS_INVALID) { + assertStrictQueryInvalid( + new String[] { column }, null, null, null, null, null, null); + } + } + + public void testStrictQueryWhere() throws Exception { + for (String column : COLUMNS_VALID) { + assertStrictQueryValid( + null, column + ">0", null, null, null, null, null); + assertStrictQueryValid( + null, "_id>" + column, null, null, null, null, null); + } + for (String column : COLUMNS_INVALID) { + assertStrictQueryInvalid( + null, column + ">0", null, null, null, null, null); + assertStrictQueryInvalid( + null, "_id>" + column, null, null, null, null, null); + } + } + + public void testStrictQueryGroupBy() { + for (String column : COLUMNS_VALID) { + assertStrictQueryValid( + null, null, null, column, null, null, null); + assertStrictQueryValid( + null, null, null, "_id," + column, null, null, null); + } + for (String column : COLUMNS_INVALID) { + assertStrictQueryInvalid( + null, null, null, column, null, null, null); + assertStrictQueryInvalid( + null, null, null, "_id," + column, null, null, null); + } + } + + public void testStrictQueryHaving() { + for (String column : COLUMNS_VALID) { + assertStrictQueryValid( + null, null, null, "_id", column, null, null); + } + for (String column : COLUMNS_INVALID) { + assertStrictQueryInvalid( + null, null, null, "_id", column, null, null); + } + } + + public void testStrictQueryOrderBy() { + for (String column : COLUMNS_VALID) { + assertStrictQueryValid( + null, null, null, null, null, column, null); + assertStrictQueryValid( + null, null, null, null, null, column + " ASC", null); + assertStrictQueryValid( + null, null, null, null, null, "_id COLLATE NOCASE ASC," + column, null); + } + for (String column : COLUMNS_INVALID) { + assertStrictQueryInvalid( + null, null, null, null, null, column, null); + assertStrictQueryInvalid( + null, null, null, null, null, column + " ASC", null); + assertStrictQueryInvalid( + null, null, null, null, null, "_id COLLATE NOCASE ASC," + column, null); + } + } + + public void testStrictQueryLimit() { + assertStrictQueryValid( + null, null, null, null, null, null, "32"); + assertStrictQueryValid( + null, null, null, null, null, null, "0,32"); + assertStrictQueryValid( + null, null, null, null, null, null, "32 OFFSET 0"); + + for (String column : COLUMNS_VALID) { + assertStrictQueryInvalid( + null, null, null, null, null, null, column); + } + for (String column : COLUMNS_INVALID) { + assertStrictQueryInvalid( + null, null, null, null, null, null, column); + } + } + + private void assertStrictQueryValid(String[] projectionIn, String selection, + String[] selectionArgs, String groupBy, String having, String sortOrder, String limit) { + try (Cursor c = mStrictBuilder.query(mDatabase, projectionIn, selection, selectionArgs, + groupBy, having, sortOrder, limit, null)) { + } + } + + private void assertStrictQueryInvalid(String[] projectionIn, String selection, + String[] selectionArgs, String groupBy, String having, String sortOrder, String limit) { + try (Cursor c = mStrictBuilder.query(mDatabase, projectionIn, selection, selectionArgs, + groupBy, having, sortOrder, limit, null)) { + fail(Arrays.asList(projectionIn, selection, selectionArgs, + groupBy, having, sortOrder, limit).toString()); + } catch (Exception expected) { + } + } + private void createEmployeeTable() { mDatabase.execSQL("CREATE TABLE employee (_id INTEGER PRIMARY KEY, " + "name TEXT, month INTEGER, salary INTEGER);"); @@ -476,4 +619,17 @@ public class SQLiteQueryBuilderTest extends AndroidTestCase { mDatabase.execSQL("INSERT INTO employee (name, month, salary) " + "VALUES ('Jim', '3', '3500');"); } + + private void createStrictQueryBuilder() { + mStrictBuilder = new SQLiteQueryBuilder(); + mStrictBuilder.setTables("employee"); + mStrictBuilder.setStrict(true); + mStrictBuilder.appendWhere("month=2"); + + final Map<String, String> projectionMap = new HashMap<>(); + projectionMap.put("_id", "_id"); + projectionMap.put("name", "name"); + projectionMap.put("month", "month"); + mStrictBuilder.setProjectionMap(projectionMap); + } } diff --git a/tests/tests/nativehardware/jni/AHardwareBufferGLTest.cpp b/tests/tests/nativehardware/jni/AHardwareBufferGLTest.cpp index fd0d37beb69..4e71dc0096f 100644 --- a/tests/tests/nativehardware/jni/AHardwareBufferGLTest.cpp +++ b/tests/tests/nativehardware/jni/AHardwareBufferGLTest.cpp @@ -1043,6 +1043,14 @@ void AHardwareBufferGLTest::SetUpFramebuffer(int width, int height, int layer, GL_RGBA8, GL_DEPTH_COMPONENT16, GL_STENCIL_INDEX8, GL_DEPTH24_STENCIL8 }; GLuint& fbo = mFramebuffers[mWhich]; + GLbitfield clear_bits[] = { + GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT, + GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT + }; + + glClearColor(0.f, 0.f, 0.f, 0.f); + glClearDepthf(1.0f); + glClearStencil(0); glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); for (int i = 0; i < 4; ++i) { @@ -1069,7 +1077,8 @@ void AHardwareBufferGLTest::SetUpFramebuffer(int width, int height, int layer, glGenRenderbuffers(1, &renderbuffer); glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer); ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError()); - if (GetParam().stride & kGlFormat) { + bool isGlFormat = GetParam().stride & kGlFormat; + if (isGlFormat) { glRenderbufferStorage(GL_RENDERBUFFER, GetParam().format, width, height); } else { glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, @@ -1077,6 +1086,8 @@ void AHardwareBufferGLTest::SetUpFramebuffer(int width, int height, int layer, } glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment_points[i], GL_RENDERBUFFER, renderbuffer); + if (isGlFormat) + glClear(clear_bits[i]); break; } case kRenderbuffer: { @@ -1087,6 +1098,7 @@ void AHardwareBufferGLTest::SetUpFramebuffer(int width, int height, int layer, glRenderbufferStorage(GL_RENDERBUFFER, default_formats[i], width, height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment_points[i], GL_RENDERBUFFER, renderbuffer); + glClear(clear_bits[i]); break; } default: FAIL() << "Unrecognized binding type"; diff --git a/tests/tests/opengl/src/android/opengl/cts/EglConfigCtsActivity.java b/tests/tests/opengl/src/android/opengl/cts/EglConfigCtsActivity.java index cef9e2f0b6b..1b8cf77c1d1 100644 --- a/tests/tests/opengl/src/android/opengl/cts/EglConfigCtsActivity.java +++ b/tests/tests/opengl/src/android/opengl/cts/EglConfigCtsActivity.java @@ -16,83 +16,176 @@ package android.opengl.cts; +import static org.junit.Assert.assertTrue; + import android.app.Activity; -import android.content.Intent; +import android.content.Context; import android.opengl.GLSurfaceView; import android.os.Bundle; +import android.util.Log; import android.view.WindowManager; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; +import javax.microedition.khronos.egl.EGL10; +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.egl.EGLContext; +import javax.microedition.khronos.egl.EGLDisplay; + /** * {@link Activity} with a {@link GLSurfaceView} that chooses a specific configuration. */ public class EglConfigCtsActivity extends Activity { + private final String TAG = this.getClass().getSimpleName(); + public static final String CONFIG_ID_EXTRA = "eglConfigId"; public static final String CONTEXT_CLIENT_VERSION_EXTRA = "eglContextClientVersion"; + private static final int EGL_OPENGL_ES_BIT = 0x1; + private static final int EGL_OPENGL_ES2_BIT = 0x4; + private EglConfigGLSurfaceView mView; private CountDownLatch mFinishedDrawing; + private CountDownLatch mFinishedTesting; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - int configId = getConfigId(); - int contextClientVersion = getContextClientVersion(); - setTitle("EGL Config Id: " + configId + " Client Version: " + contextClientVersion); // Dismiss keyguard and keep screen on while this test is on. getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); - mFinishedDrawing = new CountDownLatch(1); - mView = new EglConfigGLSurfaceView(this, configId, contextClientVersion, new Runnable() { - @Override - public void run() { - mFinishedDrawing.countDown(); - } - }); - setContentView(mView); - } - - private int getConfigId() { - Intent intent = getIntent(); - if (intent != null) { - return intent.getIntExtra(CONFIG_ID_EXTRA, 0); - } else { - return 0; - } - } - - private int getContextClientVersion() { - Intent intent = getIntent(); - if (intent != null) { - return intent.getIntExtra(CONTEXT_CLIENT_VERSION_EXTRA, 0); - } else { - return 0; + int[] configIds = getEglConfigIds(EGL_OPENGL_ES_BIT); + int[] configIds2 = getEglConfigIds(EGL_OPENGL_ES2_BIT); + assertTrue(configIds.length + configIds2.length > 0); + mFinishedTesting = new CountDownLatch(configIds.length + configIds2.length); + try { + runConfigTests(configIds, 1); + runConfigTests(configIds2, 2); + } catch (InterruptedException e) { + Log.e(TAG, "Caught exception"); } } @Override protected void onResume() { super.onResume(); - mView.onResume(); + if (mView != null) + { + mView.onResume(); + } } @Override protected void onPause() { super.onPause(); - mView.onPause(); + if (mView != null) + { + mView.onPause(); + } + } + + private void runConfigTests(int[] configIds, int contextClientVersion) + throws InterruptedException { + Context context = this; + Thread thread = new Thread() { + @Override + public void run() { + for (int configId : configIds) { + mFinishedDrawing = new CountDownLatch(1); + + runOnUiThread(new Runnable() { + @Override + public void run() { + setTitle("EGL Config Id: " + configId + " Client Version: " + contextClientVersion); + mView = new EglConfigGLSurfaceView(context, configId, contextClientVersion, new Runnable() { + @Override + public void run() { + mFinishedDrawing.countDown(); + } + }); + setContentView(mView); + } + }); + + try { + waitToFinishDrawing(); + } catch (Exception e) { + Log.e(TAG, "Timed out!"); + } + + mFinishedTesting.countDown(); + } + } + }; + thread.start(); + } + + private void waitToFinishDrawing() throws InterruptedException { + if (!mFinishedDrawing.await(5, TimeUnit.SECONDS)) { + throw new IllegalStateException("Couldn't finish drawing frames!"); + } } - public void waitToFinishDrawing() throws InterruptedException { - if (!mFinishedDrawing.await(3, TimeUnit.SECONDS)) { - throw new IllegalStateException("Coudn't finish drawing frames!"); + void waitToFinishTesting() throws InterruptedException { + if (!mFinishedTesting.await(300, TimeUnit.SECONDS)) { + throw new IllegalStateException("Couldn't finish testing!"); + } + } + + private static int[] getEglConfigIds(int renderableType) { + EGL10 egl = (EGL10) EGLContext.getEGL(); + EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); + int[] numConfigs = new int[1]; + + int[] attributeList = new int[] { + EGL10.EGL_RENDERABLE_TYPE, renderableType, + + // Avoid configs like RGBA0008 which crash even though they have the window bit set. + EGL10.EGL_RED_SIZE, 1, + EGL10.EGL_GREEN_SIZE, 1, + EGL10.EGL_BLUE_SIZE, 1, + + EGL10.EGL_SURFACE_TYPE, EGL10.EGL_WINDOW_BIT, + EGL10.EGL_NONE + }; + + if (egl.eglInitialize(display, null)) { + try { + if (egl.eglChooseConfig(display, attributeList, null, 0, numConfigs)) { + EGLConfig[] configs = new EGLConfig[numConfigs[0]]; + if (egl.eglChooseConfig(display, attributeList, configs, configs.length, + numConfigs)) { + int[] configIds = new int[numConfigs[0]]; + for (int i = 0; i < numConfigs[0]; i++) { + int[] value = new int[1]; + if (egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_CONFIG_ID, + value)) { + configIds[i] = value[0]; + } else { + throw new IllegalStateException("Couldn't call eglGetConfigAttrib"); + } + } + return configIds; + } else { + throw new IllegalStateException("Couldn't call eglChooseConfig (1)"); + } + } else { + throw new IllegalStateException("Couldn't call eglChooseConfig (2)"); + } + } finally { + egl.eglTerminate(display); + } + } else { + throw new IllegalStateException("Couldn't initialize EGL."); } } } diff --git a/tests/tests/opengl/src/android/opengl/cts/EglConfigTest.java b/tests/tests/opengl/src/android/opengl/cts/EglConfigTest.java index 3e5565eb63b..613456adc1a 100644 --- a/tests/tests/opengl/src/android/opengl/cts/EglConfigTest.java +++ b/tests/tests/opengl/src/android/opengl/cts/EglConfigTest.java @@ -25,6 +25,7 @@ import androidx.test.InstrumentationRegistry; import androidx.test.filters.LargeTest; import androidx.test.rule.ActivityTestRule; import androidx.test.runner.AndroidJUnit4; +import static androidx.test.internal.util.Checks.checkState; import org.junit.Before; import org.junit.Rule; @@ -36,14 +37,16 @@ import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.egl.EGLContext; import javax.microedition.khronos.egl.EGLDisplay; +import android.util.Log; +import java.lang.Runnable; + /** * Test that gets a list of EGL configurations and tries to use each one in a GLSurfaceView. */ @LargeTest @RunWith(AndroidJUnit4.class) public class EglConfigTest { - private static final int EGL_OPENGL_ES_BIT = 0x1; - private static final int EGL_OPENGL_ES2_BIT = 0x4; + private final String TAG = this.getClass().getSimpleName(); private Instrumentation mInstrumentation; @@ -58,75 +61,11 @@ public class EglConfigTest { @Test public void testEglConfigs() throws Exception { - int[] configIds = getEglConfigIds(EGL_OPENGL_ES_BIT); - int[] configIds2 = getEglConfigIds(EGL_OPENGL_ES2_BIT); - assertTrue(configIds.length + configIds2.length > 0); - runConfigTests(configIds, 1); - runConfigTests(configIds2, 2); - } - - private void runConfigTests(int[] configIds, int contextClientVersion) - throws InterruptedException { - for (int configId : configIds) { - Intent intent = new Intent(InstrumentationRegistry.getTargetContext(), - EglConfigCtsActivity.class); - intent.putExtra(EglConfigCtsActivity.CONFIG_ID_EXTRA, configId); - intent.putExtra(EglConfigCtsActivity.CONTEXT_CLIENT_VERSION_EXTRA, - contextClientVersion); - EglConfigCtsActivity activity = mActivityRule.launchActivity(intent); - activity.waitToFinishDrawing(); - // TODO(b/30948621): Remove the sleep below once b/30948621 is fixed. - Thread.sleep(500); - activity.finish(); - mInstrumentation.waitForIdleSync(); - } - } - - private static int[] getEglConfigIds(int renderableType) { - EGL10 egl = (EGL10) EGLContext.getEGL(); - EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); - int[] numConfigs = new int[1]; - - int[] attributeList = new int[] { - EGL10.EGL_RENDERABLE_TYPE, renderableType, - - // Avoid configs like RGBA0008 which crash even though they have the window bit set. - EGL10.EGL_RED_SIZE, 1, - EGL10.EGL_GREEN_SIZE, 1, - EGL10.EGL_BLUE_SIZE, 1, - - EGL10.EGL_SURFACE_TYPE, EGL10.EGL_WINDOW_BIT, - EGL10.EGL_NONE - }; - - if (egl.eglInitialize(display, null)) { - try { - if (egl.eglChooseConfig(display, attributeList, null, 0, numConfigs)) { - EGLConfig[] configs = new EGLConfig[numConfigs[0]]; - if (egl.eglChooseConfig(display, attributeList, configs, configs.length, - numConfigs)) { - int[] configIds = new int[numConfigs[0]]; - for (int i = 0; i < numConfigs[0]; i++) { - int[] value = new int[1]; - if (egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_CONFIG_ID, - value)) { - configIds[i] = value[0]; - } else { - throw new IllegalStateException("Couldn't call eglGetConfigAttrib"); - } - } - return configIds; - } else { - throw new IllegalStateException("Couldn't call eglChooseConfig (1)"); - } - } else { - throw new IllegalStateException("Couldn't call eglChooseConfig (2)"); - } - } finally { - egl.eglTerminate(display); - } - } else { - throw new IllegalStateException("Couldn't initialize EGL."); - } + Intent intent = new Intent(InstrumentationRegistry.getTargetContext(), + EglConfigCtsActivity.class); + EglConfigCtsActivity activity = mActivityRule.launchActivity(intent); + activity.waitToFinishTesting(); + activity.finish(); + mInstrumentation.waitForIdleSync(); } } diff --git a/tests/tests/os/Android.mk b/tests/tests/os/Android.mk index cc14790a0c2..89eb4446a77 100644 --- a/tests/tests/os/Android.mk +++ b/tests/tests/os/Android.mk @@ -40,7 +40,8 @@ LOCAL_SRC_FILES := \ src/android/os/cts/IEmptyService.aidl \ src/android/os/cts/ISeccompIsolatedService.aidl \ src/android/os/cts/ISecondary.aidl \ - src/android/os/cts/ISharedMemoryService.aidl + src/android/os/cts/ISharedMemoryService.aidl \ + src/android/os/cts/IParcelExceptionService.aidl \ LOCAL_PACKAGE_NAME := CtsOsTestCases diff --git a/tests/tests/os/AndroidManifest.xml b/tests/tests/os/AndroidManifest.xml index ef4893ee9c1..94074058d62 100644 --- a/tests/tests/os/AndroidManifest.xml +++ b/tests/tests/os/AndroidManifest.xml @@ -80,6 +80,14 @@ android:name="android.os.cts.SharedMemoryService" android:process=":sharedmem" android:exported="false" /> + <service + android:name="android.os.cts.ParcelExceptionService" + android:process=":remote" + android:exported="true" /> + <service + android:name="android.os.cts.ParcelTest$ParcelObjectFreeService" + android:process=":remote" + android:exported="true" /> <service android:name="android.os.cts.LocalService"> <intent-filter> diff --git a/tests/tests/os/src/android/os/cts/EnvironmentTest.java b/tests/tests/os/src/android/os/cts/EnvironmentTest.java index 0f2ac62f166..622d35a01d5 100644 --- a/tests/tests/os/src/android/os/cts/EnvironmentTest.java +++ b/tests/tests/os/src/android/os/cts/EnvironmentTest.java @@ -83,7 +83,12 @@ public class EnvironmentTest extends TestCase { final long maxInodes = maxsize / 4096; // Assuming the smallest storage would be 4GB, min # of free inodes // in EXT4/F2FS must be larger than 128k for Android to work properly. - final long minInodes = 128 * 1024; + long minInodes = 128 * 1024; + final long size4GB = 4294967296l; + //If the storage size is smaller than 4GB, let's consider 32k for 1GB. + if (maxsize < size4GB) { + minInodes = 32 * 1024; + } if (stat.f_ffree >= minInodes && stat.f_ffree <= maxInodes && stat.f_favail <= stat.f_ffree) { diff --git a/tests/tests/os/src/android/os/cts/ExceptionalParcelable.aidl b/tests/tests/os/src/android/os/cts/ExceptionalParcelable.aidl new file mode 100644 index 00000000000..7d0969340cd --- /dev/null +++ b/tests/tests/os/src/android/os/cts/ExceptionalParcelable.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.os.cts; + +parcelable ExceptionalParcelable;
\ No newline at end of file diff --git a/tests/tests/os/src/android/os/cts/ExceptionalParcelable.java b/tests/tests/os/src/android/os/cts/ExceptionalParcelable.java new file mode 100644 index 00000000000..333cf57e8cf --- /dev/null +++ b/tests/tests/os/src/android/os/cts/ExceptionalParcelable.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package android.os.cts; + +import android.os.IBinder; +import android.os.Parcel; +import android.os.Parcelable; + + +public class ExceptionalParcelable implements Parcelable { + private final IBinder mBinder; + + ExceptionalParcelable(IBinder binder) { + mBinder = binder; + } + + public int describeContents() { + return 0; + } + + /** + * Write a binder to the Parcel and then throw an exception + */ + public void writeToParcel(Parcel out, int flags) { + // Write a binder for the exception to overwrite + out.writeStrongBinder(mBinder); + + // Throw an exception + throw new IllegalArgumentException("A truly exceptional message"); + } + + public static final Creator<ExceptionalParcelable> CREATOR = + new Creator<ExceptionalParcelable>() { + @Override + public ExceptionalParcelable createFromParcel(Parcel source) { + return new ExceptionalParcelable(source.readStrongBinder()); + } + + @Override + public ExceptionalParcelable[] newArray(int size) { + return new ExceptionalParcelable[size]; + } + }; +} diff --git a/tests/tests/os/src/android/os/cts/IParcelExceptionService.aidl b/tests/tests/os/src/android/os/cts/IParcelExceptionService.aidl new file mode 100644 index 00000000000..ce7af6deece --- /dev/null +++ b/tests/tests/os/src/android/os/cts/IParcelExceptionService.aidl @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.os.cts; +import android.os.cts.ExceptionalParcelable; + +interface IParcelExceptionService { +//parcelable android.os.cts.ExceptionalParcelable; + ExceptionalParcelable writeBinderThrowException(); +} diff --git a/tests/tests/os/src/android/os/cts/ParcelExceptionService.java b/tests/tests/os/src/android/os/cts/ParcelExceptionService.java new file mode 100644 index 00000000000..d8387e30d41 --- /dev/null +++ b/tests/tests/os/src/android/os/cts/ParcelExceptionService.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package android.os.cts; + +import android.app.Service; +import android.content.Intent; +import android.os.Binder; +import android.os.IBinder; +import android.os.RemoteException; + +public class ParcelExceptionService extends Service { + @Override + public IBinder onBind(Intent intent) { + return new ParcelExceptionServiceImpl(); + } + + private static class ParcelExceptionServiceImpl extends IParcelExceptionService.Stub { + private final IBinder mBinder = new Binder(); + + + @Override + public ExceptionalParcelable writeBinderThrowException() throws RemoteException { + return new ExceptionalParcelable(mBinder); + } + } +} diff --git a/tests/tests/os/src/android/os/cts/ParcelTest.java b/tests/tests/os/src/android/os/cts/ParcelTest.java index 987ab0024ab..762a10e2ae5 100644 --- a/tests/tests/os/src/android/os/cts/ParcelTest.java +++ b/tests/tests/os/src/android/os/cts/ParcelTest.java @@ -24,7 +24,15 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; - +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import android.app.Service; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.ServiceConnection; import android.content.pm.Signature; import android.os.BadParcelableException; import android.os.Binder; @@ -39,6 +47,8 @@ import android.util.Log; import android.util.SparseArray; import android.util.SparseBooleanArray; +import com.google.common.util.concurrent.AbstractFuture; + public class ParcelTest extends AndroidTestCase { public void testObtain() { @@ -3283,4 +3293,119 @@ public class ParcelTest extends AndroidTestCase { // good } } + + public static class ParcelExceptionConnection extends AbstractFuture<IParcelExceptionService> + implements ServiceConnection { + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + set(IParcelExceptionService.Stub.asInterface(service)); + } + + @Override + public void onServiceDisconnected(ComponentName name) { + } + + @Override + public IParcelExceptionService get() throws InterruptedException, ExecutionException { + try { + return get(5, TimeUnit.SECONDS); + } catch (TimeoutException e) { + throw new RuntimeException(e); + } + } + } + + public void testExceptionOverwritesObject() throws Exception { + final Intent intent = new Intent(); + intent.setComponent(new ComponentName( + "android.os.cts", "android.os.cts.ParcelExceptionService")); + + final ParcelExceptionConnection connection = new ParcelExceptionConnection(); + + mContext.startService(intent); + assertTrue(mContext.bindService(intent, connection, + Context.BIND_ABOVE_CLIENT | Context.BIND_EXTERNAL_SERVICE)); + + + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken("android.os.cts.IParcelExceptionService"); + IParcelExceptionService service = connection.get(); + try { + assertTrue("Transaction failed", service.asBinder().transact( + IParcelExceptionService.Stub.TRANSACTION_writeBinderThrowException, data, reply, + 0)); + } catch (Exception e) { + fail("Exception caught from transaction: " + e); + } + reply.setDataPosition(0); + assertTrue("Exception should have occurred on service-side", + reply.readExceptionCode() != 0); + assertNull("Binder should have been overwritten by the exception", + reply.readStrongBinder()); + } + + public static class ParcelObjectFreeService extends Service { + + @Override + public IBinder onBind(Intent intent) { + return new Binder(); + } + + @Override + public void onCreate() { + super.onCreate(); + + Parcel parcel = Parcel.obtain(); + + // Construct parcel with object in it. + parcel.writeInt(1); + final int pos = parcel.dataPosition(); + parcel.writeStrongBinder(new Binder()); + + // wipe out the object by setting data size + parcel.setDataSize(pos); + + // recycle the parcel. This should not cause a native segfault + parcel.recycle(); + } + + public static class Connection extends AbstractFuture<IBinder> + implements ServiceConnection { + + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + set(service); + } + + @Override + public void onServiceDisconnected(ComponentName name) { + } + + @Override + public IBinder get() throws InterruptedException, ExecutionException { + try { + return get(5, TimeUnit.SECONDS); + } catch (TimeoutException e) { + return null; + } + } + } + } + + public void testObjectDoubleFree() throws Exception { + + final Intent intent = new Intent(); + intent.setComponent(new ComponentName( + "android.os.cts", "android.os.cts.ParcelTest$ParcelObjectFreeService")); + + final ParcelObjectFreeService.Connection connection = + new ParcelObjectFreeService.Connection(); + + mContext.startService(intent); + assertTrue(mContext.bindService(intent, connection, + Context.BIND_ABOVE_CLIENT | Context.BIND_EXTERNAL_SERVICE)); + + assertNotNull("Service should have started without crashing.", connection.get()); + } } diff --git a/tests/tests/permission2/res/raw/automotive_android_manifest.xml b/tests/tests/permission2/res/raw/automotive_android_manifest.xml index 975796d580f..6d6e86705f4 100644 --- a/tests/tests/permission2/res/raw/automotive_android_manifest.xml +++ b/tests/tests/permission2/res/raw/automotive_android_manifest.xml @@ -216,6 +216,12 @@ android:label="@string/car_permission_label_storage_monitoring" android:description="@string/car_permission_desc_storage_monitoring" /> + <permission + android:name="android.car.permission.CAR_TEST_SERVICE" + android:protectionLevel="privileged|signature" + android:label="@string/car_permission_label_car_test_service" + android:description="@string/car_permission_desc_car_test_service" /> + <uses-permission android:name="android.permission.CALL_PHONE" /> <uses-permission android:name="android.permission.DEVICE_POWER" /> <uses-permission android:name="android.permission.GRANT_RUNTIME_PERMISSIONS" /> diff --git a/tests/tests/security/src/android/security/cts/ServicePermissionsTest.java b/tests/tests/security/src/android/security/cts/ServicePermissionsTest.java index bfe1f55e375..bccbe59f88a 100644 --- a/tests/tests/security/src/android/security/cts/ServicePermissionsTest.java +++ b/tests/tests/security/src/android/security/cts/ServicePermissionsTest.java @@ -79,6 +79,8 @@ public class ServicePermissionsTest extends AndroidTestCase { return; } + final ArrayList<String> failures = new ArrayList<>(); + for (String service : services) { mTempFile.delete(); @@ -105,14 +107,18 @@ public class ServicePermissionsTest extends AndroidTestCase { } catch (SecurityException e) { String msg = e.getMessage(); if ((msg == null) || msg.contains("android.permission.DUMP")) { + Log.d(TAG, "Service " + service + " correctly checked permission"); // Service correctly checked for DUMP permission, yay } else { // Service is throwing about something else; they're // probably not checking for DUMP. - throw e; + failures.add("Service " + service + " threw exception: " + e); + continue; } } catch (TransactionTooLargeException | DeadObjectException e) { - // SELinux likely prevented the dump - assume safe + // SELinux likely prevented the dump - assume safe, but log anywasy + // (as the exception might happens in some devices but not on others) + Log.w(TAG, "Service " + service + " threw exception: " + e); continue; } finally { out.close(); @@ -133,19 +139,29 @@ public class ServicePermissionsTest extends AndroidTestCase { } if (lines.size() > 1) { - fail("dump() for " + service + " produced several lines of output; this " + failures.add("dump() for " + service + " produced several lines of output; this " + "may be leaking sensitive data. At most, services should emit a " + "single line when the caller doesn't have DUMP permission."); + continue; } if (lines.size() == 1) { String message = lines.get(0); if (!message.contains("Permission Denial") && !message.contains("android.permission.DUMP")) { - fail("dump() for " + service + " produced a single line which didn't " + failures.add("dump() for " + service + " produced a single line which didn't " + "reference a permission; it may be leaking sensitive data."); + continue; } } } + + if (!failures.isEmpty()) { + StringBuilder msg = new StringBuilder(failures.size() + " services failed:\n"); + for (String failure: failures) { + msg.append(failure).append('\n'); + } + fail(msg.toString()); + } } } diff --git a/tests/tests/slice/src/android/slice/cts/SliceProviderTest.java b/tests/tests/slice/src/android/slice/cts/SliceProviderTest.java new file mode 100644 index 00000000000..2a2e8e46b1a --- /dev/null +++ b/tests/tests/slice/src/android/slice/cts/SliceProviderTest.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.slice.cts; + +import android.app.slice.Slice; +import android.app.slice.SliceSpec; +import android.content.ContentResolver; +import android.net.Uri; +import android.os.Bundle; + +import androidx.test.rule.ActivityTestRule; +import androidx.test.runner.AndroidJUnit4; + +import com.google.android.collect.Lists; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class SliceProviderTest { + + private static final String VALID_AUTHORITY = "android.slice.cts"; + private static final String SUSPICIOUS_AUTHORITY = "com.suspicious.www"; + private static final String ACTION_BLUETOOTH = "/action/bluetooth"; + private static final String VALID_BASE_URI_STRING = "content://" + VALID_AUTHORITY; + private static final String VALID_ACTION_URI_STRING = + "content://" + VALID_AUTHORITY + ACTION_BLUETOOTH; + private static final String SHADY_ACTION_URI_STRING = + "content://" + SUSPICIOUS_AUTHORITY + ACTION_BLUETOOTH; + + @Rule + public ActivityTestRule<Launcher> mLauncherActivityTestRule = new ActivityTestRule<>(Launcher.class); + + private Uri validBaseUri = Uri.parse(VALID_BASE_URI_STRING); + private Uri validActionUri = Uri.parse(VALID_ACTION_URI_STRING); + private Uri shadyActionUri = Uri.parse(SHADY_ACTION_URI_STRING); + + private ContentResolver mContentResolver; + + @Before + public void setUp() { + mContentResolver = mLauncherActivityTestRule.getActivity().getContentResolver(); + } + + @Test + public void testCallSliceUri_ValidAuthority() { + doQuery(validActionUri); + } + + @Test(expected = SecurityException.class) + public void testCallSliceUri_ShadyAuthority() { + doQuery(shadyActionUri); + } + + private Slice doQuery(Uri actionUri) { + Bundle extras = new Bundle(); + extras.putParcelable("slice_uri", actionUri); + extras.putParcelableArrayList("supported_specs", Lists.newArrayList( + new SliceSpec("androidx.slice.LIST", 1), + new SliceSpec("androidx.app.slice.BASIC", 1), + new SliceSpec("androidx.slice.BASIC", 1), + new SliceSpec("androidx.app.slice.LIST", 1) + )); + Bundle result = mContentResolver.call( + validBaseUri, + SliceProvider.METHOD_SLICE, + null, + extras + ); + return result.getParcelable(SliceProvider.EXTRA_SLICE); + } + +} diff --git a/tests/tests/telephony/src/android/telephony/cts/CarrierServiceTest.java b/tests/tests/telephony/src/android/telephony/cts/CarrierServiceTest.java index 492f8ff8948..9cc5e7a1919 100644 --- a/tests/tests/telephony/src/android/telephony/cts/CarrierServiceTest.java +++ b/tests/tests/telephony/src/android/telephony/cts/CarrierServiceTest.java @@ -16,20 +16,51 @@ package android.telephony.cts; +import static androidx.test.InstrumentationRegistry.getInstrumentation; + import android.content.Intent; +import android.content.pm.PackageManager; import android.os.PersistableBundle; import android.service.carrier.CarrierIdentifier; import android.service.carrier.CarrierService; +import android.telephony.TelephonyManager; import android.test.ServiceTestCase; +import android.util.Log; public class CarrierServiceTest extends ServiceTestCase<CarrierServiceTest.TestCarrierService> { + private static final String TAG = CarrierServiceTest.class.getSimpleName(); + + private boolean mHasCellular; + public CarrierServiceTest() { super(TestCarrierService.class); } + @Override + public void setUp() throws Exception { + super.setUp(); + + mHasCellular = hasCellular(); + if (!mHasCellular) { + Log.e(TAG, "No cellular support, all tests will be skipped."); + } + } + + private static boolean hasCellular() { + PackageManager packageManager = getInstrumentation().getContext().getPackageManager(); + TelephonyManager telephonyManager = + getInstrumentation().getContext().getSystemService(TelephonyManager.class); + return packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY) + && telephonyManager.getPhoneCount() > 0; + } + public void testNotifyCarrierNetworkChange_true() { + if (!mHasCellular) return; + notifyCarrierNetworkChange(true); } public void testNotifyCarrierNetworkChange_false() { + if (!mHasCellular) return; + notifyCarrierNetworkChange(false); } diff --git a/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java b/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java index 0eabad7dcd3..9095ed0a976 100644 --- a/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java +++ b/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java @@ -92,8 +92,9 @@ public class TelephonyManagerTest { @Test public void testListen() throws Throwable { - if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) { - Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE"); + if (!InstrumentationRegistry.getContext().getPackageManager() + .hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { + Log.d(TAG, "Skipping test that requires PackageManager.FEATURE_TELEPHONY"); return; } @@ -186,7 +187,9 @@ public class TelephonyManagerTest { } // Make sure devices without MMS service won't fail on this - if (mTelephonyManager.getPhoneType() != TelephonyManager.PHONE_TYPE_NONE) { + if (InstrumentationRegistry.getContext().getPackageManager() + .hasSystemFeature(PackageManager.FEATURE_TELEPHONY) + && (mTelephonyManager.getPhoneType() != TelephonyManager.PHONE_TYPE_NONE)) { assertFalse(mTelephonyManager.getMmsUserAgent().isEmpty()); assertFalse(mTelephonyManager.getMmsUAProfUrl().isEmpty()); } diff --git a/tests/tests/text/src/android/text/method/cts/ScrollingMovementMethodTest.java b/tests/tests/text/src/android/text/method/cts/ScrollingMovementMethodTest.java index e19dfe84e73..34ffd767a99 100644 --- a/tests/tests/text/src/android/text/method/cts/ScrollingMovementMethodTest.java +++ b/tests/tests/text/src/android/text/method/cts/ScrollingMovementMethodTest.java @@ -263,8 +263,18 @@ public class ScrollingMovementMethodTest { assertTrue(mTextView.getScrollY() > previousScrollY); assertTrue(mTextView.getScrollX() < bottom); + assertTrue(getActionResult(new ActionRunnerWithResult() { + public void run() { + // move back up for the next test + mResult = method.onTouchEvent(mTextView, mSpannable, MotionEvent.obtain(now, now, + MotionEvent.ACTION_MOVE, 0, -distFar, 0)); + } + })); + previousScrollY = mTextView.getScrollY(); - final int distTooFar = (int) (-bottom * 10); + // further detracting mScaledTouchSlop from (-bottom * 10) so it is guaranteed to be + // greater than the touch slop value. + final int distTooFar = (int) (-bottom * 10) - mScaledTouchSlop; assertTrue(getActionResult(new ActionRunnerWithResult() { public void run() { // move for long distance diff --git a/tests/tests/transition/src/android/transition/cts/ActivityTransitionTest.java b/tests/tests/transition/src/android/transition/cts/ActivityTransitionTest.java index 4d1756c7c45..87f9de6e3c0 100644 --- a/tests/tests/transition/src/android/transition/cts/ActivityTransitionTest.java +++ b/tests/tests/transition/src/android/transition/cts/ActivityTransitionTest.java @@ -309,6 +309,7 @@ public class ActivityTransitionTest extends BaseTransitionTest { mActivityRule.runOnUiThread(() -> { mActivity.getWindow().setExitTransition(new Fade()); Intent intent = new Intent(mActivity, TargetActivity.class); + intent.putExtra(TargetActivity.EXTRA_USE_ANIMATOR, true); ActivityOptions activityOptions = ActivityOptions.makeSceneTransitionAnimation(mActivity); mActivity.startActivity(intent, activityOptions.toBundle()); @@ -372,7 +373,7 @@ public class ActivityTransitionTest extends BaseTransitionTest { TargetActivity targetActivity = waitForTargetActivity(); - assertTrue(targetActivity.transitionComplete.await(1, TimeUnit.SECONDS)); + assertTrue(targetActivity.transitionComplete.await(5, TimeUnit.SECONDS)); assertEquals(View.VISIBLE, targetActivity.startVisibility); assertEquals(View.VISIBLE, targetActivity.endVisibility); @@ -385,14 +386,13 @@ public class ActivityTransitionTest extends BaseTransitionTest { targetActivity.finishAfterTransition(); }); - assertTrue(targetActivity.transitionComplete.await(1, TimeUnit.SECONDS)); + assertTrue(targetActivity.transitionComplete.await(5, TimeUnit.SECONDS)); assertEquals(View.VISIBLE, targetActivity.startVisibility); assertEquals(View.VISIBLE, targetActivity.endVisibility); - assertTrue(targetActivity.transitionComplete.await(1, TimeUnit.SECONDS)); - verify(mReenterListener, within(3000)).onTransitionEnd(any()); - - TargetActivity.sLastCreated = null; + assertTrue(targetActivity.transitionComplete.await(5, TimeUnit.SECONDS)); + verify(mReenterListener, within(5000)).onTransitionStart(any()); + verify(mReenterListener, within(5000)).onTransitionEnd(any()); } // Starting a shared element transition and then removing the view shouldn't cause problems. diff --git a/tests/tests/transition/src/android/transition/cts/TargetActivity.java b/tests/tests/transition/src/android/transition/cts/TargetActivity.java index a710ca030c0..9cbd993a01f 100644 --- a/tests/tests/transition/src/android/transition/cts/TargetActivity.java +++ b/tests/tests/transition/src/android/transition/cts/TargetActivity.java @@ -66,7 +66,9 @@ public class TargetActivity extends Activity { if (useAnimator) { enterTransition = new TrackingVisibilityWithAnimator(); + enterTransition.setDuration(2000); returnTransition = new TrackingVisibilityWithAnimator(); + returnTransition.setDuration(2000); } if (excludeId != 0) { diff --git a/tests/tests/transition/src/android/transition/cts/TransitionTest.java b/tests/tests/transition/src/android/transition/cts/TransitionTest.java index 3a60cd465fa..8fb6bba4283 100644 --- a/tests/tests/transition/src/android/transition/cts/TransitionTest.java +++ b/tests/tests/transition/src/android/transition/cts/TransitionTest.java @@ -541,7 +541,7 @@ public class TransitionTest extends BaseTransitionTest { Animator animator = transition.animators.get(redSquare); assertFalse(animator.isRunning()); Animator.AnimatorListener listener = transition.listeners.get(redSquare); - verify(listener, within(250)).onAnimationStart(any(), eq(false)); + verify(listener, within(1000)).onAnimationStart(any(), eq(false)); endTransition(); } diff --git a/tests/tests/tv/src/android/media/tv/cts/TvContractTest.java b/tests/tests/tv/src/android/media/tv/cts/TvContractTest.java index 27c388a9153..6314ec59209 100644 --- a/tests/tests/tv/src/android/media/tv/cts/TvContractTest.java +++ b/tests/tests/tv/src/android/media/tv/cts/TvContractTest.java @@ -105,7 +105,8 @@ public class TvContractTest extends AndroidTestCase { private static final String WHITE_SPACES = " \r \n \t \f "; private static final String PARAM_CANONICAL_GENRE = "canonical_genre"; - private static final String NON_EXISTING_COLUMN_NAME = "non_existing_column"; + private static final String[] NON_EXISTING_COLUMN_NAMES = + {"non_existing_column", "another non-existing column --"}; private String mInputId; private ContentResolver mContentResolver; @@ -336,15 +337,20 @@ public class TvContractTest extends AndroidTestCase { private void verifyNonExistingColumn(Uri channelUri, long channelId) { String[] projection = { Channels._ID, - NON_EXISTING_COLUMN_NAME + NON_EXISTING_COLUMN_NAMES[0], + NON_EXISTING_COLUMN_NAMES[1] }; try (Cursor cursor = mContentResolver.query(channelUri, projection, null, null, null)) { assertNotNull(cursor); assertEquals(cursor.getCount(), 1); assertTrue(cursor.moveToNext()); assertEquals(channelId, cursor.getLong(0)); + assertEquals(NON_EXISTING_COLUMN_NAMES[0], cursor.getColumnName(1)); assertNull(cursor.getString(1)); assertEquals(0, cursor.getInt(1)); + assertEquals(NON_EXISTING_COLUMN_NAMES[1], cursor.getColumnName(2)); + assertNull(cursor.getString(2)); + assertEquals(0, cursor.getInt(2)); } } @@ -533,7 +539,8 @@ public class TvContractTest extends AndroidTestCase { return; } ContentValues values = createDummyChannelValues(mInputId, false); - values.put(NON_EXISTING_COLUMN_NAME, "dummy value"); + values.put(NON_EXISTING_COLUMN_NAMES[0], "dummy value 0"); + values.put(NON_EXISTING_COLUMN_NAMES[1], "dummy value 1"); Uri rowUri = mContentResolver.insert(mChannelsUri, values); long channelId = ContentUris.parseId(rowUri); Uri channelUri = TvContract.buildChannelUri(channelId); diff --git a/tests/tests/view/src/android/view/cts/ViewTest.java b/tests/tests/view/src/android/view/cts/ViewTest.java index acd68495f6b..cb2dd973e4c 100644 --- a/tests/tests/view/src/android/view/cts/ViewTest.java +++ b/tests/tests/view/src/android/view/cts/ViewTest.java @@ -3783,11 +3783,6 @@ public class ViewTest { CtsTouchUtils.emulateTapOnViewCenter(mInstrumentation, mockView); assertTrue(fitWindowsView.isInTouchMode()); - - event.setSource(InputDevice.SOURCE_MOUSE); - event.setAction(MotionEvent.ACTION_DOWN); - mInstrumentation.sendPointerSync(event); - assertFalse(fitWindowsView.isInTouchMode()); } @UiThreadTest diff --git a/tests/tests/voicesettings/src/android/voicesettings/cts/AirplaneModeTest.java b/tests/tests/voicesettings/src/android/voicesettings/cts/AirplaneModeTest.java index db6bbb90f44..3c508a9908a 100644 --- a/tests/tests/voicesettings/src/android/voicesettings/cts/AirplaneModeTest.java +++ b/tests/tests/voicesettings/src/android/voicesettings/cts/AirplaneModeTest.java @@ -87,7 +87,10 @@ public class AirplaneModeTest extends BroadcastTestBase { } private boolean runTest(BroadcastUtils.TestcaseType test, int expectedMode) throws Exception { - if (!startTestAndWaitForBroadcast(test, VOICE_SETTINGS_PACKAGE, VOICE_INTERACTION_CLASS)) { + if (!startTestAndWaitForChange(test, + Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON), + VOICE_SETTINGS_PACKAGE, + VOICE_INTERACTION_CLASS)) { return false; } diff --git a/tests/tests/voicesettings/src/android/voicesettings/cts/ZenModeTest.java b/tests/tests/voicesettings/src/android/voicesettings/cts/ZenModeTest.java index e01f3b9a587..e157ad00d41 100644 --- a/tests/tests/voicesettings/src/android/voicesettings/cts/ZenModeTest.java +++ b/tests/tests/voicesettings/src/android/voicesettings/cts/ZenModeTest.java @@ -92,7 +92,9 @@ public class ZenModeTest extends BroadcastTestBase { } private boolean runTest(BroadcastUtils.TestcaseType test, int expectedMode) throws Exception { - if (!startTestAndWaitForBroadcast(test, VOICE_SETTINGS_PACKAGE, VOICE_INTERACTION_CLASS)) { + if (!startTestAndWaitForChange(test, + Settings.Global.getUriFor(ZEN_MODE), VOICE_SETTINGS_PACKAGE, + VOICE_INTERACTION_CLASS)) { return false; } diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java index 6d69945ec2a..674cd36292e 100755 --- a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java +++ b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java @@ -1889,7 +1889,7 @@ public class WebViewTest extends ActivityInstrumentationTestCase2<WebViewCtsActi final int previousScrollX = mOnUiThread.getScrollX(); final int previousScrollY = mOnUiThread.getScrollY(); - mOnUiThread.flingScroll(100, 100); + mOnUiThread.flingScroll(10000, 10000); new PollingCheck() { @Override diff --git a/tests/tests/widget/src/android/widget/cts/TabHost_TabSpecTest.java b/tests/tests/widget/src/android/widget/cts/TabHost_TabSpecTest.java index b46921274f6..2deb847c131 100644 --- a/tests/tests/widget/src/android/widget/cts/TabHost_TabSpecTest.java +++ b/tests/tests/widget/src/android/widget/cts/TabHost_TabSpecTest.java @@ -195,6 +195,10 @@ public class TabHost_TabSpecTest { Uri uri = Uri.parse("ctstest://tabhost_tabspec/test"); final Intent intent = new Intent(Intent.ACTION_VIEW, uri); + Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); + ActivityMonitor am = instrumentation.addMonitor(MockURLSpanTestActivity.class.getName(), + null, false); + mActivity.runOnUiThread(() -> { TabHost.TabSpec tabSpec = mTabHost.newTabSpec("tab spec"); tabSpec.setIndicator("tab"); @@ -203,10 +207,6 @@ public class TabHost_TabSpecTest { mTabHost.setCurrentTab(1); }); - Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); - ActivityMonitor am = instrumentation.addMonitor(MockURLSpanTestActivity.class.getName(), - null, false); - Activity newActivity = am.waitForActivityWithTimeout(5000); assertNotNull(newActivity); newActivity.finish(); diff --git a/tests/tests/widget/src/android/widget/cts/TextClockTest.java b/tests/tests/widget/src/android/widget/cts/TextClockTest.java index d8caf948cce..25488cbd29e 100644 --- a/tests/tests/widget/src/android/widget/cts/TextClockTest.java +++ b/tests/tests/widget/src/android/widget/cts/TextClockTest.java @@ -104,6 +104,16 @@ public class TextClockTest { } } + // If the time was already set to 12, we want it to start at locale-specified + if (mDefaultTime1224 != null) { + final CountDownLatch changeDefault = registerForChanges(Settings.System.TIME_12_24); + mActivityRule.runOnUiThread(() -> { + Settings.System.putString(resolver, Settings.System.TIME_12_24, null); + }); + assertTrue(changeDefault.await(1, TimeUnit.SECONDS)); + } + + // Change to 12-hour mode final CountDownLatch change12 = registerForChanges(Settings.System.TIME_12_24); mActivityRule.runOnUiThread(() -> { Settings.System.putInt(resolver, Settings.System.TIME_12_24, 12); @@ -124,6 +134,7 @@ public class TextClockTest { return ok.value; }); + // Change to 24-hour mode final CountDownLatch change24 = registerForChanges(Settings.System.TIME_12_24); mActivityRule.runOnUiThread(() -> { Settings.System.putInt(resolver, Settings.System.TIME_12_24, 24); diff --git a/tests/tests/widget/src/android/widget/cts/ToastTest.java b/tests/tests/widget/src/android/widget/cts/ToastTest.java index b0d375178cd..837112a2dcf 100644 --- a/tests/tests/widget/src/android/widget/cts/ToastTest.java +++ b/tests/tests/widget/src/android/widget/cts/ToastTest.java @@ -22,6 +22,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeFalse; import android.app.Instrumentation; import android.content.Context; @@ -205,6 +206,8 @@ public class ToastTest { @Test public void testAccessMargin() throws Throwable { + assumeFalse("Skipping test: Auto does not support toast with margin", isCar()); + makeToast(); View view = mToast.getView(); assertFalse(view.getLayoutParams() instanceof WindowManager.LayoutParams); @@ -268,6 +271,8 @@ public class ToastTest { @Test public void testAccessGravity() throws Throwable { + assumeFalse("Skipping test: Auto does not support toast with gravity", isCar()); + makeToast(); mActivityRule.runOnUiThread(() -> { mToast.setGravity(Gravity.CENTER, 0, 0); @@ -417,4 +422,9 @@ public class ToastTest { toast.setView(null); toast.setText(null); } + + private boolean isCar() { + PackageManager pm = mContext.getPackageManager(); + return pm.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE); + } } |