Addresses a few issues with the Stetho fragment utilities

Summary:
There is a bug in the code to get fragments from the activity.

A boolean, result from the comparison, was added to the list instead of the actual fragments.

Reviewed By: LukeDefeo

Differential Revision: D39348019

fbshipit-source-id: 669f304055f15f59b40352d86f25d768d92df76e
This commit is contained in:
Lorenzo Blasa
2022-09-12 04:20:01 -07:00
committed by Facebook GitHub Bot
parent 4436128d07
commit ed40e16ac9
7 changed files with 45 additions and 37 deletions

View File

@@ -24,12 +24,12 @@ object ActivityDescriptor : AbstractChainedDescriptor<Activity>() {
override fun onGetChildren(activity: Activity, children: MutableList<Any>) {
activity.window?.let { window -> children.add(activity.window) }
var fragments = getFragments(FragmentCompat.supportInstance, activity)
var fragments = getDialogFragments(FragmentCompat.supportInstance, activity)
for (fragment in fragments) {
children.add(fragment)
}
fragments = getFragments(FragmentCompat.frameworkInstance, activity)
fragments = getDialogFragments(FragmentCompat.frameworkInstance, activity)
for (fragment in fragments) {
children.add(fragment)
}
@@ -40,11 +40,14 @@ object ActivityDescriptor : AbstractChainedDescriptor<Activity>() {
attributeSections: MutableMap<String, InspectableObject>
) {}
private fun getFragments(compat: FragmentCompat<*, *, *, *>?, activity: Activity): List<Any> {
private fun getDialogFragments(
compat: FragmentCompat<*, *, *, *>?,
activity: Activity
): List<Any> {
if (compat == null) {
return emptyList()
}
return compat?.getFragments(activity)
return compat.getDialogFragments(activity)
}
}

View File

@@ -103,7 +103,7 @@ abstract class FragmentCompat<
abstract fun forFragmentManager(): FragmentManagerAccessor<FRAGMENT_MANAGER, FRAGMENT>?
abstract fun forFragmentActivity(): FragmentActivityAccessor<FRAGMENT_ACTIVITY, FRAGMENT_MANAGER>?
abstract fun getFragments(activity: Activity): List<Any>
abstract fun getDialogFragments(activity: Activity): List<Any>
abstract fun findFragmentForViewInActivity(activity: Activity, view: View): Any?
abstract fun findFragmentForViewInFragment(fragment: Any, view: View): Any?
@@ -117,12 +117,10 @@ abstract class FragmentCompat<
if (fieldMAdded == null) {
fragmentManager?.let { manager ->
val field = manager::class.java.getDeclaredField("mAdded")
if (field != null) {
field.isAccessible = true
fieldMAdded = field
}
}
}
fieldMAdded?.let { field ->
return getFieldValue(field, fragmentManager) as List<FRAGMENT>

View File

@@ -64,7 +64,7 @@ class FragmentCompatFramework :
return fragmentActivityAccessor
}
override fun getFragments(activity: Activity): List<Any> {
override fun getDialogFragments(activity: Activity): List<Any> {
if (!fragmentActivityClass.isInstance(activity)) {
return emptyList()
}
@@ -79,11 +79,13 @@ class FragmentCompatFramework :
} catch (e: Exception) {}
if (addedFragments != null) {
val N = addedFragments.size - 1
val n = addedFragments.size - 1
val dialogFragments = mutableListOf<Any>()
for (i in 0..N) {
for (i in 0..n) {
val fragment = addedFragments[i]
dialogFragmentClass?.isInstance(fragment)?.let { fragment -> dialogFragments.add(fragment) }
if (fragment != null && dialogFragmentClass.isInstance(fragment)) {
dialogFragments.add(fragment)
}
}
return dialogFragments
}
@@ -113,8 +115,8 @@ class FragmentCompatFramework :
} catch (e: Exception) {}
if (fragments != null) {
val N = fragments.size - 1
for (i in 0..N) {
val n = fragments.size - 1
for (i in 0..n) {
val fragment = fragments[i]
val result = findFragmentForViewInFragment(fragment, view)
if (result != null) {

View File

@@ -41,7 +41,7 @@ class FragmentCompatSupportLib :
return fragmentActivityAccessor
}
override fun getFragments(activity: Activity): List<Any> {
override fun getDialogFragments(activity: Activity): List<Any> {
if (!fragmentActivityClass.isInstance(activity)) {
return emptyList()
}
@@ -57,11 +57,13 @@ class FragmentCompatSupportLib :
} catch (e: Exception) {}
if (addedFragments != null) {
val N = addedFragments.size - 1
val n = addedFragments.size - 1
val dialogFragments = mutableListOf<Any>()
for (i in 0..N) {
for (i in 0..n) {
val fragment = addedFragments[i]
dialogFragmentClass?.isInstance(fragment)?.let { fragment -> dialogFragments.add(fragment) }
if (fragment != null && dialogFragmentClass.isInstance(fragment)) {
dialogFragments.add(fragment)
}
}
return dialogFragments
}
@@ -92,8 +94,8 @@ class FragmentCompatSupportLib :
} catch (e: Exception) {}
if (fragments != null) {
val N = fragments.size - 1
for (i in 0..N) {
val n = fragments.size - 1
for (i in 0..n) {
val fragment = fragments[i]
val result = findFragmentForViewInFragment(fragment, view)
if (result != null) {

View File

@@ -10,7 +10,7 @@ package com.facebook.flipper.plugins.uidebugger.stetho
import java.lang.reflect.Field
object ReflectionUtil {
inline fun tryGetClassForName(className: String): Class<*>? {
fun tryGetClassForName(className: String): Class<*>? {
return try {
Class.forName(className)
} catch (e: ClassNotFoundException) {
@@ -18,7 +18,7 @@ object ReflectionUtil {
}
}
inline fun tryGetDeclaredField(theClass: Class<*>, fieldName: String): Field? {
fun tryGetDeclaredField(theClass: Class<*>, fieldName: String): Field? {
return try {
theClass.getDeclaredField(fieldName)
} catch (e: NoSuchFieldException) {
@@ -26,7 +26,7 @@ object ReflectionUtil {
}
}
inline fun getFieldValue(field: Field, target: Any?): Any? {
fun getFieldValue(field: Field, target: Any?): Any? {
return try {
field[target]
} catch (e: IllegalAccessException) {

View File

@@ -14,11 +14,10 @@ import javax.annotation.Nonnull
object ResourcesUtil {
@Nonnull
fun getIdStringQuietly(idContext: Any, r: Resources?, resourceId: Int): String {
try {
return getIdString(r, resourceId)
return try {
getIdString(r, resourceId)
} catch (e: NotFoundException) {
val idString = getFallbackIdString(resourceId)
return idString
getFallbackIdString(resourceId)
}
}

View File

@@ -31,17 +31,21 @@ object ViewUtil {
}
private fun tryGetActivity(context: Context): Activity? {
var context: Context? = context
while (context != null) {
context =
if (context is Activity) {
return context
} else if (context is ContextWrapper) {
context.baseContext
} else {
var ctx: Context? = context
while (ctx != null) {
ctx =
when (ctx) {
is Activity -> {
return ctx
}
is ContextWrapper -> {
ctx.baseContext
}
else -> {
return null
}
}
}
return null
}
}