add non-looping option to SkottieViews through xml attributes

stop running animation at the end if not looping


hook looping and background color into SkottieAnimation implementation


add looping attribute to SkottieView

Change-Id: I0c66026429018d61f49ccced1fd5add63619263a
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/329816
Commit-Queue: Jorge Betancourt <jmbetancourt@google.com>
Reviewed-by: Derek Sollenberger <djsollen@google.com>
Reviewed-by: Tyler Freeman <fuego@google.com>
diff --git a/platform_tools/android/apps/skottie/skottielib/src/main/java/org/skia/skottie/SkottieRunner.java b/platform_tools/android/apps/skottie/skottielib/src/main/java/org/skia/skottie/SkottieRunner.java
index 23246af..2fba8e1 100644
--- a/platform_tools/android/apps/skottie/skottielib/src/main/java/org/skia/skottie/SkottieRunner.java
+++ b/platform_tools/android/apps/skottie/skottielib/src/main/java/org/skia/skottie/SkottieRunner.java
@@ -70,8 +70,8 @@
      * Create a new animation by feeding data from "is" and replaying in a TextureView.
      * TextureView is tracked internally for SurfaceTexture state.
      */
-    public SkottieAnimation createAnimation(TextureView view, InputStream is) {
-        return new SkottieAnimationImpl(view, is);
+    public SkottieAnimation createAnimation(TextureView view, InputStream is, int backgroundColor, int repeatCount) {
+        return new SkottieAnimationImpl(view, is, backgroundColor, repeatCount);
     }
 
     /**
@@ -87,8 +87,8 @@
      * Create a new animation by feeding data from "is" and replaying in a SurfaceView.
      * State is controlled internally by SurfaceHolder.
      */
-    public SkottieAnimation createAnimation(SurfaceView view, InputStream is, int backgroundColor) {
-        return new SkottieAnimationImpl(view, is, backgroundColor);
+    public SkottieAnimation createAnimation(SurfaceView view, InputStream is, int backgroundColor, int repeatCount) {
+        return new SkottieAnimationImpl(view, is, backgroundColor, repeatCount);
     }
 
     /**
@@ -289,6 +289,8 @@
         SurfaceHolder mSurfaceHolder;
         boolean mValidSurface = false;
 
+        private int mRepeatCount;
+        private int mRepeatCounter;
         private int mSurfaceWidth = 0;
         private int mSurfaceHeight = 0;
         private int mBackgroundColor;
@@ -303,19 +305,24 @@
             }
         }
 
-        SkottieAnimationImpl(TextureView view, InputStream is) {
+        SkottieAnimationImpl(TextureView view, InputStream is, int backgroundColor, int repeatCount) {
             if (init(is)) {
                 mSurfaceTexture = view.getSurfaceTexture();
             }
             view.setSurfaceTextureListener(this);
+            mBackgroundColor = backgroundColor;
+            mRepeatCount = repeatCount;
+            mRepeatCounter = mRepeatCount;
         }
 
-        SkottieAnimationImpl(SurfaceView view, InputStream is, int backgroundColor) {
+        SkottieAnimationImpl(SurfaceView view, InputStream is, int backgroundColor, int repeatCount) {
             if (init(is)) {
                 mSurfaceHolder = view.getHolder();
             }
             mSurfaceHolder.addCallback(this);
             mBackgroundColor = backgroundColor;
+            mRepeatCount = repeatCount;
+            mRepeatCounter = mRepeatCount;
         }
 
         private void setSurfaceTexture(SurfaceTexture s) {
@@ -390,6 +397,7 @@
                         mAnimationStartTime = currentTime - (long)(1000000 * mDuration * mProgress);
                         mIsRunning = true;
                         mNewSurface = true;
+                        mRepeatCounter = mRepeatCount;
                         doFrame(currentTime);
                     }
                 });
@@ -582,6 +590,14 @@
                 if (timeSinceAnimationStartNS > durationNS) {
                     mAnimationStartTime += durationNS;  // prevents overflow
                 }
+                if (timeSinceAnimationStartNS > durationNS) {
+                    if (mRepeatCounter > 0) {
+                        mRepeatCounter--;
+                    } else if (mRepeatCounter == 0) {
+                        mIsRunning = false;
+                        mProgress = 1;
+                    }
+                }
             }
             if (mValidSurface) {
                 drawFrame();
diff --git a/platform_tools/android/apps/skottie/skottielib/src/main/java/org/skia/skottie/SkottieView.java b/platform_tools/android/apps/skottie/skottielib/src/main/java/org/skia/skottie/SkottieView.java
index 3fa809e..56d1be3 100644
--- a/platform_tools/android/apps/skottie/skottielib/src/main/java/org/skia/skottie/SkottieView.java
+++ b/platform_tools/android/apps/skottie/skottielib/src/main/java/org/skia/skottie/SkottieView.java
@@ -27,17 +27,20 @@
     private SkottieAnimation mAnimation;
     private View mBackingView;
     private int mBackgroundColor;
+    // Repeat follows Animator API, infinite is represented by -1 (see Animator.DURATION_INFINITE)
+    private int mRepeatCount;
 
     private static final int BACKING_VIEW_TEXTURE = 0;
     private static final int BACKING_VIEW_SURFACE = 1;
 
-
     // SkottieView constructor when initialized in XML layout
     public SkottieView(Context context, AttributeSet attrs) {
         super(context, attrs);
         TypedArray a = context.getTheme()
             .obtainStyledAttributes(attrs, R.styleable.SkottieView, 0, 0);
         try {
+            // set mRepeatCount
+            mRepeatCount = a.getInteger(R.styleable.SkottieView_android_repeatCount, 0);
             // set backing view and background color
             switch (a.getInteger(R.styleable.SkottieView_backing_view, -1)) {
                 case BACKING_VIEW_TEXTURE:
@@ -109,10 +112,10 @@
     private SkottieAnimation setSourceHelper(InputStream inputStream) {
         if (mBackingView instanceof TextureView) {
             return SkottieRunner.getInstance()
-                .createAnimation(((TextureView) mBackingView), inputStream);
+                .createAnimation(((TextureView) mBackingView), inputStream, mBackgroundColor, mRepeatCount);
         } else {
             return SkottieRunner.getInstance()
-                .createAnimation(((SurfaceView) mBackingView), inputStream, mBackgroundColor);
+                .createAnimation(((SurfaceView) mBackingView), inputStream, mBackgroundColor, mRepeatCount);
         }
     }
 
diff --git a/platform_tools/android/apps/skottie/skottielib/src/main/res/values/attrs.xml b/platform_tools/android/apps/skottie/skottielib/src/main/res/values/attrs.xml
index 9b79553..e30674d 100644
--- a/platform_tools/android/apps/skottie/skottielib/src/main/res/values/attrs.xml
+++ b/platform_tools/android/apps/skottie/skottielib/src/main/res/values/attrs.xml
@@ -7,5 +7,6 @@
     </attr>
     <attr name="background_color" format="color"/>
     <attr name="src" format="reference"/>
+    <attr name="android:repeatCount" format="integer"/>
   </declare-styleable>
 </resources>
\ No newline at end of file
diff --git a/platform_tools/android/apps/skottie/src/main/res/layout/demo_layout.xml b/platform_tools/android/apps/skottie/src/main/res/layout/demo_layout.xml
index 4f42a92..b5b92ab 100644
--- a/platform_tools/android/apps/skottie/src/main/res/layout/demo_layout.xml
+++ b/platform_tools/android/apps/skottie/src/main/res/layout/demo_layout.xml
@@ -26,27 +26,31 @@
           android:layout_width="1000px"
           android:layout_height="1000px"
           app:backing_view="texture_view"
-          app:src="@raw/star">
+          app:src="@raw/star"
+          android:repeatCount="infinite">
       </org.skia.skottie.SkottieView>
       <org.skia.skottie.SkottieView
           android:layout_width="1000px"
           android:layout_height="1000px"
           app:backing_view="texture_view"
-          app:src="@raw/movie_loading">
+          app:src="@raw/movie_loading"
+          android:repeatCount="infinite">
       </org.skia.skottie.SkottieView>
       <org.skia.skottie.SkottieView
           android:layout_width="1000px"
           android:layout_height="1000px"
           app:backing_view="surface_view"
           app:background_color="#fefefe"
-          app:src="@raw/uk">
+          app:src="@raw/uk"
+          android:repeatCount="infinite">
       </org.skia.skottie.SkottieView>
       <org.skia.skottie.SkottieView
         android:layout_width="1000px"
         android:layout_height="1000px"
         app:backing_view="surface_view"
         app:background_color="#fefefe"
-        app:src="@raw/white_material_wave_loading">
+        app:src="@raw/white_material_wave_loading"
+        android:repeatCount="infinite">
       </org.skia.skottie.SkottieView>
     </LinearLayout>
   </ScrollView>