@@ -17,6 +17,8 @@ import com.facebook.flipper.plugins.uidebugger.descriptors.ViewDescriptor
17
17
import com.facebook.flipper.plugins.uidebugger.util.StopWatch
18
18
import com.facebook.flipper.plugins.uidebugger.util.Throttler
19
19
import com.facebook.flipper.plugins.uidebugger.util.objectIdentity
20
+ import curtains.Curtains
21
+ import curtains.OnRootViewsChangedListener
20
22
21
23
/* *
22
24
* The UIDebugger does 3 things:
@@ -44,61 +46,66 @@ class DecorViewTracker(private val context: UIDContext, private val snapshotter:
44
46
45
47
fun start () {
46
48
47
- val applicationRef = context.applicationRef
48
-
49
- val rootViewListener =
50
- object : RootViewResolver .Listener {
51
- override fun onRootViewAdded (rootView : View ) {}
52
-
53
- override fun onRootViewRemoved (rootView : View ) {}
54
-
55
- override fun onRootViewsChanged (rootViews : List <View >) {
56
- // remove predraw listen from current view as its going away or will be covered
57
- Log .i(LogTag , " Removing pre draw listener from ${currentDecorView?.objectIdentity()} " )
58
- currentDecorView?.viewTreeObserver?.removeOnPreDrawListener(preDrawListener)
49
+ val rootViewChangedListener = OnRootViewsChangedListener { view, added ->
50
+ if (currentDecorView != null ) {
51
+ // remove predraw listen from current view as its going away or will be covered
52
+ Log .d(LogTag , " Removing pre draw listener from ${currentDecorView?.objectIdentity()} " )
53
+ currentDecorView?.viewTreeObserver?.removeOnPreDrawListener(preDrawListener)
54
+ }
55
+
56
+ val decorViewToActivity: Map <View , Activity > = ActivityTracker .decorViewToActivityMap
57
+
58
+ // at the time of this callback curtains.rootViews is not updated yet, so we need to use the
59
+ // 'view' and 'added' params to the callback to see any new root views
60
+ val topView =
61
+ if (added && ApplicationRefDescriptor .isUsefulRoot(decorViewToActivity[view] ? : view)) {
62
+ view
63
+ } else {
64
+ // this is technically the preview set of root view but this is the branch where the new
65
+ // root view is not 'useful' or we are popping a view off the stack so the old roots are
66
+ // fine here
67
+ Curtains .rootViews.lastOrNull {
68
+ ApplicationRefDescriptor .isUsefulRoot(decorViewToActivity[it] ? : it)
69
+ }
70
+ }
59
71
60
- // setup new listener on top most view, that will be the active child in traversal
72
+ if (topView != null ) {
73
+ val throttler = Throttler (500 ) { currentDecorView?.let { traverseSnapshotAndSend(it) } }
61
74
62
- val decorViewToActivity: Map <View , Activity > = ActivityTracker .decorViewToActivityMap
75
+ preDrawListener =
76
+ ViewTreeObserver .OnPreDrawListener {
77
+ throttler.trigger()
78
+ true
79
+ }
63
80
64
- val topView =
65
- rootViews.lastOrNull { view ->
66
- val activityOrView = decorViewToActivity[view] ? : view
67
- ApplicationRefDescriptor .isUsefulRoot(activityOrView)
68
- }
81
+ topView.viewTreeObserver.addOnPreDrawListener(preDrawListener)
82
+ currentDecorView = topView
69
83
70
- if (topView != null ) {
71
- val throttler =
72
- Throttler (500 ) { currentDecorView?.let { traverseSnapshotAndSend(it) } }
84
+ Log .i(LogTag , " Added pre draw listener to ${topView.objectIdentity()} " )
73
85
74
- preDrawListener =
75
- ViewTreeObserver .OnPreDrawListener {
76
- throttler.trigger()
77
- true
78
- }
86
+ // schedule traversal immediately when we detect a new decor view
87
+ throttler.trigger()
88
+ }
89
+ }
79
90
80
- topView.viewTreeObserver.addOnPreDrawListener(preDrawListener)
81
- currentDecorView = topView
91
+ Curtains .onRootViewsChangedListeners.add(rootViewChangedListener)
82
92
83
- Log .i(LogTag , " Added pre draw listener to ${topView.objectIdentity()} " )
93
+ // On subscribe, trigger a traversal on whatever roots we have
94
+ val decorViewToActivity: Map <View , Activity > = ActivityTracker .decorViewToActivityMap
84
95
85
- // schedule traversal immediately when we detect a new decor view
86
- throttler.trigger()
87
- }
88
- }
96
+ val topView =
97
+ Curtains .rootViews.lastOrNull {
98
+ ApplicationRefDescriptor .isUsefulRoot(decorViewToActivity[it] ? : it)
89
99
}
100
+ if (topView != null ) {
101
+ rootViewChangedListener.onRootViewsChanged(topView, true )
102
+ }
90
103
91
- context.applicationRef.rootsResolver.attachListener(rootViewListener)
92
- // On subscribe, trigger a traversal on whatever roots we have
93
- rootViewListener.onRootViewsChanged(applicationRef.rootsResolver.rootViews())
94
-
95
- Log .i(
96
- LogTag ,
97
- " Starting tracking root views, currently ${context.applicationRef.rootsResolver.rootViews().size} root views" )
104
+ Log .i(LogTag , " Starting tracking root views, currently ${Curtains .rootViews.size} root views" )
98
105
}
99
106
100
107
fun stop () {
101
- context.applicationRef.rootsResolver.attachListener( null )
108
+ Curtains .onRootViewsChangedListeners.clear( )
102
109
currentDecorView?.viewTreeObserver?.removeOnPreDrawListener(preDrawListener)
103
110
currentDecorView = null
104
111
preDrawListener = null
0 commit comments