getSnapshot

Summary:
This change introduces a new Descriptor method to obtain snapshots of an item in the layout hierarchy.

Only implemented by the ViewDescritor but it can be potentially extended to Windows, Fragments, Activities, ...

Reviewed By: LukeDefeo

Differential Revision: D39690548

fbshipit-source-id: cf3a1ccd63eb28c1de328310e8635829a40964dd
This commit is contained in:
Lorenzo Blasa
2022-09-26 06:03:49 -07:00
committed by Facebook GitHub Bot
parent 48f70ef8ec
commit 6f65517933
5 changed files with 55 additions and 1 deletions

View File

@@ -7,6 +7,7 @@
package com.facebook.flipper.plugins.uidebugger.litho 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.common.InspectableObject
import com.facebook.flipper.plugins.uidebugger.descriptors.BaseTags import com.facebook.flipper.plugins.uidebugger.descriptors.BaseTags
import com.facebook.flipper.plugins.uidebugger.descriptors.DescriptorRegister import com.facebook.flipper.plugins.uidebugger.descriptors.DescriptorRegister
@@ -36,6 +37,8 @@ object LithoViewDescriptor : NodeDescriptor<LithoView> {
override fun getBounds(node: LithoView): Bounds? = null override fun getBounds(node: LithoView): Bounds? = null
override fun getTags(node: LithoView): Set<String> = setOf() override fun getTags(node: LithoView): Set<String> = setOf()
override fun getSnapshot(node: LithoView, bitmap: Bitmap?): Bitmap? = null
} }
const val LithoTag = "Litho" const val LithoTag = "Litho"
@@ -67,9 +70,13 @@ object MountedObjectDescriptor : NodeDescriptor<MountedObject> {
node.descriptor.getData(node.obj) node.descriptor.getData(node.obj)
override fun getTags(node: MountedObject): Set<String> = node.descriptor.getTags(node.obj) override fun getTags(node: MountedObject): Set<String> = 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<DebugComponent> { class DebugComponentDescriptor(private val register: DescriptorRegister) :
NodeDescriptor<DebugComponent> {
override fun getName(node: DebugComponent): String { override fun getName(node: DebugComponent): String {
return node.component.simpleName return node.component.simpleName
@@ -100,10 +107,13 @@ class DebugComponentDescriptor(val register: DescriptorRegister) : NodeDescripto
override fun getActiveChild(node: DebugComponent): Any? = null override fun getActiveChild(node: DebugComponent): Any? = null
override fun getData(node: DebugComponent) = mapOf<String, InspectableObject>() override fun getData(node: DebugComponent) = mapOf<String, InspectableObject>()
override fun getBounds(node: DebugComponent): Bounds { override fun getBounds(node: DebugComponent): Bounds {
val bounds = node.bounds val bounds = node.bounds
return Bounds(bounds.left, bounds.top, bounds.width(), bounds.height()) return Bounds(bounds.left, bounds.top, bounds.width(), bounds.height())
} }
override fun getTags(node: DebugComponent): Set<String> = setOf(BaseTags.Declarative, LithoTag) override fun getTags(node: DebugComponent): Set<String> = setOf(BaseTags.Declarative, LithoTag)
override fun getSnapshot(node: DebugComponent, bitmap: Bitmap?): Bitmap? = null
} }

View File

@@ -7,6 +7,7 @@
package com.facebook.flipper.plugins.uidebugger.descriptors 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.common.InspectableObject
import com.facebook.flipper.plugins.uidebugger.model.Bounds import com.facebook.flipper.plugins.uidebugger.model.Bounds
@@ -101,4 +102,13 @@ abstract class ChainedDescriptor<T> : NodeDescriptor<T> {
* own section * own section
*/ */
open fun onGetData(node: T, attributeSections: MutableMap<SectionName, InspectableObject>) {} open fun onGetData(node: T, attributeSections: MutableMap<SectionName, InspectableObject>) {}
/** 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
}
} }

View File

@@ -7,6 +7,7 @@
package com.facebook.flipper.plugins.uidebugger.descriptors 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.common.InspectableObject
import com.facebook.flipper.plugins.uidebugger.model.Bounds import com.facebook.flipper.plugins.uidebugger.model.Bounds
@@ -42,6 +43,13 @@ interface NodeDescriptor<T> {
/** The children this node exposes in the inspector. */ /** The children this node exposes in the inspector. */
fun getChildren(node: T): List<Any> fun getChildren(node: T): List<Any>
/**
* 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 * 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' * listen to / traverse this child. If return null we assume all children are 'active'

View File

@@ -7,6 +7,7 @@
package com.facebook.flipper.plugins.uidebugger.descriptors 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.common.InspectableObject
import com.facebook.flipper.plugins.uidebugger.model.Bounds import com.facebook.flipper.plugins.uidebugger.model.Bounds
@@ -23,5 +24,8 @@ object ObjectDescriptor : NodeDescriptor<Any> {
override fun getData(node: Any) = mutableMapOf<SectionName, InspectableObject>() override fun getData(node: Any) = mutableMapOf<SectionName, InspectableObject>()
override fun getBounds(node: Any): Bounds? = null override fun getBounds(node: Any): Bounds? = null
override fun getTags(node: Any): Set<String> = setOf(BaseTags.Unknown) override fun getTags(node: Any): Set<String> = setOf(BaseTags.Unknown)
override fun getSnapshot(node: Any, bitmap: Bitmap?): Bitmap? = null
} }

View File

@@ -8,6 +8,8 @@
package com.facebook.flipper.plugins.uidebugger.descriptors package com.facebook.flipper.plugins.uidebugger.descriptors
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.drawable.ColorDrawable import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.os.Build import android.os.Build
@@ -105,6 +107,26 @@ object ViewDescriptor : ChainedDescriptor<View>() {
attributeSections["View"] = InspectableObject(props.toMap()) 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? { private fun fromDrawable(d: Drawable?): Inspectable? {
return if (d is ColorDrawable) { return if (d is ColorDrawable) {
InspectableValue.Color(d.color, mutable = false) InspectableValue.Color(d.color, mutable = false)