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 5bff01a95..7776fbada 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 @@ -7,6 +7,7 @@ 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 @@ -36,6 +37,8 @@ object LithoViewDescriptor : NodeDescriptor { 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" @@ -67,9 +70,13 @@ object MountedObjectDescriptor : NodeDescriptor { 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(val register: DescriptorRegister) : NodeDescriptor { +class DebugComponentDescriptor(private val register: DescriptorRegister) : + NodeDescriptor { override fun getName(node: DebugComponent): String { return node.component.simpleName @@ -100,10 +107,13 @@ class DebugComponentDescriptor(val register: DescriptorRegister) : NodeDescripto 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/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 b3a96e039..ffdf7163d 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 @@ -7,6 +7,7 @@ package com.facebook.flipper.plugins.uidebugger.descriptors +import android.graphics.Bitmap import com.facebook.flipper.plugins.uidebugger.common.InspectableObject import com.facebook.flipper.plugins.uidebugger.model.Bounds @@ -101,4 +102,13 @@ abstract class ChainedDescriptor : NodeDescriptor { * own section */ open fun onGetData(node: T, attributeSections: MutableMap) {} + + /** Get a snapshot of the node. */ + final override fun getSnapshot(node: T, bitmap: Bitmap?): Bitmap? { + return onGetSnapshot(node, bitmap) + } + + open fun onGetSnapshot(node: T, bitmap: Bitmap?): Bitmap? { + return null + } } 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 24fedb17b..182094ddc 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 @@ -7,6 +7,7 @@ package com.facebook.flipper.plugins.uidebugger.descriptors +import android.graphics.Bitmap import com.facebook.flipper.plugins.uidebugger.common.InspectableObject import com.facebook.flipper.plugins.uidebugger.model.Bounds @@ -42,6 +43,13 @@ interface NodeDescriptor { /** The children this node exposes in the inspector. */ fun getChildren(node: T): List + /** + * Get a snapshot of the node. Bitmaps are not cheap to create, so accept one as an optional + * parameter. If a bitmap is provided, it will be used by the canvas to draw on it. Otherwise, a + * bitmap will be created. + */ + fun getSnapshot(node: T, bitmap: Bitmap?): Bitmap? + /** * If you have overlapping children this indicates which child is active / on top, we will only * listen to / traverse this child. If return null we assume all children are 'active' 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 48c1d756b..7e9c0a0f3 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 @@ -7,6 +7,7 @@ package com.facebook.flipper.plugins.uidebugger.descriptors +import android.graphics.Bitmap import com.facebook.flipper.plugins.uidebugger.common.InspectableObject import com.facebook.flipper.plugins.uidebugger.model.Bounds @@ -23,5 +24,8 @@ object ObjectDescriptor : NodeDescriptor { override fun getData(node: Any) = mutableMapOf() override fun getBounds(node: Any): Bounds? = null + override fun getTags(node: Any): Set = setOf(BaseTags.Unknown) + + override fun getSnapshot(node: Any, bitmap: Bitmap?): Bitmap? = null } 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 3cc151f4b..7259c4685 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 @@ -8,6 +8,8 @@ package com.facebook.flipper.plugins.uidebugger.descriptors import android.annotation.SuppressLint +import android.graphics.Bitmap +import android.graphics.Canvas import android.graphics.drawable.ColorDrawable import android.graphics.drawable.Drawable import android.os.Build @@ -105,6 +107,26 @@ object ViewDescriptor : ChainedDescriptor() { attributeSections["View"] = InspectableObject(props.toMap()) } + override fun onGetSnapshot(node: View, bitmap: Bitmap?): Bitmap? { + var workingBitmap = bitmap + + try { + if (workingBitmap == null) { + val viewWidth: Int = node.width + val viewHeight: Int = node.height + + workingBitmap = Bitmap.createBitmap(viewWidth, viewHeight, Bitmap.Config.RGB_565) + } + + workingBitmap?.let { b -> + val canvas = Canvas(b) + node.draw(canvas) + } + } catch (e: OutOfMemoryError) {} + + return workingBitmap + } + private fun fromDrawable(d: Drawable?): Inspectable? { return if (d is ColorDrawable) { InspectableValue.Color(d.color, mutable = false)