PageRenderTime 62ms CodeModel.GetById 31ms RepoModel.GetById 0ms app.codeStats 0ms

/core/tests/coretests/src/android/animation/ValueAnimatorTests.java

http://github.com/CyanogenMod/android_frameworks_base
Java | 1192 lines | 965 code | 143 blank | 84 comment | 16 complexity | 02b61fa90523a8cee73315852ee608a2 MD5 | raw file
Possible License(s): LGPL-2.1, MPL-2.0-no-copyleft-exception, CC0-1.0, BitTorrent-1.0, BSD-3-Clause
  1. /*
  2. * Copyright (C) 2015 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. package android.animation;
  17. import android.os.Handler;
  18. import android.os.Looper;
  19. import android.os.Message;
  20. import android.os.SystemClock;
  21. import android.test.ActivityInstrumentationTestCase2;
  22. import android.test.suitebuilder.annotation.SmallTest;
  23. import android.view.Choreographer;
  24. import android.view.animation.LinearInterpolator;
  25. import java.util.ArrayList;
  26. import static android.test.MoreAsserts.assertNotEqual;
  27. public class ValueAnimatorTests extends ActivityInstrumentationTestCase2<BasicAnimatorActivity> {
  28. private static final long WAIT_TIME_OUT = 5000;
  29. private ValueAnimator a1;
  30. private ValueAnimator a2;
  31. // Tolerance of error in calculations related to duration, frame time, etc. due to frame delay.
  32. private final static long TOLERANCE = 100; // ms
  33. private final static long POLL_INTERVAL = 100; // ms
  34. private final static float A1_START_VALUE = 0f;
  35. private final static float A1_END_VALUE = 1f;
  36. private final static int A2_START_VALUE = 100;
  37. private final static int A2_END_VALUE = 200;
  38. private final static long DEFAULT_FRAME_INTERVAL = 5; //ms
  39. private final static long COMMIT_DELAY = 3; //ms
  40. public ValueAnimatorTests() {
  41. super(BasicAnimatorActivity.class);
  42. }
  43. @Override
  44. public void setUp() throws Exception {
  45. super.setUp();
  46. a1 = ValueAnimator.ofFloat(A1_START_VALUE, A1_END_VALUE).setDuration(300);
  47. a2 = ValueAnimator.ofInt(A2_START_VALUE, A2_END_VALUE).setDuration(500);
  48. }
  49. @Override
  50. public void tearDown() throws Exception {
  51. a1 = null;
  52. a2 = null;
  53. super.tearDown();
  54. }
  55. @SmallTest
  56. public void testStartDelay() throws Throwable {
  57. final ValueAnimator a = ValueAnimator.ofFloat(5f, 20f);
  58. assertEquals(a.getStartDelay(), 0);
  59. final long delay = 200;
  60. a.setStartDelay(delay);
  61. assertEquals(a.getStartDelay(), delay);
  62. final MyUpdateListener listener = new MyUpdateListener();
  63. a.addUpdateListener(listener);
  64. final long[] startTime = new long[1];
  65. runTestOnUiThread(new Runnable() {
  66. @Override
  67. public void run() {
  68. // Test the time between isRunning() and isStarted()
  69. assertFalse(a.isStarted());
  70. assertFalse(a.isRunning());
  71. a.start();
  72. startTime[0] = SystemClock.uptimeMillis();
  73. assertTrue(a.isStarted());
  74. assertFalse(a.isRunning());
  75. }
  76. });
  77. Thread.sleep(a.getTotalDuration());
  78. runTestOnUiThread(new Runnable() {
  79. @Override
  80. public void run() {
  81. assertTrue(listener.wasRunning);
  82. assertTrue(listener.firstRunningFrameTime - startTime[0] >= delay);
  83. }
  84. });
  85. Thread.sleep(a.getTotalDuration());
  86. runTestOnUiThread(new Runnable() {
  87. @Override
  88. public void run() {
  89. assertFalse(a.isStarted());
  90. }
  91. });
  92. }
  93. @SmallTest
  94. public void testListenerCallbacks() throws Throwable {
  95. final MyListener l1 = new MyListener();
  96. final MyListener l2 = new MyListener();
  97. a1.addListener(l1);
  98. a2.addListener(l2);
  99. a2.setStartDelay(400);
  100. assertFalse(l1.startCalled);
  101. assertFalse(l1.cancelCalled);
  102. assertFalse(l1.endCalled);
  103. assertFalse(l2.startCalled);
  104. assertFalse(l2.cancelCalled);
  105. assertFalse(l2.endCalled);
  106. runTestOnUiThread(new Runnable() {
  107. @Override
  108. public void run() {
  109. a1.start();
  110. a2.start();
  111. }
  112. });
  113. long wait = 0;
  114. Thread.sleep(POLL_INTERVAL);
  115. wait += POLL_INTERVAL;
  116. runTestOnUiThread(new Runnable() {
  117. @Override
  118. public void run() {
  119. assertFalse(l1.cancelCalled);
  120. a1.cancel();
  121. assertTrue(l1.cancelCalled);
  122. assertTrue(l1.endCalled);
  123. }
  124. });
  125. while (wait < a2.getStartDelay()) {
  126. runTestOnUiThread(new Runnable() {
  127. @Override
  128. public void run() {
  129. // Make sure a2's start listener isn't called during start delay.
  130. assertTrue(l1.startCalled);
  131. assertFalse(l2.startCalled);
  132. }
  133. });
  134. Thread.sleep(POLL_INTERVAL);
  135. wait += POLL_INTERVAL;
  136. }
  137. long delay = Math.max(a1.getTotalDuration(), a2.getTotalDuration()) + TOLERANCE;
  138. Thread.sleep(delay);
  139. runTestOnUiThread(new Runnable() {
  140. @Override
  141. public void run() {
  142. // a1 is canceled.
  143. assertTrue(l1.startCalled);
  144. assertTrue(l1.cancelCalled);
  145. assertTrue(l1.endCalled);
  146. // a2 is supposed to finish normally
  147. assertTrue(l2.startCalled);
  148. assertFalse(l2.cancelCalled);
  149. assertTrue(l2.endCalled);
  150. }
  151. });
  152. }
  153. @SmallTest
  154. public void testIsStarted() throws Throwable {
  155. assertFalse(a1.isStarted());
  156. assertFalse(a2.isStarted());
  157. assertFalse(a1.isRunning());
  158. assertFalse(a2.isRunning());
  159. final long startDelay = 150;
  160. a1.setStartDelay(startDelay);
  161. final long[] startTime = new long[1];
  162. runTestOnUiThread(new Runnable() {
  163. @Override
  164. public void run() {
  165. a1.start();
  166. a2.start();
  167. startTime[0] = SystemClock.uptimeMillis();
  168. assertTrue(a1.isStarted());
  169. assertTrue(a2.isStarted());
  170. }
  171. });
  172. long delayMs = 0;
  173. while (delayMs < startDelay) {
  174. Thread.sleep(POLL_INTERVAL);
  175. delayMs += POLL_INTERVAL;
  176. runTestOnUiThread(new Runnable() {
  177. @Override
  178. public void run() {
  179. if (SystemClock.uptimeMillis() - startTime[0] < startDelay) {
  180. assertFalse(a1.isRunning());
  181. }
  182. }
  183. });
  184. }
  185. Thread.sleep(startDelay);
  186. runTestOnUiThread(new Runnable() {
  187. @Override
  188. public void run() {
  189. assertTrue(a1.isRunning());
  190. assertTrue(a2.isRunning());
  191. }
  192. });
  193. long delay = Math.max(a1.getTotalDuration(), a2.getTotalDuration()) * 2;
  194. Thread.sleep(delay);
  195. runTestOnUiThread(new Runnable() {
  196. @Override
  197. public void run() {
  198. assertFalse(a1.isStarted());
  199. assertFalse(a1.isRunning());
  200. assertFalse(a2.isStarted());
  201. assertFalse(a2.isRunning());
  202. }
  203. });
  204. }
  205. @SmallTest
  206. public void testPause() throws Throwable {
  207. runTestOnUiThread(new Runnable() {
  208. @Override
  209. public void run() {
  210. assertFalse(a1.isPaused());
  211. assertFalse(a2.isPaused());
  212. a1.start();
  213. a2.start();
  214. assertFalse(a1.isPaused());
  215. assertFalse(a2.isPaused());
  216. assertTrue(a1.isStarted());
  217. assertTrue(a2.isStarted());
  218. }
  219. });
  220. Thread.sleep(POLL_INTERVAL);
  221. runTestOnUiThread(new Runnable() {
  222. @Override
  223. public void run() {
  224. assertTrue(a1.isRunning());
  225. assertTrue(a2.isRunning());
  226. a1.pause();
  227. assertTrue(a1.isPaused());
  228. assertFalse(a2.isPaused());
  229. assertTrue(a1.isRunning());
  230. }
  231. });
  232. Thread.sleep(a2.getTotalDuration());
  233. runTestOnUiThread(new Runnable() {
  234. @Override
  235. public void run() {
  236. // By this time, a2 should have finished, and a1 is still paused
  237. assertFalse(a2.isStarted());
  238. assertFalse(a2.isRunning());
  239. assertTrue(a1.isStarted());
  240. assertTrue(a1.isRunning());
  241. assertTrue(a1.isPaused());
  242. a1.resume();
  243. }
  244. });
  245. Thread.sleep(POLL_INTERVAL);
  246. runTestOnUiThread(new Runnable() {
  247. @Override
  248. public void run() {
  249. assertTrue(a1.isRunning());
  250. assertTrue(a1.isStarted());
  251. assertFalse(a1.isPaused());
  252. }
  253. });
  254. Thread.sleep(a1.getTotalDuration());
  255. runTestOnUiThread(new Runnable() {
  256. @Override
  257. public void run() {
  258. // a1 should finish by now.
  259. assertFalse(a1.isRunning());
  260. assertFalse(a1.isStarted());
  261. assertFalse(a1.isPaused());
  262. }
  263. });
  264. }
  265. @SmallTest
  266. public void testPauseListener() throws Throwable {
  267. MyPauseListener l1 = new MyPauseListener();
  268. MyPauseListener l2 = new MyPauseListener();
  269. a1.addPauseListener(l1);
  270. a2.addPauseListener(l2);
  271. assertFalse(l1.pauseCalled);
  272. assertFalse(l1.resumeCalled);
  273. assertFalse(l2.pauseCalled);
  274. assertFalse(l2.resumeCalled);
  275. runTestOnUiThread(new Runnable() {
  276. @Override
  277. public void run() {
  278. a1.start();
  279. a2.start();
  280. }
  281. });
  282. Thread.sleep(a1.getTotalDuration() / 2);
  283. a1.pause();
  284. Thread.sleep(a2.getTotalDuration());
  285. // Only a1's pause listener should be called.
  286. assertTrue(l1.pauseCalled);
  287. assertFalse(l1.resumeCalled);
  288. runTestOnUiThread(new Runnable() {
  289. @Override
  290. public void run() {
  291. a1.resume();
  292. }
  293. });
  294. Thread.sleep(a1.getTotalDuration());
  295. assertTrue(l1.pauseCalled);
  296. assertTrue(l1.resumeCalled);
  297. assertFalse(l2.pauseCalled);
  298. assertFalse(l2.resumeCalled);
  299. }
  300. @SmallTest
  301. public void testResume() throws Throwable {
  302. final MyUpdateListener l1 = new MyUpdateListener();
  303. final long totalDuration = a1.getTotalDuration();
  304. a1.addUpdateListener(l1);
  305. // Set a longer duration on a1 for this test
  306. a1.setDuration(1000);
  307. assertTrue(l1.firstRunningFrameTime < 0);
  308. assertTrue(l1.lastUpdateTime < 0);
  309. final long[] lastUpdate = new long[1];
  310. runTestOnUiThread(new Runnable() {
  311. @Override
  312. public void run() {
  313. a1.start();
  314. }
  315. });
  316. Thread.sleep(totalDuration / 2);
  317. runTestOnUiThread(new Runnable() {
  318. @Override
  319. public void run() {
  320. assertTrue(l1.firstRunningFrameTime > 0);
  321. assertTrue(l1.lastUpdateTime > l1.firstRunningFrameTime);
  322. lastUpdate[0] = l1.lastUpdateTime;
  323. a1.pause();
  324. }
  325. });
  326. Thread.sleep(totalDuration);
  327. runTestOnUiThread(new Runnable() {
  328. @Override
  329. public void run() {
  330. // There should be no update after pause()
  331. assertEquals(lastUpdate[0], l1.lastUpdateTime);
  332. a1.resume();
  333. }
  334. });
  335. do {
  336. Thread.sleep(POLL_INTERVAL);
  337. runTestOnUiThread(new Runnable() {
  338. @Override
  339. public void run() {
  340. assertTrue(l1.lastUpdateTime > lastUpdate[0]);
  341. lastUpdate[0] = l1.lastUpdateTime;
  342. }
  343. });
  344. } while (!a1.isStarted());
  345. // Time between pause and resume: totalDuration
  346. long entireSpan = totalDuration * 2;
  347. long frameDelta = l1.lastUpdateTime - l1.firstRunningFrameTime;
  348. assertTrue(Math.abs(entireSpan - frameDelta) < TOLERANCE);
  349. }
  350. @SmallTest
  351. public void testEnd() throws Throwable {
  352. final MyListener l1 = new MyListener();
  353. final MyListener l2 = new MyListener();
  354. a1.addListener(l1);
  355. a2.addListener(l2);
  356. a1.addListener(new MyListener() {
  357. @Override
  358. public void onAnimationEnd(Animator anim) {
  359. anim.cancel();
  360. }
  361. });
  362. a2.addListener(new MyListener() {
  363. @Override
  364. public void onAnimationCancel(Animator anim) {
  365. anim.end();
  366. }
  367. });
  368. runTestOnUiThread(new Runnable() {
  369. @Override
  370. public void run() {
  371. assertFalse(l1.cancelCalled);
  372. assertFalse(l1.endCalled);
  373. assertFalse(l2.cancelCalled);
  374. assertFalse(l2.endCalled);
  375. a1.start();
  376. a2.start();
  377. }
  378. });
  379. Thread.sleep(POLL_INTERVAL);
  380. runTestOnUiThread(new Runnable() {
  381. @Override
  382. public void run() {
  383. a1.end();
  384. a2.cancel();
  385. }
  386. });
  387. Thread.sleep(POLL_INTERVAL);
  388. runTestOnUiThread(new Runnable() {
  389. @Override
  390. public void run() {
  391. // Calling cancel from onAnimationEnd will be ignored.
  392. assertFalse(l1.cancelCalled);
  393. assertTrue(l1.endCalled);
  394. assertTrue(l2.cancelCalled);
  395. assertTrue(l2.endCalled);
  396. float value1 = (Float) a1.getAnimatedValue();
  397. int value2 = (Integer) a2.getAnimatedValue();
  398. assertEquals(A1_END_VALUE, value1);
  399. assertEquals(A2_END_VALUE, value2);
  400. }
  401. });
  402. }
  403. @SmallTest
  404. public void testEndValue() throws Throwable {
  405. final MyListener l1 = new MyListener();
  406. a1.addListener(l1);
  407. final MyListener l2 = new MyListener();
  408. a2.addListener(l2);
  409. runTestOnUiThread(new Runnable() {
  410. @Override
  411. public void run() {
  412. a1.start();
  413. a2.start();
  414. }
  415. });
  416. Thread.sleep(POLL_INTERVAL);
  417. runTestOnUiThread(new Runnable() {
  418. @Override
  419. public void run() {
  420. // Animation has started but not finished, check animated values against end values
  421. assertFalse(l1.endCalled);
  422. assertFalse(l2.endCalled);
  423. assertNotEqual(A1_END_VALUE, a1.getAnimatedValue());
  424. assertNotEqual(A1_END_VALUE, a2.getAnimatedValue());
  425. // Force a2 to end.
  426. a2.end();
  427. }
  428. });
  429. Thread.sleep(a1.getTotalDuration());
  430. runTestOnUiThread(new Runnable() {
  431. @Override
  432. public void run() {
  433. assertFalse(l1.cancelCalled);
  434. assertTrue(l1.endCalled);
  435. assertFalse(l2.cancelCalled);
  436. assertTrue(l2.endCalled);
  437. // By now a1 should have finished normally and a2 has skipped to the end, check
  438. // their end values.
  439. assertEquals(A1_END_VALUE, ((Float) (a1.getAnimatedValue())).floatValue());
  440. assertEquals(A2_END_VALUE, ((Integer) (a2.getAnimatedValue())).intValue());
  441. }
  442. });
  443. }
  444. @SmallTest
  445. public void testUpdateListener() throws InterruptedException {
  446. final MyFrameCallbackProvider provider = new MyFrameCallbackProvider();
  447. long sleep = 0;
  448. while (provider.mHandler == null) {
  449. Thread.sleep(POLL_INTERVAL);
  450. sleep += POLL_INTERVAL;
  451. if (sleep > WAIT_TIME_OUT) {
  452. break;
  453. }
  454. }
  455. // Either the looper has started, or timed out
  456. assertNotNull(provider.mHandler);
  457. final MyListener listener = new MyListener();
  458. final MyUpdateListener l1 = new MyUpdateListener() {
  459. @Override
  460. public void onAnimationUpdate(ValueAnimator animation) {
  461. long currentTime = SystemClock.uptimeMillis();
  462. long frameDelay = provider.getFrameDelay();
  463. if (lastUpdateTime > 0) {
  464. // Error tolerance here is one frame.
  465. assertTrue((currentTime - lastUpdateTime) < frameDelay * 2);
  466. } else {
  467. // First frame:
  468. assertTrue(listener.startCalled);
  469. assertTrue(listener.startTime > 0);
  470. assertTrue(currentTime - listener.startTime < frameDelay * 2);
  471. }
  472. super.onAnimationUpdate(animation);
  473. }
  474. };
  475. a1.addUpdateListener(l1);
  476. a1.addListener(listener);
  477. a1.setStartDelay(100);
  478. provider.mHandler.post(new Runnable() {
  479. @Override
  480. public void run() {
  481. AnimationHandler.getInstance().setProvider(provider);
  482. a1.start();
  483. }
  484. });
  485. Thread.sleep(POLL_INTERVAL);
  486. assertTrue(a1.isStarted());
  487. Thread.sleep(a1.getTotalDuration() + TOLERANCE);
  488. // Finished by now.
  489. assertFalse(a1.isStarted());
  490. assertTrue(listener.endTime > 0);
  491. // Check the time difference between last frame and end time.
  492. assertTrue(listener.endTime >= l1.lastUpdateTime);
  493. assertTrue(listener.endTime - l1.lastUpdateTime < 2 * provider.getFrameDelay());
  494. }
  495. @SmallTest
  496. public void testConcurrentModification() throws Throwable {
  497. // Attempt to modify list of animations as the list is being iterated
  498. final ValueAnimator a0 = ValueAnimator.ofInt(100, 200).setDuration(500);
  499. final ValueAnimator a3 = ValueAnimator.ofFloat(0, 1).setDuration(500);
  500. final ValueAnimator a4 = ValueAnimator.ofInt(200, 300).setDuration(500);
  501. final MyListener listener = new MyListener() {
  502. @Override
  503. public void onAnimationEnd(Animator anim) {
  504. super.onAnimationEnd(anim);
  505. // AnimationHandler should be iterating the list at the moment, end/cancel all
  506. // the other animations. No ConcurrentModificationException should happen.
  507. a0.cancel();
  508. a1.end();
  509. a3.end();
  510. a4.cancel();
  511. }
  512. };
  513. a2.addListener(listener);
  514. runTestOnUiThread(new Runnable() {
  515. @Override
  516. public void run() {
  517. a0.start();
  518. a1.start();
  519. a2.start();
  520. a3.start();
  521. a4.start();
  522. }
  523. });
  524. runTestOnUiThread(new Runnable() {
  525. @Override
  526. public void run() {
  527. assertTrue(a0.isStarted());
  528. assertTrue(a1.isStarted());
  529. assertTrue(a2.isStarted());
  530. assertTrue(a3.isStarted());
  531. assertTrue(a4.isStarted());
  532. }
  533. });
  534. Thread.sleep(POLL_INTERVAL);
  535. runTestOnUiThread(new Runnable() {
  536. @Override
  537. public void run() {
  538. // End the animator that should be in the middle of the list.
  539. a2.end();
  540. }
  541. });
  542. Thread.sleep(POLL_INTERVAL);
  543. assertTrue(listener.endCalled);
  544. assertFalse(a0.isStarted());
  545. assertFalse(a1.isStarted());
  546. assertFalse(a2.isStarted());
  547. assertFalse(a3.isStarted());
  548. assertFalse(a4.isStarted());
  549. }
  550. @SmallTest
  551. public void testSeek() throws Throwable {
  552. final MyListener l1 = new MyListener();
  553. final MyListener l2 = new MyListener();
  554. final MyUpdateListener updateListener1 = new MyUpdateListener();
  555. final MyUpdateListener updateListener2 = new MyUpdateListener();
  556. final float a1StartFraction = 0.2f;
  557. final float a2StartFraction = 0.3f;
  558. // Extend duration so we have plenty of latitude to manipulate the animations when they
  559. // are running.
  560. a1.setDuration(1000);
  561. a2.setDuration(1000);
  562. a1.addListener(l1);
  563. a2.addListener(l2);
  564. a1.addUpdateListener(updateListener1);
  565. a2.addUpdateListener(updateListener2);
  566. TimeInterpolator interpolator = new LinearInterpolator();
  567. a1.setInterpolator(interpolator);
  568. a2.setInterpolator(interpolator);
  569. runTestOnUiThread(new Runnable() {
  570. @Override
  571. public void run() {
  572. assertFalse(a1.isStarted());
  573. assertFalse(a1.isRunning());
  574. assertFalse(a2.isStarted());
  575. assertFalse(a2.isRunning());
  576. // Test isRunning() and isStarted() before and after seek
  577. a1.setCurrentFraction(a1StartFraction);
  578. a2.setCurrentFraction(a2StartFraction);
  579. assertFalse(a1.isStarted());
  580. assertFalse(a1.isRunning());
  581. assertFalse(a2.isStarted());
  582. assertFalse(a2.isRunning());
  583. }
  584. });
  585. Thread.sleep(POLL_INTERVAL);
  586. // Start animation and seek during the animation.
  587. runTestOnUiThread(new Runnable() {
  588. @Override
  589. public void run() {
  590. assertFalse(a1.isStarted());
  591. assertFalse(a1.isRunning());
  592. assertFalse(a2.isStarted());
  593. assertFalse(a2.isRunning());
  594. assertEquals(a1StartFraction, a1.getAnimatedFraction());
  595. assertEquals(a2StartFraction, a2.getAnimatedFraction());
  596. a1.start();
  597. a2.start();
  598. }
  599. });
  600. Thread.sleep(POLL_INTERVAL);
  601. final float halfwayFraction = 0.5f;
  602. runTestOnUiThread(new Runnable() {
  603. @Override
  604. public void run() {
  605. assertTrue(l1.startCalled);
  606. assertTrue(l2.startCalled);
  607. assertFalse(l1.endCalled);
  608. assertFalse(l2.endCalled);
  609. // Check whether the animations start from the seeking fraction
  610. assertTrue(updateListener1.startFraction >= a1StartFraction);
  611. assertTrue(updateListener2.startFraction >= a2StartFraction);
  612. assertTrue(a1.isStarted());
  613. assertTrue(a1.isRunning());
  614. assertTrue(a2.isStarted());
  615. assertTrue(a2.isRunning());
  616. a1.setCurrentFraction(halfwayFraction);
  617. a2.setCurrentFraction(halfwayFraction);
  618. }
  619. });
  620. Thread.sleep(POLL_INTERVAL);
  621. // Check that seeking during running doesn't change animation's internal state
  622. runTestOnUiThread(new Runnable() {
  623. @Override
  624. public void run() {
  625. assertTrue(l1.startCalled);
  626. assertTrue(l2.startCalled);
  627. assertFalse(l1.endCalled);
  628. assertFalse(l2.endCalled);
  629. assertTrue(a1.isStarted());
  630. assertTrue(a1.isRunning());
  631. assertTrue(a2.isStarted());
  632. assertTrue(a2.isRunning());
  633. }
  634. });
  635. // Wait until the animators finish successfully.
  636. long wait = Math.max(a1.getTotalDuration(), a2.getTotalDuration());
  637. Thread.sleep(wait);
  638. runTestOnUiThread(new Runnable() {
  639. @Override
  640. public void run() {
  641. // Verify that the animators have finished.
  642. assertTrue(l1.endCalled);
  643. assertTrue(l2.endCalled);
  644. assertFalse(a1.isStarted());
  645. assertFalse(a2.isStarted());
  646. assertFalse(a1.isRunning());
  647. assertFalse(a2.isRunning());
  648. }
  649. });
  650. // Re-start animator a1 after it ends normally, and check that seek value from last run
  651. // does not affect the new run.
  652. updateListener1.reset();
  653. runTestOnUiThread(new Runnable() {
  654. @Override
  655. public void run() {
  656. a1.start();
  657. }
  658. });
  659. Thread.sleep(POLL_INTERVAL);
  660. runTestOnUiThread(new Runnable() {
  661. @Override
  662. public void run() {
  663. assertTrue(updateListener1.wasRunning);
  664. assertTrue(updateListener1.startFraction >= 0);
  665. assertTrue(updateListener1.startFraction < halfwayFraction);
  666. a1.end();
  667. }
  668. });
  669. }
  670. @SmallTest
  671. public void testSeekWhileRunning() throws Throwable {
  672. // Seek one animator to the beginning and the other one to the end when they are running.
  673. final MyListener l1 = new MyListener();
  674. final MyListener l2 = new MyListener();
  675. a1.addListener(l1);
  676. a2.addListener(l2);
  677. runTestOnUiThread(new Runnable() {
  678. @Override
  679. public void run() {
  680. assertFalse(l1.startCalled);
  681. assertFalse(l2.startCalled);
  682. assertEquals(0f, a1.getAnimatedFraction());
  683. assertEquals(0f, a2.getAnimatedFraction());
  684. a1.start();
  685. a2.start();
  686. }
  687. });
  688. Thread.sleep(POLL_INTERVAL);
  689. runTestOnUiThread(new Runnable() {
  690. @Override
  691. public void run() {
  692. assertFalse(l1.endCalled);
  693. assertFalse(l2.endCalled);
  694. assertTrue(a1.isRunning());
  695. assertTrue(a2.isRunning());
  696. // During the run, seek one to the beginning, the other to the end
  697. a1.setCurrentFraction(0f);
  698. a2.setCurrentFraction(1f);
  699. }
  700. });
  701. Thread.sleep(POLL_INTERVAL);
  702. runTestOnUiThread(new Runnable() {
  703. @Override
  704. public void run() {
  705. // Check that a2 has finished due to the seeking, but a1 hasn't finished.
  706. assertFalse(l1.endCalled);
  707. assertTrue(l2.endCalled);
  708. assertEquals(1f, a2.getAnimatedFraction());
  709. }
  710. });
  711. Thread.sleep(a1.getTotalDuration());
  712. runTestOnUiThread(new Runnable() {
  713. @Override
  714. public void run() {
  715. // By now a1 should finish also.
  716. assertTrue(l1.endCalled);
  717. assertEquals(1f, a1.getAnimatedFraction());
  718. }
  719. });
  720. }
  721. @SmallTest
  722. public void testEndBeforeStart() throws Throwable {
  723. // This test calls two animators that are not yet started. One animator has completed a
  724. // previous run but hasn't started since then, the other one has never run. When end() is
  725. // called on these two animators, we expected their animation listeners to receive both
  726. // onAnimationStarted(Animator) and onAnimationEnded(Animator) callbacks, in that sequence.
  727. a1.setStartDelay(20);
  728. // First start a1's first run.
  729. final MyListener normalEndingListener = new MyListener();
  730. a1.addListener(normalEndingListener);
  731. runTestOnUiThread(new Runnable() {
  732. @Override
  733. public void run() {
  734. assertFalse(a1.isStarted());
  735. assertFalse(normalEndingListener.startCalled);
  736. assertFalse(normalEndingListener.endCalled);
  737. // Start normally
  738. a1.start();
  739. }
  740. });
  741. Thread.sleep(a1.getTotalDuration() + POLL_INTERVAL);
  742. // a1 should have finished by now.
  743. runTestOnUiThread(new Runnable() {
  744. @Override
  745. public void run() {
  746. // Call end() on both a1 and a2 without calling start()
  747. final MyListener l1 = new MyListener();
  748. a1.addListener(l1);
  749. final MyListener l2 = new MyListener();
  750. a2.addListener(l2);
  751. assertFalse(a1.isStarted());
  752. assertFalse(l1.startCalled);
  753. assertFalse(l1.endCalled);
  754. assertFalse(a2.isStarted());
  755. assertFalse(l2.startCalled);
  756. assertFalse(l1.endCalled);
  757. a1.end();
  758. a2.end();
  759. // Check that both animators' listeners have received the animation callbacks.
  760. assertTrue(l1.startCalled);
  761. assertTrue(l1.endCalled);
  762. assertFalse(a1.isStarted());
  763. assertTrue(l1.endTime >= l1.startTime);
  764. assertTrue(l2.startCalled);
  765. assertTrue(l2.endCalled);
  766. assertFalse(a2.isStarted());
  767. assertTrue(l2.endTime >= l1.startTime);
  768. }
  769. });
  770. }
  771. @SmallTest
  772. public void testZeroDuration() throws Throwable {
  773. // Run two animators with zero duration, with one running forward and the other one
  774. // backward. Check that the animations start and finish with the correct end fractions.
  775. a1.setDuration(0);
  776. a2.setDuration(0);
  777. // Set a fraction on an animation with 0-duration
  778. final ValueAnimator a3 = ValueAnimator.ofInt(0, 100);
  779. a3.setDuration(0);
  780. a3.setCurrentFraction(1.0f);
  781. assertEquals(1.0f, a3.getAnimatedFraction());
  782. final MyListener l1 = new MyListener();
  783. final MyListener l2 = new MyListener();
  784. final MyListener l3 = new MyListener();
  785. a1.addListener(l1);
  786. a2.addListener(l2);
  787. a3.addListener(l3);
  788. runTestOnUiThread(new Runnable() {
  789. @Override
  790. public void run() {
  791. assertFalse(l1.startCalled);
  792. assertFalse(l2.startCalled);
  793. assertFalse(l3.startCalled);
  794. assertFalse(l1.endCalled);
  795. assertFalse(l2.endCalled);
  796. assertFalse(l3.endCalled);
  797. a1.start();
  798. a2.reverse();
  799. a3.start();
  800. // Check that the animators' values are immediately set to end value in the case of
  801. // 0-duration.
  802. assertEquals(A1_END_VALUE, a1.getAnimatedValue());
  803. assertEquals(A2_START_VALUE, a2.getAnimatedValue());
  804. }
  805. });
  806. Thread.sleep(POLL_INTERVAL);
  807. runTestOnUiThread(new Runnable() {
  808. @Override
  809. public void run() {
  810. // Check that the animators have started and finished with the right values.
  811. assertTrue(l1.startCalled);
  812. assertTrue(l2.startCalled);
  813. assertTrue(l3.startCalled);
  814. assertTrue(l1.endCalled);
  815. assertTrue(l2.endCalled);
  816. assertTrue(l3.endCalled);
  817. assertEquals(1.0f, a1.getAnimatedFraction());
  818. assertEquals(0f, a2.getAnimatedFraction());
  819. assertEquals(1f, a3.getAnimatedFraction());
  820. assertEquals(A1_END_VALUE, a1.getAnimatedValue());
  821. assertEquals(A2_START_VALUE, a2.getAnimatedValue());
  822. assertEquals(100, a3.getAnimatedValue());
  823. }
  824. });
  825. }
  826. @SmallTest
  827. public void testZeroScale() throws Throwable {
  828. // Test whether animations would end properly when the scale is forced to be zero
  829. float scale = ValueAnimator.getDurationScale();
  830. ValueAnimator.setDurationScale(0f);
  831. // Run two animators, one of which has a start delay, after setting the duration scale to 0
  832. a1.setStartDelay(200);
  833. final MyListener l1 = new MyListener();
  834. final MyListener l2 = new MyListener();
  835. a1.addListener(l1);
  836. a2.addListener(l2);
  837. runTestOnUiThread(new Runnable() {
  838. @Override
  839. public void run() {
  840. assertFalse(l1.startCalled);
  841. assertFalse(l2.startCalled);
  842. assertFalse(l1.endCalled);
  843. assertFalse(l2.endCalled);
  844. a1.start();
  845. a2.start();
  846. // In the case of 0 duration scale applied to a non-0 duration, check that the
  847. // value is immediately set to the start value.
  848. assertEquals(A2_START_VALUE, a2.getAnimatedValue());
  849. }
  850. });
  851. Thread.sleep(POLL_INTERVAL);
  852. runTestOnUiThread(new Runnable() {
  853. @Override
  854. public void run() {
  855. assertTrue(l1.startCalled);
  856. assertTrue(l2.startCalled);
  857. assertTrue(l1.endCalled);
  858. assertTrue(l2.endCalled);
  859. assertEquals(A1_END_VALUE, a1.getAnimatedValue());
  860. assertEquals(A2_END_VALUE, a2.getAnimatedValue());
  861. }
  862. });
  863. // Restore duration scale
  864. ValueAnimator.setDurationScale(scale);
  865. }
  866. @SmallTest
  867. public void testReverse() throws Throwable {
  868. // Prolong animators duration so that we can do multiple checks during their run
  869. final ValueAnimator a3 = ValueAnimator.ofInt(0, 100);
  870. a1.setDuration(400);
  871. a2.setDuration(600);
  872. a3.setDuration(400);
  873. final MyListener l1 = new MyListener();
  874. final MyListener l2 = new MyListener();
  875. final MyListener l3 = new MyListener();
  876. a1.addListener(l1);
  877. a2.addListener(l2);
  878. a3.addListener(l3);
  879. // Reverse three animators, seek one to the beginning and another to the end, and force
  880. // to end the third one during reversing.
  881. runTestOnUiThread(new Runnable() {
  882. @Override
  883. public void run() {
  884. assertFalse(l1.startCalled);
  885. assertFalse(l2.startCalled);
  886. assertFalse(l3.startCalled);
  887. assertFalse(l1.endCalled);
  888. assertFalse(l2.endCalled);
  889. assertFalse(l3.endCalled);
  890. a1.reverse();
  891. a2.reverse();
  892. a3.reverse();
  893. }
  894. });
  895. Thread.sleep(POLL_INTERVAL);
  896. runTestOnUiThread(new Runnable() {
  897. @Override
  898. public void run() {
  899. assertTrue(l1.startCalled);
  900. assertTrue(l2.startCalled);
  901. assertTrue(l3.startCalled);
  902. a1.setCurrentFraction(0f);
  903. a2.setCurrentFraction(1f);
  904. a3.end();
  905. // Check that the fraction has been set, and the getter returns the correct values.
  906. assertEquals(1f, a1.getAnimatedFraction());
  907. assertEquals(0f, a2.getAnimatedFraction());
  908. }
  909. });
  910. Thread.sleep(POLL_INTERVAL);
  911. // By now, a2 should have finished due to the seeking. It wouldn't have finished otherwise.
  912. runTestOnUiThread(new Runnable() {
  913. @Override
  914. public void run() {
  915. // Check that both animations have started, and a2 has finished.
  916. assertFalse(l1.endCalled);
  917. assertTrue(l2.endCalled);
  918. assertTrue(l3.endCalled);
  919. }
  920. });
  921. Thread.sleep(a1.getTotalDuration());
  922. runTestOnUiThread(new Runnable() {
  923. @Override
  924. public void run() {
  925. // Verify that a1 has finished as well.
  926. assertTrue(l1.endCalled);
  927. assertEquals(0f, a1.getAnimatedFraction());
  928. assertEquals(0f, a2.getAnimatedFraction());
  929. assertEquals(0f, a3.getAnimatedFraction());
  930. }
  931. });
  932. }
  933. class MyUpdateListener implements ValueAnimator.AnimatorUpdateListener {
  934. boolean wasRunning = false;
  935. long firstRunningFrameTime = -1;
  936. long lastUpdateTime = -1;
  937. float startFraction = 0;
  938. @Override
  939. public void onAnimationUpdate(ValueAnimator animation) {
  940. lastUpdateTime = SystemClock.uptimeMillis();
  941. if (animation.isRunning() && !wasRunning) {
  942. // Delay has passed
  943. firstRunningFrameTime = lastUpdateTime;
  944. startFraction = animation.getAnimatedFraction();
  945. wasRunning = animation.isRunning();
  946. }
  947. }
  948. void reset() {
  949. wasRunning = false;
  950. firstRunningFrameTime = -1;
  951. lastUpdateTime = -1;
  952. startFraction = 0;
  953. }
  954. }
  955. class MyListener implements Animator.AnimatorListener {
  956. boolean startCalled = false;
  957. boolean cancelCalled = false;
  958. boolean endCalled = false;
  959. long startTime = -1;
  960. long endTime = -1;
  961. @Override
  962. public void onAnimationStart(Animator animation) {
  963. startCalled = true;
  964. startTime = SystemClock.uptimeMillis();
  965. }
  966. @Override
  967. public void onAnimationEnd(Animator animation) {
  968. endCalled = true;
  969. endTime = SystemClock.uptimeMillis();
  970. }
  971. @Override
  972. public void onAnimationCancel(Animator animation) {
  973. cancelCalled = true;
  974. }
  975. @Override
  976. public void onAnimationRepeat(Animator animation) {
  977. }
  978. }
  979. class MyPauseListener implements Animator.AnimatorPauseListener {
  980. boolean pauseCalled = false;
  981. boolean resumeCalled = false;
  982. @Override
  983. public void onAnimationPause(Animator animation) {
  984. pauseCalled = true;
  985. }
  986. @Override
  987. public void onAnimationResume(Animator animation) {
  988. resumeCalled = true;
  989. }
  990. }
  991. class MyFrameCallbackProvider implements AnimationHandler.AnimationFrameCallbackProvider {
  992. Handler mHandler = null;
  993. private final static int MSG_FRAME = 0;
  994. private long mFrameDelay = DEFAULT_FRAME_INTERVAL;
  995. private ArrayList<Choreographer.FrameCallback> mFrameCallbacks = new ArrayList<>();
  996. final LooperThread mThread = new LooperThread();
  997. public MyFrameCallbackProvider() {
  998. mThread.start();
  999. }
  1000. @Override
  1001. public void postFrameCallback(Choreographer.FrameCallback callback) {
  1002. mHandler.sendEmptyMessageDelayed(MSG_FRAME, mFrameDelay);
  1003. if (!mFrameCallbacks.contains(callback)) {
  1004. mFrameCallbacks.add(callback);
  1005. }
  1006. }
  1007. @Override
  1008. public void postCommitCallback(Runnable runnable) {
  1009. // Run the runnable after a commit delay
  1010. mHandler.postDelayed(runnable, COMMIT_DELAY);
  1011. }
  1012. @Override
  1013. public long getFrameTime() {
  1014. return SystemClock.uptimeMillis();
  1015. }
  1016. @Override
  1017. public long getFrameDelay() {
  1018. return mFrameDelay;
  1019. }
  1020. @Override
  1021. public void setFrameDelay(long delay) {
  1022. mFrameDelay = delay;
  1023. if (mFrameCallbacks.size() != 0) {
  1024. mHandler.removeMessages(MSG_FRAME);
  1025. mHandler.sendEmptyMessageDelayed(MSG_FRAME, mFrameDelay);
  1026. }
  1027. }
  1028. class LooperThread extends Thread {
  1029. public void run() {
  1030. Looper.prepare();
  1031. mHandler = new Handler() {
  1032. public void handleMessage(Message msg) {
  1033. // Handle message here.
  1034. switch (msg.what) {
  1035. case MSG_FRAME:
  1036. for (int i = 0; i < mFrameCallbacks.size(); i++) {
  1037. mFrameCallbacks.get(i).doFrame(SystemClock.uptimeMillis());
  1038. }
  1039. break;
  1040. default:
  1041. break;
  1042. }
  1043. }
  1044. };
  1045. Looper.loop();
  1046. }
  1047. }
  1048. }
  1049. }