Docs and LottieConfig cleanup (#1656)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9522768..f678266 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+# 3.5.0
+### Features and Improvements
+* Added a new global configuration to add a custom network stack, custom network cache, enable systrace markers, and more ([#1629](https://github.com/airbnb/lottie-android/pull/1629))
+* Initial implementation of Lottie Compose (not yet released)
+
 # 3.4.4
 ### Bugs Fixed
 * Properly clamp gradient values ([#1636](https://github.com/airbnb/lottie-android/pull/1636))
diff --git a/lottie/src/main/java/com/airbnb/lottie/L.java b/lottie/src/main/java/com/airbnb/lottie/L.java
index 834b7e7..e0365e6 100644
--- a/lottie/src/main/java/com/airbnb/lottie/L.java
+++ b/lottie/src/main/java/com/airbnb/lottie/L.java
@@ -33,6 +33,9 @@
   private static volatile NetworkFetcher networkFetcher;
   private static volatile NetworkCache networkCache;
 
+  private L() {
+  }
+
   public static void setTraceEnabled(boolean enabled) {
     if (traceEnabled == enabled) {
       return;
diff --git a/lottie/src/main/java/com/airbnb/lottie/Lottie.java b/lottie/src/main/java/com/airbnb/lottie/Lottie.java
index 96c7a6f..af577c7 100644
--- a/lottie/src/main/java/com/airbnb/lottie/Lottie.java
+++ b/lottie/src/main/java/com/airbnb/lottie/Lottie.java
@@ -10,8 +10,14 @@
   private Lottie() {
   }
 
+  /**
+   * Initialize Lottie with global configuration.
+   *
+   * @see LottieConfig.Builder
+   */
   public static void initialize(@NonNull final LottieConfig lottieConfig) {
     L.setFetcher(lottieConfig.networkFetcher);
     L.setCacheProvider(lottieConfig.cacheProvider);
+    L.setTraceEnabled(lottieConfig.enableSystraceMarkers);
   }
 }
\ No newline at end of file
diff --git a/lottie/src/main/java/com/airbnb/lottie/LottieAnimationView.java b/lottie/src/main/java/com/airbnb/lottie/LottieAnimationView.java
index e2a0ef2..5bf4b31 100644
--- a/lottie/src/main/java/com/airbnb/lottie/LottieAnimationView.java
+++ b/lottie/src/main/java/com/airbnb/lottie/LottieAnimationView.java
@@ -5,6 +5,7 @@
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.Bitmap;
+import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.ColorFilter;
 import android.graphics.drawable.Drawable;
@@ -27,7 +28,6 @@
 import androidx.core.view.ViewCompat;
 
 import com.airbnb.lottie.model.KeyPath;
-import com.airbnb.lottie.parser.moshi.JsonReader;
 import com.airbnb.lottie.utils.Logger;
 import com.airbnb.lottie.utils.Utils;
 import com.airbnb.lottie.value.LottieFrameInfo;
@@ -51,12 +51,13 @@
  * 1) Attrs: {@link R.styleable#LottieAnimationView_lottie_fileName}
  * 2) Programmatically:
  *      {@link #setAnimation(String)}
- *      {@link #setAnimation(JsonReader, String)}
+ *      {@link #setAnimation(int)}
+ *      {@link #setAnimation(InputStream, String)}
  *      {@link #setAnimationFromJson(String, String)}
  *      {@link #setAnimationFromUrl(String)}
  *      {@link #setComposition(LottieComposition)}
  * <p>
- * You can set a default cache strategy with {@link R.attr#lottie_cacheStrategy}.
+ * You can set a default cache strategy with {@link R.attr#lottie_cacheComposition}.
  * <p>
  * You can manually set the progress of the animation with {@link #setProgress(float)} or
  * {@link R.attr#lottie_progress}
@@ -108,7 +109,7 @@
   private boolean autoPlay = false;
   private boolean cacheComposition = true;
   private RenderMode renderMode = RenderMode.AUTOMATIC;
-  private Set<LottieOnCompositionLoadedListener> lottieOnCompositionLoadedListeners = new HashSet<>();
+  private final Set<LottieOnCompositionLoadedListener> lottieOnCompositionLoadedListeners = new HashSet<>();
   /**
    * Prevents a StackOverflowException on 4.4 in which getDrawingCache() calls buildDrawingCache().
    * This isn't a great solution but it works and has very little performance overhead.
@@ -382,7 +383,7 @@
   private LottieTask<LottieComposition> fromRawRes(@RawRes final int rawRes) {
     if (isInEditMode()) {
       return new LottieTask<>(new Callable<LottieResult<LottieComposition>>() {
-        @Override public LottieResult<LottieComposition> call() throws Exception {
+        @Override public LottieResult<LottieComposition> call() {
           return cacheComposition
               ? LottieCompositionFactory.fromRawResSync(getContext(), rawRes) : LottieCompositionFactory.fromRawResSync(getContext(), rawRes, null);
         }
@@ -402,7 +403,7 @@
   private LottieTask<LottieComposition> fromAssets(final String assetName) {
     if (isInEditMode()) {
       return new LottieTask<>(new Callable<LottieResult<LottieComposition>>() {
-        @Override public LottieResult<LottieComposition> call() throws Exception {
+        @Override public LottieResult<LottieComposition> call() {
           return cacheComposition ?
               LottieCompositionFactory.fromAssetSync(getContext(), assetName) : LottieCompositionFactory.fromAssetSync(getContext(), assetName, null);
         }
@@ -448,6 +449,11 @@
    * Under the hood, Lottie uses Java HttpURLConnection because it doesn't require any transitive networking dependencies. It will download the file
    * to the application cache under a temporary name. If the file successfully parses to a composition, it will rename the temporary file to one that
    * can be accessed immediately for subsequent requests. If the file does not parse to a composition, the temporary file will be deleted.
+   *
+   * You can replace the default network stack or cache handling with a global {@link LottieConfig}
+   *
+   * @see LottieConfig.Builder
+   * @see Lottie#initialize(LottieConfig)
    */
   public void setAnimationFromUrl(String url) {
     LottieTask<LottieComposition> task = cacheComposition ?
@@ -462,6 +468,11 @@
    * Under the hood, Lottie uses Java HttpURLConnection because it doesn't require any transitive networking dependencies. It will download the file
    * to the application cache under a temporary name. If the file successfully parses to a composition, it will rename the temporary file to one that
    * can be accessed immediately for subsequent requests. If the file does not parse to a composition, the temporary file will be deleted.
+   *
+   * You can replace the default network stack or cache handling with a global {@link LottieConfig}
+   *
+   * @see LottieConfig.Builder
+   * @see Lottie#initialize(LottieConfig)
    */
   public void setAnimationFromUrl(String url, @Nullable String cacheKey) {
     LottieTask<LottieComposition> task = LottieCompositionFactory.fromUrl(getContext(), url, cacheKey);
@@ -516,7 +527,7 @@
   /**
    * Sets a composition.
    * You can set a default cache strategy if this view was inflated with xml by
-   * using {@link R.attr#lottie_cacheStrategy}.
+   * using {@link R.attr#lottie_cacheComposition}.
    */
   public void setComposition(@NonNull LottieComposition composition) {
     if (L.DBG) {
@@ -845,8 +856,7 @@
   /**
    * Use this to manually set fonts.
    */
-  public void setFontAssetDelegate(
-      @SuppressWarnings("NullableProblems") FontAssetDelegate assetDelegate) {
+  public void setFontAssetDelegate(FontAssetDelegate assetDelegate) {
     lottieDrawable.setFontAssetDelegate(assetDelegate);
   }
 
@@ -1064,8 +1074,6 @@
    *
    * <b>Attention:</b> Disable the extra scale mode can downgrade the performance and may lead to larger memory footprint. Please only disable this
    * mode when using animation with a reasonable dimension (smaller than screen size).
-   *
-   * @see LottieDrawable#drawWithNewAspectRatio(Canvas)
    */
   public void disableExtraScaleModeInFitXY() {
     lottieDrawable.disableExtraScaleModeInFitXY();
diff --git a/lottie/src/main/java/com/airbnb/lottie/LottieConfig.java b/lottie/src/main/java/com/airbnb/lottie/LottieConfig.java
index 2a560dc..e82e868 100644
--- a/lottie/src/main/java/com/airbnb/lottie/LottieConfig.java
+++ b/lottie/src/main/java/com/airbnb/lottie/LottieConfig.java
@@ -9,16 +9,21 @@
 import androidx.annotation.Nullable;
 
 /**
- * Class for custom library configuration
+ * Class for custom library configuration.
+ *
+ * This should be constructed with {@link LottieConfig.Builder}
  */
 public class LottieConfig {
 
   @Nullable final LottieNetworkFetcher networkFetcher;
   @Nullable final LottieNetworkCacheProvider cacheProvider;
+  final boolean enableSystraceMarkers;
 
-  private LottieConfig(@Nullable LottieNetworkFetcher networkFetcher, @Nullable LottieNetworkCacheProvider cacheProvider) {
+  private LottieConfig(@Nullable LottieNetworkFetcher networkFetcher, @Nullable LottieNetworkCacheProvider cacheProvider,
+      boolean enableSystraceMarkers) {
     this.networkFetcher = networkFetcher;
     this.cacheProvider = cacheProvider;
+    this.enableSystraceMarkers = enableSystraceMarkers;
   }
 
   public static final class Builder {
@@ -27,15 +32,28 @@
     private LottieNetworkFetcher networkFetcher;
     @Nullable
     private LottieNetworkCacheProvider cacheProvider;
+    private boolean enableSystraceMarkers = false;
 
+    /**
+     * Lottie has a default network fetching stack built on {@link java.net.HttpURLConnection}. However, if you would like to hook into your own
+     * network stack for performance, caching, or analytics, you may replace the internal stack with your own.
+     */
     @NonNull
     public Builder setNetworkFetcher(@NonNull LottieNetworkFetcher fetcher) {
       this.networkFetcher = fetcher;
       return this;
     }
 
+    /**
+     * Provide your own network cache directory. By default, animations will be saved in your application's cacheDir/lottie_network_cache.
+     *
+     * @see #setNetworkCacheProvider(LottieNetworkCacheProvider)
+     */
     @NonNull
-    public Builder setCacheDir(@NonNull final File file) {
+    public Builder setNetworkCacheDir(@NonNull final File file) {
+      if (cacheProvider != null) {
+        throw new IllegalStateException("There is already a cache provider!");
+      }
       cacheProvider = new LottieNetworkCacheProvider() {
         @Override @NonNull public File getCacheDir() {
           if (!file.isDirectory()) {
@@ -47,8 +65,14 @@
       return this;
     }
 
+    /**
+     * Provide your own network cache provider. By default, animations will be saved in your application's cacheDir/lottie_network_cache.
+     */
     @NonNull
-    public Builder setCacheProvider(@NonNull final LottieNetworkCacheProvider fileCacheProvider) {
+    public Builder setNetworkCacheProvider(@NonNull final LottieNetworkCacheProvider fileCacheProvider) {
+      if (cacheProvider != null) {
+        throw new IllegalStateException("There is already a cache provider!");
+      }
       cacheProvider = new LottieNetworkCacheProvider() {
         @NonNull @Override public File getCacheDir() {
           File file = fileCacheProvider.getCacheDir();
@@ -61,9 +85,22 @@
       return this;
     }
 
+    /**
+     * Enable this if you want to run systrace to debug the performance of animations.
+     * <p/>
+     * DO NOT leave this enabled in production. The overhead is low but non-zero.
+     *
+     * @see <a href="https://developer.android.com/topic/performance/tracing/command-line">Systrace Docs</a>
+     */
+    @NonNull
+    public Builder setEnableSystraceMarkers(boolean enable) {
+      enableSystraceMarkers = enable;
+      return this;
+    }
+
     @NonNull
     public LottieConfig build() {
-      return new LottieConfig(networkFetcher, cacheProvider);
+      return new LottieConfig(networkFetcher, cacheProvider, enableSystraceMarkers);
     }
   }
 }
\ No newline at end of file
diff --git a/lottie/src/main/java/com/airbnb/lottie/network/LottieNetworkFetcher.java b/lottie/src/main/java/com/airbnb/lottie/network/LottieNetworkFetcher.java
index 48b7658..a607d51 100644
--- a/lottie/src/main/java/com/airbnb/lottie/network/LottieNetworkFetcher.java
+++ b/lottie/src/main/java/com/airbnb/lottie/network/LottieNetworkFetcher.java
@@ -7,8 +7,8 @@
 
 /**
  * Implement this interface to handle network fetching manually when animations are requested via url. By default, Lottie will use an
- * HttpUrlConnection under the hood but this enables you to hook into your own network stack. By default, Lottie will also handle caching the
- * animations but if you want to provide your own cache directory, you may implement `LottieNetworkCacheProvider`.
+ * {@link java.net.HttpURLConnection} under the hood but this enables you to hook into your own network stack. By default, Lottie will also handle caching the
+ * animations but if you want to provide your own cache directory, you may implement {@link LottieNetworkCacheProvider}.
  *
  * @see com.airbnb.lottie.Lottie#initialize
  */