[Breaking Change] Automatic hardware acceleration detection
diff --git a/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/PlayerFragment.kt b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/PlayerFragment.kt
index bf47e6b..df218ee 100644
--- a/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/PlayerFragment.kt
+++ b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/PlayerFragment.kt
@@ -181,12 +181,6 @@
             trimContainer.animateVisible(it)
         }
 
-        hardwareAccelerationToggle.setOnClickListener { viewModel.toggleHardwareAcceleration() }
-        viewModel.selectSubscribe(PlayerState::useHardwareAcceleration) {
-            hardwareAccelerationToggle.isActivated = it
-            animationView.useHardwareAcceleration(it)
-        }
-
         mergePathsToggle.setOnClickListener { viewModel.toggleMergePaths() }
         viewModel.selectSubscribe(PlayerState::useMergePaths) {
             animationView.enableMergePathsForKitKatAndAbove(it)
@@ -411,6 +405,7 @@
         composition ?: return
 
         animationView.setComposition(composition)
+        hardwareAccelerationToggle.isActivated = animationView.layerType == View.LAYER_TYPE_HARDWARE
         animationView.setPerformanceTrackingEnabled(true)
         var renderTimeGraphRange = 4f
         animationView.performanceTracker?.addFrameListener { ms ->
diff --git a/lottie/src/main/java/com/airbnb/lottie/LottieAnimationView.java b/lottie/src/main/java/com/airbnb/lottie/LottieAnimationView.java
index 483f694..8035373 100644
--- a/lottie/src/main/java/com/airbnb/lottie/LottieAnimationView.java
+++ b/lottie/src/main/java/com/airbnb/lottie/LottieAnimationView.java
@@ -8,6 +8,7 @@
 import android.graphics.Color;
 import android.graphics.ColorFilter;
 import android.graphics.drawable.Drawable;
+import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
 import androidx.annotation.FloatRange;
@@ -15,7 +16,6 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.RawRes;
-import androidx.annotation.VisibleForTesting;
 import androidx.appcompat.widget.AppCompatImageView;
 import android.text.TextUtils;
 import android.util.AttributeSet;
@@ -73,7 +73,6 @@
   private @RawRes int animationResId;
   private boolean wasAnimatingWhenDetached = false;
   private boolean autoPlay = false;
-  private boolean useHardwareLayer = false;
   private Set<LottieOnCompositionLoadedListener> lottieOnCompositionLoadedListeners = new HashSet<>();
 
   @Nullable private LottieTask<LottieComposition> compositionTask;
@@ -262,54 +261,6 @@
   }
 
   /**
-   * @see #useHardwareAcceleration(boolean)
-   */
-  @Deprecated
-  public void useExperimentalHardwareAcceleration() {
-    useHardwareAcceleration(true);
-  }
-
-
-  /**
-   * @see #useHardwareAcceleration(boolean)
-   */
-  @Deprecated
-  public void useExperimentalHardwareAcceleration(boolean use) {
-    useHardwareAcceleration(use);
-  }
-
-  /**
-   * @see #useHardwareAcceleration(boolean)
-   */
-  public void useHardwareAcceleration() {
-    useHardwareAcceleration(true);
-  }
-
-  /**
-   * Enable hardware acceleration for this view.
-   * READ THIS BEFORE ENABLING HARDWARE ACCELERATION:
-   * 1) Test your animation on the minimum API level you support. Some drawing features such as
-   *    dashes and stroke caps have min api levels
-   *    (https://developer.android.com/guide/topics/graphics/hardware-accel.html#unsupported)
-   * 2) Enabling hardware acceleration is not always more performant. Check it with your specific
-   *    animation only if you are having performance issues with software rendering.
-   * 3) Software rendering is safer and will be consistent across devices. Manufacturers can
-   *    potentially break hardware rendering with bugs in their SKIA engine. Lottie cannot do
-   *    anything about that.
-   */
-  public void useHardwareAcceleration(boolean use) {
-    if (useHardwareLayer == use) {
-      return;
-    }
-    useHardwareLayer = use;
-    enableOrDisableHardwareLayer();
-  }
-
-  public boolean getUseHardwareAcceleration() {
-    return useHardwareLayer;
-  }
-
-  /**
    * Sets the animation from a file in the raw directory.
    * This will load and deserialize the file asynchronously.
    */
@@ -794,7 +745,10 @@
   }
 
   private void enableOrDisableHardwareLayer() {
-    boolean useHardwareLayer = this.useHardwareLayer && lottieDrawable.isAnimating();
+    boolean useHardwareLayer = true;
+    if (composition != null && composition.hasDashPattern() && Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
+      useHardwareLayer = false;
+    }
     setLayerType(useHardwareLayer ? LAYER_TYPE_HARDWARE : LAYER_TYPE_SOFTWARE, null);
   }
 
diff --git a/lottie/src/main/java/com/airbnb/lottie/LottieComposition.java b/lottie/src/main/java/com/airbnb/lottie/LottieComposition.java
index d7578a2..1314c01 100644
--- a/lottie/src/main/java/com/airbnb/lottie/LottieComposition.java
+++ b/lottie/src/main/java/com/airbnb/lottie/LottieComposition.java
@@ -51,7 +51,12 @@
   private float startFrame;
   private float endFrame;
   private float frameRate;
+  /**
+   * Used to determine if an animation can be drawn with hardware acceleration.
+   */
+  private boolean hasDashPattern;
 
+  @RestrictTo(RestrictTo.Scope.LIBRARY)
   public void init(Rect bounds, float startFrame, float endFrame, float frameRate,
       List<Layer> layers, LongSparseArray<Layer> layerMap, Map<String,
       List<Layer>> precomps, Map<String, LottieImageAsset> images,
@@ -74,6 +79,18 @@
     warnings.add(warning);
   }
 
+  @RestrictTo(RestrictTo.Scope.LIBRARY)
+  public void setHasDashPattern(boolean hasDashPattern) {
+    this.hasDashPattern = hasDashPattern;
+  }
+
+  /**
+   * Used to determine if an animation can be drawn with hardware acceleration.
+   */
+  public boolean hasDashPattern() {
+    return hasDashPattern;
+  }
+
   public ArrayList<String> getWarnings() {
     return new ArrayList<>(Arrays.asList(warnings.toArray(new String[warnings.size()])));
   }
diff --git a/lottie/src/main/java/com/airbnb/lottie/parser/GradientStrokeParser.java b/lottie/src/main/java/com/airbnb/lottie/parser/GradientStrokeParser.java
index 5d26436..2266721 100644
--- a/lottie/src/main/java/com/airbnb/lottie/parser/GradientStrokeParser.java
+++ b/lottie/src/main/java/com/airbnb/lottie/parser/GradientStrokeParser.java
@@ -109,6 +109,7 @@
             if (n.equals("o")) {
               offset = val;
             } else if (n.equals("d") || n.equals("g")) {
+              composition.setHasDashPattern(true);
               lineDashPattern.add(val);
             }
           }
diff --git a/lottie/src/main/java/com/airbnb/lottie/parser/ShapeStrokeParser.java b/lottie/src/main/java/com/airbnb/lottie/parser/ShapeStrokeParser.java
index cf0bb50..b81bc06 100644
--- a/lottie/src/main/java/com/airbnb/lottie/parser/ShapeStrokeParser.java
+++ b/lottie/src/main/java/com/airbnb/lottie/parser/ShapeStrokeParser.java
@@ -83,6 +83,7 @@
                 break;
               case "d":
               case "g":
+                composition.setHasDashPattern(true);
                 lineDashPattern.add(val);
                 break;
             }