Make sure parent graphicsLayer is correctly propagated in Views implementation and software rendering mode

Views could re-execute the recorded draw lambda from a different flow so we have to correctly call withTracking every time the draw block is executed.

Test: new test in AndroidGraphicsLayerTest.kt
Change-Id: I48efb24b487d0da1189d0efd567eb266a7d06123
diff --git a/compose/ui/ui-graphics/src/androidInstrumentedTest/kotlin/androidx/compose/ui/graphics/layer/AndroidGraphicsLayerTest.kt b/compose/ui/ui-graphics/src/androidInstrumentedTest/kotlin/androidx/compose/ui/graphics/layer/AndroidGraphicsLayerTest.kt
index 658156b..2b840b3 100644
--- a/compose/ui/ui-graphics/src/androidInstrumentedTest/kotlin/androidx/compose/ui/graphics/layer/AndroidGraphicsLayerTest.kt
+++ b/compose/ui/ui-graphics/src/androidInstrumentedTest/kotlin/androidx/compose/ui/graphics/layer/AndroidGraphicsLayerTest.kt
@@ -1700,6 +1700,31 @@
     }
 
     @Test
+    fun testChildLayerHasReferenceToParentLayer() {
+        lateinit var layer1: GraphicsLayer
+        lateinit var layer2: GraphicsLayer
+        graphicsLayerTest(
+            block = { context ->
+                // creating new layers will also schedule a persistence pass in Handler
+                layer1 = context.createGraphicsLayer()
+                layer2 = context.createGraphicsLayer()
+                layer2.record(Density(1f), Ltr, IntSize(10, 10)) {
+                    assertEquals(layer2, drawContext.graphicsLayer)
+                    drawRect(Color.Red)
+                }
+                layer1.record(Density(1f), Ltr, IntSize(10, 10)) {
+                    assertEquals(layer1, drawContext.graphicsLayer)
+                    drawLayer(layer2)
+                }
+                drawLayer(layer1)
+            },
+            verify = {
+                // just verifying there is no crash
+            }
+        )
+    }
+
+    @Test
     fun testCanvasTransformStateRestore() {
         val bg = Color.White
         val layerColor1 = Color.Red
diff --git a/compose/ui/ui-graphics/src/androidMain/kotlin/androidx/compose/ui/graphics/layer/AndroidGraphicsLayer.android.kt b/compose/ui/ui-graphics/src/androidMain/kotlin/androidx/compose/ui/graphics/layer/AndroidGraphicsLayer.android.kt
index b9b0424..857a07a 100644
--- a/compose/ui/ui-graphics/src/androidMain/kotlin/androidx/compose/ui/graphics/layer/AndroidGraphicsLayer.android.kt
+++ b/compose/ui/ui-graphics/src/androidMain/kotlin/androidx/compose/ui/graphics/layer/AndroidGraphicsLayer.android.kt
@@ -41,6 +41,7 @@
 import androidx.compose.ui.graphics.drawscope.DefaultDensity
 import androidx.compose.ui.graphics.drawscope.DrawScope
 import androidx.compose.ui.graphics.drawscope.clipPath
+import androidx.compose.ui.graphics.drawscope.draw
 import androidx.compose.ui.graphics.layer.LayerManager.Companion.isRobolectric
 import androidx.compose.ui.graphics.nativeCanvas
 import androidx.compose.ui.unit.Density
@@ -67,9 +68,9 @@
     private val clipDrawBlock: DrawScope.() -> Unit = {
         val path = outlinePath
         if (usePathForClip && clip && path != null) {
-            clipPath(path, block = drawBlock)
+            clipPath(path) { drawWithChildTracking() }
         } else {
-            drawBlock()
+            drawWithChildTracking()
         }
     }
 
@@ -432,10 +433,14 @@
     }
 
     private fun recordInternal() {
+        impl.record(density, layoutDirection, this, clipDrawBlock)
+    }
+
+    private fun DrawScope.drawWithChildTracking() {
         childDependenciesTracker.withTracking(
             onDependencyRemoved = { it.onRemovedFromParentLayer() }
         ) {
-            impl.record(density, layoutDirection, this, clipDrawBlock)
+            drawBlock()
         }
     }
 
@@ -550,7 +555,9 @@
             impl.draw(canvas)
         } else {
             val drawScope = softwareDrawScope ?: CanvasDrawScope().also { softwareDrawScope = it }
-            drawScope.draw(density, layoutDirection, canvas, size.toSize(), drawBlock)
+            drawScope.draw(density, layoutDirection, canvas, size.toSize(), this) {
+                drawWithChildTracking()
+            }
         }
 
         if (willClipPath) {
diff --git a/compose/ui/ui-graphics/src/androidMain/kotlin/androidx/compose/ui/graphics/layer/GraphicsViewLayer.android.kt b/compose/ui/ui-graphics/src/androidMain/kotlin/androidx/compose/ui/graphics/layer/GraphicsViewLayer.android.kt
index 9ed246d..024dff6 100644
--- a/compose/ui/ui-graphics/src/androidMain/kotlin/androidx/compose/ui/graphics/layer/GraphicsViewLayer.android.kt
+++ b/compose/ui/ui-graphics/src/androidMain/kotlin/androidx/compose/ui/graphics/layer/GraphicsViewLayer.android.kt
@@ -437,7 +437,14 @@
                 val pictureCanvas = p.beginRecording(size.width, size.height)
                 try {
                     pictureCanvasHolder?.drawInto(pictureCanvas) {
-                        pictureDrawScope?.draw(density, layoutDirection, this, size.toSize(), block)
+                        pictureDrawScope?.draw(
+                            density,
+                            layoutDirection,
+                            this,
+                            size.toSize(),
+                            layer,
+                            block
+                        )
                     }
                 } finally {
                     p.endRecording()