Merge "Modified text field arrow tests for different input devices" into oc-dev
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/DirectBootHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/DirectBootHostTest.java
index 3a282bf..6a6c27d 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/DirectBootHostTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/DirectBootHostTest.java
@@ -47,8 +47,13 @@
private static final String MODE_EMULATED = "emulated";
private static final String MODE_NONE = "none";
+ private static final String FEATURE_DEVICE_ADMIN = "feature:android.software.device_admin\n";
+ private static final String FEATURE_AUTOMOTIVE = "feature:android.hardware.type.automotive\n";
+
private static final long SHUTDOWN_TIME_MS = 30 * 1000;
+ private String mFeatureList = null;
+
private IAbi mAbi;
private IBuildInfo mCtsBuild;
@@ -82,6 +87,22 @@
}
/**
+ * Automotive devices MUST support native FBE.
+ */
+ public void testAutomotiveNativeFbe() throws Exception {
+ if (!isSupportedDevice()) {
+ Log.v(TAG, "Device not supported; skipping test");
+ return;
+ } else if (!isAutomotiveDevice()) {
+ Log.v(TAG, "Device not automotive; skipping test");
+ return;
+ }
+
+ assertTrue("Automotive devices must support native FBE",
+ MODE_NATIVE.equals(getFbeMode()));
+ }
+
+ /**
* If device has native FBE, verify lifecycle.
*/
public void testDirectBootNative() throws Exception {
@@ -227,9 +248,20 @@
return "1".equals(output);
}
+ private boolean hasSystemFeature(final String feature) throws Exception {
+ if (mFeatureList == null) {
+ mFeatureList = getDevice().executeShellCommand("pm list features");
+ }
+
+ return mFeatureList.contains(feature);
+ }
+
private boolean isSupportedDevice() throws Exception {
- final String featureList = getDevice().executeShellCommand("pm list features");
- return featureList.contains("feature:android.software.device_admin\n");
+ return hasSystemFeature(FEATURE_DEVICE_ADMIN);
+ }
+
+ private boolean isAutomotiveDevice() throws Exception {
+ return hasSystemFeature(FEATURE_AUTOMOTIVE);
}
private void waitForBootCompleted() throws Exception {
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/EphemeralTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/EphemeralTest.java
index 77513c5..7de83d6 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/EphemeralTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/EphemeralTest.java
@@ -110,12 +110,9 @@
runDeviceTests(EPHEMERAL_1_PKG, TEST_CLASS, "testStartEphemeral");
}
- /*
- * Disabled pending drops of updated prebuilts
public void testExposedSystemActivities() throws Exception {
runDeviceTests(EPHEMERAL_1_PKG, TEST_CLASS, "testExposedSystemActivities");
}
- */
public void testBuildSerialUnknown() throws Exception {
runDeviceTests(EPHEMERAL_1_PKG, TEST_CLASS, "testBuildSerialUnknown");
diff --git a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/src/com/android/cts/ephemeralapp1/ClientTest.java b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/src/com/android/cts/ephemeralapp1/ClientTest.java
index 21afece..fa8730d 100644
--- a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/src/com/android/cts/ephemeralapp1/ClientTest.java
+++ b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/src/com/android/cts/ephemeralapp1/ClientTest.java
@@ -97,9 +97,6 @@
ContactsContract.CommonDataKinds.Email.CONTENT_TYPE, null),
makeIntent(Intent.ACTION_PICK, null,
ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_TYPE, null),
- makeIntent(Intent.ACTION_INSERT, null, ContactsContract.Contacts.CONTENT_TYPE, null),
- // Email
- makeIntent(Intent.ACTION_SEND, null, "text/plain", Uri.parse("mailto:")),
// File Storage
makeIntent(Intent.ACTION_OPEN_DOCUMENT, Intent.CATEGORY_OPENABLE, "*/*", null),
makeIntent(Intent.ACTION_OPEN_DOCUMENT, null, "*/*", null),
@@ -108,13 +105,8 @@
makeIntent(Intent.ACTION_OPEN_DOCUMENT_TREE, null, null, null),
makeIntent(Intent.ACTION_CREATE_DOCUMENT, Intent.CATEGORY_OPENABLE, "text/plain", null),
makeIntent(Intent.ACTION_CREATE_DOCUMENT, null, "text/plain", null),
- // Phone call
- makeIntent(Intent.ACTION_DIAL, null, null, Uri.parse("tel:")),
- // SMS
- makeIntent(Intent.ACTION_SEND, null, "text/plain", Uri.parse("sms:")),
- makeIntent(Intent.ACTION_SEND, null, "text/plain", Uri.parse("smsto:")),
- // Web
- makeIntent(Intent.ACTION_VIEW, null, "text/html", Uri.parse("https://example.com")),
+ // Framework
+ makeIntent(Intent.ACTION_CHOOSER, null, null, null),
};
private BroadcastReceiver mReceiver;
diff --git a/hostsidetests/dumpsys/src/android/dumpsys/cts/BatteryStatsDumpsysTest.java b/hostsidetests/dumpsys/src/android/dumpsys/cts/BatteryStatsDumpsysTest.java
index fd3e85d..8ba3064 100644
--- a/hostsidetests/dumpsys/src/android/dumpsys/cts/BatteryStatsDumpsysTest.java
+++ b/hostsidetests/dumpsys/src/android/dumpsys/cts/BatteryStatsDumpsysTest.java
@@ -387,7 +387,7 @@
}
private void checkBattery(String[] parts) {
- assertEquals(13, parts.length);
+ assertEquals(15, parts.length);
if (!parts[4].equals("N/A")) {
assertInteger(parts[4]); // startCount
}
@@ -399,6 +399,9 @@
long bOffReal = assertInteger(parts[10]); // batteryScreenOffRealtime
long bOffUp = assertInteger(parts[11]); // batteryScreenOffUptime
long bEstCap = assertInteger(parts[12]); // batteryEstimatedCapacity
+ assertInteger(parts[13]); // minLearnedBatteryCapacity
+ assertInteger(parts[14]); // maxLearnedBatteryCapacity
+
// The device cannot be up more than there are real-world seconds.
assertTrue("batteryRealtime must be >= batteryUptime", bReal >= bUp);
assertTrue("totalRealtime must be >= totalUptime", tReal >= tUp);
diff --git a/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
index 38f4020..ce640d9 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
@@ -23,6 +23,7 @@
import static android.autofillservice.cts.Helper.assertNumberOfChildren;
import static android.autofillservice.cts.Helper.assertTextAndValue;
import static android.autofillservice.cts.Helper.assertTextIsSanitized;
+import static android.autofillservice.cts.Helper.assertValue;
import static android.autofillservice.cts.Helper.eventually;
import static android.autofillservice.cts.Helper.findNodeByResourceId;
import static android.autofillservice.cts.Helper.runShellCommand;
@@ -45,6 +46,7 @@
import static android.service.autofill.SaveInfo.SAVE_DATA_TYPE_USERNAME;
import static android.text.InputType.TYPE_NULL;
import static android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD;
+import static android.view.View.IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS;
import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
import static com.google.common.truth.Truth.assertThat;
@@ -1287,21 +1289,14 @@
assertThat(usernameContainer.getChildCount()).isEqualTo(2);
}
- private static final boolean BUG_36171235_FIXED = false;
-
@Test
public void testAutofillManuallyOneDataset() throws Exception {
// Set service.
enableService();
- if (BUG_36171235_FIXED)
// And activity.
- mActivity.onUsername((v) -> {
- v.setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS);
- // TODO: setting an empty text, otherwise longPress() does not
- // display the AUTOFILL context menu. Need to fix it, but it's a test case issue...
- v.setText("");
- });
+ mActivity.onUsername(
+ (v) -> v.setImportantForAutofill(IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS));
// Set expectations.
sReplier.addResponse(new CannedDataset.Builder()
@@ -1311,12 +1306,7 @@
.build());
mActivity.expectAutoFill("dude", "sweet");
- // Long-press field to trigger AUTOFILL menu.
- if (BUG_36171235_FIXED) {
- sUiBot.getAutofillMenuOption(ID_USERNAME).click();
- } else {
- mActivity.onUsername((v) -> mActivity.getAutofillManager().requestAutofill(v));
- }
+ sUiBot.getAutofillMenuOption(ID_USERNAME).click();
final FillRequest fillRequest = sReplier.getNextFillRequest();
assertThat(fillRequest.flags).isEqualTo(FLAG_MANUAL_REQUEST);
@@ -1342,14 +1332,9 @@
// Set service.
enableService();
- if (BUG_36171235_FIXED)
// And activity.
- mActivity.onUsername((v) -> {
- v.setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS);
- // TODO: setting an empty text, otherwise longPress() does not display the AUTOFILL
- // context menu. Need to fix it, but it's a test case issue...
- v.setText("");
- });
+ mActivity.onUsername(
+ (v) -> v.setImportantForAutofill(IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS));
// Set expectations.
sReplier.addResponse(new CannedFillResponse.Builder()
@@ -1372,11 +1357,7 @@
}
// Long-press field to trigger AUTOFILL menu.
- if (BUG_36171235_FIXED) {
- sUiBot.getAutofillMenuOption(ID_USERNAME).click();
- } else {
- mActivity.onUsername((v) -> mActivity.getAutofillManager().requestAutofill(v));
- }
+ sUiBot.getAutofillMenuOption(ID_USERNAME).click();
final FillRequest fillRequest = sReplier.getNextFillRequest();
assertThat(fillRequest.flags).isEqualTo(FLAG_MANUAL_REQUEST);
@@ -1390,6 +1371,42 @@
}
@Test
+ public void testAutofillManuallyPartialField() throws Exception {
+ // Set service.
+ enableService();
+
+ // And activity.
+ mActivity.onUsername((v) -> {
+ v.setText("dud");
+ v.setImportantForAutofill(IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS);
+ });
+ mActivity.onPassword((v) -> v.setText("IamSecretMan"));
+
+ // Set expectations.
+ sReplier.addResponse(new CannedDataset.Builder()
+ .setField(ID_USERNAME, "dude")
+ .setField(ID_PASSWORD, "sweet")
+ .setPresentation(createPresentation("The Dude"))
+ .build());
+ mActivity.expectAutoFill("dude", "sweet");
+
+ sUiBot.getAutofillMenuOption(ID_USERNAME).click();
+
+ final FillRequest fillRequest = sReplier.getNextFillRequest();
+ assertThat(fillRequest.flags).isEqualTo(FLAG_MANUAL_REQUEST);
+ // Username value should be available because it triggered the manual request...
+ assertValue(fillRequest.structure, ID_USERNAME, "dud");
+ // ... but password didn't
+ assertTextIsSanitized(fillRequest.structure, ID_PASSWORD);
+
+ // Should have been automatically filled.
+ sUiBot.assertNoDatasets();
+
+ // Check the results.
+ mActivity.assertAutoFilled();
+ }
+
+ @Test
public void testCommitMultipleTimes() throws Throwable {
// Set service.
enableService();
diff --git a/tests/autofillservice/src/android/autofillservice/cts/PartitionedActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/PartitionedActivityTest.java
index 19f6b80..51221b5 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/PartitionedActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/PartitionedActivityTest.java
@@ -240,7 +240,11 @@
final FillRequest fillRequest1 = sReplier.getNextFillRequest();
assertThat(fillRequest1.flags).isEqualTo(expectedFlag);
- assertTextIsSanitized(fillRequest1.structure, ID_L1C1);
+ if (manually) {
+ assertValue(fillRequest1.structure, ID_L1C1, "");
+ } else {
+ assertTextIsSanitized(fillRequest1.structure, ID_L1C1);
+ }
assertTextIsSanitized(fillRequest1.structure, ID_L1C2);
// Auto-fill it.
@@ -272,7 +276,11 @@
assertValue(fillRequest2.structure, ID_L1C1, "l1c1");
assertValue(fillRequest2.structure, ID_L1C2, "l1c2");
- assertTextIsSanitized(fillRequest2.structure, ID_L2C1);
+ if (manually) {
+ assertValue(fillRequest2.structure, ID_L2C1, "");
+ } else {
+ assertTextIsSanitized(fillRequest2.structure, ID_L2C1);
+ }
assertTextIsSanitized(fillRequest2.structure, ID_L2C2);
// Auto-fill it.
@@ -306,7 +314,11 @@
assertValue(fillRequest3.structure, ID_L1C2, "l1c2");
assertValue(fillRequest3.structure, ID_L2C1, "l2c1");
assertValue(fillRequest3.structure, ID_L2C2, "l2c2");
- assertTextIsSanitized(fillRequest3.structure, ID_L3C1);
+ if (manually) {
+ assertValue(fillRequest3.structure, ID_L3C1, "");
+ } else {
+ assertTextIsSanitized(fillRequest3.structure, ID_L3C1);
+ }
assertTextIsSanitized(fillRequest3.structure, ID_L3C2);
// Auto-fill it.
@@ -342,7 +354,11 @@
assertValue(fillRequest4.structure, ID_L2C2, "l2c2");
assertValue(fillRequest4.structure, ID_L3C1, "l3c1");
assertValue(fillRequest4.structure, ID_L3C2, "l3c2");
- assertTextIsSanitized(fillRequest4.structure, ID_L4C1);
+ if (manually) {
+ assertValue(fillRequest4.structure, ID_L4C1, "");
+ } else {
+ assertTextIsSanitized(fillRequest4.structure, ID_L4C1);
+ }
assertTextIsSanitized(fillRequest4.structure, ID_L4C2);
// Auto-fill it.
@@ -400,6 +416,7 @@
final FillExpectation expectation2 = mActivity.expectAutofill()
.onCell(2, 1, "l2c1")
.onCell(2, 2, "l2c2");
+ mActivity.setText(2, 1, "L2..");
// Trigger auto-fill.
mActivity.forceAutofill(2, 1);
@@ -408,7 +425,7 @@
assertValue(fillRequest2.structure, ID_L1C1, "l1c1");
assertValue(fillRequest2.structure, ID_L1C2, "l1c2");
- assertTextIsSanitized(fillRequest2.structure, ID_L2C1);
+ assertValue(fillRequest2.structure, ID_L2C1, "L2..");
assertTextIsSanitized(fillRequest2.structure, ID_L2C2);
// Check the results.
@@ -456,6 +473,7 @@
.build())
.build();
sReplier.addResponse(response4);
+ mActivity.setText(4, 1, "L4..");
final FillExpectation expectation4 = mActivity.expectAutofill()
.onCell(4, 1, "l4c1")
.onCell(4, 2, "l4c2");
@@ -471,7 +489,7 @@
assertValue(fillRequest4.structure, ID_L2C2, "l2c2");
assertValue(fillRequest4.structure, ID_L3C1, "l3c1");
assertValue(fillRequest4.structure, ID_L3C2, "l3c2");
- assertTextIsSanitized(fillRequest4.structure, ID_L4C1);
+ assertValue(fillRequest4.structure, ID_L4C1, "L4..");
assertTextIsSanitized(fillRequest4.structure, ID_L4C2);
// Check the results.
diff --git a/tests/tests/nativemedia/aaudio/src/test_aaudio.cpp b/tests/tests/nativemedia/aaudio/src/test_aaudio.cpp
index 37b434e..c57682f 100644
--- a/tests/tests/nativemedia/aaudio/src/test_aaudio.cpp
+++ b/tests/tests/nativemedia/aaudio/src/test_aaudio.cpp
@@ -57,6 +57,58 @@
}
+
+// Test creating a default stream with specific devices
+void runtest_aaudio_devices(int32_t deviceId, bool expectFail) {
+ AAudioStreamBuilder *aaudioBuilder = nullptr;
+ AAudioStream *aaudioStream = nullptr;
+
+ // Use an AAudioStreamBuilder to define the stream.
+ aaudio_result_t result = AAudio_createStreamBuilder(&aaudioBuilder);
+ ASSERT_EQ(AAUDIO_OK, result);
+ ASSERT_NE(nullptr, aaudioBuilder);
+
+ AAudioStreamBuilder_setDeviceId(aaudioBuilder,deviceId);
+
+ // Create an AAudioStream using the Builder.
+ result = AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream);
+ if (expectFail) {
+ ASSERT_NE(AAUDIO_OK, result);
+ ASSERT_EQ(nullptr, aaudioStream);
+ } else {
+ // Pass or fail is OK. Just don't crash.
+ ASSERT_TRUE(((result < 0) && (aaudioStream == nullptr))
+ || ((result == AAUDIO_OK) && (aaudioStream != nullptr)));
+ }
+
+ // Cleanup
+ EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_delete(aaudioBuilder));
+ if (aaudioStream != nullptr) {
+ AAudioStream_close(aaudioStream);
+ }
+}
+
+TEST(test_aaudio, aaudio_stream_device_unspecified) {
+ runtest_aaudio_devices(AAUDIO_DEVICE_UNSPECIFIED, false);
+}
+
+/* FIXME - why can we open this device? What is an illegal deviceId?
+TEST(test_aaudio, aaudio_stream_device_absurd) {
+ runtest_aaudio_devices(19736459, true);
+}
+*/
+/* FIXME review
+TEST(test_aaudio, aaudio_stream_device_reasonable) {
+ runtest_aaudio_devices(1, false);
+}
+*/
+
+/* FIXME - why can we open this device? What is an illegal deviceId?
+TEST(test_aaudio, aaudio_stream_device_negative) {
+ runtest_aaudio_devices(-765, true);
+}
+*/
+
// Test creating a default stream with everything unspecified.
TEST(test_aaudio, aaudio_stream_unspecified) {
AAudioStreamBuilder *aaudioBuilder = nullptr;
@@ -120,7 +172,12 @@
AAudioStreamBuilder_setBufferCapacityInFrames(aaudioBuilder, 2000);
// Create an AAudioStream using the Builder.
- ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
+ result = AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream);
+ if (requestedSharingMode == AAUDIO_SHARING_MODE_EXCLUSIVE
+ && result != AAUDIO_OK) {
+ return; // EXCLUSIVE just may not be available. Should not crash.
+ }
+ ASSERT_EQ(AAUDIO_OK, result);
EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_delete(aaudioBuilder));
EXPECT_EQ(AAUDIO_STREAM_STATE_OPEN, AAudioStream_getState(aaudioStream));
@@ -184,15 +241,14 @@
// Write some data while we are running. Read counter should be advancing.
writeLoops = 1 * actualSampleRate / framesPerBurst; // 1 second
ASSERT_LT(2, writeLoops); // detect absurdly high framesPerBurst
- timeoutNanos = 10 * NANOS_PER_SECOND * framesPerBurst / actualSampleRate; // bursts
+ timeoutNanos = 100 * (NANOS_PER_SECOND * framesPerBurst / actualSampleRate); // N bursts
framesWritten = 1;
aaudioFramesRead = AAudioStream_getFramesRead(aaudioStream);
aaudioFramesRead1 = aaudioFramesRead;
int64_t beginTime = getNanoseconds(CLOCK_MONOTONIC);
do {
framesWritten = AAudioStream_write(aaudioStream, data, framesPerBurst, timeoutNanos);
- ASSERT_GE(framesWritten, 0);
- ASSERT_LE(framesWritten, framesPerBurst);
+ ASSERT_EQ(framesWritten, framesPerBurst);
framesTotal += framesWritten;
aaudioFramesWritten = AAudioStream_getFramesWritten(aaudioStream);
@@ -211,8 +267,8 @@
aaudioFramesRead2 = AAudioStream_getFramesRead(aaudioStream);
int64_t endTime = getNanoseconds(CLOCK_MONOTONIC);
ASSERT_GT(aaudioFramesRead2, 0);
- ASSERT_GT(aaudioFramesRead2, aaudioFramesRead1);
- ASSERT_LE(aaudioFramesRead2, aaudioFramesWritten);
+ EXPECT_GT(aaudioFramesRead2, aaudioFramesRead1);
+
// TODO why is AudioTrack path so inaccurate?
const double rateTolerance = 200.0; // arbitrary tolerance for sample rate
@@ -236,15 +292,16 @@
aaudioFramesRead = AAudioStream_getFramesRead(aaudioStream);
ASSERT_GE(aaudioFramesRead, aaudioFramesRead2); // monotonic increase
- // Use this to sleep by waiting for something that won't happen.
- AAudioStream_waitForStateChange(aaudioStream, AAUDIO_STREAM_STATE_PAUSED, &state, timeoutNanos);
+ // Use this to sleep by waiting for a state that won't happen.
+ timeoutNanos = 100 * NANOS_PER_MILLISECOND;
+ AAudioStream_waitForStateChange(aaudioStream, AAUDIO_STREAM_STATE_OPEN, &state, timeoutNanos);
aaudioFramesRead2 = AAudioStream_getFramesRead(aaudioStream);
EXPECT_EQ(aaudioFramesRead, aaudioFramesRead2);
// ------------------- TEST FLUSH -----------------
// Prime the buffer.
timeoutNanos = 0;
- writeLoops = 100;
+ writeLoops = 1000;
do {
framesWritten = AAudioStream_write(aaudioStream, data, framesPerBurst, timeoutNanos);
framesTotal += framesWritten;
@@ -282,12 +339,10 @@
runtest_aaudio_stream(AAUDIO_SHARING_MODE_SHARED);
}
-/* TODO Enable exclusive mode test.
-// Test Writing to an AAudioStream using EXCLUSIVE sharing mode.
+// Test Writing to an AAudioStream using EXCLUSIVE sharing mode. It may fail gracefully.
TEST(test_aaudio, aaudio_stream_exclusive) {
runtest_aaudio_stream(AAUDIO_SHARING_MODE_EXCLUSIVE);
}
-*/
int main(int argc, char **argv) {
testing::InitGoogleTest(&argc, argv);
diff --git a/tests/tests/nativemedia/aaudio/src/test_aaudio_callback.cpp b/tests/tests/nativemedia/aaudio/src/test_aaudio_callback.cpp
index 2ec1e1c..3786967 100644
--- a/tests/tests/nativemedia/aaudio/src/test_aaudio_callback.cpp
+++ b/tests/tests/nativemedia/aaudio/src/test_aaudio_callback.cpp
@@ -18,17 +18,55 @@
#define LOG_TAG "AAudioTest"
#include <gtest/gtest.h>
+#include <atomic>
#include <utils/Log.h>
#include <aaudio/AAudio.h>
#include "test_aaudio.h"
typedef struct AAudioCallbackTestData {
- int32_t callbackCount;
int32_t expectedFramesPerCallback;
int32_t actualFramesPerCallback;
+ int32_t minLatency;
+ int32_t maxLatency;
+ std::atomic<aaudio_result_t> callbackError;
+ std::atomic<int32_t> callbackCount;
} AAudioCallbackTestData;
+static int32_t measureLatency(AAudioStream *stream) {
+ int64_t presentationTime = 0;
+ int64_t presentationPosition = 0;
+ int64_t now = getNanoseconds();
+ int32_t sampleRate = AAudioStream_getSampleRate(stream);
+ int64_t framesWritten = AAudioStream_getFramesWritten(stream);
+ aaudio_result_t result = AAudioStream_getTimestamp(stream,
+ CLOCK_MONOTONIC,
+ &presentationPosition,
+ &presentationTime);
+ if (result < 0) {
+ return result;
+ }
+ // Calculate when the last frame written would be played.
+ int64_t deltaFrames = framesWritten - presentationPosition;
+ EXPECT_GE(framesWritten, presentationPosition);
+ int64_t calculatedDeltaNanos = deltaFrames * NANOS_PER_SECOND / sampleRate;
+ int64_t calculatedTimeNanos = presentationTime + calculatedDeltaNanos;
+ int64_t latencyNanos = calculatedTimeNanos - now;
+ int32_t latencyMillis = (int32_t) ((latencyNanos + NANOS_PER_MILLISECOND - 1)
+ / NANOS_PER_MILLISECOND);
+ return latencyMillis;
+}
+
+static void MyErrorCallbackProc(
+ AAudioStream *stream,
+ void *userData,
+ aaudio_result_t error) {
+ (void) stream;
+ AAudioCallbackTestData *myData = (AAudioCallbackTestData *) userData;
+ myData->callbackError = error;
+
+}
+
// Callback function that fills the audio output buffer.
static aaudio_data_callback_result_t MyDataCallbackProc(
AAudioStream *stream,
@@ -54,6 +92,17 @@
float *floatData = (float *) audioData;
for (int i = 0; i < numSamples; i++) *floatData++ = 0.0f;
}
+
+ int32_t latency = measureLatency(stream);
+ if (latency > 0) {
+ if (latency < myData->minLatency) {
+ myData->minLatency = latency;
+ }
+ if (latency > myData->maxLatency) {
+ myData->maxLatency = latency;
+ }
+ }
+
myData->callbackCount++;
return AAUDIO_CALLBACK_RESULT_CONTINUE;
}
@@ -61,7 +110,7 @@
// Test Writing to an AAudioStream using a Callback
void runtest_aaudio_callback(aaudio_sharing_mode_t requestedSharingMode,
int32_t framesPerDataCallback) {
- AAudioCallbackTestData myTestData = { 0, 0, 0 };
+ AAudioCallbackTestData myTestData;
const int32_t requestedSampleRate = 48000;
const int32_t requestedSamplesPerFrame = 2;
const aaudio_audio_format_t requestedDataFormat = AAUDIO_FORMAT_PCM_I16;
@@ -79,6 +128,10 @@
AAudioStream *stream = nullptr;
aaudio_result_t result = AAUDIO_OK;
+ myTestData.callbackCount.store(0);
+ myTestData.callbackError = AAUDIO_OK;
+ myTestData.actualFramesPerCallback = 0;
+ myTestData.expectedFramesPerCallback = 0;
// Use an AAudioStreamBuilder to define the stream.
result = AAudio_createStreamBuilder(&builder);
@@ -93,6 +146,7 @@
AAudioStreamBuilder_setSharingMode(builder, requestedSharingMode);
AAudioStreamBuilder_setBufferCapacityInFrames(builder, 2000);
+ AAudioStreamBuilder_setErrorCallback(builder, MyErrorCallbackProc, &myTestData);
AAudioStreamBuilder_setDataCallback(builder, MyDataCallbackProc, &myTestData);
if (framesPerDataCallback != AAUDIO_UNSPECIFIED) {
AAudioStreamBuilder_setFramesPerDataCallback(builder, framesPerDataCallback);
@@ -118,8 +172,8 @@
actualDataFormat = AAudioStream_getFormat(stream);
- // TODO test this on full build
- // ASSERT_NE(AAUDIO_DEVICE_UNSPECIFIED, AAudioStream_getDeviceId(stream));
+ // TODO Why does getDeviceId() always return 0?
+ // EXPECT_NE(AAUDIO_DEVICE_UNSPECIFIED, AAudioStream_getDeviceId(stream));
framesPerBurst = AAudioStream_getFramesPerBurst(stream);
ASSERT_TRUE(framesPerBurst >= 16 && framesPerBurst <= 1024); // TODO what is min/max?
@@ -136,18 +190,27 @@
// Start/stop more than once to see if it fails after the first time.
// Write some data and measure the rate to see if the timing is OK.
for (int loopIndex = 0; loopIndex < 2; loopIndex++) {
+
myTestData.callbackCount = 0;
+ myTestData.minLatency = INT32_MAX;
+ myTestData.maxLatency = 0;
+ myTestData.callbackCount.store(0);
+
myTestData.expectedFramesPerCallback = actualFramesPerDataCallback;
// Start and wait for server to respond.
ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStart(stream));
+
ASSERT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(stream,
AAUDIO_STREAM_STATE_STARTING,
&state,
DEFAULT_STATE_TIMEOUT));
EXPECT_EQ(AAUDIO_STREAM_STATE_STARTED, state);
- sleep(2);
+ sleep(2); // let the stream run
+
+ ASSERT_EQ(myTestData.callbackError.load(), AAUDIO_OK);
+ ASSERT_GT(myTestData.callbackCount.load(), 10);
// For more coverage, alternate pausing and stopping.
if ((loopIndex & 1) == 0) {
@@ -168,29 +231,34 @@
EXPECT_EQ(AAUDIO_STREAM_STATE_STOPPED, state);
}
- int32_t oldCallbackCount = myTestData.callbackCount;
+ int32_t oldCallbackCount = myTestData.callbackCount.load();
EXPECT_GT(oldCallbackCount, 10);
sleep(1);
- EXPECT_EQ(oldCallbackCount, myTestData.callbackCount); // expect not advancing
+ EXPECT_EQ(oldCallbackCount, myTestData.callbackCount.load()); // expect not advancing
if (framesPerDataCallback != AAUDIO_UNSPECIFIED) {
ASSERT_EQ(framesPerDataCallback, myTestData.actualFramesPerCallback);
}
+
+ EXPECT_GE(myTestData.minLatency, 1); // Absurdly low
+ EXPECT_LE(myTestData.maxLatency, 200); // Absurdly high, should be < 30
+ //printf("latency: %d, %d\n", myTestData.minLatency, myTestData.maxLatency);
}
+ ASSERT_EQ(myTestData.callbackError.load(), AAUDIO_OK);
+
EXPECT_EQ(AAUDIO_OK, AAudioStream_close(stream));
}
// Test Using an AAudioStream callback in SHARED mode.
-
TEST(test_aaudio, aaudio_callback_shared_unspecified) {
-runtest_aaudio_callback(AAUDIO_SHARING_MODE_SHARED, AAUDIO_UNSPECIFIED);
+ runtest_aaudio_callback(AAUDIO_SHARING_MODE_SHARED, AAUDIO_UNSPECIFIED);
}
TEST(test_aaudio, aaudio_callback_shared_109) {
-runtest_aaudio_callback(AAUDIO_SHARING_MODE_SHARED, 109); // arbitrary prime number < 192
+ runtest_aaudio_callback(AAUDIO_SHARING_MODE_SHARED, 109); // arbitrary prime number < 192
}
TEST(test_aaudio, aaudio_callback_shared_223) {
-runtest_aaudio_callback(AAUDIO_SHARING_MODE_SHARED, 223); // arbitrary prime number > 192
+ runtest_aaudio_callback(AAUDIO_SHARING_MODE_SHARED, 223); // arbitrary prime number > 192
}
diff --git a/tests/tests/nativemedia/aaudio/src/test_aaudio_misc.cpp b/tests/tests/nativemedia/aaudio/src/test_aaudio_misc.cpp
index 8599d48..6662b72 100644
--- a/tests/tests/nativemedia/aaudio/src/test_aaudio_misc.cpp
+++ b/tests/tests/nativemedia/aaudio/src/test_aaudio_misc.cpp
@@ -1,7 +1,7 @@
/*
* Copyright 2017 The Android Open Source Project
*
- * Licensed under the Apache License, Version 2.0 (the "License");
+ * Licensed under the Apache License, Version 2.0 (the "License", ENUM_CANNOT_CHANGE);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
@@ -25,53 +25,55 @@
// Make sure enums do not change value.
TEST(test_aaudio_misc, aaudio_freeze_enums) {
- ASSERT_EQ(0, AAUDIO_DIRECTION_OUTPUT);
- ASSERT_EQ(1, AAUDIO_DIRECTION_INPUT);
+#define ENUM_CANNOT_CHANGE "enum in API cannot change"
- ASSERT_EQ(-1, AAUDIO_FORMAT_INVALID);
- ASSERT_EQ(0, AAUDIO_FORMAT_UNSPECIFIED);
- ASSERT_EQ(1, AAUDIO_FORMAT_PCM_I16);
- ASSERT_EQ(2, AAUDIO_FORMAT_PCM_FLOAT);
+ static_assert(0 == AAUDIO_DIRECTION_OUTPUT, ENUM_CANNOT_CHANGE);
+ static_assert(1 == AAUDIO_DIRECTION_INPUT, ENUM_CANNOT_CHANGE);
- ASSERT_EQ(0, AAUDIO_OK);
- ASSERT_EQ(-900, AAUDIO_ERROR_BASE);
- ASSERT_EQ(-899, AAUDIO_ERROR_DISCONNECTED);
- ASSERT_EQ(-898, AAUDIO_ERROR_ILLEGAL_ARGUMENT);
- ASSERT_EQ(-897, AAUDIO_ERROR_INCOMPATIBLE);
- ASSERT_EQ(-896, AAUDIO_ERROR_INTERNAL);
- ASSERT_EQ(-895, AAUDIO_ERROR_INVALID_STATE);
- ASSERT_EQ(-894, AAUDIO_ERROR_UNEXPECTED_STATE);
- ASSERT_EQ(-893, AAUDIO_ERROR_UNEXPECTED_VALUE);
- ASSERT_EQ(-892, AAUDIO_ERROR_INVALID_HANDLE);
- ASSERT_EQ(-891, AAUDIO_ERROR_INVALID_QUERY);
- ASSERT_EQ(-890, AAUDIO_ERROR_UNIMPLEMENTED);
- ASSERT_EQ(-889, AAUDIO_ERROR_UNAVAILABLE);
- ASSERT_EQ(-888, AAUDIO_ERROR_NO_FREE_HANDLES);
- ASSERT_EQ(-887, AAUDIO_ERROR_NO_MEMORY);
- ASSERT_EQ(-886, AAUDIO_ERROR_NULL);
- ASSERT_EQ(-885, AAUDIO_ERROR_TIMEOUT);
- ASSERT_EQ(-884, AAUDIO_ERROR_WOULD_BLOCK);
- ASSERT_EQ(-883, AAUDIO_ERROR_INVALID_FORMAT);
- ASSERT_EQ(-882, AAUDIO_ERROR_OUT_OF_RANGE);
- ASSERT_EQ(-881, AAUDIO_ERROR_NO_SERVICE);
+ static_assert(-1 == AAUDIO_FORMAT_INVALID, ENUM_CANNOT_CHANGE);
+ static_assert(0 == AAUDIO_FORMAT_UNSPECIFIED, ENUM_CANNOT_CHANGE);
+ static_assert(1 == AAUDIO_FORMAT_PCM_I16, ENUM_CANNOT_CHANGE);
+ static_assert(2 == AAUDIO_FORMAT_PCM_FLOAT, ENUM_CANNOT_CHANGE);
- ASSERT_EQ(0, AAUDIO_STREAM_STATE_UNINITIALIZED);
- ASSERT_EQ(1, AAUDIO_STREAM_STATE_UNKNOWN);
- ASSERT_EQ(2, AAUDIO_STREAM_STATE_OPEN);
- ASSERT_EQ(3, AAUDIO_STREAM_STATE_STARTING);
- ASSERT_EQ(4, AAUDIO_STREAM_STATE_STARTED);
- ASSERT_EQ(5, AAUDIO_STREAM_STATE_PAUSING);
- ASSERT_EQ(6, AAUDIO_STREAM_STATE_PAUSED);
- ASSERT_EQ(7, AAUDIO_STREAM_STATE_FLUSHING);
- ASSERT_EQ(8, AAUDIO_STREAM_STATE_FLUSHED);
- ASSERT_EQ(9, AAUDIO_STREAM_STATE_STOPPING);
- ASSERT_EQ(10, AAUDIO_STREAM_STATE_STOPPED);
- ASSERT_EQ(11, AAUDIO_STREAM_STATE_CLOSING);
- ASSERT_EQ(12, AAUDIO_STREAM_STATE_CLOSED);
+ static_assert(0 == AAUDIO_OK, ENUM_CANNOT_CHANGE);
+ static_assert(-900 == AAUDIO_ERROR_BASE, ENUM_CANNOT_CHANGE);
+ static_assert(-899 == AAUDIO_ERROR_DISCONNECTED, ENUM_CANNOT_CHANGE);
+ static_assert(-898 == AAUDIO_ERROR_ILLEGAL_ARGUMENT, ENUM_CANNOT_CHANGE);
+ static_assert(-897 == AAUDIO_ERROR_INCOMPATIBLE, ENUM_CANNOT_CHANGE);
+ static_assert(-896 == AAUDIO_ERROR_INTERNAL, ENUM_CANNOT_CHANGE);
+ static_assert(-895 == AAUDIO_ERROR_INVALID_STATE, ENUM_CANNOT_CHANGE);
+ static_assert(-894 == AAUDIO_ERROR_UNEXPECTED_STATE, ENUM_CANNOT_CHANGE);
+ static_assert(-893 == AAUDIO_ERROR_UNEXPECTED_VALUE, ENUM_CANNOT_CHANGE);
+ static_assert(-892 == AAUDIO_ERROR_INVALID_HANDLE, ENUM_CANNOT_CHANGE);
+ static_assert(-891 == AAUDIO_ERROR_INVALID_QUERY, ENUM_CANNOT_CHANGE);
+ static_assert(-890 == AAUDIO_ERROR_UNIMPLEMENTED, ENUM_CANNOT_CHANGE);
+ static_assert(-889 == AAUDIO_ERROR_UNAVAILABLE, ENUM_CANNOT_CHANGE);
+ static_assert(-888 == AAUDIO_ERROR_NO_FREE_HANDLES, ENUM_CANNOT_CHANGE);
+ static_assert(-887 == AAUDIO_ERROR_NO_MEMORY, ENUM_CANNOT_CHANGE);
+ static_assert(-886 == AAUDIO_ERROR_NULL, ENUM_CANNOT_CHANGE);
+ static_assert(-885 == AAUDIO_ERROR_TIMEOUT, ENUM_CANNOT_CHANGE);
+ static_assert(-884 == AAUDIO_ERROR_WOULD_BLOCK, ENUM_CANNOT_CHANGE);
+ static_assert(-883 == AAUDIO_ERROR_INVALID_FORMAT, ENUM_CANNOT_CHANGE);
+ static_assert(-882 == AAUDIO_ERROR_OUT_OF_RANGE, ENUM_CANNOT_CHANGE);
+ static_assert(-881 == AAUDIO_ERROR_NO_SERVICE, ENUM_CANNOT_CHANGE);
- ASSERT_EQ(0, AAUDIO_SHARING_MODE_EXCLUSIVE);
- ASSERT_EQ(1, AAUDIO_SHARING_MODE_SHARED);
+ static_assert(0 == AAUDIO_STREAM_STATE_UNINITIALIZED, ENUM_CANNOT_CHANGE);
+ static_assert(1 == AAUDIO_STREAM_STATE_UNKNOWN, ENUM_CANNOT_CHANGE);
+ static_assert(2 == AAUDIO_STREAM_STATE_OPEN, ENUM_CANNOT_CHANGE);
+ static_assert(3 == AAUDIO_STREAM_STATE_STARTING, ENUM_CANNOT_CHANGE);
+ static_assert(4 == AAUDIO_STREAM_STATE_STARTED, ENUM_CANNOT_CHANGE);
+ static_assert(5 == AAUDIO_STREAM_STATE_PAUSING, ENUM_CANNOT_CHANGE);
+ static_assert(6 == AAUDIO_STREAM_STATE_PAUSED, ENUM_CANNOT_CHANGE);
+ static_assert(7 == AAUDIO_STREAM_STATE_FLUSHING, ENUM_CANNOT_CHANGE);
+ static_assert(8 == AAUDIO_STREAM_STATE_FLUSHED, ENUM_CANNOT_CHANGE);
+ static_assert(9 == AAUDIO_STREAM_STATE_STOPPING, ENUM_CANNOT_CHANGE);
+ static_assert(10 == AAUDIO_STREAM_STATE_STOPPED, ENUM_CANNOT_CHANGE);
+ static_assert(11 == AAUDIO_STREAM_STATE_CLOSING, ENUM_CANNOT_CHANGE);
+ static_assert(12 == AAUDIO_STREAM_STATE_CLOSED, ENUM_CANNOT_CHANGE);
- ASSERT_EQ(0, AAUDIO_CALLBACK_RESULT_CONTINUE);
- ASSERT_EQ(1, AAUDIO_CALLBACK_RESULT_STOP);
+ static_assert(0 == AAUDIO_SHARING_MODE_EXCLUSIVE, ENUM_CANNOT_CHANGE);
+ static_assert(1 == AAUDIO_SHARING_MODE_SHARED, ENUM_CANNOT_CHANGE);
+
+ static_assert(0 == AAUDIO_CALLBACK_RESULT_CONTINUE, ENUM_CANNOT_CHANGE);
+ static_assert(1 == AAUDIO_CALLBACK_RESULT_STOP, ENUM_CANNOT_CHANGE);
}
diff --git a/tests/tests/text/src/android/text/format/cts/FormatterTest.java b/tests/tests/text/src/android/text/format/cts/FormatterTest.java
index fa11023..8c7fdc9 100644
--- a/tests/tests/text/src/android/text/format/cts/FormatterTest.java
+++ b/tests/tests/text/src/android/text/format/cts/FormatterTest.java
@@ -19,6 +19,8 @@
import static org.junit.Assert.assertEquals;
import android.content.Context;
+import android.content.res.Configuration;
+import android.os.LocaleList;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
@@ -29,6 +31,7 @@
import java.math.BigDecimal;
import java.math.MathContext;
+import java.util.Locale;
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -38,9 +41,12 @@
// test null Context
assertEquals("", Formatter.formatFileSize(null, 0));
- MathContext mc = MathContext.DECIMAL64;
- BigDecimal bd = new BigDecimal((long) 1000, mc);
- Context context = InstrumentationRegistry.getTargetContext();
+ final MathContext mc = MathContext.DECIMAL64;
+ final BigDecimal bd = new BigDecimal((long) 1000, mc);
+ final Configuration config = new Configuration();
+ config.setLocales(new LocaleList(Locale.US));
+ final Context context =
+ InstrumentationRegistry.getTargetContext().createConfigurationContext(config);
// test different long values with various length
assertEquals("0 B", Formatter.formatFileSize(context, 0));
@@ -53,6 +59,8 @@
assertEquals("0.90 kB", Formatter.formatFileSize(context, 901));
assertEquals("1.00 kB", Formatter.formatFileSize(context, bd.pow(1).longValue()));
+ assertEquals("1.50 kB", Formatter.formatFileSize(context, bd.pow(1).longValue() * 3 / 2));
+ assertEquals("12.50 kB", Formatter.formatFileSize(context, bd.pow(1).longValue() * 25 / 2));
assertEquals("1.00 MB", Formatter.formatFileSize(context, bd.pow(2).longValue()));
@@ -69,6 +77,48 @@
}
@Test
+ public void testFormatShortFileSize() {
+ // test null Context
+ assertEquals("", Formatter.formatFileSize(null, 0));
+
+ final MathContext mc = MathContext.DECIMAL64;
+ final BigDecimal bd = new BigDecimal((long) 1000, mc);
+ final Configuration config = new Configuration();
+ config.setLocales(new LocaleList(Locale.US));
+ final Context context =
+ InstrumentationRegistry.getTargetContext().createConfigurationContext(config);
+
+ // test different long values with various length
+ assertEquals("0 B", Formatter.formatShortFileSize(context, 0));
+ assertEquals("1 B", Formatter.formatShortFileSize(context, 1));
+ assertEquals("9 B", Formatter.formatShortFileSize(context, 9));
+ assertEquals("10 B", Formatter.formatShortFileSize(context, 10));
+ assertEquals("99 B", Formatter.formatShortFileSize(context, 99));
+ assertEquals("100 B", Formatter.formatShortFileSize(context, 100));
+ assertEquals("900 B", Formatter.formatShortFileSize(context, 900));
+ assertEquals("0.90 kB", Formatter.formatShortFileSize(context, 901));
+
+ assertEquals("1.0 kB", Formatter.formatShortFileSize(context, bd.pow(1).longValue()));
+ assertEquals("1.5 kB", Formatter.formatShortFileSize(context,
+ bd.pow(1).longValue() * 3 / 2));
+ assertEquals("13 kB", Formatter.formatShortFileSize(context,
+ bd.pow(1).longValue() * 25 / 2));
+
+ assertEquals("1.0 MB", Formatter.formatShortFileSize(context, bd.pow(2).longValue()));
+
+ assertEquals("1.0 GB", Formatter.formatShortFileSize(context, bd.pow(3).longValue()));
+
+ assertEquals("1.0 TB", Formatter.formatShortFileSize(context, bd.pow(4).longValue()));
+
+ assertEquals("1.0 PB", Formatter.formatShortFileSize(context, bd.pow(5).longValue()));
+
+ assertEquals("1000 PB", Formatter.formatShortFileSize(context, bd.pow(6).longValue()));
+
+ // test Negative value
+ assertEquals("-1 B", Formatter.formatShortFileSize(context, -1));
+ }
+
+ @Test
public void testFormatIpAddress() {
assertEquals("1.0.168.192", Formatter.formatIpAddress(0xC0A80001));
assertEquals("1.0.0.127", Formatter.formatIpAddress(0x7F000001));