From 256d907060c0080d3404125edf01daecd97d71c0 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Tue, 5 Dec 2023 11:28:28 -0700 Subject: Support more internal utils under Ravenwood. Tests for these internal utils are local within the frameworks/base/ repo, instead of in CTS. To help future-proof, bring the entire utils/* test directory by default into the Ravenwood suites, and give developers the way to easily opt-out with @IgnoreUnderRavenwood at the class level. Bug: 292141694 Test: atest FrameworksCoreTestsRavenwood FrameworksCoreTests Test: atest FrameworksUtilTestsRavenwood FrameworksUtilTests Change-Id: I5251dca752396faa77774659d0923d8cdb719830 --- core/java/android/util/DumpableContainer.java | 1 + core/java/com/android/internal/os/SomeArgs.java | 1 + core/java/com/android/internal/util/BitUtils.java | 1 + .../android/internal/util/BitwiseInputStream.java | 1 + .../android/internal/util/BitwiseOutputStream.java | 1 + .../android/internal/util/CallbackRegistry.java | 1 + core/java/com/android/internal/util/DumpUtils.java | 7 + core/java/com/android/internal/util/FastMath.java | 1 + .../com/android/internal/util/FastPrintWriter.java | 1 + .../android/internal/util/GrowingArrayUtils.java | 1 + .../android/internal/util/HeavyHitterSketch.java | 1 + .../internal/util/LineBreakBufferedWriter.java | 1 + .../com/android/internal/util/ObjectUtils.java | 1 + .../java/com/android/internal/util/Parcelling.java | 1 + .../java/com/android/internal/util/ParseUtils.java | 1 + .../com/android/internal/util/ProcFileReader.java | 1 + .../android/internal/util/ProgressReporter.java | 4 +- .../com/android/internal/util/QuickSelect.java | 1 + .../java/com/android/internal/util/RingBuffer.java | 1 + .../java/com/android/internal/util/StringPool.java | 1 + .../internal/util/dump/DumpableContainerImpl.java | 1 + core/java/com/google/android/collect/Lists.java | 1 + core/java/com/google/android/collect/Maps.java | 1 + core/java/com/google/android/collect/Sets.java | 1 + core/tests/coretests/Android.bp | 3 + .../com/android/internal/util/BitUtilsTest.java | 2 +- .../internal/util/ContrastColorUtilTest.java | 34 +-- .../com/android/internal/util/DumpUtilsTest.java | 26 ++- .../internal/util/DumpableContainerImplTest.java | 20 +- .../internal/util/FakeLatencyTrackerTest.java | 8 +- .../com/android/internal/util/FastDataTest.java | 12 +- .../com/android/internal/util/FastMathTest.java | 34 +++ .../internal/util/GrowingArrayUtilsTest.java | 140 ++++++++++++ .../src/com/android/internal/util/HexDumpTest.java | 22 +- .../android/internal/util/LatencyTrackerTest.java | 8 +- .../internal/util/LineBreakBufferedWriterTest.java | 28 ++- .../com/android/internal/util/ParseUtilsTest.java | 36 +++- .../internal/util/ProgressReporterTest.java | 28 ++- .../com/android/internal/util/RingBufferTest.java | 2 +- .../com/android/internal/util/TokenBucketTest.java | 19 +- core/tests/utiltests/Android.bp | 17 +- .../src/android/util/MemoryIntArrayTest.java | 17 +- .../src/android/util/MetadataReaderTest.java | 16 +- .../SystemConfigFileCommitEventLoggerTest.java | 12 +- .../com/android/internal/util/ArrayUtilsTest.java | 49 ++++- .../android/internal/util/BitwiseStreamsTest.java | 23 +- .../internal/util/CallbackRegistryTest.java | 26 ++- .../android/internal/util/CharSequencesTest.java | 20 +- .../internal/util/FastXmlSerializerTest.java | 25 ++- .../com/android/internal/util/FileRotatorTest.java | 47 ++-- .../internal/util/HeavyHitterSketchTest.java | 15 +- .../util/InlinePresentationStyleUtilsTest.java | 8 + .../internal/util/LockPatternUtilsTest.java | 6 + .../android/internal/util/MessageUtilsTest.java | 6 +- .../android/internal/util/MimeIconUtilsTest.java | 19 +- .../com/android/internal/util/ObjectUtilsTest.java | 13 +- .../util/ObservableServiceConnectionTest.java | 10 + .../util/PersistentServiceConnectionTest.java | 11 + .../android/internal/util/ProcFileReaderTest.java | 28 ++- .../com/android/internal/util/QuickSelectTest.java | 11 +- .../com/android/internal/util/StringPoolTest.java | 16 +- .../android/internal/util/WakeupMessageTest.java | 19 +- .../com/android/internal/util/XmlUtilsTest.java | 11 +- .../util/test/FakeSettingsProviderTest.java | 32 +-- .../framework-minus-apex-ravenwood-policies.txt | 12 +- .../test/annotations/IgnoreUnderRavenwood.java | 2 +- .../platform/test/ravenwood/RavenwoodRule.java | 5 +- ravenwood/ravenwood-annotation-allowed-classes.txt | 28 +++ .../libcore-fake/libcore/util/HexEncoding.java | 240 +++++++++++++++++++++ 69 files changed, 1043 insertions(+), 156 deletions(-) create mode 100644 core/tests/coretests/src/com/android/internal/util/FastMathTest.java create mode 100644 core/tests/coretests/src/com/android/internal/util/GrowingArrayUtilsTest.java create mode 100644 tools/hoststubgen/hoststubgen/helper-framework-runtime-src/libcore-fake/libcore/util/HexEncoding.java diff --git a/core/java/android/util/DumpableContainer.java b/core/java/android/util/DumpableContainer.java index fef5acd42e4e..24640c974500 100644 --- a/core/java/android/util/DumpableContainer.java +++ b/core/java/android/util/DumpableContainer.java @@ -20,6 +20,7 @@ import android.annotation.NonNull; /** * Represents a container that manages {@link Dumpable dumpables}. */ +@android.ravenwood.annotation.RavenwoodKeepWholeClass public interface DumpableContainer { /** diff --git a/core/java/com/android/internal/os/SomeArgs.java b/core/java/com/android/internal/os/SomeArgs.java index b12df6ed36ca..4701af3f2ddc 100644 --- a/core/java/com/android/internal/os/SomeArgs.java +++ b/core/java/com/android/internal/os/SomeArgs.java @@ -26,6 +26,7 @@ import android.os.Build; * it is responsibility of the client to recycle and instance * once it is no longer used. */ +@android.ravenwood.annotation.RavenwoodKeepWholeClass public final class SomeArgs { private static final int MAX_POOL_SIZE = 10; diff --git a/core/java/com/android/internal/util/BitUtils.java b/core/java/com/android/internal/util/BitUtils.java index 154ea52bf9ba..d928bbc3e9ad 100644 --- a/core/java/com/android/internal/util/BitUtils.java +++ b/core/java/com/android/internal/util/BitUtils.java @@ -31,6 +31,7 @@ import java.util.function.IntFunction; * sugar methods for {@link ByteBuffer}. Useful for networking and packet manipulations. * {@hide} */ +@android.ravenwood.annotation.RavenwoodKeepWholeClass public final class BitUtils { private BitUtils() {} diff --git a/core/java/com/android/internal/util/BitwiseInputStream.java b/core/java/com/android/internal/util/BitwiseInputStream.java index ffae3ce89ce4..91f89f39fc4d 100644 --- a/core/java/com/android/internal/util/BitwiseInputStream.java +++ b/core/java/com/android/internal/util/BitwiseInputStream.java @@ -26,6 +26,7 @@ import android.compat.annotation.UnsupportedAppUsage; * * NOTE -- This class is not threadsafe. */ +@android.ravenwood.annotation.RavenwoodKeepWholeClass public class BitwiseInputStream { // The byte array being read from. diff --git a/core/java/com/android/internal/util/BitwiseOutputStream.java b/core/java/com/android/internal/util/BitwiseOutputStream.java index 9f4150860887..9b7568b54639 100644 --- a/core/java/com/android/internal/util/BitwiseOutputStream.java +++ b/core/java/com/android/internal/util/BitwiseOutputStream.java @@ -26,6 +26,7 @@ import android.compat.annotation.UnsupportedAppUsage; * * NOTE -- This class is not threadsafe. */ +@android.ravenwood.annotation.RavenwoodKeepWholeClass public class BitwiseOutputStream { // The byte array being written to, which will be grown as needed. diff --git a/core/java/com/android/internal/util/CallbackRegistry.java b/core/java/com/android/internal/util/CallbackRegistry.java index 0f228d4775fd..0ae8e1d1e0c4 100644 --- a/core/java/com/android/internal/util/CallbackRegistry.java +++ b/core/java/com/android/internal/util/CallbackRegistry.java @@ -39,6 +39,7 @@ import java.util.List; * @param The notification sender type. Typically this is the containing class. * @param Opaque argument used to pass additional data beyond an int. */ +@android.ravenwood.annotation.RavenwoodKeepWholeClass public class CallbackRegistry implements Cloneable { private static final String TAG = "CallbackRegistry"; diff --git a/core/java/com/android/internal/util/DumpUtils.java b/core/java/com/android/internal/util/DumpUtils.java index 8fe2b9cdf1e5..d1ff034ff001 100644 --- a/core/java/com/android/internal/util/DumpUtils.java +++ b/core/java/com/android/internal/util/DumpUtils.java @@ -37,6 +37,7 @@ import java.util.function.Predicate; * Test: atest FrameworksCoreTests:DumpUtilsTest */ +@android.ravenwood.annotation.RavenwoodKeepWholeClass public final class DumpUtils { /** @@ -92,6 +93,8 @@ public final class DumpUtils { * @return true if access should be granted. * @hide */ + @android.ravenwood.annotation.RavenwoodThrow( + blockedBy = android.permission.PermissionManager.class) public static boolean checkDumpPermission(Context context, String tag, PrintWriter pw) { if (context.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) != PackageManager.PERMISSION_GRANTED) { @@ -112,6 +115,8 @@ public final class DumpUtils { * @return true if access should be granted. * @hide */ + @android.ravenwood.annotation.RavenwoodThrow( + blockedBy = android.permission.PermissionManager.class) public static boolean checkUsageStatsPermission(Context context, String tag, PrintWriter pw) { // System internals always get access final int uid = Binder.getCallingUid(); @@ -166,6 +171,8 @@ public final class DumpUtils { * @return true if access should be granted. * @hide */ + @android.ravenwood.annotation.RavenwoodThrow( + blockedBy = android.permission.PermissionManager.class) public static boolean checkDumpAndUsageStatsPermission(Context context, String tag, PrintWriter pw) { return checkDumpPermission(context, tag, pw) && checkUsageStatsPermission(context, tag, pw); diff --git a/core/java/com/android/internal/util/FastMath.java b/core/java/com/android/internal/util/FastMath.java index b7dbee53a4be..6e8fef281445 100644 --- a/core/java/com/android/internal/util/FastMath.java +++ b/core/java/com/android/internal/util/FastMath.java @@ -21,6 +21,7 @@ import android.compat.annotation.UnsupportedAppUsage; /** * Fast and loose math routines. */ +@android.ravenwood.annotation.RavenwoodKeepWholeClass public class FastMath { /** diff --git a/core/java/com/android/internal/util/FastPrintWriter.java b/core/java/com/android/internal/util/FastPrintWriter.java index 63124def6d2f..fcd6df091c88 100644 --- a/core/java/com/android/internal/util/FastPrintWriter.java +++ b/core/java/com/android/internal/util/FastPrintWriter.java @@ -32,6 +32,7 @@ import java.nio.charset.CharsetEncoder; import java.nio.charset.CoderResult; import java.nio.charset.CodingErrorAction; +@android.ravenwood.annotation.RavenwoodKeepWholeClass public class FastPrintWriter extends PrintWriter { private static class DummyWriter extends Writer { @Override diff --git a/core/java/com/android/internal/util/GrowingArrayUtils.java b/core/java/com/android/internal/util/GrowingArrayUtils.java index 8c12e36a27d1..83d06d180179 100644 --- a/core/java/com/android/internal/util/GrowingArrayUtils.java +++ b/core/java/com/android/internal/util/GrowingArrayUtils.java @@ -29,6 +29,7 @@ import android.os.Build; * * @hide */ +@android.ravenwood.annotation.RavenwoodKeepWholeClass public final class GrowingArrayUtils { /** diff --git a/core/java/com/android/internal/util/HeavyHitterSketch.java b/core/java/com/android/internal/util/HeavyHitterSketch.java index e18acaf36797..2973d305f517 100644 --- a/core/java/com/android/internal/util/HeavyHitterSketch.java +++ b/core/java/com/android/internal/util/HeavyHitterSketch.java @@ -35,6 +35,7 @@ import java.util.List; *

* {@hide} */ +@android.ravenwood.annotation.RavenwoodKeepWholeClass public interface HeavyHitterSketch { /** * Return the default implementation. diff --git a/core/java/com/android/internal/util/LineBreakBufferedWriter.java b/core/java/com/android/internal/util/LineBreakBufferedWriter.java index 552a93f6666a..8393b229e011 100644 --- a/core/java/com/android/internal/util/LineBreakBufferedWriter.java +++ b/core/java/com/android/internal/util/LineBreakBufferedWriter.java @@ -27,6 +27,7 @@ import java.util.Arrays; * * Note: this class is not thread-safe. */ +@android.ravenwood.annotation.RavenwoodKeepWholeClass public class LineBreakBufferedWriter extends PrintWriter { /** diff --git a/core/java/com/android/internal/util/ObjectUtils.java b/core/java/com/android/internal/util/ObjectUtils.java index 0e7b93d406f5..292ee14911c5 100644 --- a/core/java/com/android/internal/util/ObjectUtils.java +++ b/core/java/com/android/internal/util/ObjectUtils.java @@ -22,6 +22,7 @@ import android.annotation.Nullable; import java.util.Objects; /** @hide */ +@android.ravenwood.annotation.RavenwoodKeepWholeClass public class ObjectUtils { private ObjectUtils() {} diff --git a/core/java/com/android/internal/util/Parcelling.java b/core/java/com/android/internal/util/Parcelling.java index 3147c34a7129..70c3869d8e23 100644 --- a/core/java/com/android/internal/util/Parcelling.java +++ b/core/java/com/android/internal/util/Parcelling.java @@ -38,6 +38,7 @@ import java.util.regex.Pattern; * * @param the type being [un]parcelled */ +@android.ravenwood.annotation.RavenwoodKeepWholeClass public interface Parcelling { /** diff --git a/core/java/com/android/internal/util/ParseUtils.java b/core/java/com/android/internal/util/ParseUtils.java index a591f4aa41fc..a16ce2b0570f 100644 --- a/core/java/com/android/internal/util/ParseUtils.java +++ b/core/java/com/android/internal/util/ParseUtils.java @@ -23,6 +23,7 @@ import android.annotation.Nullable; * Test: atest /android/pi-dev/frameworks/base/core/tests/coretests/src/com/android/internal/util/ParseUtilsTest.java */ +@android.ravenwood.annotation.RavenwoodKeepWholeClass public final class ParseUtils { private ParseUtils() { } diff --git a/core/java/com/android/internal/util/ProcFileReader.java b/core/java/com/android/internal/util/ProcFileReader.java index b726d5d75239..6cf241e65d00 100644 --- a/core/java/com/android/internal/util/ProcFileReader.java +++ b/core/java/com/android/internal/util/ProcFileReader.java @@ -32,6 +32,7 @@ import java.nio.charset.StandardCharsets; * Currently doesn't support formats based on {@code \0}, tabs. * Consecutive spaces are treated as a single delimiter. */ +@android.ravenwood.annotation.RavenwoodKeepWholeClass public class ProcFileReader implements Closeable { private final InputStream mStream; private final byte[] mBuffer; diff --git a/core/java/com/android/internal/util/ProgressReporter.java b/core/java/com/android/internal/util/ProgressReporter.java index 7a8efba8a637..5640d8f28330 100644 --- a/core/java/com/android/internal/util/ProgressReporter.java +++ b/core/java/com/android/internal/util/ProgressReporter.java @@ -25,6 +25,7 @@ import android.os.RemoteException; import android.util.MathUtils; import com.android.internal.annotations.GuardedBy; +import com.android.internal.annotations.VisibleForTesting; /** * Tracks and reports progress of a single task to a {@link IProgressListener}. @@ -175,7 +176,8 @@ public class ProgressReporter { } } - int getProgress() { + @VisibleForTesting + public int getProgress() { return mProgress; } diff --git a/core/java/com/android/internal/util/QuickSelect.java b/core/java/com/android/internal/util/QuickSelect.java index 17739c9c8832..052efede2fba 100644 --- a/core/java/com/android/internal/util/QuickSelect.java +++ b/core/java/com/android/internal/util/QuickSelect.java @@ -28,6 +28,7 @@ import java.util.List; * * @hide */ +@android.ravenwood.annotation.RavenwoodKeepWholeClass public final class QuickSelect { private static int selectImpl(@NonNull List list, int left, int right, int k, @NonNull Comparator comparator) { diff --git a/core/java/com/android/internal/util/RingBuffer.java b/core/java/com/android/internal/util/RingBuffer.java index 8fc4c30e54ab..04886598de35 100644 --- a/core/java/com/android/internal/util/RingBuffer.java +++ b/core/java/com/android/internal/util/RingBuffer.java @@ -27,6 +27,7 @@ import java.util.Arrays; * full, oldest events are dropped when new events are added. * {@hide} */ +@android.ravenwood.annotation.RavenwoodKeepWholeClass public class RingBuffer { // Array for storing events. diff --git a/core/java/com/android/internal/util/StringPool.java b/core/java/com/android/internal/util/StringPool.java index c5180a3fe8cf..94f6ec9677ec 100644 --- a/core/java/com/android/internal/util/StringPool.java +++ b/core/java/com/android/internal/util/StringPool.java @@ -23,6 +23,7 @@ package com.android.internal.util; * * @hide */ +@android.ravenwood.annotation.RavenwoodKeepWholeClass public final class StringPool { private final String[] mPool = new String[512]; diff --git a/core/java/com/android/internal/util/dump/DumpableContainerImpl.java b/core/java/com/android/internal/util/dump/DumpableContainerImpl.java index ccec6c61b92a..bb5224f65904 100644 --- a/core/java/com/android/internal/util/dump/DumpableContainerImpl.java +++ b/core/java/com/android/internal/util/dump/DumpableContainerImpl.java @@ -32,6 +32,7 @@ import java.util.Objects; * * @hide */ +@android.ravenwood.annotation.RavenwoodKeepWholeClass public final class DumpableContainerImpl implements DumpableContainer { private static final String TAG = DumpableContainerImpl.class.getSimpleName(); diff --git a/core/java/com/google/android/collect/Lists.java b/core/java/com/google/android/collect/Lists.java index 585847da566c..392b87e6bd04 100644 --- a/core/java/com/google/android/collect/Lists.java +++ b/core/java/com/google/android/collect/Lists.java @@ -25,6 +25,7 @@ import java.util.Collections; * Provides static methods for creating {@code List} instances easily, and other * utility methods for working with lists. */ +@android.ravenwood.annotation.RavenwoodKeepWholeClass public class Lists { /** diff --git a/core/java/com/google/android/collect/Maps.java b/core/java/com/google/android/collect/Maps.java index cd4c1280545e..6492b0350669 100644 --- a/core/java/com/google/android/collect/Maps.java +++ b/core/java/com/google/android/collect/Maps.java @@ -24,6 +24,7 @@ import java.util.HashMap; /** * Provides static methods for creating mutable {@code Maps} instances easily. */ +@android.ravenwood.annotation.RavenwoodKeepWholeClass public class Maps { /** * Creates a {@code HashMap} instance. diff --git a/core/java/com/google/android/collect/Sets.java b/core/java/com/google/android/collect/Sets.java index e2429157d529..76eaf21cae04 100644 --- a/core/java/com/google/android/collect/Sets.java +++ b/core/java/com/google/android/collect/Sets.java @@ -31,6 +31,7 @@ import java.util.TreeSet; * other static methods for working with Sets. * */ +@android.ravenwood.annotation.RavenwoodKeepWholeClass public class Sets { /** diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp index 37f592f5797b..21a406988104 100644 --- a/core/tests/coretests/Android.bp +++ b/core/tests/coretests/Android.bp @@ -168,11 +168,14 @@ android_library { android_ravenwood_test { name: "FrameworksCoreTestsRavenwood", static_libs: [ + "androidx.core_core", "androidx.annotation_annotation", "androidx.test.rules", ], srcs: [ "src/android/os/FileUtilsTest.java", + "src/com/android/internal/util/**/*.java", + "testdoubles/src/com/android/internal/util/**/*.java", ], auto_gen_config: true, } diff --git a/core/tests/coretests/src/com/android/internal/util/BitUtilsTest.java b/core/tests/coretests/src/com/android/internal/util/BitUtilsTest.java index fdba811f3eaa..fdde36ad8e35 100644 --- a/core/tests/coretests/src/com/android/internal/util/BitUtilsTest.java +++ b/core/tests/coretests/src/com/android/internal/util/BitUtilsTest.java @@ -30,8 +30,8 @@ import static com.android.internal.util.BitUtils.unpackBits; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/core/tests/coretests/src/com/android/internal/util/ContrastColorUtilTest.java b/core/tests/coretests/src/com/android/internal/util/ContrastColorUtilTest.java index 5f5bf1165004..e6ebfefd2aea 100644 --- a/core/tests/coretests/src/com/android/internal/util/ContrastColorUtilTest.java +++ b/core/tests/coretests/src/com/android/internal/util/ContrastColorUtilTest.java @@ -23,6 +23,8 @@ import static com.google.common.truth.Truth.assertThat; import android.content.Context; import android.content.res.ColorStateList; import android.graphics.Color; +import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.ravenwood.RavenwoodRule; import android.text.Spannable; import android.text.SpannableString; import android.text.SpannableStringBuilder; @@ -32,23 +34,21 @@ import android.text.style.TextAppearanceSpan; import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; import com.android.internal.R; -import junit.framework.TestCase; - -import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.runner.RunWith; -public class ContrastColorUtilTest extends TestCase { - - private Context mContext; - - @Before - public void setUp() { - mContext = InstrumentationRegistry.getContext(); - } +@RunWith(AndroidJUnit4.class) +@IgnoreUnderRavenwood(blockedBy = Color.class) +public class ContrastColorUtilTest { + @Rule + public final RavenwoodRule mRavenwood = new RavenwoodRule(); + @Test @SmallTest public void testEnsureTextContrastAgainstDark() { int darkBg = 0xFF35302A; @@ -70,6 +70,7 @@ public class ContrastColorUtilTest extends TestCase { assertContrastIsWithinRange(selfContrastColor, darkBg, 4.5, 4.75); } + @Test @SmallTest public void testEnsureTextContrastAgainstLight() { int lightBg = 0xFFFFF8F2; @@ -91,13 +92,16 @@ public class ContrastColorUtilTest extends TestCase { assertContrastIsWithinRange(selfContrastColor, lightBg, 4.5, 4.75); } + @Test public void testBuilder_ensureColorSpanContrast_removesAllFullLengthColorSpans() { + Context context = InstrumentationRegistry.getContext(); + Spannable text = new SpannableString("blue text with yellow and green"); text.setSpan(new ForegroundColorSpan(Color.YELLOW), 15, 21, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); text.setSpan(new ForegroundColorSpan(Color.BLUE), 0, text.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE); - TextAppearanceSpan taSpan = new TextAppearanceSpan(mContext, + TextAppearanceSpan taSpan = new TextAppearanceSpan(context, R.style.TextAppearance_DeviceDefault_Notification_Title); assertThat(taSpan.getTextColor()).isNotNull(); // it must be set to prove it is cleared. text.setSpan(taSpan, 0, text.length(), @@ -123,6 +127,7 @@ public class ContrastColorUtilTest extends TestCase { assertThat(((ForegroundColorSpan) spans[2]).getForegroundColor()).isEqualTo(Color.GREEN); } + @Test public void testBuilder_ensureColorSpanContrast_partialLength_adjusted() { int background = 0xFFFF0101; // Slightly lighter red CharSequence text = new SpannableStringBuilder() @@ -138,14 +143,17 @@ public class ContrastColorUtilTest extends TestCase { assertContrastIsWithinRange(foregroundColor, background, 3, 3.2); } + @Test public void testBuilder_ensureColorSpanContrast_worksWithComplexInput() { + Context context = InstrumentationRegistry.getContext(); + Spannable text = new SpannableString("blue text with yellow and green and cyan"); text.setSpan(new ForegroundColorSpan(Color.YELLOW), 15, 21, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); text.setSpan(new ForegroundColorSpan(Color.BLUE), 0, text.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE); // cyan TextAppearanceSpan - TextAppearanceSpan taSpan = new TextAppearanceSpan(mContext, + TextAppearanceSpan taSpan = new TextAppearanceSpan(context, R.style.TextAppearance_DeviceDefault_Notification_Title); taSpan = new TextAppearanceSpan(taSpan.getFamily(), taSpan.getTextStyle(), taSpan.getTextSize(), ColorStateList.valueOf(Color.CYAN), null); diff --git a/core/tests/coretests/src/com/android/internal/util/DumpUtilsTest.java b/core/tests/coretests/src/com/android/internal/util/DumpUtilsTest.java index 36c2a62ae6ed..d2d3c134f390 100644 --- a/core/tests/coretests/src/com/android/internal/util/DumpUtilsTest.java +++ b/core/tests/coretests/src/com/android/internal/util/DumpUtilsTest.java @@ -25,10 +25,16 @@ import static com.android.internal.util.DumpUtils.isPlatformPackage; import static com.google.common.truth.Truth.assertWithMessage; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + import android.content.ComponentName; import android.util.SparseArray; -import junit.framework.TestCase; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; import java.io.PrintWriter; import java.io.StringWriter; @@ -37,7 +43,8 @@ import java.io.StringWriter; * Run with: atest FrameworksCoreTests:DumpUtilsTest */ -public class DumpUtilsTest extends TestCase { +@RunWith(AndroidJUnit4.class) +public class DumpUtilsTest { private final StringWriter mStringWriter = new StringWriter(); private final PrintWriter mPrintWriter = new PrintWriter(mStringWriter); @@ -56,6 +63,7 @@ public class DumpUtilsTest extends TestCase { return () -> cn(componentName); } + @Test public void testIsPlatformPackage() { assertTrue(isPlatformPackage("android")); assertTrue(isPlatformPackage("android.abc")); @@ -79,6 +87,7 @@ public class DumpUtilsTest extends TestCase { assertFalse(isPlatformPackage(wcn("com.google.def/abc"))); } + @Test public void testIsNonPlatformPackage() { assertFalse(isNonPlatformPackage("android")); assertFalse(isNonPlatformPackage("android.abc")); @@ -102,6 +111,7 @@ public class DumpUtilsTest extends TestCase { assertTrue(isNonPlatformPackage(wcn("com.google.def/abc"))); } + @Test public void testIsPlatformCriticalPackage() { for (final ComponentName componentName : CRITICAL_SECTION_COMPONENTS) { assertTrue(isPlatformCriticalPackage(() -> componentName)); @@ -115,6 +125,7 @@ public class DumpUtilsTest extends TestCase { assertFalse(isPlatformCriticalPackage(null)); } + @Test public void testIsPlatformNonCriticalPackage() { for (final ComponentName componentName : CRITICAL_SECTION_COMPONENTS) { assertFalse(isPlatformNonCriticalPackage(() -> componentName)); @@ -128,6 +139,7 @@ public class DumpUtilsTest extends TestCase { assertFalse(isPlatformNonCriticalPackage(null)); } + @Test public void testFilterRecord() { assertFalse(filterRecord(null).test(wcn("com.google.p/abc"))); assertFalse(filterRecord(null).test(wcn("com.android.p/abc"))); @@ -178,6 +190,7 @@ public class DumpUtilsTest extends TestCase { wcn("com.google/.abc"))); } + @Test public void testDumpSparseArray_empty() { SparseArray array = new SparseArray<>(); @@ -188,6 +201,7 @@ public class DumpUtilsTest extends TestCase { assertWithMessage("empty array dump").that(output).isEqualTo("...No whatevers\n"); } + @Test public void testDumpSparseArray_oneElement() { SparseArray array = new SparseArray<>(); array.put(1, "uno"); @@ -201,6 +215,7 @@ public class DumpUtilsTest extends TestCase { + "..0: 1->uno\n"); } + @Test public void testDumpSparseArray_oneNullElement() { SparseArray array = new SparseArray<>(); array.put(1, null); @@ -214,6 +229,7 @@ public class DumpUtilsTest extends TestCase { + "..0: 1->(null)\n"); } + @Test public void testDumpSparseArray_multipleElements() { SparseArray array = new SparseArray<>(); array.put(1, "uno"); @@ -231,6 +247,7 @@ public class DumpUtilsTest extends TestCase { + "..2: 42->(null)\n"); } + @Test public void testDumpSparseArray_keyDumperOnly() { SparseArray array = new SparseArray<>(); array.put(1, "uno"); @@ -251,6 +268,7 @@ public class DumpUtilsTest extends TestCase { + "_2=42_(null)\n"); } + @Test public void testDumpSparseArray_valueDumperOnly() { SparseArray array = new SparseArray<>(); array.put(1, "uno"); @@ -272,6 +290,7 @@ public class DumpUtilsTest extends TestCase { + "..2: 42->(null)\n"); } + @Test public void testDumpSparseArray_keyAndValueDumpers() { SparseArray array = new SparseArray<>(); array.put(1, "uno"); @@ -295,6 +314,7 @@ public class DumpUtilsTest extends TestCase { + "_2=42_(null)\n"); } + @Test public void testDumpSparseArrayValues() { SparseArray array = new SparseArray<>(); array.put(1, "uno"); @@ -306,7 +326,7 @@ public class DumpUtilsTest extends TestCase { String output = flushPrintWriter(); assertWithMessage("dump of %s", array).that(output).isEqualTo("" - + ".3 numbers:\n" + + ".3 number(s):\n" + "..uno\n" + "..duo\n" + "..(null)\n"); diff --git a/core/tests/coretests/src/com/android/internal/util/DumpableContainerImplTest.java b/core/tests/coretests/src/com/android/internal/util/DumpableContainerImplTest.java index 589e4f98a32a..61d4e3da5036 100644 --- a/core/tests/coretests/src/com/android/internal/util/DumpableContainerImplTest.java +++ b/core/tests/coretests/src/com/android/internal/util/DumpableContainerImplTest.java @@ -17,30 +17,32 @@ package com.android.internal.util; import static com.google.common.truth.Truth.assertWithMessage; -import static org.testng.Assert.assertThrows; - import android.util.Dumpable; +import androidx.test.runner.AndroidJUnit4; + import com.android.internal.util.dump.DumpableContainerImpl; import org.junit.Test; +import org.junit.runner.RunWith; import java.io.PrintWriter; import java.io.StringWriter; import java.util.concurrent.atomic.AtomicReference; -public final class DumpableContainerImplTest { +@RunWith(AndroidJUnit4.class) +public class DumpableContainerImplTest { private final DumpableContainerImpl mImpl = new DumpableContainerImpl(); private final StringWriter mSw = new StringWriter(); private final PrintWriter mWriter = new PrintWriter(mSw); - @Test + @Test(expected = NullPointerException.class) public void testAddDumpable_null() { - assertThrows(NullPointerException.class, () -> mImpl.addDumpable(null)); + mImpl.addDumpable(null); } - @Test + @Test(expected = NullPointerException.class) public void testAddDumpable_dumpableWithoutName() { Dumpable namelessDumpable = new Dumpable() { @@ -55,7 +57,7 @@ public final class DumpableContainerImplTest { } }; - assertThrows(NullPointerException.class, () -> mImpl.addDumpable(namelessDumpable)); + mImpl.addDumpable(namelessDumpable); } @Test @@ -179,9 +181,9 @@ public final class DumpableContainerImplTest { + "......6 Args: 4,8,15,16,23,42,\n"); } - @Test + @Test(expected = NullPointerException.class) public void testRemoveDumpable_null() { - assertThrows(NullPointerException.class, () -> mImpl.removeDumpable(null)); + mImpl.removeDumpable(null); } @Test diff --git a/core/tests/coretests/src/com/android/internal/util/FakeLatencyTrackerTest.java b/core/tests/coretests/src/com/android/internal/util/FakeLatencyTrackerTest.java index 3946cdf76821..6bd67ea486d1 100644 --- a/core/tests/coretests/src/com/android/internal/util/FakeLatencyTrackerTest.java +++ b/core/tests/coretests/src/com/android/internal/util/FakeLatencyTrackerTest.java @@ -24,12 +24,15 @@ import static com.android.internal.util.LatencyTracker.ACTION_SHOW_VOICE_INTERAC import static com.google.common.truth.Truth.assertThat; +import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.ravenwood.RavenwoodRule; import android.provider.DeviceConfig; -import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.runner.AndroidJUnit4; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -42,7 +45,10 @@ import java.util.List; * {@link LatencyTrackerTest} */ @RunWith(AndroidJUnit4.class) +@IgnoreUnderRavenwood(blockedBy = DeviceConfig.class) public class FakeLatencyTrackerTest { + @Rule + public final RavenwoodRule mRavenwood = new RavenwoodRule(); private FakeLatencyTracker mFakeLatencyTracker; private int mInitialSyncDisabledMode; diff --git a/core/tests/coretests/src/com/android/internal/util/FastDataTest.java b/core/tests/coretests/src/com/android/internal/util/FastDataTest.java index de325ab7d186..316b95ac1b7d 100644 --- a/core/tests/coretests/src/com/android/internal/util/FastDataTest.java +++ b/core/tests/coretests/src/com/android/internal/util/FastDataTest.java @@ -21,6 +21,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import android.annotation.NonNull; +import android.platform.test.ravenwood.RavenwoodRule; import android.util.ExceptionUtils; import com.android.modules.utils.FastDataInput; @@ -29,6 +30,7 @@ import com.android.modules.utils.FastDataOutput; import libcore.util.HexEncoding; import org.junit.Assume; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -51,6 +53,9 @@ import java.util.function.Consumer; @RunWith(Parameterized.class) public class FastDataTest { + @Rule + public final RavenwoodRule mRavenwood = new RavenwoodRule(); + private final boolean use4ByteSequence; private static final String TEST_SHORT_STRING = "a"; @@ -59,7 +64,12 @@ public class FastDataTest { @Parameters(name = "use4ByteSequence={0}") public static Collection data() { - return Arrays.asList(new Object[][] { {true}, {false} }); + if (RavenwoodRule.isUnderRavenwood()) { + // TODO: 4-byte sequences are only supported on ART + return Arrays.asList(new Object[][]{{false}}); + } else { + return Arrays.asList(new Object[][]{{true}, {false}}); + } } public FastDataTest(boolean use4ByteSequence) { diff --git a/core/tests/coretests/src/com/android/internal/util/FastMathTest.java b/core/tests/coretests/src/com/android/internal/util/FastMathTest.java new file mode 100644 index 000000000000..dd263345022b --- /dev/null +++ b/core/tests/coretests/src/com/android/internal/util/FastMathTest.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2023 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.internal.util; + +import static org.junit.Assert.assertEquals; + +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class FastMathTest { + @Test + public void testRound() { + assertEquals(-1, FastMath.round(-1.0f)); + assertEquals(0, FastMath.round(0.0f)); + assertEquals(1, FastMath.round(1.0f)); + } +} diff --git a/core/tests/coretests/src/com/android/internal/util/GrowingArrayUtilsTest.java b/core/tests/coretests/src/com/android/internal/util/GrowingArrayUtilsTest.java new file mode 100644 index 000000000000..8456161f9709 --- /dev/null +++ b/core/tests/coretests/src/com/android/internal/util/GrowingArrayUtilsTest.java @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2023 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.internal.util; + +import static com.android.internal.util.GrowingArrayUtils.append; +import static com.android.internal.util.GrowingArrayUtils.insert; + +import static org.junit.Assert.assertArrayEquals; + +import android.util.EmptyArray; + +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.Arrays; + +@RunWith(AndroidJUnit4.class) +public class GrowingArrayUtilsTest { + private final Object TEST_OBJECT = new Object(); + + @Test + public void testAppend_Object() { + assertArrayEqualsPrefix(new Object[]{TEST_OBJECT}, + append(EmptyArray.OBJECT, 0, TEST_OBJECT)); + assertArrayEqualsPrefix(new Object[]{TEST_OBJECT, TEST_OBJECT}, + append(new Object[]{TEST_OBJECT}, 1, TEST_OBJECT)); + assertArrayEqualsPrefix(new Object[]{TEST_OBJECT}, + append(new Object[]{null, null}, 0, TEST_OBJECT)); + } + + @Test + public void testInsert_Object() { + assertArrayEqualsPrefix(new Object[]{TEST_OBJECT}, + insert(EmptyArray.OBJECT, 0, 0, TEST_OBJECT)); + assertArrayEqualsPrefix(new Object[]{null, TEST_OBJECT}, + insert(new Object[]{TEST_OBJECT}, 1, 0, null)); + assertArrayEqualsPrefix(new Object[]{TEST_OBJECT, null}, + insert(new Object[]{TEST_OBJECT}, 1, 1, null)); + assertArrayEqualsPrefix(new Object[]{TEST_OBJECT, null, TEST_OBJECT}, + insert(new Object[]{TEST_OBJECT, TEST_OBJECT}, 2, 1, null)); + } + + @Test + public void testAppend_Int() { + assertArrayEqualsPrefix(new int[]{42}, + append(EmptyArray.INT, 0, 42)); + assertArrayEqualsPrefix(new int[]{42, 42}, + append(new int[]{42}, 1, 42)); + assertArrayEqualsPrefix(new int[]{42}, + append(new int[]{0, 0}, 0, 42)); + } + + @Test + public void testInsert_Int() { + assertArrayEqualsPrefix(new int[]{42}, + insert(EmptyArray.INT, 0, 0, 42)); + assertArrayEqualsPrefix(new int[]{21, 42}, + insert(new int[]{42}, 1, 0, 21)); + assertArrayEqualsPrefix(new int[]{42, 21}, + insert(new int[]{42}, 1, 1, 21)); + assertArrayEqualsPrefix(new int[]{42, 21, 43}, + insert(new int[]{42, 43}, 2, 1, 21)); + } + + @Test + public void testAppend_Long() { + assertArrayEqualsPrefix(new long[]{42}, + append(EmptyArray.LONG, 0, 42)); + assertArrayEqualsPrefix(new long[]{42, 42}, + append(new long[]{42}, 1, 42)); + assertArrayEqualsPrefix(new long[]{42}, + append(new long[]{0, 0}, 0, 42)); + } + + @Test + public void testInsert_Long() { + assertArrayEqualsPrefix(new long[]{42}, + insert(EmptyArray.LONG, 0, 0, 42)); + assertArrayEqualsPrefix(new long[]{21, 42}, + insert(new long[]{42}, 1, 0, 21)); + assertArrayEqualsPrefix(new long[]{42, 21}, + insert(new long[]{42}, 1, 1, 21)); + assertArrayEqualsPrefix(new long[]{42, 21, 43}, + insert(new long[]{42, 43}, 2, 1, 21)); + } + + @Test + public void testAppend_Boolean() { + assertArrayEqualsPrefix(new boolean[]{true}, + append(EmptyArray.BOOLEAN, 0, true)); + assertArrayEqualsPrefix(new boolean[]{true, true}, + append(new boolean[]{true}, 1, true)); + assertArrayEqualsPrefix(new boolean[]{true}, + append(new boolean[]{false, false}, 0, true)); + } + + @Test + public void testInsert_Boolean() { + assertArrayEqualsPrefix(new boolean[]{true}, + insert(EmptyArray.BOOLEAN, 0, 0, true)); + assertArrayEqualsPrefix(new boolean[]{false, true}, + insert(new boolean[]{true}, 1, 0, false)); + assertArrayEqualsPrefix(new boolean[]{true, false}, + insert(new boolean[]{true}, 1, 1, false)); + assertArrayEqualsPrefix(new boolean[]{true, false, true}, + insert(new boolean[]{true, true}, 2, 1, false)); + } + + private void assertArrayEqualsPrefix(T[] expected, T[] actual) { + assertArrayEquals(expected, Arrays.copyOf(actual, expected.length)); + } + + private void assertArrayEqualsPrefix(int[] expected, int[] actual) { + assertArrayEquals(expected, Arrays.copyOf(actual, expected.length)); + } + + private void assertArrayEqualsPrefix(long[] expected, long[] actual) { + assertArrayEquals(expected, Arrays.copyOf(actual, expected.length)); + } + + private void assertArrayEqualsPrefix(boolean[] expected, boolean[] actual) { + assertArrayEquals(expected, Arrays.copyOf(actual, expected.length)); + } +} diff --git a/core/tests/coretests/src/com/android/internal/util/HexDumpTest.java b/core/tests/coretests/src/com/android/internal/util/HexDumpTest.java index f1cd89bf49f4..dcffa1cf6975 100644 --- a/core/tests/coretests/src/com/android/internal/util/HexDumpTest.java +++ b/core/tests/coretests/src/com/android/internal/util/HexDumpTest.java @@ -19,14 +19,22 @@ package com.android.internal.util; import static com.android.internal.util.HexDump.hexStringToByteArray; import static com.android.internal.util.HexDump.toHexString; -import junit.framework.TestCase; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; import java.io.PrintWriter; import java.io.StringWriter; import java.util.Arrays; import java.util.Random; -public final class HexDumpTest extends TestCase { +@RunWith(AndroidJUnit4.class) +public final class HexDumpTest { + @Test public void testBytesToHexString() { assertEquals("abcdef", HexDump.toHexString( new byte[] { (byte) 0xab, (byte) 0xcd, (byte) 0xef }, false)); @@ -34,12 +42,14 @@ public final class HexDumpTest extends TestCase { new byte[] { (byte) 0xab, (byte) 0xcd, (byte) 0xef }, true)); } + @Test public void testNullByteArray() { assertThrows( NullPointerException.class, () -> HexDump.toHexString(null)); } + @Test public void testBytesToHexString_allByteValues() { byte[] bytes = new byte[256]; for (int i = 0; i < bytes.length; i++) { @@ -57,6 +67,7 @@ public final class HexDumpTest extends TestCase { assertEquals(expected, HexDump.toHexString(bytes)); } + @Test public void testRoundTrip_fromBytes() { Random deterministicRandom = new Random(31337); // arbitrary but deterministic for (int length = 0; length < 100; length++) { @@ -68,6 +79,7 @@ public final class HexDumpTest extends TestCase { } } + @Test public void testRoundTrip_fromString() { String hexString = "0123456789ABCDEF72f9a3438934c378d34f32a8b932"; for (int length = 0; length < hexString.length(); length += 2) { @@ -77,6 +89,7 @@ public final class HexDumpTest extends TestCase { } } + @Test public void testToHexString_offsetLength() { byte[] bytes = new byte[32]; for (int i = 0; i < 16; i++) { @@ -97,6 +110,7 @@ public final class HexDumpTest extends TestCase { } } + @Test public void testToHexString_case() { byte[] bytes = new byte[32]; for (int i = 0; i < 16; i++) { @@ -113,16 +127,19 @@ public final class HexDumpTest extends TestCase { assertEquals(expected.toUpperCase(), toHexString(bytes)); } + @Test public void testHexStringToByteArray_empty() { assertBytesEqual(new byte[0], HexDump.hexStringToByteArray("")); } + @Test public void testHexStringToByteArray_null() { assertThrows( NullPointerException.class, () -> HexDump.hexStringToByteArray((String) null)); } + @Test public void testHexStringToByteArray_invalidCharacters() { // IllegalArgumentException would probably have been better than RuntimeException, but it // might be too late to change now. @@ -137,6 +154,7 @@ public final class HexDumpTest extends TestCase { () -> HexDump.hexStringToByteArray("abcdefgh")); } + @Test public void testHexStringToByteArray_oddLength() { // IllegalArgumentException would probably have been better than // StringIndexOutOfBoundsException, but it might be too late to change now. diff --git a/core/tests/coretests/src/com/android/internal/util/LatencyTrackerTest.java b/core/tests/coretests/src/com/android/internal/util/LatencyTrackerTest.java index f24894e7f263..010f72466f3a 100644 --- a/core/tests/coretests/src/com/android/internal/util/LatencyTrackerTest.java +++ b/core/tests/coretests/src/com/android/internal/util/LatencyTrackerTest.java @@ -25,9 +25,11 @@ import static com.android.internal.util.LatencyTracker.STATSD_ACTION; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; +import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.ravenwood.RavenwoodRule; import android.provider.DeviceConfig; -import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.runner.AndroidJUnit4; import com.android.internal.util.LatencyTracker.ActionProperties; @@ -49,7 +51,11 @@ import java.util.Map; import java.util.stream.Collectors; @RunWith(AndroidJUnit4.class) +@IgnoreUnderRavenwood(blockedBy = DeviceConfig.class) public class LatencyTrackerTest { + @Rule + public final RavenwoodRule mRavenwood = new RavenwoodRule(); + private static final String ENUM_NAME_PREFIX = "UIACTION_LATENCY_REPORTED__ACTION__"; @Rule diff --git a/core/tests/coretests/src/com/android/internal/util/LineBreakBufferedWriterTest.java b/core/tests/coretests/src/com/android/internal/util/LineBreakBufferedWriterTest.java index b2a2265d30ae..e6418fae7dca 100644 --- a/core/tests/coretests/src/com/android/internal/util/LineBreakBufferedWriterTest.java +++ b/core/tests/coretests/src/com/android/internal/util/LineBreakBufferedWriterTest.java @@ -16,7 +16,13 @@ package com.android.internal.util; -import junit.framework.TestCase; +import static org.junit.Assert.assertEquals; + +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; import java.io.ByteArrayOutputStream; import java.io.Writer; @@ -26,18 +32,18 @@ import java.util.List; /** * Tests for {@link IndentingPrintWriter}. */ -public class LineBreakBufferedWriterTest extends TestCase { +@RunWith(AndroidJUnit4.class) +public class LineBreakBufferedWriterTest { private ByteArrayOutputStream mStream; private RecordingWriter mWriter; - @Override - protected void setUp() throws Exception { - super.setUp(); - + @Before + public void setUp() throws Exception { mWriter = new RecordingWriter(); } + @Test public void testLessThanBufferSize() { final LineBreakBufferedWriter lw = new LineBreakBufferedWriter(mWriter, 1000); @@ -49,6 +55,7 @@ public class LineBreakBufferedWriterTest extends TestCase { assertOutput("Hello\nWorld\nTest\n"); } + @Test public void testMoreThanBufferSizeNoLineBreaks() { final LineBreakBufferedWriter lw = new LineBreakBufferedWriter(mWriter, 20); @@ -71,6 +78,7 @@ public class LineBreakBufferedWriterTest extends TestCase { } } + @Test public void testMoreThanBufferSizeNoLineBreaksSingleString() { final LineBreakBufferedWriter lw = new LineBreakBufferedWriter(mWriter, 20); @@ -92,6 +100,7 @@ public class LineBreakBufferedWriterTest extends TestCase { } } + @Test public void testMoreThanBufferSizeLineBreakBefore() { final LineBreakBufferedWriter lw = new LineBreakBufferedWriter(mWriter, 20); @@ -104,6 +113,7 @@ public class LineBreakBufferedWriterTest extends TestCase { assertOutput("aaaaaaaaaa", "bbbbcccccccccc"); } + @Test public void testMoreThanBufferSizeLineBreakBeforeSingleString() { final LineBreakBufferedWriter lw = new LineBreakBufferedWriter(mWriter, 20); @@ -115,6 +125,7 @@ public class LineBreakBufferedWriterTest extends TestCase { assertOutput("aaaaaaaaaa", "bbbbcccccccccc"); } + @Test public void testMoreThanBufferSizeLineBreakNew() { final LineBreakBufferedWriter lw = new LineBreakBufferedWriter(mWriter, 20); @@ -127,6 +138,7 @@ public class LineBreakBufferedWriterTest extends TestCase { assertOutput("aaaaaaaaaabbbbbc\nd", "ddddddddd"); } + @Test public void testMoreThanBufferSizeLineBreakBeforeAndNew() { final LineBreakBufferedWriter lw = new LineBreakBufferedWriter(mWriter, 20); @@ -139,6 +151,7 @@ public class LineBreakBufferedWriterTest extends TestCase { assertOutput("aaaaaaaaaa\nbbbbbc\nd", "ddddddddd"); } + @Test public void testMoreThanBufferSizeInt() { final LineBreakBufferedWriter lw = new LineBreakBufferedWriter(mWriter, 15); @@ -151,6 +164,7 @@ public class LineBreakBufferedWriterTest extends TestCase { assertOutput("123456789098765", "4321"); } + @Test public void testMoreThanBufferSizeChar() { final LineBreakBufferedWriter lw = new LineBreakBufferedWriter(mWriter, 15); @@ -165,6 +179,7 @@ public class LineBreakBufferedWriterTest extends TestCase { assertOutput("$$$$$$$$$$%%%%%", "%%%%%"); } + @Test public void testMoreThanBufferSizeLineBreakNewChars() { final LineBreakBufferedWriter lw = new LineBreakBufferedWriter(mWriter, 20); @@ -177,6 +192,7 @@ public class LineBreakBufferedWriterTest extends TestCase { assertOutput("aaaaaaaaaabbbbbc\nd", "ddddddddd"); } + @Test public void testMoreThenInitialCapacitySimpleWrites() { // This check is different from testMoreThanBufferSizeChar. The initial capacity is lower // than the maximum buffer size here. diff --git a/core/tests/coretests/src/com/android/internal/util/ParseUtilsTest.java b/core/tests/coretests/src/com/android/internal/util/ParseUtilsTest.java index 867152e720dd..d24cbfef9f10 100644 --- a/core/tests/coretests/src/com/android/internal/util/ParseUtilsTest.java +++ b/core/tests/coretests/src/com/android/internal/util/ParseUtilsTest.java @@ -16,13 +16,23 @@ package com.android.internal.util; -import junit.framework.TestCase; +import static org.junit.Assert.assertEquals; + +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; /** * Run with: atest /android/pi-dev/frameworks/base/core/tests/coretests/src/com/android/internal/util/ParseUtilsTest.java */ -public class ParseUtilsTest extends TestCase { +@RunWith(AndroidJUnit4.class) +public class ParseUtilsTest { + private static final float DELTA_FLOAT = 0.0f; + private static final double DELTA_DOUBLE = 0.0d; + + @Test public void testParseInt() { assertEquals(1, ParseUtils.parseInt(null, 1)); assertEquals(1, ParseUtils.parseInt("", 1)); @@ -33,6 +43,7 @@ public class ParseUtilsTest extends TestCase { assertEquals(-2, ParseUtils.parseInt("-2", 1)); } + @Test public void testParseIntWithBase() { assertEquals(1, ParseUtils.parseIntWithBase(null, 10, 1)); assertEquals(1, ParseUtils.parseIntWithBase("", 10, 1)); @@ -45,6 +56,7 @@ public class ParseUtilsTest extends TestCase { assertEquals(-3, ParseUtils.parseIntWithBase("-10", 3, 1)); } + @Test public void testParseLong() { assertEquals(1L, ParseUtils.parseLong(null, 1)); assertEquals(1L, ParseUtils.parseLong("", 1)); @@ -52,6 +64,7 @@ public class ParseUtilsTest extends TestCase { assertEquals(2L, ParseUtils.parseLong("2", 1)); } + @Test public void testParseLongWithBase() { assertEquals(1L, ParseUtils.parseLongWithBase(null, 10, 1)); assertEquals(1L, ParseUtils.parseLongWithBase("", 10, 1)); @@ -69,20 +82,23 @@ public class ParseUtilsTest extends TestCase { assertEquals(10_000_000_000L, ParseUtils.parseLongWithBase(null, 10, 10_000_000_000L)); } + @Test public void testParseFloat() { - assertEquals(0.5f, ParseUtils.parseFloat(null, 0.5f)); - assertEquals(0.5f, ParseUtils.parseFloat("", 0.5f)); - assertEquals(0.5f, ParseUtils.parseFloat("1x", 0.5f)); - assertEquals(1.5f, ParseUtils.parseFloat("1.5", 0.5f)); + assertEquals(0.5f, ParseUtils.parseFloat(null, 0.5f), DELTA_FLOAT); + assertEquals(0.5f, ParseUtils.parseFloat("", 0.5f), DELTA_FLOAT); + assertEquals(0.5f, ParseUtils.parseFloat("1x", 0.5f), DELTA_FLOAT); + assertEquals(1.5f, ParseUtils.parseFloat("1.5", 0.5f), DELTA_FLOAT); } + @Test public void testParseDouble() { - assertEquals(0.5, ParseUtils.parseDouble(null, 0.5)); - assertEquals(0.5, ParseUtils.parseDouble("", 0.5)); - assertEquals(0.5, ParseUtils.parseDouble("1x", 0.5)); - assertEquals(1.5, ParseUtils.parseDouble("1.5", 0.5)); + assertEquals(0.5, ParseUtils.parseDouble(null, 0.5), DELTA_DOUBLE); + assertEquals(0.5, ParseUtils.parseDouble("", 0.5), DELTA_DOUBLE); + assertEquals(0.5, ParseUtils.parseDouble("1x", 0.5), DELTA_DOUBLE); + assertEquals(1.5, ParseUtils.parseDouble("1.5", 0.5), DELTA_DOUBLE); } + @Test public void testParseBoolean() { assertEquals(false, ParseUtils.parseBoolean(null, false)); assertEquals(true, ParseUtils.parseBoolean(null, true)); diff --git a/core/tests/coretests/src/com/android/internal/util/ProgressReporterTest.java b/core/tests/coretests/src/com/android/internal/util/ProgressReporterTest.java index 87f2a8a67947..0d213357c9a5 100644 --- a/core/tests/coretests/src/com/android/internal/util/ProgressReporterTest.java +++ b/core/tests/coretests/src/com/android/internal/util/ProgressReporterTest.java @@ -16,14 +16,28 @@ package com.android.internal.util; -import junit.framework.TestCase; +import static org.junit.Assert.assertEquals; + +import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.ravenwood.RavenwoodRule; + +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +@IgnoreUnderRavenwood(blockedBy = ProgressReporter.class) +public class ProgressReporterTest { + @Rule + public final RavenwoodRule mRavenwood = new RavenwoodRule(); -public class ProgressReporterTest extends TestCase { private ProgressReporter r; - @Override - protected void setUp() throws Exception { - super.setUp(); + @Before + public void setUp() throws Exception { r = new ProgressReporter(0); } @@ -37,6 +51,7 @@ public class ProgressReporterTest extends TestCase { assertEquals("len", len, range[1]); } + @Test public void testBasic() throws Exception { assertProgress(0); @@ -50,6 +65,7 @@ public class ProgressReporterTest extends TestCase { assertProgress(100); } + @Test public void testSegment() throws Exception { r.setProgress(20); assertProgress(20); @@ -68,6 +84,7 @@ public class ProgressReporterTest extends TestCase { assertProgress(80); } + @Test public void testSegmentOvershoot() throws Exception { r.setProgress(20); assertProgress(20); @@ -87,6 +104,7 @@ public class ProgressReporterTest extends TestCase { assertProgress(60); } + @Test public void testSegmentNested() throws Exception { r.setProgress(20); assertProgress(20); diff --git a/core/tests/coretests/src/com/android/internal/util/RingBufferTest.java b/core/tests/coretests/src/com/android/internal/util/RingBufferTest.java index 4497770ef40d..d7a100a30ac8 100644 --- a/core/tests/coretests/src/com/android/internal/util/RingBufferTest.java +++ b/core/tests/coretests/src/com/android/internal/util/RingBufferTest.java @@ -20,8 +20,8 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; -import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/core/tests/coretests/src/com/android/internal/util/TokenBucketTest.java b/core/tests/coretests/src/com/android/internal/util/TokenBucketTest.java index 8b30828a8936..ef579fe07af5 100644 --- a/core/tests/coretests/src/com/android/internal/util/TokenBucketTest.java +++ b/core/tests/coretests/src/com/android/internal/util/TokenBucketTest.java @@ -16,22 +16,29 @@ package com.android.internal.util; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; import android.os.SystemClock; import android.text.format.DateUtils; -import junit.framework.TestCase; +import androidx.test.runner.AndroidJUnit4; -public class TokenBucketTest extends TestCase { +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class TokenBucketTest { static final int FILL_DELTA_VERY_SHORT = 1; static final int FILL_DELTA_VERY_LONG = Integer.MAX_VALUE; + @Test public void testArgumentValidation() { assertThrow(() -> new TokenBucket(0, 1, 1)); assertThrow(() -> new TokenBucket(1, 0, 1)); - assertThrow(() -> new TokenBucket(1, 1, 0)); assertThrow(() -> new TokenBucket(0, 1)); assertThrow(() -> new TokenBucket(1, 0)); assertThrow(() -> new TokenBucket(-1, 1, 1)); @@ -46,6 +53,7 @@ public class TokenBucketTest extends TestCase { new TokenBucket(5000, 1); } + @Test public void testInitialCapacity() { drain(new TokenBucket(FILL_DELTA_VERY_LONG, 1), 1); drain(new TokenBucket(FILL_DELTA_VERY_LONG, 10), 10); @@ -62,6 +70,7 @@ public class TokenBucketTest extends TestCase { drain(new TokenBucket((int) DateUtils.DAY_IN_MILLIS, 200), 200); } + @Test public void testReset() { TokenBucket tb = new TokenBucket(FILL_DELTA_VERY_LONG, 100, 10); drain(tb, 10); @@ -77,6 +86,7 @@ public class TokenBucketTest extends TestCase { drain(tb, 30); } + @Test public void testFill() throws Exception { int delta = 50; TokenBucket tb = new TokenBucket(delta, 10, 0); @@ -88,6 +98,7 @@ public class TokenBucketTest extends TestCase { assertTrue(tb.has()); } + @Test public void testRefill() throws Exception { TokenBucket tb = new TokenBucket(FILL_DELTA_VERY_SHORT, 10, 10); @@ -107,6 +118,7 @@ public class TokenBucketTest extends TestCase { assertEquals(10, tb.get(100)); } + @Test public void testAverage() throws Exception { final int delta = 3; final int want = 60; @@ -124,6 +136,7 @@ public class TokenBucketTest extends TestCase { assertDuration(want * delta, SystemClock.elapsedRealtime() - start); } + @Test public void testBurst() throws Exception { final int delta = 2; final int capacity = 20; diff --git a/core/tests/utiltests/Android.bp b/core/tests/utiltests/Android.bp index 967047e74555..2ccee71c8ff7 100644 --- a/core/tests/utiltests/Android.bp +++ b/core/tests/utiltests/Android.bp @@ -54,21 +54,20 @@ android_test { android_ravenwood_test { name: "FrameworksUtilTestsRavenwood", + libs: [ + "android.test.mock", + ], static_libs: [ "androidx.annotation_annotation", "androidx.test.rules", "mockito_ravenwood", + "frameworks-base-testutils", + "servicestests-utils", ], srcs: [ - "src/android/util/AtomicFileTest.java", - "src/android/util/DataUnitTest.java", - "src/android/util/EventLogTest.java", - "src/android/util/IndentingPrintWriterTest.java", - "src/android/util/IntArrayTest.java", - "src/android/util/LocalLogTest.java", - "src/android/util/LongArrayTest.java", - "src/android/util/SlogTest.java", - "src/android/util/TimeUtilsTest.java", + "src/android/util/IRemoteMemoryIntArray.aidl", + "src/android/util/**/*.java", + "src/com/android/internal/util/**/*.java", ], auto_gen_config: true, } diff --git a/core/tests/utiltests/src/android/util/MemoryIntArrayTest.java b/core/tests/utiltests/src/android/util/MemoryIntArrayTest.java index 1966e122ee5b..51013e4b4f00 100644 --- a/core/tests/utiltests/src/android/util/MemoryIntArrayTest.java +++ b/core/tests/utiltests/src/android/util/MemoryIntArrayTest.java @@ -23,11 +23,14 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import android.os.Parcel; +import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.ravenwood.RavenwoodRule; -import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.runner.AndroidJUnit4; import libcore.io.IoUtils; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -35,13 +38,17 @@ import java.lang.reflect.Field; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; - -import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) +@IgnoreUnderRavenwood(blockedBy = MemoryIntArray.class) public class MemoryIntArrayTest { + @Rule + public final RavenwoodRule mRavenwood = new RavenwoodRule(); + static { - System.loadLibrary("cutils"); - System.loadLibrary("memoryintarraytest"); + if (!RavenwoodRule.isUnderRavenwood()) { + System.loadLibrary("cutils"); + System.loadLibrary("memoryintarraytest"); + } } @Test diff --git a/core/tests/utiltests/src/android/util/MetadataReaderTest.java b/core/tests/utiltests/src/android/util/MetadataReaderTest.java index a828edbac6ab..24e9e0cd38c9 100644 --- a/core/tests/utiltests/src/android/util/MetadataReaderTest.java +++ b/core/tests/utiltests/src/android/util/MetadataReaderTest.java @@ -16,25 +16,35 @@ package android.util; +import static org.junit.Assert.assertEquals; + import android.media.ExifInterface; import android.os.Bundle; +import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.ravenwood.RavenwoodRule; import android.provider.DocumentsContract; import android.provider.MetadataReader; -import libcore.io.IoUtils; +import androidx.test.runner.AndroidJUnit4; -import junit.framework.TestCase; +import libcore.io.IoUtils; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.runner.RunWith; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; -public class MetadataReaderTest extends TestCase { +@RunWith(AndroidJUnit4.class) +@IgnoreUnderRavenwood(blockedBy = MetadataReader.class) +public class MetadataReaderTest { + @Rule + public final RavenwoodRule mRavenwood = new RavenwoodRule(); private InputStream mInputStream; private Bundle mData; diff --git a/core/tests/utiltests/src/android/util/SystemConfigFileCommitEventLoggerTest.java b/core/tests/utiltests/src/android/util/SystemConfigFileCommitEventLoggerTest.java index 5f6c20141c37..3bb79ec91d09 100644 --- a/core/tests/utiltests/src/android/util/SystemConfigFileCommitEventLoggerTest.java +++ b/core/tests/utiltests/src/android/util/SystemConfigFileCommitEventLoggerTest.java @@ -21,12 +21,22 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import android.os.SystemClock; +import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.ravenwood.RavenwoodRule; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Rule; import org.junit.Test; +import org.junit.runner.RunWith; import org.mockito.Mockito; - +@RunWith(AndroidJUnit4.class) +@IgnoreUnderRavenwood(blockedBy = SystemConfigFileCommitEventLogger.class) public class SystemConfigFileCommitEventLoggerTest { + @Rule + public final RavenwoodRule mRavenwood = new RavenwoodRule(); + @Test public void testSimple() throws Exception { var logger = spy(new SystemConfigFileCommitEventLogger("name")); diff --git a/core/tests/utiltests/src/com/android/internal/util/ArrayUtilsTest.java b/core/tests/utiltests/src/com/android/internal/util/ArrayUtilsTest.java index 72f3af640b67..0c5e9664bbde 100644 --- a/core/tests/utiltests/src/com/android/internal/util/ArrayUtilsTest.java +++ b/core/tests/utiltests/src/com/android/internal/util/ArrayUtilsTest.java @@ -17,19 +17,28 @@ package com.android.internal.util; import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import junit.framework.TestCase; - /** * Tests for {@link ArrayUtils} */ -public class ArrayUtilsTest extends TestCase { +@RunWith(AndroidJUnit4.class) +public class ArrayUtilsTest { + @Test public void testContains() throws Exception { final Object A = new Object(); final Object B = new Object(); @@ -46,6 +55,7 @@ public class ArrayUtilsTest extends TestCase { assertFalse(ArrayUtils.contains(new Object[] { null }, A)); } + @Test public void testIndexOf() throws Exception { final Object A = new Object(); final Object B = new Object(); @@ -66,6 +76,7 @@ public class ArrayUtilsTest extends TestCase { assertEquals(2, ArrayUtils.indexOf(new Object[] { A, null, B }, B)); } + @Test public void testContainsAll() throws Exception { final Object A = new Object(); final Object B = new Object(); @@ -86,6 +97,7 @@ public class ArrayUtilsTest extends TestCase { assertFalse(ArrayUtils.containsAll(new Object[] { A }, new Object[] { null })); } + @Test public void testContainsInt() throws Exception { assertTrue(ArrayUtils.contains(new int[] { 1, 2, 3 }, 1)); assertTrue(ArrayUtils.contains(new int[] { 1, 2, 3 }, 2)); @@ -96,6 +108,7 @@ public class ArrayUtilsTest extends TestCase { assertFalse(ArrayUtils.contains(new int[] { }, 2)); } + @Test public void testAppendInt() throws Exception { assertArrayEquals(new int[] { 1 }, ArrayUtils.appendInt(null, 1)); @@ -107,6 +120,7 @@ public class ArrayUtilsTest extends TestCase { ArrayUtils.appendInt(new int[] { 1, 2 }, 1)); } + @Test public void testRemoveInt() throws Exception { assertNull(ArrayUtils.removeInt(null, 1)); assertArrayEquals(new int[] { }, @@ -123,6 +137,7 @@ public class ArrayUtilsTest extends TestCase { ArrayUtils.removeInt(new int[] { 1, 2, 3, 1 }, 1)); } + @Test public void testContainsLong() throws Exception { assertTrue(ArrayUtils.contains(new long[] { 1, 2, 3 }, 1)); assertTrue(ArrayUtils.contains(new long[] { 1, 2, 3 }, 2)); @@ -133,6 +148,7 @@ public class ArrayUtilsTest extends TestCase { assertFalse(ArrayUtils.contains(new long[] { }, 2)); } + @Test public void testAppendLong() throws Exception { assertArrayEquals(new long[] { 1 }, ArrayUtils.appendLong(null, 1)); @@ -144,6 +160,7 @@ public class ArrayUtilsTest extends TestCase { ArrayUtils.appendLong(new long[] { 1, 2 }, 1)); } + @Test public void testRemoveLong() throws Exception { assertNull(ArrayUtils.removeLong(null, 1)); assertArrayEquals(new long[] { }, @@ -160,6 +177,7 @@ public class ArrayUtilsTest extends TestCase { ArrayUtils.removeLong(new long[] { 1, 2, 3, 1 }, 1)); } + @Test public void testConcat_zeroObjectArrays() { // empty varargs array assertArrayEquals(new String[] {}, ArrayUtils.concat(String.class)); @@ -167,16 +185,19 @@ public class ArrayUtilsTest extends TestCase { assertArrayEquals(new String[] {}, ArrayUtils.concat(String.class, (String[][]) null)); } + @Test public void testConcat_oneObjectArray() { assertArrayEquals(new String[] { "1", "2" }, ArrayUtils.concat(String.class, new String[] { "1", "2" })); } + @Test public void testConcat_oneEmptyObjectArray() { assertArrayEquals(new String[] {}, ArrayUtils.concat(String.class, (String[]) null)); assertArrayEquals(new String[] {}, ArrayUtils.concat(String.class, new String[] {})); } + @Test public void testConcat_twoObjectArrays() { assertArrayEquals(new Long[] { 1L }, ArrayUtils.concat(Long.class, new Long[] { 1L }, new Long[] {})); @@ -188,6 +209,7 @@ public class ArrayUtilsTest extends TestCase { ArrayUtils.concat(Long.class, new Long[] { 1L, 2L }, new Long[] { 3L, 4L })); } + @Test public void testConcat_twoEmptyObjectArrays() { assertArrayEquals(new Long[] {}, ArrayUtils.concat(Long.class, null, null)); assertArrayEquals(new Long[] {}, ArrayUtils.concat(Long.class, new Long[] {}, null)); @@ -196,6 +218,7 @@ public class ArrayUtilsTest extends TestCase { ArrayUtils.concat(Long.class, new Long[] {}, new Long[] {})); } + @Test public void testConcat_threeObjectArrays() { String[] array1 = { "1", "2" }; String[] array2 = { "3", "4" }; @@ -205,6 +228,7 @@ public class ArrayUtilsTest extends TestCase { assertArrayEquals(expectation, ArrayUtils.concat(String.class, array1, array2, array3)); } + @Test public void testConcat_threeObjectArraysWithNull() { String[] array1 = { "1", "2" }; String[] array2 = null; @@ -214,6 +238,7 @@ public class ArrayUtilsTest extends TestCase { assertArrayEquals(expectation, ArrayUtils.concat(String.class, array1, array2, array3)); } + @Test public void testConcat_zeroByteArrays() { // empty varargs array assertArrayEquals(new byte[] {}, ArrayUtils.concat()); @@ -221,15 +246,18 @@ public class ArrayUtilsTest extends TestCase { assertArrayEquals(new byte[] {}, ArrayUtils.concat((byte[][]) null)); } + @Test public void testConcat_oneByteArray() { assertArrayEquals(new byte[] { 1, 2 }, ArrayUtils.concat(new byte[] { 1, 2 })); } + @Test public void testConcat_oneEmptyByteArray() { assertArrayEquals(new byte[] {}, ArrayUtils.concat((byte[]) null)); assertArrayEquals(new byte[] {}, ArrayUtils.concat(new byte[] {})); } + @Test public void testConcat_twoByteArrays() { assertArrayEquals(new byte[] { 1 }, ArrayUtils.concat(new byte[] { 1 }, new byte[] {})); assertArrayEquals(new byte[] { 1 }, ArrayUtils.concat(new byte[] {}, new byte[] { 1 })); @@ -239,6 +267,7 @@ public class ArrayUtilsTest extends TestCase { ArrayUtils.concat(new byte[] { 1, 2 }, new byte[] { 3, 4 })); } + @Test public void testConcat_twoEmptyByteArrays() { assertArrayEquals(new byte[] {}, ArrayUtils.concat((byte[]) null, null)); assertArrayEquals(new byte[] {}, ArrayUtils.concat(new byte[] {}, null)); @@ -246,6 +275,7 @@ public class ArrayUtilsTest extends TestCase { assertArrayEquals(new byte[] {}, ArrayUtils.concat(new byte[] {}, new byte[] {})); } + @Test public void testConcat_threeByteArrays() { byte[] array1 = { 1, 2 }; byte[] array2 = { 3, 4 }; @@ -255,6 +285,7 @@ public class ArrayUtilsTest extends TestCase { assertArrayEquals(expectation, ArrayUtils.concat(array1, array2, array3)); } + @Test public void testConcat_threeByteArraysWithNull() { byte[] array1 = { 1, 2 }; byte[] array2 = null; @@ -264,6 +295,7 @@ public class ArrayUtilsTest extends TestCase { assertArrayEquals(expectation, ArrayUtils.concat(array1, array2, array3)); } + @Test @SmallTest public void testUnstableRemoveIf() throws Exception { java.util.function.Predicate isNull = new java.util.function.Predicate() { @@ -357,31 +389,37 @@ public class ArrayUtilsTest extends TestCase { assertEquals(0, collection.size()); } + @Test @SmallTest public void testThrowsIfOutOfBounds_passesWhenRangeInsideArray() { ArrayUtils.throwsIfOutOfBounds(10, 2, 6); } + @Test @SmallTest public void testThrowsIfOutOfBounds_passesWhenRangeIsWholeArray() { ArrayUtils.throwsIfOutOfBounds(10, 0, 10); } + @Test @SmallTest public void testThrowsIfOutOfBounds_passesWhenEmptyRangeAtStart() { ArrayUtils.throwsIfOutOfBounds(10, 0, 0); } + @Test @SmallTest public void testThrowsIfOutOfBounds_passesWhenEmptyRangeAtEnd() { ArrayUtils.throwsIfOutOfBounds(10, 10, 0); } + @Test @SmallTest public void testThrowsIfOutOfBounds_passesWhenEmptyArray() { ArrayUtils.throwsIfOutOfBounds(0, 0, 0); } + @Test @SmallTest public void testThrowsIfOutOfBounds_failsWhenRangeStartNegative() { try { @@ -392,6 +430,7 @@ public class ArrayUtilsTest extends TestCase { } } + @Test @SmallTest public void testThrowsIfOutOfBounds_failsWhenCountNegative() { try { @@ -402,6 +441,7 @@ public class ArrayUtilsTest extends TestCase { } } + @Test @SmallTest public void testThrowsIfOutOfBounds_failsWhenRangeStartTooHigh() { try { @@ -412,6 +452,7 @@ public class ArrayUtilsTest extends TestCase { } } + @Test @SmallTest public void testThrowsIfOutOfBounds_failsWhenRangeEndTooHigh() { try { @@ -422,6 +463,7 @@ public class ArrayUtilsTest extends TestCase { } } + @Test @SmallTest public void testThrowsIfOutOfBounds_failsWhenLengthNegative() { try { @@ -432,6 +474,7 @@ public class ArrayUtilsTest extends TestCase { } } + @Test @SmallTest public void testThrowsIfOutOfBounds_failsWhenOverflowRangeEndTooHigh() { try { diff --git a/core/tests/utiltests/src/com/android/internal/util/BitwiseStreamsTest.java b/core/tests/utiltests/src/com/android/internal/util/BitwiseStreamsTest.java index 306f58fcce2e..092d6999e85e 100644 --- a/core/tests/utiltests/src/com/android/internal/util/BitwiseStreamsTest.java +++ b/core/tests/utiltests/src/com/android/internal/util/BitwiseStreamsTest.java @@ -16,20 +16,23 @@ package com.android.internal.util; -import com.android.internal.util.BitwiseInputStream; -import com.android.internal.util.BitwiseOutputStream; -import com.android.internal.util.HexDump; - -import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; +import static org.junit.Assert.assertEquals; import android.util.Log; +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + import java.util.Random; -public class BitwiseStreamsTest extends AndroidTestCase { +@RunWith(AndroidJUnit4.class) +public class BitwiseStreamsTest { private final static String LOG_TAG = "BitwiseStreamsTest"; + @Test @SmallTest public void testOne() throws Exception { int offset = 3; @@ -45,6 +48,7 @@ public class BitwiseStreamsTest extends AndroidTestCase { assertEquals(HexDump.toHexString(inBuf), HexDump.toHexString(inBufDup)); } + @Test @SmallTest public void testTwo() throws Exception { int offset = 3; @@ -59,6 +63,7 @@ public class BitwiseStreamsTest extends AndroidTestCase { assertEquals(HexDump.toHexString(inBuf), HexDump.toHexString(inBufDup)); } + @Test @SmallTest public void testThree() throws Exception { int offset = 4; @@ -73,6 +78,7 @@ public class BitwiseStreamsTest extends AndroidTestCase { assertEquals(HexDump.toHexString(inBuf), HexDump.toHexString(inBufDup)); } + @Test @SmallTest public void testFour() throws Exception { int offset = 7; @@ -90,6 +96,7 @@ public class BitwiseStreamsTest extends AndroidTestCase { assertEquals(HexDump.toHexString(inBuf), HexDump.toHexString(inBufDup)); } + @Test @SmallTest public void testFive() throws Exception { Random random = new Random(); @@ -111,6 +118,7 @@ public class BitwiseStreamsTest extends AndroidTestCase { } } + @Test @SmallTest public void testSix() throws Exception { int num_runs = 10; @@ -134,6 +142,7 @@ public class BitwiseStreamsTest extends AndroidTestCase { Log.d(LOG_TAG, "repeated encode-decode took " + (end - start) + " ms"); } + @Test @SmallTest public void testExpandArray() throws Exception { Random random = new Random(); diff --git a/core/tests/utiltests/src/com/android/internal/util/CallbackRegistryTest.java b/core/tests/utiltests/src/com/android/internal/util/CallbackRegistryTest.java index 1581abb5a9c6..9a1402e04011 100644 --- a/core/tests/utiltests/src/com/android/internal/util/CallbackRegistryTest.java +++ b/core/tests/utiltests/src/com/android/internal/util/CallbackRegistryTest.java @@ -15,19 +15,21 @@ */ package com.android.internal.util; -import junit.framework.TestCase; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import androidx.test.runner.AndroidJUnit4; import org.junit.Test; +import org.junit.runner.RunWith; import java.util.ArrayList; import java.util.Objects; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -public class CallbackRegistryTest extends TestCase { +@RunWith(AndroidJUnit4.class) +public class CallbackRegistryTest { final Integer callback1 = 1; final Integer callback2 = 2; @@ -50,6 +52,7 @@ public class CallbackRegistryTest extends TestCase { deepNotifyCount[callback]++; } + @Test public void testAddListener() { CallbackRegistry.NotifierCallback notifier = new CallbackRegistry.NotifierCallback() { @@ -89,6 +92,7 @@ public class CallbackRegistryTest extends TestCase { assertEquals(otherListener, callbacks.get(0)); } + @Test public void testSimpleNotify() { CallbackRegistry.NotifierCallback notifier = new CallbackRegistry.NotifierCallback() { @@ -108,6 +112,7 @@ public class CallbackRegistryTest extends TestCase { assertEquals(1, notify2); } + @Test public void testRemoveWhileNotifying() { CallbackRegistry.NotifierCallback notifier = new CallbackRegistry.NotifierCallback() { @@ -135,6 +140,7 @@ public class CallbackRegistryTest extends TestCase { assertEquals(callback3, callbacks.get(0)); } + @Test public void testDeepRemoveWhileNotifying() { CallbackRegistry.NotifierCallback notifier = new CallbackRegistry.NotifierCallback() { @@ -159,6 +165,7 @@ public class CallbackRegistryTest extends TestCase { assertEquals(0, callbacks.size()); } + @Test public void testAddRemovedListener() { CallbackRegistry.NotifierCallback notifier = @@ -191,6 +198,7 @@ public class CallbackRegistryTest extends TestCase { assertEquals(1, notify3); } + @Test public void testVeryDeepRemoveWhileNotifying() { final Integer[] callbacks = new Integer[deepNotifyCount.length]; for (int i = 0; i < callbacks.length; i++) { @@ -221,6 +229,7 @@ public class CallbackRegistryTest extends TestCase { assertEquals(0, callbackList.size()); } + @Test public void testClear() { CallbackRegistry.NotifierCallback notifier = new CallbackRegistry.NotifierCallback() { @@ -245,6 +254,7 @@ public class CallbackRegistryTest extends TestCase { } } + @Test public void testNestedClear() { CallbackRegistry.NotifierCallback notifier = new CallbackRegistry.NotifierCallback() { @@ -268,6 +278,7 @@ public class CallbackRegistryTest extends TestCase { assertEquals(0, callbackList.size()); } + @Test public void testIsEmpty() throws Exception { CallbackRegistry.NotifierCallback notifier = new CallbackRegistry.NotifierCallback() { @@ -284,6 +295,7 @@ public class CallbackRegistryTest extends TestCase { assertFalse(registry.isEmpty()); } + @Test public void testClone() throws Exception { CallbackRegistry.NotifierCallback notifier = new CallbackRegistry.NotifierCallback() { diff --git a/core/tests/utiltests/src/com/android/internal/util/CharSequencesTest.java b/core/tests/utiltests/src/com/android/internal/util/CharSequencesTest.java index 469a4ccd05e4..988854038e53 100644 --- a/core/tests/utiltests/src/com/android/internal/util/CharSequencesTest.java +++ b/core/tests/utiltests/src/com/android/internal/util/CharSequencesTest.java @@ -18,12 +18,26 @@ package com.android.internal.util; import static com.android.internal.util.CharSequences.forAsciiBytes; -import android.test.suitebuilder.annotation.SmallTest; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; -import junit.framework.TestCase; +import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.ravenwood.RavenwoodRule; -public class CharSequencesTest extends TestCase { +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +@IgnoreUnderRavenwood(blockedBy = CharSequences.class) +public class CharSequencesTest { + @Rule + public final RavenwoodRule mRavenwood = new RavenwoodRule(); + + @Test @SmallTest public void testCharSequences() { String s = "Hello Bob"; diff --git a/core/tests/utiltests/src/com/android/internal/util/FastXmlSerializerTest.java b/core/tests/utiltests/src/com/android/internal/util/FastXmlSerializerTest.java index 3cef33621a01..7723d589a723 100644 --- a/core/tests/utiltests/src/com/android/internal/util/FastXmlSerializerTest.java +++ b/core/tests/utiltests/src/com/android/internal/util/FastXmlSerializerTest.java @@ -16,13 +16,23 @@ package com.android.internal.util; -import android.test.suitebuilder.annotation.LargeTest; -import android.test.suitebuilder.annotation.SmallTest; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.ravenwood.RavenwoodRule; +import android.provider.DeviceConfig; import android.util.Log; import android.util.Xml; -import junit.framework.TestCase; +import androidx.test.filters.LargeTest; +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlSerializer; @@ -34,7 +44,9 @@ import java.nio.charset.StandardCharsets; * Tests for {@link FastXmlSerializer} */ @SmallTest -public class FastXmlSerializerTest extends TestCase { +@RunWith(AndroidJUnit4.class) +@IgnoreUnderRavenwood(blockedBy = Xml.class) +public class FastXmlSerializerTest { private static final String TAG = "FastXmlSerializerTest"; private static final boolean ENABLE_DUMP = false; // DO NOT SUBMIT WITH TRUE. @@ -42,6 +54,10 @@ public class FastXmlSerializerTest extends TestCase { private static final String ROOT_TAG = "root"; private static final String ATTR = "attr"; + @Rule + public final RavenwoodRule mRavenwood = new RavenwoodRule(); + + @Test public void testEmptyText() throws Exception { final ByteArrayOutputStream stream = new ByteArrayOutputStream(); @@ -128,6 +144,7 @@ public class FastXmlSerializerTest extends TestCase { return ok; } + @Test @LargeTest public void testAllCharacters() throws Exception { boolean ok = true; diff --git a/core/tests/utiltests/src/com/android/internal/util/FileRotatorTest.java b/core/tests/utiltests/src/com/android/internal/util/FileRotatorTest.java index 73e47e1635b4..47c17959d28d 100644 --- a/core/tests/utiltests/src/com/android/internal/util/FileRotatorTest.java +++ b/core/tests/utiltests/src/com/android/internal/util/FileRotatorTest.java @@ -23,16 +23,23 @@ import static android.text.format.DateUtils.SECOND_IN_MILLIS; import static android.text.format.DateUtils.WEEK_IN_MILLIS; import static android.text.format.DateUtils.YEAR_IN_MILLIS; -import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.Suppress; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + import android.util.Log; +import androidx.test.runner.AndroidJUnit4; + import com.android.internal.util.FileRotator.Reader; import com.android.internal.util.FileRotator.Writer; -import com.android.internal.util.test.FsUtil; import com.google.android.collect.Lists; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; + import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; @@ -40,6 +47,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.nio.file.Files; import java.util.ArrayList; import java.util.Arrays; import java.util.Random; @@ -47,7 +55,8 @@ import java.util.Random; /** * Tests for {@link FileRotator}. */ -public class FileRotatorTest extends AndroidTestCase { +@RunWith(AndroidJUnit4.class) +public class FileRotatorTest { private static final String TAG = "FileRotatorTest"; private File mBasePath; @@ -59,14 +68,12 @@ public class FileRotatorTest extends AndroidTestCase { // TODO: test throwing rolls back correctly - @Override - protected void setUp() throws Exception { - super.setUp(); - - mBasePath = getContext().getFilesDir(); - FsUtil.deleteContents(mBasePath); + @Before + public void setUp() throws Exception { + mBasePath = Files.createTempDirectory(TAG).toFile(); } + @Test public void testEmpty() throws Exception { final FileRotator rotate1 = new FileRotator( mBasePath, PREFIX, DAY_IN_MILLIS, WEEK_IN_MILLIS); @@ -85,6 +92,7 @@ public class FileRotatorTest extends AndroidTestCase { assertReadAll(rotate2); } + @Test public void testCombine() throws Exception { final FileRotator rotate = new FileRotator( mBasePath, PREFIX, DAY_IN_MILLIS, WEEK_IN_MILLIS); @@ -106,6 +114,7 @@ public class FileRotatorTest extends AndroidTestCase { assertReadAll(rotate, "bar"); } + @Test public void testRotate() throws Exception { final FileRotator rotate = new FileRotator( mBasePath, PREFIX, DAY_IN_MILLIS, WEEK_IN_MILLIS); @@ -138,6 +147,7 @@ public class FileRotatorTest extends AndroidTestCase { assertReadAll(rotate, "bar", "baz"); } + @Test public void testDelete() throws Exception { final FileRotator rotate = new FileRotator( mBasePath, PREFIX, MINUTE_IN_MILLIS, DAY_IN_MILLIS); @@ -168,6 +178,7 @@ public class FileRotatorTest extends AndroidTestCase { assertReadAll(rotate); } + @Test public void testThrowRestoresBackup() throws Exception { final FileRotator rotate = new FileRotator( mBasePath, PREFIX, MINUTE_IN_MILLIS, DAY_IN_MILLIS); @@ -201,6 +212,7 @@ public class FileRotatorTest extends AndroidTestCase { assertReadAll(rotate, "foo"); } + @Test public void testOtherFilesAndMalformed() throws Exception { final FileRotator rotate = new FileRotator( mBasePath, PREFIX, SECOND_IN_MILLIS, SECOND_IN_MILLIS); @@ -229,6 +241,7 @@ public class FileRotatorTest extends AndroidTestCase { private static final String BLUE = "blue"; private static final String YELLOW = "yellow"; + @Test public void testQueryMatch() throws Exception { final FileRotator rotate = new FileRotator( mBasePath, PREFIX, HOUR_IN_MILLIS, YEAR_IN_MILLIS); @@ -277,6 +290,7 @@ public class FileRotatorTest extends AndroidTestCase { assertReadMatching(rotate, Long.MIN_VALUE, TEST_TIME - DAY_IN_MILLIS); } + @Test public void testClockRollingBackwards() throws Exception { final FileRotator rotate = new FileRotator( mBasePath, PREFIX, DAY_IN_MILLIS, YEAR_IN_MILLIS); @@ -325,7 +339,8 @@ public class FileRotatorTest extends AndroidTestCase { assertReadAll(rotate, "meow", "yay"); } - @Suppress + @Test + @Ignore public void testFuzz() throws Exception { final FileRotator rotate = new FileRotator( mBasePath, PREFIX, HOUR_IN_MILLIS, DAY_IN_MILLIS); @@ -352,6 +367,7 @@ public class FileRotatorTest extends AndroidTestCase { Log.d(TAG, Arrays.toString(mBasePath.list())); } + @Test public void testRecoverAtomic() throws Exception { write("rotator.1024-2048", "foo"); write("rotator.1024-2048.backup", "bar"); @@ -366,6 +382,7 @@ public class FileRotatorTest extends AndroidTestCase { assertReadAll(rotate, "bar"); } + @Test public void testReadSorted() throws Exception { write("rotator.1024-2048", "2"); write("rotator.2048-4096", "3"); @@ -376,11 +393,11 @@ public class FileRotatorTest extends AndroidTestCase { assertReadAll(rotate, "1", "2", "3"); } + @Test public void testFileSystemInaccessible() throws Exception { - File inaccessibleDir = null; - String dirPath = getContext().getFilesDir() + File.separator + "inaccessible"; - inaccessibleDir = new File(dirPath); - final FileRotator rotate = new FileRotator(inaccessibleDir, PREFIX, SECOND_IN_MILLIS, SECOND_IN_MILLIS); + File inaccessibleDir = mBasePath.toPath().resolve("does_not_exist").toFile(); + final FileRotator rotate = new FileRotator(inaccessibleDir, PREFIX, + SECOND_IN_MILLIS, SECOND_IN_MILLIS); // rotate should not throw on dir not mkdir-ed (or otherwise inaccessible) rotate.maybeRotate(TEST_TIME); diff --git a/core/tests/utiltests/src/com/android/internal/util/HeavyHitterSketchTest.java b/core/tests/utiltests/src/com/android/internal/util/HeavyHitterSketchTest.java index f2285a12e30a..74184cacc91c 100644 --- a/core/tests/utiltests/src/com/android/internal/util/HeavyHitterSketchTest.java +++ b/core/tests/utiltests/src/com/android/internal/util/HeavyHitterSketchTest.java @@ -16,10 +16,17 @@ package com.android.internal.util; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + import android.util.ArraySet; import android.util.Pair; -import junit.framework.TestCase; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; import java.util.ArrayList; import java.util.Comparator; @@ -32,7 +39,8 @@ import java.util.stream.Collectors; /** * Tests for {@link HeavyHitterSketch}. */ -public final class HeavyHitterSketchTest extends TestCase { +@RunWith(AndroidJUnit4.class) +public final class HeavyHitterSketchTest { private static final float EPSILON = 0.00001f; @@ -163,6 +171,7 @@ public final class HeavyHitterSketchTest extends TestCase { return input; } + @Test public void testPositive() throws Exception { // Simple case verify(new int[]{2, 9, 9, 9, 7, 6, 4, 9, 9, 9, 3, 9}, 2, new int[]{9}, @@ -179,6 +188,7 @@ public final class HeavyHitterSketchTest extends TestCase { new float[]{0.32f, 0.24f, 0.16f, 0.08f}); } + @Test public void testNegative() throws Exception { // Simple case verifyNotExpected(new int[]{2, 9, 9, 9, 7, 6, 4, 9, 9, 9, 3, 9}, 2, new int[]{0, 1, 2}); @@ -193,6 +203,7 @@ public final class HeavyHitterSketchTest extends TestCase { verifyNotExpected(input, 12, new int[]{0, 1, 2, 1000, 1005}); } + @Test public void testFalsePositive() throws Exception { // Simple case verifyNotExpected(new int[]{2, 9, 2, 2, 7, 6, 4, 9, 9, 9, 3, 9}, 2, new int[]{9}); diff --git a/core/tests/utiltests/src/com/android/internal/util/InlinePresentationStyleUtilsTest.java b/core/tests/utiltests/src/com/android/internal/util/InlinePresentationStyleUtilsTest.java index 35c56818a108..7203b8c6a8c8 100644 --- a/core/tests/utiltests/src/com/android/internal/util/InlinePresentationStyleUtilsTest.java +++ b/core/tests/utiltests/src/com/android/internal/util/InlinePresentationStyleUtilsTest.java @@ -22,20 +22,28 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import android.graphics.Color; import android.os.Binder; import android.os.Bundle; +import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.internal.widget.InlinePresentationStyleUtils; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) @SmallTest +@IgnoreUnderRavenwood(blockedBy = InlinePresentationStyleUtils.class) public class InlinePresentationStyleUtilsTest { + @Rule + public final RavenwoodRule mRavenwood = new RavenwoodRule(); + @Test public void testBundleEquals_empty() { Bundle bundle1 = new Bundle(); diff --git a/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java b/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java index 0b7019995acb..0df5b0a4093e 100644 --- a/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java +++ b/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java @@ -43,6 +43,8 @@ import android.content.pm.UserInfo; import android.os.Looper; import android.os.RemoteException; import android.os.UserManager; +import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.ravenwood.RavenwoodRule; import android.provider.Settings; import android.test.mock.MockContentResolver; @@ -58,6 +60,7 @@ import com.android.internal.widget.LockPatternUtils; import com.google.android.collect.Lists; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; @@ -68,7 +71,10 @@ import java.util.List; @RunWith(AndroidJUnit4.class) @SmallTest +@IgnoreUnderRavenwood(blockedBy = LockPatternUtils.class) public class LockPatternUtilsTest { + @Rule + public final RavenwoodRule mRavenwood = new RavenwoodRule(); private static final int DEMO_USER_ID = 5; diff --git a/core/tests/utiltests/src/com/android/internal/util/MessageUtilsTest.java b/core/tests/utiltests/src/com/android/internal/util/MessageUtilsTest.java index 32b969a8d1b5..36f238e7429c 100644 --- a/core/tests/utiltests/src/com/android/internal/util/MessageUtilsTest.java +++ b/core/tests/utiltests/src/com/android/internal/util/MessageUtilsTest.java @@ -19,10 +19,13 @@ package com.android.internal.util; import static org.junit.Assert.*; import com.android.internal.util.MessageUtils; -import android.test.suitebuilder.annotation.SmallTest; +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + import android.util.SparseArray; import org.junit.Test; +import org.junit.runner.RunWith; class A { @@ -48,6 +51,7 @@ class B { * Unit tests for {@link com.android.util.MessageUtils}. */ @SmallTest +@RunWith(AndroidJUnit4.class) public class MessageUtilsTest { private static final Class[] CLASSES = { A.class, B.class }; diff --git a/core/tests/utiltests/src/com/android/internal/util/MimeIconUtilsTest.java b/core/tests/utiltests/src/com/android/internal/util/MimeIconUtilsTest.java index 4412c2c6949c..6c3479722526 100644 --- a/core/tests/utiltests/src/com/android/internal/util/MimeIconUtilsTest.java +++ b/core/tests/utiltests/src/com/android/internal/util/MimeIconUtilsTest.java @@ -16,12 +16,27 @@ package com.android.internal.util; -import junit.framework.TestCase; +import static org.junit.Assert.assertEquals; + +import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.ravenwood.RavenwoodRule; + +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; /** * Tests for {@link MimeIconUtils}. */ -public class MimeIconUtilsTest extends TestCase { +@RunWith(AndroidJUnit4.class) +@IgnoreUnderRavenwood(blockedBy = MimeIconUtils.class) +public class MimeIconUtilsTest { + @Rule + public final RavenwoodRule mRavenwood = new RavenwoodRule(); + + @Test public void testSimple() throws Exception { assertEquals("PNG image", MimeIconUtils.getTypeInfo("image/png").getLabel()); diff --git a/core/tests/utiltests/src/com/android/internal/util/ObjectUtilsTest.java b/core/tests/utiltests/src/com/android/internal/util/ObjectUtilsTest.java index 443183eeba4d..4eaacfffd433 100644 --- a/core/tests/utiltests/src/com/android/internal/util/ObjectUtilsTest.java +++ b/core/tests/utiltests/src/com/android/internal/util/ObjectUtilsTest.java @@ -15,11 +15,18 @@ */ package com.android.internal.util; -import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; +import static org.junit.Assert.assertEquals; + +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; @SmallTest -public class ObjectUtilsTest extends AndroidTestCase { +@RunWith(AndroidJUnit4.class) +public class ObjectUtilsTest { + @Test public void testCompare() { assertEquals(0, ObjectUtils.compare(null, null)); assertEquals(1, ObjectUtils.compare("a", null)); diff --git a/core/tests/utiltests/src/com/android/internal/util/ObservableServiceConnectionTest.java b/core/tests/utiltests/src/com/android/internal/util/ObservableServiceConnectionTest.java index d124ad9ddfb0..c852e9f17bc0 100644 --- a/core/tests/utiltests/src/com/android/internal/util/ObservableServiceConnectionTest.java +++ b/core/tests/utiltests/src/com/android/internal/util/ObservableServiceConnectionTest.java @@ -29,14 +29,19 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.os.IBinder; +import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; import com.android.internal.util.ObservableServiceConnection.ServiceTransformer; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -46,7 +51,12 @@ import java.util.Queue; import java.util.concurrent.Executor; @SmallTest +@RunWith(AndroidJUnit4.class) +@IgnoreUnderRavenwood(blockedBy = ObservableServiceConnection.class) public class ObservableServiceConnectionTest { + @Rule + public final RavenwoodRule mRavenwood = new RavenwoodRule(); + private static final ComponentName COMPONENT_NAME = new ComponentName("test.package", "component"); diff --git a/core/tests/utiltests/src/com/android/internal/util/PersistentServiceConnectionTest.java b/core/tests/utiltests/src/com/android/internal/util/PersistentServiceConnectionTest.java index fee46545ac62..096f303247ff 100644 --- a/core/tests/utiltests/src/com/android/internal/util/PersistentServiceConnectionTest.java +++ b/core/tests/utiltests/src/com/android/internal/util/PersistentServiceConnectionTest.java @@ -30,6 +30,10 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.os.IBinder; +import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.ravenwood.RavenwoodRule; + +import androidx.test.runner.AndroidJUnit4; import com.android.internal.util.ObservableServiceConnection.ServiceTransformer; import com.android.server.testutils.OffsettableClock; @@ -37,7 +41,9 @@ import com.android.server.testutils.TestHandler; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -45,7 +51,12 @@ import java.util.ArrayDeque; import java.util.Queue; import java.util.concurrent.Executor; +@RunWith(AndroidJUnit4.class) +@IgnoreUnderRavenwood(blockedBy = PersistentServiceConnection.class) public class PersistentServiceConnectionTest { + @Rule + public final RavenwoodRule mRavenwood = new RavenwoodRule(); + private static final ComponentName COMPONENT_NAME = new ComponentName("test.package", "component"); private static final int MAX_RETRIES = 2; diff --git a/core/tests/utiltests/src/com/android/internal/util/ProcFileReaderTest.java b/core/tests/utiltests/src/com/android/internal/util/ProcFileReaderTest.java index b93276053caf..4c00c1667e3c 100644 --- a/core/tests/utiltests/src/com/android/internal/util/ProcFileReaderTest.java +++ b/core/tests/utiltests/src/com/android/internal/util/ProcFileReaderTest.java @@ -16,7 +16,15 @@ package com.android.internal.util; -import android.test.AndroidTestCase; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; import java.io.ByteArrayInputStream; import java.io.File; @@ -28,8 +36,10 @@ import java.nio.file.Files; /** * Tests for {@link ProcFileReader}. */ -public class ProcFileReaderTest extends AndroidTestCase { +@RunWith(AndroidJUnit4.class) +public class ProcFileReaderTest { + @Test public void testEmpty() throws Exception { final ProcFileReader reader = buildReader(""); @@ -43,6 +53,7 @@ public class ProcFileReaderTest extends AndroidTestCase { assertFalse(reader.hasMoreData()); } + @Test public void testSingleString() throws Exception { final ProcFileReader reader = buildReader("a\nb\nc\n"); @@ -59,6 +70,7 @@ public class ProcFileReaderTest extends AndroidTestCase { assertFalse(reader.hasMoreData()); } + @Test public void testMixedNumbersSkip() throws Exception { final ProcFileReader reader = buildReader("1 2 3\n4 abc_def 5 6 7 8 9\n10\n"); @@ -79,6 +91,7 @@ public class ProcFileReaderTest extends AndroidTestCase { assertFalse(reader.hasMoreData()); } + @Test public void testBufferSize() throws Exception { // read numbers using very small buffer size, exercising fillBuf() final ProcFileReader reader = buildReader("1 21 3 41 5 61 7 81 9 10\n", 3); @@ -97,6 +110,7 @@ public class ProcFileReaderTest extends AndroidTestCase { assertFalse(reader.hasMoreData()); } + @Test public void testBlankLines() throws Exception { final ProcFileReader reader = buildReader("1\n\n2\n\n3\n"); @@ -117,6 +131,7 @@ public class ProcFileReaderTest extends AndroidTestCase { assertFalse(reader.hasMoreData()); } + @Test public void testMinMax() throws Exception { final ProcFileReader reader = buildReader( "1 -1024 9223372036854775807 -9223372036854775808\n"); @@ -129,6 +144,7 @@ public class ProcFileReaderTest extends AndroidTestCase { assertFalse(reader.hasMoreData()); } + @Test public void testDelimiterNeverFound() throws Exception { final ProcFileReader reader = buildReader("teststringwithoutdelimiters"); @@ -141,6 +157,7 @@ public class ProcFileReaderTest extends AndroidTestCase { } } + @Test public void testLargerThanBuffer() throws Exception { // try finishing line larger than buffer final ProcFileReader reader = buildReader("1 teststringlongerthanbuffer\n", 4); @@ -155,6 +172,7 @@ public class ProcFileReaderTest extends AndroidTestCase { } } + @Test public void testOptionalLongs() throws Exception { final ProcFileReader reader = buildReader("123 456\n789\n"); @@ -169,6 +187,7 @@ public class ProcFileReaderTest extends AndroidTestCase { assertEquals(-1L, reader.nextOptionalLong(-1L)); } + @Test public void testInvalidLongs() throws Exception { final ProcFileReader reader = buildReader("12: 34\n56 78@#\n"); @@ -183,6 +202,7 @@ public class ProcFileReaderTest extends AndroidTestCase { assertFalse(reader.hasMoreData()); } + @Test public void testConsecutiveDelimiters() throws Exception { final ProcFileReader reader = buildReader("1 2 3 4 5\n"); @@ -195,6 +215,7 @@ public class ProcFileReaderTest extends AndroidTestCase { assertFalse(reader.hasMoreData()); } + @Test public void testIgnore() throws Exception { final ProcFileReader reader = buildReader("a b c\n"); @@ -209,6 +230,7 @@ public class ProcFileReaderTest extends AndroidTestCase { assertFalse(reader.hasMoreData()); } + @Test public void testRewind() throws Exception { final ProcFileReader reader = buildReader("abc\n"); @@ -224,7 +246,7 @@ public class ProcFileReaderTest extends AndroidTestCase { assertFalse(reader.hasMoreData()); } - + @Test public void testRewindFileInputStream() throws Exception { File tempFile = File.createTempFile("procfile", null, null); Files.write(tempFile.toPath(), "abc\n".getBytes(StandardCharsets.US_ASCII)); diff --git a/core/tests/utiltests/src/com/android/internal/util/QuickSelectTest.java b/core/tests/utiltests/src/com/android/internal/util/QuickSelectTest.java index 1b9d2ef58c10..1eb5e3ab7d6c 100644 --- a/core/tests/utiltests/src/com/android/internal/util/QuickSelectTest.java +++ b/core/tests/utiltests/src/com/android/internal/util/QuickSelectTest.java @@ -16,7 +16,12 @@ package com.android.internal.util; -import junit.framework.TestCase; +import static org.junit.Assert.assertEquals; + +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; import java.util.Arrays; import java.util.List; @@ -24,8 +29,10 @@ import java.util.List; /** * Tests for {@link QuickSelect}. */ -public final class QuickSelectTest extends TestCase { +@RunWith(AndroidJUnit4.class) +public class QuickSelectTest { + @Test public void testQuickSelect() throws Exception { test((List) null, 0, null); test(Arrays.asList(), -1, null); diff --git a/core/tests/utiltests/src/com/android/internal/util/StringPoolTest.java b/core/tests/utiltests/src/com/android/internal/util/StringPoolTest.java index f67fd516fcf6..6523ed7fabb7 100644 --- a/core/tests/utiltests/src/com/android/internal/util/StringPoolTest.java +++ b/core/tests/utiltests/src/com/android/internal/util/StringPoolTest.java @@ -16,12 +16,21 @@ package com.android.internal.util; -import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertSame; + +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; @SmallTest -public final class StringPoolTest extends AndroidTestCase { +@RunWith(AndroidJUnit4.class) +public final class StringPoolTest { + @Test public void testStringPool() { StringPool stringPool = new StringPool(); String bcd = stringPool.get(new char[] { 'a', 'b', 'c', 'd', 'e' }, 1, 3); @@ -29,6 +38,7 @@ public final class StringPoolTest extends AndroidTestCase { assertSame(bcd, stringPool.get(new char[] { 'a', 'b', 'c', 'd', 'e' }, 1, 3)); } + @Test public void testHashCollision() { StringPool stringPool = new StringPool(); char[] a = { (char) 1, (char) 0 }; diff --git a/core/tests/utiltests/src/com/android/internal/util/WakeupMessageTest.java b/core/tests/utiltests/src/com/android/internal/util/WakeupMessageTest.java index 734ebef0007e..b0db8a1da3a8 100644 --- a/core/tests/utiltests/src/com/android/internal/util/WakeupMessageTest.java +++ b/core/tests/utiltests/src/com/android/internal/util/WakeupMessageTest.java @@ -24,11 +24,17 @@ import android.content.Context; import android.os.Handler; import android.os.Looper; import android.os.Message; -import android.test.suitebuilder.annotation.SmallTest; +import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.ravenwood.RavenwoodRule; + +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -40,6 +46,8 @@ import org.mockito.stubbing.Answer; * Unit tests for {@link com.android.internal.util.WakeupMessage}. */ @SmallTest +@RunWith(AndroidJUnit4.class) +@IgnoreUnderRavenwood(blockedBy = WakeupMessage.class) public class WakeupMessageTest { private static final String TEST_CMD_NAME = "TEST cmd Name"; private static final int TEST_CMD = 18; @@ -47,11 +55,16 @@ public class WakeupMessageTest { private static final int TEST_ARG2 = 182; private static final Object TEST_OBJ = "hello"; + @Rule + public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() + .setProvideMainThread(true) + .build(); + @Mock Context mContext; @Mock AlarmManager mAlarmManager; WakeupMessage mMessage; // Make a spy so that we can verify calls to it - @Spy MessageCapturingHandler mHandler = new MessageCapturingHandler(); + @Spy MessageCapturingHandler mHandler; ArgumentCaptor mListenerCaptor = ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); @@ -85,6 +98,8 @@ public class WakeupMessageTest { */ @Before public void setUp() { + mHandler = new MessageCapturingHandler(); + MockitoAnnotations.initMocks(this); when(mContext.getSystemService(Context.ALARM_SERVICE)).thenReturn(mAlarmManager); diff --git a/core/tests/utiltests/src/com/android/internal/util/XmlUtilsTest.java b/core/tests/utiltests/src/com/android/internal/util/XmlUtilsTest.java index 0484068bf900..24eb213751bc 100644 --- a/core/tests/utiltests/src/com/android/internal/util/XmlUtilsTest.java +++ b/core/tests/utiltests/src/com/android/internal/util/XmlUtilsTest.java @@ -17,13 +17,17 @@ package com.android.internal.util; import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; import android.util.Xml; +import androidx.test.runner.AndroidJUnit4; + import com.android.modules.utils.TypedXmlPullParser; import com.android.modules.utils.TypedXmlSerializer; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -32,9 +36,11 @@ import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; -public class XmlUtilsTest extends TestCase { +@RunWith(AndroidJUnit4.class) +public class XmlUtilsTest { // https://code.google.com/p/android/issues/detail?id=63717 + @Test public void testMapWithNullKeys() throws Exception { ByteArrayOutputStream baos = new ByteArrayOutputStream(1024); Map map = new HashMap(); @@ -48,6 +54,7 @@ public class XmlUtilsTest extends TestCase { assertEquals("fooValue", deserialized.get("foo")); } + @Test public void testreadWriteXmlByteArrayValue() throws Exception { byte[] testByteArray = {0x1 , 0xa, 0xb, 0x9, 0x34, (byte) 0xaa, (byte) 0xba, (byte) 0x99}; diff --git a/core/tests/utiltests/src/com/android/internal/util/test/FakeSettingsProviderTest.java b/core/tests/utiltests/src/com/android/internal/util/test/FakeSettingsProviderTest.java index f2be109c8602..502d6b6d7270 100644 --- a/core/tests/utiltests/src/com/android/internal/util/test/FakeSettingsProviderTest.java +++ b/core/tests/utiltests/src/com/android/internal/util/test/FakeSettingsProviderTest.java @@ -16,33 +16,41 @@ package com.android.internal.util.test; -import android.content.ContentResolver; -import android.database.ContentObserver; -import android.net.Uri; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import android.content.ContentProvider; +import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.ravenwood.RavenwoodRule; import android.provider.Settings; -import android.test.AndroidTestCase; import android.test.mock.MockContentResolver; -import android.test.mock.MockContext; -import android.test.suitebuilder.annotation.SmallTest; -import android.test.suitebuilder.annotation.Suppress; -import android.util.Log; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; /** * Unit tests for FakeSettingsProvider. */ -public class FakeSettingsProviderTest extends AndroidTestCase { +@RunWith(AndroidJUnit4.class) +@IgnoreUnderRavenwood(blockedBy = ContentProvider.class) +public class FakeSettingsProviderTest { + @Rule + public final RavenwoodRule mRavenwood = new RavenwoodRule(); private MockContentResolver mCr; - @Override + @Before public void setUp() throws Exception { mCr = new MockContentResolver(); mCr.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); } + @Test @SmallTest public void testBasicOperation() throws Exception { String settingName = Settings.System.SCREEN_BRIGHTNESS; diff --git a/ravenwood/framework-minus-apex-ravenwood-policies.txt b/ravenwood/framework-minus-apex-ravenwood-policies.txt index a75bba6a347f..63f687264990 100644 --- a/ravenwood/framework-minus-apex-ravenwood-policies.txt +++ b/ravenwood/framework-minus-apex-ravenwood-policies.txt @@ -81,15 +81,11 @@ class android.util.Patterns stubclass class android.util.UtilConfig stubclass # Internals -class com.android.internal.util.FastMath stubclass -class com.android.internal.util.FastPrintWriter stubclass -class com.android.internal.util.GrowingArrayUtils stubclass -class com.android.internal.util.LineBreakBufferedWriter stubclass -class com.android.internal.util.Parcelling stubclass +class com.android.internal.util.FileRotator stubclass +class com.android.internal.util.HexDump stubclass +class com.android.internal.util.MessageUtils stubclass class com.android.internal.util.Preconditions stubclass -class com.android.internal.util.StringPool stubclass - -class com.android.internal.os.SomeArgs stubclass +class com.android.internal.util.TokenBucket stubclass # Parcel class android.os.Parcel stubclass diff --git a/ravenwood/junit-src/android/platform/test/annotations/IgnoreUnderRavenwood.java b/ravenwood/junit-src/android/platform/test/annotations/IgnoreUnderRavenwood.java index edb0442e7b29..916dd5943059 100644 --- a/ravenwood/junit-src/android/platform/test/annotations/IgnoreUnderRavenwood.java +++ b/ravenwood/junit-src/android/platform/test/annotations/IgnoreUnderRavenwood.java @@ -36,7 +36,7 @@ import java.lang.annotation.Target; * * @hide */ -@Target(ElementType.METHOD) +@Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface IgnoreUnderRavenwood { /** diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java index 9db5b9895749..d175713eb92f 100644 --- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java +++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java @@ -93,7 +93,7 @@ public class RavenwoodRule implements TestRule { /** * Return if the current process is running under a Ravenwood test environment. */ - public boolean isUnderRavenwood() { + public static boolean isUnderRavenwood() { return IS_UNDER_RAVENWOOD; } @@ -102,6 +102,9 @@ public class RavenwoodRule implements TestRule { return new Statement() { @Override public void evaluate() throws Throwable { + if (description.getTestClass().getAnnotation(IgnoreUnderRavenwood.class) != null) { + Assume.assumeFalse(IS_UNDER_RAVENWOOD); + } if (description.getAnnotation(IgnoreUnderRavenwood.class) != null) { Assume.assumeFalse(IS_UNDER_RAVENWOOD); } diff --git a/ravenwood/ravenwood-annotation-allowed-classes.txt b/ravenwood/ravenwood-annotation-allowed-classes.txt index 72e9ba367bc9..0e33d5620d60 100644 --- a/ravenwood/ravenwood-annotation-allowed-classes.txt +++ b/ravenwood/ravenwood-annotation-allowed-classes.txt @@ -4,6 +4,7 @@ com.android.internal.util.ArrayUtils android.util.AtomicFile android.util.DataUnit +android.util.DumpableContainer android.util.EventLog android.util.IntArray android.util.LongArray @@ -66,3 +67,30 @@ android.graphics.Rect android.graphics.RectF com.android.server.LocalServices + +com.android.internal.os.SomeArgs + +com.android.internal.util.BitUtils +com.android.internal.util.BitwiseInputStream +com.android.internal.util.BitwiseOutputStream +com.android.internal.util.CallbackRegistry +com.android.internal.util.DumpableContainer +com.android.internal.util.dump.DumpableContainerImpl +com.android.internal.util.DumpUtils +com.android.internal.util.FastMath +com.android.internal.util.FastPrintWriter +com.android.internal.util.FileRotator +com.android.internal.util.GrowingArrayUtils +com.android.internal.util.HeavyHitterSketch +com.android.internal.util.LineBreakBufferedWriter +com.android.internal.util.ObjectUtils +com.android.internal.util.Parcelling +com.android.internal.util.ParseUtils +com.android.internal.util.ProcFileReader +com.android.internal.util.QuickSelect +com.android.internal.util.RingBuffer +com.android.internal.util.StringPool + +com.google.android.collect.Lists +com.google.android.collect.Maps +com.google.android.collect.Sets diff --git a/tools/hoststubgen/hoststubgen/helper-framework-runtime-src/libcore-fake/libcore/util/HexEncoding.java b/tools/hoststubgen/hoststubgen/helper-framework-runtime-src/libcore-fake/libcore/util/HexEncoding.java new file mode 100644 index 000000000000..cc2fb7bbf236 --- /dev/null +++ b/tools/hoststubgen/hoststubgen/helper-framework-runtime-src/libcore-fake/libcore/util/HexEncoding.java @@ -0,0 +1,240 @@ +/* + * Copyright (C) 2014 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 libcore.util; + +/** + * Hexadecimal encoding where each byte is represented by two hexadecimal digits. + * @hide + */ +public class HexEncoding { + + private static final char[] LOWER_CASE_DIGITS = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' + }; + + private static final char[] UPPER_CASE_DIGITS = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' + }; + + /** Hidden constructor to prevent instantiation. */ + private HexEncoding() {} + + /** + * Encodes the provided byte as a two-digit hexadecimal String value. + * + * @param b byte to encode + * @param upperCase {@code true} to use uppercase letters, {@code false} + * for lowercase + * @return the encoded string + * + * @hide + */ + public static String encodeToString(byte b, boolean upperCase) { + char[] digits = upperCase ? UPPER_CASE_DIGITS : LOWER_CASE_DIGITS; + char[] buf = new char[2]; // We always want two digits. + buf[0] = digits[(b >> 4) & 0xf]; + buf[1] = digits[b & 0xf]; + return new String(buf, 0, 2); + } + + /** + * Encodes the provided data as a sequence of hexadecimal characters. + * + * @param data byte array to encode + * @return the encoded data, using uppercase letters + * + * @hide + */ + public static char[] encode(byte[] data) { + return encode(data, 0, data.length, true /* upperCase */); + } + + /** + * Encodes the provided data as a sequence of hexadecimal characters. + * + * @param data byte array to encode + * @param upperCase {@code true} to use uppercase letters, {@code false} + * for lowercase + * @return the encoded data + * + * @hide + */ + public static char[] encode(byte[] data, boolean upperCase) { + return encode(data, 0, data.length, upperCase); + } + + /** + * Encodes the provided data as a sequence of hexadecimal characters. + * + * @param data byte array containing the data to encode + * @param offset offset of the data to encode in the {@code data} array + * @param len length of the data to encode in the {@code data} array + * @return the encoded data, using uppercase letters + * + * @hide + */ + public static char[] encode(byte[] data, int offset, int len) { + return encode(data, offset, len, true /* upperCase */); + } + + /** + * Encodes the provided data as a sequence of hexadecimal characters. + */ + private static char[] encode(byte[] data, int offset, int len, boolean upperCase) { + char[] digits = upperCase ? UPPER_CASE_DIGITS : LOWER_CASE_DIGITS; + char[] result = new char[len * 2]; + for (int i = 0; i < len; i++) { + byte b = data[offset + i]; + int resultIndex = 2 * i; + result[resultIndex] = (digits[(b >> 4) & 0x0f]); + result[resultIndex + 1] = (digits[b & 0x0f]); + } + + return result; + } + + /** + * Encodes the provided data as a sequence of hexadecimal characters. + * + * @param data byte array to encode + * @return the encoded data, using uppercase letters + * + * @hide + */ + public static String encodeToString(byte[] data) { + return encodeToString(data, true /* upperCase */); + } + + /** + * Encodes the provided data as a sequence of hexadecimal characters. + * + * @param data byte array to encode. + * @param upperCase {@code true} to use uppercase letters, {@code false} + * for lowercase + * @return the encoded data + * + * @hide + */ + public static String encodeToString(byte[] data, boolean upperCase) { + return new String(encode(data, upperCase)); + } + + /** + * Decodes the provided hexadecimal sequence. Odd-length inputs are not + * allowed. + * + * @param encoded string of hexadecimal characters to decode. Letters + * can be either uppercase or lowercase. + * @return the decoded data + * @throws IllegalArgumentException if the input is malformed + * + * @hide + */ + public static byte[] decode(String encoded) throws IllegalArgumentException { + return decode(encoded.toCharArray()); + } + + /** + * Decodes the provided hexadecimal sequence. + * + * @param encoded string of hexadecimal characters to decode. Letters + * can be either uppercase or lowercase. + * @param allowSingleChar If {@code true} odd-length inputs are allowed and + * the first character is interpreted as the lower bits of the first + * result byte. If {@code false} odd-length inputs are not allowed. + * @return the decoded data + * @throws IllegalArgumentException if the input is malformed + * + * @hide + */ + public static byte[] decode(String encoded, boolean allowSingleChar) + throws IllegalArgumentException { + return decode(encoded.toCharArray(), allowSingleChar); + } + + /** + * Decodes the provided hexadecimal sequence. Odd-length inputs are not + * allowed. + * + * @param encoded char array of hexadecimal characters to decode. Letters + * can be either uppercase or lowercase. + * @return the decoded data + * @throws IllegalArgumentException if the input is malformed + * + * @hide + */ + public static byte[] decode(char[] encoded) throws IllegalArgumentException { + return decode(encoded, false); + } + + /** + * Decodes the provided hexadecimal sequence. + * + * @param encoded char array of hexadecimal characters to decode. Letters + * can be either uppercase or lowercase. + * @param allowSingleChar If {@code true} odd-length inputs are allowed and + * the first character is interpreted as the lower bits of the first + * result byte. If {@code false} odd-length inputs are not allowed. + * @return the decoded data + * @throws IllegalArgumentException if the input is malformed + * + * @hide + */ + public static byte[] decode(char[] encoded, boolean allowSingleChar) + throws IllegalArgumentException { + int encodedLength = encoded.length; + int resultLengthBytes = (encodedLength + 1) / 2; + byte[] result = new byte[resultLengthBytes]; + + int resultOffset = 0; + int i = 0; + if (allowSingleChar) { + if ((encodedLength % 2) != 0) { + // Odd number of digits -- the first digit is the lower 4 bits of the first result + // byte. + result[resultOffset++] = (byte) toDigit(encoded, i); + i++; + } + } else { + if ((encodedLength % 2) != 0) { + throw new IllegalArgumentException("Invalid input length: " + encodedLength); + } + } + + for (; i < encodedLength; i += 2) { + result[resultOffset++] = (byte) ((toDigit(encoded, i) << 4) | toDigit(encoded, i + 1)); + } + + return result; + } + + private static int toDigit(char[] str, int offset) throws IllegalArgumentException { + // NOTE: that this isn't really a code point in the traditional sense, since we're + // just rejecting surrogate pairs outright. + int pseudoCodePoint = str[offset]; + + if ('0' <= pseudoCodePoint && pseudoCodePoint <= '9') { + return pseudoCodePoint - '0'; + } else if ('a' <= pseudoCodePoint && pseudoCodePoint <= 'f') { + return 10 + (pseudoCodePoint - 'a'); + } else if ('A' <= pseudoCodePoint && pseudoCodePoint <= 'F') { + return 10 + (pseudoCodePoint - 'A'); + } + + throw new IllegalArgumentException("Illegal char: " + str[offset] + " at offset " + offset); + } +} -- cgit v1.2.3-59-g8ed1b From 55066bb46fffe5d63366e230c76ec87d274761b2 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Tue, 5 Dec 2023 13:55:59 -0700 Subject: Trivial test package refactoring. These common test base classes belong under the `widget` package where they're actually used; placing them under `util` is a layering violation. Bug: 292141694 Test: TH Change-Id: I3f3e1ae1cc8e3b0f92295742483dd53c2f28cec9 --- .../coretests/src/android/util/GridScenario.java | 370 ------------ .../src/android/util/InternalSelectionView.java | 278 --------- .../coretests/src/android/util/ListScenario.java | 665 --------------------- .../src/android/util/ScrollViewScenario.java | 274 --------- .../src/android/view/menu/MenuScenario.java | 2 +- .../coretests/src/android/widget/GridScenario.java | 370 ++++++++++++ .../src/android/widget/InternalSelectionView.java | 279 +++++++++ .../coretests/src/android/widget/ListScenario.java | 660 ++++++++++++++++++++ .../src/android/widget/ScrollViewScenario.java | 275 +++++++++ .../widget/focus/AdjacentVerticalRectLists.java | 4 +- .../FocusChangeWithInterestingRectHintTest.java | 4 +- .../widget/focus/ListOfInternalSelectionViews.java | 2 +- .../ScrollingThroughListOfFocusablesTest.java | 2 +- .../src/android/widget/gridview/GridDelete.java | 2 +- .../android/widget/gridview/GridSetSelection.java | 2 +- .../widget/gridview/GridSetSelectionBaseTest.java | 2 +- .../widget/gridview/GridSetSelectionMany.java | 2 +- .../gridview/GridSetSelectionStackFromBottom.java | 2 +- .../GridSetSelectionStackFromBottomMany.java | 2 +- .../src/android/widget/gridview/GridSimple.java | 2 +- .../android/widget/gridview/GridSingleColumn.java | 2 +- .../widget/gridview/GridStackFromBottom.java | 2 +- .../widget/gridview/GridStackFromBottomMany.java | 2 +- .../widget/gridview/GridVerticalSpacing.java | 2 +- .../GridVerticalSpacingStackFromBottom.java | 2 +- .../AdjacentListsWithAdjacentISVsInside.java | 2 +- .../android/widget/listview/ListBottomGravity.java | 2 +- .../widget/listview/ListBottomGravityMany.java | 2 +- .../listview/ListButtonsDiagonalAcrossItems.java | 2 +- .../listview/ListEndingWithMultipleSeparators.java | 2 +- .../widget/listview/ListGetSelectedView.java | 2 +- .../android/widget/listview/ListHeterogeneous.java | 2 +- .../ListHorizontalFocusWithinItemWins.java | 2 +- .../widget/listview/ListInterleaveFocusables.java | 2 +- .../ListItemFocusableAboveUnfocusable.java | 2 +- .../widget/listview/ListItemFocusablesClose.java | 2 +- .../listview/ListItemFocusablesFarApart.java | 2 +- .../widget/listview/ListItemISVAndButton.java | 4 +- .../listview/ListItemsExpandOnSelection.java | 2 +- .../listview/ListLastItemPartiallyVisible.java | 2 +- .../listview/ListOfItemsShorterThanScreen.java | 2 +- .../listview/ListOfItemsTallerThanScreen.java | 2 +- .../listview/ListOfShortShortTallShortShort.java | 2 +- .../widget/listview/ListOfShortTallShort.java | 2 +- .../android/widget/listview/ListOfThinItems.java | 2 +- .../android/widget/listview/ListOfTouchables.java | 2 +- .../android/widget/listview/ListSetSelection.java | 2 +- .../src/android/widget/listview/ListSimple.java | 2 +- .../android/widget/listview/ListTopGravity.java | 2 +- .../widget/listview/ListTopGravityMany.java | 2 +- .../widget/listview/ListWithEditTextHeader.java | 2 +- .../listview/ListWithFirstScreenUnSelectable.java | 2 +- .../android/widget/listview/ListWithHeaders.java | 2 +- .../widget/listview/ListWithNoFadingEdge.java | 2 +- .../listview/ListWithOffScreenNextSelectable.java | 2 +- .../listview/ListWithOnItemSelectedAction.java | 2 +- .../listview/ListWithScreenOfNoSelectables.java | 2 +- .../widget/listview/ListWithSeparators.java | 2 +- .../AdjacentListsWithAdjacentISVsInsideTest.java | 2 +- .../ButtonAboveTallInternalSelectionView.java | 4 +- .../ButtonAboveTallInternalSelectionViewTest.java | 2 +- .../scroll/ButtonsWithTallTextViewInBetween.java | 2 +- .../src/android/widget/scroll/ShortButtons.java | 2 +- .../android/widget/scroll/TallTextAboveButton.java | 2 +- .../arrowscroll/MultiPageTextWithPadding.java | 2 +- 65 files changed, 1645 insertions(+), 1648 deletions(-) delete mode 100644 core/tests/coretests/src/android/util/GridScenario.java delete mode 100644 core/tests/coretests/src/android/util/InternalSelectionView.java delete mode 100644 core/tests/coretests/src/android/util/ListScenario.java delete mode 100644 core/tests/coretests/src/android/util/ScrollViewScenario.java create mode 100644 core/tests/coretests/src/android/widget/GridScenario.java create mode 100644 core/tests/coretests/src/android/widget/InternalSelectionView.java create mode 100644 core/tests/coretests/src/android/widget/ListScenario.java create mode 100644 core/tests/coretests/src/android/widget/ScrollViewScenario.java diff --git a/core/tests/coretests/src/android/util/GridScenario.java b/core/tests/coretests/src/android/util/GridScenario.java deleted file mode 100644 index e7ee1cd59c7c..000000000000 --- a/core/tests/coretests/src/android/util/GridScenario.java +++ /dev/null @@ -1,370 +0,0 @@ -/* - * Copyright (C) 2007 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.util; - -import android.app.Activity; -import android.os.Bundle; -import android.view.View; -import android.view.ViewGroup; -import android.view.Window; -import android.widget.AbsListView; -import android.widget.AdapterView; -import android.widget.BaseAdapter; -import android.widget.GridView; -import android.widget.ListAdapter; -import android.widget.TextView; - -import com.google.android.collect.Maps; - -import java.util.Map; - -/** - * Utility base class for creating various GridView scenarios. Configurable by the number - * of items, how tall each item should be (in relation to the screen height), and - * what item should start with selection. - */ -public abstract class GridScenario extends Activity { - - private GridView mGridView; - - private int mNumItems; - - private int mStartingSelectionPosition; - private double mItemScreenSizeFactor; - private Map mOverrideItemScreenSizeFactors = Maps.newHashMap(); - - private int mScreenHeight; - - private boolean mStackFromBottom; - - private int mColumnWidth; - - private int mNumColumns; - - private int mStretchMode; - - private int mVerticalSpacing; - - public GridView getGridView() { - return mGridView; - } - - protected int getScreenHeight() { - return mScreenHeight; - } - - /** - * @return The initial number of items in the grid as specified by the scenario. - * This number may change over time. - */ - protected int getInitialNumItems() { - return mNumItems; - } - - /** - * @return The desired height of 1 item, ignoring overrides - */ - public int getDesiredItemHeight() { - return (int) (mScreenHeight * mItemScreenSizeFactor); - } - - /** - * Better way to pass in optional params than a honkin' paramater list :) - */ - public static class Params { - private int mNumItems = 4; - private int mStartingSelectionPosition = -1; - private double mItemScreenSizeFactor = 1 / 5; - - private Map mOverrideItemScreenSizeFactors = Maps.newHashMap(); - - private boolean mStackFromBottom = false; - private boolean mMustFillScreen = true; - - private int mColumnWidth = 0; - private int mNumColumns = GridView.AUTO_FIT; - private int mStretchMode = GridView.STRETCH_COLUMN_WIDTH; - private int mVerticalSpacing = 0; - - /** - * Set the number of items in the grid. - */ - public Params setNumItems(int numItems) { - mNumItems = numItems; - return this; - } - - /** - * Set the position that starts selected. - * - * @param startingSelectionPosition The selected position within the adapter's data set. - * Pass -1 if you do not want to force a selection. - * @return - */ - public Params setStartingSelectionPosition(int startingSelectionPosition) { - mStartingSelectionPosition = startingSelectionPosition; - return this; - } - - /** - * Set the factor that determines how tall each item is in relation to the - * screen height. - */ - public Params setItemScreenSizeFactor(double itemScreenSizeFactor) { - mItemScreenSizeFactor = itemScreenSizeFactor; - return this; - } - - /** - * Override the item screen size factor for a particular item. Useful for - * creating grids with non-uniform item height. - * @param position The position in the grid. - * @param itemScreenSizeFactor The screen size factor to use for the height. - */ - public Params setPositionScreenSizeFactorOverride( - int position, double itemScreenSizeFactor) { - mOverrideItemScreenSizeFactors.put(position, itemScreenSizeFactor); - return this; - } - - /** - * Sets the stacking direction - * @param stackFromBottom - * @return - */ - public Params setStackFromBottom(boolean stackFromBottom) { - mStackFromBottom = stackFromBottom; - return this; - } - - /** - * Sets whether the sum of the height of the grid items must be at least the - * height of the grid view. - */ - public Params setMustFillScreen(boolean fillScreen) { - mMustFillScreen = fillScreen; - return this; - } - - /** - * Sets the individual width of each column. - * - * @param requestedWidth the width in pixels of the column - */ - public Params setColumnWidth(int requestedWidth) { - mColumnWidth = requestedWidth; - return this; - } - - /** - * Sets the number of columns in the grid. - */ - public Params setNumColumns(int numColumns) { - mNumColumns = numColumns; - return this; - } - - /** - * Sets the stretch mode. - */ - public Params setStretchMode(int stretchMode) { - mStretchMode = stretchMode; - return this; - } - - /** - * Sets the spacing between rows in the grid - */ - public Params setVerticalSpacing(int verticalSpacing) { - mVerticalSpacing = verticalSpacing; - return this; - } - } - - /** - * How each scenario customizes its behavior. - * @param params - */ - protected abstract void init(Params params); - - /** - * Override this to provide an different adapter for your scenario - * @return The adapter that this scenario will use - */ - protected ListAdapter createAdapter() { - return new MyAdapter(); - } - - /** - * Override this if you want to know when something has been selected (perhaps - * more importantly, that {@link android.widget.AdapterView.OnItemSelectedListener} has - * been triggered). - */ - @SuppressWarnings({ "UnusedDeclaration" }) - protected void positionSelected(int positon) { - - } - - /** - * Override this if you want to know that nothing is selected. - */ - protected void nothingSelected() { - - } - - @Override - protected void onCreate(Bundle icicle) { - super.onCreate(icicle); - - // turn off title bar - requestWindowFeature(Window.FEATURE_NO_TITLE); - - mScreenHeight = getWindowManager().getCurrentWindowMetrics().getBounds().height(); - - final Params params = new Params(); - init(params); - - readAndValidateParams(params); - - mGridView = new GridView(this); - mGridView.setLayoutParams(new ViewGroup.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT)); - mGridView.setDrawSelectorOnTop(false); - if (mNumColumns >= GridView.AUTO_FIT) { - mGridView.setNumColumns(mNumColumns); - } - if (mColumnWidth > 0) { - mGridView.setColumnWidth(mColumnWidth); - } - if (mVerticalSpacing > 0) { - mGridView.setVerticalSpacing(mVerticalSpacing); - } - mGridView.setStretchMode(mStretchMode); - mGridView.setAdapter(createAdapter()); - if (mStartingSelectionPosition >= 0) { - mGridView.setSelection(mStartingSelectionPosition); - } - mGridView.setPadding(10, 10, 10, 10); - mGridView.setStackFromBottom(mStackFromBottom); - - mGridView.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { - public void onItemSelected(AdapterView parent, View v, int position, long id) { - positionSelected(position); - } - - public void onNothingSelected(AdapterView parent) { - nothingSelected(); - } - }); - - setContentView(mGridView); - } - - - - /** - * Read in and validate all of the params passed in by the scenario. - * @param params - */ - private void readAndValidateParams(Params params) { - if (params.mMustFillScreen ) { - double totalFactor = 0.0; - for (int i = 0; i < params.mNumItems; i++) { - if (params.mOverrideItemScreenSizeFactors.containsKey(i)) { - totalFactor += params.mOverrideItemScreenSizeFactors.get(i); - } else { - totalFactor += params.mItemScreenSizeFactor; - } - } - if (totalFactor < 1.0) { - throw new IllegalArgumentException("grid items must combine to be at least " + - "the height of the screen. this is not the case with " + params.mNumItems - + " items and " + params.mItemScreenSizeFactor + " screen factor and " + - "screen height of " + mScreenHeight); - } - } - - mNumItems = params.mNumItems; - mStartingSelectionPosition = params.mStartingSelectionPosition; - mItemScreenSizeFactor = params.mItemScreenSizeFactor; - - mOverrideItemScreenSizeFactors.putAll(params.mOverrideItemScreenSizeFactors); - - mStackFromBottom = params.mStackFromBottom; - mColumnWidth = params.mColumnWidth; - mNumColumns = params.mNumColumns; - mStretchMode = params.mStretchMode; - mVerticalSpacing = params.mVerticalSpacing; - } - - public final String getValueAtPosition(int position) { - return "postion " + position; - } - - /** - * Create a view for a grid item. Override this to create a custom view beyond - * the simple focusable / unfocusable text view. - * @param position The position. - * @param parent The parent - * @param desiredHeight The height the view should be to respect the desired item - * to screen height ratio. - * @return a view for the grid. - */ - protected View createView(int position, ViewGroup parent, int desiredHeight) { - TextView result = new TextView(parent.getContext()); - result.setHeight(desiredHeight); - result.setText(getValueAtPosition(position)); - final ViewGroup.LayoutParams lp = new AbsListView.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.WRAP_CONTENT); - result.setLayoutParams(lp); - result.setId(position); - result.setBackgroundColor(0x55ffffff); - return result; - } - - - - private class MyAdapter extends BaseAdapter { - public int getCount() { - return mNumItems; - } - - public Object getItem(int position) { - return getValueAtPosition(position); - } - - public long getItemId(int position) { - return position; - } - - public View getView(int position, View convertView, ViewGroup parent) { - if (convertView != null) { - ((TextView) convertView).setText(getValueAtPosition(position)); - convertView.setId(position); - return convertView; - } - - int desiredHeight = getDesiredItemHeight(); - if (mOverrideItemScreenSizeFactors.containsKey(position)) { - desiredHeight = (int) (mScreenHeight * mOverrideItemScreenSizeFactors.get(position)); - } - return createView(position, parent, desiredHeight); - } - } -} diff --git a/core/tests/coretests/src/android/util/InternalSelectionView.java b/core/tests/coretests/src/android/util/InternalSelectionView.java deleted file mode 100644 index 4a1baef8077a..000000000000 --- a/core/tests/coretests/src/android/util/InternalSelectionView.java +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Copyright (C) 2007 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.util; - -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.graphics.Rect; -import android.view.KeyEvent; -import android.view.View; - -import com.android.frameworks.coretests.R; - -/** - * A view that has a known number of selectable rows, and maintains a notion of which - * row is selected. The rows take up the - * entire width of the view. The height of the view is divided evenly among - * the rows. - * - * Note: If the height of the view does not divide exactly to the number of rows, - * the last row's height is inflated with the remainder. For example, if the - * view height is 22 and there are two rows, the height of the first row is - * 10 and the second 22. - * - * Notice what this view does to be a good citizen w.r.t its internal selection: - * 1) calls {@link View#requestRectangleOnScreen} each time the selection changes due to - * internal navigation. - * 2) implements {@link View#getFocusedRect} by filling in the rectangle of the currently - * selected row - * 3) overrides {@link View#onFocusChanged} and sets selection appropriately according to - * the previously focused rectangle. - */ -public class InternalSelectionView extends View { - - private Paint mPainter = new Paint(); - private Paint mTextPaint = new Paint(); - private Rect mTempRect = new Rect(); - - private int mNumRows = 5; - private int mSelectedRow = 0; - private final int mEstimatedPixelHeight = 10; - - private Integer mDesiredHeight = null; - private String mLabel = null; - - public InternalSelectionView(Context context, int numRows, String label) { - super(context); - mNumRows = numRows; - mLabel = label; - init(); - } - - public InternalSelectionView(Context context, AttributeSet attrs) { - super(context, attrs); - TypedArray a = - context.obtainStyledAttributes( - attrs, R.styleable.SelectableRowView); - mNumRows = a.getInt(R.styleable.SelectableRowView_numRows, 5); - init(); - } - - private void init() { - setFocusable(true); - mTextPaint.setAntiAlias(true); - mTextPaint.setTextSize(10); - mTextPaint.setColor(Color.WHITE); - } - - public int getNumRows() { - return mNumRows; - } - - public int getSelectedRow() { - return mSelectedRow; - } - - public void setDesiredHeight(int desiredHeight) { - mDesiredHeight = desiredHeight; - } - - public String getLabel() { - return mLabel; - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - setMeasuredDimension( - measureWidth(widthMeasureSpec), - measureHeight(heightMeasureSpec)); - } - - private int measureWidth(int measureSpec) { - int specMode = MeasureSpec.getMode(measureSpec); - int specSize = MeasureSpec.getSize(measureSpec); - - int desiredWidth = 300 + mPaddingLeft + mPaddingRight; - if (specMode == MeasureSpec.EXACTLY) { - // We were told how big to be - return specSize; - } else if (specMode == MeasureSpec.AT_MOST) { - return desiredWidth < specSize ? desiredWidth : specSize; - } else { - return desiredWidth; - } - } - - private int measureHeight(int measureSpec) { - int specMode = MeasureSpec.getMode(measureSpec); - int specSize = MeasureSpec.getSize(measureSpec); - - int desiredHeight = mDesiredHeight != null ? - mDesiredHeight : - mNumRows * mEstimatedPixelHeight + mPaddingTop + mPaddingBottom; - if (specMode == MeasureSpec.EXACTLY) { - // We were told how big to be - return specSize; - } else if (specMode == MeasureSpec.AT_MOST) { - return desiredHeight < specSize ? desiredHeight : specSize; - } else { - return desiredHeight; - } - } - - - @Override - protected void onDraw(Canvas canvas) { - int rectTop = mPaddingTop; - int rectLeft = mPaddingLeft; - int rectRight = getWidth() - mPaddingRight; - for (int i = 0; i < mNumRows; i++) { - - mPainter.setColor(Color.BLACK); - mPainter.setAlpha(0x20); - - int rowHeight = getRowHeight(i); - - // draw background rect - mTempRect.set(rectLeft, rectTop, rectRight, rectTop + rowHeight); - canvas.drawRect(mTempRect, mPainter); - - // draw forground rect - if (i == mSelectedRow && hasFocus()) { - mPainter.setColor(Color.RED); - mPainter.setAlpha(0xF0); - mTextPaint.setAlpha(0xFF); - } else { - mPainter.setColor(Color.BLACK); - mPainter.setAlpha(0x40); - mTextPaint.setAlpha(0xF0); - } - mTempRect.set(rectLeft + 2, rectTop + 2, - rectRight - 2, rectTop + rowHeight - 2); - canvas.drawRect(mTempRect, mPainter); - - // draw text to help when visually inspecting - canvas.drawText( - Integer.toString(i), - rectLeft + 2, - rectTop + 2 - (int) mTextPaint.ascent(), - mTextPaint); - - rectTop += rowHeight; - } - } - - private int getRowHeight(int row) { - final int availableHeight = getHeight() - mPaddingTop - mPaddingBottom; - final int desiredRowHeight = availableHeight / mNumRows; - if (row < mNumRows - 1) { - return desiredRowHeight; - } else { - final int residualHeight = availableHeight % mNumRows; - return desiredRowHeight + residualHeight; - } - } - - public void getRectForRow(Rect rect, int row) { - final int rowHeight = getRowHeight(row); - final int top = mPaddingTop + row * rowHeight; - rect.set(mPaddingLeft, - top, - getWidth() - mPaddingRight, - top + rowHeight); - } - - - void ensureRectVisible() { - getRectForRow(mTempRect, mSelectedRow); - requestRectangleOnScreen(mTempRect); - } - - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - switch(event.getKeyCode()) { - case KeyEvent.KEYCODE_DPAD_UP: - if (mSelectedRow > 0) { - mSelectedRow--; - invalidate(); - ensureRectVisible(); - return true; - } - break; - case KeyEvent.KEYCODE_DPAD_DOWN: - if (mSelectedRow < (mNumRows - 1)) { - mSelectedRow++; - invalidate(); - ensureRectVisible(); - return true; - } - break; - } - return false; - } - - - @Override - public void getFocusedRect(Rect r) { - getRectForRow(r, mSelectedRow); - } - - @Override - protected void onFocusChanged(boolean focused, int direction, - Rect previouslyFocusedRect) { - super.onFocusChanged(focused, direction, previouslyFocusedRect); - - if (focused) { - switch (direction) { - case View.FOCUS_DOWN: - mSelectedRow = 0; - break; - case View.FOCUS_UP: - mSelectedRow = mNumRows - 1; - break; - case View.FOCUS_LEFT: // fall through - case View.FOCUS_RIGHT: - // set the row that is closest to the rect - if (previouslyFocusedRect != null) { - int y = previouslyFocusedRect.top - + (previouslyFocusedRect.height() / 2); - int yPerRow = getHeight() / mNumRows; - mSelectedRow = y / yPerRow; - } else { - mSelectedRow = 0; - } - break; - default: - // can't gleam any useful information about what internal - // selection should be... - return; - } - invalidate(); - } - } - - @Override - public String toString() { - if (mLabel != null) { - return mLabel; - } - return super.toString(); - } -} diff --git a/core/tests/coretests/src/android/util/ListScenario.java b/core/tests/coretests/src/android/util/ListScenario.java deleted file mode 100644 index 74dc4b4b34a1..000000000000 --- a/core/tests/coretests/src/android/util/ListScenario.java +++ /dev/null @@ -1,665 +0,0 @@ -/* - * Copyright (C) 2007 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.util; - -import android.app.Activity; -import android.graphics.Rect; -import android.os.Bundle; -import android.view.View; -import android.view.ViewGroup; -import android.view.Window; -import android.widget.AdapterView; -import android.widget.BaseAdapter; -import android.widget.EditText; -import android.widget.LinearLayout; -import android.widget.ListView; -import android.widget.TextView; - -import com.google.android.collect.Maps; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * Utility base class for creating various List scenarios. Configurable by the number - * of items, how tall each item should be (in relation to the screen height), and - * what item should start with selection. - */ -public abstract class ListScenario extends Activity { - - private ListView mListView; - private TextView mHeaderTextView; - - private int mNumItems; - protected boolean mItemsFocusable; - - private int mStartingSelectionPosition; - private double mItemScreenSizeFactor; - private Map mOverrideItemScreenSizeFactors = Maps.newHashMap(); - - private int mScreenHeight; - - // whether to include a text view above the list - private boolean mIncludeHeader; - - // separators - private Set mUnselectableItems = new HashSet(); - - private boolean mStackFromBottom; - - private int mClickedPosition = -1; - - private int mLongClickedPosition = -1; - - private int mConvertMisses = 0; - - private int mHeaderViewCount; - private boolean mHeadersFocusable; - - private int mFooterViewCount; - private LinearLayout mLinearLayout; - - public ListView getListView() { - return mListView; - } - - protected int getScreenHeight() { - return mScreenHeight; - } - - /** - * Return whether the item at position is selectable (i.e is a separator). - * (external users can access this info using the adapter) - */ - private boolean isItemAtPositionSelectable(int position) { - return !mUnselectableItems.contains(position); - } - - /** - * Better way to pass in optional params than a honkin' paramater list :) - */ - public static class Params { - private int mNumItems = 4; - private boolean mItemsFocusable = false; - private int mStartingSelectionPosition = 0; - private double mItemScreenSizeFactor = 1 / 5; - private Double mFadingEdgeScreenSizeFactor = null; - - private Map mOverrideItemScreenSizeFactors = Maps.newHashMap(); - - // separators - private List mUnselectableItems = new ArrayList(8); - // whether to include a text view above the list - private boolean mIncludeHeader = false; - private boolean mStackFromBottom = false; - public boolean mMustFillScreen = true; - private int mHeaderViewCount; - private boolean mHeaderFocusable = false; - private int mFooterViewCount; - - private boolean mConnectAdapter = true; - - /** - * Set the number of items in the list. - */ - public Params setNumItems(int numItems) { - mNumItems = numItems; - return this; - } - - /** - * Set whether the items are focusable. - */ - public Params setItemsFocusable(boolean itemsFocusable) { - mItemsFocusable = itemsFocusable; - return this; - } - - /** - * Set the position that starts selected. - * - * @param startingSelectionPosition The selected position within the adapter's data set. - * Pass -1 if you do not want to force a selection. - * @return - */ - public Params setStartingSelectionPosition(int startingSelectionPosition) { - mStartingSelectionPosition = startingSelectionPosition; - return this; - } - - /** - * Set the factor that determines how tall each item is in relation to the - * screen height. - */ - public Params setItemScreenSizeFactor(double itemScreenSizeFactor) { - mItemScreenSizeFactor = itemScreenSizeFactor; - return this; - } - - /** - * Override the item screen size factor for a particular item. Useful for - * creating lists with non-uniform item height. - * @param position The position in the list. - * @param itemScreenSizeFactor The screen size factor to use for the height. - */ - public Params setPositionScreenSizeFactorOverride( - int position, double itemScreenSizeFactor) { - mOverrideItemScreenSizeFactors.put(position, itemScreenSizeFactor); - return this; - } - - /** - * Set a position as unselectable (a.k.a a separator) - * @param position - * @return - */ - public Params setPositionUnselectable(int position) { - mUnselectableItems.add(position); - return this; - } - - /** - * Set positions as unselectable (a.k.a a separator) - */ - public Params setPositionsUnselectable(int ...positions) { - for (int pos : positions) { - setPositionUnselectable(pos); - } - return this; - } - - /** - * Include a header text view above the list. - * @param includeHeader - * @return - */ - public Params includeHeaderAboveList(boolean includeHeader) { - mIncludeHeader = includeHeader; - return this; - } - - /** - * Sets the stacking direction - * @param stackFromBottom - * @return - */ - public Params setStackFromBottom(boolean stackFromBottom) { - mStackFromBottom = stackFromBottom; - return this; - } - - /** - * Sets whether the sum of the height of the list items must be at least the - * height of the list view. - */ - public Params setMustFillScreen(boolean fillScreen) { - mMustFillScreen = fillScreen; - return this; - } - - /** - * Set the factor for the fading edge length. - */ - public Params setFadingEdgeScreenSizeFactor(double fadingEdgeScreenSizeFactor) { - mFadingEdgeScreenSizeFactor = fadingEdgeScreenSizeFactor; - return this; - } - - /** - * Set the number of header views to appear within the list - */ - public Params setHeaderViewCount(int headerViewCount) { - mHeaderViewCount = headerViewCount; - return this; - } - - /** - * Set whether the headers should be focusable. - * @param headerFocusable Whether the headers should be focusable (i.e - * created as edit texts rather than text views). - */ - public Params setHeaderFocusable(boolean headerFocusable) { - mHeaderFocusable = headerFocusable; - return this; - } - - /** - * Set the number of footer views to appear within the list - */ - public Params setFooterViewCount(int footerViewCount) { - mFooterViewCount = footerViewCount; - return this; - } - - /** - * Sets whether the {@link ListScenario} will automatically set the - * adapter on the list view. If this is false, the client MUST set it - * manually (this is useful when adding headers to the list view, which - * must be done before the adapter is set). - */ - public Params setConnectAdapter(boolean connectAdapter) { - mConnectAdapter = connectAdapter; - return this; - } - } - - /** - * How each scenario customizes its behavior. - * @param params - */ - protected abstract void init(Params params); - - /** - * Override this if you want to know when something has been selected (perhaps - * more importantly, that {@link android.widget.AdapterView.OnItemSelectedListener} has - * been triggered). - */ - protected void positionSelected(int positon) { - } - - /** - * Override this if you want to know that nothing is selected. - */ - protected void nothingSelected() { - } - - /** - * Override this if you want to know when something has been clicked (perhaps - * more importantly, that {@link android.widget.AdapterView.OnItemClickListener} has - * been triggered). - */ - protected void positionClicked(int position) { - setClickedPosition(position); - } - - /** - * Override this if you want to know when something has been long clicked (perhaps - * more importantly, that {@link android.widget.AdapterView.OnItemLongClickListener} has - * been triggered). - */ - protected void positionLongClicked(int position) { - setLongClickedPosition(position); - } - - @Override - protected void onCreate(Bundle icicle) { - super.onCreate(icicle); - - // for test stability, turn off title bar - requestWindowFeature(Window.FEATURE_NO_TITLE); - - - mScreenHeight = getWindowManager().getCurrentWindowMetrics().getBounds().height(); - - final Params params = createParams(); - init(params); - - readAndValidateParams(params); - - - mListView = createListView(); - mListView.setLayoutParams(new ViewGroup.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT)); - mListView.setDrawSelectorOnTop(false); - - for (int i=0; i= 0) { - mListView.setSelection(mStartingSelectionPosition); - } - mListView.setPadding(0, 0, 0, 0); - mListView.setStackFromBottom(mStackFromBottom); - mListView.setDivider(null); - - mListView.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { - public void onItemSelected(AdapterView parent, View v, int position, long id) { - positionSelected(position); - } - - public void onNothingSelected(AdapterView parent) { - nothingSelected(); - } - }); - - mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { - public void onItemClick(AdapterView parent, View v, int position, long id) { - positionClicked(position); - } - }); - - // set the fading edge length porportionally to the screen - // height for test stability - if (params.mFadingEdgeScreenSizeFactor != null) { - mListView.setFadingEdgeLength( - (int) (params.mFadingEdgeScreenSizeFactor * mScreenHeight)); - } else { - mListView.setFadingEdgeLength((int) ((64.0 / 480) * mScreenHeight)); - } - - if (mIncludeHeader) { - mLinearLayout = new LinearLayout(this); - - mHeaderTextView = new TextView(this); - mHeaderTextView.setText("hi"); - mHeaderTextView.setLayoutParams(new LinearLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.WRAP_CONTENT)); - mLinearLayout.addView(mHeaderTextView); - - mLinearLayout.setOrientation(LinearLayout.VERTICAL); - mLinearLayout.setLayoutParams(new ViewGroup.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT)); - mListView.setLayoutParams((new LinearLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - 0, - 1f))); - - mLinearLayout.addView(mListView); - setContentView(mLinearLayout); - } else { - mLinearLayout = new LinearLayout(this); - mLinearLayout.setOrientation(LinearLayout.VERTICAL); - mLinearLayout.setLayoutParams(new ViewGroup.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT)); - mListView.setLayoutParams((new LinearLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - 0, - 1f))); - mLinearLayout.addView(mListView); - setContentView(mLinearLayout); - } - mLinearLayout.restoreDefaultFocus(); - } - - /** - * Returns the LinearLayout containing the ListView in this scenario. - * - * @return The LinearLayout in which the ListView is held. - */ - protected LinearLayout getListViewContainer() { - return mLinearLayout; - } - - /** - * Attaches a long press listener. You can find out which views were clicked by calling - * {@link #getLongClickedPosition()}. - */ - public void enableLongPress() { - mListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { - public boolean onItemLongClick(AdapterView parent, View v, int position, long id) { - positionLongClicked(position); - return true; - } - }); - } - - /** - * @return The newly created ListView widget. - */ - protected ListView createListView() { - return new ListView(this); - } - - /** - * @return The newly created Params object. - */ - protected Params createParams() { - return new Params(); - } - - /** - * Sets an adapter on a ListView. - * - * @param listView The ListView to set the adapter on. - */ - protected void setAdapter(ListView listView) { - listView.setAdapter(new MyAdapter()); - } - - /** - * Read in and validate all of the params passed in by the scenario. - * @param params - */ - protected void readAndValidateParams(Params params) { - if (params.mMustFillScreen ) { - double totalFactor = 0.0; - for (int i = 0; i < params.mNumItems; i++) { - if (params.mOverrideItemScreenSizeFactors.containsKey(i)) { - totalFactor += params.mOverrideItemScreenSizeFactors.get(i); - } else { - totalFactor += params.mItemScreenSizeFactor; - } - } - if (totalFactor < 1.0) { - throw new IllegalArgumentException("list items must combine to be at least " + - "the height of the screen. this is not the case with " + params.mNumItems - + " items and " + params.mItemScreenSizeFactor + " screen factor and " + - "screen height of " + mScreenHeight); - } - } - - mNumItems = params.mNumItems; - mItemsFocusable = params.mItemsFocusable; - mStartingSelectionPosition = params.mStartingSelectionPosition; - mItemScreenSizeFactor = params.mItemScreenSizeFactor; - - mOverrideItemScreenSizeFactors.putAll(params.mOverrideItemScreenSizeFactors); - - mUnselectableItems.addAll(params.mUnselectableItems); - mIncludeHeader = params.mIncludeHeader; - mStackFromBottom = params.mStackFromBottom; - mHeaderViewCount = params.mHeaderViewCount; - mHeadersFocusable = params.mHeaderFocusable; - mFooterViewCount = params.mFooterViewCount; - } - - public final String getValueAtPosition(int position) { - return isItemAtPositionSelectable(position) - ? - "position " + position: - "------- " + position; - } - - /** - * @return The height that will be set for a particular position. - */ - public int getHeightForPosition(int position) { - int desiredHeight = (int) (mScreenHeight * mItemScreenSizeFactor); - if (mOverrideItemScreenSizeFactors.containsKey(position)) { - desiredHeight = (int) (mScreenHeight * mOverrideItemScreenSizeFactors.get(position)); - } - return desiredHeight; - } - - - /** - * @return The contents of the header above the list. - * @throws IllegalArgumentException if there is no header. - */ - public final String getHeaderValue() { - if (!mIncludeHeader) { - throw new IllegalArgumentException("no header above list"); - } - return mHeaderTextView.getText().toString(); - } - - /** - * @param value What to put in the header text view - * @throws IllegalArgumentException if there is no header. - */ - protected final void setHeaderValue(String value) { - if (!mIncludeHeader) { - throw new IllegalArgumentException("no header above list"); - } - mHeaderTextView.setText(value); - } - - /** - * Create a view for a list item. Override this to create a custom view beyond - * the simple focusable / unfocusable text view. - * @param position The position. - * @param parent The parent - * @param desiredHeight The height the view should be to respect the desired item - * to screen height ratio. - * @return a view for the list. - */ - protected View createView(int position, ViewGroup parent, int desiredHeight) { - return ListItemFactory.text(position, parent.getContext(), getValueAtPosition(position), - desiredHeight); - } - - /** - * Convert a non-null view. - */ - public View convertView(int position, View convertView, ViewGroup parent) { - return ListItemFactory.convertText(convertView, getValueAtPosition(position), position); - } - - public void setClickedPosition(int clickedPosition) { - mClickedPosition = clickedPosition; - } - - public int getClickedPosition() { - return mClickedPosition; - } - - public void setLongClickedPosition(int longClickedPosition) { - mLongClickedPosition = longClickedPosition; - } - - public int getLongClickedPosition() { - return mLongClickedPosition; - } - - /** - * Have a child of the list view call {@link View#requestRectangleOnScreen(android.graphics.Rect)}. - * @param childIndex The index into the viewgroup children (i.e the children that are - * currently visible). - * @param rect The rectangle, in the child's coordinates. - */ - public void requestRectangleOnScreen(int childIndex, final Rect rect) { - final View child = getListView().getChildAt(childIndex); - - child.post(new Runnable() { - public void run() { - child.requestRectangleOnScreen(rect); - } - }); - } - - /** - * Return an item type for the specified position in the adapter. Override if your - * adapter creates more than one type. - */ - public int getItemViewType(int position) { - return 0; - } - - /** - * Return the number of types created by the adapter. Override if your - * adapter creates more than one type. - */ - public int getViewTypeCount() { - return 1; - } - - /** - * @return The number of times convertView failed - */ - public int getConvertMisses() { - return mConvertMisses; - } - - private class MyAdapter extends BaseAdapter { - - public int getCount() { - return mNumItems; - } - - public Object getItem(int position) { - return getValueAtPosition(position); - } - - public long getItemId(int position) { - return position; - } - - @Override - public boolean areAllItemsEnabled() { - return mUnselectableItems.isEmpty(); - } - - @Override - public boolean isEnabled(int position) { - return isItemAtPositionSelectable(position); - } - - public View getView(int position, View convertView, ViewGroup parent) { - View result = null; - if (position >= mNumItems || position < 0) { - throw new IllegalStateException("position out of range for adapter!"); - } - - if (convertView != null) { - result = convertView(position, convertView, parent); - if (result == null) { - mConvertMisses++; - } - } - - if (result == null) { - int desiredHeight = getHeightForPosition(position); - result = createView(position, parent, desiredHeight); - } - return result; - } - - @Override - public int getItemViewType(int position) { - return ListScenario.this.getItemViewType(position); - } - - @Override - public int getViewTypeCount() { - return ListScenario.this.getViewTypeCount(); - } - - } -} diff --git a/core/tests/coretests/src/android/util/ScrollViewScenario.java b/core/tests/coretests/src/android/util/ScrollViewScenario.java deleted file mode 100644 index ab1a642a9327..000000000000 --- a/core/tests/coretests/src/android/util/ScrollViewScenario.java +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Copyright (C) 2008 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.util; - -import android.app.Activity; -import android.content.Context; -import android.os.Bundle; -import android.view.View; -import android.view.ViewGroup; -import android.view.Window; -import android.widget.Button; -import android.widget.LinearLayout; -import android.widget.ScrollView; -import android.widget.TextView; - -import com.google.android.collect.Lists; - -import java.util.List; - -/** - * Utility base class for creating scroll view scenarios, allowing you to add - * a series of different kinds of views arranged vertically, taking up a - * specified amount of the screen height. - */ -public abstract class ScrollViewScenario extends Activity { - - /** - * Holds content of scroll view - */ - private LinearLayout mLinearLayout; - - /** - * The actual scroll view - */ - private ScrollView mScrollView; - - - /** - * What we need of each view that the user wants: the view, and the ratio - * to the screen height for its desired height. - */ - private interface ViewFactory { - View create(final Context context); - - float getHeightRatio(); - } - - /** - * Partially implement ViewFactory given a height ratio. - * A negative height ratio means that WRAP_CONTENT will be used as height - */ - private static abstract class ViewFactoryBase implements ViewFactory { - - private float mHeightRatio; - - @SuppressWarnings({"UnusedDeclaration"}) - private ViewFactoryBase() {throw new UnsupportedOperationException("don't call this!");} - - protected ViewFactoryBase(float heightRatio) { - mHeightRatio = heightRatio; - } - - public float getHeightRatio() { - return mHeightRatio; - } - } - - /** - * Builder for selecting the views to be vertically arranged in the scroll - * view. - */ - @SuppressWarnings({"JavaDoc"}) - public static class Params { - - List mViewFactories = Lists.newArrayList(); - - int mTopPadding = 0; - int mBottomPadding = 0; - - /** - * Add a text view. - * @param text The text of the text view. - * @param heightRatio The view's height will be this * the screen height. - */ - public Params addTextView(final String text, float heightRatio) { - mViewFactories.add(new ViewFactoryBase(heightRatio) { - public View create(final Context context) { - final TextView tv = new TextView(context); - tv.setText(text); - return tv; - } - }); - return this; - } - - /** - * Add multiple text views. - * @param numViews the number of views to add. - * @param textPrefix The text to prepend to each text view. - * @param heightRatio The view's height will be this * the screen height. - */ - public Params addTextViews(int numViews, String textPrefix, float heightRatio) { - for (int i = 0; i < numViews; i++) { - addTextView(textPrefix + i, heightRatio); - } - return this; - } - - /** - * Add a button. - * @param text The text of the button. - * @param heightRatio The view's height will be this * the screen height. - */ - public Params addButton(final String text, float heightRatio) { - mViewFactories.add(new ViewFactoryBase(heightRatio) { - public View create(final Context context) { - final Button button = new Button(context); - button.setText(text); - return button; - } - }); - return this; - } - - /** - * Add multiple buttons. - * @param numButtons the number of views to add. - * @param textPrefix The text to prepend to each button. - * @param heightRatio The view's height will be this * the screen height. - */ - public Params addButtons(int numButtons, String textPrefix, float heightRatio) { - for (int i = 0; i < numButtons; i++) { - addButton(textPrefix + i, heightRatio); - } - return this; - } - - /** - * Add an {@link InternalSelectionView}. - * @param numRows The number of rows in the internal selection view. - * @param heightRatio The view's height will be this * the screen height. - */ - public Params addInternalSelectionView(final int numRows, float heightRatio) { - mViewFactories.add(new ViewFactoryBase(heightRatio) { - public View create(final Context context) { - return new InternalSelectionView(context, numRows, "isv"); - } - }); - return this; - } - - /** - * Add a sublayout of buttons as a single child of the scroll view. - * @param numButtons The number of buttons in the sub layout - * @param heightRatio The layout's height will be this * the screen height. - */ - public Params addVerticalLLOfButtons(final String prefix, final int numButtons, float heightRatio) { - mViewFactories.add(new ViewFactoryBase(heightRatio) { - - public View create(Context context) { - final LinearLayout ll = new LinearLayout(context); - ll.setOrientation(LinearLayout.VERTICAL); - - // fill width, equally weighted on height - final LinearLayout.LayoutParams lp = - new LinearLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, 0, 1f); - for (int i = 0; i < numButtons; i++) { - final Button button = new Button(context); - button.setText(prefix + i); - ll.addView(button, lp); - } - - return ll; - } - }); - return this; - } - - public Params addPaddingToScrollView(int topPadding, int bottomPadding) { - mTopPadding = topPadding; - mBottomPadding = bottomPadding; - - return this; - } - } - - /** - * Override this and initialized the views in the scroll view. - * @param params Used to configure the contents of the scroll view. - */ - protected abstract void init(Params params); - - public LinearLayout getLinearLayout() { - return mLinearLayout; - } - - public ScrollView getScrollView() { - return mScrollView; - } - - /** - * Get the child contained within the vertical linear layout of the - * scroll view. - * @param index The index within the linear layout. - * @return the child within the vertical linear layout of the scroll view - * at the specified index. - */ - @SuppressWarnings({"unchecked"}) - public T getContentChildAt(int index) { - return (T) mLinearLayout.getChildAt(index); - } - - /** - * Hook for changing how scroll view's are created. - */ - @SuppressWarnings({"JavaDoc"}) - protected ScrollView createScrollView() { - return new ScrollView(this); - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - // for test stability, turn off title bar - requestWindowFeature(Window.FEATURE_NO_TITLE); - int screenHeight = getWindowManager().getCurrentWindowMetrics().getBounds().height() - - 25; - mLinearLayout = new LinearLayout(this); - mLinearLayout.setOrientation(LinearLayout.VERTICAL); - - // initialize params - final Params params = new Params(); - init(params); - - // create views specified by params - for (ViewFactory viewFactory : params.mViewFactories) { - int height = ViewGroup.LayoutParams.WRAP_CONTENT; - if (viewFactory.getHeightRatio() >= 0) { - height = (int) (viewFactory.getHeightRatio() * screenHeight); - } - final LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, height); - mLinearLayout.addView(viewFactory.create(this), lp); - } - - mScrollView = createScrollView(); - mScrollView.setPadding(0, params.mTopPadding, 0, params.mBottomPadding); - mScrollView.addView(mLinearLayout, new ViewGroup.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT)); - - // no animation to speed up tests - mScrollView.setSmoothScrollingEnabled(false); - - setContentView(mScrollView); - mScrollView.post(() -> mScrollView.restoreDefaultFocus()); - } -} diff --git a/core/tests/coretests/src/android/view/menu/MenuScenario.java b/core/tests/coretests/src/android/view/menu/MenuScenario.java index 668aec4eb18f..a1615afe4fa3 100644 --- a/core/tests/coretests/src/android/view/menu/MenuScenario.java +++ b/core/tests/coretests/src/android/view/menu/MenuScenario.java @@ -18,7 +18,7 @@ package android.view.menu; import android.app.Activity; import android.os.Bundle; -import android.util.ListScenario; +import android.widget.ListScenario; import android.util.SparseArray; import android.view.Menu; import android.view.MenuItem; diff --git a/core/tests/coretests/src/android/widget/GridScenario.java b/core/tests/coretests/src/android/widget/GridScenario.java new file mode 100644 index 000000000000..d74080863895 --- /dev/null +++ b/core/tests/coretests/src/android/widget/GridScenario.java @@ -0,0 +1,370 @@ +/* + * Copyright (C) 2023 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.widget; + +import android.app.Activity; +import android.os.Bundle; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.widget.AbsListView; +import android.widget.AdapterView; +import android.widget.BaseAdapter; +import android.widget.GridView; +import android.widget.ListAdapter; +import android.widget.TextView; + +import com.google.android.collect.Maps; + +import java.util.Map; + +/** + * Utility base class for creating various GridView scenarios. Configurable by the number + * of items, how tall each item should be (in relation to the screen height), and + * what item should start with selection. + */ +public abstract class GridScenario extends Activity { + + private GridView mGridView; + + private int mNumItems; + + private int mStartingSelectionPosition; + private double mItemScreenSizeFactor; + private Map mOverrideItemScreenSizeFactors = Maps.newHashMap(); + + private int mScreenHeight; + + private boolean mStackFromBottom; + + private int mColumnWidth; + + private int mNumColumns; + + private int mStretchMode; + + private int mVerticalSpacing; + + public GridView getGridView() { + return mGridView; + } + + protected int getScreenHeight() { + return mScreenHeight; + } + + /** + * @return The initial number of items in the grid as specified by the scenario. + * This number may change over time. + */ + protected int getInitialNumItems() { + return mNumItems; + } + + /** + * @return The desired height of 1 item, ignoring overrides + */ + public int getDesiredItemHeight() { + return (int) (mScreenHeight * mItemScreenSizeFactor); + } + + /** + * Better way to pass in optional params than a honkin' paramater list :) + */ + public static class Params { + private int mNumItems = 4; + private int mStartingSelectionPosition = -1; + private double mItemScreenSizeFactor = 1 / 5; + + private Map mOverrideItemScreenSizeFactors = Maps.newHashMap(); + + private boolean mStackFromBottom = false; + private boolean mMustFillScreen = true; + + private int mColumnWidth = 0; + private int mNumColumns = GridView.AUTO_FIT; + private int mStretchMode = GridView.STRETCH_COLUMN_WIDTH; + private int mVerticalSpacing = 0; + + /** + * Set the number of items in the grid. + */ + public Params setNumItems(int numItems) { + mNumItems = numItems; + return this; + } + + /** + * Set the position that starts selected. + * + * @param startingSelectionPosition The selected position within the adapter's data set. + * Pass -1 if you do not want to force a selection. + * @return + */ + public Params setStartingSelectionPosition(int startingSelectionPosition) { + mStartingSelectionPosition = startingSelectionPosition; + return this; + } + + /** + * Set the factor that determines how tall each item is in relation to the + * screen height. + */ + public Params setItemScreenSizeFactor(double itemScreenSizeFactor) { + mItemScreenSizeFactor = itemScreenSizeFactor; + return this; + } + + /** + * Override the item screen size factor for a particular item. Useful for + * creating grids with non-uniform item height. + * @param position The position in the grid. + * @param itemScreenSizeFactor The screen size factor to use for the height. + */ + public Params setPositionScreenSizeFactorOverride( + int position, double itemScreenSizeFactor) { + mOverrideItemScreenSizeFactors.put(position, itemScreenSizeFactor); + return this; + } + + /** + * Sets the stacking direction + * @param stackFromBottom + * @return + */ + public Params setStackFromBottom(boolean stackFromBottom) { + mStackFromBottom = stackFromBottom; + return this; + } + + /** + * Sets whether the sum of the height of the grid items must be at least the + * height of the grid view. + */ + public Params setMustFillScreen(boolean fillScreen) { + mMustFillScreen = fillScreen; + return this; + } + + /** + * Sets the individual width of each column. + * + * @param requestedWidth the width in pixels of the column + */ + public Params setColumnWidth(int requestedWidth) { + mColumnWidth = requestedWidth; + return this; + } + + /** + * Sets the number of columns in the grid. + */ + public Params setNumColumns(int numColumns) { + mNumColumns = numColumns; + return this; + } + + /** + * Sets the stretch mode. + */ + public Params setStretchMode(int stretchMode) { + mStretchMode = stretchMode; + return this; + } + + /** + * Sets the spacing between rows in the grid + */ + public Params setVerticalSpacing(int verticalSpacing) { + mVerticalSpacing = verticalSpacing; + return this; + } + } + + /** + * How each scenario customizes its behavior. + * @param params + */ + protected abstract void init(Params params); + + /** + * Override this to provide an different adapter for your scenario + * @return The adapter that this scenario will use + */ + protected ListAdapter createAdapter() { + return new MyAdapter(); + } + + /** + * Override this if you want to know when something has been selected (perhaps + * more importantly, that {@link android.widget.AdapterView.OnItemSelectedListener} has + * been triggered). + */ + @SuppressWarnings({ "UnusedDeclaration" }) + protected void positionSelected(int positon) { + + } + + /** + * Override this if you want to know that nothing is selected. + */ + protected void nothingSelected() { + + } + + @Override + protected void onCreate(Bundle icicle) { + super.onCreate(icicle); + + // turn off title bar + requestWindowFeature(Window.FEATURE_NO_TITLE); + + mScreenHeight = getWindowManager().getCurrentWindowMetrics().getBounds().height(); + + final Params params = new Params(); + init(params); + + readAndValidateParams(params); + + mGridView = new GridView(this); + mGridView.setLayoutParams(new ViewGroup.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT)); + mGridView.setDrawSelectorOnTop(false); + if (mNumColumns >= GridView.AUTO_FIT) { + mGridView.setNumColumns(mNumColumns); + } + if (mColumnWidth > 0) { + mGridView.setColumnWidth(mColumnWidth); + } + if (mVerticalSpacing > 0) { + mGridView.setVerticalSpacing(mVerticalSpacing); + } + mGridView.setStretchMode(mStretchMode); + mGridView.setAdapter(createAdapter()); + if (mStartingSelectionPosition >= 0) { + mGridView.setSelection(mStartingSelectionPosition); + } + mGridView.setPadding(10, 10, 10, 10); + mGridView.setStackFromBottom(mStackFromBottom); + + mGridView.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + public void onItemSelected(AdapterView parent, View v, int position, long id) { + positionSelected(position); + } + + public void onNothingSelected(AdapterView parent) { + nothingSelected(); + } + }); + + setContentView(mGridView); + } + + + + /** + * Read in and validate all of the params passed in by the scenario. + * @param params + */ + private void readAndValidateParams(Params params) { + if (params.mMustFillScreen ) { + double totalFactor = 0.0; + for (int i = 0; i < params.mNumItems; i++) { + if (params.mOverrideItemScreenSizeFactors.containsKey(i)) { + totalFactor += params.mOverrideItemScreenSizeFactors.get(i); + } else { + totalFactor += params.mItemScreenSizeFactor; + } + } + if (totalFactor < 1.0) { + throw new IllegalArgumentException("grid items must combine to be at least " + + "the height of the screen. this is not the case with " + params.mNumItems + + " items and " + params.mItemScreenSizeFactor + " screen factor and " + + "screen height of " + mScreenHeight); + } + } + + mNumItems = params.mNumItems; + mStartingSelectionPosition = params.mStartingSelectionPosition; + mItemScreenSizeFactor = params.mItemScreenSizeFactor; + + mOverrideItemScreenSizeFactors.putAll(params.mOverrideItemScreenSizeFactors); + + mStackFromBottom = params.mStackFromBottom; + mColumnWidth = params.mColumnWidth; + mNumColumns = params.mNumColumns; + mStretchMode = params.mStretchMode; + mVerticalSpacing = params.mVerticalSpacing; + } + + public final String getValueAtPosition(int position) { + return "postion " + position; + } + + /** + * Create a view for a grid item. Override this to create a custom view beyond + * the simple focusable / unfocusable text view. + * @param position The position. + * @param parent The parent + * @param desiredHeight The height the view should be to respect the desired item + * to screen height ratio. + * @return a view for the grid. + */ + protected View createView(int position, ViewGroup parent, int desiredHeight) { + TextView result = new TextView(parent.getContext()); + result.setHeight(desiredHeight); + result.setText(getValueAtPosition(position)); + final ViewGroup.LayoutParams lp = new AbsListView.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT); + result.setLayoutParams(lp); + result.setId(position); + result.setBackgroundColor(0x55ffffff); + return result; + } + + + + private class MyAdapter extends BaseAdapter { + public int getCount() { + return mNumItems; + } + + public Object getItem(int position) { + return getValueAtPosition(position); + } + + public long getItemId(int position) { + return position; + } + + public View getView(int position, View convertView, ViewGroup parent) { + if (convertView != null) { + ((TextView) convertView).setText(getValueAtPosition(position)); + convertView.setId(position); + return convertView; + } + + int desiredHeight = getDesiredItemHeight(); + if (mOverrideItemScreenSizeFactors.containsKey(position)) { + desiredHeight = (int) (mScreenHeight * mOverrideItemScreenSizeFactors.get(position)); + } + return createView(position, parent, desiredHeight); + } + } +} diff --git a/core/tests/coretests/src/android/widget/InternalSelectionView.java b/core/tests/coretests/src/android/widget/InternalSelectionView.java new file mode 100644 index 000000000000..f2d318226540 --- /dev/null +++ b/core/tests/coretests/src/android/widget/InternalSelectionView.java @@ -0,0 +1,279 @@ +/* + * Copyright (C) 2023 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.widget; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Rect; +import android.util.AttributeSet; +import android.view.KeyEvent; +import android.view.View; + +import com.android.frameworks.coretests.R; + +/** + * A view that has a known number of selectable rows, and maintains a notion of which + * row is selected. The rows take up the + * entire width of the view. The height of the view is divided evenly among + * the rows. + * + * Note: If the height of the view does not divide exactly to the number of rows, + * the last row's height is inflated with the remainder. For example, if the + * view height is 22 and there are two rows, the height of the first row is + * 10 and the second 22. + * + * Notice what this view does to be a good citizen w.r.t its internal selection: + * 1) calls {@link View#requestRectangleOnScreen} each time the selection changes due to + * internal navigation. + * 2) implements {@link View#getFocusedRect} by filling in the rectangle of the currently + * selected row + * 3) overrides {@link View#onFocusChanged} and sets selection appropriately according to + * the previously focused rectangle. + */ +public class InternalSelectionView extends View { + + private Paint mPainter = new Paint(); + private Paint mTextPaint = new Paint(); + private Rect mTempRect = new Rect(); + + private int mNumRows = 5; + private int mSelectedRow = 0; + private final int mEstimatedPixelHeight = 10; + + private Integer mDesiredHeight = null; + private String mLabel = null; + + public InternalSelectionView(Context context, int numRows, String label) { + super(context); + mNumRows = numRows; + mLabel = label; + init(); + } + + public InternalSelectionView(Context context, AttributeSet attrs) { + super(context, attrs); + TypedArray a = + context.obtainStyledAttributes( + attrs, R.styleable.SelectableRowView); + mNumRows = a.getInt(R.styleable.SelectableRowView_numRows, 5); + init(); + } + + private void init() { + setFocusable(true); + mTextPaint.setAntiAlias(true); + mTextPaint.setTextSize(10); + mTextPaint.setColor(Color.WHITE); + } + + public int getNumRows() { + return mNumRows; + } + + public int getSelectedRow() { + return mSelectedRow; + } + + public void setDesiredHeight(int desiredHeight) { + mDesiredHeight = desiredHeight; + } + + public String getLabel() { + return mLabel; + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + setMeasuredDimension( + measureWidth(widthMeasureSpec), + measureHeight(heightMeasureSpec)); + } + + private int measureWidth(int measureSpec) { + int specMode = MeasureSpec.getMode(measureSpec); + int specSize = MeasureSpec.getSize(measureSpec); + + int desiredWidth = 300 + mPaddingLeft + mPaddingRight; + if (specMode == MeasureSpec.EXACTLY) { + // We were told how big to be + return specSize; + } else if (specMode == MeasureSpec.AT_MOST) { + return desiredWidth < specSize ? desiredWidth : specSize; + } else { + return desiredWidth; + } + } + + private int measureHeight(int measureSpec) { + int specMode = MeasureSpec.getMode(measureSpec); + int specSize = MeasureSpec.getSize(measureSpec); + + int desiredHeight = mDesiredHeight != null ? + mDesiredHeight : + mNumRows * mEstimatedPixelHeight + mPaddingTop + mPaddingBottom; + if (specMode == MeasureSpec.EXACTLY) { + // We were told how big to be + return specSize; + } else if (specMode == MeasureSpec.AT_MOST) { + return desiredHeight < specSize ? desiredHeight : specSize; + } else { + return desiredHeight; + } + } + + + @Override + protected void onDraw(Canvas canvas) { + int rectTop = mPaddingTop; + int rectLeft = mPaddingLeft; + int rectRight = getWidth() - mPaddingRight; + for (int i = 0; i < mNumRows; i++) { + + mPainter.setColor(Color.BLACK); + mPainter.setAlpha(0x20); + + int rowHeight = getRowHeight(i); + + // draw background rect + mTempRect.set(rectLeft, rectTop, rectRight, rectTop + rowHeight); + canvas.drawRect(mTempRect, mPainter); + + // draw forground rect + if (i == mSelectedRow && hasFocus()) { + mPainter.setColor(Color.RED); + mPainter.setAlpha(0xF0); + mTextPaint.setAlpha(0xFF); + } else { + mPainter.setColor(Color.BLACK); + mPainter.setAlpha(0x40); + mTextPaint.setAlpha(0xF0); + } + mTempRect.set(rectLeft + 2, rectTop + 2, + rectRight - 2, rectTop + rowHeight - 2); + canvas.drawRect(mTempRect, mPainter); + + // draw text to help when visually inspecting + canvas.drawText( + Integer.toString(i), + rectLeft + 2, + rectTop + 2 - (int) mTextPaint.ascent(), + mTextPaint); + + rectTop += rowHeight; + } + } + + private int getRowHeight(int row) { + final int availableHeight = getHeight() - mPaddingTop - mPaddingBottom; + final int desiredRowHeight = availableHeight / mNumRows; + if (row < mNumRows - 1) { + return desiredRowHeight; + } else { + final int residualHeight = availableHeight % mNumRows; + return desiredRowHeight + residualHeight; + } + } + + public void getRectForRow(Rect rect, int row) { + final int rowHeight = getRowHeight(row); + final int top = mPaddingTop + row * rowHeight; + rect.set(mPaddingLeft, + top, + getWidth() - mPaddingRight, + top + rowHeight); + } + + + void ensureRectVisible() { + getRectForRow(mTempRect, mSelectedRow); + requestRectangleOnScreen(mTempRect); + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + switch(event.getKeyCode()) { + case KeyEvent.KEYCODE_DPAD_UP: + if (mSelectedRow > 0) { + mSelectedRow--; + invalidate(); + ensureRectVisible(); + return true; + } + break; + case KeyEvent.KEYCODE_DPAD_DOWN: + if (mSelectedRow < (mNumRows - 1)) { + mSelectedRow++; + invalidate(); + ensureRectVisible(); + return true; + } + break; + } + return false; + } + + + @Override + public void getFocusedRect(Rect r) { + getRectForRow(r, mSelectedRow); + } + + @Override + protected void onFocusChanged(boolean focused, int direction, + Rect previouslyFocusedRect) { + super.onFocusChanged(focused, direction, previouslyFocusedRect); + + if (focused) { + switch (direction) { + case View.FOCUS_DOWN: + mSelectedRow = 0; + break; + case View.FOCUS_UP: + mSelectedRow = mNumRows - 1; + break; + case View.FOCUS_LEFT: // fall through + case View.FOCUS_RIGHT: + // set the row that is closest to the rect + if (previouslyFocusedRect != null) { + int y = previouslyFocusedRect.top + + (previouslyFocusedRect.height() / 2); + int yPerRow = getHeight() / mNumRows; + mSelectedRow = y / yPerRow; + } else { + mSelectedRow = 0; + } + break; + default: + // can't gleam any useful information about what internal + // selection should be... + return; + } + invalidate(); + } + } + + @Override + public String toString() { + if (mLabel != null) { + return mLabel; + } + return super.toString(); + } +} diff --git a/core/tests/coretests/src/android/widget/ListScenario.java b/core/tests/coretests/src/android/widget/ListScenario.java new file mode 100644 index 000000000000..589d90d82285 --- /dev/null +++ b/core/tests/coretests/src/android/widget/ListScenario.java @@ -0,0 +1,660 @@ +/* + * Copyright (C) 2023 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.widget; + +import android.app.Activity; +import android.graphics.Rect; +import android.os.Bundle; +import android.util.ListItemFactory; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; + +import com.google.android.collect.Maps; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Utility base class for creating various List scenarios. Configurable by the number + * of items, how tall each item should be (in relation to the screen height), and + * what item should start with selection. + */ +public abstract class ListScenario extends Activity { + + private ListView mListView; + private TextView mHeaderTextView; + + private int mNumItems; + protected boolean mItemsFocusable; + + private int mStartingSelectionPosition; + private double mItemScreenSizeFactor; + private Map mOverrideItemScreenSizeFactors = Maps.newHashMap(); + + private int mScreenHeight; + + // whether to include a text view above the list + private boolean mIncludeHeader; + + // separators + private Set mUnselectableItems = new HashSet(); + + private boolean mStackFromBottom; + + private int mClickedPosition = -1; + + private int mLongClickedPosition = -1; + + private int mConvertMisses = 0; + + private int mHeaderViewCount; + private boolean mHeadersFocusable; + + private int mFooterViewCount; + private LinearLayout mLinearLayout; + + public ListView getListView() { + return mListView; + } + + protected int getScreenHeight() { + return mScreenHeight; + } + + /** + * Return whether the item at position is selectable (i.e is a separator). + * (external users can access this info using the adapter) + */ + private boolean isItemAtPositionSelectable(int position) { + return !mUnselectableItems.contains(position); + } + + /** + * Better way to pass in optional params than a honkin' paramater list :) + */ + public static class Params { + private int mNumItems = 4; + private boolean mItemsFocusable = false; + private int mStartingSelectionPosition = 0; + private double mItemScreenSizeFactor = 1 / 5; + private Double mFadingEdgeScreenSizeFactor = null; + + private Map mOverrideItemScreenSizeFactors = Maps.newHashMap(); + + // separators + private List mUnselectableItems = new ArrayList(8); + // whether to include a text view above the list + private boolean mIncludeHeader = false; + private boolean mStackFromBottom = false; + public boolean mMustFillScreen = true; + private int mHeaderViewCount; + private boolean mHeaderFocusable = false; + private int mFooterViewCount; + + private boolean mConnectAdapter = true; + + /** + * Set the number of items in the list. + */ + public Params setNumItems(int numItems) { + mNumItems = numItems; + return this; + } + + /** + * Set whether the items are focusable. + */ + public Params setItemsFocusable(boolean itemsFocusable) { + mItemsFocusable = itemsFocusable; + return this; + } + + /** + * Set the position that starts selected. + * + * @param startingSelectionPosition The selected position within the adapter's data set. + * Pass -1 if you do not want to force a selection. + * @return + */ + public Params setStartingSelectionPosition(int startingSelectionPosition) { + mStartingSelectionPosition = startingSelectionPosition; + return this; + } + + /** + * Set the factor that determines how tall each item is in relation to the + * screen height. + */ + public Params setItemScreenSizeFactor(double itemScreenSizeFactor) { + mItemScreenSizeFactor = itemScreenSizeFactor; + return this; + } + + /** + * Override the item screen size factor for a particular item. Useful for + * creating lists with non-uniform item height. + * @param position The position in the list. + * @param itemScreenSizeFactor The screen size factor to use for the height. + */ + public Params setPositionScreenSizeFactorOverride( + int position, double itemScreenSizeFactor) { + mOverrideItemScreenSizeFactors.put(position, itemScreenSizeFactor); + return this; + } + + /** + * Set a position as unselectable (a.k.a a separator) + * @param position + * @return + */ + public Params setPositionUnselectable(int position) { + mUnselectableItems.add(position); + return this; + } + + /** + * Set positions as unselectable (a.k.a a separator) + */ + public Params setPositionsUnselectable(int ...positions) { + for (int pos : positions) { + setPositionUnselectable(pos); + } + return this; + } + + /** + * Include a header text view above the list. + * @param includeHeader + * @return + */ + public Params includeHeaderAboveList(boolean includeHeader) { + mIncludeHeader = includeHeader; + return this; + } + + /** + * Sets the stacking direction + * @param stackFromBottom + * @return + */ + public Params setStackFromBottom(boolean stackFromBottom) { + mStackFromBottom = stackFromBottom; + return this; + } + + /** + * Sets whether the sum of the height of the list items must be at least the + * height of the list view. + */ + public Params setMustFillScreen(boolean fillScreen) { + mMustFillScreen = fillScreen; + return this; + } + + /** + * Set the factor for the fading edge length. + */ + public Params setFadingEdgeScreenSizeFactor(double fadingEdgeScreenSizeFactor) { + mFadingEdgeScreenSizeFactor = fadingEdgeScreenSizeFactor; + return this; + } + + /** + * Set the number of header views to appear within the list + */ + public Params setHeaderViewCount(int headerViewCount) { + mHeaderViewCount = headerViewCount; + return this; + } + + /** + * Set whether the headers should be focusable. + * @param headerFocusable Whether the headers should be focusable (i.e + * created as edit texts rather than text views). + */ + public Params setHeaderFocusable(boolean headerFocusable) { + mHeaderFocusable = headerFocusable; + return this; + } + + /** + * Set the number of footer views to appear within the list + */ + public Params setFooterViewCount(int footerViewCount) { + mFooterViewCount = footerViewCount; + return this; + } + + /** + * Sets whether the {@link ListScenario} will automatically set the + * adapter on the list view. If this is false, the client MUST set it + * manually (this is useful when adding headers to the list view, which + * must be done before the adapter is set). + */ + public Params setConnectAdapter(boolean connectAdapter) { + mConnectAdapter = connectAdapter; + return this; + } + } + + /** + * How each scenario customizes its behavior. + * @param params + */ + protected abstract void init(Params params); + + /** + * Override this if you want to know when something has been selected (perhaps + * more importantly, that {@link android.widget.AdapterView.OnItemSelectedListener} has + * been triggered). + */ + protected void positionSelected(int positon) { + } + + /** + * Override this if you want to know that nothing is selected. + */ + protected void nothingSelected() { + } + + /** + * Override this if you want to know when something has been clicked (perhaps + * more importantly, that {@link android.widget.AdapterView.OnItemClickListener} has + * been triggered). + */ + protected void positionClicked(int position) { + setClickedPosition(position); + } + + /** + * Override this if you want to know when something has been long clicked (perhaps + * more importantly, that {@link android.widget.AdapterView.OnItemLongClickListener} has + * been triggered). + */ + protected void positionLongClicked(int position) { + setLongClickedPosition(position); + } + + @Override + protected void onCreate(Bundle icicle) { + super.onCreate(icicle); + + // for test stability, turn off title bar + requestWindowFeature(Window.FEATURE_NO_TITLE); + + + mScreenHeight = getWindowManager().getCurrentWindowMetrics().getBounds().height(); + + final Params params = createParams(); + init(params); + + readAndValidateParams(params); + + + mListView = createListView(); + mListView.setLayoutParams(new ViewGroup.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT)); + mListView.setDrawSelectorOnTop(false); + + for (int i=0; i= 0) { + mListView.setSelection(mStartingSelectionPosition); + } + mListView.setPadding(0, 0, 0, 0); + mListView.setStackFromBottom(mStackFromBottom); + mListView.setDivider(null); + + mListView.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + public void onItemSelected(AdapterView parent, View v, int position, long id) { + positionSelected(position); + } + + public void onNothingSelected(AdapterView parent) { + nothingSelected(); + } + }); + + mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + public void onItemClick(AdapterView parent, View v, int position, long id) { + positionClicked(position); + } + }); + + // set the fading edge length porportionally to the screen + // height for test stability + if (params.mFadingEdgeScreenSizeFactor != null) { + mListView.setFadingEdgeLength( + (int) (params.mFadingEdgeScreenSizeFactor * mScreenHeight)); + } else { + mListView.setFadingEdgeLength((int) ((64.0 / 480) * mScreenHeight)); + } + + if (mIncludeHeader) { + mLinearLayout = new LinearLayout(this); + + mHeaderTextView = new TextView(this); + mHeaderTextView.setText("hi"); + mHeaderTextView.setLayoutParams(new LinearLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT)); + mLinearLayout.addView(mHeaderTextView); + + mLinearLayout.setOrientation(LinearLayout.VERTICAL); + mLinearLayout.setLayoutParams(new ViewGroup.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT)); + mListView.setLayoutParams((new LinearLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + 0, + 1f))); + + mLinearLayout.addView(mListView); + setContentView(mLinearLayout); + } else { + mLinearLayout = new LinearLayout(this); + mLinearLayout.setOrientation(LinearLayout.VERTICAL); + mLinearLayout.setLayoutParams(new ViewGroup.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT)); + mListView.setLayoutParams((new LinearLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + 0, + 1f))); + mLinearLayout.addView(mListView); + setContentView(mLinearLayout); + } + mLinearLayout.restoreDefaultFocus(); + } + + /** + * Returns the LinearLayout containing the ListView in this scenario. + * + * @return The LinearLayout in which the ListView is held. + */ + protected LinearLayout getListViewContainer() { + return mLinearLayout; + } + + /** + * Attaches a long press listener. You can find out which views were clicked by calling + * {@link #getLongClickedPosition()}. + */ + public void enableLongPress() { + mListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { + public boolean onItemLongClick(AdapterView parent, View v, int position, long id) { + positionLongClicked(position); + return true; + } + }); + } + + /** + * @return The newly created ListView widget. + */ + protected ListView createListView() { + return new ListView(this); + } + + /** + * @return The newly created Params object. + */ + protected Params createParams() { + return new Params(); + } + + /** + * Sets an adapter on a ListView. + * + * @param listView The ListView to set the adapter on. + */ + protected void setAdapter(ListView listView) { + listView.setAdapter(new MyAdapter()); + } + + /** + * Read in and validate all of the params passed in by the scenario. + * @param params + */ + protected void readAndValidateParams(Params params) { + if (params.mMustFillScreen ) { + double totalFactor = 0.0; + for (int i = 0; i < params.mNumItems; i++) { + if (params.mOverrideItemScreenSizeFactors.containsKey(i)) { + totalFactor += params.mOverrideItemScreenSizeFactors.get(i); + } else { + totalFactor += params.mItemScreenSizeFactor; + } + } + if (totalFactor < 1.0) { + throw new IllegalArgumentException("list items must combine to be at least " + + "the height of the screen. this is not the case with " + params.mNumItems + + " items and " + params.mItemScreenSizeFactor + " screen factor and " + + "screen height of " + mScreenHeight); + } + } + + mNumItems = params.mNumItems; + mItemsFocusable = params.mItemsFocusable; + mStartingSelectionPosition = params.mStartingSelectionPosition; + mItemScreenSizeFactor = params.mItemScreenSizeFactor; + + mOverrideItemScreenSizeFactors.putAll(params.mOverrideItemScreenSizeFactors); + + mUnselectableItems.addAll(params.mUnselectableItems); + mIncludeHeader = params.mIncludeHeader; + mStackFromBottom = params.mStackFromBottom; + mHeaderViewCount = params.mHeaderViewCount; + mHeadersFocusable = params.mHeaderFocusable; + mFooterViewCount = params.mFooterViewCount; + } + + public final String getValueAtPosition(int position) { + return isItemAtPositionSelectable(position) + ? + "position " + position: + "------- " + position; + } + + /** + * @return The height that will be set for a particular position. + */ + public int getHeightForPosition(int position) { + int desiredHeight = (int) (mScreenHeight * mItemScreenSizeFactor); + if (mOverrideItemScreenSizeFactors.containsKey(position)) { + desiredHeight = (int) (mScreenHeight * mOverrideItemScreenSizeFactors.get(position)); + } + return desiredHeight; + } + + + /** + * @return The contents of the header above the list. + * @throws IllegalArgumentException if there is no header. + */ + public final String getHeaderValue() { + if (!mIncludeHeader) { + throw new IllegalArgumentException("no header above list"); + } + return mHeaderTextView.getText().toString(); + } + + /** + * @param value What to put in the header text view + * @throws IllegalArgumentException if there is no header. + */ + protected final void setHeaderValue(String value) { + if (!mIncludeHeader) { + throw new IllegalArgumentException("no header above list"); + } + mHeaderTextView.setText(value); + } + + /** + * Create a view for a list item. Override this to create a custom view beyond + * the simple focusable / unfocusable text view. + * @param position The position. + * @param parent The parent + * @param desiredHeight The height the view should be to respect the desired item + * to screen height ratio. + * @return a view for the list. + */ + protected View createView(int position, ViewGroup parent, int desiredHeight) { + return ListItemFactory.text(position, parent.getContext(), getValueAtPosition(position), + desiredHeight); + } + + /** + * Convert a non-null view. + */ + public View convertView(int position, View convertView, ViewGroup parent) { + return ListItemFactory.convertText(convertView, getValueAtPosition(position), position); + } + + public void setClickedPosition(int clickedPosition) { + mClickedPosition = clickedPosition; + } + + public int getClickedPosition() { + return mClickedPosition; + } + + public void setLongClickedPosition(int longClickedPosition) { + mLongClickedPosition = longClickedPosition; + } + + public int getLongClickedPosition() { + return mLongClickedPosition; + } + + /** + * Have a child of the list view call {@link View#requestRectangleOnScreen(android.graphics.Rect)}. + * @param childIndex The index into the viewgroup children (i.e the children that are + * currently visible). + * @param rect The rectangle, in the child's coordinates. + */ + public void requestRectangleOnScreen(int childIndex, final Rect rect) { + final View child = getListView().getChildAt(childIndex); + + child.post(new Runnable() { + public void run() { + child.requestRectangleOnScreen(rect); + } + }); + } + + /** + * Return an item type for the specified position in the adapter. Override if your + * adapter creates more than one type. + */ + public int getItemViewType(int position) { + return 0; + } + + /** + * Return the number of types created by the adapter. Override if your + * adapter creates more than one type. + */ + public int getViewTypeCount() { + return 1; + } + + /** + * @return The number of times convertView failed + */ + public int getConvertMisses() { + return mConvertMisses; + } + + private class MyAdapter extends BaseAdapter { + + public int getCount() { + return mNumItems; + } + + public Object getItem(int position) { + return getValueAtPosition(position); + } + + public long getItemId(int position) { + return position; + } + + @Override + public boolean areAllItemsEnabled() { + return mUnselectableItems.isEmpty(); + } + + @Override + public boolean isEnabled(int position) { + return isItemAtPositionSelectable(position); + } + + public View getView(int position, View convertView, ViewGroup parent) { + View result = null; + if (position >= mNumItems || position < 0) { + throw new IllegalStateException("position out of range for adapter!"); + } + + if (convertView != null) { + result = convertView(position, convertView, parent); + if (result == null) { + mConvertMisses++; + } + } + + if (result == null) { + int desiredHeight = getHeightForPosition(position); + result = createView(position, parent, desiredHeight); + } + return result; + } + + @Override + public int getItemViewType(int position) { + return ListScenario.this.getItemViewType(position); + } + + @Override + public int getViewTypeCount() { + return ListScenario.this.getViewTypeCount(); + } + + } +} diff --git a/core/tests/coretests/src/android/widget/ScrollViewScenario.java b/core/tests/coretests/src/android/widget/ScrollViewScenario.java new file mode 100644 index 000000000000..ff2ab05d645f --- /dev/null +++ b/core/tests/coretests/src/android/widget/ScrollViewScenario.java @@ -0,0 +1,275 @@ +/* + * Copyright (C) 2023 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.widget; + +import android.app.Activity; +import android.content.Context; +import android.os.Bundle; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.widget.Button; +import android.widget.InternalSelectionView; +import android.widget.LinearLayout; +import android.widget.ScrollView; +import android.widget.TextView; + +import com.google.android.collect.Lists; + +import java.util.List; + +/** + * Utility base class for creating scroll view scenarios, allowing you to add + * a series of different kinds of views arranged vertically, taking up a + * specified amount of the screen height. + */ +public abstract class ScrollViewScenario extends Activity { + + /** + * Holds content of scroll view + */ + private LinearLayout mLinearLayout; + + /** + * The actual scroll view + */ + private ScrollView mScrollView; + + + /** + * What we need of each view that the user wants: the view, and the ratio + * to the screen height for its desired height. + */ + private interface ViewFactory { + View create(final Context context); + + float getHeightRatio(); + } + + /** + * Partially implement ViewFactory given a height ratio. + * A negative height ratio means that WRAP_CONTENT will be used as height + */ + private static abstract class ViewFactoryBase implements ViewFactory { + + private float mHeightRatio; + + @SuppressWarnings({"UnusedDeclaration"}) + private ViewFactoryBase() {throw new UnsupportedOperationException("don't call this!");} + + protected ViewFactoryBase(float heightRatio) { + mHeightRatio = heightRatio; + } + + public float getHeightRatio() { + return mHeightRatio; + } + } + + /** + * Builder for selecting the views to be vertically arranged in the scroll + * view. + */ + @SuppressWarnings({"JavaDoc"}) + public static class Params { + + List mViewFactories = Lists.newArrayList(); + + int mTopPadding = 0; + int mBottomPadding = 0; + + /** + * Add a text view. + * @param text The text of the text view. + * @param heightRatio The view's height will be this * the screen height. + */ + public Params addTextView(final String text, float heightRatio) { + mViewFactories.add(new ViewFactoryBase(heightRatio) { + public View create(final Context context) { + final TextView tv = new TextView(context); + tv.setText(text); + return tv; + } + }); + return this; + } + + /** + * Add multiple text views. + * @param numViews the number of views to add. + * @param textPrefix The text to prepend to each text view. + * @param heightRatio The view's height will be this * the screen height. + */ + public Params addTextViews(int numViews, String textPrefix, float heightRatio) { + for (int i = 0; i < numViews; i++) { + addTextView(textPrefix + i, heightRatio); + } + return this; + } + + /** + * Add a button. + * @param text The text of the button. + * @param heightRatio The view's height will be this * the screen height. + */ + public Params addButton(final String text, float heightRatio) { + mViewFactories.add(new ViewFactoryBase(heightRatio) { + public View create(final Context context) { + final Button button = new Button(context); + button.setText(text); + return button; + } + }); + return this; + } + + /** + * Add multiple buttons. + * @param numButtons the number of views to add. + * @param textPrefix The text to prepend to each button. + * @param heightRatio The view's height will be this * the screen height. + */ + public Params addButtons(int numButtons, String textPrefix, float heightRatio) { + for (int i = 0; i < numButtons; i++) { + addButton(textPrefix + i, heightRatio); + } + return this; + } + + /** + * Add an {@link InternalSelectionView}. + * @param numRows The number of rows in the internal selection view. + * @param heightRatio The view's height will be this * the screen height. + */ + public Params addInternalSelectionView(final int numRows, float heightRatio) { + mViewFactories.add(new ViewFactoryBase(heightRatio) { + public View create(final Context context) { + return new InternalSelectionView(context, numRows, "isv"); + } + }); + return this; + } + + /** + * Add a sublayout of buttons as a single child of the scroll view. + * @param numButtons The number of buttons in the sub layout + * @param heightRatio The layout's height will be this * the screen height. + */ + public Params addVerticalLLOfButtons(final String prefix, final int numButtons, float heightRatio) { + mViewFactories.add(new ViewFactoryBase(heightRatio) { + + public View create(Context context) { + final LinearLayout ll = new LinearLayout(context); + ll.setOrientation(LinearLayout.VERTICAL); + + // fill width, equally weighted on height + final LinearLayout.LayoutParams lp = + new LinearLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, 0, 1f); + for (int i = 0; i < numButtons; i++) { + final Button button = new Button(context); + button.setText(prefix + i); + ll.addView(button, lp); + } + + return ll; + } + }); + return this; + } + + public Params addPaddingToScrollView(int topPadding, int bottomPadding) { + mTopPadding = topPadding; + mBottomPadding = bottomPadding; + + return this; + } + } + + /** + * Override this and initialized the views in the scroll view. + * @param params Used to configure the contents of the scroll view. + */ + protected abstract void init(Params params); + + public LinearLayout getLinearLayout() { + return mLinearLayout; + } + + public ScrollView getScrollView() { + return mScrollView; + } + + /** + * Get the child contained within the vertical linear layout of the + * scroll view. + * @param index The index within the linear layout. + * @return the child within the vertical linear layout of the scroll view + * at the specified index. + */ + @SuppressWarnings({"unchecked"}) + public T getContentChildAt(int index) { + return (T) mLinearLayout.getChildAt(index); + } + + /** + * Hook for changing how scroll view's are created. + */ + @SuppressWarnings({"JavaDoc"}) + protected ScrollView createScrollView() { + return new ScrollView(this); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // for test stability, turn off title bar + requestWindowFeature(Window.FEATURE_NO_TITLE); + int screenHeight = getWindowManager().getCurrentWindowMetrics().getBounds().height() + - 25; + mLinearLayout = new LinearLayout(this); + mLinearLayout.setOrientation(LinearLayout.VERTICAL); + + // initialize params + final Params params = new Params(); + init(params); + + // create views specified by params + for (ViewFactory viewFactory : params.mViewFactories) { + int height = ViewGroup.LayoutParams.WRAP_CONTENT; + if (viewFactory.getHeightRatio() >= 0) { + height = (int) (viewFactory.getHeightRatio() * screenHeight); + } + final LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, height); + mLinearLayout.addView(viewFactory.create(this), lp); + } + + mScrollView = createScrollView(); + mScrollView.setPadding(0, params.mTopPadding, 0, params.mBottomPadding); + mScrollView.addView(mLinearLayout, new ViewGroup.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT)); + + // no animation to speed up tests + mScrollView.setSmoothScrollingEnabled(false); + + setContentView(mScrollView); + mScrollView.post(() -> mScrollView.restoreDefaultFocus()); + } +} diff --git a/core/tests/coretests/src/android/widget/focus/AdjacentVerticalRectLists.java b/core/tests/coretests/src/android/widget/focus/AdjacentVerticalRectLists.java index 85a4509c18a3..7e2f293b3a99 100644 --- a/core/tests/coretests/src/android/widget/focus/AdjacentVerticalRectLists.java +++ b/core/tests/coretests/src/android/widget/focus/AdjacentVerticalRectLists.java @@ -18,7 +18,7 @@ package android.widget.focus; import android.app.Activity; import android.os.Bundle; -import android.util.InternalSelectionView; +import android.widget.InternalSelectionView; import android.view.ViewGroup; import android.widget.LinearLayout; @@ -30,7 +30,7 @@ import android.widget.LinearLayout; * rectangle of the previously focused view. The view taking focus can use this * to set an internal selection more appropriate using this rect. * - * This Activity excercises that behavior using three adjacent {@link android.util.InternalSelectionView} + * This Activity excercises that behavior using three adjacent {@link InternalSelectionView} * that report interesting rects when giving up focus, and use interesting rects * when taking focus to best select the internal row to show as selected. */ diff --git a/core/tests/coretests/src/android/widget/focus/FocusChangeWithInterestingRectHintTest.java b/core/tests/coretests/src/android/widget/focus/FocusChangeWithInterestingRectHintTest.java index 26dc23398366..16a0b35c2dd5 100644 --- a/core/tests/coretests/src/android/widget/focus/FocusChangeWithInterestingRectHintTest.java +++ b/core/tests/coretests/src/android/widget/focus/FocusChangeWithInterestingRectHintTest.java @@ -17,7 +17,7 @@ package android.widget.focus; import android.test.ActivityInstrumentationTestCase; -import android.util.InternalSelectionView; +import android.widget.InternalSelectionView; import android.view.KeyEvent; import androidx.test.filters.LargeTest; @@ -31,7 +31,7 @@ import androidx.test.filters.MediumTest; * rectangle of the previously focused view. The view taking focus can use this * to set an internal selection more appropriate using this rect. * - * This tests that behavior using three adjacent {@link android.util.InternalSelectionView} + * This tests that behavior using three adjacent {@link InternalSelectionView} * that report interesting rects when giving up focus, and use interesting rects * when taking focus to best select the internal row to show as selected. * diff --git a/core/tests/coretests/src/android/widget/focus/ListOfInternalSelectionViews.java b/core/tests/coretests/src/android/widget/focus/ListOfInternalSelectionViews.java index c5e69b67862f..4231b40431f1 100644 --- a/core/tests/coretests/src/android/widget/focus/ListOfInternalSelectionViews.java +++ b/core/tests/coretests/src/android/widget/focus/ListOfInternalSelectionViews.java @@ -18,7 +18,7 @@ package android.widget.focus; import android.app.Activity; import android.os.Bundle; -import android.util.InternalSelectionView; +import android.widget.InternalSelectionView; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; diff --git a/core/tests/coretests/src/android/widget/focus/ScrollingThroughListOfFocusablesTest.java b/core/tests/coretests/src/android/widget/focus/ScrollingThroughListOfFocusablesTest.java index e6e76ccc2caf..46190c4ce7c7 100644 --- a/core/tests/coretests/src/android/widget/focus/ScrollingThroughListOfFocusablesTest.java +++ b/core/tests/coretests/src/android/widget/focus/ScrollingThroughListOfFocusablesTest.java @@ -18,7 +18,7 @@ package android.widget.focus; import android.graphics.Rect; import android.test.InstrumentationTestCase; -import android.util.InternalSelectionView; +import android.widget.InternalSelectionView; import android.view.KeyEvent; import android.widget.ListView; diff --git a/core/tests/coretests/src/android/widget/gridview/GridDelete.java b/core/tests/coretests/src/android/widget/gridview/GridDelete.java index b040f69545f1..5f4326cd7758 100644 --- a/core/tests/coretests/src/android/widget/gridview/GridDelete.java +++ b/core/tests/coretests/src/android/widget/gridview/GridDelete.java @@ -16,7 +16,7 @@ package android.widget.gridview; -import android.util.GridScenario; +import android.widget.GridScenario; import android.view.KeyEvent; import android.view.View; import android.view.ViewGroup; diff --git a/core/tests/coretests/src/android/widget/gridview/GridSetSelection.java b/core/tests/coretests/src/android/widget/gridview/GridSetSelection.java index a3cda3b1f030..140dd7b696fd 100644 --- a/core/tests/coretests/src/android/widget/gridview/GridSetSelection.java +++ b/core/tests/coretests/src/android/widget/gridview/GridSetSelection.java @@ -16,7 +16,7 @@ package android.widget.gridview; -import android.util.GridScenario; +import android.widget.GridScenario; /** * Basic stacking from top scenario, nothing fancy. Items do not diff --git a/core/tests/coretests/src/android/widget/gridview/GridSetSelectionBaseTest.java b/core/tests/coretests/src/android/widget/gridview/GridSetSelectionBaseTest.java index db4f2dc224fc..1428fea9fc87 100644 --- a/core/tests/coretests/src/android/widget/gridview/GridSetSelectionBaseTest.java +++ b/core/tests/coretests/src/android/widget/gridview/GridSetSelectionBaseTest.java @@ -18,7 +18,7 @@ package android.widget.gridview; import android.test.ActivityInstrumentationTestCase; import android.test.ViewAsserts; -import android.util.GridScenario; +import android.widget.GridScenario; import android.widget.GridView; import androidx.test.filters.MediumTest; diff --git a/core/tests/coretests/src/android/widget/gridview/GridSetSelectionMany.java b/core/tests/coretests/src/android/widget/gridview/GridSetSelectionMany.java index a6d481f8a9fd..71766195fcc7 100644 --- a/core/tests/coretests/src/android/widget/gridview/GridSetSelectionMany.java +++ b/core/tests/coretests/src/android/widget/gridview/GridSetSelectionMany.java @@ -16,7 +16,7 @@ package android.widget.gridview; -import android.util.GridScenario; +import android.widget.GridScenario; /** * Basic stacking from top scenario, nothing fancy. Items do diff --git a/core/tests/coretests/src/android/widget/gridview/GridSetSelectionStackFromBottom.java b/core/tests/coretests/src/android/widget/gridview/GridSetSelectionStackFromBottom.java index dfcd5fc09cc2..01bb2be37fb8 100644 --- a/core/tests/coretests/src/android/widget/gridview/GridSetSelectionStackFromBottom.java +++ b/core/tests/coretests/src/android/widget/gridview/GridSetSelectionStackFromBottom.java @@ -16,7 +16,7 @@ package android.widget.gridview; -import android.util.GridScenario; +import android.widget.GridScenario; /** * Basic stacking from bottom scenario, nothing fancy. Items do not diff --git a/core/tests/coretests/src/android/widget/gridview/GridSetSelectionStackFromBottomMany.java b/core/tests/coretests/src/android/widget/gridview/GridSetSelectionStackFromBottomMany.java index 26a567e90cef..d79ee880ec97 100644 --- a/core/tests/coretests/src/android/widget/gridview/GridSetSelectionStackFromBottomMany.java +++ b/core/tests/coretests/src/android/widget/gridview/GridSetSelectionStackFromBottomMany.java @@ -16,7 +16,7 @@ package android.widget.gridview; -import android.util.GridScenario; +import android.widget.GridScenario; /** * Basic stacking from bottom scenario, nothing fancy. Items do diff --git a/core/tests/coretests/src/android/widget/gridview/GridSimple.java b/core/tests/coretests/src/android/widget/gridview/GridSimple.java index 67bb7511122a..6ca7eaa14f40 100644 --- a/core/tests/coretests/src/android/widget/gridview/GridSimple.java +++ b/core/tests/coretests/src/android/widget/gridview/GridSimple.java @@ -18,7 +18,7 @@ package android.widget.gridview; import android.graphics.drawable.PaintDrawable; import android.os.Bundle; -import android.util.GridScenario; +import android.widget.GridScenario; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; diff --git a/core/tests/coretests/src/android/widget/gridview/GridSingleColumn.java b/core/tests/coretests/src/android/widget/gridview/GridSingleColumn.java index 566e71b7e14f..aaed9ba2789f 100644 --- a/core/tests/coretests/src/android/widget/gridview/GridSingleColumn.java +++ b/core/tests/coretests/src/android/widget/gridview/GridSingleColumn.java @@ -16,7 +16,7 @@ package android.widget.gridview; -import android.util.GridScenario; +import android.widget.GridScenario; import android.widget.GridView; /** diff --git a/core/tests/coretests/src/android/widget/gridview/GridStackFromBottom.java b/core/tests/coretests/src/android/widget/gridview/GridStackFromBottom.java index 2f0a88fc9767..457b00ddce54 100644 --- a/core/tests/coretests/src/android/widget/gridview/GridStackFromBottom.java +++ b/core/tests/coretests/src/android/widget/gridview/GridStackFromBottom.java @@ -16,7 +16,7 @@ package android.widget.gridview; -import android.util.GridScenario; +import android.widget.GridScenario; /** * Basic bottom stacking from bottom scenario, nothing fancy. Items do not diff --git a/core/tests/coretests/src/android/widget/gridview/GridStackFromBottomMany.java b/core/tests/coretests/src/android/widget/gridview/GridStackFromBottomMany.java index 33a9592fdc9b..9029bc57ac85 100644 --- a/core/tests/coretests/src/android/widget/gridview/GridStackFromBottomMany.java +++ b/core/tests/coretests/src/android/widget/gridview/GridStackFromBottomMany.java @@ -16,7 +16,7 @@ package android.widget.gridview; -import android.util.GridScenario; +import android.widget.GridScenario; /** * Basic bottom stacking from bottom scenario, nothing fancy. The grid items do not fit on the diff --git a/core/tests/coretests/src/android/widget/gridview/GridVerticalSpacing.java b/core/tests/coretests/src/android/widget/gridview/GridVerticalSpacing.java index 0d01d3087d9d..6aa864f756fc 100644 --- a/core/tests/coretests/src/android/widget/gridview/GridVerticalSpacing.java +++ b/core/tests/coretests/src/android/widget/gridview/GridVerticalSpacing.java @@ -16,7 +16,7 @@ package android.widget.gridview; -import android.util.GridScenario; +import android.widget.GridScenario; /** * A grid with vertical spacing between rows diff --git a/core/tests/coretests/src/android/widget/gridview/GridVerticalSpacingStackFromBottom.java b/core/tests/coretests/src/android/widget/gridview/GridVerticalSpacingStackFromBottom.java index bd686809dba7..25ef6820c8b5 100644 --- a/core/tests/coretests/src/android/widget/gridview/GridVerticalSpacingStackFromBottom.java +++ b/core/tests/coretests/src/android/widget/gridview/GridVerticalSpacingStackFromBottom.java @@ -16,7 +16,7 @@ package android.widget.gridview; -import android.util.GridScenario; +import android.widget.GridScenario; /** * A grid with vertical spacing between rows that stacks from the bottom diff --git a/core/tests/coretests/src/android/widget/listview/AdjacentListsWithAdjacentISVsInside.java b/core/tests/coretests/src/android/widget/listview/AdjacentListsWithAdjacentISVsInside.java index 62b93d6d208a..1e57d69edec6 100644 --- a/core/tests/coretests/src/android/widget/listview/AdjacentListsWithAdjacentISVsInside.java +++ b/core/tests/coretests/src/android/widget/listview/AdjacentListsWithAdjacentISVsInside.java @@ -18,7 +18,7 @@ package android.widget.listview; import android.app.Activity; import android.os.Bundle; -import android.util.InternalSelectionView; +import android.widget.InternalSelectionView; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; diff --git a/core/tests/coretests/src/android/widget/listview/ListBottomGravity.java b/core/tests/coretests/src/android/widget/listview/ListBottomGravity.java index cd76d70acdaf..5d319c5f4930 100644 --- a/core/tests/coretests/src/android/widget/listview/ListBottomGravity.java +++ b/core/tests/coretests/src/android/widget/listview/ListBottomGravity.java @@ -16,7 +16,7 @@ package android.widget.listview; -import android.util.ListScenario; +import android.widget.ListScenario; /** * Basic bottom gravity scenario, nothing fancy. Items do not diff --git a/core/tests/coretests/src/android/widget/listview/ListBottomGravityMany.java b/core/tests/coretests/src/android/widget/listview/ListBottomGravityMany.java index e048e3eb98a0..331fd121370c 100644 --- a/core/tests/coretests/src/android/widget/listview/ListBottomGravityMany.java +++ b/core/tests/coretests/src/android/widget/listview/ListBottomGravityMany.java @@ -16,7 +16,7 @@ package android.widget.listview; -import android.util.ListScenario; +import android.widget.ListScenario; /** * Basic bottom gravity scenario, nothing fancy. There are diff --git a/core/tests/coretests/src/android/widget/listview/ListButtonsDiagonalAcrossItems.java b/core/tests/coretests/src/android/widget/listview/ListButtonsDiagonalAcrossItems.java index 86407411c2d0..bc7c19f34fd9 100644 --- a/core/tests/coretests/src/android/widget/listview/ListButtonsDiagonalAcrossItems.java +++ b/core/tests/coretests/src/android/widget/listview/ListButtonsDiagonalAcrossItems.java @@ -19,7 +19,7 @@ package android.widget.listview; import static android.util.ListItemFactory.Slot; import android.util.ListItemFactory; -import android.util.ListScenario; +import android.widget.ListScenario; import android.view.View; import android.view.ViewGroup; import android.widget.Button; diff --git a/core/tests/coretests/src/android/widget/listview/ListEndingWithMultipleSeparators.java b/core/tests/coretests/src/android/widget/listview/ListEndingWithMultipleSeparators.java index 85f9924a16aa..834f0d1ec01c 100644 --- a/core/tests/coretests/src/android/widget/listview/ListEndingWithMultipleSeparators.java +++ b/core/tests/coretests/src/android/widget/listview/ListEndingWithMultipleSeparators.java @@ -16,7 +16,7 @@ package android.widget.listview; -import android.util.ListScenario; +import android.widget.ListScenario; public class ListEndingWithMultipleSeparators extends ListScenario { diff --git a/core/tests/coretests/src/android/widget/listview/ListGetSelectedView.java b/core/tests/coretests/src/android/widget/listview/ListGetSelectedView.java index 5639195198f1..abd5d2e5dab4 100644 --- a/core/tests/coretests/src/android/widget/listview/ListGetSelectedView.java +++ b/core/tests/coretests/src/android/widget/listview/ListGetSelectedView.java @@ -16,7 +16,7 @@ package android.widget.listview; -import android.util.ListScenario; +import android.widget.ListScenario; /** * Basic top gravity scenario. This test is made to check that getSelectedView() will return diff --git a/core/tests/coretests/src/android/widget/listview/ListHeterogeneous.java b/core/tests/coretests/src/android/widget/listview/ListHeterogeneous.java index 74eda3b850b9..fd24d61d4327 100644 --- a/core/tests/coretests/src/android/widget/listview/ListHeterogeneous.java +++ b/core/tests/coretests/src/android/widget/listview/ListHeterogeneous.java @@ -17,7 +17,7 @@ package android.widget.listview; import android.util.ListItemFactory; -import android.util.ListScenario; +import android.widget.ListScenario; import android.view.View; import android.view.ViewGroup; diff --git a/core/tests/coretests/src/android/widget/listview/ListHorizontalFocusWithinItemWins.java b/core/tests/coretests/src/android/widget/listview/ListHorizontalFocusWithinItemWins.java index e98de9c1204c..7ce5ee3d2f81 100644 --- a/core/tests/coretests/src/android/widget/listview/ListHorizontalFocusWithinItemWins.java +++ b/core/tests/coretests/src/android/widget/listview/ListHorizontalFocusWithinItemWins.java @@ -20,7 +20,7 @@ import static android.util.ListItemFactory.Slot; import android.content.Context; import android.util.ListItemFactory; -import android.util.ListScenario; +import android.widget.ListScenario; import android.view.View; import android.view.ViewGroup; import android.widget.Button; diff --git a/core/tests/coretests/src/android/widget/listview/ListInterleaveFocusables.java b/core/tests/coretests/src/android/widget/listview/ListInterleaveFocusables.java index 0ec7a2431b93..b613741a9c62 100644 --- a/core/tests/coretests/src/android/widget/listview/ListInterleaveFocusables.java +++ b/core/tests/coretests/src/android/widget/listview/ListInterleaveFocusables.java @@ -17,7 +17,7 @@ package android.widget.listview; import android.util.ListItemFactory; -import android.util.ListScenario; +import android.widget.ListScenario; import android.view.View; import android.view.ViewGroup; diff --git a/core/tests/coretests/src/android/widget/listview/ListItemFocusableAboveUnfocusable.java b/core/tests/coretests/src/android/widget/listview/ListItemFocusableAboveUnfocusable.java index 3159e53eabc5..dc40f5f5d98b 100644 --- a/core/tests/coretests/src/android/widget/listview/ListItemFocusableAboveUnfocusable.java +++ b/core/tests/coretests/src/android/widget/listview/ListItemFocusableAboveUnfocusable.java @@ -17,7 +17,7 @@ package android.widget.listview; import android.util.ListItemFactory; -import android.util.ListScenario; +import android.widget.ListScenario; import android.view.View; import android.view.ViewGroup; diff --git a/core/tests/coretests/src/android/widget/listview/ListItemFocusablesClose.java b/core/tests/coretests/src/android/widget/listview/ListItemFocusablesClose.java index 861e2a919052..d21d234c92aa 100644 --- a/core/tests/coretests/src/android/widget/listview/ListItemFocusablesClose.java +++ b/core/tests/coretests/src/android/widget/listview/ListItemFocusablesClose.java @@ -17,7 +17,7 @@ package android.widget.listview; import android.util.ListItemFactory; -import android.util.ListScenario; +import android.widget.ListScenario; import android.view.View; import android.view.ViewGroup; diff --git a/core/tests/coretests/src/android/widget/listview/ListItemFocusablesFarApart.java b/core/tests/coretests/src/android/widget/listview/ListItemFocusablesFarApart.java index e9c9c1dd586c..0bb080b071a1 100644 --- a/core/tests/coretests/src/android/widget/listview/ListItemFocusablesFarApart.java +++ b/core/tests/coretests/src/android/widget/listview/ListItemFocusablesFarApart.java @@ -17,7 +17,7 @@ package android.widget.listview; import android.util.ListItemFactory; -import android.util.ListScenario; +import android.widget.ListScenario; import android.view.View; import android.view.ViewGroup; diff --git a/core/tests/coretests/src/android/widget/listview/ListItemISVAndButton.java b/core/tests/coretests/src/android/widget/listview/ListItemISVAndButton.java index 2a0e013be616..cbe07cc475f0 100644 --- a/core/tests/coretests/src/android/widget/listview/ListItemISVAndButton.java +++ b/core/tests/coretests/src/android/widget/listview/ListItemISVAndButton.java @@ -17,8 +17,8 @@ package android.widget.listview; import android.content.Context; -import android.util.InternalSelectionView; -import android.util.ListScenario; +import android.widget.InternalSelectionView; +import android.widget.ListScenario; import android.view.View; import android.view.ViewGroup; import android.widget.Button; diff --git a/core/tests/coretests/src/android/widget/listview/ListItemsExpandOnSelection.java b/core/tests/coretests/src/android/widget/listview/ListItemsExpandOnSelection.java index d80fd90de53e..240119e947d6 100644 --- a/core/tests/coretests/src/android/widget/listview/ListItemsExpandOnSelection.java +++ b/core/tests/coretests/src/android/widget/listview/ListItemsExpandOnSelection.java @@ -17,7 +17,7 @@ package android.widget.listview; import android.content.Context; -import android.util.ListScenario; +import android.widget.ListScenario; import android.view.View; import android.view.ViewGroup; import android.widget.AbsListView; diff --git a/core/tests/coretests/src/android/widget/listview/ListLastItemPartiallyVisible.java b/core/tests/coretests/src/android/widget/listview/ListLastItemPartiallyVisible.java index d7337497a443..48c70d6cd84c 100644 --- a/core/tests/coretests/src/android/widget/listview/ListLastItemPartiallyVisible.java +++ b/core/tests/coretests/src/android/widget/listview/ListLastItemPartiallyVisible.java @@ -16,7 +16,7 @@ package android.widget.listview; -import android.util.ListScenario; +import android.widget.ListScenario; /** * A list where the very last item is partially visible, but still requires scrolling diff --git a/core/tests/coretests/src/android/widget/listview/ListOfItemsShorterThanScreen.java b/core/tests/coretests/src/android/widget/listview/ListOfItemsShorterThanScreen.java index 46decfa2e578..55af8d47c803 100644 --- a/core/tests/coretests/src/android/widget/listview/ListOfItemsShorterThanScreen.java +++ b/core/tests/coretests/src/android/widget/listview/ListOfItemsShorterThanScreen.java @@ -16,7 +16,7 @@ package android.widget.listview; -import android.util.ListScenario; +import android.widget.ListScenario; public class ListOfItemsShorterThanScreen extends ListScenario { diff --git a/core/tests/coretests/src/android/widget/listview/ListOfItemsTallerThanScreen.java b/core/tests/coretests/src/android/widget/listview/ListOfItemsTallerThanScreen.java index 0d8899371085..2b619e95f5dc 100644 --- a/core/tests/coretests/src/android/widget/listview/ListOfItemsTallerThanScreen.java +++ b/core/tests/coretests/src/android/widget/listview/ListOfItemsTallerThanScreen.java @@ -16,7 +16,7 @@ package android.widget.listview; -import android.util.ListScenario; +import android.widget.ListScenario; public class ListOfItemsTallerThanScreen extends ListScenario { diff --git a/core/tests/coretests/src/android/widget/listview/ListOfShortShortTallShortShort.java b/core/tests/coretests/src/android/widget/listview/ListOfShortShortTallShortShort.java index 1639aa457cac..09f56b38578f 100644 --- a/core/tests/coretests/src/android/widget/listview/ListOfShortShortTallShortShort.java +++ b/core/tests/coretests/src/android/widget/listview/ListOfShortShortTallShortShort.java @@ -16,7 +16,7 @@ package android.widget.listview; -import android.util.ListScenario; +import android.widget.ListScenario; /** * Exposes fading in and out multiple items. diff --git a/core/tests/coretests/src/android/widget/listview/ListOfShortTallShort.java b/core/tests/coretests/src/android/widget/listview/ListOfShortTallShort.java index 960e1297cb22..8ad8fff735fe 100644 --- a/core/tests/coretests/src/android/widget/listview/ListOfShortTallShort.java +++ b/core/tests/coretests/src/android/widget/listview/ListOfShortTallShort.java @@ -16,7 +16,7 @@ package android.widget.listview; -import android.util.ListScenario; +import android.widget.ListScenario; /** * Two short items separated by one that is taller than the screen. diff --git a/core/tests/coretests/src/android/widget/listview/ListOfThinItems.java b/core/tests/coretests/src/android/widget/listview/ListOfThinItems.java index 007479f01a77..3f703afea752 100644 --- a/core/tests/coretests/src/android/widget/listview/ListOfThinItems.java +++ b/core/tests/coretests/src/android/widget/listview/ListOfThinItems.java @@ -16,7 +16,7 @@ package android.widget.listview; -import android.util.ListScenario; +import android.widget.ListScenario; public class ListOfThinItems extends ListScenario { diff --git a/core/tests/coretests/src/android/widget/listview/ListOfTouchables.java b/core/tests/coretests/src/android/widget/listview/ListOfTouchables.java index 70b9081128a0..f1dcdad20e89 100644 --- a/core/tests/coretests/src/android/widget/listview/ListOfTouchables.java +++ b/core/tests/coretests/src/android/widget/listview/ListOfTouchables.java @@ -16,7 +16,7 @@ package android.widget.listview; -import android.util.ListScenario; +import android.widget.ListScenario; import android.view.View; import android.view.ViewGroup; import android.widget.Button; diff --git a/core/tests/coretests/src/android/widget/listview/ListSetSelection.java b/core/tests/coretests/src/android/widget/listview/ListSetSelection.java index af8e899a867a..a107117250b0 100644 --- a/core/tests/coretests/src/android/widget/listview/ListSetSelection.java +++ b/core/tests/coretests/src/android/widget/listview/ListSetSelection.java @@ -17,7 +17,7 @@ package android.widget.listview; import android.os.Bundle; -import android.util.ListScenario; +import android.widget.ListScenario; import android.view.KeyEvent; import android.view.View; import android.widget.Button; diff --git a/core/tests/coretests/src/android/widget/listview/ListSimple.java b/core/tests/coretests/src/android/widget/listview/ListSimple.java index f53638eb8ff1..9b3a98fe44d6 100644 --- a/core/tests/coretests/src/android/widget/listview/ListSimple.java +++ b/core/tests/coretests/src/android/widget/listview/ListSimple.java @@ -17,7 +17,7 @@ package android.widget.listview; import android.os.Bundle; -import android.util.ListScenario; +import android.widget.ListScenario; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; diff --git a/core/tests/coretests/src/android/widget/listview/ListTopGravity.java b/core/tests/coretests/src/android/widget/listview/ListTopGravity.java index 31339e9ee9c2..67ef6d15538e 100644 --- a/core/tests/coretests/src/android/widget/listview/ListTopGravity.java +++ b/core/tests/coretests/src/android/widget/listview/ListTopGravity.java @@ -16,7 +16,7 @@ package android.widget.listview; -import android.util.ListScenario; +import android.widget.ListScenario; /** * Basic top gravity scenario, nothing fancy. Items do not diff --git a/core/tests/coretests/src/android/widget/listview/ListTopGravityMany.java b/core/tests/coretests/src/android/widget/listview/ListTopGravityMany.java index 5592ad9f6d20..9618c81de5e1 100644 --- a/core/tests/coretests/src/android/widget/listview/ListTopGravityMany.java +++ b/core/tests/coretests/src/android/widget/listview/ListTopGravityMany.java @@ -16,7 +16,7 @@ package android.widget.listview; -import android.util.ListScenario; +import android.widget.ListScenario; /** * Basic top gravity scenario, nothing fancy. There are diff --git a/core/tests/coretests/src/android/widget/listview/ListWithEditTextHeader.java b/core/tests/coretests/src/android/widget/listview/ListWithEditTextHeader.java index 5303faf8d320..1a204a24b9e3 100644 --- a/core/tests/coretests/src/android/widget/listview/ListWithEditTextHeader.java +++ b/core/tests/coretests/src/android/widget/listview/ListWithEditTextHeader.java @@ -16,7 +16,7 @@ package android.widget.listview; -import android.util.ListScenario; +import android.widget.ListScenario; /** * A list view with a single edit text in a header. diff --git a/core/tests/coretests/src/android/widget/listview/ListWithFirstScreenUnSelectable.java b/core/tests/coretests/src/android/widget/listview/ListWithFirstScreenUnSelectable.java index 526128371375..d6e7c6fe6c9e 100644 --- a/core/tests/coretests/src/android/widget/listview/ListWithFirstScreenUnSelectable.java +++ b/core/tests/coretests/src/android/widget/listview/ListWithFirstScreenUnSelectable.java @@ -16,7 +16,7 @@ package android.widget.listview; -import android.util.ListScenario; +import android.widget.ListScenario; /** * The first item is unselectable, and takes up the whole screen. diff --git a/core/tests/coretests/src/android/widget/listview/ListWithHeaders.java b/core/tests/coretests/src/android/widget/listview/ListWithHeaders.java index 6030582a2445..fa2832edf614 100644 --- a/core/tests/coretests/src/android/widget/listview/ListWithHeaders.java +++ b/core/tests/coretests/src/android/widget/listview/ListWithHeaders.java @@ -17,7 +17,7 @@ package android.widget.listview; import android.os.Bundle; -import android.util.ListScenario; +import android.widget.ListScenario; import android.widget.Button; import android.widget.ListAdapter; import android.widget.ListView; diff --git a/core/tests/coretests/src/android/widget/listview/ListWithNoFadingEdge.java b/core/tests/coretests/src/android/widget/listview/ListWithNoFadingEdge.java index b870fc855646..f8b4f786820a 100644 --- a/core/tests/coretests/src/android/widget/listview/ListWithNoFadingEdge.java +++ b/core/tests/coretests/src/android/widget/listview/ListWithNoFadingEdge.java @@ -16,7 +16,7 @@ package android.widget.listview; -import android.util.ListScenario; +import android.widget.ListScenario; public class ListWithNoFadingEdge extends ListScenario { diff --git a/core/tests/coretests/src/android/widget/listview/ListWithOffScreenNextSelectable.java b/core/tests/coretests/src/android/widget/listview/ListWithOffScreenNextSelectable.java index 2e65bd0f2ffe..b8f14d21c1e1 100644 --- a/core/tests/coretests/src/android/widget/listview/ListWithOffScreenNextSelectable.java +++ b/core/tests/coretests/src/android/widget/listview/ListWithOffScreenNextSelectable.java @@ -16,7 +16,7 @@ package android.widget.listview; -import android.util.ListScenario; +import android.widget.ListScenario; /** * Pressing down from position 0 requires looking past positions 1, 2 and 3 to diff --git a/core/tests/coretests/src/android/widget/listview/ListWithOnItemSelectedAction.java b/core/tests/coretests/src/android/widget/listview/ListWithOnItemSelectedAction.java index 13e770cd4e47..afc4c3b754c7 100644 --- a/core/tests/coretests/src/android/widget/listview/ListWithOnItemSelectedAction.java +++ b/core/tests/coretests/src/android/widget/listview/ListWithOnItemSelectedAction.java @@ -16,7 +16,7 @@ package android.widget.listview; -import android.util.ListScenario; +import android.widget.ListScenario; import android.widget.TextView; /** diff --git a/core/tests/coretests/src/android/widget/listview/ListWithScreenOfNoSelectables.java b/core/tests/coretests/src/android/widget/listview/ListWithScreenOfNoSelectables.java index 108ac4d9e6f6..fe33bf05acb3 100644 --- a/core/tests/coretests/src/android/widget/listview/ListWithScreenOfNoSelectables.java +++ b/core/tests/coretests/src/android/widget/listview/ListWithScreenOfNoSelectables.java @@ -16,7 +16,7 @@ package android.widget.listview; -import android.util.ListScenario; +import android.widget.ListScenario; public class ListWithScreenOfNoSelectables extends ListScenario { diff --git a/core/tests/coretests/src/android/widget/listview/ListWithSeparators.java b/core/tests/coretests/src/android/widget/listview/ListWithSeparators.java index 0f4f2d88a41b..1a3955a4b1cb 100644 --- a/core/tests/coretests/src/android/widget/listview/ListWithSeparators.java +++ b/core/tests/coretests/src/android/widget/listview/ListWithSeparators.java @@ -16,7 +16,7 @@ package android.widget.listview; -import android.util.ListScenario; +import android.widget.ListScenario; /** * Basic separator scenario, nothing fancy. diff --git a/core/tests/coretests/src/android/widget/listview/focus/AdjacentListsWithAdjacentISVsInsideTest.java b/core/tests/coretests/src/android/widget/listview/focus/AdjacentListsWithAdjacentISVsInsideTest.java index e9baabf3175a..09c140ee96d9 100644 --- a/core/tests/coretests/src/android/widget/listview/focus/AdjacentListsWithAdjacentISVsInsideTest.java +++ b/core/tests/coretests/src/android/widget/listview/focus/AdjacentListsWithAdjacentISVsInsideTest.java @@ -17,7 +17,7 @@ package android.widget.listview.focus; import android.test.ActivityInstrumentationTestCase; -import android.util.InternalSelectionView; +import android.widget.InternalSelectionView; import android.view.KeyEvent; import android.widget.ListView; import android.widget.listview.AdjacentListsWithAdjacentISVsInside; diff --git a/core/tests/coretests/src/android/widget/scroll/ButtonAboveTallInternalSelectionView.java b/core/tests/coretests/src/android/widget/scroll/ButtonAboveTallInternalSelectionView.java index a30985bfaf87..30f5c67f9f4e 100644 --- a/core/tests/coretests/src/android/widget/scroll/ButtonAboveTallInternalSelectionView.java +++ b/core/tests/coretests/src/android/widget/scroll/ButtonAboveTallInternalSelectionView.java @@ -16,8 +16,8 @@ package android.widget.scroll; -import android.util.InternalSelectionView; -import android.util.ScrollViewScenario; +import android.widget.InternalSelectionView; +import android.widget.ScrollViewScenario; import android.widget.Button; /** diff --git a/core/tests/coretests/src/android/widget/scroll/ButtonAboveTallInternalSelectionViewTest.java b/core/tests/coretests/src/android/widget/scroll/ButtonAboveTallInternalSelectionViewTest.java index 825aa1aa85a3..d977ab4c7efa 100644 --- a/core/tests/coretests/src/android/widget/scroll/ButtonAboveTallInternalSelectionViewTest.java +++ b/core/tests/coretests/src/android/widget/scroll/ButtonAboveTallInternalSelectionViewTest.java @@ -17,7 +17,7 @@ package android.widget.scroll; import android.test.ActivityInstrumentationTestCase; -import android.util.InternalSelectionView; +import android.widget.InternalSelectionView; import android.view.KeyEvent; import androidx.test.filters.MediumTest; diff --git a/core/tests/coretests/src/android/widget/scroll/ButtonsWithTallTextViewInBetween.java b/core/tests/coretests/src/android/widget/scroll/ButtonsWithTallTextViewInBetween.java index 47d36ddf9be1..5149fd43bc65 100644 --- a/core/tests/coretests/src/android/widget/scroll/ButtonsWithTallTextViewInBetween.java +++ b/core/tests/coretests/src/android/widget/scroll/ButtonsWithTallTextViewInBetween.java @@ -16,7 +16,7 @@ package android.widget.scroll; -import android.util.ScrollViewScenario; +import android.widget.ScrollViewScenario; import android.widget.Button; import android.widget.LinearLayout; import android.widget.TextView; diff --git a/core/tests/coretests/src/android/widget/scroll/ShortButtons.java b/core/tests/coretests/src/android/widget/scroll/ShortButtons.java index 90ede7d35511..01d3b53ba062 100644 --- a/core/tests/coretests/src/android/widget/scroll/ShortButtons.java +++ b/core/tests/coretests/src/android/widget/scroll/ShortButtons.java @@ -16,7 +16,7 @@ package android.widget.scroll; -import android.util.ScrollViewScenario; +import android.widget.ScrollViewScenario; import android.widget.Button; import android.widget.LinearLayout; diff --git a/core/tests/coretests/src/android/widget/scroll/TallTextAboveButton.java b/core/tests/coretests/src/android/widget/scroll/TallTextAboveButton.java index 4096fe9c1c2e..bf800c0d09d7 100644 --- a/core/tests/coretests/src/android/widget/scroll/TallTextAboveButton.java +++ b/core/tests/coretests/src/android/widget/scroll/TallTextAboveButton.java @@ -16,7 +16,7 @@ package android.widget.scroll; -import android.util.ScrollViewScenario; +import android.widget.ScrollViewScenario; /** * An (unfocusable) text view that takes up more than the height diff --git a/core/tests/coretests/src/android/widget/scroll/arrowscroll/MultiPageTextWithPadding.java b/core/tests/coretests/src/android/widget/scroll/arrowscroll/MultiPageTextWithPadding.java index 7d5a8d8441e8..6febdf96ebbb 100644 --- a/core/tests/coretests/src/android/widget/scroll/arrowscroll/MultiPageTextWithPadding.java +++ b/core/tests/coretests/src/android/widget/scroll/arrowscroll/MultiPageTextWithPadding.java @@ -16,7 +16,7 @@ package android.widget.scroll.arrowscroll; -import android.util.ScrollViewScenario; +import android.widget.ScrollViewScenario; /** * One TextView with a text covering several pages. Padding is added -- cgit v1.2.3-59-g8ed1b From 3e68053d37d71e99cc0d416e2bdc85861ef6defe Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Tue, 5 Dec 2023 16:17:33 -0700 Subject: Support more utils under Ravenwood. Tests for these internal utils are local within the frameworks/base/ repo, instead of in CTS. To help future-proof, bring the entire utils/* test directory by default into the Ravenwood suites, and give developers the way to easily opt-out with @IgnoreUnderRavenwood at the class level. Bug: 292141694 Test: atest FrameworksCoreTestsRavenwood FrameworksCoreTests Test: atest FrameworksUtilTestsRavenwood FrameworksUtilTests Change-Id: Ibcabec764efa31cc8cb4c56d7815948d4029aaea --- core/java/android/util/DayOfMonthCursor.java | 1 + core/java/android/util/KeyValueListParser.java | 1 + core/java/android/util/LongArrayQueue.java | 1 + core/java/android/util/LongSparseLongArray.java | 1 + core/java/android/util/MonthDisplayHelper.java | 1 + core/java/android/util/RecurrenceRule.java | 1 + core/java/android/util/RotationUtils.java | 1 + core/java/android/util/SparseDoubleArray.java | 1 + core/java/android/util/SparseSetArray.java | 1 + core/java/android/util/StateSet.java | 1 - core/java/android/util/Xml.java | 2 + core/tests/coretests/Android.bp | 9 ++ .../coretests/src/android/util/ArrayMapTest.java | 17 ++- .../coretests/src/android/util/ArraySetTest.java | 9 +- .../coretests/src/android/util/Base64Test.java | 111 ++++++++++--------- .../src/android/util/CharsetUtilsTest.java | 14 ++- .../coretests/src/android/util/CloseGuardTest.java | 16 ++- .../src/android/util/DayOfMonthCursorTest.java | 31 +++--- .../src/android/util/HashedStringCacheTest.java | 17 ++- .../src/android/util/LogNullabilityTest.java | 54 ++++----- core/tests/coretests/src/android/util/LogTest.java | 22 ++-- .../src/android/util/LongSparseLongArrayTest.java | 13 ++- .../coretests/src/android/util/LruCacheTest.java | 39 ++++++- .../src/android/util/MonthDisplayHelperTest.java | 23 +++- .../src/android/util/NtpTrustedTimeTest.java | 8 ++ .../coretests/src/android/util/PatternsTest.java | 121 ++++++++++++++++++++- .../src/android/util/RecurrenceRuleTest.java | 28 +++-- .../src/android/util/SparseSetArrayTest.java | 8 ++ .../coretests/src/android/util/StateSetTest.java | 28 ++++- .../android/util/apk/SourceStampVerifierTest.java | 14 ++- .../src/android/util/MetadataReaderTest.java | 4 +- .../framework-minus-apex-ravenwood-policies.txt | 1 + ravenwood/ravenwood-annotation-allowed-classes.txt | 9 ++ 33 files changed, 470 insertions(+), 138 deletions(-) diff --git a/core/java/android/util/DayOfMonthCursor.java b/core/java/android/util/DayOfMonthCursor.java index 393b98e324d3..ac5dc3a169c8 100644 --- a/core/java/android/util/DayOfMonthCursor.java +++ b/core/java/android/util/DayOfMonthCursor.java @@ -32,6 +32,7 @@ package android.util; * * @hide */ +@android.ravenwood.annotation.RavenwoodKeepWholeClass public class DayOfMonthCursor extends MonthDisplayHelper { private int mRow; diff --git a/core/java/android/util/KeyValueListParser.java b/core/java/android/util/KeyValueListParser.java index fbc66e6bda2a..783b2d63bcf3 100644 --- a/core/java/android/util/KeyValueListParser.java +++ b/core/java/android/util/KeyValueListParser.java @@ -28,6 +28,7 @@ import java.time.format.DateTimeParseException; * can be used. * @hide */ +@android.ravenwood.annotation.RavenwoodKeepWholeClass public class KeyValueListParser { private final ArrayMap mValues = new ArrayMap<>(); private final TextUtils.StringSplitter mSplitter; diff --git a/core/java/android/util/LongArrayQueue.java b/core/java/android/util/LongArrayQueue.java index 354f8df0a43d..b9752fe4d1cc 100644 --- a/core/java/android/util/LongArrayQueue.java +++ b/core/java/android/util/LongArrayQueue.java @@ -28,6 +28,7 @@ import java.util.NoSuchElementException; * * @hide */ +@android.ravenwood.annotation.RavenwoodKeepWholeClass public class LongArrayQueue { private long[] mValues; diff --git a/core/java/android/util/LongSparseLongArray.java b/core/java/android/util/LongSparseLongArray.java index d4a012602f80..86268facbec0 100644 --- a/core/java/android/util/LongSparseLongArray.java +++ b/core/java/android/util/LongSparseLongArray.java @@ -46,6 +46,7 @@ import com.android.internal.util.Preconditions; * * @hide */ +@android.ravenwood.annotation.RavenwoodKeepWholeClass public class LongSparseLongArray implements Cloneable { @UnsupportedAppUsage(maxTargetSdk = 28) // The type isn't even public. private long[] mKeys; diff --git a/core/java/android/util/MonthDisplayHelper.java b/core/java/android/util/MonthDisplayHelper.java index c3f13fc2176b..3bd292b4ba49 100644 --- a/core/java/android/util/MonthDisplayHelper.java +++ b/core/java/android/util/MonthDisplayHelper.java @@ -24,6 +24,7 @@ import java.util.Calendar; * * Not thread safe. */ +@android.ravenwood.annotation.RavenwoodKeepWholeClass public class MonthDisplayHelper { // display pref diff --git a/core/java/android/util/RecurrenceRule.java b/core/java/android/util/RecurrenceRule.java index 39d1f2cbef19..dc470d7edc53 100644 --- a/core/java/android/util/RecurrenceRule.java +++ b/core/java/android/util/RecurrenceRule.java @@ -42,6 +42,7 @@ import java.util.Objects; * * @hide */ +@android.ravenwood.annotation.RavenwoodKeepWholeClass public class RecurrenceRule implements Parcelable { private static final String TAG = "RecurrenceRule"; private static final boolean LOGD = Log.isLoggable(TAG, Log.DEBUG); diff --git a/core/java/android/util/RotationUtils.java b/core/java/android/util/RotationUtils.java index f20767b7485a..07ab996af12f 100644 --- a/core/java/android/util/RotationUtils.java +++ b/core/java/android/util/RotationUtils.java @@ -36,6 +36,7 @@ import android.view.SurfaceControl; * * @hide */ +@android.ravenwood.annotation.RavenwoodKeepWholeClass public class RotationUtils { /** diff --git a/core/java/android/util/SparseDoubleArray.java b/core/java/android/util/SparseDoubleArray.java index 4b0cbe45d857..8a0b11e09d89 100644 --- a/core/java/android/util/SparseDoubleArray.java +++ b/core/java/android/util/SparseDoubleArray.java @@ -41,6 +41,7 @@ package android.util; * * @hide */ +@android.ravenwood.annotation.RavenwoodKeepWholeClass public class SparseDoubleArray implements Cloneable { /** * The int->double map, but storing the doubles as longs using diff --git a/core/java/android/util/SparseSetArray.java b/core/java/android/util/SparseSetArray.java index 61f29a40ff50..80f6a4a0847f 100644 --- a/core/java/android/util/SparseSetArray.java +++ b/core/java/android/util/SparseSetArray.java @@ -22,6 +22,7 @@ import android.annotation.NonNull; * * @hide */ +@android.ravenwood.annotation.RavenwoodKeepWholeClass public class SparseSetArray { private final SparseArray> mData; diff --git a/core/java/android/util/StateSet.java b/core/java/android/util/StateSet.java index 4bbc0f863603..16d6082649a7 100644 --- a/core/java/android/util/StateSet.java +++ b/core/java/android/util/StateSet.java @@ -34,7 +34,6 @@ import com.android.internal.R; * and not have static methods here but there is some concern about * performance since these methods are called during view drawing. */ - public class StateSet { /** * The order here is very important to diff --git a/core/java/android/util/Xml.java b/core/java/android/util/Xml.java index 2a33caaf7e28..ec6e90b4153e 100644 --- a/core/java/android/util/Xml.java +++ b/core/java/android/util/Xml.java @@ -334,6 +334,7 @@ public class Xml { * * @hide */ + @android.ravenwood.annotation.RavenwoodKeep public static void copy(@NonNull XmlPullParser in, @NonNull XmlSerializer out) throws XmlPullParserException, IOException { // Some parsers may have already consumed the event that starts the @@ -393,6 +394,7 @@ public class Xml { * unsupported, which can confuse serializers. This method normalizes empty * strings to be {@code null}. */ + @android.ravenwood.annotation.RavenwoodKeep private static @Nullable String normalizeNamespace(@Nullable String namespace) { if (namespace == null || namespace.isEmpty()) { return null; diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp index 21a406988104..0ad349ba5281 100644 --- a/core/tests/coretests/Android.bp +++ b/core/tests/coretests/Android.bp @@ -167,13 +167,22 @@ android_library { android_ravenwood_test { name: "FrameworksCoreTestsRavenwood", + libs: [ + "android.test.runner", + "android.test.base", + ], static_libs: [ + "core-test-rules", // for libcore.dalvik.system.CloseGuardSupport "androidx.core_core", "androidx.annotation_annotation", "androidx.test.rules", + "androidx.test.ext.junit", + "mockito_ravenwood", + "platform-test-annotations", ], srcs: [ "src/android/os/FileUtilsTest.java", + "src/android/util/**/*.java", "src/com/android/internal/util/**/*.java", "testdoubles/src/com/android/internal/util/**/*.java", ], diff --git a/core/tests/coretests/src/android/util/ArrayMapTest.java b/core/tests/coretests/src/android/util/ArrayMapTest.java index b212cf6b0803..1e444adbc362 100644 --- a/core/tests/coretests/src/android/util/ArrayMapTest.java +++ b/core/tests/coretests/src/android/util/ArrayMapTest.java @@ -14,11 +14,17 @@ package android.util; -import androidx.test.filters.LargeTest; +import static org.junit.Assert.fail; + +import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.ravenwood.RavenwoodRule; -import junit.framework.TestCase; +import androidx.test.filters.LargeTest; +import androidx.test.runner.AndroidJUnit4; +import org.junit.Rule; import org.junit.Test; +import org.junit.runner.RunWith; import java.util.ConcurrentModificationException; @@ -26,10 +32,14 @@ import java.util.ConcurrentModificationException; * Unit tests for ArrayMap that don't belong in CTS. */ @LargeTest -public class ArrayMapTest extends TestCase { +@RunWith(AndroidJUnit4.class) +public class ArrayMapTest { private static final String TAG = "ArrayMapTest"; ArrayMap map = new ArrayMap<>(); + @Rule + public final RavenwoodRule mRavenwood = new RavenwoodRule(); + /** * Attempt to generate a ConcurrentModificationException in ArrayMap. *

@@ -41,6 +51,7 @@ public class ArrayMapTest extends TestCase { * @throws Exception */ @Test + @IgnoreUnderRavenwood(reason = "Long test runtime") public void testConcurrentModificationException() throws Exception { final int TEST_LEN_MS = 5000; System.out.println("Starting ArrayMap concurrency test"); diff --git a/core/tests/coretests/src/android/util/ArraySetTest.java b/core/tests/coretests/src/android/util/ArraySetTest.java index f1bebfb9bd93..51de6341179b 100644 --- a/core/tests/coretests/src/android/util/ArraySetTest.java +++ b/core/tests/coretests/src/android/util/ArraySetTest.java @@ -16,12 +16,14 @@ package android.util; -import androidx.test.filters.LargeTest; +import static org.junit.Assert.fail; -import junit.framework.TestCase; +import androidx.test.filters.LargeTest; +import androidx.test.runner.AndroidJUnit4; import org.junit.After; import org.junit.Test; +import org.junit.runner.RunWith; import java.util.ConcurrentModificationException; @@ -29,7 +31,8 @@ import java.util.ConcurrentModificationException; * Unit tests for ArraySet that don't belong in CTS. */ @LargeTest -public class ArraySetTest extends TestCase { +@RunWith(AndroidJUnit4.class) +public class ArraySetTest { private static final String TAG = "ArraySetTest"; ArraySet mSet = new ArraySet<>(); diff --git a/core/tests/coretests/src/android/util/Base64Test.java b/core/tests/coretests/src/android/util/Base64Test.java index 15c51af0b3e1..b64826611f81 100644 --- a/core/tests/coretests/src/android/util/Base64Test.java +++ b/core/tests/coretests/src/android/util/Base64Test.java @@ -16,9 +16,16 @@ package android.util; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + import androidx.test.filters.LargeTest; +import androidx.test.runner.AndroidJUnit4; -import junit.framework.TestCase; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -32,7 +39,8 @@ import java.util.Random; import java.util.stream.Collectors; @LargeTest -public class Base64Test extends TestCase { +@RunWith(AndroidJUnit4.class) +public class Base64Test { private static final String TAG = "Base64Test"; /** Decodes a string, returning a string. */ @@ -62,7 +70,7 @@ public class Base64Test extends TestCase { } /** Assert that actual equals the first len bytes of expected. */ - private void assertEquals(byte[] expected, int len, byte[] actual) { + private void assertPartialEquals(byte[] expected, int len, byte[] actual) { assertEquals(len, actual.length); for (int i = 0; i < len; ++i) { assertEquals(expected[i], actual[i]); @@ -70,21 +78,14 @@ public class Base64Test extends TestCase { } /** Assert that actual equals the first len bytes of expected. */ - private void assertEquals(byte[] expected, int len, byte[] actual, int alen) { + private void assertPartialEquals(byte[] expected, int len, byte[] actual, int alen) { assertEquals(len, alen); for (int i = 0; i < len; ++i) { assertEquals(expected[i], actual[i]); } } - /** Assert that actual equals the first len bytes of expected. */ - private void assertEquals(byte[] expected, byte[] actual) { - assertEquals(expected.length, actual.length); - for (int i = 0; i < expected.length; ++i) { - assertEquals(expected[i], actual[i]); - } - } - + @Test public void testDecodeExtraChars() throws Exception { // padding 0 assertEquals("hello, world", decodeString("aGVsbG8sIHdvcmxk")); @@ -131,28 +132,30 @@ public class Base64Test extends TestCase { (byte) 0xcc, (byte) 0xbb, (byte) 0xaa, (byte) 0x99, (byte) 0x88, (byte) 0x77 }; + @Test public void testBinaryDecode() throws Exception { - assertEquals(BYTES, 0, Base64.decode("", 0)); - assertEquals(BYTES, 1, Base64.decode("/w==", 0)); - assertEquals(BYTES, 2, Base64.decode("/+4=", 0)); - assertEquals(BYTES, 3, Base64.decode("/+7d", 0)); - assertEquals(BYTES, 4, Base64.decode("/+7dzA==", 0)); - assertEquals(BYTES, 5, Base64.decode("/+7dzLs=", 0)); - assertEquals(BYTES, 6, Base64.decode("/+7dzLuq", 0)); - assertEquals(BYTES, 7, Base64.decode("/+7dzLuqmQ==", 0)); - assertEquals(BYTES, 8, Base64.decode("/+7dzLuqmYg=", 0)); + assertPartialEquals(BYTES, 0, Base64.decode("", 0)); + assertPartialEquals(BYTES, 1, Base64.decode("/w==", 0)); + assertPartialEquals(BYTES, 2, Base64.decode("/+4=", 0)); + assertPartialEquals(BYTES, 3, Base64.decode("/+7d", 0)); + assertPartialEquals(BYTES, 4, Base64.decode("/+7dzA==", 0)); + assertPartialEquals(BYTES, 5, Base64.decode("/+7dzLs=", 0)); + assertPartialEquals(BYTES, 6, Base64.decode("/+7dzLuq", 0)); + assertPartialEquals(BYTES, 7, Base64.decode("/+7dzLuqmQ==", 0)); + assertPartialEquals(BYTES, 8, Base64.decode("/+7dzLuqmYg=", 0)); } + @Test public void testWebSafe() throws Exception { - assertEquals(BYTES, 0, Base64.decode("", Base64.URL_SAFE)); - assertEquals(BYTES, 1, Base64.decode("_w==", Base64.URL_SAFE)); - assertEquals(BYTES, 2, Base64.decode("_-4=", Base64.URL_SAFE)); - assertEquals(BYTES, 3, Base64.decode("_-7d", Base64.URL_SAFE)); - assertEquals(BYTES, 4, Base64.decode("_-7dzA==", Base64.URL_SAFE)); - assertEquals(BYTES, 5, Base64.decode("_-7dzLs=", Base64.URL_SAFE)); - assertEquals(BYTES, 6, Base64.decode("_-7dzLuq", Base64.URL_SAFE)); - assertEquals(BYTES, 7, Base64.decode("_-7dzLuqmQ==", Base64.URL_SAFE)); - assertEquals(BYTES, 8, Base64.decode("_-7dzLuqmYg=", Base64.URL_SAFE)); + assertPartialEquals(BYTES, 0, Base64.decode("", Base64.URL_SAFE)); + assertPartialEquals(BYTES, 1, Base64.decode("_w==", Base64.URL_SAFE)); + assertPartialEquals(BYTES, 2, Base64.decode("_-4=", Base64.URL_SAFE)); + assertPartialEquals(BYTES, 3, Base64.decode("_-7d", Base64.URL_SAFE)); + assertPartialEquals(BYTES, 4, Base64.decode("_-7dzA==", Base64.URL_SAFE)); + assertPartialEquals(BYTES, 5, Base64.decode("_-7dzLs=", Base64.URL_SAFE)); + assertPartialEquals(BYTES, 6, Base64.decode("_-7dzLuq", Base64.URL_SAFE)); + assertPartialEquals(BYTES, 7, Base64.decode("_-7dzLuqmQ==", Base64.URL_SAFE)); + assertPartialEquals(BYTES, 8, Base64.decode("_-7dzLuqmYg=", Base64.URL_SAFE)); assertEquals("", Base64.encodeToString(BYTES, 0, 0, Base64.URL_SAFE)); assertEquals("_w==\n", Base64.encodeToString(BYTES, 0, 1, Base64.URL_SAFE)); @@ -165,6 +168,7 @@ public class Base64Test extends TestCase { assertEquals("_-7dzLuqmYg=\n", Base64.encodeToString(BYTES, 0, 8, Base64.URL_SAFE)); } + @Test public void testFlags() throws Exception { assertEquals("YQ==\n", encodeToString("a", 0)); assertEquals("YQ==", encodeToString("a", Base64.NO_WRAP)); @@ -195,6 +199,7 @@ public class Base64Test extends TestCase { assertEquals("YWJjZA\r\n", encodeToString("abcd", Base64.CRLF | Base64.NO_PADDING)); } + @Test public void testLineLength() throws Exception { String in_56 = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd"; String in_57 = in_56 + "e"; @@ -245,7 +250,9 @@ public class Base64Test extends TestCase { * us to get at package-private members (Base64.Encoder in * this case). */ - public void XXXtestEncodeInternal() throws Exception { + @Test + @Ignore + public void testEncodeInternal() throws Exception { byte[] input = { (byte) 0x61, (byte) 0x62, (byte) 0x63 }; byte[] output = new byte[100]; @@ -253,11 +260,11 @@ public class Base64Test extends TestCase { output); encoder.process(input, 0, 3, false); - assertEquals("YWJj".getBytes(), 4, encoder.output, encoder.op); + assertPartialEquals("YWJj".getBytes(), 4, encoder.output, encoder.op); assertEquals(0, encoder.tailLen); encoder.process(input, 0, 3, false); - assertEquals("YWJj".getBytes(), 4, encoder.output, encoder.op); + assertPartialEquals("YWJj".getBytes(), 4, encoder.output, encoder.op); assertEquals(0, encoder.tailLen); encoder.process(input, 0, 1, false); @@ -269,7 +276,7 @@ public class Base64Test extends TestCase { assertEquals(2, encoder.tailLen); encoder.process(input, 0, 1, false); - assertEquals("YWFh".getBytes(), 4, encoder.output, encoder.op); + assertPartialEquals("YWFh".getBytes(), 4, encoder.output, encoder.op); assertEquals(0, encoder.tailLen); encoder.process(input, 0, 2, false); @@ -277,15 +284,15 @@ public class Base64Test extends TestCase { assertEquals(2, encoder.tailLen); encoder.process(input, 0, 2, false); - assertEquals("YWJh".getBytes(), 4, encoder.output, encoder.op); + assertPartialEquals("YWJh".getBytes(), 4, encoder.output, encoder.op); assertEquals(1, encoder.tailLen); encoder.process(input, 0, 2, false); - assertEquals("YmFi".getBytes(), 4, encoder.output, encoder.op); + assertPartialEquals("YmFi".getBytes(), 4, encoder.output, encoder.op); assertEquals(0, encoder.tailLen); encoder.process(input, 0, 1, true); - assertEquals("YQ".getBytes(), 2, encoder.output, encoder.op); + assertPartialEquals("YQ".getBytes(), 2, encoder.output, encoder.op); } private static final String lipsum = @@ -311,6 +318,7 @@ public class Base64Test extends TestCase { "molestie dapibus commodo. Ut vel tellus at massa gravida " + "semper non sed orci."; + @Test public void testInputStream() throws Exception { int[] flagses = { Base64.DEFAULT, Base64.NO_PADDING, @@ -343,7 +351,7 @@ public class Base64Test extends TestCase { while ((b = b64is.read(actual, ap, actual.length-ap)) != -1) { ap += b; } - assertEquals(actual, ap, plain); + assertPartialEquals(actual, ap, plain); // read individual bytes bais = new ByteArrayInputStream(encoded); @@ -352,7 +360,7 @@ public class Base64Test extends TestCase { while ((b = b64is.read()) != -1) { actual[ap++] = (byte) b; } - assertEquals(actual, ap, plain); + assertPartialEquals(actual, ap, plain); // mix reads of variously-sized arrays with one-byte reads bais = new ByteArrayInputStream(encoded); @@ -371,7 +379,7 @@ public class Base64Test extends TestCase { } } } - assertEquals(actual, ap, plain); + assertPartialEquals(actual, ap, plain); // ----- test encoding ("plain" -> "encoded") ----- @@ -382,7 +390,7 @@ public class Base64Test extends TestCase { while ((b = b64is.read(actual, ap, actual.length-ap)) != -1) { ap += b; } - assertEquals(actual, ap, encoded); + assertPartialEquals(actual, ap, encoded); // read individual bytes bais = new ByteArrayInputStream(plain); @@ -391,7 +399,7 @@ public class Base64Test extends TestCase { while ((b = b64is.read()) != -1) { actual[ap++] = (byte) b; } - assertEquals(actual, ap, encoded); + assertPartialEquals(actual, ap, encoded); // mix reads of variously-sized arrays with one-byte reads bais = new ByteArrayInputStream(plain); @@ -410,11 +418,12 @@ public class Base64Test extends TestCase { } } } - assertEquals(actual, ap, encoded); + assertPartialEquals(actual, ap, encoded); } } /** http://b/3026478 */ + @Test public void testSingleByteReads() throws IOException { InputStream in = new Base64InputStream( new ByteArrayInputStream("/v8=".getBytes()), Base64.DEFAULT); @@ -426,6 +435,7 @@ public class Base64Test extends TestCase { * Tests that Base64OutputStream produces exactly the same results * as calling Base64.encode/.decode on an in-memory array. */ + @Test public void testOutputStream() throws Exception { int[] flagses = { Base64.DEFAULT, Base64.NO_PADDING, @@ -456,7 +466,7 @@ public class Base64Test extends TestCase { b64os.write(plain); b64os.close(); actual = baos.toByteArray(); - assertEquals(encoded, actual); + assertArrayEquals(encoded, actual); // many calls to write(int) baos = new ByteArrayOutputStream(); @@ -466,7 +476,7 @@ public class Base64Test extends TestCase { } b64os.close(); actual = baos.toByteArray(); - assertEquals(encoded, actual); + assertArrayEquals(encoded, actual); // intermixed sequences of write(int) with // write(byte[],int,int) of various lengths. @@ -489,7 +499,7 @@ public class Base64Test extends TestCase { } b64os.close(); actual = baos.toByteArray(); - assertEquals(encoded, actual); + assertArrayEquals(encoded, actual); // ----- test decoding ("encoded" -> "plain") ----- @@ -499,7 +509,7 @@ public class Base64Test extends TestCase { b64os.write(encoded); b64os.close(); actual = baos.toByteArray(); - assertEquals(plain, actual); + assertArrayEquals(plain, actual); // many calls to write(int) baos = new ByteArrayOutputStream(); @@ -509,7 +519,7 @@ public class Base64Test extends TestCase { } b64os.close(); actual = baos.toByteArray(); - assertEquals(plain, actual); + assertArrayEquals(plain, actual); // intermixed sequences of write(int) with // write(byte[],int,int) of various lengths. @@ -532,10 +542,11 @@ public class Base64Test extends TestCase { } b64os.close(); actual = baos.toByteArray(); - assertEquals(plain, actual); + assertArrayEquals(plain, actual); } } + @Test public void testOutputStream_ioExceptionDuringClose() { OutputStream out = new OutputStream() { @Override public void write(int b) throws IOException { } @@ -551,6 +562,7 @@ public class Base64Test extends TestCase { } } + @Test public void testOutputStream_ioExceptionDuringCloseAndWrite() { OutputStream out = new OutputStream() { @Override public void write(int b) throws IOException { @@ -583,6 +595,7 @@ public class Base64Test extends TestCase { } } + @Test public void testOutputStream_ioExceptionDuringWrite() { OutputStream out = new OutputStream() { @Override public void write(int b) throws IOException { diff --git a/core/tests/coretests/src/android/util/CharsetUtilsTest.java b/core/tests/coretests/src/android/util/CharsetUtilsTest.java index c29545168758..fbbe311d44fb 100644 --- a/core/tests/coretests/src/android/util/CharsetUtilsTest.java +++ b/core/tests/coretests/src/android/util/CharsetUtilsTest.java @@ -18,6 +18,9 @@ package android.util; import static org.junit.Assert.assertEquals; +import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.ravenwood.RavenwoodRule; + import androidx.test.runner.AndroidJUnit4; import com.android.internal.util.HexDump; @@ -25,18 +28,25 @@ import com.android.internal.util.HexDump; import dalvik.system.VMRuntime; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) +@IgnoreUnderRavenwood(blockedBy = CharsetUtils.class) public class CharsetUtilsTest { + @Rule + public final RavenwoodRule mRavenwood = new RavenwoodRule(); + private byte[] dest; private long destPtr; @Before public void setUp() { - dest = (byte[]) VMRuntime.getRuntime().newNonMovableArray(byte.class, 8); - destPtr = VMRuntime.getRuntime().addressOf(dest); + if (!RavenwoodRule.isUnderRavenwood()) { + dest = (byte[]) VMRuntime.getRuntime().newNonMovableArray(byte.class, 8); + destPtr = VMRuntime.getRuntime().addressOf(dest); + } } @Test diff --git a/core/tests/coretests/src/android/util/CloseGuardTest.java b/core/tests/coretests/src/android/util/CloseGuardTest.java index d86c7b79fad6..15c57b1aa6f7 100644 --- a/core/tests/coretests/src/android/util/CloseGuardTest.java +++ b/core/tests/coretests/src/android/util/CloseGuardTest.java @@ -16,6 +16,9 @@ package android.util; +import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.ravenwood.RavenwoodRule; + import libcore.dalvik.system.CloseGuardSupport; import org.junit.Rule; @@ -23,10 +26,21 @@ import org.junit.Test; import org.junit.rules.TestRule; /** Unit tests for {@link android.util.CloseGuard} */ +@IgnoreUnderRavenwood(blockedBy = CloseGuard.class) public class CloseGuardTest { + @Rule + public final RavenwoodRule mRavenwood = new RavenwoodRule(); @Rule - public final TestRule rule = CloseGuardSupport.getRule(); + public final TestRule rule; + + public CloseGuardTest() { + if (!RavenwoodRule.isUnderRavenwood()) { + rule = CloseGuardSupport.getRule(); + } else { + rule = null; + } + } @Test public void testEnabled_NotOpen() throws Throwable { diff --git a/core/tests/coretests/src/android/util/DayOfMonthCursorTest.java b/core/tests/coretests/src/android/util/DayOfMonthCursorTest.java index 572e9b062097..72bd578ad8b9 100644 --- a/core/tests/coretests/src/android/util/DayOfMonthCursorTest.java +++ b/core/tests/coretests/src/android/util/DayOfMonthCursorTest.java @@ -16,30 +16,40 @@ package android.util; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; import java.util.Calendar; /** * Unit tests for {@link DayOfMonthCursor}. */ -public class DayOfMonthCursorTest extends TestCase { +@RunWith(AndroidJUnit4.class) +public class DayOfMonthCursorTest { + @Test @SmallTest public void testMonthRows() { DayOfMonthCursor mc = new DayOfMonthCursor(2007, Calendar.SEPTEMBER, 11, Calendar.SUNDAY); - assertArraysEqual(new int[]{26, 27, 28, 29, 30, 31, 1}, + assertArrayEquals(new int[]{26, 27, 28, 29, 30, 31, 1}, mc.getDigitsForRow(0)); - assertArraysEqual(new int[]{2, 3, 4, 5, 6, 7, 8}, + assertArrayEquals(new int[]{2, 3, 4, 5, 6, 7, 8}, mc.getDigitsForRow(1)); - assertArraysEqual(new int[]{30, 1, 2, 3, 4, 5, 6}, + assertArrayEquals(new int[]{30, 1, 2, 3, 4, 5, 6}, mc.getDigitsForRow(5)); } + @Test @SmallTest public void testMoveLeft() { DayOfMonthCursor mc = new DayOfMonthCursor(2007, @@ -70,6 +80,7 @@ public class DayOfMonthCursorTest extends TestCase { assertEquals(5, mc.getSelectedColumn()); } + @Test @SmallTest public void testMoveRight() { DayOfMonthCursor mc = new DayOfMonthCursor(2007, @@ -100,6 +111,7 @@ public class DayOfMonthCursorTest extends TestCase { assertEquals(1, mc.getSelectedColumn()); } + @Test @SmallTest public void testMoveUp() { DayOfMonthCursor mc = new DayOfMonthCursor(2007, @@ -124,6 +136,7 @@ public class DayOfMonthCursorTest extends TestCase { assertEquals(4, mc.getSelectedColumn()); } + @Test @SmallTest public void testMoveDown() { DayOfMonthCursor mc = new DayOfMonthCursor(2007, @@ -147,12 +160,4 @@ public class DayOfMonthCursorTest extends TestCase { assertEquals(1, mc.getSelectedRow()); assertEquals(0, mc.getSelectedColumn()); } - - private void assertArraysEqual(int[] expected, int[] actual) { - assertEquals("array length", expected.length, actual.length); - for (int i = 0; i < expected.length; i++) { - assertEquals("index " + i, - expected[i], actual[i]); - } - } } diff --git a/core/tests/coretests/src/android/util/HashedStringCacheTest.java b/core/tests/coretests/src/android/util/HashedStringCacheTest.java index 229247353a52..08c85ac5c0d6 100644 --- a/core/tests/coretests/src/android/util/HashedStringCacheTest.java +++ b/core/tests/coretests/src/android/util/HashedStringCacheTest.java @@ -26,28 +26,37 @@ import android.content.Context; import android.content.SharedPreferences; import android.os.Environment; import android.os.storage.StorageManager; +import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.InstrumentationRegistry; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import java.io.File; - /** * Unit tests for {@link HashedStringCache}. */ +@IgnoreUnderRavenwood(blockedBy = HashedStringCache.class) public class HashedStringCacheTest { private static final String TAG = "HashedStringCacheTest"; private Context mContext; private static final String TEST_STRING = "test_string"; + @Rule + public final RavenwoodRule mRavenwood = new RavenwoodRule(); + @Before public void setup() { - mContext = null; - mContext = InstrumentationRegistry.getContext(); - clearSharedPreferences(); + if (!RavenwoodRule.isUnderRavenwood()) { + mContext = InstrumentationRegistry.getContext(); + clearSharedPreferences(); + } else { + mContext = null; + } } @Test diff --git a/core/tests/coretests/src/android/util/LogNullabilityTest.java b/core/tests/coretests/src/android/util/LogNullabilityTest.java index 370885d3d4ac..475e347141df 100644 --- a/core/tests/coretests/src/android/util/LogNullabilityTest.java +++ b/core/tests/coretests/src/android/util/LogNullabilityTest.java @@ -19,6 +19,8 @@ package android.util; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; +import android.platform.test.ravenwood.RavenwoodRule; + import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; @@ -35,8 +37,10 @@ public final class LogNullabilityTest { Log.i(null, ""); Log.w(null, ""); Log.e(null, ""); - Log.wtf(null, ""); - Log.wtfStack(null, ""); + if (!RavenwoodRule.isUnderRavenwood()) { + Log.wtf(null, ""); + Log.wtfStack(null, ""); + } Log.println(Log.INFO, null, ""); // Implicit assertions of not crashing. @@ -49,7 +53,9 @@ public final class LogNullabilityTest { Log.i(null, "", new Throwable()); Log.w(null, "", new Throwable()); Log.e(null, "", new Throwable()); - Log.wtf(null, "", new Throwable()); + if (!RavenwoodRule.isUnderRavenwood()) { + Log.wtf(null, "", new Throwable()); + } Log.printlns(Log.LOG_ID_MAIN, Log.INFO, null, "", new Throwable()); // Implicit assertions of not crashing. @@ -84,8 +90,10 @@ public final class LogNullabilityTest { } catch (NullPointerException expected) { } - Log.wtf("", (String) null); - Log.wtfStack("", (String) null); + if (!RavenwoodRule.isUnderRavenwood()) { + Log.wtf("", (String) null); + Log.wtfStack("", (String) null); + } // Implicit assertion of not crashing. @@ -103,15 +111,10 @@ public final class LogNullabilityTest { Log.i("", null, new Throwable()); Log.w("", null, new Throwable()); Log.e("", null, new Throwable()); - Log.wtf("", null, new Throwable()); - - // Implicit assertions of not crashing. - - try { - Log.printlns(Log.LOG_ID_MAIN, Log.INFO, "", null, new Throwable()); - fail(); - } catch (NullPointerException expected) { + if (!RavenwoodRule.isUnderRavenwood()) { + Log.wtf("", null, new Throwable()); } + Log.printlns(Log.LOG_ID_MAIN, Log.INFO, "", null, new Throwable()); } @Test @@ -121,7 +124,9 @@ public final class LogNullabilityTest { Log.i("", "", null); Log.w("", "", null); Log.e("", "", null); - Log.wtf("", "", null); + if (!RavenwoodRule.isUnderRavenwood()) { + Log.wtf("", "", null); + } // Warning has its own (String, Throwable) overload. Log.w("", (Throwable) null); @@ -131,10 +136,12 @@ public final class LogNullabilityTest { // Implicit assertions of not crashing. // WTF has its own (String, Throwable) overload with different behavior. - try { - Log.wtf("", (Throwable) null); - fail(); - } catch (NullPointerException expected) { + if (!RavenwoodRule.isUnderRavenwood()) { + try { + Log.wtf("", (Throwable) null); + fail(); + } catch (NullPointerException expected) { + } } } @@ -145,15 +152,10 @@ public final class LogNullabilityTest { Log.i("", null, null); Log.w("", null, null); Log.e("", null, null); - Log.wtf("", null, null); - - // Implicit assertions of not crashing. - - try { - Log.printlns(Log.LOG_ID_MAIN, Log.INFO, "", null, null); - fail(); - } catch (NullPointerException expected) { + if (!RavenwoodRule.isUnderRavenwood()) { + Log.wtf("", null, null); } + Log.printlns(Log.LOG_ID_MAIN, Log.INFO, "", null, null); } @Test diff --git a/core/tests/coretests/src/android/util/LogTest.java b/core/tests/coretests/src/android/util/LogTest.java index d783c127d8c4..f9966a1cf65d 100644 --- a/core/tests/coretests/src/android/util/LogTest.java +++ b/core/tests/coretests/src/android/util/LogTest.java @@ -20,23 +20,24 @@ import android.os.SystemProperties; import android.test.PerformanceTestCase; import androidx.test.filters.Suppress; +import androidx.test.runner.AndroidJUnit4; import junit.framework.TestCase; +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; + //This is an empty TestCase. @Suppress -public class LogTest extends TestCase { +@RunWith(AndroidJUnit4.class) +public class LogTest { private static final String PROPERTY_TAG = "log.tag.LogTest"; private static final String LOG_TAG = "LogTest"; - - // TODO: remove this test once we uncomment out the following test. - public void testLogTestDummy() { - return; - } - - - /* TODO: This test is commented out because we will not be able to set properities. Fix the test. + @Test + @Ignore public void testIsLoggable() { // First clear any SystemProperty setting for our test key. SystemProperties.set(PROPERTY_TAG, null); @@ -129,8 +130,7 @@ public class LogTest extends TestCase { Assert.assertFalse(Log.isLoggable(LOG_TAG, Log.ERROR)); Assert.assertFalse(Log.isLoggable(LOG_TAG, Log.ASSERT)); } - */ - + public static class PerformanceTest extends TestCase implements PerformanceTestCase { private static final int ITERATIONS = 1000; diff --git a/core/tests/coretests/src/android/util/LongSparseLongArrayTest.java b/core/tests/coretests/src/android/util/LongSparseLongArrayTest.java index a1d48e689427..9dbaae0d0555 100644 --- a/core/tests/coretests/src/android/util/LongSparseLongArrayTest.java +++ b/core/tests/coretests/src/android/util/LongSparseLongArrayTest.java @@ -16,9 +16,13 @@ package android.util; +import static org.junit.Assert.assertEquals; + import androidx.test.filters.LargeTest; +import androidx.test.runner.AndroidJUnit4; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; import java.util.HashMap; import java.util.Iterator; @@ -29,9 +33,11 @@ import java.util.Random; * Tests for {@link LongSparseLongArray}. */ @LargeTest -public class LongSparseLongArrayTest extends TestCase { +@RunWith(AndroidJUnit4.class) +public class LongSparseLongArrayTest { private static final String TAG = "LongSparseLongArrayTest"; + @Test public void testSimplePut() throws Exception { final LongSparseLongArray array = new LongSparseLongArray(5); for (int i = 0; i < 48; i++) { @@ -45,6 +51,7 @@ public class LongSparseLongArrayTest extends TestCase { } } + @Test public void testSimplePutBackwards() throws Exception { final LongSparseLongArray array = new LongSparseLongArray(5); for (int i = 47; i >= 0; i--) { @@ -58,6 +65,7 @@ public class LongSparseLongArrayTest extends TestCase { } } + @Test public void testMiddleInsert() throws Exception { final LongSparseLongArray array = new LongSparseLongArray(5); for (int i = 0; i < 48; i++) { @@ -74,6 +82,7 @@ public class LongSparseLongArrayTest extends TestCase { assertEquals(1024, array.get(special, -1)); } + @Test public void testFuzz() throws Exception { final Random r = new Random(); diff --git a/core/tests/coretests/src/android/util/LruCacheTest.java b/core/tests/coretests/src/android/util/LruCacheTest.java index 1928bfdfc61d..10e8308e7964 100644 --- a/core/tests/coretests/src/android/util/LruCacheTest.java +++ b/core/tests/coretests/src/android/util/LruCacheTest.java @@ -16,7 +16,14 @@ package android.util; -import junit.framework.TestCase; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.fail; + +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; import java.util.ArrayList; import java.util.Arrays; @@ -24,13 +31,15 @@ import java.util.Collections; import java.util.List; import java.util.Map; -public final class LruCacheTest extends TestCase { +@RunWith(AndroidJUnit4.class) +public final class LruCacheTest { private int expectedCreateCount; private int expectedPutCount; private int expectedHitCount; private int expectedMissCount; private int expectedEvictionCount; + @Test public void testStatistics() { LruCache cache = new LruCache(3); assertStatistics(cache); @@ -80,6 +89,7 @@ public final class LruCacheTest extends TestCase { assertSnapshot(cache, "e", "E", "b", "B", "c", "C"); } + @Test public void testStatisticsWithCreate() { LruCache cache = newCreatingCache(); assertStatistics(cache); @@ -104,18 +114,21 @@ public final class LruCacheTest extends TestCase { assertSnapshot(cache, "cc", "created-cc", "dd", "created-dd", "aa", "created-aa"); } + @Test public void testCreateOnCacheMiss() { LruCache cache = newCreatingCache(); String created = cache.get("aa"); assertEquals("created-aa", created); } + @Test public void testNoCreateOnCacheHit() { LruCache cache = newCreatingCache(); cache.put("aa", "put-aa"); assertEquals("put-aa", cache.get("aa")); } + @Test public void testConstructorDoesNotAllowZeroCacheSize() { try { new LruCache(0); @@ -124,6 +137,7 @@ public final class LruCacheTest extends TestCase { } } + @Test public void testCannotPutNullKey() { LruCache cache = new LruCache(3); try { @@ -133,6 +147,7 @@ public final class LruCacheTest extends TestCase { } } + @Test public void testCannotPutNullValue() { LruCache cache = new LruCache(3); try { @@ -142,6 +157,7 @@ public final class LruCacheTest extends TestCase { } } + @Test public void testToString() { LruCache cache = new LruCache(3); assertEquals("LruCache[maxSize=3,hits=0,misses=0,hitRate=0%]", cache.toString()); @@ -160,6 +176,7 @@ public final class LruCacheTest extends TestCase { assertEquals("LruCache[maxSize=3,hits=3,misses=2,hitRate=60%]", cache.toString()); } + @Test public void testEvictionWithSingletonCache() { LruCache cache = new LruCache(1); cache.put("a", "A"); @@ -167,6 +184,7 @@ public final class LruCacheTest extends TestCase { assertSnapshot(cache, "b", "B"); } + @Test public void testEntryEvictedWhenFull() { List log = new ArrayList(); LruCache cache = newRemovalLogCache(log); @@ -184,6 +202,7 @@ public final class LruCacheTest extends TestCase { * Replacing the value for a key doesn't cause an eviction but it does bring * the replaced entry to the front of the queue. */ + @Test public void testPutCauseEviction() { List log = new ArrayList(); LruCache cache = newRemovalLogCache(log); @@ -196,6 +215,7 @@ public final class LruCacheTest extends TestCase { assertSnapshot(cache, "a", "A", "c", "C", "b", "B2"); } + @Test public void testCustomSizesImpactsSize() { LruCache cache = new LruCache(10) { @Override protected int sizeOf(String key, String value) { @@ -212,6 +232,7 @@ public final class LruCacheTest extends TestCase { assertEquals(6, cache.size()); } + @Test public void testEvictionWithCustomSizes() { LruCache cache = new LruCache(4) { @Override protected int sizeOf(String key, String value) { @@ -241,6 +262,7 @@ public final class LruCacheTest extends TestCase { assertSnapshot(cache, "j", "JJJ"); } + @Test public void testEvictionThrowsWhenSizesAreInconsistent() { LruCache cache = new LruCache(4) { @Override protected int sizeOf(String key, int[] value) { @@ -263,6 +285,7 @@ public final class LruCacheTest extends TestCase { } } + @Test public void testEvictionThrowsWhenSizesAreNegative() { LruCache cache = new LruCache(4) { @Override protected int sizeOf(String key, String value) { @@ -282,6 +305,7 @@ public final class LruCacheTest extends TestCase { * because evicting a small element may be insufficient to make room for a * large element. */ + @Test public void testDifferentElementSizes() { LruCache cache = new LruCache(10) { @Override protected int sizeOf(String key, String value) { @@ -299,6 +323,7 @@ public final class LruCacheTest extends TestCase { assertSnapshot(cache, "e", "12345678"); } + @Test public void testEvictAll() { List log = new ArrayList(); LruCache cache = newRemovalLogCache(log); @@ -310,6 +335,7 @@ public final class LruCacheTest extends TestCase { assertEquals(Arrays.asList("a=A", "b=B", "c=C"), log); } + @Test public void testEvictAllEvictsSizeZeroElements() { LruCache cache = new LruCache(10) { @Override protected int sizeOf(String key, String value) { @@ -323,6 +349,7 @@ public final class LruCacheTest extends TestCase { assertSnapshot(cache); } + @Test public void testRemoveWithCustomSizes() { LruCache cache = new LruCache(10) { @Override protected int sizeOf(String key, String value) { @@ -335,6 +362,7 @@ public final class LruCacheTest extends TestCase { assertEquals(4, cache.size()); } + @Test public void testRemoveAbsentElement() { LruCache cache = new LruCache(10); cache.put("a", "A"); @@ -343,6 +371,7 @@ public final class LruCacheTest extends TestCase { assertEquals(2, cache.size()); } + @Test public void testRemoveNullThrows() { LruCache cache = new LruCache(10); try { @@ -352,6 +381,7 @@ public final class LruCacheTest extends TestCase { } } + @Test public void testRemoveCallsEntryRemoved() { List log = new ArrayList(); LruCache cache = newRemovalLogCache(log); @@ -360,6 +390,7 @@ public final class LruCacheTest extends TestCase { assertEquals(Arrays.asList("a=A>null"), log); } + @Test public void testPutCallsEntryRemoved() { List log = new ArrayList(); LruCache cache = newRemovalLogCache(log); @@ -368,6 +399,7 @@ public final class LruCacheTest extends TestCase { assertEquals(Arrays.asList("a=A>A2"), log); } + @Test public void testEntryRemovedIsCalledWithoutSynchronization() { LruCache cache = new LruCache(3) { @Override protected void entryRemoved( @@ -385,6 +417,7 @@ public final class LruCacheTest extends TestCase { cache.evictAll(); // multiple eviction } + @Test public void testCreateIsCalledWithoutSynchronization() { LruCache cache = new LruCache(3) { @Override protected String create(String key) { @@ -401,6 +434,7 @@ public final class LruCacheTest extends TestCase { * working. The map value should be returned by get(), and the created value * should be released with entryRemoved(). */ + @Test public void testCreateWithConcurrentPut() { final List log = new ArrayList(); LruCache cache = new LruCache(3) { @@ -423,6 +457,7 @@ public final class LruCacheTest extends TestCase { * the first create to return is returned by both gets. The other created * values should be released with entryRemove(). */ + @Test public void testCreateWithConcurrentCreate() { final List log = new ArrayList(); LruCache cache = new LruCache(3) { diff --git a/core/tests/coretests/src/android/util/MonthDisplayHelperTest.java b/core/tests/coretests/src/android/util/MonthDisplayHelperTest.java index 30d5f778e945..06f970fcf77c 100644 --- a/core/tests/coretests/src/android/util/MonthDisplayHelperTest.java +++ b/core/tests/coretests/src/android/util/MonthDisplayHelperTest.java @@ -16,18 +16,26 @@ package android.util; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; import java.util.Calendar; /** * Unit tests for {@link MonthDisplayHelper}. */ -public class MonthDisplayHelperTest extends TestCase { +@RunWith(AndroidJUnit4.class) +public class MonthDisplayHelperTest { + @Test @SmallTest public void testFirstDayOfMonth() { @@ -40,12 +48,14 @@ public class MonthDisplayHelperTest extends TestCase { new MonthDisplayHelper(2007, Calendar.SEPTEMBER).getFirstDayOfMonth()); } + @Test @SmallTest public void testNumberOfDaysInCurrentMonth() { assertEquals(30, new MonthDisplayHelper(2007, Calendar.SEPTEMBER).getNumberOfDaysInMonth()); } + @Test @SmallTest public void testMonthRows() { MonthDisplayHelper helper = new MonthDisplayHelper(2007, Calendar.SEPTEMBER); @@ -59,6 +69,7 @@ public class MonthDisplayHelperTest extends TestCase { } + @Test @SmallTest public void testMonthRowsWeekStartsMonday() { MonthDisplayHelper helper = new MonthDisplayHelper(2007, @@ -74,6 +85,7 @@ public class MonthDisplayHelperTest extends TestCase { helper.getDigitsForRow(5)); } + @Test @SmallTest public void testMonthRowsWeekStartsSaturday() { MonthDisplayHelper helper = new MonthDisplayHelper(2007, @@ -98,6 +110,7 @@ public class MonthDisplayHelperTest extends TestCase { helper.getDigitsForRow(4)); } + @Test @SmallTest public void testGetDayAt() { MonthDisplayHelper helper = new MonthDisplayHelper(2007, @@ -109,6 +122,7 @@ public class MonthDisplayHelperTest extends TestCase { assertEquals(2, helper.getDayAt(5, 2)); } + @Test @SmallTest public void testPrevMonth() { MonthDisplayHelper helper = new MonthDisplayHelper(2007, @@ -124,6 +138,7 @@ public class MonthDisplayHelperTest extends TestCase { helper.getDigitsForRow(0)); } + @Test @SmallTest public void testPrevMonthRollOver() { MonthDisplayHelper helper = new MonthDisplayHelper(2007, @@ -135,6 +150,7 @@ public class MonthDisplayHelperTest extends TestCase { assertEquals(Calendar.DECEMBER, helper.getMonth()); } + @Test @SmallTest public void testNextMonth() { MonthDisplayHelper helper = new MonthDisplayHelper(2007, @@ -150,6 +166,7 @@ public class MonthDisplayHelperTest extends TestCase { helper.getDigitsForRow(0)); } + @Test @SmallTest public void testGetRowOf() { MonthDisplayHelper helper = new MonthDisplayHelper(2007, @@ -162,6 +179,7 @@ public class MonthDisplayHelperTest extends TestCase { assertEquals(3, helper.getRowOf(19)); } + @Test @SmallTest public void testGetColumnOf() { MonthDisplayHelper helper = new MonthDisplayHelper(2007, @@ -174,6 +192,7 @@ public class MonthDisplayHelperTest extends TestCase { assertEquals(0, helper.getColumnOf(26)); } + @Test @SmallTest public void testWithinCurrentMonth() { MonthDisplayHelper helper = new MonthDisplayHelper(2007, diff --git a/core/tests/coretests/src/android/util/NtpTrustedTimeTest.java b/core/tests/coretests/src/android/util/NtpTrustedTimeTest.java index 4de27c332d96..ce1eabc741a3 100644 --- a/core/tests/coretests/src/android/util/NtpTrustedTimeTest.java +++ b/core/tests/coretests/src/android/util/NtpTrustedTimeTest.java @@ -31,10 +31,15 @@ import static java.lang.String.join; import static java.util.Arrays.asList; import android.net.Network; +import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; +import androidx.test.platform.app.InstrumentationRegistry; +import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InOrder; @@ -51,7 +56,10 @@ import java.util.stream.Stream; @SmallTest @RunWith(AndroidJUnit4.class) +@IgnoreUnderRavenwood(blockedBy = NtpTrustedTime.class) public class NtpTrustedTimeTest { + @Rule + public final RavenwoodRule mRavenwood = new RavenwoodRule(); private static final Duration VALID_TIMEOUT = Duration.ofSeconds(5); diff --git a/core/tests/coretests/src/android/util/PatternsTest.java b/core/tests/coretests/src/android/util/PatternsTest.java index dd8f73fd54c4..a180ec3f9e35 100644 --- a/core/tests/coretests/src/android/util/PatternsTest.java +++ b/core/tests/coretests/src/android/util/PatternsTest.java @@ -16,17 +16,25 @@ package android.util; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; import java.util.regex.Matcher; import java.util.regex.Pattern; -public class PatternsTest extends TestCase { +@RunWith(AndroidJUnit4.class) +public class PatternsTest { // Tests for Patterns.TOP_LEVEL_DOMAIN + @Test @SmallTest public void testTldPattern() throws Exception { boolean t; @@ -58,36 +66,42 @@ public class PatternsTest extends TestCase { // Tests for Patterns.IANA_TOP_LEVEL_DOMAINS + @Test @SmallTest public void testIanaTopLevelDomains_matchesValidTld() throws Exception { Pattern pattern = Pattern.compile(Patterns.IANA_TOP_LEVEL_DOMAINS); assertTrue("Should match 'com'", pattern.matcher("com").matches()); } + @Test @SmallTest public void testIanaTopLevelDomains_matchesValidNewTld() throws Exception { Pattern pattern = Pattern.compile(Patterns.IANA_TOP_LEVEL_DOMAINS); assertTrue("Should match 'me'", pattern.matcher("me").matches()); } + @Test @SmallTest public void testIanaTopLevelDomains_matchesPunycodeTld() throws Exception { Pattern pattern = Pattern.compile(Patterns.IANA_TOP_LEVEL_DOMAINS); assertTrue("Should match Punycode TLD", pattern.matcher("xn--qxam").matches()); } + @Test @SmallTest public void testIanaTopLevelDomains_matchesIriTLD() throws Exception { Pattern pattern = Pattern.compile(Patterns.IANA_TOP_LEVEL_DOMAINS); assertTrue("Should match IRI TLD", pattern.matcher("\uD55C\uAD6D").matches()); } + @Test @SmallTest public void testIanaTopLevelDomains_doesNotMatchWrongTld() throws Exception { Pattern pattern = Pattern.compile(Patterns.IANA_TOP_LEVEL_DOMAINS); assertFalse("Should not match 'mem'", pattern.matcher("mem").matches()); } + @Test @SmallTest public void testIanaTopLevelDomains_doesNotMatchWrongPunycodeTld() throws Exception { Pattern pattern = Pattern.compile(Patterns.IANA_TOP_LEVEL_DOMAINS); @@ -96,6 +110,7 @@ public class PatternsTest extends TestCase { // Tests for Patterns.WEB_URL + @Test @SmallTest public void testWebUrl_matchesValidUrlWithSchemeAndHostname() throws Exception { String url = "http://www.android.com"; @@ -103,6 +118,7 @@ public class PatternsTest extends TestCase { Patterns.WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testWebUrl_matchesValidUrlWithSchemeHostnameAndNewTld() throws Exception { String url = "http://www.android.me"; @@ -110,6 +126,7 @@ public class PatternsTest extends TestCase { Patterns.WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testWebUrl_matchesValidUrlWithHostnameAndNewTld() throws Exception { String url = "android.me"; @@ -117,6 +134,7 @@ public class PatternsTest extends TestCase { Patterns.WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testWebUrl_matchesChinesePunycodeUrlWithProtocol() throws Exception { String url = "http://xn--fsqu00a.xn--0zwm56d"; @@ -124,6 +142,7 @@ public class PatternsTest extends TestCase { Patterns.WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testWebUrl_matchesChinesePunycodeUrlWithoutProtocol() throws Exception { String url = "xn--fsqu00a.xn--0zwm56d"; @@ -131,6 +150,7 @@ public class PatternsTest extends TestCase { Patterns.WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testWebUrl_matchesArabicPunycodeUrlWithProtocol() throws Exception { String url = "http://xn--4gbrim.xn----rmckbbajlc6dj7bxne2c.xn--wgbh1c/ar/default.aspx"; @@ -138,6 +158,7 @@ public class PatternsTest extends TestCase { Patterns.WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testWebUrl_matchesArabicPunycodeUrlWithoutProtocol() throws Exception { String url = "xn--4gbrim.xn----rmckbbajlc6dj7bxne2c.xn--wgbh1c/ar/default.aspx"; @@ -145,6 +166,7 @@ public class PatternsTest extends TestCase { Patterns.WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testWebUrl_matchesUrlWithUnicodeDomainNameWithProtocol() throws Exception { String url = "http://\uD604\uAE08\uC601\uC218\uC99D.kr"; @@ -152,6 +174,7 @@ public class PatternsTest extends TestCase { Patterns.WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testWebUrl_matchesUrlWithUnicodeDomainNameWithoutProtocol() throws Exception { String url = "\uD604\uAE08\uC601\uC218\uC99D.kr"; @@ -159,6 +182,7 @@ public class PatternsTest extends TestCase { Patterns.WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testWebUrl_matchesUrlWithUnicodeTld() throws Exception { String url = "\uB3C4\uBA54\uC778.\uD55C\uAD6D"; @@ -166,6 +190,7 @@ public class PatternsTest extends TestCase { Patterns.WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testWebUrl_matchesUrlWithUnicodePath() throws Exception { String url = "http://brainstormtech.blogs.fortune.cnn.com/2010/03/11/" + @@ -174,19 +199,22 @@ public class PatternsTest extends TestCase { Patterns.WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testWebUrl_doesNotMatchValidUrlWithInvalidProtocol() throws Exception { - String url = "ftp://www.example.com"; + String url = "invalid://www.example.com"; assertFalse("Should not match URL with invalid protocol", Patterns.WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testWebUrl_matchesValidUrlWithPort() throws Exception { String url = "http://www.example.com:8080"; assertTrue("Should match URL with port", Patterns.WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testWebUrl_matchesUrlWithPortAndQuery() throws Exception { String url = "http://www.example.com:8080/?foo=bar"; @@ -194,12 +222,14 @@ public class PatternsTest extends TestCase { Patterns.WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testWebUrl_matchesUrlWithTilde() throws Exception { String url = "http://www.example.com:8080/~user/?foo=bar"; assertTrue("Should match URL with tilde", Patterns.WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testWebUrl_matchesProtocolCaseInsensitive() throws Exception { String url = "hTtP://android.com"; @@ -207,6 +237,7 @@ public class PatternsTest extends TestCase { Patterns.WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testWebUrl_matchesDomainNameWithDash() throws Exception { String url = "http://a-nd.r-oid.com"; @@ -218,6 +249,7 @@ public class PatternsTest extends TestCase { Patterns.WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testWebUrl_matchesDomainNameWithUnderscore() throws Exception { String url = "http://a_nd.r_oid.com"; @@ -229,6 +261,7 @@ public class PatternsTest extends TestCase { Patterns.WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testWebUrl_matchesPathAndQueryWithDollarSign() throws Exception { String url = "http://android.com/path$?v=$val"; @@ -240,6 +273,7 @@ public class PatternsTest extends TestCase { Patterns.WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testWebUrl_matchesEmptyPathWithQueryParams() throws Exception { String url = "http://android.com?q=v"; @@ -261,6 +295,7 @@ public class PatternsTest extends TestCase { // Tests for Patterns.AUTOLINK_WEB_URL + @Test @SmallTest public void testAutoLinkWebUrl_matchesValidUrlWithSchemeAndHostname() throws Exception { String url = "http://www.android.com"; @@ -268,6 +303,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testAutoLinkWebUrl_matchesValidUrlWithSchemeHostnameAndNewTld() throws Exception { String url = "http://www.android.me"; @@ -275,6 +311,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testAutoLinkWebUrl_matchesValidUrlWithHostnameAndNewTld() throws Exception { String url = "android.me"; @@ -286,6 +323,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testAutoLinkWebUrl_matchesChinesePunycodeUrlWithProtocol() throws Exception { String url = "http://xn--fsqu00a.xn--0zwm56d"; @@ -293,6 +331,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testAutoLinkWebUrl_matchesChinesePunycodeUrlWithoutProtocol() throws Exception { String url = "xn--fsqu00a.xn--0zwm56d"; @@ -300,6 +339,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testAutoLinkWebUrl_matchesArabicPunycodeUrlWithProtocol() throws Exception { String url = "http://xn--4gbrim.xn--rmckbbajlc6dj7bxne2c.xn--wgbh1c/ar/default.aspx"; @@ -307,6 +347,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testAutoLinkWebUrl_matchesArabicPunycodeUrlWithoutProtocol() throws Exception { String url = "xn--4gbrim.xn--rmckbbajlc6dj7bxne2c.xn--wgbh1c/ar/default.aspx"; @@ -314,6 +355,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testAutoLinkWebUrl_doesNotMatchPunycodeTldThatStartsWithDash() throws Exception { String url = "http://xn--fsqu00a.-xn--0zwm56d"; @@ -321,6 +363,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testAutoLinkWebUrl_doesNotMatchPunycodeTldThatEndsWithDash() throws Exception { String url = "http://xn--fsqu00a.xn--0zwm56d-"; @@ -328,6 +371,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testAutoLinkWebUrl_matchesUrlWithUnicodeDomainName() throws Exception { String url = "http://\uD604\uAE08\uC601\uC218\uC99D.kr"; @@ -339,6 +383,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testAutoLinkWebUrl_matchesUrlWithUnicodeTld() throws Exception { String url = "\uB3C4\uBA54\uC778.\uD55C\uAD6D"; @@ -346,6 +391,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testAutoLinkWebUrl_matchesUrlWithUnicodePath() throws Exception { String url = "http://brainstormtech.blogs.fortune.cnn.com/2010/03/11/" + @@ -354,13 +400,15 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testAutoLinkWebUrl_doesNotMatchValidUrlWithInvalidProtocol() throws Exception { - String url = "ftp://www.example.com"; + String url = "invalid://www.example.com"; assertFalse("Should not match URL with invalid protocol", Patterns.AUTOLINK_WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testAutoLinkWebUrl_matchesValidUrlWithPort() throws Exception { String url = "http://www.example.com:8080"; @@ -368,6 +416,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testAutoLinkWebUrl_matchesUrlWithPortAndQuery() throws Exception { String url = "http://www.example.com:8080/?foo=bar"; @@ -375,6 +424,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testAutoLinkWebUrl_matchesUrlWithTilde() throws Exception { String url = "http://www.example.com:8080/~user/?foo=bar"; @@ -382,6 +432,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testAutoLinkWebUrl_matchesProtocolCaseInsensitive() throws Exception { String url = "hTtP://android.com"; @@ -389,6 +440,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testAutoLinkWebUrl_matchesUrlStartingWithHttpAndDoesNotHaveTld() throws Exception { String url = "http://android/#notld///a/n/d/r/o/i/d&p1=1&p2=2"; @@ -396,6 +448,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testAutoLinkWebUrl_doesNotMatchUrlsWithoutProtocolAndWithUnknownTld() throws Exception { @@ -405,13 +458,15 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testAutoLinkWebUrl_doesNotPartiallyMatchUnknownProtocol() throws Exception { - String url = "ftp://foo.bar/baz"; + String url = "invalid://foo.bar/baz"; assertFalse("Should not partially match URL with unknown protocol", Patterns.AUTOLINK_WEB_URL.matcher(url).find()); } + @Test @SmallTest public void testAutoLinkWebUrl_matchesValidUrlWithEmoji() throws Exception { String url = "Thank\u263A.com"; @@ -419,6 +474,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testAutoLinkWebUrl_doesNotMatchUrlsWithEmojiWithoutProtocolAndWithoutKnownTld() throws Exception { @@ -427,6 +483,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testAutoLinkWebUrl_doesNotMatchEmailAddress() throws Exception { @@ -435,6 +492,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testAutoLinkWebUrl_matchesDomainNameWithSurrogatePairs() throws Exception { String url = "android\uD83C\uDF38.com"; @@ -442,6 +500,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testAutoLinkWebUrl_matchesTldWithSurrogatePairs() throws Exception { String url = "http://android.\uD83C\uDF38com"; @@ -449,6 +508,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testAutoLinkWebUrl_matchesPathWithSurrogatePairs() throws Exception { String url = "http://android.com/path-with-\uD83C\uDF38?v=\uD83C\uDF38"; @@ -456,6 +516,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testAutoLinkWebUrl_doesNotMatchUrlWithExcludedSurrogate() throws Exception { String url = "http://android\uD83F\uDFFE.com"; @@ -463,6 +524,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testAutoLinkWebUrl_doesNotMatchUnicodeSpaces() throws Exception { String part1 = "http://and"; @@ -493,6 +555,7 @@ public class PatternsTest extends TestCase { } } + @Test @SmallTest public void testAutoLinkWebUrl_matchesDomainNameWithDash() throws Exception { String url = "http://a-nd.r-oid.com"; @@ -504,6 +567,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testAutoLinkWebUrl_matchesDomainNameWithUnderscore() throws Exception { String url = "http://a_nd.r_oid.com"; @@ -515,6 +579,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testAutoLinkWebUrl_matchesPathAndQueryWithDollarSign() throws Exception { String url = "http://android.com/path$?v=$val"; @@ -526,6 +591,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testAutoLinkWebUrl_matchesEmptyPathWithQueryParams() throws Exception { String url = "http://android.com?q=v"; @@ -547,6 +613,7 @@ public class PatternsTest extends TestCase { // Tests for Patterns.IP_ADDRESS + @Test @SmallTest public void testIpPattern() throws Exception { boolean t; @@ -560,6 +627,7 @@ public class PatternsTest extends TestCase { // Tests for Patterns.DOMAIN_NAME + @Test @SmallTest public void testDomain_matchesPunycodeTld() throws Exception { String domain = "xn--fsqu00a.xn--0zwm56d"; @@ -567,6 +635,7 @@ public class PatternsTest extends TestCase { Patterns.DOMAIN_NAME.matcher(domain).matches()); } + @Test @SmallTest public void testDomain_doesNotMatchPunycodeThatStartsWithDash() throws Exception { String domain = "xn--fsqu00a.-xn--0zwm56d"; @@ -574,6 +643,7 @@ public class PatternsTest extends TestCase { Patterns.DOMAIN_NAME.matcher(domain).matches()); } + @Test @SmallTest public void testDomain_doesNotMatchPunycodeThatEndsWithDash() throws Exception { String domain = "xn--fsqu00a.xn--0zwm56d-"; @@ -581,6 +651,7 @@ public class PatternsTest extends TestCase { Patterns.DOMAIN_NAME.matcher(domain).matches()); } + @Test @SmallTest public void testDomain_doesNotMatchPunycodeLongerThanAllowed() throws Exception { String tld = "xn--"; @@ -592,6 +663,7 @@ public class PatternsTest extends TestCase { Patterns.DOMAIN_NAME.matcher(domain).matches()); } + @Test @SmallTest public void testDomain_matchesObsoleteTld() throws Exception { String domain = "test.yu"; @@ -599,6 +671,7 @@ public class PatternsTest extends TestCase { Patterns.DOMAIN_NAME.matcher(domain).matches()); } + @Test @SmallTest public void testDomain_matchesWithSubDomain() throws Exception { String domain = "mail.example.com"; @@ -606,6 +679,7 @@ public class PatternsTest extends TestCase { Patterns.DOMAIN_NAME.matcher(domain).matches()); } + @Test @SmallTest public void testDomain_matchesWithoutSubDomain() throws Exception { String domain = "android.me"; @@ -613,6 +687,7 @@ public class PatternsTest extends TestCase { Patterns.DOMAIN_NAME.matcher(domain).matches()); } + @Test @SmallTest public void testDomain_matchesUnicodeDomainNames() throws Exception { String domain = "\uD604\uAE08\uC601\uC218\uC99D.kr"; @@ -620,6 +695,7 @@ public class PatternsTest extends TestCase { Patterns.DOMAIN_NAME.matcher(domain).matches()); } + @Test @SmallTest public void testDomain_doesNotMatchInvalidDomain() throws Exception { String domain = "__+&42.xer"; @@ -627,6 +703,7 @@ public class PatternsTest extends TestCase { Patterns.DOMAIN_NAME.matcher(domain).matches()); } + @Test @SmallTest public void testDomain_matchesPunycodeArabicDomainName() throws Exception { String domain = "xn--4gbrim.xn----rmckbbajlc6dj7bxne2c.xn--wgbh1c"; @@ -634,6 +711,7 @@ public class PatternsTest extends TestCase { Patterns.DOMAIN_NAME.matcher(domain).matches()); } + @Test @SmallTest public void testDomain_matchesDomainNameWithDash() throws Exception { String url = "http://a-nd.r-oid.com"; @@ -645,6 +723,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_WEB_URL.matcher(url).matches()); } + @Test @SmallTest public void testDomain_matchesDomainNameWithUnderscore() throws Exception { String url = "http://a_nd.r_oid.com"; @@ -658,6 +737,7 @@ public class PatternsTest extends TestCase { // Tests for Patterns.AUTOLINK_EMAIL_ADDRESS + @Test @SmallTest public void testAutoLinkEmailAddress_matchesShortValidEmail() throws Exception { String email = "a@a.co"; @@ -665,6 +745,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches()); } + @Test @SmallTest public void testAutoLinkEmailAddress_matchesRegularEmail() throws Exception { String email = "email@android.com"; @@ -672,6 +753,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches()); } + @Test @SmallTest public void testAutoLinkEmailAddress_matchesEmailWithMultipleSubdomains() throws Exception { String email = "email@e.somelongdomainnameforandroid.abc.uk"; @@ -679,6 +761,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches()); } + @Test @SmallTest public void testAutoLinkEmailAddress_matchesLocalPartWithDot() throws Exception { String email = "e.mail@android.com"; @@ -686,6 +769,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches()); } + @Test @SmallTest public void testAutoLinkEmailAddress_matchesLocalPartWithPlus() throws Exception { String email = "e+mail@android.com"; @@ -693,6 +777,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches()); } + @Test @SmallTest public void testAutoLinkEmailAddress_matchesLocalPartWithUnderscore() throws Exception { String email = "e_mail@android.com"; @@ -700,6 +785,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches()); } + @Test @SmallTest public void testAutoLinkEmailAddress_matchesLocalPartWithDash() throws Exception { String email = "e-mail@android.com"; @@ -707,6 +793,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches()); } + @Test @SmallTest public void testAutoLinkEmailAddress_matchesLocalPartWithApostrophe() throws Exception { String email = "e'mail@android.com"; @@ -714,6 +801,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches()); } + @Test @SmallTest public void testAutoLinkEmailAddress_matchesLocalPartWithDigits() throws Exception { String email = "123@android.com"; @@ -721,6 +809,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches()); } + @Test @SmallTest public void testAutoLinkEmailAddress_matchesUnicodeLocalPart() throws Exception { String email = "\uD604\uAE08\uC601\uC218\uC99D@android.kr"; @@ -728,6 +817,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches()); } + @Test @SmallTest public void testAutoLinkEmailAddress_matchesLocalPartWithEmoji() throws Exception { String email = "smiley\u263A@android.com"; @@ -735,6 +825,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches()); } + @Test @SmallTest public void testAutoLinkEmailAddress_matchesLocalPartWithSurrogatePairs() throws Exception { String email = "\uD83C\uDF38@android.com"; @@ -742,6 +833,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches()); } + @Test @SmallTest public void testAutoLinkEmailAddress_matchesDomainWithDash() throws Exception { String email = "email@an-droid.com"; @@ -749,6 +841,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches()); } + @Test @SmallTest public void testAutoLinkEmailAddress_matchesUnicodeDomain() throws Exception { String email = "email@\uD604\uAE08\uC601\uC218\uC99D.kr"; @@ -756,6 +849,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches()); } + @Test @SmallTest public void testAutoLinkEmailAddress_matchesUnicodeLocalPartAndDomain() throws Exception { String email = "\uD604\uAE08\uC601\uC218\uC99D@\uD604\uAE08\uC601\uC218\uC99D.kr"; @@ -763,6 +857,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches()); } + @Test @SmallTest public void testAutoLinkEmailAddress_matchesDomainWithEmoji() throws Exception { String email = "smiley@\u263Aandroid.com"; @@ -770,6 +865,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches()); } + @Test @SmallTest public void testAutoLinkEmailAddress_matchesDomainWithSurrogatePairs() throws Exception { String email = "email@\uD83C\uDF38android.com"; @@ -777,6 +873,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches()); } + @Test @SmallTest public void testAutoLinkEmailAddress_matchesLocalPartAndDomainWithSurrogatePairs() throws Exception { @@ -785,6 +882,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches()); } + @Test @SmallTest public void testAutoLinkEmailAddress_doesNotMatchStringWithoutAtSign() throws Exception { String email = "android.com"; @@ -792,6 +890,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches()); } + @Test @SmallTest public void testAutoLinkEmailAddress_doesNotMatchPlainString() throws Exception { String email = "email"; @@ -799,6 +898,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches()); } + @Test @SmallTest public void testAutoLinkEmailAddress_doesNotMatchStringWithMultipleAtSigns() throws Exception { String email = "email@android@android.com"; @@ -806,6 +906,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches()); } + @Test @SmallTest public void testAutoLinkEmailAddress_doesNotMatchEmailWithoutTld() throws Exception { String email = "email@android"; @@ -813,6 +914,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches()); } + @Test @SmallTest public void testAutoLinkEmailAddress_doesNotMatchLocalPartEndingWithDot() throws Exception { String email = "email.@android.com"; @@ -820,6 +922,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches()); } + @Test @SmallTest public void testAutoLinkEmailAddress_doesNotMatchLocalPartStartingWithDot() throws Exception { String email = ".email@android.com"; @@ -827,6 +930,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches()); } + @Test @SmallTest public void testAutoLinkEmailAddress_doesNotMatchDomainStartingWithDash() throws Exception { String email = "email@-android.com"; @@ -834,6 +938,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches()); } + @Test @SmallTest public void testAutoLinkEmailAddress_doesNotMatchDomainWithConsecutiveDots() throws Exception { String email = "email@android..com"; @@ -841,6 +946,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches()); } + @Test @SmallTest public void testAutoLinkEmailAddress_doesNotMatchEmailWithIpAsDomain() throws Exception { String email = "email@127.0.0.1"; @@ -848,6 +954,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches()); } + @Test @SmallTest public void testAutoLinkEmailAddress_doesNotMatchEmailWithInvalidTld() throws Exception { String email = "email@android.c"; @@ -855,6 +962,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches()); } + @Test @SmallTest public void testAutoLinkEmailAddress_matchesLocalPartUpTo64Chars() throws Exception { String localPart = ""; @@ -871,6 +979,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches()); } + @Test @SmallTest public void testAutoLinkEmailAddress_matchesSubdomainUpTo63Chars() throws Exception { String subdomain = ""; @@ -888,6 +997,7 @@ public class PatternsTest extends TestCase { Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches()); } + @Test @SmallTest public void testAutoLinkEmailAddress_matchesDomainUpTo255Chars() throws Exception { String longDomain = ""; @@ -909,6 +1019,7 @@ public class PatternsTest extends TestCase { // Tests for Patterns.PHONE + @Test @SmallTest public void testPhonePattern() throws Exception { boolean t; diff --git a/core/tests/coretests/src/android/util/RecurrenceRuleTest.java b/core/tests/coretests/src/android/util/RecurrenceRuleTest.java index caa12083fafb..32548b4cff19 100644 --- a/core/tests/coretests/src/android/util/RecurrenceRuleTest.java +++ b/core/tests/coretests/src/android/util/RecurrenceRuleTest.java @@ -16,9 +16,17 @@ package android.util; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; -import junit.framework.TestCase; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; import java.time.Clock; import java.time.Instant; @@ -28,19 +36,18 @@ import java.time.ZonedDateTime; import java.util.Iterator; @SmallTest -public class RecurrenceRuleTest extends TestCase { +@RunWith(AndroidJUnit4.class) +public class RecurrenceRuleTest { static Clock sOriginalClock; - @Override - protected void setUp() throws Exception { - super.setUp(); + @Before + public void setUp() throws Exception { sOriginalClock = RecurrenceRule.sClock; } - @Override - protected void tearDown() throws Exception { - super.tearDown(); + @After + public void tearDown() throws Exception { RecurrenceRule.sClock = sOriginalClock; } @@ -48,6 +55,7 @@ public class RecurrenceRuleTest extends TestCase { RecurrenceRule.sClock = Clock.fixed(instant, ZoneId.systemDefault()); } + @Test public void testSimpleMonth() throws Exception { setClock(Instant.parse("2015-11-20T10:15:30.00Z")); final RecurrenceRule r = new RecurrenceRule( @@ -68,6 +76,7 @@ public class RecurrenceRuleTest extends TestCase { ZonedDateTime.parse("2015-11-14T00:00:00.00Z")), it.next()); } + @Test public void testSimpleDays() throws Exception { setClock(Instant.parse("2015-01-01T10:15:30.00Z")); final RecurrenceRule r = new RecurrenceRule( @@ -89,6 +98,7 @@ public class RecurrenceRuleTest extends TestCase { assertFalse(it.hasNext()); } + @Test public void testNotRecurring() throws Exception { setClock(Instant.parse("2015-01-01T10:15:30.00Z")); final RecurrenceRule r = new RecurrenceRule( @@ -106,6 +116,7 @@ public class RecurrenceRuleTest extends TestCase { assertFalse(it.hasNext()); } + @Test public void testNever() throws Exception { setClock(Instant.parse("2015-01-01T10:15:30.00Z")); final RecurrenceRule r = RecurrenceRule.buildNever(); @@ -116,6 +127,7 @@ public class RecurrenceRuleTest extends TestCase { assertFalse(it.hasNext()); } + @Test public void testSane() throws Exception { final RecurrenceRule r = new RecurrenceRule( ZonedDateTime.parse("1980-01-31T00:00:00.000Z"), diff --git a/core/tests/coretests/src/android/util/SparseSetArrayTest.java b/core/tests/coretests/src/android/util/SparseSetArrayTest.java index 3c17486aeb94..1df1090e0343 100644 --- a/core/tests/coretests/src/android/util/SparseSetArrayTest.java +++ b/core/tests/coretests/src/android/util/SparseSetArrayTest.java @@ -17,9 +17,13 @@ package android.util; import static com.google.common.truth.Truth.assertThat; +import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.ravenwood.RavenwoodRule; + import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -29,6 +33,9 @@ import org.junit.runner.RunWith; @SmallTest @RunWith(AndroidJUnit4.class) public class SparseSetArrayTest { + @Rule + public final RavenwoodRule mRavenwood = new RavenwoodRule(); + @Test public void testAddAll() { final SparseSetArray sparseSetArray = new SparseSetArray<>(); @@ -51,6 +58,7 @@ public class SparseSetArrayTest { } @Test + @IgnoreUnderRavenwood(reason = "b/315036461") public void testCopyConstructor() { final SparseSetArray sparseSetArray = new SparseSetArray<>(); diff --git a/core/tests/coretests/src/android/util/StateSetTest.java b/core/tests/coretests/src/android/util/StateSetTest.java index b5d62704ba29..dfd1523465ae 100644 --- a/core/tests/coretests/src/android/util/StateSetTest.java +++ b/core/tests/coretests/src/android/util/StateSetTest.java @@ -16,16 +16,29 @@ package android.util; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.ravenwood.RavenwoodRule; + import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; -import junit.framework.TestCase; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; /** * Tests for {@link StateSet} */ +@RunWith(AndroidJUnit4.class) +@IgnoreUnderRavenwood(blockedBy = StateSet.class) +public class StateSetTest { + @Rule + public final RavenwoodRule mRavenwood = new RavenwoodRule(); -public class StateSetTest extends TestCase { - + @Test @SmallTest public void testStateSetPositiveMatches() throws Exception { int[] stateSpec = new int[2]; @@ -48,6 +61,7 @@ public class StateSetTest extends TestCase { assertTrue(StateSet.stateSetMatches(stateSpec, stateSet)); } + @Test @SmallTest public void testStatesSetMatchMixEmUp() throws Exception { int[] stateSpec = new int[2]; @@ -70,6 +84,7 @@ public class StateSetTest extends TestCase { assertTrue(StateSet.stateSetMatches(stateSpec, stateSet)); } + @Test @SmallTest public void testStateSetNegativeMatches() throws Exception { int[] stateSpec = new int[2]; @@ -92,6 +107,7 @@ public class StateSetTest extends TestCase { assertFalse(StateSet.stateSetMatches(stateSpec, stateSet)); } + @Test @SmallTest public void testEmptySetMatchesNegtives() throws Exception { int[] stateSpec = {-12345, -6789}; @@ -101,6 +117,7 @@ public class StateSetTest extends TestCase { assertTrue(StateSet.stateSetMatches(stateSpec, stateSet2)); } + @Test @SmallTest public void testEmptySetFailsPositives() throws Exception { int[] stateSpec = {12345}; @@ -110,6 +127,7 @@ public class StateSetTest extends TestCase { assertFalse(StateSet.stateSetMatches(stateSpec, stateSet2)); } + @Test @SmallTest public void testEmptySetMatchesWildcard() throws Exception { int[] stateSpec = StateSet.WILD_CARD; @@ -119,6 +137,7 @@ public class StateSetTest extends TestCase { assertTrue(StateSet.stateSetMatches(stateSpec, stateSet2)); } + @Test @SmallTest public void testSingleStatePositiveMatches() throws Exception { int[] stateSpec = new int[2]; @@ -135,6 +154,7 @@ public class StateSetTest extends TestCase { assertFalse(StateSet.stateSetMatches(stateSpec, state)); } + @Test @SmallTest public void testSingleStateNegativeMatches() throws Exception { int[] stateSpec = new int[2]; @@ -151,6 +171,7 @@ public class StateSetTest extends TestCase { assertTrue(StateSet.stateSetMatches(stateSpec, state)); } + @Test @SmallTest public void testZeroStateOnlyMatchesDefault() throws Exception { int[] stateSpec = new int[3]; @@ -166,6 +187,7 @@ public class StateSetTest extends TestCase { assertTrue(StateSet.stateSetMatches(stateSpec, state)); } + @Test @SmallTest public void testNullStateOnlyMatchesDefault() throws Exception { int[] stateSpec = new int[3]; diff --git a/core/tests/coretests/src/android/util/apk/SourceStampVerifierTest.java b/core/tests/coretests/src/android/util/apk/SourceStampVerifierTest.java index e0c583ddc978..48e76f79a928 100644 --- a/core/tests/coretests/src/android/util/apk/SourceStampVerifierTest.java +++ b/core/tests/coretests/src/android/util/apk/SourceStampVerifierTest.java @@ -26,12 +26,16 @@ import static org.junit.Assert.assertTrue; import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; import android.content.Context; +import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.core.app.ApplicationProvider; import libcore.io.Streams; import org.junit.After; +import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -48,13 +52,21 @@ import java.util.zip.ZipFile; /** Unit test for {@link android.util.apk.SourceStampVerifier} */ @RunWith(JUnit4.class) +@IgnoreUnderRavenwood(blockedBy = SourceStampVerifier.class) public class SourceStampVerifierTest { + @Rule + public final RavenwoodRule mRavenwood = new RavenwoodRule(); - private final Context mContext = ApplicationProvider.getApplicationContext(); + private Context mContext; private File mPrimaryApk; private File mSecondaryApk; + @Before + public void setUp() throws Exception { + mContext = ApplicationProvider.getApplicationContext(); + } + @After public void tearDown() throws Exception { if (mPrimaryApk != null) { diff --git a/core/tests/utiltests/src/android/util/MetadataReaderTest.java b/core/tests/utiltests/src/android/util/MetadataReaderTest.java index 24e9e0cd38c9..14feed8b89a1 100644 --- a/core/tests/utiltests/src/android/util/MetadataReaderTest.java +++ b/core/tests/utiltests/src/android/util/MetadataReaderTest.java @@ -50,13 +50,13 @@ public class MetadataReaderTest { private Bundle mData; @Before - protected void setUp() throws Exception { + public void setUp() throws Exception { mInputStream = getClass().getClassLoader().getResourceAsStream("res/drawable/image.jpg"); mData = new Bundle(); } @After - protected void tearDown() throws Exception { + public void tearDown() throws Exception { IoUtils.closeQuietly(mInputStream); } diff --git a/ravenwood/framework-minus-apex-ravenwood-policies.txt b/ravenwood/framework-minus-apex-ravenwood-policies.txt index 63f687264990..e417d37280d0 100644 --- a/ravenwood/framework-minus-apex-ravenwood-policies.txt +++ b/ravenwood/framework-minus-apex-ravenwood-policies.txt @@ -74,6 +74,7 @@ class android.util.proto.ProtoUtils stubclass class android.util.proto.WireTypeMismatchException stubclass # Misc +class android.util.BackupUtils stubclass class android.util.Dumpable stubclass class android.util.DebugUtils stubclass class android.util.MathUtils stubclass diff --git a/ravenwood/ravenwood-annotation-allowed-classes.txt b/ravenwood/ravenwood-annotation-allowed-classes.txt index 0e33d5620d60..99bc88a9d3c7 100644 --- a/ravenwood/ravenwood-annotation-allowed-classes.txt +++ b/ravenwood/ravenwood-annotation-allowed-classes.txt @@ -4,12 +4,21 @@ com.android.internal.util.ArrayUtils android.util.AtomicFile android.util.DataUnit +android.util.DayOfMonthCursor android.util.DumpableContainer android.util.EventLog android.util.IntArray +android.util.KeyValueListParser android.util.LongArray +android.util.LongArrayQueue +android.util.LongSparseLongArray android.util.LruCache +android.util.MonthDisplayHelper +android.util.RecurrenceRule +android.util.RotationUtils android.util.Slog +android.util.SparseDoubleArray +android.util.SparseSetArray android.util.TimeUtils android.util.Xml -- cgit v1.2.3-59-g8ed1b