Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b7d66cce authored by Steve Elliott's avatar Steve Elliott Committed by Automerger Merge Worker
Browse files

Merge "Fix stale View tracking in ShadeViewDiffer" into tm-dev am: 5c4291d7

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/17244063

Change-Id: Ied073e93f194645a9de6d774da726ac420d18980
parents a0fa5e68 5c4291d7
Loading
Loading
Loading
Loading
+21 −30
Original line number Original line Diff line number Diff line
@@ -18,7 +18,6 @@ package com.android.systemui.statusbar.notification.collection.render


import android.annotation.MainThread
import android.annotation.MainThread
import android.view.View
import android.view.View
import com.android.systemui.util.kotlin.transform
import com.android.systemui.util.traceSection
import com.android.systemui.util.traceSection


/**
/**
@@ -41,7 +40,6 @@ class ShadeViewDiffer(
) {
) {
    private val rootNode = ShadeNode(rootController)
    private val rootNode = ShadeNode(rootController)
    private val nodes = mutableMapOf(rootController to rootNode)
    private val nodes = mutableMapOf(rootController to rootNode)
    private val views = mutableMapOf<View, ShadeNode>()


    /**
    /**
     * Adds and removes views from the root (and its children) until their structure matches the
     * Adds and removes views from the root (and its children) until their structure matches the
@@ -66,27 +64,26 @@ class ShadeViewDiffer(
     *
     *
     * For debugging purposes.
     * For debugging purposes.
     */
     */
    fun getViewLabel(view: View): String = views[view]?.label ?: view.toString()
    fun getViewLabel(view: View): String =
            nodes.values.firstOrNull { node -> node.view === view }?.label ?: view.toString()


    private fun detachChildren(
    private fun detachChildren(parentNode: ShadeNode, specMap: Map<NodeController, NodeSpec>) {
        parentNode: ShadeNode,
        val views = nodes.values.asSequence().map { node -> node.view to node }.toMap()
        specMap: Map<NodeController, NodeSpec>
        fun detachRecursively(parentNode: ShadeNode, specMap: Map<NodeController, NodeSpec>) {
    ) {
            val parentSpec = specMap[parentNode.controller]
            val parentSpec = specMap[parentNode.controller]

            for (i in parentNode.getChildCount() - 1 downTo 0) {
            for (i in parentNode.getChildCount() - 1 downTo 0) {
                val childView = parentNode.getChildAt(i)
                val childView = parentNode.getChildAt(i)
                views[childView]?.let { childNode ->
                views[childView]?.let { childNode ->
                    val childSpec = specMap[childNode.controller]
                    val childSpec = specMap[childNode.controller]

                    maybeDetachChild(parentNode, parentSpec, childNode, childSpec)
                    maybeDetachChild(parentNode, parentSpec, childNode, childSpec)

                    if (childNode.controller.getChildCount() > 0) {
                    if (childNode.controller.getChildCount() > 0) {
                    detachChildren(childNode, specMap)
                        detachRecursively(childNode, specMap)
                    }
                    }
                }
                }
            }
            }
        }
        }
        detachRecursively(parentNode, specMap)
    }


    private fun maybeDetachChild(
    private fun maybeDetachChild(
        parentNode: ShadeNode,
        parentNode: ShadeNode,
@@ -94,14 +91,13 @@ class ShadeViewDiffer(
        childNode: ShadeNode,
        childNode: ShadeNode,
        childSpec: NodeSpec?
        childSpec: NodeSpec?
    ) {
    ) {
        val newParentNode = transform(childSpec?.parent) { getNode(it) }
        val newParentNode = childSpec?.parent?.let { getNode(it) }


        if (newParentNode != parentNode) {
        if (newParentNode != parentNode) {
            val childCompletelyRemoved = newParentNode == null
            val childCompletelyRemoved = newParentNode == null


            if (childCompletelyRemoved) {
            if (childCompletelyRemoved) {
                nodes.remove(childNode.controller)
                nodes.remove(childNode.controller)
                views.remove(childNode.controller.view)
            }
            }


            logger.logDetachingChild(
            logger.logDetachingChild(
@@ -115,10 +111,7 @@ class ShadeViewDiffer(
        }
        }
    }
    }


    private fun attachChildren(
    private fun attachChildren(parentNode: ShadeNode, specMap: Map<NodeController, NodeSpec>) {
        parentNode: ShadeNode,
        specMap: Map<NodeController, NodeSpec>
    ) {
        val parentSpec = checkNotNull(specMap[parentNode.controller])
        val parentSpec = checkNotNull(specMap[parentNode.controller])


        for ((index, childSpec) in parentSpec.children.withIndex()) {
        for ((index, childSpec) in parentSpec.children.withIndex()) {
@@ -160,7 +153,6 @@ class ShadeViewDiffer(
        if (node == null) {
        if (node == null) {
            node = ShadeNode(spec.controller)
            node = ShadeNode(spec.controller)
            nodes[node.controller] = node
            nodes[node.controller] = node
            views[node.view] = node
        }
        }
        return node
        return node
    }
    }
@@ -194,10 +186,9 @@ class ShadeViewDiffer(


private class DuplicateNodeException(message: String) : RuntimeException(message)
private class DuplicateNodeException(message: String) : RuntimeException(message)


private class ShadeNode(
private class ShadeNode(val controller: NodeController) {
    val controller: NodeController
    val view: View
) {
        get() = controller.view
    val view = controller.view


    var parent: ShadeNode? = null
    var parent: ShadeNode? = null