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(",");
}