Skip to content

Commit f4b6131

Browse files
huntiefacebook-github-bot
authored andcommitted
Harden lifecycle handling for Perf Monitor (#53905)
Summary: Pull Request resolved: #53905 Updates `PerfMonitorOverlayManager` so that it is minimally and correctly integrated in the `DevSupportManagerBase` reload cycle — attempting to fix a bug where the background profiling state on startup / subsequent packager connections would be out of sync. Changelog: [Internal] Reviewed By: rubennorte Differential Revision: D83058519 fbshipit-source-id: 9a9bb32d3215ccf722aa39ca0ca943449f7ae62e
1 parent b9e6e34 commit f4b6131

File tree

3 files changed

+31
-45
lines changed

3 files changed

+31
-45
lines changed

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.kt

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ import java.io.File
7878
import java.net.MalformedURLException
7979
import java.net.URL
8080
import java.util.Locale
81-
import javax.inject.Provider
8281

8382
public abstract class DevSupportManagerBase(
8483
protected val applicationContext: Context,
@@ -185,6 +184,7 @@ public abstract class DevSupportManagerBase(
185184
}
186185

187186
private var perfMonitorOverlayManager: PerfMonitorOverlayManager? = null
187+
private var perfMonitorInitialized = false
188188
private var tracingStateProvider: TracingStateProvider? = null
189189

190190
init {
@@ -222,13 +222,6 @@ public abstract class DevSupportManagerBase(
222222
perfMonitorOverlayManager =
223223
PerfMonitorOverlayManager(
224224
reactInstanceDevHelper,
225-
Provider {
226-
val context = reactInstanceDevHelper.currentActivity
227-
if (context == null || context.isFinishing) {
228-
return@Provider null
229-
}
230-
context
231-
},
232225
{ openDebugger(DebuggerFrontendPanelName.PERFORMANCE.toString()) },
233226
)
234227
}
@@ -552,14 +545,16 @@ public abstract class DevSupportManagerBase(
552545
}
553546

554547
override fun onNewReactContextCreated(reactContext: ReactContext) {
555-
resetCurrentContext(reactContext)
556-
557-
if (reactInstanceDevHelper is PerfMonitorDevHelper) {
548+
if (!perfMonitorInitialized && reactInstanceDevHelper is PerfMonitorDevHelper) {
558549
perfMonitorOverlayManager?.let { manager ->
559550
reactInstanceDevHelper.inspectorTarget?.addPerfMonitorListener(manager)
560551
}
561552
perfMonitorOverlayManager?.enable()
553+
perfMonitorOverlayManager?.startBackgroundTrace()
554+
perfMonitorInitialized = true
562555
}
556+
557+
resetCurrentContext(reactContext)
563558
}
564559

565560
override fun onReactInstanceDestroyed(reactContext: ReactContext) {
@@ -877,8 +872,6 @@ public abstract class DevSupportManagerBase(
877872
devLoadingViewManager?.showMessage("Reloading...")
878873
}
879874

880-
perfMonitorOverlayManager?.reset()
881-
882875
devServerHelper.openPackagerConnection(
883876
javaClass.simpleName,
884877
object : PackagerCommandListener {
@@ -928,7 +921,7 @@ public abstract class DevSupportManagerBase(
928921
hideRedboxDialog()
929922
hideDevOptionsDialog()
930923
devLoadingViewManager?.hide()
931-
perfMonitorOverlayManager?.reset()
924+
perfMonitorOverlayManager?.disable()
932925

933926
devServerHelper.closePackagerConnection()
934927
}

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/perfmonitor/PerfMonitorDevHelper.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,15 @@
77

88
package com.facebook.react.devsupport.perfmonitor
99

10+
import android.app.Activity
11+
1012
/**
1113
* Interface implemented by [com.facebook.react.runtime.ReactHostImplDevHelper] exposing additional
1214
* hooks used to implement the V2 Perf Monitor overlay (experimental).
1315
*/
1416
internal interface PerfMonitorDevHelper {
17+
public val currentActivity: Activity?
18+
1519
/**
1620
* The inspector target object. Matches the lifetime of the ReactHost. May be null if modern JS
1721
* debugging is disabled.

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/perfmonitor/PerfMonitorOverlayManager.kt

Lines changed: 20 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,69 +7,58 @@
77

88
package com.facebook.react.devsupport.perfmonitor
99

10-
import android.content.Context
1110
import com.facebook.react.bridge.UiThreadUtil
1211
import com.facebook.react.devsupport.interfaces.TracingState
13-
import javax.inject.Provider
1412

1513
internal class PerfMonitorOverlayManager(
1614
private val devHelper: PerfMonitorDevHelper,
17-
private val contextProvider: Provider<Context?>,
1815
private val onRequestOpenDevTools: () -> Unit,
1916
) : PerfMonitorUpdateListener {
2017
private var enabled: Boolean = false
21-
private var initialized: Boolean = false
2218
private var view: PerfMonitorOverlayView? = null
2319
private var tracingState: TracingState = TracingState.ENABLEDINCDPMODE
2420

25-
private fun init() {
26-
if (initialized || !enabled) {
27-
return
28-
}
29-
21+
/** Enable the Perf Monitor overlay. */
22+
fun enable() {
23+
enabled = true
3024
UiThreadUtil.runOnUiThread {
31-
val context = contextProvider.get() ?: return@runOnUiThread
25+
val context = devHelper.currentActivity ?: return@runOnUiThread
3226
view = PerfMonitorOverlayView(context, ::handleRecordingButtonPress)
33-
34-
// Start background tracing
35-
devHelper.inspectorTarget?.resumeBackgroundTrace()
36-
37-
view?.show()
38-
initialized = true
3927
}
4028
}
4129

42-
/** Enable the Perf Monitor overlay. Will be shown when updates are received. */
43-
fun enable() {
44-
enabled = true
45-
init()
46-
}
47-
4830
/** Disable the Perf Monitor overlay. Will remain hidden when updates are received. */
4931
fun disable() {
5032
UiThreadUtil.runOnUiThread { view?.hide() }
5133
view = null
5234
enabled = false
5335
}
5436

55-
/** Reset the Perf Monitor overlay, e.g. after a reload. */
56-
fun reset() {
57-
// Update with current recording state
58-
onRecordingStateChanged(
59-
devHelper.inspectorTarget?.getTracingState() ?: TracingState.ENABLEDINCDPMODE
60-
)
37+
/** Start background trace recording. */
38+
fun startBackgroundTrace() {
39+
if (!enabled) {
40+
return
41+
}
42+
43+
devHelper.inspectorTarget?.let { target ->
44+
target.resumeBackgroundTrace()
45+
onRecordingStateChanged(target.getTracingState())
46+
}
6147
}
6248

6349
override fun onRecordingStateChanged(state: TracingState) {
6450
tracingState = state
65-
view?.updateRecordingState(state)
51+
UiThreadUtil.runOnUiThread {
52+
view?.updateRecordingState(state)
53+
view?.show()
54+
}
6655
}
6756

6857
private fun handleRecordingButtonPress() {
6958
when (tracingState) {
7059
TracingState.ENABLEDINBACKGROUNDMODE -> {
71-
devHelper.inspectorTarget?.let {
72-
if (!it.pauseAndAnalyzeBackgroundTrace()) {
60+
devHelper.inspectorTarget?.let { target ->
61+
if (!target.pauseAndAnalyzeBackgroundTrace()) {
7362
onRequestOpenDevTools()
7463
}
7564
}

0 commit comments

Comments
 (0)