Descriptor clean up

Summary:
Now that we have the tree observer we can make descriptors completely about describing an object. To that end we have removed init method and made them all object to indicate to future readers their singleton nature.

onGetActive child was made open instead of abstract to avoid needed to override in all subclasses

Reviewed By: lblasa

Differential Revision: D39387935

fbshipit-source-id: 802b8afdd9aa639daecf10d774ca5b960ee48003
This commit is contained in:
Luke De Feo
2022-09-12 03:48:43 -07:00
committed by Facebook GitHub Bot
parent 9a270cdc7a
commit 4436128d07
12 changed files with 52 additions and 104 deletions

View File

@@ -26,14 +26,6 @@ abstract class AbstractChainedDescriptor<T> : Descriptor<T>(), ChainedDescriptor
return mSuper
}
/** Initialize a descriptor. */
final override fun init() {
mSuper?.init()
onInit()
}
open fun onInit() {}
final override fun getActiveChild(node: T): Any? {
// ask each descriptor in the chain for an active child, if none available look up the chain
// until no more super descriptors
@@ -58,7 +50,7 @@ abstract class AbstractChainedDescriptor<T> : Descriptor<T>(), ChainedDescriptor
return onGetName(node)
}
abstract fun onGetActiveChild(node: T): Any?
open fun onGetActiveChild(node: T): Any? = null
abstract fun onGetName(node: T): String

View File

@@ -11,11 +11,7 @@ import android.app.Activity
import com.facebook.flipper.plugins.uidebugger.common.InspectableObject
import com.facebook.flipper.plugins.uidebugger.stetho.FragmentCompat
class ActivityDescriptor : AbstractChainedDescriptor<Activity>() {
override fun onInit() {}
override fun onGetActiveChild(node: Activity): Any? {
return null
}
object ActivityDescriptor : AbstractChainedDescriptor<Activity>() {
override fun onGetId(activity: Activity): String {
return Integer.toString(System.identityHashCode(activity))

View File

@@ -8,12 +8,10 @@
package com.facebook.flipper.plugins.uidebugger.descriptors
import android.app.Activity
import com.facebook.flipper.plugins.uidebugger.common.InspectableObject
import com.facebook.flipper.plugins.uidebugger.core.ApplicationRef
class ApplicationRefDescriptor : AbstractChainedDescriptor<ApplicationRef>() {
object ApplicationRefDescriptor : AbstractChainedDescriptor<ApplicationRef>() {
override fun onInit() {}
override fun onGetActiveChild(node: ApplicationRef): Any? {
return if (node.activitiesStack.size > 0) node.activitiesStack.last() else null
}
@@ -34,9 +32,4 @@ class ApplicationRefDescriptor : AbstractChainedDescriptor<ApplicationRef>() {
children.add(activity)
}
}
override fun onGetData(
applicationRef: ApplicationRef,
attributeSections: MutableMap<String, InspectableObject>
) {}
}

View File

@@ -10,7 +10,7 @@ package com.facebook.flipper.plugins.uidebugger.descriptors
import android.widget.Button
import com.facebook.flipper.plugins.uidebugger.common.InspectableObject
class ButtonDescriptor : AbstractChainedDescriptor<Button>() {
object ButtonDescriptor : AbstractChainedDescriptor<Button>() {
override fun onGetId(button: Button): String {
return Integer.toString(System.identityHashCode(button))
@@ -24,9 +24,4 @@ class ButtonDescriptor : AbstractChainedDescriptor<Button>() {
button: Button,
attributeSections: MutableMap<String, InspectableObject>
) {}
override fun onGetChildren(button: Button, children: MutableList<Any>) {}
override fun onGetActiveChild(node: Button): Any? {
return null
}
}

View File

@@ -24,15 +24,15 @@ class DescriptorRegister {
fun withDefaults(): DescriptorRegister {
val mapping = DescriptorRegister()
mapping.register(Any::class.java, ObjectDescriptor())
mapping.register(ApplicationRef::class.java, ApplicationRefDescriptor())
mapping.register(Activity::class.java, ActivityDescriptor())
mapping.register(Window::class.java, WindowDescriptor())
mapping.register(ViewGroup::class.java, ViewGroupDescriptor())
mapping.register(View::class.java, ViewDescriptor())
mapping.register(TextView::class.java, TextViewDescriptor())
mapping.register(Button::class.java, ButtonDescriptor())
mapping.register(ViewPager::class.java, ViewPagerDescriptor())
mapping.register(Any::class.java, ObjectDescriptor)
mapping.register(ApplicationRef::class.java, ApplicationRefDescriptor)
mapping.register(Activity::class.java, ActivityDescriptor)
mapping.register(Window::class.java, WindowDescriptor)
mapping.register(ViewGroup::class.java, ViewGroupDescriptor)
mapping.register(View::class.java, ViewDescriptor)
mapping.register(TextView::class.java, TextViewDescriptor)
mapping.register(Button::class.java, ButtonDescriptor)
mapping.register(ViewPager::class.java, ViewPagerDescriptor)
for (clazz in mapping.register.keys) {
val descriptor: Descriptor<*>? = mapping.register[clazz]

View File

@@ -9,10 +9,14 @@ package com.facebook.flipper.plugins.uidebugger.descriptors
import com.facebook.flipper.plugins.uidebugger.common.InspectableObject
interface NodeDescriptor<T> {
/** Initialize a descriptor. */
fun init()
/*
Descriptors are an extension point used during traversal to extract data out of arbitary
objects in the hierachy. Descriptors can represent native view or declarative components or
any type of object such as an activity
Descriptors should be stateless and each descriptor should be a singleton
*/
interface NodeDescriptor<T> {
/**
* A globally unique ID used to identify a node in a hierarchy. If your node does not have a
* globally unique ID it is fine to rely on [System.identityHashCode].

View File

@@ -9,11 +9,9 @@ package com.facebook.flipper.plugins.uidebugger.descriptors
import com.facebook.flipper.plugins.uidebugger.common.InspectableObject
class ObjectDescriptor : Descriptor<Any>() {
override fun init() {}
override fun getActiveChild(node: Any): Any? {
return null
}
object ObjectDescriptor : Descriptor<Any>() {
override fun getActiveChild(node: Any): Any? = null
override fun getId(obj: Any): String {
return Integer.toString(System.identityHashCode(obj))

View File

@@ -10,7 +10,7 @@ package com.facebook.flipper.plugins.uidebugger.descriptors
import android.widget.TextView
import com.facebook.flipper.plugins.uidebugger.common.InspectableObject
class TextViewDescriptor : AbstractChainedDescriptor<TextView>() {
object TextViewDescriptor : AbstractChainedDescriptor<TextView>() {
override fun onGetId(textView: TextView): String {
return Integer.toString(System.identityHashCode(textView))
@@ -20,14 +20,8 @@ class TextViewDescriptor : AbstractChainedDescriptor<TextView>() {
return textView.javaClass.simpleName
}
override fun onGetChildren(textView: TextView, children: MutableList<Any>) {}
override fun onGetData(
textView: TextView,
attributeSections: MutableMap<String, InspectableObject>
) {}
override fun onGetActiveChild(node: TextView): Any? {
return null
}
}

View File

@@ -22,7 +22,7 @@ import com.facebook.flipper.plugins.uidebugger.common.InspectableValue
import com.facebook.flipper.plugins.uidebugger.stetho.ResourcesUtil
import java.lang.reflect.Field
class ViewDescriptor : AbstractChainedDescriptor<View>() {
object ViewDescriptor : AbstractChainedDescriptor<View>() {
override fun onGetId(view: View): String {
return Integer.toBinaryString(System.identityHashCode(view))
@@ -32,8 +32,6 @@ class ViewDescriptor : AbstractChainedDescriptor<View>() {
return view.javaClass.simpleName
}
override fun onGetChildren(view: View, children: MutableList<Any>) {}
override fun onGetData(view: View, attributeSections: MutableMap<String, InspectableObject>) {
val positionOnScreen = IntArray(2)
view.getLocationOnScreen(positionOnScreen)
@@ -239,25 +237,19 @@ class ViewDescriptor : AbstractChainedDescriptor<View>() {
"FILL_HORIZONTAL" to Gravity.FILL_HORIZONTAL,
)) {}
companion object {
private var KeyedTagsField: Field? = null
private var ListenerInfoField: Field? = null
private var OnClickListenerField: Field? = null
private var KeyedTagsField: Field? = null
private var ListenerInfoField: Field? = null
private var OnClickListenerField: Field? = null
init {
try {
KeyedTagsField = View::class.java.getDeclaredField("mKeyedTags")
KeyedTagsField?.let { field -> field.isAccessible = true }
ListenerInfoField = View::class.java.getDeclaredField("mListenerInfo")
ListenerInfoField?.let { field -> field.isAccessible = true }
val viewInfoClassName = View::class.java.name + "\$ListenerInfo"
OnClickListenerField = Class.forName(viewInfoClassName).getDeclaredField("mOnClickListener")
OnClickListenerField?.let { field -> field.isAccessible = true }
} catch (ignored: Exception) {}
}
}
override fun onGetActiveChild(node: View): Any? {
return null
init {
try {
KeyedTagsField = View::class.java.getDeclaredField("mKeyedTags")
KeyedTagsField?.let { field -> field.isAccessible = true }
ListenerInfoField = View::class.java.getDeclaredField("mListenerInfo")
ListenerInfoField?.let { field -> field.isAccessible = true }
val viewInfoClassName = View::class.java.name + "\$ListenerInfo"
OnClickListenerField = Class.forName(viewInfoClassName).getDeclaredField("mOnClickListener")
OnClickListenerField?.let { field -> field.isAccessible = true }
} catch (ignored: Exception) {}
}
}

View File

@@ -18,7 +18,7 @@ import com.facebook.flipper.plugins.uidebugger.common.InspectableObject
import com.facebook.flipper.plugins.uidebugger.common.InspectableValue
import com.facebook.flipper.plugins.uidebugger.stetho.FragmentCompat
class ViewGroupDescriptor : AbstractChainedDescriptor<ViewGroup>() {
object ViewGroupDescriptor : AbstractChainedDescriptor<ViewGroup>() {
override fun onGetId(viewGroup: ViewGroup): String {
return Integer.toString(System.identityHashCode(viewGroup))
@@ -69,24 +69,18 @@ class ViewGroupDescriptor : AbstractChainedDescriptor<ViewGroup>() {
"LAYOUT_MODE_OPTICAL_BOUNDS" to ViewGroupCompat.LAYOUT_MODE_OPTICAL_BOUNDS,
)) {}
companion object {
private fun getAttachedFragmentForView(v: View): Any? {
return try {
val fragment = FragmentCompat.findFragmentForView(v)
var added = false
if (fragment is Fragment) {
added = fragment.isAdded
} else if (fragment is androidx.fragment.app.Fragment) {
added = fragment.isAdded
}
if (added) fragment else null
} catch (e: RuntimeException) {
null
private fun getAttachedFragmentForView(v: View): Any? {
return try {
val fragment = FragmentCompat.findFragmentForView(v)
var added = false
if (fragment is Fragment) {
added = fragment.isAdded
} else if (fragment is androidx.fragment.app.Fragment) {
added = fragment.isAdded
}
if (added) fragment else null
} catch (e: RuntimeException) {
null
}
}
override fun onGetActiveChild(node: ViewGroup): Any? {
return null
}
}

View File

@@ -9,7 +9,7 @@ package com.facebook.flipper.plugins.uidebugger.descriptors
import androidx.viewpager.widget.ViewPager
class ViewPagerDescriptor : AbstractChainedDescriptor<ViewPager>() {
object ViewPagerDescriptor : AbstractChainedDescriptor<ViewPager>() {
override fun onGetId(node: ViewPager): String = System.identityHashCode(node).toString()

View File

@@ -8,9 +8,8 @@
package com.facebook.flipper.plugins.uidebugger.descriptors
import android.view.Window
import com.facebook.flipper.plugins.uidebugger.common.InspectableObject
class WindowDescriptor : AbstractChainedDescriptor<Window>() {
object WindowDescriptor : AbstractChainedDescriptor<Window>() {
override fun onGetId(window: Window): String {
return Integer.toString(System.identityHashCode(window))
@@ -23,13 +22,4 @@ class WindowDescriptor : AbstractChainedDescriptor<Window>() {
override fun onGetChildren(window: Window, children: MutableList<Any>) {
children.add(window.decorView)
}
override fun onGetData(
window: Window,
attributeSections: MutableMap<String, InspectableObject>
) {}
override fun onGetActiveChild(node: Window): Any? {
return null
}
}