Merge changes from topic "148087431" into pie-cts-dev
* changes:
Revert "DO NOT MERGE Verify that remote exceptions will not cause object leaks"
Revert "DO NOT MERGE Verify Parcel object list does not get double freed after a setDataSize"
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 6895c5f..217ee24 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_r11">
+ android:versionName="9.0_r12">
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="28"/>
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index f0f0b7e..7b3f626 100755
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -1142,6 +1142,7 @@
<string name="ci_intents_label">Intents Test</string>
<string name="ci_intents_direction_label">clockwise</string>
<string name="ci_instruction_heading_label">Instructions:</string>
+ <string name="ci_directory_creation_error">CTS Verifier debug directory could not be created, please try again</string>
<string name="ci_instruction_text_photo_label">READ BEFORE STARTING TEST</string>
<string name="ci_instruction_text_passfail_label">Choose \"Pass\" if the right intent is fired after taking a photo from the camera app. Otherwise, choose \"Fail\".</string>
<string name="ci_instruction_text_app_picture_label">\n
diff --git a/apps/CtsVerifier/res/xml/filepaths.xml b/apps/CtsVerifier/res/xml/filepaths.xml
index 2d555a2..9993951 100644
--- a/apps/CtsVerifier/res/xml/filepaths.xml
+++ b/apps/CtsVerifier/res/xml/filepaths.xml
@@ -1,3 +1,4 @@
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<files-path path="images/" name="images" />
+ <files-path path="debug" name="debug/" />
</paths>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/AbstractTestListActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/AbstractTestListActivity.java
index 3132219..9378596 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 @@
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 @@
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 @@
@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 aa6eaba..bed5a77 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 @@
// 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 @@
// 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 4a8004a..7776d27 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.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 @@
/** @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 @@
@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 @@
@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 @@
@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 @@
@Override
public void onClick(View target) {
setTestResultAndFinish(activity, activity.getTestId(), activity.getTestDetails(),
- activity.getReportLog(), target);
+ activity.getReportLog(), activity.getHistoryCollection(), target);
}
};
@@ -399,7 +435,8 @@
/** 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 @@
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/TestListAdapter.java b/apps/CtsVerifier/src/com/android/cts/verifier/TestListAdapter.java
index d9ea84f..17efb22 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 @@
/** 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 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 @@
mTestDetails.putAll(result.mDetails);
mReportLogs.clear();
mReportLogs.putAll(result.mReportLogs);
+ mHistories.clear();
+ mHistories.putAll(result.mHistories);
notifyDataSetChanged();
}
}
@@ -223,16 +235,19 @@
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 @@
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 @@
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 @@
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 @@
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 @@
: 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 @@
}
}
- 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 07208dd..9f867d5 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 @@
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 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 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 @@
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 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 0000000..0e7160c
--- /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 64c04eb..bdf32fa 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 @@
/** 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 @@
+ 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 @@
}
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 8893e0d..d9d63c2 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.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.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 @@
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/camera/intents/CameraIntentsActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/intents/CameraIntentsActivity.java
index 161cceb..7c0e475 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/intents/CameraIntentsActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/intents/CameraIntentsActivity.java
@@ -23,6 +23,7 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.Camera;
+import android.media.ExifInterface;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
@@ -34,13 +35,21 @@
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.core.content.FileProvider;
import com.android.cts.verifier.camera.intents.CameraContentJobService;
import com.android.cts.verifier.PassFailButtons;
import com.android.cts.verifier.R;
import com.android.cts.verifier.TestResult;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
import java.util.TreeSet;
+import java.util.Date;
+import java.text.SimpleDateFormat;
/**
* Tests for manual verification of uri trigger being fired.
@@ -80,6 +89,8 @@
private ImageButton mPassButton;
private ImageButton mFailButton;
private Button mStartTestButton;
+ private File mDebugFolder = null;
+ private File mImageTarget = null;
private int mState = STATE_OFF;
@@ -271,27 +282,66 @@
@Override
protected void onActivityResult(
int requestCode, int resultCode, Intent data) {
- if (requestCode == 1337 + getStageIndex()) {
+ int stageIndex = getStageIndex();
+ if (requestCode == 1337 + stageIndex) {
Log.v(TAG, "Activity we launched was finished");
mActivityResult = true;
if (mState != STATE_FAILED
&& getStageIndex() == STAGE_INTENT_PICTURE) {
- mPassButton.setEnabled(true);
- mFailButton.setEnabled(false);
-
- mState = STATE_SUCCESSFUL;
- /* successful, unless we get the URI trigger back
- at some point later on */
+ handleIntentPictureResult();
}
}
}
+ private void handleIntentPictureResult() {
+ if (mImageTarget == null) {
+ Log.d(TAG, "Image target was not set");
+ return;
+ }
+ try {
+ if (!mImageTarget.exists() || mImageTarget.length() == 0) {
+ Log.d(TAG, "Image target does not exist or it is empty");
+ mState = STATE_FAILED;
+ return;
+ }
+
+ try {
+ final ExifInterface exif = new ExifInterface(new FileInputStream(mImageTarget));
+ if (!checkExifAttribute(exif, ExifInterface.TAG_MAKE)
+ || !checkExifAttribute(exif, ExifInterface.TAG_MODEL)
+ || !checkExifAttribute(exif, ExifInterface.TAG_DATETIME)) {
+ Log.d(TAG, "The required tag does not appear in the exif");
+ mState = STATE_FAILED;
+ return;
+ }
+ mState = STATE_SUCCESSFUL;
+ setPassButton(true);
+ } catch (IOException ex) {
+ Log.e(TAG, "Failed to verify Exif", ex);
+ mState = STATE_FAILED;
+ return;
+ }
+ } finally {
+ mImageTarget.delete();
+ }
+ }
+
+ private boolean checkExifAttribute(ExifInterface exif, String tag) {
+ final String res = exif.getAttribute(tag);
+ return res != null && res.length() > 0;
+ }
+
@Override
public String getTestDetails() {
return mReportBuilder.toString();
}
+ private void setPassButton(Boolean pass) {
+ mPassButton.setEnabled(pass);
+ mFailButton.setEnabled(!pass);
+ }
+
private class WaitForTriggerTask extends AsyncTask<Void, Void, Boolean> {
protected Boolean doInBackground(Void... param) {
try {
@@ -387,7 +437,33 @@
if (intentStr != null) {
cameraIntent = new Intent(intentStr);
- startActivityForResult(cameraIntent, 1337 + getStageIndex());
+ switch (stageIndex) {
+ case STAGE_INTENT_PICTURE:
+ mDebugFolder = new File(this.getFilesDir(), "debug");
+ mDebugFolder.mkdirs();
+ if (!mDebugFolder.exists()) {
+ Toast.makeText(this, R.string.ci_directory_creation_error,
+ Toast.LENGTH_SHORT).show();
+ Log.v(TAG, "Could not create directory");
+ return;
+ }
+
+ File targetFile;
+ String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
+ mImageTarget = new File(mDebugFolder, timeStamp + "capture.jpg");
+ targetFile = mImageTarget;
+ cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, FileProvider.getUriForFile(this,
+ "com.android.cts.verifier.managedprovisioning.fileprovider",
+ targetFile));
+ startActivityForResult(cameraIntent, 1337 + getStageIndex());
+ break;
+ case STAGE_INTENT_VIDEO:
+ startActivityForResult(cameraIntent, 1337 + getStageIndex());
+ break;
+ default:
+ Log.wtf(TAG, "Unexpected stage index to send intent");
+ return;
+ }
}
mStartTestButton.setEnabled(false);
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 67f82d0..71dce24 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 @@
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 ff4f540..0cc57a8 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 @@
}
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 a49985d..2f1c21e 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 @@
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 c0a1626..ef2d798 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 @@
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/device-info/src/com/android/compatibility/common/deviceinfo/PackageDeviceInfo.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/PackageDeviceInfo.java
index 16f7610..8b1e28c 100644
--- a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/PackageDeviceInfo.java
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/PackageDeviceInfo.java
@@ -15,19 +15,22 @@
*/
package com.android.compatibility.common.deviceinfo;
+import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
-import android.os.Bundle;
-
-import com.android.compatibility.common.deviceinfo.DeviceInfo;
+import android.content.pm.PermissionInfo;
import com.android.compatibility.common.util.DeviceInfoStore;
+import java.io.IOException;
+import java.util.*;
+
/**
* PackageDeviceInfo collector.
*/
public class PackageDeviceInfo extends DeviceInfo {
private static final String PACKAGE = "package";
+
private static final String NAME = "name";
private static final String VERSION_NAME = "version_name";
private static final String SYSTEM_PRIV = "system_priv";
@@ -35,24 +38,97 @@
private static final String MIN_SDK = "min_sdk";
private static final String TARGET_SDK = "target_sdk";
+ private static final String REQUESTED_PERMISSIONS = "requested_permissions";
+ private static final String PERMISSION_NAME = "name";
+ private static final String PERMISSION_FLAGS = "flags";
+ private static final String PERMISSION_GROUP = "permission_group";
+ private static final String PERMISSION_PROTECTION = "protection_level";
+ private static final String PERMISSION_PROTECTION_FLAGS = "protection_level_flags";
+
+ private static final int SYS_UID_MAX = 10000;
+ private static final String HAS_SYSTEM_UID = "has_system_uid";
+
+ private static final String SHARES_INSTALL_PERMISSION = "shares_install_packages_permission";
+ private static final String INSTALL_PACKAGES_PERMISSION = "android.permission.INSTALL_PACKAGES";
+
@Override
protected void collectDeviceInfo(DeviceInfoStore store) throws Exception {
- PackageManager pm = getContext().getPackageManager();
+ final PackageManager pm = getContext().getPackageManager();
+
+ final List<PackageInfo> allPackages = pm.getInstalledPackages(PackageManager.GET_PERMISSIONS);
+
store.startArray(PACKAGE);
- for (PackageInfo pkg : pm.getInstalledPackages(0)) {
+ for (PackageInfo pkg : allPackages) {
store.startGroup();
+
store.addResult(NAME, pkg.packageName);
store.addResult(VERSION_NAME, pkg.versionName);
- if (pkg.applicationInfo != null) {
- String dir = pkg.applicationInfo.sourceDir;
+ store.startArray(REQUESTED_PERMISSIONS);
+ if (pkg.requestedPermissions != null && pkg.requestedPermissions.length > 0) {
+ for (String permission : pkg.requestedPermissions) {
+ try {
+ final PermissionInfo pi = pm.getPermissionInfo(permission, 0);
+
+ store.startGroup();
+ store.addResult(PERMISSION_NAME, permission);
+ store.addResult(PERMISSION_FLAGS, pi.flags);
+ store.addResult(PERMISSION_GROUP, pi.group);
+ store.addResult(PERMISSION_PROTECTION, pi.getProtection());
+ store.addResult(PERMISSION_PROTECTION_FLAGS, pi.getProtectionFlags());
+ store.endGroup();
+ } catch (PackageManager.NameNotFoundException e) {
+ // ignore unrecognized permission and continue
+ }
+ }
+ }
+ store.endArray();
+
+ final ApplicationInfo appInfo = pkg.applicationInfo;
+ if (appInfo != null) {
+ String dir = appInfo.sourceDir;
store.addResult(SYSTEM_PRIV, dir != null && dir.startsWith(PRIV_APP_DIR));
- store.addResult(MIN_SDK, pkg.applicationInfo.minSdkVersion);
- store.addResult(TARGET_SDK, pkg.applicationInfo.targetSdkVersion);
+ store.addResult(MIN_SDK, appInfo.minSdkVersion);
+ store.addResult(TARGET_SDK, appInfo.targetSdkVersion);
+
+ store.addResult(HAS_SYSTEM_UID, appInfo.uid < SYS_UID_MAX);
+
+ final boolean canInstall = sharesUidWithPackageHolding(pm, appInfo.uid, INSTALL_PACKAGES_PERMISSION);
+ store.addResult(SHARES_INSTALL_PERMISSION, canInstall);
}
+
store.endGroup();
}
- store.endArray(); // Package
+ store.endArray(); // "package"
+ }
+ private static boolean sharesUidWithPackageHolding(PackageManager pm, int uid, String permission) {
+ final String[] sharesUidWith = pm.getPackagesForUid(uid);
+
+ if (sharesUidWith == null) {
+ return false;
+ }
+
+ // Approx 20 permissions per package for rough estimate of sizing
+ final List<String> sharedPermissions = new ArrayList<>(sharesUidWith.length * 20);
+ for (String pkg :sharesUidWith){
+ try {
+ final PackageInfo info = pm.getPackageInfo(pkg, PackageManager.GET_PERMISSIONS);
+
+ if (info.requestedPermissions == null) {
+ continue;
+ }
+
+ for (String p : info.requestedPermissions) {
+ if (p != null) {
+ sharedPermissions.add(p);
+ }
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ // ignore, continue
+ }
+ }
+
+ return sharedPermissions.contains(permission);
}
}
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 bf5dc39..2dd54e6 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 @@
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 @@
}
}
}
+
+ 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/common/device-side/util-axt/src/com/android/compatibility/common/util/RequiredServiceRule.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/RequiredServiceRule.java
new file mode 100644
index 0000000..bbfa2db
--- /dev/null
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/RequiredServiceRule.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compatibility.common.util;
+
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.test.InstrumentationRegistry;
+
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * Custom JUnit4 rule that does not run a test case if the device does not have a given service.
+ */
+public class RequiredServiceRule implements TestRule {
+ private static final String TAG = "RequiredServiceRule";
+
+ private final String mService;
+ private final boolean mHasService;
+
+ /**
+ * Creates a rule for the given service.
+ */
+ public RequiredServiceRule(@NonNull String service) {
+ mService = service;
+ mHasService = hasService(service);
+ }
+
+ @Override
+ public Statement apply(@NonNull Statement base, @NonNull Description description) {
+ return new Statement() {
+
+ @Override
+ public void evaluate() throws Throwable {
+ if (!mHasService) {
+ Log.d(TAG, "skipping "
+ + description.getClassName() + "#" + description.getMethodName()
+ + " because device does not have service '" + mService + "'");
+ return;
+ }
+ base.evaluate();
+ }
+ };
+ }
+
+ /**
+ * Checks if the device has the given service.
+ */
+ public static boolean hasService(@NonNull 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 = SystemUtil.runShellCommand(
+ InstrumentationRegistry.getInstrumentation(), command);
+ return !commandOutput.contains("not found");
+ } catch (Exception e) {
+ Log.w(TAG, "Exception running '" + command + "': " + e);
+ return false;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "RequiredServiceRule[" + mService + "]";
+ }
+}
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/devicepolicy/provisioning/SilentProvisioningTestManager.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/devicepolicy/provisioning/SilentProvisioningTestManager.java
index ae6849c..f27ab55 100644
--- a/common/device-side/util-axt/src/com/android/compatibility/common/util/devicepolicy/provisioning/SilentProvisioningTestManager.java
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/devicepolicy/provisioning/SilentProvisioningTestManager.java
@@ -93,13 +93,15 @@
}
mReceivedProfileProvisionedIntent =
- managedProfileProvisionedReceiver.awaitForBroadcast();
+ managedProfileProvisionedReceiver.awaitForBroadcast(
+ TimeUnit.SECONDS.toMillis(TIMEOUT_SECONDS));
if (mReceivedProfileProvisionedIntent == null) {
Log.i(TAG, "managedProfileProvisionedReceiver.awaitForBroadcast(): failed");
return false;
}
- if (managedProfileAddedReceiver.awaitForBroadcast() == null) {
+ if (managedProfileAddedReceiver.awaitForBroadcast(
+ TimeUnit.SECONDS.toMillis(TIMEOUT_SECONDS)) == null) {
Log.i(TAG, "managedProfileAddedReceiver.awaitForBroadcast(): failed");
return false;
}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/devicepolicy/provisioning/SilentProvisioningTestManager.java b/common/device-side/util/src/com/android/compatibility/common/util/devicepolicy/provisioning/SilentProvisioningTestManager.java
index 05edf1a..59f3ebf 100644
--- a/common/device-side/util/src/com/android/compatibility/common/util/devicepolicy/provisioning/SilentProvisioningTestManager.java
+++ b/common/device-side/util/src/com/android/compatibility/common/util/devicepolicy/provisioning/SilentProvisioningTestManager.java
@@ -93,13 +93,15 @@
}
mReceivedProfileProvisionedIntent =
- managedProfileProvisionedReceiver.awaitForBroadcast();
+ managedProfileProvisionedReceiver.awaitForBroadcast(
+ TimeUnit.SECONDS.toMillis(TIMEOUT_SECONDS));
if (mReceivedProfileProvisionedIntent == null) {
Log.i(TAG, "managedProfileProvisionedReceiver.awaitForBroadcast(): failed");
return false;
}
- if (managedProfileAddedReceiver.awaitForBroadcast() == null) {
+ if (managedProfileAddedReceiver.awaitForBroadcast(
+ TimeUnit.SECONDS.toMillis(TIMEOUT_SECONDS)) == null) {
Log.i(TAG, "managedProfileAddedReceiver.awaitForBroadcast(): failed");
return false;
}
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 6188303..6be6612 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 @@
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/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DelegatedCertInstallerTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DelegatedCertInstallerTest.java
index 99b310e..74706c9 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DelegatedCertInstallerTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DelegatedCertInstallerTest.java
@@ -324,7 +324,7 @@
private void assertResult(String testName, Boolean expectSuccess) throws InterruptedException {
assertTrue("Cert installer did not respond in time.",
- mAvailableResultSemaphore.tryAcquire(10, TimeUnit.SECONDS));
+ mAvailableResultSemaphore.tryAcquire(60, TimeUnit.SECONDS));
synchronized (this) {
if (expectSuccess) {
assertTrue(testName + " failed unexpectedly.", mReceivedResult);
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CreateAndManageUserTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CreateAndManageUserTest.java
index 0280bdf..86af199 100755
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CreateAndManageUserTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CreateAndManageUserTest.java
@@ -59,7 +59,7 @@
private static final String SERIAL_EXTRA = "serialExtra";
private static final String PROFILE_OWNER_EXTRA = "profileOwnerExtra";
private static final String SETUP_COMPLETE_EXTRA = "setupCompleteExtra";
- private static final int BROADCAST_TIMEOUT = 15_000;
+ private static final int BROADCAST_TIMEOUT = 60_000;
private static final int USER_SWITCH_DELAY = 10_000;
private static final String AFFILIATION_ID = "affiliation.id";
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DisallowSharingIntoProfileTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DisallowSharingIntoProfileTest.java
index 8f1f88e..9ddc92f 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DisallowSharingIntoProfileTest.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DisallowSharingIntoProfileTest.java
@@ -176,7 +176,8 @@
UserManager.DISALLOW_SHARE_INTO_MANAGED_PROFILE);
}
// Wait for the restriction to apply
- assertTrue("Restriction not applied after 5 seconds", latch.await(5, TimeUnit.SECONDS));
+ assertTrue("Restriction not applied after 60 seconds",
+ latch.await(60, TimeUnit.SECONDS));
} finally {
mContext.unregisterReceiver(receiver);
}
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 f39dbbe..65c952f 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 @@
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 b42b2bd..ce8736f 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 @@
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/DeviceAndProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
index edc2ff6..1135318 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 @@
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 @@
if (!mHasFeature) {
return;
}
+ if (!hasService("wallpaper")) {
+ CLog.d("testDisallowSetWallpaper_allowed(): device does not support wallpapers");
+ return;
+ }
executeDeviceTestMethod(".CustomizationRestrictionsTest",
"testDisallowSetWallpaper_allowed");
}
@@ -1144,4 +1153,19 @@
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 83e8de2..09c7a4c 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 @@
if (!mHasFeature) {
return;
}
- executeDeviceOwnerTest("SystemUpdatePolicyTest");
+ // Disabled due to 145932189
+ // executeDeviceOwnerTest("SystemUpdatePolicyTest");
}
public void testWifiConfigLockdown() throws Exception {
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
index b81afd2..d551872 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
@@ -85,7 +85,7 @@
private static final String PROFILE_CREDENTIAL = "1234";
// This should be sufficiently larger than ProfileTimeoutTestHelper.TIMEOUT_MS
- private static final int PROFILE_TIMEOUT_DELAY_MS = 10_000;
+ private static final int PROFILE_TIMEOUT_DELAY_MS = 60_000;
//The maximum time to wait for user to be unlocked.
private static final long USER_UNLOCK_TIMEOUT_NANO = 30_000_000_000L;
diff --git a/hostsidetests/dumpsys/src/android/dumpsys/cts/BatteryStatsDumpsysTest.java b/hostsidetests/dumpsys/src/android/dumpsys/cts/BatteryStatsDumpsysTest.java
old mode 100644
new mode 100755
diff --git a/hostsidetests/incident/apps/graphicsstatsapp/src/com/android/server/cts/device/graphicsstats/DrawFramesActivity.java b/hostsidetests/incident/apps/graphicsstatsapp/src/com/android/server/cts/device/graphicsstats/DrawFramesActivity.java
index 65fd3ff..1bbc601 100644
--- a/hostsidetests/incident/apps/graphicsstatsapp/src/com/android/server/cts/device/graphicsstats/DrawFramesActivity.java
+++ b/hostsidetests/incident/apps/graphicsstatsapp/src/com/android/server/cts/device/graphicsstats/DrawFramesActivity.java
@@ -123,6 +123,7 @@
}
private void scheduleDraw() {
+ mColorView.invalidate();
mChoreographer.postFrameCallback((long timestamp) -> {
setupFrame();
jankIf(FRAME_JANK_ANIMATION);
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java b/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java
index 23e2d6c..23355a6 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 @@
/** 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 1d5a6f0..90999f8 100644
--- a/hostsidetests/theme/app/Android.mk
+++ b/hostsidetests/theme/app/Android.mk
@@ -38,6 +38,6 @@
# 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 0f3c1de..a351a01 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 844c578..e007129 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 @@
*/
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 6e0731d..3707bb1 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 9469a0c..2e3b97a 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.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 @@
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 @@
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 @@
}
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 @@
}
// List of themes to verify.
+ @SuppressWarnings("deprecation")
static final Theme[] THEMES = {
// Holo
new Theme(Theme.HOLO, android.R.style.Theme_Holo,
@@ -397,15 +412,17 @@
new Layout(R.layout.radiobutton, "radiobutton"),
new Layout(R.layout.radiogroup_horizontal, "radiogroup_horizontal"),
new Layout(R.layout.radiogroup_vertical, "radiogroup_vertical"),
- new Layout(R.layout.ratingbar_0, "ratingbar_0"),
- new Layout(R.layout.ratingbar_2point5, "ratingbar_2point5"),
- new Layout(R.layout.ratingbar_5, "ratingbar_5"),
- new Layout(R.layout.ratingbar_0, "ratingbar_0_pressed",
- new ViewPressedModifier()),
- new Layout(R.layout.ratingbar_2point5, "ratingbar_2point5_pressed",
- new ViewPressedModifier()),
- new Layout(R.layout.ratingbar_5, "ratingbar_5_pressed",
- new ViewPressedModifier()),
+ // Temporarily remove tests for the RatingBar widget. It has indeterminate rendering
+ // behavior on 360dpi devices, but we don't know why yet.
+ //new Layout(R.layout.ratingbar_0, "ratingbar_0"),
+ //new Layout(R.layout.ratingbar_2point5, "ratingbar_2point5"),
+ //new Layout(R.layout.ratingbar_5, "ratingbar_5"),
+ //new Layout(R.layout.ratingbar_0, "ratingbar_0_pressed",
+ // new ViewPressedModifier()),
+ //new Layout(R.layout.ratingbar_2point5, "ratingbar_2point5_pressed",
+ // new ViewPressedModifier()),
+ //new Layout(R.layout.ratingbar_5, "ratingbar_5_pressed",
+ // new ViewPressedModifier()),
new Layout(R.layout.searchview, "searchview_query",
new SearchViewModifier(SearchViewModifier.QUERY)),
new Layout(R.layout.searchview, "searchview_query_hint",
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 5c945ef..e9dca7a 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 26ccd67..f155fcb 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 @@
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 9849a64..dcd8c89 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 @@
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 75dd20a..de341ce 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 @@
}
@Override
- public View modifyView(View view) {
+ public void modifyViewBeforeAdd(View view) {
SearchView searchView = (SearchView) view;
Context context = view.getContext();
@@ -52,6 +52,5 @@
}
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 b2ed4ef..8e06ad8 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 @@
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 f55f057..7810219 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 @@
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 a94962d..78b329c 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 @@
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 a2a0e449..0f49281 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 @@
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 void onColorsChanged(WallpaperColors colors, int which) {
}
}
-}
\ No newline at end of file
+}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/DisplaySizeTest.java b/tests/framework/base/activitymanager/src/android/server/am/DisplaySizeTest.java
index 83ceabd..b286695 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/DisplaySizeTest.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/DisplaySizeTest.java
@@ -111,10 +111,10 @@
private static final String DENSITY_PROP_EMULATOR = "qemu.sf.lcd_density";
void setUnsupportedDensity() {
- // Set device to 0.85 zoom. It doesn't matter that we're zooming out
+ // Set device to 6x zoom. It doesn't matter that we're zooming in
// since the feature verifies that we're in a non-default density.
final int stableDensity = getStableDensity();
- final int targetDensity = (int) (stableDensity * 0.85);
+ final int targetDensity = (int) (stableDensity * 6);
setDensity(targetDensity);
}
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 b43b06d..157a83a 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 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 @@
static final String TEST_WITH_MARGINS = "WithMargins";
private AlertDialog mDialog;
- int mSize;
+ int mSize = 200;
@Override
protected void onStop() {
@@ -72,7 +73,9 @@
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 00eb590..7fd635e 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.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 @@
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 341cc7b..12ed658 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 fe8cd6e..f1711f4 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 @@
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 0000000..1ab0a8a
--- /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 a01e9e0..b2b5753 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 @@
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 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 void testGetWallpaperDesiredMinimumHeightAndWidth() {
+ if (!isWallpaperSupported()) return;
+
int height = mContextWrapper.getWallpaperDesiredMinimumHeight();
int width = mContextWrapper.getWallpaperDesiredMinimumWidth();
@@ -832,6 +837,10 @@
}
}
+ 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 97b0b8f..4479a5d 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 @@
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.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 @@
getContext().deleteDatabase(DATABASE_FILE);
mDatabase = getContext().openOrCreateDatabase(DATABASE_FILE, Context.MODE_PRIVATE, null);
assertNotNull(mDatabase);
+
+ createEmployeeTable();
+ createStrictQueryBuilder();
}
@Override
@@ -202,8 +209,6 @@
}
public void testQuery() {
- createEmployeeTable();
-
SQLiteQueryBuilder sqliteQueryBuilder = new SQLiteQueryBuilder();
sqliteQueryBuilder.setTables("Employee");
Cursor cursor = sqliteQueryBuilder.query(mDatabase,
@@ -276,8 +281,6 @@
}
public void testCancelableQuery_WhenNotCanceled_ReturnsResultSet() {
- createEmployeeTable();
-
CancellationSignal cancellationSignal = new CancellationSignal();
SQLiteQueryBuilder sqliteQueryBuilder = new SQLiteQueryBuilder();
sqliteQueryBuilder.setTables("Employee");
@@ -289,8 +292,6 @@
}
public void testCancelableQuery_WhenCanceledBeforeQuery_ThrowsImmediately() {
- createEmployeeTable();
-
CancellationSignal cancellationSignal = new CancellationSignal();
SQLiteQueryBuilder sqliteQueryBuilder = new SQLiteQueryBuilder();
sqliteQueryBuilder.setTables("Employee");
@@ -307,8 +308,6 @@
}
public void testCancelableQuery_WhenCanceledAfterQuery_ThrowsWhenExecuted() {
- createEmployeeTable();
-
CancellationSignal cancellationSignal = new CancellationSignal();
SQLiteQueryBuilder sqliteQueryBuilder = new SQLiteQueryBuilder();
sqliteQueryBuilder.setTables("Employee");
@@ -327,8 +326,6 @@
}
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 @@
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 @@
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 8ba89a2..4e71dc0 100644
--- a/tests/tests/nativehardware/jni/AHardwareBufferGLTest.cpp
+++ b/tests/tests/nativehardware/jni/AHardwareBufferGLTest.cpp
@@ -1043,6 +1043,14 @@
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 @@
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 @@
}
glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment_points[i],
GL_RENDERBUFFER, renderbuffer);
+ if (isGlFormat)
+ glClear(clear_bits[i]);
break;
}
case kRenderbuffer: {
@@ -1087,8 +1098,7 @@
glRenderbufferStorage(GL_RENDERBUFFER, default_formats[i], width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment_points[i],
GL_RENDERBUFFER, renderbuffer);
- glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ glClear(clear_bits[i]);
break;
}
default: FAIL() << "Unrecognized binding type";
diff --git a/tests/tests/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java b/tests/tests/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java
index d3235da..9fb7ac4 100644
--- a/tests/tests/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java
@@ -34,7 +34,6 @@
public class WifiEnterpriseConfigTest extends AndroidTestCase {
private WifiManager mWifiManager;
-
private static final String SSID = "\"TestSSID\"";
private static final String IDENTITY = "identity";
private static final String PASSWORD = "password";
@@ -684,6 +683,9 @@
@Override
protected void setUp() throws Exception {
super.setUp();
+ if(!hasWifi()) {
+ return;
+ }
mWifiManager = (WifiManager) mContext
.getSystemService(Context.WIFI_SERVICE);
assertNotNull(mWifiManager);
@@ -802,6 +804,9 @@
}
public void testEnterpriseConfigDoesNotPrintPassword() {
+ if(!hasWifi()) {
+ return;
+ }
WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
final String identity = "IdentityIsOkayToBeDisplayedHere";
final String password = "PasswordIsNotOkayToBeDisplayedHere";
diff --git a/tests/tests/opengl/src/android/opengl/cts/EglConfigCtsActivity.java b/tests/tests/opengl/src/android/opengl/cts/EglConfigCtsActivity.java
index cef9e2f..1b8cf77 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();
+ }
}
- public void waitToFinishDrawing() throws InterruptedException {
- if (!mFinishedDrawing.await(3, TimeUnit.SECONDS)) {
- throw new IllegalStateException("Coudn't finish drawing frames!");
+ 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!");
+ }
+ }
+
+ 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 3e5565e..613456a 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.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.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 @@
@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/src/android/os/cts/EnvironmentTest.java b/tests/tests/os/src/android/os/cts/EnvironmentTest.java
index 0f2ac62..622d35a 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 @@
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/permission/src/android/permission/cts/ServicesInstantAppsCannotAccessTests.java b/tests/tests/permission/src/android/permission/cts/ServicesInstantAppsCannotAccessTests.java
index 8609e33..84c2dd6 100644
--- a/tests/tests/permission/src/android/permission/cts/ServicesInstantAppsCannotAccessTests.java
+++ b/tests/tests/permission/src/android/permission/cts/ServicesInstantAppsCannotAccessTests.java
@@ -25,11 +25,15 @@
import static android.content.Context.WIFI_P2P_SERVICE;
import static android.content.Context.WIFI_SERVICE;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
+import android.app.WallpaperManager;
import android.content.Context;
import android.platform.test.annotations.AppModeInstant;
+import com.android.compatibility.common.util.RequiredServiceRule;
+
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
@@ -68,8 +72,14 @@
@Test
public void cannotGetWallpaperManager() {
- assertNull(InstrumentationRegistry.getTargetContext().getSystemService(
- WALLPAPER_SERVICE));
+ WallpaperManager mgr = (WallpaperManager) InstrumentationRegistry.getTargetContext()
+ .getSystemService(WALLPAPER_SERVICE);
+ boolean supported = RequiredServiceRule.hasService("wallpaper");
+ if (supported) {
+ assertNull(mgr);
+ } else {
+ assertFalse(mgr.isWallpaperSupported());
+ }
}
@Test
diff --git a/tests/tests/permission2/res/raw/automotive_android_manifest.xml b/tests/tests/permission2/res/raw/automotive_android_manifest.xml
index 975796d..6d6e867 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/provider/src/android/provider/cts/MediaStoreUiTest.java b/tests/tests/provider/src/android/provider/cts/MediaStoreUiTest.java
index 9e65d0b..2668d4d 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStoreUiTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStoreUiTest.java
@@ -16,54 +16,33 @@
package android.provider.cts;
-import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
-import static android.Manifest.permission.ACCESS_FINE_LOCATION;
-import static android.Manifest.permission.CAMERA;
-import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
-import static android.Manifest.permission.RECORD_AUDIO;
-import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
-
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.UriPermission;
-import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.media.ExifInterface;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Environment;
import android.os.ParcelFileDescriptor;
-import android.os.SystemClock;
import android.os.storage.StorageManager;
import android.os.storage.StorageVolume;
-import android.provider.MediaStore;
import android.provider.cts.GetResultActivity.Result;
+import android.provider.MediaStore;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.BySelector;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject2;
-import android.support.test.uiautomator.UiSelector;
import android.support.test.uiautomator.Until;
import android.test.InstrumentationTestCase;
import android.text.format.DateUtils;
-import android.util.Log;
-import android.view.KeyEvent;
-
-import androidx.core.content.FileProvider;
-import androidx.test.InstrumentationRegistry;
import java.io.BufferedReader;
import java.io.File;
-import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.OutputStream;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -144,127 +123,6 @@
}
}
- private void maybeClick(UiSelector sel) {
- try { mDevice.findObject(sel).click(); } catch (Throwable ignored) { }
- }
-
- private void maybeClick(BySelector sel) {
- try { mDevice.findObject(sel).click(); } catch (Throwable ignored) { }
- }
-
- private void maybeGrantRuntimePermission(String pkg, Set<String> requested, String permission) {
- if (requested.contains(permission)) {
- InstrumentationRegistry.getInstrumentation().getUiAutomation()
- .grantRuntimePermission(pkg, permission);
- }
- }
-
- /**
- * Verify that whoever handles {@link MediaStore#ACTION_IMAGE_CAPTURE} can
- * correctly write the contents into a passed {@code content://} Uri.
- */
- public void testImageCapture() throws Exception {
- final Context context = getInstrumentation().getContext();
- if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
- Log.d(TAG, "Skipping due to lack of camera");
- return;
- }
-
- final File targetDir = new File(context.getFilesDir(), "debug");
- final File target = new File(targetDir, "capture.jpg");
-
- targetDir.mkdirs();
- assertFalse(target.exists());
-
- final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
- intent.putExtra(MediaStore.EXTRA_OUTPUT,
- FileProvider.getUriForFile(context, "android.provider.cts.fileprovider", target));
-
- // Figure out who is going to answer the phone
- final ResolveInfo ri = context.getPackageManager().resolveActivity(intent, 0);
- final String pkg = ri.activityInfo.packageName;
- Log.d(TAG, "We're probably launching " + ri);
-
- final PackageInfo pi = context.getPackageManager().getPackageInfo(pkg,
- PackageManager.GET_PERMISSIONS);
- final Set<String> req = new HashSet<>();
- req.addAll(Arrays.asList(pi.requestedPermissions));
-
- // Grant them all the permissions they might want
- maybeGrantRuntimePermission(pkg, req, CAMERA);
- maybeGrantRuntimePermission(pkg, req, ACCESS_COARSE_LOCATION);
- maybeGrantRuntimePermission(pkg, req, ACCESS_FINE_LOCATION);
- maybeGrantRuntimePermission(pkg, req, RECORD_AUDIO);
- maybeGrantRuntimePermission(pkg, req, READ_EXTERNAL_STORAGE);
- maybeGrantRuntimePermission(pkg, req, WRITE_EXTERNAL_STORAGE);
- SystemClock.sleep(DateUtils.SECOND_IN_MILLIS);
-
- mActivity.startActivityForResult(intent, REQUEST_CODE);
- mDevice.waitForIdle();
-
- // To ensure camera app is launched
- SystemClock.sleep(5 * DateUtils.SECOND_IN_MILLIS);
-
- // Try a couple different strategies for taking a photo: first take a
- // photo and confirm using hardware keys
- mDevice.pressKeyCode(KeyEvent.KEYCODE_CAMERA);
- mDevice.waitForIdle();
- SystemClock.sleep(5 * DateUtils.SECOND_IN_MILLIS);
- mDevice.pressKeyCode(KeyEvent.KEYCODE_DPAD_CENTER);
- mDevice.waitForIdle();
-
- // Maybe that gave us a result?
- Result result = mActivity.getResult(15, TimeUnit.SECONDS);
- Log.d(TAG, "First pass result was " + result);
-
- // Hrm, that didn't work; let's try an alternative approach of digging
- // around for a shutter button
- if (result == null) {
- maybeClick(new UiSelector().resourceId(pkg + ":id/shutter_button"));
- mDevice.waitForIdle();
- SystemClock.sleep(5 * DateUtils.SECOND_IN_MILLIS);
- maybeClick(new UiSelector().resourceId(pkg + ":id/shutter_button"));
- mDevice.waitForIdle();
- maybeClick(new UiSelector().resourceId(pkg + ":id/done_button"));
- mDevice.waitForIdle();
-
- result = mActivity.getResult(15, TimeUnit.SECONDS);
- Log.d(TAG, "Second pass result was " + result);
- }
-
- // Grr, let's try hunting around even more
- if (result == null) {
- maybeClick(By.pkg(pkg).descContains("Capture"));
- mDevice.waitForIdle();
- SystemClock.sleep(5 * DateUtils.SECOND_IN_MILLIS);
- maybeClick(By.pkg(pkg).descContains("Done"));
- mDevice.waitForIdle();
-
- result = mActivity.getResult(15, TimeUnit.SECONDS);
- Log.d(TAG, "Third pass result was " + result);
- }
-
- assertNotNull("Expected to get a IMAGE_CAPTURE result; your camera app should "
- + "respond to the CAMERA and DPAD_CENTER keycodes", result);
-
- assertTrue("exists", target.exists());
- assertTrue("has data", target.length() > 65536);
-
- // At the very least we expect photos generated by the device to have
- // sane baseline EXIF data
- final ExifInterface exif = new ExifInterface(new FileInputStream(target));
- assertAttribute(exif, ExifInterface.TAG_MAKE);
- assertAttribute(exif, ExifInterface.TAG_MODEL);
- assertAttribute(exif, ExifInterface.TAG_DATETIME);
- }
-
- private static void assertAttribute(ExifInterface exif, String tag) {
- final String res = exif.getAttribute(tag);
- if (res == null || res.length() == 0) {
- Log.d(TAG, "Expected valid EXIF tag for tag " + tag);
- }
- }
-
private boolean supportsHardware() {
final PackageManager pm = getInstrumentation().getContext().getPackageManager();
return !pm.hasSystemFeature("android.hardware.type.automotive")
diff --git a/tests/tests/security/src/android/security/cts/ServicePermissionsTest.java b/tests/tests/security/src/android/security/cts/ServicePermissionsTest.java
index 60e27e6..bccbe59 100644
--- a/tests/tests/security/src/android/security/cts/ServicePermissionsTest.java
+++ b/tests/tests/security/src/android/security/cts/ServicePermissionsTest.java
@@ -107,6 +107,7 @@
} 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
@@ -115,7 +116,9 @@
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();
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 0000000..2a2e8e4
--- /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/TelephonyManagerTest.java b/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java
index 0eabad7..9095ed0 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 @@
@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 @@
}
// 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/transition/src/android/transition/cts/ActivityTransitionTest.java b/tests/tests/transition/src/android/transition/cts/ActivityTransitionTest.java
index 4d1756c..87f9de6 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 @@
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 @@
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 @@
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 a710ca0..9cbd993 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 @@
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 3a60cd4..8fb6bba 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 @@
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 27c388a..6314ec5 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 @@
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 @@
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 @@
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/surfacevalidator/CapturedActivity.java b/tests/tests/view/src/android/view/cts/surfacevalidator/CapturedActivity.java
index f1838e2..641d6c9 100644
--- a/tests/tests/view/src/android/view/cts/surfacevalidator/CapturedActivity.java
+++ b/tests/tests/view/src/android/view/cts/surfacevalidator/CapturedActivity.java
@@ -212,9 +212,9 @@
display.getRealSize(size);
display.getMetrics(metrics);
- View decorView = getWindow().getDecorView();
- Rect boundsToCheck = new Rect(0, 0, decorView.getWidth(), decorView.getHeight());
- int[] topLeft = decorView.getLocationOnScreen();
+ View testAreaView = findViewById(android.R.id.content);
+ Rect boundsToCheck = new Rect(0, 0, testAreaView.getWidth(), testAreaView.getHeight());
+ int[] topLeft = testAreaView.getLocationOnScreen();
boundsToCheck.offset(topLeft[0], topLeft[1]);
if (boundsToCheck.width() < 90 || boundsToCheck.height() < 90) {
diff --git a/tests/tests/voicesettings/src/android/voicesettings/cts/AirplaneModeTest.java b/tests/tests/voicesettings/src/android/voicesettings/cts/AirplaneModeTest.java
index db6bbb9..3c508a9 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 @@
}
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 e01f3b9..e157ad0 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 @@
}
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 6d69945..674cd36 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 @@
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 b469212..2deb847 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 @@
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 @@
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();