Add SkAnimatedImage::isFinished

Bug: b/63908092

Allows Android to know when to call onAnimationEnd.

Change-Id: I9cc102fb485e944ad5983eed9f0b941153128e88
Reviewed-on: https://skia-review.googlesource.com/97401
Reviewed-by: Derek Sollenberger <djsollen@google.com>
Commit-Queue: Leon Scroggins <scroggo@google.com>
diff --git a/include/android/SkAnimatedImage.h b/include/android/SkAnimatedImage.h
index d74c6be..d2f4e3d 100644
--- a/include/android/SkAnimatedImage.h
+++ b/include/android/SkAnimatedImage.h
@@ -67,6 +67,14 @@
     bool isRunning() const { return fRunning && !fFinished; }
 
     /**
+     *  Whether the animation completed.
+     *
+     *  Returns true after all repetitions are complete, or an error stops the
+     *  animation. Gets reset to false if the animation is restarted.
+     */
+    bool isFinished() const { return fFinished; }
+
+    /**
      *  Update the current time. If the image is animating, this may decode
      *  a new frame.
      *
diff --git a/tests/AnimatedImageTest.cpp b/tests/AnimatedImageTest.cpp
index c8113d3..584a69c 100644
--- a/tests/AnimatedImageTest.cpp
+++ b/tests/AnimatedImageTest.cpp
@@ -132,8 +132,10 @@
             if (i == frameInfos.size() - 1 && defaultRepetitionCount == 0) {
                 REPORTER_ASSERT(r, next == std::numeric_limits<double>::max());
                 REPORTER_ASSERT(r, !animatedImage->isRunning());
+                REPORTER_ASSERT(r, animatedImage->isFinished());
             } else {
                 REPORTER_ASSERT(r, animatedImage->isRunning());
+                REPORTER_ASSERT(r, !animatedImage->isFinished());
                 double expectedNext = currentTime + frameInfos[i].fDuration;
                 if (next != expectedNext) {
                     ERRORF(r, "Time did not match for frame %i: next: %g expected: %g",
@@ -182,6 +184,7 @@
             double interval = next - currentTime;
             animatedImage->stop();
             REPORTER_ASSERT(r, !animatedImage->isRunning());
+            REPORTER_ASSERT(r, !animatedImage->isFinished());
 
             currentTime = next;
             double stoppedNext = animatedImage->update(currentTime);
@@ -201,6 +204,7 @@
         }
 
         REPORTER_ASSERT(r, animatedImage->isRunning());
+        REPORTER_ASSERT(r, !animatedImage->isFinished());
         animatedImage->reset();
         if (!testDraw(animatedImage, 0)) {
             ERRORF(r, "reset failed");
@@ -214,6 +218,7 @@
             animatedImage->setRepetitionCount(loopCount);
             for (int loops = 0; loops <= loopCount; loops++) {
                 REPORTER_ASSERT(r, animatedImage->isRunning());
+                REPORTER_ASSERT(r, !animatedImage->isFinished());
                 for (size_t i = 0; i < frameInfos.size(); ++i) {
                     double next = animatedImage->update(currentTime);
                     if (animatedImage->isRunning()) {
@@ -224,6 +229,11 @@
             if (animatedImage->isRunning()) {
                 ERRORF(r, "%s animation still running after %i loops", file, loopCount);
             }
+
+            if (!animatedImage->isFinished()) {
+                ERRORF(r, "%s animation should have finished with specified loop count (%i)",
+                          file, loopCount);
+            }
         }
     }
 }