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 deleted file mode 100644 index 7776fbada..000000000 --- a/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/LithoDescriptors.kt +++ /dev/null @@ -1,119 +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.litho - -import android.graphics.Bitmap -import com.facebook.flipper.plugins.uidebugger.common.InspectableObject -import com.facebook.flipper.plugins.uidebugger.descriptors.BaseTags -import com.facebook.flipper.plugins.uidebugger.descriptors.DescriptorRegister -import com.facebook.flipper.plugins.uidebugger.descriptors.NodeDescriptor -import com.facebook.flipper.plugins.uidebugger.descriptors.SectionName -import com.facebook.flipper.plugins.uidebugger.model.Bounds -import com.facebook.litho.DebugComponent -import com.facebook.litho.LithoView - -object LithoViewDescriptor : NodeDescriptor { - - override fun getName(node: LithoView): String = "LithoView" - - override fun getChildren(node: LithoView): List { - val result = mutableListOf() - val debugComponent = DebugComponent.getRootInstance(node) - if (debugComponent != null) { - result.add(debugComponent) - } - return result - } - - 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() - - override fun getSnapshot(node: LithoView, bitmap: Bitmap?): Bitmap? = null -} - -const val LithoTag = "Litho" - -/** a drawable or view that is mounted, along with the correct descriptor */ -class MountedObject(val obj: Any, val descriptor: NodeDescriptor) - -object MountedObjectDescriptor : NodeDescriptor { - - override fun getBounds(node: MountedObject): Bounds? { - val bounds = node.descriptor.getBounds(node.obj) - - /** - * When we ask android for the bounds the x,y offset is w.r.t to the nearest android parent view - * group. From UI debuggers perspective using the raw android offset will double the total - * offset of this native view as the offset is included by the litho components between the - * mounted view and its native parent - */ - return bounds?.copy(x = 0, y = 0) - } - - override fun getName(node: MountedObject): String = node.descriptor.getName(node.obj) - - override fun getChildren(node: MountedObject): List = node.descriptor.getChildren(node.obj) - - override fun getActiveChild(node: MountedObject): Any? = node.descriptor.getActiveChild(node.obj) - - override fun getData(node: MountedObject): Map = - node.descriptor.getData(node.obj) - - override fun getTags(node: MountedObject): Set = node.descriptor.getTags(node.obj) - - override fun getSnapshot(node: MountedObject, bitmap: Bitmap?): Bitmap? = - node.descriptor.getSnapshot(node.obj, bitmap) -} - -class DebugComponentDescriptor(private val register: DescriptorRegister) : - NodeDescriptor { - - override fun getName(node: DebugComponent): String { - return node.component.simpleName - } - - override fun getChildren(node: DebugComponent): List { - val result = mutableListOf() - - val mountedView = node.mountedView - val mountedDrawable = node.mountedDrawable - - if (mountedView != null) { - val descriptor: NodeDescriptor = register.descriptorForClassUnsafe(mountedView.javaClass) - result.add(MountedObject(mountedView, descriptor)) - } else if (mountedDrawable != null) { - val descriptor: NodeDescriptor = - register.descriptorForClassUnsafe(mountedDrawable.javaClass) - result.add(MountedObject(mountedDrawable, descriptor)) - } else { - for (child in node.childComponents) { - result.add(child) - } - } - - return result - } - - 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) - - override fun getSnapshot(node: DebugComponent, bitmap: Bitmap?): Bitmap? = null -} diff --git a/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/UIDebuggerLithoSupport.kt b/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/UIDebuggerLithoSupport.kt index 38c982cb4..069bb6c66 100644 --- a/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/UIDebuggerLithoSupport.kt +++ b/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/UIDebuggerLithoSupport.kt @@ -8,15 +8,22 @@ package com.facebook.flipper.plugins.uidebugger.litho import com.facebook.flipper.plugins.uidebugger.descriptors.DescriptorRegister +import com.facebook.flipper.plugins.uidebugger.litho.descriptors.* import com.facebook.flipper.plugins.uidebugger.observers.TreeObserverFactory import com.facebook.litho.DebugComponent import com.facebook.litho.LithoView +import com.facebook.litho.MatrixDrawable +import com.facebook.litho.widget.TextDrawable + +const val LithoTag = "Litho" object UIDebuggerLithoSupport { fun addDescriptors(register: DescriptorRegister) { register.register(LithoView::class.java, LithoViewDescriptor) register.register(DebugComponent::class.java, DebugComponentDescriptor(register)) + register.register(TextDrawable::class.java, TextDrawableDescriptor) + register.register(MatrixDrawable::class.java, MatrixDrawableDescriptor) } fun addObserver(observerFactory: TreeObserverFactory) { diff --git a/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/descriptors/DebugComponentDescriptor.kt b/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/descriptors/DebugComponentDescriptor.kt new file mode 100644 index 000000000..50fc8d5dc --- /dev/null +++ b/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/descriptors/DebugComponentDescriptor.kt @@ -0,0 +1,64 @@ +/* + * 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.litho.descriptors + +import android.graphics.Bitmap +import com.facebook.flipper.plugins.uidebugger.common.InspectableObject +import com.facebook.flipper.plugins.uidebugger.descriptors.BaseTags +import com.facebook.flipper.plugins.uidebugger.descriptors.DescriptorRegister +import com.facebook.flipper.plugins.uidebugger.descriptors.NodeDescriptor +import com.facebook.flipper.plugins.uidebugger.descriptors.OffsetChild +import com.facebook.flipper.plugins.uidebugger.litho.LithoTag +import com.facebook.flipper.plugins.uidebugger.model.Bounds +import com.facebook.litho.DebugComponent + +class DebugComponentDescriptor(val register: DescriptorRegister) : NodeDescriptor { + + override fun getName(node: DebugComponent): String { + return node.component.simpleName + } + + override fun getChildren(node: DebugComponent): List { + val result = mutableListOf() + + val mountedView = node.mountedView + val mountedDrawable = node.mountedDrawable + + if (mountedView != null) { + val descriptor: NodeDescriptor = register.descriptorForClassUnsafe(mountedView.javaClass) + /** + * When we ask android for the bounds the x,y offset is w.r.t to the nearest android parent + * view group. From UI debuggers perspective using the raw android offset will double the + * total offset of this native view as the offset is included by the litho components between + * the mounted view and its native parent + */ + result.add(OffsetChild.zero(mountedView, descriptor)) + } else if (mountedDrawable != null) { + val descriptor: NodeDescriptor = + register.descriptorForClassUnsafe(mountedDrawable.javaClass) + // same here + result.add(OffsetChild.zero(mountedDrawable, descriptor)) + } else { + for (child in node.childComponents) { + result.add(child) + } + } + + return result + } + + override fun getActiveChild(node: DebugComponent): Any? = null + + override fun getData(node: DebugComponent) = mapOf() + + override fun getBounds(node: DebugComponent): Bounds = Bounds.fromRect(node.bounds) + + override fun getTags(node: DebugComponent): Set = setOf(BaseTags.Declarative, LithoTag) + + override fun getSnapshot(node: DebugComponent, bitmap: Bitmap?): Bitmap? = null +} diff --git a/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/descriptors/LithoViewDescriptor.kt b/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/descriptors/LithoViewDescriptor.kt new file mode 100644 index 000000000..91cd41273 --- /dev/null +++ b/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/descriptors/LithoViewDescriptor.kt @@ -0,0 +1,41 @@ +/* + * 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.litho.descriptors + +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.descriptors.ChainedDescriptor +import com.facebook.flipper.plugins.uidebugger.descriptors.SectionName +import com.facebook.litho.DebugComponent +import com.facebook.litho.LithoView + +object LithoViewDescriptor : ChainedDescriptor() { + + override fun onGetName(node: LithoView): String = node.javaClass.simpleName + + override fun onGetChildren(node: LithoView): List? { + val result = mutableListOf() + val debugComponent = DebugComponent.getRootInstance(node) + if (debugComponent != null) { + result.add(debugComponent) + } + return result + } + + override fun onGetData( + node: LithoView, + attributeSections: MutableMap + ) { + attributeSections["Litho"] = + InspectableObject( + mapOf( + "isIncrementalMountEnabled" to + InspectableValue.Boolean(node.isIncrementalMountEnabled, false))) + } +} diff --git a/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/descriptors/MatrixDrawableDescriptor.kt b/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/descriptors/MatrixDrawableDescriptor.kt new file mode 100644 index 000000000..f6368c200 --- /dev/null +++ b/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/descriptors/MatrixDrawableDescriptor.kt @@ -0,0 +1,24 @@ +/* + * 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.litho.descriptors + +import com.facebook.flipper.plugins.uidebugger.descriptors.ChainedDescriptor +import com.facebook.litho.MatrixDrawable + +object MatrixDrawableDescriptor : ChainedDescriptor>() { + + override fun onGetChildren(node: MatrixDrawable<*>): List? { + val mountedDrawable = node.mountedDrawable + return if (mountedDrawable != null) { + listOf(mountedDrawable) + } else { + listOf() + } + } + override fun onGetName(node: MatrixDrawable<*>): String = node.javaClass.simpleName +} diff --git a/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/descriptors/MountedDawable.kt b/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/descriptors/MountedDawable.kt new file mode 100644 index 000000000..5205e0db2 --- /dev/null +++ b/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/descriptors/MountedDawable.kt @@ -0,0 +1,45 @@ +/* + * 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.litho.descriptors + +import android.graphics.Bitmap +import com.facebook.flipper.plugins.uidebugger.common.InspectableObject +import com.facebook.flipper.plugins.uidebugger.descriptors.* +import com.facebook.flipper.plugins.uidebugger.model.Bounds + +/** a drawable or view that is mounted, along with the correct descriptor */ +class MountedObject(val obj: Any, val descriptor: NodeDescriptor) + +object MountedObjectDescriptor : NodeDescriptor { + + override fun getBounds(node: MountedObject): Bounds? { + val bounds = node.descriptor.getBounds(node.obj) + + /** + * When we ask android for the bounds the x,y offset is w.r.t to the nearest android parent view + * group. From UI debuggers perspective using the raw android offset will double the total + * offset of this native view as the offset is included by the litho components between the + * mounted view and its native parent + */ + return bounds?.copy(x = 0, y = 0) + } + + override fun getName(node: MountedObject): String = node.descriptor.getName(node.obj) + + override fun getChildren(node: MountedObject): List = node.descriptor.getChildren(node.obj) + + override fun getActiveChild(node: MountedObject): Any? = node.descriptor.getActiveChild(node.obj) + + override fun getData(node: MountedObject): Map = + node.descriptor.getData(node.obj) + + override fun getTags(node: MountedObject): Set = node.descriptor.getTags(node.obj) + + override fun getSnapshot(node: MountedObject, bitmap: Bitmap?): Bitmap? = + node.descriptor.getSnapshot(node.obj, bitmap) +} diff --git a/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/descriptors/TextDrawableDescriptor.kt b/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/descriptors/TextDrawableDescriptor.kt new file mode 100644 index 000000000..8154dd97e --- /dev/null +++ b/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/descriptors/TextDrawableDescriptor.kt @@ -0,0 +1,30 @@ +/* + * 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.litho.descriptors + +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.descriptors.ChainedDescriptor +import com.facebook.flipper.plugins.uidebugger.descriptors.SectionName +import com.facebook.litho.widget.TextDrawable + +object TextDrawableDescriptor : ChainedDescriptor() { + override fun onGetName(node: TextDrawable): String = node.javaClass.simpleName + + override fun onGetData( + node: TextDrawable, + attributeSections: MutableMap + ) { + + val props = + mapOf("text" to InspectableValue.Text(node.text.toString(), false)) + + attributeSections["TextDrawable"] = InspectableObject(props) + } +} 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 ed23555c3..0827f6ab2 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 @@ -7,6 +7,7 @@ package com.facebook.flipper.plugins.uidebugger.model +import android.graphics.Rect import com.facebook.flipper.plugins.uidebugger.common.InspectableObject import com.facebook.flipper.plugins.uidebugger.descriptors.Id @@ -22,4 +23,10 @@ data class Node( ) @kotlinx.serialization.Serializable -data class Bounds(val x: Int, val y: Int, val width: Int, val height: Int) +data class Bounds(val x: Int, val y: Int, val width: Int, val height: Int) { + companion object { + fun fromRect(rect: Rect): Bounds { + return Bounds(rect.left, rect.top, rect.width(), rect.height()) + } + } +}