diff --git a/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/LithoDescriptors.kt b/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/LithoDescriptors.kt index 490f00270..c106cee2d 100644 --- a/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/LithoDescriptors.kt +++ b/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/LithoDescriptors.kt @@ -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 { override fun getActiveChild(node: LithoView): Any? = null override fun getData(node: LithoView) = mapOf() + + override fun getBounds(node: LithoView): Bounds? = null + + override fun getTags(node: LithoView): Set = setOf() } +const val LithoTag = "Litho" + object DebugComponentDescriptor : NodeDescriptor { override fun getId(node: DebugComponent): String = System.identityHashCode(node).toString() @@ -60,4 +68,10 @@ object DebugComponentDescriptor : NodeDescriptor { override fun getActiveChild(node: DebugComponent): Any? = null override fun getData(node: DebugComponent) = mapOf() + 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 = setOf(BaseTags.Declarative, LithoTag) } diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/LayoutTraversal.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/LayoutTraversal.kt index 98d4f33e5..c9f6f860c 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/LayoutTraversal.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/LayoutTraversal.kt @@ -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) { diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ApplicationRefDescriptor.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ApplicationRefDescriptor.kt index b9acf0eb5..079a3453b 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ApplicationRefDescriptor.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ApplicationRefDescriptor.kt @@ -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() { @@ -21,6 +23,11 @@ object ApplicationRefDescriptor : ChainedDescriptor() { 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 diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ChainedDescriptor.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ChainedDescriptor.kt index d183c11ac..3d4491a31 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ChainedDescriptor.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ChainedDescriptor.kt @@ -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 : NodeDescriptor { return onGetName(node) } + final override fun getTags(node: T): Set { + val tags = onGetTags(node) ?: mSuper?.getTags(node) + return tags ?: setOf() + } + + open fun onGetTags(node: T): Set? = 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 { val builder = mutableListOf() diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/NodeDescriptor.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/NodeDescriptor.kt index 3d5e9977f..23a95b42a 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/NodeDescriptor.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/NodeDescriptor.kt @@ -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 { /** * 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 { */ 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 { * order and with a header matching the given name. */ fun getData(node: T): Map + + /** + * 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 } diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ObjectDescriptor.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ObjectDescriptor.kt index 0c4fa2144..30fb02b08 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ObjectDescriptor.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ObjectDescriptor.kt @@ -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 { @@ -24,4 +25,7 @@ object ObjectDescriptor : NodeDescriptor { override fun getChildren(node: Any) = listOf() override fun getData(node: Any) = mutableMapOf() + + override fun getBounds(node: Any): Bounds? = null + override fun getTags(node: Any): Set = setOf(BaseTags.Unknown) } diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ViewDescriptor.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ViewDescriptor.kt index 3627c3c49..deb9d4fcd 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ViewDescriptor.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ViewDescriptor.kt @@ -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() { 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 = setOf(BaseTags.Native, BaseTags.Android) + override fun onGetData( node: View, attributeSections: MutableMap @@ -50,7 +57,7 @@ object ViewDescriptor : ChainedDescriptor() { 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() { return InspectableObject(params) } - private fun getTags(node: View): MutableMap { + private fun getViewTags(node: View): MutableMap { val tags = mutableMapOf() KeyedTagsField?.let { field -> diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/model/Node.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/model/Node.kt index 4051252a2..058d8a72b 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/model/Node.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/model/Node.kt @@ -14,6 +14,11 @@ data class Node( val id: String, val name: String, val attributes: Map, + val bounds: Bounds?, + val tags: Set, val children: List, val activeChild: String?, ) + +@kotlinx.serialization.Serializable +data class Bounds(val x: Int, val y: Int, val width: Int, val height: Int) diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/observers/PartialLayoutTraversal.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/observers/PartialLayoutTraversal.kt index 2021d3de4..71e7c4e6e 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/observers/PartialLayoutTraversal.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/observers/PartialLayoutTraversal.kt @@ -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) {