[go: nahoru, domu]

Fix RestrictedApiAndroidX in transition

Relnote: "Make PathParser public. The class can create a Path instance from SVG path strings."
Bug: 302376846
Test: ./gradlew :transition:transition:lintDebug
Change-Id: Ic7af2e7ea294ed43e8ebcf41852d2c1618816655
diff --git a/core/core-animation/build.gradle b/core/core-animation/build.gradle
index cbfd656..0bd7a99 100644
--- a/core/core-animation/build.gradle
+++ b/core/core-animation/build.gradle
@@ -23,7 +23,7 @@
 
 dependencies {
     api("androidx.annotation:annotation:1.2.0")
-    implementation("androidx.core:core:1.3.1")
+    implementation(project(":core:core"))
     implementation("androidx.collection:collection:1.1.0")
     implementation("androidx.tracing:tracing:1.0.0")
 
diff --git a/core/core/api/api_lint.ignore b/core/core/api/api_lint.ignore
index 842f89f..2c91af6 100644
--- a/core/core/api/api_lint.ignore
+++ b/core/core/api/api_lint.ignore
@@ -117,6 +117,28 @@
     Method parameter should be Collection<Intent> (or subclass) instead of raw array; was `android.content.Intent[]`
 ArrayReturn: androidx.core.content.pm.ShortcutInfoCompat.Builder#setPersons(androidx.core.app.Person[]) parameter #0:
     Method parameter should be Collection<Person> (or subclass) instead of raw array; was `androidx.core.app.Person[]`
+ArrayReturn: androidx.core.graphics.PathParser#canMorph(androidx.core.graphics.PathParser.PathDataNode[], androidx.core.graphics.PathParser.PathDataNode[]) parameter #0:
+    Method parameter should be Collection<PathDataNode> (or subclass) instead of raw array; was `androidx.core.graphics.PathParser.PathDataNode[]`
+ArrayReturn: androidx.core.graphics.PathParser#canMorph(androidx.core.graphics.PathParser.PathDataNode[], androidx.core.graphics.PathParser.PathDataNode[]) parameter #1:
+    Method parameter should be Collection<PathDataNode> (or subclass) instead of raw array; was `androidx.core.graphics.PathParser.PathDataNode[]`
+ArrayReturn: androidx.core.graphics.PathParser#createNodesFromPathData(String):
+    Method should return Collection<PathDataNode> (or subclass) instead of raw array; was `androidx.core.graphics.PathParser.PathDataNode[]`
+ArrayReturn: androidx.core.graphics.PathParser#deepCopyNodes(androidx.core.graphics.PathParser.PathDataNode[]):
+    Method should return Collection<PathDataNode> (or subclass) instead of raw array; was `androidx.core.graphics.PathParser.PathDataNode[]`
+ArrayReturn: androidx.core.graphics.PathParser#deepCopyNodes(androidx.core.graphics.PathParser.PathDataNode[]) parameter #0:
+    Method parameter should be Collection<PathDataNode> (or subclass) instead of raw array; was `androidx.core.graphics.PathParser.PathDataNode[]`
+ArrayReturn: androidx.core.graphics.PathParser#interpolatePathDataNodes(androidx.core.graphics.PathParser.PathDataNode[], androidx.core.graphics.PathParser.PathDataNode[], androidx.core.graphics.PathParser.PathDataNode[], float) parameter #0:
+    Method parameter should be Collection<PathDataNode> (or subclass) instead of raw array; was `androidx.core.graphics.PathParser.PathDataNode[]`
+ArrayReturn: androidx.core.graphics.PathParser#interpolatePathDataNodes(androidx.core.graphics.PathParser.PathDataNode[], androidx.core.graphics.PathParser.PathDataNode[], androidx.core.graphics.PathParser.PathDataNode[], float) parameter #1:
+    Method parameter should be Collection<PathDataNode> (or subclass) instead of raw array; was `androidx.core.graphics.PathParser.PathDataNode[]`
+ArrayReturn: androidx.core.graphics.PathParser#interpolatePathDataNodes(androidx.core.graphics.PathParser.PathDataNode[], androidx.core.graphics.PathParser.PathDataNode[], androidx.core.graphics.PathParser.PathDataNode[], float) parameter #2:
+    Method parameter should be Collection<PathDataNode> (or subclass) instead of raw array; was `androidx.core.graphics.PathParser.PathDataNode[]`
+ArrayReturn: androidx.core.graphics.PathParser#updateNodes(androidx.core.graphics.PathParser.PathDataNode[], androidx.core.graphics.PathParser.PathDataNode[]) parameter #0:
+    Method parameter should be Collection<PathDataNode> (or subclass) instead of raw array; was `androidx.core.graphics.PathParser.PathDataNode[]`
+ArrayReturn: androidx.core.graphics.PathParser#updateNodes(androidx.core.graphics.PathParser.PathDataNode[], androidx.core.graphics.PathParser.PathDataNode[]) parameter #1:
+    Method parameter should be Collection<PathDataNode> (or subclass) instead of raw array; was `androidx.core.graphics.PathParser.PathDataNode[]`
+ArrayReturn: androidx.core.graphics.PathParser.PathDataNode#nodesToPath(androidx.core.graphics.PathParser.PathDataNode[], android.graphics.Path) parameter #0:
+    Method parameter should be Collection<PathDataNode> (or subclass) instead of raw array; was `androidx.core.graphics.PathParser.PathDataNode[]`
 ArrayReturn: androidx.core.hardware.display.DisplayManagerCompat#getDisplays():
     Method should return Collection<Display> (or subclass) instead of raw array; was `android.view.Display[]`
 ArrayReturn: androidx.core.hardware.display.DisplayManagerCompat#getDisplays(String):
@@ -261,12 +283,10 @@
     Invalid nullability on parameter `provider` in method `onStatusChanged`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
 InvalidNullabilityOverride: androidx.core.widget.NestedScrollView#addView(android.view.View) parameter #0:
     Invalid nullability on parameter `child` in method `addView`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
-InvalidNullabilityOverride: androidx.core.widget.NestedScrollView#draw(android.graphics.Canvas) parameter #0:
-    Invalid nullability on parameter `canvas` in method `draw`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
 InvalidNullabilityOverride: androidx.core.widget.NestedScrollView#measureChild(android.view.View, int, int) parameter #0:
     Invalid nullability on parameter `child` in method `measureChild`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
 InvalidNullabilityOverride: androidx.core.widget.NestedScrollView#onGenericMotionEvent(android.view.MotionEvent) parameter #0:
-    Invalid nullability on parameter `event` in method `onGenericMotionEvent`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
+    Invalid nullability on parameter `motionEvent` in method `onGenericMotionEvent`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
 InvalidNullabilityOverride: androidx.core.widget.NestedScrollView#onInterceptTouchEvent(android.view.MotionEvent) parameter #0:
     Invalid nullability on parameter `ev` in method `onInterceptTouchEvent`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
 InvalidNullabilityOverride: androidx.core.widget.NestedScrollView#onNestedFling(android.view.View, float, float, boolean) parameter #0:
@@ -290,7 +310,7 @@
 InvalidNullabilityOverride: androidx.core.widget.NestedScrollView#onStopNestedScroll(android.view.View) parameter #0:
     Invalid nullability on parameter `target` in method `onStopNestedScroll`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
 InvalidNullabilityOverride: androidx.core.widget.NestedScrollView#onTouchEvent(android.view.MotionEvent) parameter #0:
-    Invalid nullability on parameter `ev` in method `onTouchEvent`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
+    Invalid nullability on parameter `motionEvent` in method `onTouchEvent`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
 InvalidNullabilityOverride: androidx.core.widget.NestedScrollView#requestChildRectangleOnScreen(android.view.View, android.graphics.Rect, boolean) parameter #0:
     Invalid nullability on parameter `child` in method `requestChildRectangleOnScreen`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
 
@@ -451,8 +471,6 @@
 
 MissingNullability: androidx.core.app.JobIntentService#onBind(android.content.Intent):
     Missing nullability on method `onBind` return
-MissingNullability: androidx.core.app.NotificationCompat.Action#actionIntent:
-    Missing nullability on field `actionIntent` in class `class androidx.core.app.NotificationCompat.Action`
 MissingNullability: androidx.core.app.NotificationCompat.Action#title:
     Missing nullability on field `title` in class `class androidx.core.app.NotificationCompat.Action`
 MissingNullability: androidx.core.app.NotificationCompatSideChannelService#cancel(String, int, String) parameter #0:
diff --git a/core/core/api/current.txt b/core/core/api/current.txt
index af5ccd0..9266dac 100644
--- a/core/core/api/current.txt
+++ b/core/core/api/current.txt
@@ -1504,6 +1504,22 @@
     method public static boolean setBlendMode(android.graphics.Paint, androidx.core.graphics.BlendModeCompat?);
   }
 
+  public class PathParser {
+    method public static boolean canMorph(androidx.core.graphics.PathParser.PathDataNode![]?, androidx.core.graphics.PathParser.PathDataNode![]?);
+    method public static androidx.core.graphics.PathParser.PathDataNode![] createNodesFromPathData(String);
+    method public static android.graphics.Path createPathFromPathData(String);
+    method public static androidx.core.graphics.PathParser.PathDataNode![] deepCopyNodes(androidx.core.graphics.PathParser.PathDataNode![]);
+    method public static boolean interpolatePathDataNodes(androidx.core.graphics.PathParser.PathDataNode![], androidx.core.graphics.PathParser.PathDataNode![], androidx.core.graphics.PathParser.PathDataNode![], float);
+    method public static void updateNodes(androidx.core.graphics.PathParser.PathDataNode![], androidx.core.graphics.PathParser.PathDataNode![]);
+  }
+
+  public static class PathParser.PathDataNode {
+    method public float[] getParams();
+    method public char getType();
+    method public void interpolatePathDataNode(androidx.core.graphics.PathParser.PathDataNode, androidx.core.graphics.PathParser.PathDataNode, float);
+    method public static void nodesToPath(androidx.core.graphics.PathParser.PathDataNode![], android.graphics.Path);
+  }
+
   public final class PathSegment {
     ctor public PathSegment(android.graphics.PointF, float, android.graphics.PointF, float);
     method public android.graphics.PointF getEnd();
diff --git a/core/core/api/restricted_current.txt b/core/core/api/restricted_current.txt
index f54f4e86..3f003f9 100644
--- a/core/core/api/restricted_current.txt
+++ b/core/core/api/restricted_current.txt
@@ -1746,6 +1746,22 @@
     method public static boolean setBlendMode(android.graphics.Paint, androidx.core.graphics.BlendModeCompat?);
   }
 
+  public class PathParser {
+    method public static boolean canMorph(androidx.core.graphics.PathParser.PathDataNode![]?, androidx.core.graphics.PathParser.PathDataNode![]?);
+    method public static androidx.core.graphics.PathParser.PathDataNode![] createNodesFromPathData(String);
+    method public static android.graphics.Path createPathFromPathData(String);
+    method public static androidx.core.graphics.PathParser.PathDataNode![] deepCopyNodes(androidx.core.graphics.PathParser.PathDataNode![]);
+    method public static boolean interpolatePathDataNodes(androidx.core.graphics.PathParser.PathDataNode![], androidx.core.graphics.PathParser.PathDataNode![], androidx.core.graphics.PathParser.PathDataNode![], float);
+    method public static void updateNodes(androidx.core.graphics.PathParser.PathDataNode![], androidx.core.graphics.PathParser.PathDataNode![]);
+  }
+
+  public static class PathParser.PathDataNode {
+    method public float[] getParams();
+    method public char getType();
+    method public void interpolatePathDataNode(androidx.core.graphics.PathParser.PathDataNode, androidx.core.graphics.PathParser.PathDataNode, float);
+    method public static void nodesToPath(androidx.core.graphics.PathParser.PathDataNode![], android.graphics.Path);
+  }
+
   public final class PathSegment {
     ctor public PathSegment(android.graphics.PointF, float, android.graphics.PointF, float);
     method public android.graphics.PointF getEnd();
diff --git a/core/core/src/main/java/androidx/core/graphics/PathParser.java b/core/core/src/main/java/androidx/core/graphics/PathParser.java
index be86323..8788fad 100644
--- a/core/core/src/main/java/androidx/core/graphics/PathParser.java
+++ b/core/core/src/main/java/androidx/core/graphics/PathParser.java
@@ -20,18 +20,16 @@
 import android.graphics.Path;
 import android.util.Log;
 
+import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.annotation.RestrictTo;
 
 import java.util.ArrayList;
 
+// This class is a duplicate from the PathParser.java of frameworks/base, with slight
+// update on incompatible API like copyOfRange().
 /**
- * This class is a duplicate from the PathParser.java of frameworks/base, with slight
- * update on incompatible API like copyOfRange().
- *
+ * Parses SVG path strings.
  */
-@RestrictTo(RestrictTo.Scope.LIBRARY)
-// TODO: Make this class public
 public class PathParser {
     private static final String LOGTAG = "PathParser";
 
@@ -67,31 +65,29 @@
     }
 
     /**
+     * Takes a string representation of an SVG path and converts it to a {@link Path}.
+     *
      * @param pathData The string representing a path, the same as "d" string in svg file.
      * @return the generated Path object.
      */
-    public static Path createPathFromPathData(String pathData) {
+    @NonNull
+    public static Path createPathFromPathData(@NonNull String pathData) {
         Path path = new Path();
         PathDataNode[] nodes = createNodesFromPathData(pathData);
-        if (nodes != null) {
-            try {
-                PathDataNode.nodesToPath(nodes, path);
-            } catch (RuntimeException e) {
-                throw new RuntimeException("Error in parsing " + pathData, e);
-            }
-            return path;
+        try {
+            PathDataNode.nodesToPath(nodes, path);
+        } catch (RuntimeException e) {
+            throw new RuntimeException("Error in parsing " + pathData, e);
         }
-        return null;
+        return path;
     }
 
     /**
      * @param pathData The string representing a path, the same as "d" string in svg file.
      * @return an array of the PathDataNode.
      */
-    public static PathDataNode[] createNodesFromPathData(String pathData) {
-        if (pathData == null) {
-            return null;
-        }
+    @NonNull
+    public static PathDataNode[] createNodesFromPathData(@NonNull String pathData) {
         int start = 0;
         int end = 1;
 
@@ -99,7 +95,7 @@
         while (end < pathData.length()) {
             end = nextStart(pathData, end);
             String s = pathData.substring(start, end).trim();
-            if (s.length() > 0) {
+            if (!s.isEmpty()) {
                 float[] val = getFloats(s);
                 addNode(list, s.charAt(0), val);
             }
@@ -110,17 +106,15 @@
         if ((end - start) == 1 && start < pathData.length()) {
             addNode(list, pathData.charAt(start), new float[0]);
         }
-        return list.toArray(new PathDataNode[list.size()]);
+        return list.toArray(new PathDataNode[0]);
     }
 
     /**
      * @param source The array of PathDataNode to be duplicated.
      * @return a deep copy of the <code>source</code>.
      */
-    public static PathDataNode[] deepCopyNodes(PathDataNode[] source) {
-        if (source == null) {
-            return null;
-        }
+    @NonNull
+    public static PathDataNode[] deepCopyNodes(@NonNull PathDataNode[] source) {
         PathDataNode[] copy = new PathParser.PathDataNode[source.length];
         for (int i = 0; i < source.length; i++) {
             copy[i] = new PathDataNode(source[i]);
@@ -159,7 +153,7 @@
      * @param target The target path represented in an array of PathDataNode
      * @param source The source path represented in an array of PathDataNode
      */
-    public static void updateNodes(PathDataNode[] target, PathDataNode[] source) {
+    public static void updateNodes(@NonNull PathDataNode[] target, @NonNull PathDataNode[] source) {
         for (int i = 0; i < source.length; i++) {
             target[i].mType = source[i].mType;
             for (int j = 0; j < source[i].mParams.length; j++) {
@@ -308,15 +302,10 @@
      * @param to The array of {@link PathDataNode} when the fraction is 1
      * @param fraction A float fraction value in the range of 0 to 1
      * @return whether it's possible to interpolate between the two arrays of PathDataNodes
-     * @see {@link #canMorph(PathDataNode[], PathDataNode[])}
+     * @see #canMorph(PathDataNode[], PathDataNode[])
      */
-    public static boolean interpolatePathDataNodes(PathDataNode[] target, PathDataNode[] from,
-            PathDataNode[] to, float fraction) {
-        if (target == null || from == null || to == null) {
-            throw new IllegalArgumentException("The nodes to be interpolated and resulting nodes"
-                    + " cannot be null");
-        }
-
+    public static boolean interpolatePathDataNodes(@NonNull PathDataNode[] target,
+            @NonNull PathDataNode[] from, @NonNull PathDataNode[] to, float fraction) {
         if (target.length != from.length || from.length != to.length) {
             throw new IllegalArgumentException("The nodes to be interpolated and resulting nodes"
                     + " must have the same length");
@@ -341,11 +330,20 @@
 
         /**
          */
-        public char mType;
+        private char mType;
 
         /**
          */
-        public float[] mParams;
+        private final float[] mParams;
+
+        public char getType() {
+            return mType;
+        }
+
+        @NonNull
+        public float[] getParams() {
+            return mParams;
+        }
 
         PathDataNode(char type, float[] params) {
             this.mType = type;
@@ -363,7 +361,7 @@
          * @param node The source array of PathDataNode.
          * @param path The target Path object.
          */
-        public static void nodesToPath(PathDataNode[] node, Path path) {
+        public static void nodesToPath(@NonNull PathDataNode[] node, @NonNull Path path) {
             float[] current = new float[6];
             char previousCommand = 'm';
             for (int i = 0; i < node.length; i++) {
@@ -381,8 +379,8 @@
          * @param nodeTo   The end value as a PathDataNode
          * @param fraction The fraction to interpolate.
          */
-        public void interpolatePathDataNode(PathDataNode nodeFrom, PathDataNode nodeTo,
-                float fraction) {
+        public void interpolatePathDataNode(@NonNull PathDataNode nodeFrom,
+                @NonNull PathDataNode nodeTo, float fraction) {
             mType = nodeFrom.mType;
             for (int i = 0; i < nodeFrom.mParams.length; i++) {
                 mParams[i] = nodeFrom.mParams[i] * (1 - fraction)
diff --git a/fragment/fragment-testing/build.gradle b/fragment/fragment-testing/build.gradle
index 1ad0ac7..f92585a 100644
--- a/fragment/fragment-testing/build.gradle
+++ b/fragment/fragment-testing/build.gradle
@@ -28,6 +28,7 @@
     api("androidx.test:core:1.5.0")
     api(libs.kotlinStdlib)
     api(project(":fragment:fragment-testing-manifest"))
+    implementation(project(":core:core-ktx"))
     androidTestImplementation(libs.kotlinStdlib)
     androidTestImplementation(libs.espressoCore)
     androidTestImplementation(libs.testExtJunit)
diff --git a/transition/transition/build.gradle b/transition/transition/build.gradle
index 693fbbd..6d5daad 100644
--- a/transition/transition/build.gradle
+++ b/transition/transition/build.gradle
@@ -8,7 +8,7 @@
 
 dependencies {
     api("androidx.annotation:annotation:1.2.0")
-    api("androidx.core:core:1.12.0")
+    api(project(":core:core"))
     implementation("androidx.collection:collection:1.1.0")
     compileOnly(projectOrArtifact(":fragment:fragment"))
     compileOnly("androidx.appcompat:appcompat:1.0.1")
diff --git a/transition/transition/lint-baseline.xml b/transition/transition/lint-baseline.xml
index fba6654..29f82c2 100644
--- a/transition/transition/lint-baseline.xml
+++ b/transition/transition/lint-baseline.xml
@@ -217,13 +217,4 @@
             file="src/main/java/androidx/transition/Styleable.java"/>
     </issue>
 
-    <issue
-        id="RestrictedApiAndroidX"
-        message="PathParser.createPathFromPathData can only be called from within the same library (androidx.core:core)"
-        errorLine1="            Path pattern = PathParser.createPathFromPathData(pathData);"
-        errorLine2="                                      ~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/transition/PatternPathMotion.java"/>
-    </issue>
-
 </issues>
diff --git a/vectordrawable/vectordrawable-animated/build.gradle b/vectordrawable/vectordrawable-animated/build.gradle
index 41599cf..db008c9 100644
--- a/vectordrawable/vectordrawable-animated/build.gradle
+++ b/vectordrawable/vectordrawable-animated/build.gradle
@@ -8,7 +8,7 @@
 dependencies {
     api("androidx.annotation:annotation:1.2.0")
     api(project(":vectordrawable:vectordrawable"))
-    implementation("androidx.core:core:1.6.0")
+    implementation(project(":core:core"))
     implementation("androidx.interpolator:interpolator:1.0.0")
     implementation("androidx.collection:collection:1.1.0")
 
diff --git a/vectordrawable/vectordrawable/build.gradle b/vectordrawable/vectordrawable/build.gradle
index 44b0415..edcf674 100644
--- a/vectordrawable/vectordrawable/build.gradle
+++ b/vectordrawable/vectordrawable/build.gradle
@@ -7,7 +7,7 @@
 
 dependencies {
     api("androidx.annotation:annotation:1.1.0")
-    api("androidx.core:core:1.6.0")
+    api(project(":core:core"))
     implementation("androidx.collection:collection:1.1.0")
 
     androidTestImplementation(libs.testExtJunit)
diff --git a/vectordrawable/vectordrawable/src/main/java/androidx/vectordrawable/graphics/drawable/VectorDrawableCompat.java b/vectordrawable/vectordrawable/src/main/java/androidx/vectordrawable/graphics/drawable/VectorDrawableCompat.java
index 82f43b6..2b8df02 100644
--- a/vectordrawable/vectordrawable/src/main/java/androidx/vectordrawable/graphics/drawable/VectorDrawableCompat.java
+++ b/vectordrawable/vectordrawable/src/main/java/androidx/vectordrawable/graphics/drawable/VectorDrawableCompat.java
@@ -1723,8 +1723,8 @@
         public String nodesToString(PathParser.PathDataNode[] nodes) {
             StringBuilder result = new StringBuilder(" ");
             for (PathParser.PathDataNode node : nodes) {
-                result.append(node.mType).append(":");
-                float[] params = node.mParams;
+                result.append(node.getType()).append(":");
+                float[] params = node.getParams();
                 for (float param : params) {
                     result.append(param).append(",");
                 }