Fix media gallery activity
Summary: Weird edge case, this activity doesnt actualy contain the content and instead its in the decor view behind it, solution is to filter it out from traversal and snapshot https://fb.workplace.com/groups/443457641253219/permalink/643518977913750/ Reviewed By: elboman, lblasa Differential Revision: D50936817 fbshipit-source-id: 8c1e276d4d943c42c9c2085bf70113347cbd5c74
This commit is contained in:
committed by
Facebook GitHub Bot
parent
62e9181075
commit
3bb3ce6a66
@@ -12,6 +12,7 @@ import android.app.Activity
|
|||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
import java.lang.reflect.Field
|
import java.lang.reflect.Field
|
||||||
import java.lang.reflect.Method
|
import java.lang.reflect.Method
|
||||||
@@ -103,6 +104,11 @@ object ActivityTracker : Application.ActivityLifecycleCallbacks {
|
|||||||
return stack
|
return stack
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val decorViewToActivityMap: Map<View, Activity>
|
||||||
|
get() {
|
||||||
|
return activitiesStack.toList().associateBy { it.window.decorView }
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Activity tracker is used to track activities. However, it cannot track via life-cycle events
|
* Activity tracker is used to track activities. However, it cannot track via life-cycle events
|
||||||
* all those activities that were created prior to initialisation via the `start(application:
|
* all those activities that were created prior to initialisation via the `start(application:
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ package com.facebook.flipper.plugins.uidebugger.core
|
|||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
|
import android.view.View
|
||||||
|
|
||||||
class ApplicationRef(val application: Application) {
|
class ApplicationRef(val application: Application) {
|
||||||
init {
|
init {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
package com.facebook.flipper.plugins.uidebugger.core
|
package com.facebook.flipper.plugins.uidebugger.core
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewTreeObserver
|
import android.view.ViewTreeObserver
|
||||||
@@ -58,7 +59,14 @@ class DecorViewTracker(private val context: UIDContext, private val snapshotter:
|
|||||||
currentDecorView?.viewTreeObserver?.removeOnPreDrawListener(preDrawListener)
|
currentDecorView?.viewTreeObserver?.removeOnPreDrawListener(preDrawListener)
|
||||||
|
|
||||||
// setup new listener on top most view, that will be the active child in traversal
|
// setup new listener on top most view, that will be the active child in traversal
|
||||||
val topView = rootViews.lastOrNull(ApplicationRefDescriptor::isUsefulRoot)
|
|
||||||
|
val decorViewToActivity: Map<View, Activity> = ActivityTracker.decorViewToActivityMap
|
||||||
|
|
||||||
|
val topView =
|
||||||
|
rootViews.lastOrNull { view ->
|
||||||
|
val activityOrView = decorViewToActivity[view] ?: view
|
||||||
|
ApplicationRefDescriptor.isUsefulRoot(activityOrView)
|
||||||
|
}
|
||||||
|
|
||||||
if (topView != null) {
|
if (topView != null) {
|
||||||
val throttler =
|
val throttler =
|
||||||
|
|||||||
@@ -104,8 +104,8 @@ class PixelCopySnapshotter(
|
|||||||
bitmap: BitmapPool.ReusableBitmap
|
bitmap: BitmapPool.ReusableBitmap
|
||||||
): Boolean {
|
): Boolean {
|
||||||
|
|
||||||
val decorViewToActivity: Map<View, Activity> =
|
|
||||||
applicationRef.activitiesStack.toList().associateBy { it.window.decorView }
|
val decorViewToActivity: Map<View, Activity> = ActivityTracker.decorViewToActivityMap
|
||||||
|
|
||||||
val activityForDecorView = decorViewToActivity[view] ?: return false
|
val activityForDecorView = decorViewToActivity[view] ?: return false
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ package com.facebook.flipper.plugins.uidebugger.descriptors
|
|||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import com.facebook.flipper.plugins.uidebugger.core.ActivityTracker
|
||||||
import com.facebook.flipper.plugins.uidebugger.core.ApplicationRef
|
import com.facebook.flipper.plugins.uidebugger.core.ApplicationRef
|
||||||
import com.facebook.flipper.plugins.uidebugger.model.Bounds
|
import com.facebook.flipper.plugins.uidebugger.model.Bounds
|
||||||
import com.facebook.flipper.plugins.uidebugger.util.DisplayMetrics
|
import com.facebook.flipper.plugins.uidebugger.util.DisplayMetrics
|
||||||
@@ -33,12 +34,11 @@ object ApplicationRefDescriptor : ChainedDescriptor<ApplicationRef>() {
|
|||||||
override fun onGetChildren(node: ApplicationRef): List<Any> {
|
override fun onGetChildren(node: ApplicationRef): List<Any> {
|
||||||
val children = mutableListOf<Any>()
|
val children = mutableListOf<Any>()
|
||||||
|
|
||||||
val activeRoots = node.rootsResolver.rootViews()
|
val rootViews = node.rootsResolver.rootViews()
|
||||||
|
|
||||||
val decorViewToActivity: Map<View, Activity> =
|
val decorViewToActivity: Map<View, Activity> = ActivityTracker.decorViewToActivityMap
|
||||||
node.activitiesStack.toList().associateBy { it.window.decorView }
|
|
||||||
|
|
||||||
for (root in activeRoots) {
|
for (root in rootViews) {
|
||||||
// if there is an activity for this root view use that,
|
// if there is an activity for this root view use that,
|
||||||
// if not just return the root view that was added directly to the window manager
|
// if not just return the root view that was added directly to the window manager
|
||||||
val activity = decorViewToActivity[root]
|
val activity = decorViewToActivity[root]
|
||||||
@@ -52,16 +52,31 @@ object ApplicationRefDescriptor : ChainedDescriptor<ApplicationRef>() {
|
|||||||
return children
|
return children
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isUsefulRoot(obj: Any): Boolean {
|
/**
|
||||||
if (obj is Activity) {
|
* arg is either an acitivity if the root view has one other views the root view attached to the
|
||||||
|
* window manager returns boolean indicating whether we are interested in it and whether we should
|
||||||
|
* track, traverse and snapshot it
|
||||||
|
*/
|
||||||
|
fun isUsefulRoot(rootViewOrActivity: Any): Boolean {
|
||||||
|
val className = rootViewOrActivity.javaClass.name
|
||||||
|
|
||||||
|
if (className.contains("mediagallery.ui.MediaGalleryActivity")) {
|
||||||
|
// this activity doesn't contain the content and its actually in the decor view behind it, so
|
||||||
|
// skip it :/
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rootViewOrActivity is Activity) {
|
||||||
|
// in general we want views attached to activities
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
val isFoldableOverlayInfraView = javaClass.simpleName.contains("OverlayHandlerView")
|
|
||||||
|
val isFoldableOverlayInfraView = className.contains("OverlayHandlerView")
|
||||||
return if (isFoldableOverlayInfraView) {
|
return if (isFoldableOverlayInfraView) {
|
||||||
false
|
false
|
||||||
} else if (obj is ViewGroup) {
|
} else if (rootViewOrActivity is ViewGroup) {
|
||||||
// sometimes there is a root view on top that has no children that isn't useful to inspect
|
// sometimes there is a root view on top that has no children that isn't useful to inspect
|
||||||
obj.childCount > 0
|
rootViewOrActivity.childCount > 0
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user