Merge "Add test cases for Typeface.setFallback." into oc-dev
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/peripheralprofile/ProfileManager.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/peripheralprofile/ProfileManager.java
index 1d585ac..035dc3f 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/peripheralprofile/ProfileManager.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/peripheralprofile/ProfileManager.java
@@ -56,6 +56,10 @@
"<OutputDevInfo ChanCounts=\"2\" ChanPosMasks=\"12\" ChanIndexMasks=\"3\" Encodings=\"4\" SampleRates=\"44100,48000,88200,96000\" />" +
"<InputDevInfo ChanCounts=\"2\" ChanPosMasks=\"12\" ChanIndexMasks=\"3\" Encodings=\"4\" SampleRates=\"44100,48000,88200,96000\" />" +
"</PeripheralProfile>" +
+ "<PeripheralProfile ProfileName=\"AudioBox USB\" ProfileDescription=\"Presonus AudioBox USB\" ProductName=\"USB-Audio - AudioBox USB\">" +
+ "<OutputDevInfo ChanCounts=\"2\" ChanPosMasks=\"12\" ChanIndexMasks=\"3\" Encodings=\"4\" SampleRates=\"44100,48000\" />" +
+ "<InputDevInfo ChanCounts=\"2\" ChanPosMasks=\"12\" ChanIndexMasks=\"3\" Encodings=\"4\" SampleRates=\"44100,48000\" />" +
+ "</PeripheralProfile>" +
"</ProfileList>";
// XML Tags and Attributes
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
index 15daed9..60d5cb9 100644
--- a/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
@@ -700,9 +700,9 @@
Log.i(TAG, "Setting Battery Saver Mode to " + enabled);
if (enabled) {
turnBatteryOff();
- executeSilentShellCommand("settings put global low_power 1");
+ executeSilentShellCommand("cmd power set-mode 1");
} else {
- executeSilentShellCommand("settings put global low_power 0");
+ executeSilentShellCommand("cmd power set-mode 0");
turnBatteryOn();
}
}
diff --git a/tests/app/src/android/app/cts/NotificationChannelTest.java b/tests/app/src/android/app/cts/NotificationChannelTest.java
index 74047be..70ec9cf 100644
--- a/tests/app/src/android/app/cts/NotificationChannelTest.java
+++ b/tests/app/src/android/app/cts/NotificationChannelTest.java
@@ -25,6 +25,7 @@
import android.media.AudioAttributes;
import android.net.Uri;
import android.os.Parcel;
+import android.provider.Settings;
import android.test.AndroidTestCase;
public class NotificationChannelTest extends AndroidTestCase {
@@ -52,7 +53,7 @@
assertEquals(false, channel.shouldVibrate());
assertEquals(null, channel.getVibrationPattern());
assertEquals(IMPORTANCE_DEFAULT, channel.getImportance());
- assertEquals(null, channel.getSound());
+ assertEquals(Settings.System.DEFAULT_NOTIFICATION_URI, channel.getSound());
assertTrue(channel.canShowBadge());
assertEquals(Notification.AUDIO_ATTRIBUTES_DEFAULT, channel.getAudioAttributes());
assertEquals(null, channel.getGroup());
diff --git a/tests/tests/content/src/android/content/cts/ContentResolverTest.java b/tests/tests/content/src/android/content/cts/ContentResolverTest.java
index 0ceda3a..e5e8fe4 100644
--- a/tests/tests/content/src/android/content/cts/ContentResolverTest.java
+++ b/tests/tests/content/src/android/content/cts/ContentResolverTest.java
@@ -24,7 +24,6 @@
import android.content.res.AssetFileDescriptor;
import android.database.ContentObserver;
import android.database.Cursor;
-import android.database.PageViewCursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.CancellationSignal;
@@ -35,6 +34,7 @@
import android.util.Log;
import com.android.compatibility.common.util.PollingCheck;
+import com.android.internal.util.ArrayUtils;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
@@ -419,41 +419,10 @@
}
/**
- * Verifies that paging arguments are handled correctly
- * when the provider supports paging.
+ * Verifies that paging information is correctly relayed, and that
+ * honored arguments from a supporting client are returned correctly.
*/
- public void testQuery_InProcessProvider_NoAutoPaging() {
-
- mContentResolver.delete(TABLE1_URI, null, null);
- ContentValues values = new ContentValues();
-
- for (int i = 0; i < 100; i++) {
- values.put(COLUMN_KEY_NAME, i);
- mContentResolver.insert(TABLE1_URI, values);
- }
-
- Bundle queryArgs = new Bundle();
- queryArgs.putInt(ContentResolver.QUERY_ARG_OFFSET, 10);
- queryArgs.putInt(ContentResolver.QUERY_ARG_LIMIT, 3);
-
- mCursor = mContentResolver.query(TABLE1_URI, null, queryArgs, null);
- int col = mCursor.getColumnIndexOrThrow(COLUMN_KEY_NAME);
-
- Bundle extras = mCursor.getExtras();
- extras = extras != null ? extras : Bundle.EMPTY;
-
- assertEquals(100, mCursor.getCount());
- assertFalse(extras.containsKey(PageViewCursor.EXTRA_AUTO_PAGED));
- assertFalse(extras.containsKey(ContentResolver.EXTRA_TOTAL_SIZE));
-
- mCursor.close();
- }
-
- /**
- * Verifies that paging arguments are handled correctly
- * when the provider supports paging.
- */
- public void testQuery_OutOfProcessProvider_AutoPaging() {
+ public void testQuery_PagedResults() {
Bundle queryArgs = new Bundle();
queryArgs.putInt(ContentResolver.QUERY_ARG_OFFSET, 10);
@@ -461,88 +430,30 @@
queryArgs.putInt(TestPagingContentProvider.RECORDSET_SIZE, 100);
mCursor = mContentResolver.query(
- TestPagingContentProvider.UNPAGED_DATA_URI, null, queryArgs, null);
-
- Bundle extras = mCursor.getExtras();
- extras = extras != null ? extras : Bundle.EMPTY;
-
- assertEquals(3, mCursor.getCount());
- assertTrue(extras.getBoolean(PageViewCursor.EXTRA_AUTO_PAGED));
- assertTrue(extras.containsKey(ContentResolver.EXTRA_TOTAL_SIZE));
- assertEquals(100, extras.getInt(ContentResolver.EXTRA_TOTAL_SIZE));
-
- int col = mCursor.getColumnIndexOrThrow(TestPagingContentProvider.COLUMN_POS);
-
- mCursor.moveToNext();
- assertEquals(10, mCursor.getInt(col));
- mCursor.moveToNext();
- assertEquals(11, mCursor.getInt(col));
- mCursor.moveToNext();
- assertEquals(12, mCursor.getInt(col));
-
- assertFalse(mCursor.moveToNext());
-
- mCursor.close();
- }
-
- /**
- * Verifies that paging arguments are handled correctly
- * when the provider supports paging.
- */
- public void testQuery_OutOfProcessProvider_AutoPaging_OffsetOutOfBounds() {
-
- Bundle queryArgs = new Bundle();
- queryArgs.putInt(ContentResolver.QUERY_ARG_OFFSET, 10);
- queryArgs.putInt(ContentResolver.QUERY_ARG_LIMIT, 3);
- queryArgs.putInt(TestPagingContentProvider.RECORDSET_SIZE, 100);
-
- mCursor = mContentResolver.query(
- TestPagingContentProvider.UNPAGED_DATA_URI, null, queryArgs, null);
-
- Bundle extras = mCursor.getExtras();
- extras = extras != null ? extras : Bundle.EMPTY;
-
- assertEquals(3, mCursor.getCount());
- assertTrue(extras.getBoolean(PageViewCursor.EXTRA_AUTO_PAGED));
- assertTrue(extras.containsKey(ContentResolver.EXTRA_TOTAL_SIZE));
- assertEquals(100, extras.getInt(ContentResolver.EXTRA_TOTAL_SIZE));
-
- int col = mCursor.getColumnIndexOrThrow(TestPagingContentProvider.COLUMN_POS);
-
- mCursor.moveToNext();
- assertEquals(10, mCursor.getInt(col));
- mCursor.moveToNext();
- assertEquals(11, mCursor.getInt(col));
- mCursor.moveToNext();
- assertEquals(12, mCursor.getInt(col));
-
- assertFalse(mCursor.moveToNext());
-
- mCursor.close();
- }
-
- /**
- * Verifies that auto-paging isn't applied when the underlying remote
- * provider has already applied paging.
- */
- public void testQuery_OutOfProcessProvider_NoAutoPagingForAlreadyPagedResults() {
-
- Bundle queryArgs = new Bundle();
- queryArgs.putInt(ContentResolver.QUERY_ARG_OFFSET, 20);
- queryArgs.putInt(ContentResolver.QUERY_ARG_LIMIT, 2);
- queryArgs.putInt(TestPagingContentProvider.RECORDSET_SIZE, 500);
-
- mCursor = mContentResolver.query(
TestPagingContentProvider.PAGED_DATA_URI, null, queryArgs, null);
Bundle extras = mCursor.getExtras();
extras = extras != null ? extras : Bundle.EMPTY;
- assertFalse(extras.getBoolean(PageViewCursor.EXTRA_AUTO_PAGED));
+ assertEquals(3, mCursor.getCount());
+ assertTrue(extras.containsKey(ContentResolver.EXTRA_TOTAL_SIZE));
+ assertEquals(100, extras.getInt(ContentResolver.EXTRA_TOTAL_SIZE));
- // we don't test the contents of the self-paged cursor
- // because that's provided by TestPagingContentProvider
- // a test-only test support class.
+ String[] honoredArgs = extras.getStringArray(ContentResolver.EXTRA_HONORED_ARGS);
+ assertNotNull(honoredArgs);
+ assertTrue(ArrayUtils.contains(honoredArgs, ContentResolver.QUERY_ARG_OFFSET));
+ assertTrue(ArrayUtils.contains(honoredArgs, ContentResolver.QUERY_ARG_LIMIT));
+
+ int col = mCursor.getColumnIndexOrThrow(TestPagingContentProvider.COLUMN_POS);
+
+ mCursor.moveToNext();
+ assertEquals(10, mCursor.getInt(col));
+ mCursor.moveToNext();
+ assertEquals(11, mCursor.getInt(col));
+ mCursor.moveToNext();
+ assertEquals(12, mCursor.getInt(col));
+
+ assertFalse(mCursor.moveToNext());
mCursor.close();
}
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/ShapeDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/ShapeDrawableTest.java
index 80d604e..d563102 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/ShapeDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/ShapeDrawableTest.java
@@ -36,6 +36,7 @@
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff.Mode;
+import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.Shader;
import android.graphics.cts.R;
@@ -219,6 +220,18 @@
assertNull(shapeDrawable.getShaderFactory());
}
+ @Test
+ public void testSetXfermode() {
+ ShapeDrawable shapeDrawable = new ShapeDrawable();
+
+ PorterDuffXfermode xfermode = new PorterDuffXfermode(Mode.SRC_OVER);
+ shapeDrawable.setXfermode(xfermode);
+ assertSame(xfermode, shapeDrawable.getPaint().getXfermode());
+
+ shapeDrawable.setXfermode(null);
+ assertNull(shapeDrawable.getPaint().getXfermode());
+ }
+
public static class MockShaderFactory extends ShaderFactory {
public Shader resize(int width, int height) {
return null;
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java
index f01b833..b7f7c8e 100644
--- a/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java
@@ -109,6 +109,7 @@
.compile("([0-9]{4})-([0-9]{2})-[0-9]{2}");
private static final int KM_ERROR_INVALID_INPUT_LENGTH = -21;
+ private static final int KM_ERROR_PERMISSION_DENIED = 6;
public void testVersionParser() throws Exception {
// Non-numerics/empty give version 0
@@ -211,6 +212,29 @@
}
}
+ public void testEcAttestation_KeyStoreExceptionWhenRequestingUniqueId() throws Exception {
+ String keystoreAlias = "test_key";
+ KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(keystoreAlias, PURPOSE_SIGN)
+ .setAlgorithmParameterSpec(new ECGenParameterSpec("secp256r1"))
+ .setDigests(DIGEST_NONE, DIGEST_SHA256, DIGEST_SHA512)
+ .setAttestationChallenge(new byte[128])
+ .setUniqueIdIncluded(true)
+ .build();
+
+ try {
+ generateKeyPair(KEY_ALGORITHM_EC, spec);
+ fail("Attestation should have failed.");
+ } catch (ProviderException e) {
+ // Attestation is expected to fail because of lack of permissions.
+ KeyStoreException cause = (KeyStoreException) e.getCause();
+ assertEquals(KM_ERROR_PERMISSION_DENIED, cause.getErrorCode());
+ } finally {
+ KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+ keyStore.load(null);
+ keyStore.deleteEntry(keystoreAlias);
+ }
+ }
+
public void testRsaAttestation() throws Exception {
int[] keySizes = { // Smallish sizes to keep test runtimes down.
512, 768, 1024
diff --git a/tests/tests/nativemedia/aaudio/Android.mk b/tests/tests/nativemedia/aaudio/Android.mk
index af46aee..d8cfcf3 100644
--- a/tests/tests/nativemedia/aaudio/Android.mk
+++ b/tests/tests/nativemedia/aaudio/Android.mk
@@ -27,7 +27,8 @@
frameworks/av/media/libaaudio/include
LOCAL_SRC_FILES := \
- src/test_aaudio.cpp
+ src/test_aaudio.cpp \
+ src/test_aaudio_callback.cpp
LOCAL_SHARED_LIBRARIES := \
libaaudio \
diff --git a/tests/tests/nativemedia/aaudio/src/test_aaudio.cpp b/tests/tests/nativemedia/aaudio/src/test_aaudio.cpp
index 77c91e4..4072fce 100644
--- a/tests/tests/nativemedia/aaudio/src/test_aaudio.cpp
+++ b/tests/tests/nativemedia/aaudio/src/test_aaudio.cpp
@@ -21,17 +21,9 @@
#include <utils/Log.h>
#include <aaudio/AAudio.h>
-#include <aaudio/AAudioDefinitions.h>
+#include "test_aaudio.h"
-
-#define NANOS_PER_MICROSECOND ((int64_t)1000)
-#define NANOS_PER_MILLISECOND (NANOS_PER_MICROSECOND * 1000)
-#define MILLIS_PER_SECOND 1000
-#define NANOS_PER_SECOND (NANOS_PER_MILLISECOND * MILLIS_PER_SECOND)
-
-#define DEFAULT_STATE_TIMEOUT (500 * NANOS_PER_MILLISECOND)
-
-static int64_t getNanoseconds(clockid_t clockId = CLOCK_MONOTONIC) {
+int64_t getNanoseconds(clockid_t clockId) {
struct timespec time;
int result = clock_gettime(clockId, &time);
if (result < 0) {
@@ -136,10 +128,12 @@
// Check to see what kind of stream we actually got.
actualSampleRate = AAudioStream_getSampleRate(aaudioStream);
- ASSERT_TRUE(actualSampleRate >= 44100 && actualSampleRate <= 96000); // TODO what is range?
+ ASSERT_GE(actualSampleRate, 44100);
+ ASSERT_LE(actualSampleRate, 96000); // TODO what is min/max?
actualSamplesPerFrame = AAudioStream_getSamplesPerFrame(aaudioStream);
- ASSERT_TRUE(actualSamplesPerFrame >= 1 && actualSamplesPerFrame <= 16); // TODO what is max?
+ ASSERT_GE(actualSamplesPerFrame, 1);
+ ASSERT_LE(actualSamplesPerFrame, 16); // TODO what is min/max?
actualSharingMode = AAudioStream_getSharingMode(aaudioStream);
ASSERT_TRUE(actualSharingMode == AAUDIO_SHARING_MODE_EXCLUSIVE
@@ -151,7 +145,8 @@
// ASSERT_NE(AAUDIO_DEVICE_UNSPECIFIED, AAudioStream_getDeviceId(aaudioStream));
framesPerBurst = AAudioStream_getFramesPerBurst(aaudioStream);
- ASSERT_TRUE(framesPerBurst >= 16 && framesPerBurst <= 1024); // TODO what is min/max?
+ ASSERT_GE(framesPerBurst, 16);
+ ASSERT_LE(framesPerBurst, 4096); // TODO what is min/max?
// Allocate a buffer for the audio data.
// TODO handle possibility of other data formats
@@ -270,10 +265,13 @@
aaudioFramesRead = AAudioStream_getFramesRead(aaudioStream);
EXPECT_EQ(aaudioFramesRead, aaudioFramesWritten);
+ sleep(1); // FIXME - The write returns 0 if we remove this sleep! Why?
+
// The buffer should be empty after a flush so we should be able to write.
framesWritten = AAudioStream_write(aaudioStream, data, framesPerBurst, timeoutNanos);
// There should be some room for priming the buffer.
- ASSERT_TRUE(framesWritten > 0 && framesWritten <= framesPerBurst);
+ ASSERT_GT(framesWritten, 0);
+ ASSERT_LE(framesWritten, framesPerBurst);
EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream));
free(data);
@@ -291,60 +289,6 @@
}
*/
-#define AAUDIO_THREAD_ANSWER 1826375
-#define AAUDIO_THREAD_DURATION_MSEC 500
-
-static void *TestAAudioStreamThreadProc(void *arg) {
- AAudioStream* aaudioStream = (AAudioStream*) reinterpret_cast<size_t>(arg);
- aaudio_stream_state_t state;
-
- // Use this to sleep by waiting for something that won't happen.
- state = AAudioStream_getState(aaudioStream);
- AAudioStream_waitForStateChange(aaudioStream, AAUDIO_STREAM_STATE_PAUSED, &state,
- AAUDIO_THREAD_DURATION_MSEC * NANOS_PER_MILLISECOND);
- return reinterpret_cast<void *>(AAUDIO_THREAD_ANSWER);
-}
-
-// Test creating a stream related thread.
-TEST(test_aaudio, aaudio_stream_thread_basic) {
- AAudioStreamBuilder *aaudioBuilder = nullptr;
- AAudioStream *aaudioStream = nullptr;
- aaudio_result_t result = AAUDIO_OK;
- void *threadResult;
-
- // Use an AAudioStreamBuilder to define the stream.
- result = AAudio_createStreamBuilder(&aaudioBuilder);
- ASSERT_EQ(AAUDIO_OK, result);
-
- // Create an AAudioStream using the Builder.
- ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
-
- // Start a thread.
- ASSERT_EQ(AAUDIO_OK, AAudioStream_createThread(aaudioStream,
- 10 * NANOS_PER_MILLISECOND,
- TestAAudioStreamThreadProc,
- reinterpret_cast<void *>(aaudioStream)));
- // Thread already started.
- ASSERT_NE(AAUDIO_OK, AAudioStream_createThread(aaudioStream, // should fail!
- 10 * NANOS_PER_MILLISECOND,
- TestAAudioStreamThreadProc,
- reinterpret_cast<void *>(aaudioStream)));
-
- // Wait for the thread to finish.
- ASSERT_EQ(AAUDIO_OK, AAudioStream_joinThread(aaudioStream,
- &threadResult, 2 * AAUDIO_THREAD_DURATION_MSEC * NANOS_PER_MILLISECOND));
- // The thread returns a special answer.
- ASSERT_EQ(AAUDIO_THREAD_ANSWER, (int)reinterpret_cast<size_t>(threadResult));
-
- // Thread should already be joined.
- ASSERT_NE(AAUDIO_OK, AAudioStream_joinThread(aaudioStream, // should fail!
- &threadResult, 2 * AAUDIO_THREAD_DURATION_MSEC * NANOS_PER_MILLISECOND));
-
- // Cleanup
- EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_delete(aaudioBuilder));
- EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream));
-}
-
int main(int argc, char **argv) {
testing::InitGoogleTest(&argc, argv);
diff --git a/tests/tests/nativemedia/aaudio/src/test_aaudio.h b/tests/tests/nativemedia/aaudio/src/test_aaudio.h
new file mode 100644
index 0000000..dbb111d
--- /dev/null
+++ b/tests/tests/nativemedia/aaudio/src/test_aaudio.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2017 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.
+ */
+
+#ifndef CTS_MEDIA_TEST_AAUDIO_H
+#define CTS_MEDIA_TEST_AAUDIO_H
+
+#define NANOS_PER_MICROSECOND ((int64_t)1000)
+#define NANOS_PER_MILLISECOND (NANOS_PER_MICROSECOND * 1000)
+#define MILLIS_PER_SECOND 1000
+#define NANOS_PER_SECOND (NANOS_PER_MILLISECOND * MILLIS_PER_SECOND)
+
+#define DEFAULT_STATE_TIMEOUT (500 * NANOS_PER_MILLISECOND)
+
+int64_t getNanoseconds(clockid_t clockId = CLOCK_MONOTONIC);
+
+#endif //CTS_MEDIA_TEST_AAUDIO_H
diff --git a/tests/tests/nativemedia/aaudio/src/test_aaudio_callback.cpp b/tests/tests/nativemedia/aaudio/src/test_aaudio_callback.cpp
new file mode 100644
index 0000000..2ec1e1c
--- /dev/null
+++ b/tests/tests/nativemedia/aaudio/src/test_aaudio_callback.cpp
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2017 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.
+ */
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "AAudioTest"
+
+#include <gtest/gtest.h>
+#include <utils/Log.h>
+
+#include <aaudio/AAudio.h>
+#include "test_aaudio.h"
+
+typedef struct AAudioCallbackTestData {
+ int32_t callbackCount;
+ int32_t expectedFramesPerCallback;
+ int32_t actualFramesPerCallback;
+} AAudioCallbackTestData;
+
+// Callback function that fills the audio output buffer.
+static aaudio_data_callback_result_t MyDataCallbackProc(
+ AAudioStream *stream,
+ void *userData,
+ void *audioData,
+ int32_t numFrames
+) {
+ AAudioCallbackTestData *myData = (AAudioCallbackTestData *) userData;
+
+ if (numFrames != myData->expectedFramesPerCallback) {
+ // record unexpected framecounts
+ myData->actualFramesPerCallback = numFrames;
+ } else if (myData->actualFramesPerCallback == 0) {
+ // record at least one frame count
+ myData->actualFramesPerCallback = numFrames;
+ }
+ int32_t samplesPerFrame = AAudioStream_getSamplesPerFrame(stream);
+ int32_t numSamples = samplesPerFrame * numFrames;
+ if (AAudioStream_getFormat(stream) == AAUDIO_FORMAT_PCM_I16) {
+ int16_t *shortData = (int16_t *) audioData;
+ for (int i = 0; i < numSamples; i++) *shortData++ = 0;
+ } else if (AAudioStream_getFormat(stream) == AAUDIO_FORMAT_PCM_FLOAT) {
+ float *floatData = (float *) audioData;
+ for (int i = 0; i < numSamples; i++) *floatData++ = 0.0f;
+ }
+ myData->callbackCount++;
+ return AAUDIO_CALLBACK_RESULT_CONTINUE;
+}
+
+// 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 };
+ const int32_t requestedSampleRate = 48000;
+ const int32_t requestedSamplesPerFrame = 2;
+ const aaudio_audio_format_t requestedDataFormat = AAUDIO_FORMAT_PCM_I16;
+
+ int32_t actualSampleRate = -1;
+ int32_t actualSamplesPerFrame = -1;
+ aaudio_audio_format_t actualDataFormat = AAUDIO_FORMAT_INVALID;
+ aaudio_sharing_mode_t actualSharingMode;
+ int32_t framesPerBurst = -1;
+ int32_t actualBufferSize = 0;
+ int32_t actualFramesPerDataCallback = 0;
+
+ aaudio_stream_state_t state = AAUDIO_STREAM_STATE_UNINITIALIZED;
+ AAudioStreamBuilder *builder = nullptr;
+ AAudioStream *stream = nullptr;
+
+ aaudio_result_t result = AAUDIO_OK;
+
+ // Use an AAudioStreamBuilder to define the stream.
+ result = AAudio_createStreamBuilder(&builder);
+ ASSERT_EQ(AAUDIO_OK, result);
+
+ // Request stream properties.
+ AAudioStreamBuilder_setDeviceId(builder, AAUDIO_DEVICE_UNSPECIFIED);
+ AAudioStreamBuilder_setDirection(builder, AAUDIO_DIRECTION_OUTPUT);
+ AAudioStreamBuilder_setSampleRate(builder, requestedSampleRate);
+ AAudioStreamBuilder_setSamplesPerFrame(builder, requestedSamplesPerFrame);
+ AAudioStreamBuilder_setFormat(builder, requestedDataFormat);
+ AAudioStreamBuilder_setSharingMode(builder, requestedSharingMode);
+ AAudioStreamBuilder_setBufferCapacityInFrames(builder, 2000);
+
+ AAudioStreamBuilder_setDataCallback(builder, MyDataCallbackProc, &myTestData);
+ if (framesPerDataCallback != AAUDIO_UNSPECIFIED) {
+ AAudioStreamBuilder_setFramesPerDataCallback(builder, framesPerDataCallback);
+ }
+
+ // Create an AAudioStream using the Builder.
+ ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(builder, &stream));
+ EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_delete(builder));
+
+ EXPECT_EQ(AAUDIO_STREAM_STATE_OPEN, AAudioStream_getState(stream));
+ EXPECT_EQ(AAUDIO_DIRECTION_OUTPUT, AAudioStream_getDirection(stream));
+
+ // Check to see what kind of stream we actually got.
+ actualSampleRate = AAudioStream_getSampleRate(stream);
+ ASSERT_TRUE(actualSampleRate >= 44100 && actualSampleRate <= 96000); // TODO what is range?
+
+ actualSamplesPerFrame = AAudioStream_getSamplesPerFrame(stream);
+ ASSERT_TRUE(actualSamplesPerFrame >= 1 && actualSamplesPerFrame <= 16); // TODO what is max?
+
+ actualSharingMode = AAudioStream_getSharingMode(stream);
+ ASSERT_TRUE(actualSharingMode == AAUDIO_SHARING_MODE_EXCLUSIVE
+ || actualSharingMode == AAUDIO_SHARING_MODE_SHARED);
+
+ actualDataFormat = AAudioStream_getFormat(stream);
+
+ // TODO test this on full build
+ // ASSERT_NE(AAUDIO_DEVICE_UNSPECIFIED, AAudioStream_getDeviceId(stream));
+
+ framesPerBurst = AAudioStream_getFramesPerBurst(stream);
+ ASSERT_TRUE(framesPerBurst >= 16 && framesPerBurst <= 1024); // TODO what is min/max?
+
+ actualFramesPerDataCallback = AAudioStream_getFramesPerDataCallback(stream);
+ if (framesPerDataCallback != AAUDIO_UNSPECIFIED) {
+ ASSERT_EQ(framesPerDataCallback, actualFramesPerDataCallback);
+ }
+
+ actualBufferSize = AAudioStream_getBufferSizeInFrames(stream);
+ actualBufferSize = AAudioStream_setBufferSizeInFrames(stream, actualBufferSize);
+ ASSERT_TRUE(actualBufferSize > 0);
+
+ // 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.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);
+
+ // For more coverage, alternate pausing and stopping.
+ if ((loopIndex & 1) == 0) {
+ // Request async pause and wait for server to say that it has completed the request.
+ ASSERT_EQ(AAUDIO_OK, AAudioStream_requestPause(stream));
+ EXPECT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(stream,
+ AAUDIO_STREAM_STATE_PAUSING,
+ &state,
+ DEFAULT_STATE_TIMEOUT));
+ EXPECT_EQ(AAUDIO_STREAM_STATE_PAUSED, state);
+ } else {
+ // Request async stop and wait for server to say that it has completed the request.
+ ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStop(stream));
+ EXPECT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(stream,
+ AAUDIO_STREAM_STATE_STOPPING,
+ &state,
+ DEFAULT_STATE_TIMEOUT));
+ EXPECT_EQ(AAUDIO_STREAM_STATE_STOPPED, state);
+ }
+
+ int32_t oldCallbackCount = myTestData.callbackCount;
+ EXPECT_GT(oldCallbackCount, 10);
+ sleep(1);
+ EXPECT_EQ(oldCallbackCount, myTestData.callbackCount); // expect not advancing
+
+ if (framesPerDataCallback != AAUDIO_UNSPECIFIED) {
+ ASSERT_EQ(framesPerDataCallback, myTestData.actualFramesPerCallback);
+ }
+ }
+
+ 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);
+}
+
+TEST(test_aaudio, aaudio_callback_shared_109) {
+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
+}
diff --git a/tests/tests/widget/src/android/widget/cts/TextViewTest.java b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
index 4ff3e5e..e66640a 100644
--- a/tests/tests/widget/src/android/widget/cts/TextViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
@@ -4546,7 +4546,7 @@
| InputType.TYPE_NUMBER_FLAG_DECIMAL
| InputType.TYPE_NUMBER_FLAG_SIGNED, mTextView.getInputType());
assertSame(mTextView.getKeyListener(),
- DigitsKeyListener.getInstance(mTextView.getTextLocale(), true, true));
+ DigitsKeyListener.getInstance(null, true, true));
mTextView.setInputType(InputType.TYPE_CLASS_PHONE);
assertEquals(InputType.TYPE_CLASS_PHONE, mTextView.getInputType());
@@ -4762,6 +4762,59 @@
@UiThreadTest
@Test
+ public void testSetImeHintLocalesChangesInputType() {
+ final TextView textView = new TextView(mActivity);
+ textView.setText("", BufferType.EDITABLE);
+
+ textView.setInputType(InputType.TYPE_CLASS_NUMBER);
+ assertEquals(InputType.TYPE_CLASS_NUMBER, textView.getInputType());
+
+ final LocaleList localeList = LocaleList.forLanguageTags("fa-IR");
+ textView.setImeHintLocales(localeList);
+ final int textType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL;
+ // Setting IME hint locales to Persian must change the input type to a full text IME,
+ // since the typical number input IME may not have localized digits.
+ assertEquals(textType, textView.getInputType());
+
+ // Changing the input type to datetime should keep the full text IME, since the IME hint
+ // is still set to Persian, which needs advanced input.
+ final int dateType = InputType.TYPE_CLASS_DATETIME | InputType.TYPE_DATETIME_VARIATION_DATE;
+ textView.setInputType(dateType);
+ assertEquals(textType, textView.getInputType());
+
+ // Changing the input type to number password should keep the full text IME, since the IME
+ // hint is still set to Persian, which needs advanced input. But it also needs to set the
+ // text password flag.
+ final int numberPasswordType = InputType.TYPE_CLASS_NUMBER
+ | InputType.TYPE_NUMBER_VARIATION_PASSWORD;
+ final int textPasswordType = InputType.TYPE_CLASS_TEXT
+ | InputType.TYPE_TEXT_VARIATION_PASSWORD;
+ textView.setInputType(numberPasswordType);
+ assertEquals(textPasswordType, textView.getInputType());
+
+ // Setting the IME hint locales to null should reset the type to number password, since we
+ // no longer need internationalized input.
+ textView.setImeHintLocales(null);
+ assertEquals(numberPasswordType, textView.getInputType());
+ }
+
+ @UiThreadTest
+ @Test
+ public void testSetImeHintLocalesDoesntLoseInputType() {
+ final TextView textView = new TextView(mActivity);
+ textView.setText("", BufferType.EDITABLE);
+ final int inputType = InputType.TYPE_CLASS_TEXT
+ | InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT
+ | InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
+ | InputType.TYPE_TEXT_FLAG_MULTI_LINE
+ | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS;
+ textView.setInputType(inputType);
+ textView.setImeHintLocales(new LocaleList(Locale.US));
+ assertEquals(inputType, textView.getInputType());
+ }
+
+ @UiThreadTest
+ @Test
public void testSetExtractedText() {
mTextView = findTextView(R.id.textview_text);
assertEquals(mActivity.getResources().getString(R.string.text_view_hello),