Modified ShapeState#newDrawable to pass a deep copy of ShapeState

Because ShapeState#newDrawable passes a reference to the existing
ShapeState instance, modifications to a single ShapeDrawable instance
affect all instances of the ShapeDrawable obtained through
ShapeState

Bug: 74570674
Test: Tested by flashing a local build onto a Taimen and running
the sample application provided in the corresponding bug to verifying
that both usages of OvalShape within the sample app produce the same
visual result

Change-Id: I10a8aac8eb51d551a13f2b6292f0cd84bff84045
diff --git a/graphics/java/android/graphics/drawable/ShapeDrawable.java b/graphics/java/android/graphics/drawable/ShapeDrawable.java
index 34da928..7bfb4c3 100644
--- a/graphics/java/android/graphics/drawable/ShapeDrawable.java
+++ b/graphics/java/android/graphics/drawable/ShapeDrawable.java
@@ -594,12 +594,12 @@
 
         @Override
         public Drawable newDrawable() {
-            return new ShapeDrawable(this, null);
+            return new ShapeDrawable(new ShapeState(this), null);
         }
 
         @Override
         public Drawable newDrawable(Resources res) {
-            return new ShapeDrawable(this, res);
+            return new ShapeDrawable(new ShapeState(this), res);
         }
 
         @Override
diff --git a/graphics/java/android/graphics/drawable/shapes/ArcShape.java b/graphics/java/android/graphics/drawable/shapes/ArcShape.java
index 85ba0a9..90d07bc 100644
--- a/graphics/java/android/graphics/drawable/shapes/ArcShape.java
+++ b/graphics/java/android/graphics/drawable/shapes/ArcShape.java
@@ -20,6 +20,8 @@
 import android.graphics.Outline;
 import android.graphics.Paint;
 
+import java.util.Objects;
+
 /**
  * Creates an arc shape. The arc shape starts at a specified angle and sweeps
  * clockwise, drawing slices of pie.
@@ -74,5 +76,26 @@
     public ArcShape clone() throws CloneNotSupportedException {
         return (ArcShape) super.clone();
     }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        if (!super.equals(o)) {
+            return false;
+        }
+        ArcShape arcShape = (ArcShape) o;
+        return Float.compare(arcShape.mStartAngle, mStartAngle) == 0
+            && Float.compare(arcShape.mSweepAngle, mSweepAngle) == 0;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(super.hashCode(), mStartAngle, mSweepAngle);
+    }
 }
 
diff --git a/graphics/java/android/graphics/drawable/shapes/PathShape.java b/graphics/java/android/graphics/drawable/shapes/PathShape.java
index ce5552b..393fdee 100644
--- a/graphics/java/android/graphics/drawable/shapes/PathShape.java
+++ b/graphics/java/android/graphics/drawable/shapes/PathShape.java
@@ -21,6 +21,8 @@
 import android.graphics.Paint;
 import android.graphics.Path;
 
+import java.util.Objects;
+
 /**
  * Creates geometric paths, utilizing the {@link android.graphics.Path} class.
  * <p>
@@ -74,5 +76,30 @@
         shape.mPath = new Path(mPath);
         return shape;
     }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        if (!super.equals(o)) {
+            return false;
+        }
+        PathShape pathShape = (PathShape) o;
+        return Float.compare(pathShape.mStdWidth, mStdWidth) == 0
+            && Float.compare(pathShape.mStdHeight, mStdHeight) == 0
+            && Float.compare(pathShape.mScaleX, mScaleX) == 0
+            && Float.compare(pathShape.mScaleY, mScaleY) == 0
+            // Path does not have equals implementation but incase it gains one, use it here
+            && Objects.equals(mPath, pathShape.mPath);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(super.hashCode(), mStdWidth, mStdHeight, mPath, mScaleX, mScaleY);
+    }
 }
 
diff --git a/graphics/java/android/graphics/drawable/shapes/RectShape.java b/graphics/java/android/graphics/drawable/shapes/RectShape.java
index e339a21..1bbd1d7 100644
--- a/graphics/java/android/graphics/drawable/shapes/RectShape.java
+++ b/graphics/java/android/graphics/drawable/shapes/RectShape.java
@@ -21,6 +21,8 @@
 import android.graphics.Paint;
 import android.graphics.RectF;
 
+import java.util.Objects;
+
 /**
  * Defines a rectangle shape.
  * <p>
@@ -63,4 +65,24 @@
         shape.mRect = new RectF(mRect);
         return shape;
     }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        if (!super.equals(o)) {
+            return false;
+        }
+        RectShape rectShape = (RectShape) o;
+        return Objects.equals(mRect, rectShape.mRect);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(super.hashCode(), mRect);
+    }
 }
diff --git a/graphics/java/android/graphics/drawable/shapes/RoundRectShape.java b/graphics/java/android/graphics/drawable/shapes/RoundRectShape.java
index f5cbb24..475e0bb 100644
--- a/graphics/java/android/graphics/drawable/shapes/RoundRectShape.java
+++ b/graphics/java/android/graphics/drawable/shapes/RoundRectShape.java
@@ -23,6 +23,9 @@
 import android.graphics.Path;
 import android.graphics.RectF;
 
+import java.util.Arrays;
+import java.util.Objects;
+
 /**
  * Creates a rounded-corner rectangle. Optionally, an inset (rounded) rectangle
  * can be included (to make a sort of "O" shape).
@@ -137,4 +140,31 @@
         shape.mPath = new Path(mPath);
         return shape;
     }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        if (!super.equals(o)) {
+            return false;
+        }
+        RoundRectShape that = (RoundRectShape) o;
+        return Arrays.equals(mOuterRadii, that.mOuterRadii)
+            && Objects.equals(mInset, that.mInset)
+            && Arrays.equals(mInnerRadii, that.mInnerRadii)
+            && Objects.equals(mInnerRect, that.mInnerRect)
+            && Objects.equals(mPath, that.mPath);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = Objects.hash(super.hashCode(), mInset, mInnerRect, mPath);
+        result = 31 * result + Arrays.hashCode(mOuterRadii);
+        result = 31 * result + Arrays.hashCode(mInnerRadii);
+        return result;
+    }
 }
diff --git a/graphics/java/android/graphics/drawable/shapes/Shape.java b/graphics/java/android/graphics/drawable/shapes/Shape.java
index 30b28f3..3b044ec 100644
--- a/graphics/java/android/graphics/drawable/shapes/Shape.java
+++ b/graphics/java/android/graphics/drawable/shapes/Shape.java
@@ -21,6 +21,8 @@
 import android.graphics.Outline;
 import android.graphics.Paint;
 
+import java.util.Objects;
+
 /**
  * Defines a generic graphical "shape."
  * <p>
@@ -115,4 +117,22 @@
     public Shape clone() throws CloneNotSupportedException {
         return (Shape) super.clone();
     }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        Shape shape = (Shape) o;
+        return Float.compare(shape.mWidth, mWidth) == 0
+            && Float.compare(shape.mHeight, mHeight) == 0;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mWidth, mHeight);
+    }
 }