Add bounds and tags to descriptor

Summary: This is to support a future diff where we will draw a basic wireframe for debugging

Reviewed By: lblasa

Differential Revision: D39509407

fbshipit-source-id: d99fd6fe39404996a0ed944c10905331262fd0c6
This commit is contained in:
Luke De Feo
2022-09-21 07:02:48 -07:00
committed by Facebook GitHub Bot
parent c09e185867
commit 80b05092ac
9 changed files with 81 additions and 2 deletions

View File

@@ -8,7 +8,9 @@
package com.facebook.flipper.plugins.uidebugger.litho
import com.facebook.flipper.plugins.uidebugger.common.InspectableObject
import com.facebook.flipper.plugins.uidebugger.descriptors.BaseTags
import com.facebook.flipper.plugins.uidebugger.descriptors.NodeDescriptor
import com.facebook.flipper.plugins.uidebugger.model.Bounds
import com.facebook.litho.DebugComponent
import com.facebook.litho.LithoView
@@ -29,8 +31,14 @@ object LithoViewDescriptor : NodeDescriptor<LithoView> {
override fun getActiveChild(node: LithoView): Any? = null
override fun getData(node: LithoView) = mapOf<String, InspectableObject>()
override fun getBounds(node: LithoView): Bounds? = null
override fun getTags(node: LithoView): Set<String> = setOf()
}
const val LithoTag = "Litho"
object DebugComponentDescriptor : NodeDescriptor<DebugComponent> {
override fun getId(node: DebugComponent): String = System.identityHashCode(node).toString()
@@ -60,4 +68,10 @@ object DebugComponentDescriptor : NodeDescriptor<DebugComponent> {
override fun getActiveChild(node: DebugComponent): Any? = null
override fun getData(node: DebugComponent) = mapOf<String, InspectableObject>()
override fun getBounds(node: DebugComponent): Bounds {
val bounds = node.bounds
return Bounds(bounds.left, bounds.top, bounds.width(), bounds.height())
}
override fun getTags(node: DebugComponent): Set<String> = setOf(BaseTags.Declarative, LithoTag)
}

View File

@@ -57,11 +57,17 @@ class LayoutTraversal(
}
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) {

View File

@@ -8,8 +8,10 @@
package com.facebook.flipper.plugins.uidebugger.descriptors
import android.app.Activity
import android.content.res.Resources
import android.view.View
import com.facebook.flipper.plugins.uidebugger.core.ApplicationRef
import com.facebook.flipper.plugins.uidebugger.model.Bounds
object ApplicationRefDescriptor : ChainedDescriptor<ApplicationRef>() {
@@ -21,6 +23,11 @@ object ApplicationRefDescriptor : ChainedDescriptor<ApplicationRef>() {
return node.application.packageName
}
override fun onGetBounds(node: ApplicationRef): Bounds {
val displayMetrics = Resources.getSystem().getDisplayMetrics()
return Bounds(0, 0, displayMetrics.widthPixels, displayMetrics.heightPixels)
}
override fun onGetName(node: ApplicationRef): String {
val applicationInfo = node.application.applicationInfo
val stringId = applicationInfo.labelRes

View File

@@ -8,6 +8,7 @@
package com.facebook.flipper.plugins.uidebugger.descriptors
import com.facebook.flipper.plugins.uidebugger.common.InspectableObject
import com.facebook.flipper.plugins.uidebugger.model.Bounds
/**
* A chained descriptor is a special type of descriptor that models the inheritance hierarchy in
@@ -56,10 +57,23 @@ abstract class ChainedDescriptor<T> : NodeDescriptor<T> {
return onGetName(node)
}
final override fun getTags(node: T): Set<String> {
val tags = onGetTags(node) ?: mSuper?.getTags(node)
return tags ?: setOf()
}
open fun onGetTags(node: T): Set<String>? = null
open fun onGetActiveChild(node: T): Any? = null
abstract fun onGetName(node: T): String
final override fun getBounds(node: T): Bounds? {
return onGetBounds(node) ?: mSuper?.getBounds(node)
}
open fun onGetBounds(node: T): Bounds? = null
/** The children this node exposes in the inspector. */
final override fun getChildren(node: T): List<Any> {
val builder = mutableListOf<Any>()

View File

@@ -8,6 +8,7 @@
package com.facebook.flipper.plugins.uidebugger.descriptors
import com.facebook.flipper.plugins.uidebugger.common.InspectableObject
import com.facebook.flipper.plugins.uidebugger.model.Bounds
/*
Descriptors are an extension point used during traversal to extract data out of arbitrary
@@ -19,6 +20,14 @@ import com.facebook.flipper.plugins.uidebugger.common.InspectableObject
typealias SectionName = String
object BaseTags {
const val Declarative = "Declarative"
const val Native = "Native"
const val Accessibility = "Accessibility"
const val Android = "Android"
const val Unknown = "Unknown"
}
interface NodeDescriptor<T> {
/**
* A globally unique ID used to identify a node in a hierarchy. If your node does not have a
@@ -26,6 +35,9 @@ interface NodeDescriptor<T> {
*/
fun getId(node: T): String
/** Should be w.r.t the direct parent */
fun getBounds(node: T): Bounds?
/**
* The name used to identify this node in the inspector. Does not need to be unique. A good
* default is to use the class name of the node.
@@ -46,4 +58,10 @@ interface NodeDescriptor<T> {
* order and with a header matching the given name.
*/
fun getData(node: T): Map<SectionName, InspectableObject>
/**
* Set of tags to describe this node in an abstract way for the UI Unfortunately this can't be an
* enum as we have to plugin 3rd party frameworks dynamically
*/
fun getTags(node: T): Set<String>
}

View File

@@ -8,6 +8,7 @@
package com.facebook.flipper.plugins.uidebugger.descriptors
import com.facebook.flipper.plugins.uidebugger.common.InspectableObject
import com.facebook.flipper.plugins.uidebugger.model.Bounds
object ObjectDescriptor : NodeDescriptor<Any> {
@@ -24,4 +25,7 @@ object ObjectDescriptor : NodeDescriptor<Any> {
override fun getChildren(node: Any) = listOf<Any>()
override fun getData(node: Any) = mutableMapOf<SectionName, InspectableObject>()
override fun getBounds(node: Any): Bounds? = null
override fun getTags(node: Any): Set<String> = setOf(BaseTags.Unknown)
}

View File

@@ -21,6 +21,7 @@ import com.facebook.flipper.plugins.uidebugger.common.EnumMapping
import com.facebook.flipper.plugins.uidebugger.common.Inspectable
import com.facebook.flipper.plugins.uidebugger.common.InspectableObject
import com.facebook.flipper.plugins.uidebugger.common.InspectableValue
import com.facebook.flipper.plugins.uidebugger.model.Bounds
import com.facebook.flipper.plugins.uidebugger.util.ResourcesUtil
import java.lang.reflect.Field
@@ -34,6 +35,12 @@ object ViewDescriptor : ChainedDescriptor<View>() {
return node.javaClass.simpleName
}
override fun onGetBounds(node: View): Bounds {
return Bounds(node.left, node.top, node.width, node.height)
}
override fun onGetTags(node: View): Set<String> = setOf(BaseTags.Native, BaseTags.Android)
override fun onGetData(
node: View,
attributeSections: MutableMap<SectionName, InspectableObject>
@@ -50,7 +57,7 @@ object ViewDescriptor : ChainedDescriptor<View>() {
fromDrawable(node.background)?.let { props["background"] = it }
node.tag?.let { InspectableValue.fromAny(it, mutable = false) }?.let { props.put("tag", it) }
props["keyedTags"] = InspectableObject(getTags(node))
props["keyedTags"] = InspectableObject(getViewTags(node))
props["layoutParams"] = getLayoutParams(node)
props["state"] =
InspectableObject(
@@ -136,7 +143,7 @@ object ViewDescriptor : ChainedDescriptor<View>() {
return InspectableObject(params)
}
private fun getTags(node: View): MutableMap<String, Inspectable> {
private fun getViewTags(node: View): MutableMap<String, Inspectable> {
val tags = mutableMapOf<String, Inspectable>()
KeyedTagsField?.let { field ->

View File

@@ -14,6 +14,11 @@ data class Node(
val id: String,
val name: String,
val attributes: Map<String, InspectableObject>,
val bounds: Bounds?,
val tags: Set<String>,
val children: List<String>,
val activeChild: String?,
)
@kotlinx.serialization.Serializable
data class Bounds(val x: Int, val y: Int, val width: Int, val height: Int)

View File

@@ -70,12 +70,16 @@ class PartialLayoutTraversal(
}
val attributes = descriptor.getData(node)
val bounds = descriptor.getBounds(node)
val tags = descriptor.getTags(node)
visited.add(
Node(
descriptor.getId(node),
descriptor.getName(node),
attributes,
bounds,
tags,
childrenIds,
activeChildId))
} catch (exception: Exception) {