CTS for Drawable.hasFocusStateSpecified.
Test: cts-tradefed run singleCommand cts --skip-device-info
--skip-preconditions --abi armeabi-v7a -m CtsGraphicsTestCases
-t android.graphics.drawable.cts.DefaultFocusHighlightTest
Bug: 35096940
Change-Id: I8a95e3cb72b7b9a0cfbd2ea6eef3777226198a20
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/DefaultFocusHighlightTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/DefaultFocusHighlightTest.java
new file mode 100644
index 0000000..4849e71
--- /dev/null
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/DefaultFocusHighlightTest.java
@@ -0,0 +1,357 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.graphics.drawable.cts;
+
+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 android.content.Context;
+import android.content.res.ColorStateList;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
+import android.graphics.BitmapFactory;
+import android.graphics.NinePatch;
+import android.graphics.Picture;
+import android.graphics.cts.R;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.DrawableContainer;
+import android.graphics.drawable.DrawableContainer.DrawableContainerState;
+import android.graphics.drawable.GradientDrawable;
+import android.graphics.drawable.LevelListDrawable;
+import android.graphics.drawable.NinePatchDrawable;
+import android.graphics.drawable.PaintDrawable;
+import android.graphics.drawable.PictureDrawable;
+import android.graphics.drawable.RippleDrawable;
+import android.graphics.drawable.ShapeDrawable;
+import android.graphics.drawable.StateListDrawable;
+import android.graphics.drawable.shapes.RectShape;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.annotation.UiThreadTest;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.StateSet;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+public class DefaultFocusHighlightTest {
+
+ // The target context.
+ private Context mContext;
+
+ @Before
+ public void setup() {
+ mContext = InstrumentationRegistry.getTargetContext();
+ }
+
+ private static final int A_COLOR = 0x920424;
+ private static final int[] NO_STATE_FOCUSED = new int[] { android.R.attr.state_enabled };
+ private static final int[] ONLY_STATE_FOCUSED = new int[] { android.R.attr.state_focused };
+ private static final int[] STATE_FOCUSED_WITH_POS =
+ new int[] { android.R.attr.state_focused, android.R.attr.state_hovered };
+ private static final int[] STATE_FOCUSED_WITH_NEG =
+ new int[] { android.R.attr.state_focused, -android.R.attr.state_hovered };
+ private static final int[] STATE_FOCUSED_WITH_ENABLED =
+ new int[] { android.R.attr.state_focused, android.R.attr.state_enabled };
+
+ final static int[] FOCUSED_STATE =
+ new int[] { android.R.attr.state_focused, android.R.attr.state_enabled };
+
+ @UiThreadTest
+ @Test
+ public void testStateListDrawable() {
+ Drawable d;
+ // Empty state spec
+ d = DrawableFactory.createStateListDrawable(
+ new int[][] {}
+ );
+ d.setState(FOCUSED_STATE);
+ assertFalse(d.hasFocusStateSpecified());
+
+ // Wild card
+ d = DrawableFactory.createStateListDrawable(
+ new int[][] { StateSet.WILD_CARD }
+ );
+ d.setState(FOCUSED_STATE);
+ assertFalse(d.hasFocusStateSpecified());
+
+ // No state spec of state_focused=true
+ d = DrawableFactory.createStateListDrawable(
+ new int[][] { NO_STATE_FOCUSED }
+ );
+ d.setState(FOCUSED_STATE);
+ assertFalse(d.hasFocusStateSpecified());
+
+ // One state spec of only state_focused=true
+ d = DrawableFactory.createStateListDrawable(
+ new int[][] { ONLY_STATE_FOCUSED }
+ );
+ d.setState(FOCUSED_STATE);
+ assertTrue(d.hasFocusStateSpecified());
+
+ // One state spec of state_focused=true and something=true, but no state spec of
+ // state_focused=true and something=false (something is not enabled)
+ d = DrawableFactory.createStateListDrawable(
+ new int[][] { STATE_FOCUSED_WITH_POS }
+ );
+ d.setState(FOCUSED_STATE);
+ assertTrue(d.hasFocusStateSpecified());
+
+ // One state spec of state_focused=true and something=true, and one spec of
+ // state_focused=true and something=false (something is not enabled)
+ d = DrawableFactory.createStateListDrawable(
+ new int[][] { STATE_FOCUSED_WITH_POS, STATE_FOCUSED_WITH_NEG }
+ );
+ d.setState(FOCUSED_STATE);
+ assertTrue(d.hasFocusStateSpecified());
+
+ // One state spec of state_focused=true and enabled=true
+ d = DrawableFactory.createStateListDrawable(
+ new int[][] { STATE_FOCUSED_WITH_ENABLED }
+ );
+ d.setState(FOCUSED_STATE);
+ assertTrue(d.hasFocusStateSpecified());
+ }
+
+ @UiThreadTest
+ @Test
+ public void testRippleDrawable() {
+ Drawable d = DrawableFactory.createRippleDrawable();
+ d.setState(FOCUSED_STATE);
+ assertTrue(d.hasFocusStateSpecified());
+ }
+
+ @UiThreadTest
+ @Test
+ public void testPictureDrawable() {
+ Drawable d = DrawableFactory.createPictureDrawable(null);
+ d.setState(FOCUSED_STATE);
+ assertFalse(d.hasFocusStateSpecified());
+
+ d = DrawableFactory.createPictureDrawable(new Picture());
+ d.setState(FOCUSED_STATE);
+ assertFalse(d.hasFocusStateSpecified());
+ }
+
+ @UiThreadTest
+ @Test
+ public void testColorStateListHandledDrawable() {
+ final Drawable[] drawables = new Drawable[] {
+ DrawableFactory.createShapeDrawable(),
+ DrawableFactory.createPaintDrawable(),
+ DrawableFactory.createBitmapDrawable(mContext),
+ DrawableFactory.createColorDrawable(),
+ DrawableFactory.createGradientDrawable(),
+ DrawableFactory.createNinePatchDrawable(mContext),
+ };
+ final ColorStateList[] stateLists = new ColorStateList[] {
+ // Empty state spec
+ new ColorStateList(
+ new int[][] { },
+ new int[] { }),
+ // Wild card
+ new ColorStateList(
+ new int[][] { StateSet.WILD_CARD },
+ new int[] { A_COLOR }),
+ // No state spec of state_focused=true
+ new ColorStateList(
+ new int[][] { NO_STATE_FOCUSED },
+ new int[] { A_COLOR }),
+ // One state spec of only state_focused=true
+ new ColorStateList(
+ new int[][] { ONLY_STATE_FOCUSED },
+ new int[] { A_COLOR }),
+ // One state spec of state_focused=true and something=true,
+ // but no state spec of state_focused=true and something=false
+ new ColorStateList(
+ new int[][] { STATE_FOCUSED_WITH_POS },
+ new int[] { A_COLOR }),
+ // One state spec of state_focused=true and something=true,
+ // and one spec of state_focused=true and something=false
+ new ColorStateList(
+ new int[][] { STATE_FOCUSED_WITH_POS, STATE_FOCUSED_WITH_NEG },
+ new int[] { A_COLOR, A_COLOR }),
+ };
+ final boolean[] expectedResults = new boolean[] {
+ // Empty state spec
+ false,
+ // Wild card
+ false,
+ // No state spec of state_focused=true
+ false,
+ // One state spec of only state_focused=true
+ true,
+ // One state spec of state_focused=true and something=true,
+ // but no state spec of state_focused=true and something=false
+ true,
+ // One state spec of state_focused=true and something=true,
+ // and one spec of state_focused=true and something=false
+ true
+ };
+ assertEquals(stateLists.length, expectedResults.length);
+ for (Drawable drawable : drawables) {
+ // No ColorStateList set
+ String drawableName = drawable.getClass().toString();
+ String errorMsg = "[" + drawableName + "] Testing no ColorStateList failed.";
+ drawable.setState(FOCUSED_STATE);
+ assertFalse(errorMsg, drawable.hasFocusStateSpecified());
+ // With ColorStateList set
+ for (int i = 0; i < stateLists.length; i++) {
+ ColorStateList stateList = stateLists[i];
+ boolean expectedResult = expectedResults[i];
+ drawable.setTintList(stateList);
+ errorMsg = "[" + drawableName + "] Testing ColorStateList No." + i + " failed.";
+
+ drawable.setState(FOCUSED_STATE);
+ if (expectedResult) {
+ assertTrue(errorMsg, drawable.hasFocusStateSpecified());
+ } else {
+ assertFalse(errorMsg, drawable.hasFocusStateSpecified());
+ }
+ }
+ }
+ }
+
+ @UiThreadTest
+ @Test
+ public void testDrawableContainer() {
+ MockDrawableContainer container;
+ DrawableContainerState containerState;
+
+ // Empty
+ container = new MockDrawableContainer();
+ containerState = (DrawableContainerState) new LevelListDrawable().getConstantState();
+ assertNotNull(containerState);
+ container.setConstantState(containerState);
+ container.setState(FOCUSED_STATE);
+ assertFalse(container.hasFocusStateSpecified());
+
+ // No drawable of state_focused=true
+ container = new MockDrawableContainer();
+ containerState = (DrawableContainerState) new LevelListDrawable().getConstantState();
+ assertNotNull(containerState);
+ container.setConstantState(containerState);
+ containerState.addChild(DrawableFactory.createPaintDrawable());
+ containerState.addChild(DrawableFactory.createBitmapDrawable(mContext));
+ containerState.addChild(DrawableFactory.createColorDrawable());
+ container.selectDrawable(0);
+ container.setState(FOCUSED_STATE);
+ assertFalse(container.hasFocusStateSpecified());
+ container.selectDrawable(1);
+ container.setState(FOCUSED_STATE);
+ assertFalse(container.hasFocusStateSpecified());
+ container.selectDrawable(2);
+ container.setState(FOCUSED_STATE);
+ assertFalse(container.hasFocusStateSpecified());
+
+ // Only drawables of state_focused=true
+ container = new MockDrawableContainer();
+ containerState = (DrawableContainerState) new LevelListDrawable().getConstantState();
+ assertNotNull(containerState);
+ container.setConstantState(containerState);
+ containerState.addChild(DrawableFactory.createRippleDrawable());
+ containerState.addChild(
+ DrawableFactory.createStateListDrawable(
+ new int[][] { STATE_FOCUSED_WITH_POS, STATE_FOCUSED_WITH_NEG }
+ )
+ );
+ container.selectDrawable(0);
+ container.setState(FOCUSED_STATE);
+ assertTrue(container.hasFocusStateSpecified());
+ container.selectDrawable(1);
+ container.setState(FOCUSED_STATE);
+ assertTrue(container.hasFocusStateSpecified());
+
+ // Both drawables of state_focused=true and state_focused=false
+ containerState.addChild(DrawableFactory.createColorDrawable());
+ container.selectDrawable(2);
+ container.setState(FOCUSED_STATE);
+ assertFalse(container.hasFocusStateSpecified());
+ container.selectDrawable(1);
+ container.setState(FOCUSED_STATE);
+ assertTrue(container.hasFocusStateSpecified());
+ container.selectDrawable(0);
+ container.setState(FOCUSED_STATE);
+ assertTrue(container.hasFocusStateSpecified());
+ }
+
+ static class DrawableFactory {
+ static ShapeDrawable createShapeDrawable() {
+ return new ShapeDrawable(new RectShape());
+ }
+ static PaintDrawable createPaintDrawable() {
+ PaintDrawable paintDrawable = new PaintDrawable();
+ paintDrawable.setCornerRadius(1.5f);
+ return paintDrawable;
+ }
+ static BitmapDrawable createBitmapDrawable(Context context) {
+ Bitmap bitmap = Bitmap.createBitmap(200, 300, Config.ARGB_8888);
+ BitmapDrawable bitmapDrawable = new BitmapDrawable(context.getResources(), bitmap);
+ return bitmapDrawable;
+ }
+ static ColorDrawable createColorDrawable() {
+ return new ColorDrawable(A_COLOR);
+ }
+ static GradientDrawable createGradientDrawable() {
+ GradientDrawable gradientDrawable = new GradientDrawable();
+ gradientDrawable.setColor(A_COLOR);
+ gradientDrawable.setCornerRadius(10f);
+ return gradientDrawable;
+ }
+ static NinePatchDrawable createNinePatchDrawable(Context context) {
+ Resources res = context.getResources();
+ Bitmap bitmap = BitmapFactory.decodeResource(res, R.drawable.ninepatch_0);
+ NinePatch np = new NinePatch(bitmap, bitmap.getNinePatchChunk(), null);
+ NinePatchDrawable ninePatchDrawable = new NinePatchDrawable(res, np);
+ return ninePatchDrawable;
+ }
+ static RippleDrawable createRippleDrawable() {
+ RippleDrawable rippleDrawable =
+ new RippleDrawable(ColorStateList.valueOf(A_COLOR), null, null);
+ return rippleDrawable;
+ }
+ static PictureDrawable createPictureDrawable(Picture picture) {
+ PictureDrawable pictureDrawable = new PictureDrawable(picture);
+ return pictureDrawable;
+ }
+ static StateListDrawable createStateListDrawable(int[][] stateList) {
+ StateListDrawable drawable = new StateListDrawable();
+ ColorDrawable colorDrawable = DrawableFactory.createColorDrawable();
+ for (int i = 0; i < stateList.length; i++) {
+ drawable.addState(stateList[i], colorDrawable);
+ }
+ return drawable;
+ }
+ }
+
+ // We're calling protected methods in DrawableContainer.
+ // So we have to extend it here to make it accessible.
+ private class MockDrawableContainer extends DrawableContainer {
+ @Override
+ protected void setConstantState(DrawableContainerState state) {
+ super.setConstantState(state);
+ }
+ }
+
+}