Remove layout traversal
Summary: The old full traversal was not needed as the partial traversal is a superset of the functionality and it was a pain to maintain both Reviewed By: lblasa Differential Revision: D39700216 fbshipit-source-id: 0b028995a59f7c5ea4318add8b0534851ca99547
This commit is contained in:
committed by
Facebook GitHub Bot
parent
ed662d2468
commit
32b7a5589f
@@ -1,80 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the MIT license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.facebook.flipper.plugins.uidebugger.core
|
|
||||||
|
|
||||||
import android.util.Log
|
|
||||||
import com.facebook.flipper.plugins.uidebugger.LogTag
|
|
||||||
import com.facebook.flipper.plugins.uidebugger.descriptors.DescriptorRegister
|
|
||||||
import com.facebook.flipper.plugins.uidebugger.descriptors.NodeDescriptor
|
|
||||||
import com.facebook.flipper.plugins.uidebugger.model.Node
|
|
||||||
|
|
||||||
class LayoutTraversal(
|
|
||||||
private val descriptorRegister: DescriptorRegister,
|
|
||||||
val root: ApplicationRef
|
|
||||||
) {
|
|
||||||
|
|
||||||
@Suppress("unchecked_cast")
|
|
||||||
internal fun NodeDescriptor<*>.asAny(): NodeDescriptor<Any> = this as NodeDescriptor<Any>
|
|
||||||
|
|
||||||
/** Traverses the native android hierarchy */
|
|
||||||
fun traverse(): List<Node> {
|
|
||||||
|
|
||||||
val result = mutableListOf<Node>()
|
|
||||||
val stack = mutableListOf<Any>()
|
|
||||||
stack.add(this.root)
|
|
||||||
|
|
||||||
while (stack.isNotEmpty()) {
|
|
||||||
val node = stack.removeLast()
|
|
||||||
|
|
||||||
try {
|
|
||||||
val descriptor = descriptorRegister.descriptorForClassUnsafe(node::class.java).asAny()
|
|
||||||
val children = descriptor.getChildren(node)
|
|
||||||
val activeChild = descriptor.getActiveChild(node)
|
|
||||||
|
|
||||||
val childrenIds = mutableListOf<String>()
|
|
||||||
children.forEach { child ->
|
|
||||||
val childDescriptor =
|
|
||||||
descriptorRegister.descriptorForClassUnsafe(child::class.java).asAny()
|
|
||||||
// It might make sense one day to remove id from the descriptor since its always the
|
|
||||||
// hash code
|
|
||||||
childrenIds.add(childDescriptor.getId(child))
|
|
||||||
// If there is an active child then don't traverse it
|
|
||||||
if (activeChild == null) {
|
|
||||||
stack.add(child)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var activeChildId: String? = null
|
|
||||||
if (activeChild != null) {
|
|
||||||
stack.add(activeChild)
|
|
||||||
activeChildId =
|
|
||||||
descriptorRegister.descriptorForClassUnsafe(activeChild.javaClass).getId(activeChild)
|
|
||||||
}
|
|
||||||
|
|
||||||
val attributes = descriptor.getData(node)
|
|
||||||
|
|
||||||
val bounds = descriptor.getBounds(node)
|
|
||||||
val tags = descriptor.getTags(node)
|
|
||||||
|
|
||||||
result.add(
|
|
||||||
Node(
|
|
||||||
descriptor.getId(node),
|
|
||||||
descriptor.getName(node),
|
|
||||||
attributes,
|
|
||||||
bounds,
|
|
||||||
tags,
|
|
||||||
childrenIds,
|
|
||||||
activeChildId))
|
|
||||||
} catch (exception: Exception) {
|
|
||||||
Log.e(LogTag, "Error while processing node ${node.javaClass.name} $node", exception)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -13,6 +13,8 @@ import com.facebook.flipper.plugins.uidebugger.LogTag
|
|||||||
import com.facebook.flipper.plugins.uidebugger.model.NativeScanEvent
|
import com.facebook.flipper.plugins.uidebugger.model.NativeScanEvent
|
||||||
import com.facebook.flipper.plugins.uidebugger.model.Node
|
import com.facebook.flipper.plugins.uidebugger.model.Node
|
||||||
import com.facebook.flipper.plugins.uidebugger.model.PerfStatsEvent
|
import com.facebook.flipper.plugins.uidebugger.model.PerfStatsEvent
|
||||||
|
import com.facebook.flipper.plugins.uidebugger.observers.PartialLayoutTraversal
|
||||||
|
import com.facebook.flipper.plugins.uidebugger.observers.TreeObserverFactory
|
||||||
import com.facebook.flipper.plugins.uidebugger.scheduler.Scheduler
|
import com.facebook.flipper.plugins.uidebugger.scheduler.Scheduler
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
|
|
||||||
@@ -23,13 +25,19 @@ data class ScanResult(
|
|||||||
val nodes: List<Node>
|
val nodes: List<Node>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/** This is used to stress test the ui debugger, should not be used in production */
|
||||||
class NativeScanScheduler(val context: Context) : Scheduler.Task<ScanResult> {
|
class NativeScanScheduler(val context: Context) : Scheduler.Task<ScanResult> {
|
||||||
private val traversal = LayoutTraversal(context.descriptorRegister, context.applicationRef)
|
/**
|
||||||
|
* when you supply no observers the traversal will never halt and will effectively scan the entire
|
||||||
|
* hierarchy
|
||||||
|
*/
|
||||||
|
private val emptyObserverFactory = TreeObserverFactory()
|
||||||
|
private val traversal = PartialLayoutTraversal(context.descriptorRegister, emptyObserverFactory)
|
||||||
private var txId = 0L
|
private var txId = 0L
|
||||||
|
|
||||||
override fun execute(): ScanResult {
|
override fun execute(): ScanResult {
|
||||||
val start = System.currentTimeMillis()
|
val start = System.currentTimeMillis()
|
||||||
val nodes = traversal.traverse()
|
val (nodes) = traversal.traverse(context.applicationRef)
|
||||||
val scanEnd = System.currentTimeMillis()
|
val scanEnd = System.currentTimeMillis()
|
||||||
|
|
||||||
Log.d(
|
Log.d(
|
||||||
|
|||||||
Reference in New Issue
Block a user