Allow targeting mattes with KeyPaths (#1710)

Fixes #974
diff --git a/lottie/src/main/java/com/airbnb/lottie/animation/content/ContentGroup.java b/lottie/src/main/java/com/airbnb/lottie/animation/content/ContentGroup.java
index 166ee8b..ebe2ad5 100644
--- a/lottie/src/main/java/com/airbnb/lottie/animation/content/ContentGroup.java
+++ b/lottie/src/main/java/com/airbnb/lottie/animation/content/ContentGroup.java
@@ -221,7 +221,7 @@
 
   @Override public void resolveKeyPath(
       KeyPath keyPath, int depth, List<KeyPath> accumulator, KeyPath currentPartialKeyPath) {
-    if (!keyPath.matches(getName(), depth)) {
+    if (!keyPath.matches(getName(), depth) && !"__container".equals(getName())) {
       return;
     }
 
diff --git a/lottie/src/main/java/com/airbnb/lottie/model/layer/BaseLayer.java b/lottie/src/main/java/com/airbnb/lottie/model/layer/BaseLayer.java
index 71acea8..f287299 100644
--- a/lottie/src/main/java/com/airbnb/lottie/model/layer/BaseLayer.java
+++ b/lottie/src/main/java/com/airbnb/lottie/model/layer/BaseLayer.java
@@ -592,6 +592,18 @@
   @Override
   public void resolveKeyPath(
       KeyPath keyPath, int depth, List<KeyPath> accumulator, KeyPath currentPartialKeyPath) {
+    if (matteLayer != null) {
+      KeyPath matteCurrentPartialKeyPath = currentPartialKeyPath.addKey(matteLayer.getName());
+      if (keyPath.fullyResolvesTo(matteLayer.getName(), depth)) {
+        accumulator.add(matteCurrentPartialKeyPath.resolve(matteLayer));
+      }
+
+      if (keyPath.propagateToChildren(getName(), depth)) {
+        int newDepth = depth + keyPath.incrementDepthBy(matteLayer.getName(), depth);
+        matteLayer.resolveChildKeyPath(keyPath, newDepth, accumulator, matteCurrentPartialKeyPath);
+      }
+    }
+
     if (!keyPath.matches(getName(), depth)) {
       return;
     }
diff --git a/sample/src/androidTest/java/com/airbnb/lottie/samples/LottieTest.kt b/sample/src/androidTest/java/com/airbnb/lottie/samples/LottieTest.kt
index 5395a62..64675c6 100644
--- a/sample/src/androidTest/java/com/airbnb/lottie/samples/LottieTest.kt
+++ b/sample/src/androidTest/java/com/airbnb/lottie/samples/LottieTest.kt
@@ -746,6 +746,11 @@
                     { ScaleXY(-1.0f, 1.0f) })
         }
 
+        withDrawable("Tests/TrackMattes.json", "Matte", "Matte property") { drawable ->
+            val keyPath = KeyPath("Shape Layer 1", "Rectangle 1", "Rectangle Path 1")
+            drawable.addValueCallback(keyPath, LottieProperty.RECTANGLE_SIZE, LottieValueCallback(PointF(50f, 50f)))
+        }
+
         withDrawable("Tests/Text.json", "Text", "Text Fill (Blue -> Green)") { drawable ->
             val value = object : LottieValueCallback<Int>() {
                 override fun getValue(frameInfo: LottieFrameInfo<Int>?) = Color.GREEN