1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.widget.cts; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertFalse; 21 import static org.junit.Assert.assertSame; 22 import static org.junit.Assert.assertTrue; 23 import static org.mockito.Mockito.atLeastOnce; 24 import static org.mockito.Mockito.reset; 25 import static org.mockito.Mockito.spy; 26 import static org.mockito.Mockito.times; 27 import static org.mockito.Mockito.verify; 28 29 import android.app.Activity; 30 import android.app.Instrumentation; 31 import android.content.Context; 32 import android.content.res.ColorStateList; 33 import android.graphics.Color; 34 import android.graphics.PorterDuff; 35 import android.graphics.drawable.ColorDrawable; 36 import android.graphics.drawable.Drawable; 37 import android.support.test.InstrumentationRegistry; 38 import android.support.test.annotation.UiThreadTest; 39 import android.support.test.filters.SmallTest; 40 import android.support.test.rule.ActivityTestRule; 41 import android.support.test.runner.AndroidJUnit4; 42 import android.util.AttributeSet; 43 import android.view.KeyEvent; 44 import android.widget.AbsSeekBar; 45 import android.widget.SeekBar; 46 import android.widget.cts.util.TestUtils; 47 48 import com.android.compatibility.common.util.PollingCheck; 49 import com.android.compatibility.common.util.WidgetTestUtils; 50 51 import org.junit.Before; 52 import org.junit.Rule; 53 import org.junit.Test; 54 import org.junit.runner.RunWith; 55 import org.mockito.ArgumentCaptor; 56 57 import java.util.List; 58 59 /** 60 * Test {@link AbsSeekBar}. 61 */ 62 @SmallTest 63 @RunWith(AndroidJUnit4.class) 64 public class AbsSeekBarTest { 65 private Instrumentation mInstrumentation; 66 private Activity mActivity; 67 68 @Rule 69 public ActivityTestRule<AbsSeekBarCtsActivity> mActivityRule = 70 new ActivityTestRule<>(AbsSeekBarCtsActivity.class); 71 72 @Before setup()73 public void setup() { 74 mInstrumentation = InstrumentationRegistry.getInstrumentation(); 75 mActivity = mActivityRule.getActivity(); 76 } 77 78 @Test testConstructor()79 public void testConstructor() { 80 new MyAbsSeekBar(mActivity); 81 82 new MyAbsSeekBar(mActivity, null); 83 84 new MyAbsSeekBar(mActivity, null, android.R.attr.progressBarStyle); 85 86 new MyAbsSeekBar(mActivity, null, 0, android.R.style.Widget_Material_Light_ProgressBar); 87 } 88 89 @Test testAccessThumbOffset()90 public void testAccessThumbOffset() { 91 AbsSeekBar myAbsSeekBar = new MyAbsSeekBar(mActivity); 92 final int positive = 5; 93 final int negative = -5; 94 final int zero = 0; 95 96 myAbsSeekBar.setThumbOffset(positive); 97 assertEquals(positive, myAbsSeekBar.getThumbOffset()); 98 99 myAbsSeekBar.setThumbOffset(zero); 100 assertEquals(zero, myAbsSeekBar.getThumbOffset()); 101 102 myAbsSeekBar.setThumbOffset(negative); 103 assertEquals(negative, myAbsSeekBar.getThumbOffset()); 104 } 105 106 @Test testAccessThumb()107 public void testAccessThumb() { 108 // Both are pointing to the same object. This works around current limitation in CTS 109 // coverage report tool for properly reporting coverage of base class method calls. 110 final MyAbsSeekBar myAbsSeekBar = new MyAbsSeekBar(mActivity); 111 final AbsSeekBar absSeekBar = myAbsSeekBar; 112 113 Drawable drawable1 = mActivity.getDrawable(R.drawable.scenery); 114 Drawable drawable2 = mActivity.getDrawable(R.drawable.pass); 115 116 assertFalse(myAbsSeekBar.verifyDrawable(drawable1)); 117 assertFalse(myAbsSeekBar.verifyDrawable(drawable2)); 118 119 absSeekBar.setThumb(drawable1); 120 assertSame(drawable1, absSeekBar.getThumb()); 121 assertTrue(myAbsSeekBar.verifyDrawable(drawable1)); 122 assertFalse(myAbsSeekBar.verifyDrawable(drawable2)); 123 124 absSeekBar.setThumb(drawable2); 125 assertSame(drawable2, absSeekBar.getThumb()); 126 assertFalse(myAbsSeekBar.verifyDrawable(drawable1)); 127 assertTrue(myAbsSeekBar.verifyDrawable(drawable2)); 128 } 129 130 @Test testAccessTickMark()131 public void testAccessTickMark() { 132 // Both are pointing to the same object. This works around current limitation in CTS 133 // coverage report tool for properly reporting coverage of base class method calls. 134 final MyAbsSeekBar myAbsSeekBar = new MyAbsSeekBar(mActivity); 135 final AbsSeekBar absSeekBar = myAbsSeekBar; 136 137 Drawable drawable1 = mActivity.getDrawable(R.drawable.black); 138 Drawable drawable2 = mActivity.getDrawable(R.drawable.black); 139 140 assertFalse(myAbsSeekBar.verifyDrawable(drawable1)); 141 assertFalse(myAbsSeekBar.verifyDrawable(drawable2)); 142 143 absSeekBar.setTickMark(drawable1); 144 assertSame(drawable1, absSeekBar.getTickMark()); 145 assertTrue(myAbsSeekBar.verifyDrawable(drawable1)); 146 assertFalse(myAbsSeekBar.verifyDrawable(drawable2)); 147 148 absSeekBar.setTickMark(drawable2); 149 assertSame(drawable2, absSeekBar.getTickMark()); 150 assertFalse(myAbsSeekBar.verifyDrawable(drawable1)); 151 assertTrue(myAbsSeekBar.verifyDrawable(drawable2)); 152 } 153 154 @Test testDrawableStateChanged()155 public void testDrawableStateChanged() { 156 MyAbsSeekBar myAbsSeekBar = new MyAbsSeekBar(mActivity); 157 Drawable mockProgressDrawable = spy(new ColorDrawable(Color.YELLOW)); 158 myAbsSeekBar.setProgressDrawable(mockProgressDrawable); 159 160 ArgumentCaptor<Integer> alphaCaptor = ArgumentCaptor.forClass(Integer.class); 161 myAbsSeekBar.setEnabled(false); 162 myAbsSeekBar.drawableStateChanged(); 163 verify(mockProgressDrawable, atLeastOnce()).setAlpha(alphaCaptor.capture()); 164 // Verify that the last call to setAlpha was with argument 0x00 165 List<Integer> alphaCaptures = alphaCaptor.getAllValues(); 166 assertTrue(!alphaCaptures.isEmpty()); 167 assertEquals(Integer.valueOf(0x00), alphaCaptures.get(alphaCaptures.size() - 1)); 168 169 alphaCaptor = ArgumentCaptor.forClass(Integer.class); 170 myAbsSeekBar.setEnabled(true); 171 myAbsSeekBar.drawableStateChanged(); 172 verify(mockProgressDrawable, atLeastOnce()).setAlpha(alphaCaptor.capture()); 173 // Verify that the last call to setAlpha was with argument 0xFF 174 alphaCaptures = alphaCaptor.getAllValues(); 175 assertTrue(!alphaCaptures.isEmpty()); 176 assertEquals(Integer.valueOf(0xFF), alphaCaptures.get(alphaCaptures.size() - 1)); 177 } 178 179 @Test testVerifyDrawable()180 public void testVerifyDrawable() { 181 MyAbsSeekBar myAbsSeekBar = new MyAbsSeekBar(mActivity); 182 Drawable drawable1 = mActivity.getDrawable(R.drawable.scenery); 183 Drawable drawable2 = mActivity.getDrawable(R.drawable.pass); 184 Drawable drawable3 = mActivity.getDrawable(R.drawable.blue); 185 Drawable drawable4 = mActivity.getDrawable(R.drawable.black); 186 187 assertFalse(myAbsSeekBar.verifyDrawable(drawable1)); 188 assertFalse(myAbsSeekBar.verifyDrawable(drawable2)); 189 assertFalse(myAbsSeekBar.verifyDrawable(drawable3)); 190 assertFalse(myAbsSeekBar.verifyDrawable(drawable4)); 191 192 myAbsSeekBar.setThumb(drawable1); 193 assertTrue(myAbsSeekBar.verifyDrawable(drawable1)); 194 assertFalse(myAbsSeekBar.verifyDrawable(drawable2)); 195 assertFalse(myAbsSeekBar.verifyDrawable(drawable3)); 196 assertFalse(myAbsSeekBar.verifyDrawable(drawable4)); 197 198 myAbsSeekBar.setThumb(drawable2); 199 assertFalse(myAbsSeekBar.verifyDrawable(drawable1)); 200 assertTrue(myAbsSeekBar.verifyDrawable(drawable2)); 201 assertFalse(myAbsSeekBar.verifyDrawable(drawable3)); 202 assertFalse(myAbsSeekBar.verifyDrawable(drawable4)); 203 204 myAbsSeekBar.setBackgroundDrawable(drawable2); 205 myAbsSeekBar.setProgressDrawable(drawable3); 206 myAbsSeekBar.setIndeterminateDrawable(drawable4); 207 assertFalse(myAbsSeekBar.verifyDrawable(drawable1)); 208 assertTrue(myAbsSeekBar.verifyDrawable(drawable2)); 209 assertTrue(myAbsSeekBar.verifyDrawable(drawable3)); 210 assertTrue(myAbsSeekBar.verifyDrawable(drawable4)); 211 } 212 213 @Test testAccessKeyProgressIncrement()214 public void testAccessKeyProgressIncrement() throws Throwable { 215 // AbsSeekBar is an abstract class, use its subclass: SeekBar to do this test. 216 mActivityRule.runOnUiThread(() -> mActivity.setContentView(R.layout.seekbar_layout)); 217 mInstrumentation.waitForIdleSync(); 218 219 final SeekBar seekBar = (SeekBar) mActivity.findViewById(R.id.seekBar); 220 final int keyProgressIncrement = 2; 221 mActivityRule.runOnUiThread(() -> { 222 seekBar.setKeyProgressIncrement(keyProgressIncrement); 223 seekBar.setFocusable(true); 224 seekBar.requestFocus(); 225 }); 226 PollingCheck.waitFor(1000, seekBar::hasWindowFocus); 227 assertEquals(keyProgressIncrement, seekBar.getKeyProgressIncrement()); 228 229 int oldProgress = seekBar.getProgress(); 230 KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_RIGHT); 231 mInstrumentation.sendKeySync(keyEvent); 232 assertEquals(oldProgress + keyProgressIncrement, seekBar.getProgress()); 233 oldProgress = seekBar.getProgress(); 234 keyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_LEFT); 235 mInstrumentation.sendKeySync(keyEvent); 236 assertEquals(oldProgress - keyProgressIncrement, seekBar.getProgress()); 237 } 238 239 @Test testAccessMax()240 public void testAccessMax() { 241 AbsSeekBar myAbsSeekBar = new MyAbsSeekBar(mActivity, null, R.style.TestProgressBar); 242 243 int progress = 10; 244 myAbsSeekBar.setProgress(progress); 245 int max = progress + 1; 246 myAbsSeekBar.setMax(max); 247 assertEquals(max, myAbsSeekBar.getMax()); 248 assertEquals(progress, myAbsSeekBar.getProgress()); 249 assertEquals(1, myAbsSeekBar.getKeyProgressIncrement()); 250 251 max = progress - 1; 252 myAbsSeekBar.setMax(max); 253 assertEquals(max, myAbsSeekBar.getMax()); 254 assertEquals(max, myAbsSeekBar.getProgress()); 255 assertEquals(1, myAbsSeekBar.getKeyProgressIncrement()); 256 257 int keyProgressIncrement = 10; 258 myAbsSeekBar.setKeyProgressIncrement(keyProgressIncrement); 259 assertEquals(keyProgressIncrement, myAbsSeekBar.getKeyProgressIncrement()); 260 max = (keyProgressIncrement - 1) * 20; 261 myAbsSeekBar.setMax(max); 262 assertEquals(keyProgressIncrement, myAbsSeekBar.getKeyProgressIncrement()); 263 max = (keyProgressIncrement + 1) * 20; 264 myAbsSeekBar.setMax(max); 265 assertEquals(keyProgressIncrement + 1, myAbsSeekBar.getKeyProgressIncrement()); 266 } 267 268 @Test testAccessMin()269 public void testAccessMin() { 270 AbsSeekBar myAbsSeekBar = new MyAbsSeekBar(mActivity, null, R.style.TestProgressBar); 271 272 int progress = -5; 273 int min = progress - 1; 274 int max = 5; 275 myAbsSeekBar.setMax(max); 276 myAbsSeekBar.setMin(min); 277 myAbsSeekBar.setProgress(progress); 278 assertEquals(min, myAbsSeekBar.getMin()); 279 assertEquals(progress, myAbsSeekBar.getProgress()); 280 assertEquals(1, myAbsSeekBar.getKeyProgressIncrement()); 281 282 min = progress + 1; 283 myAbsSeekBar.setMin(min); 284 assertEquals(min, myAbsSeekBar.getMin()); 285 assertEquals(min, myAbsSeekBar.getProgress()); 286 assertEquals(1, myAbsSeekBar.getKeyProgressIncrement()); 287 288 int keyProgressIncrement = 10; 289 myAbsSeekBar.setKeyProgressIncrement(keyProgressIncrement); 290 assertEquals(keyProgressIncrement, myAbsSeekBar.getKeyProgressIncrement()); 291 max = (keyProgressIncrement - 1) * 10; 292 min = -1 * keyProgressIncrement * 10; 293 myAbsSeekBar.setMax(max); 294 myAbsSeekBar.setMin(min); 295 assertEquals(keyProgressIncrement, myAbsSeekBar.getKeyProgressIncrement()); 296 297 max += 20; 298 myAbsSeekBar.setMax(max); 299 assertEquals(keyProgressIncrement + 1, myAbsSeekBar.getKeyProgressIncrement()); 300 assertEquals(min, myAbsSeekBar.getMin()); 301 assertEquals(max, myAbsSeekBar.getMax()); 302 } 303 304 @UiThreadTest 305 @Test testThumbTint()306 public void testThumbTint() { 307 AbsSeekBar inflatedView = (AbsSeekBar) mActivity.findViewById(R.id.thumb_tint); 308 309 assertEquals("Thumb tint inflated correctly", 310 Color.WHITE, inflatedView.getThumbTintList().getDefaultColor()); 311 assertEquals("Thumb tint mode inflated correctly", 312 PorterDuff.Mode.SRC_OVER, inflatedView.getThumbTintMode()); 313 314 Drawable mockThumb = spy(new ColorDrawable(Color.BLUE)); 315 316 inflatedView.setThumb(mockThumb); 317 verify(mockThumb, times(1)).setTintList(TestUtils.colorStateListOf(Color.WHITE)); 318 319 reset(mockThumb); 320 inflatedView.setThumbTintList(ColorStateList.valueOf(Color.RED)); 321 verify(mockThumb, times(1)).setTintList(TestUtils.colorStateListOf(Color.RED)); 322 323 inflatedView.setThumbTintMode(PorterDuff.Mode.DST_ATOP); 324 assertEquals("Thumb tint mode changed correctly", 325 PorterDuff.Mode.DST_ATOP, inflatedView.getThumbTintMode()); 326 327 reset(mockThumb); 328 inflatedView.setThumb(null); 329 inflatedView.setThumb(mockThumb); 330 verify(mockThumb, times(1)).setTintList(TestUtils.colorStateListOf(Color.RED)); 331 } 332 333 @UiThreadTest 334 @Test testTickMarkTint()335 public void testTickMarkTint() { 336 AbsSeekBar inflatedView = (AbsSeekBar) mActivity.findViewById(R.id.tick_mark_tint); 337 338 assertEquals("TickMark tint inflated correctly", 339 Color.WHITE, inflatedView.getTickMarkTintList().getDefaultColor()); 340 assertEquals("TickMark tint mode inflated correctly", 341 PorterDuff.Mode.SRC_OVER, inflatedView.getTickMarkTintMode()); 342 343 Drawable mockTickMark = spy(new ColorDrawable(Color.BLUE)); 344 345 inflatedView.setTickMark(mockTickMark); 346 verify(mockTickMark, times(1)).setTintList(TestUtils.colorStateListOf(Color.WHITE)); 347 348 reset(mockTickMark); 349 inflatedView.setTickMarkTintList(ColorStateList.valueOf(Color.RED)); 350 verify(mockTickMark, times(1)).setTintList(TestUtils.colorStateListOf(Color.RED)); 351 352 inflatedView.setTickMarkTintMode(PorterDuff.Mode.DARKEN); 353 assertEquals("TickMark tint mode changed correctly", 354 PorterDuff.Mode.DARKEN, inflatedView.getTickMarkTintMode()); 355 356 reset(mockTickMark); 357 inflatedView.setTickMark(null); 358 inflatedView.setTickMark(mockTickMark); 359 verify(mockTickMark, times(1)).setTintList(TestUtils.colorStateListOf(Color.RED)); 360 } 361 362 @Test testAccessSplitTrack()363 public void testAccessSplitTrack() throws Throwable { 364 AbsSeekBar inflatedView = (AbsSeekBar) mActivity.findViewById(R.id.tick_mark_tint); 365 366 WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, inflatedView, 367 () -> inflatedView.setSplitTrack(true)); 368 assertTrue(inflatedView.getSplitTrack()); 369 370 WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, inflatedView, 371 () -> inflatedView.setSplitTrack(false)); 372 assertFalse(inflatedView.getSplitTrack()); 373 } 374 375 private static class MyAbsSeekBar extends AbsSeekBar { MyAbsSeekBar(Context context)376 public MyAbsSeekBar(Context context) { 377 super(context); 378 } 379 MyAbsSeekBar(Context context, AttributeSet attrs)380 public MyAbsSeekBar(Context context, AttributeSet attrs) { 381 super(context, attrs); 382 } 383 MyAbsSeekBar(Context context, AttributeSet attrs, int defStyle)384 public MyAbsSeekBar(Context context, AttributeSet attrs, int defStyle) { 385 super(context, attrs, defStyle); 386 } 387 MyAbsSeekBar(Context context, AttributeSet attrs, int defStyle, int defStyleRes)388 public MyAbsSeekBar(Context context, AttributeSet attrs, int defStyle, int defStyleRes) { 389 super(context, attrs, defStyle, defStyleRes); 390 } 391 392 @Override drawableStateChanged()393 protected void drawableStateChanged() { 394 super.drawableStateChanged(); 395 } 396 397 @Override verifyDrawable(Drawable who)398 protected boolean verifyDrawable(Drawable who) { 399 return super.verifyDrawable(who); 400 } 401 } 402 } 403