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:
Luke De Feo
2022-09-22 04:26:18 -07:00
committed by Facebook GitHub Bot
parent ed662d2468
commit 32b7a5589f
2 changed files with 10 additions and 82 deletions

View File

@@ -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
}
}

View File

@@ -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(