Skip to content

Commit a8065aa

Browse files
authored
Avoid NPE if addPerfListener is called out of order with creating (#3182)
1 parent 6560a40 commit a8065aa

File tree

5 files changed

+38
-4
lines changed

5 files changed

+38
-4
lines changed

src/io/flutter/perf/FlutterWidgetPerf.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ class StatsForReportKind {
6363
private boolean requestInProgress = false;
6464
private long lastRequestTime;
6565

66-
private final List<PerfModel> perfListeners = new ArrayList<>();
66+
private final Set<PerfModel> perfListeners = new HashSet<>();
6767

6868
private final Map<TextEditor, EditorPerfModel> editorDecorations = new HashMap<>();
6969
private final TIntObjectHashMap<Location> knownLocationIds = new TIntObjectHashMap<>();
@@ -246,6 +246,11 @@ public void addPerfListener(PerfModel listener) {
246246
perfListeners.add(listener);
247247
}
248248

249+
@Override
250+
public void removePerfListener(PerfModel listener) {
251+
perfListeners.remove(listener);
252+
}
253+
249254
private StatsForReportKind getStatsForKind(PerfReportKind kind) {
250255
StatsForReportKind report = stats.get(kind);
251256
if (report == null) {

src/io/flutter/perf/FlutterWidgetPerfManager.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ public FlutterWidgetPerf getCurrentStats() {
6262
private boolean trackRepaintWidgets = trackRepaintWidgetsDefault;
6363
private boolean debugIsActive;
6464

65+
private final Set<PerfModel> listeners = new HashSet<>();
66+
6567
/**
6668
* File editors visible to the user that might contain widgets.
6769
*/
@@ -197,6 +199,10 @@ private void debugActive(Project project, FlutterViewMessages.FlutterDebugEvent
197199
(TextEditor textEditor) -> new EditorPerfDecorations(textEditor, app),
198200
path -> new DocumentFileLocationMapper(path, app.getProject())
199201
);
202+
203+
for (PerfModel listener : listeners) {
204+
currentStats.addPerfListener(listener);
205+
}
200206
}
201207

202208
public void stateChanged(FlutterApp.State newState) {
@@ -318,6 +324,21 @@ public void dispose() {
318324
if (currentStats != null) {
319325
currentStats.dispose();
320326
currentStats = null;
327+
listeners.clear();
328+
}
329+
}
330+
331+
public void addPerfListener(PerfModel listener) {
332+
listeners.add(listener);
333+
if (currentStats != null) {
334+
currentStats.addPerfListener(listener);
335+
}
336+
}
337+
338+
public void removePerfListener(PerfModel listener) {
339+
listeners.remove(listener);
340+
if (currentStats != null) {
341+
currentStats.removePerfListener(listener);
321342
}
322343
}
323344
}

src/io/flutter/perf/WidgetPerfListener.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,5 @@ public interface WidgetPerfListener {
1818
void onNavigation();
1919

2020
void addPerfListener(PerfModel listener);
21+
void removePerfListener(PerfModel listener);
2122
}

src/io/flutter/view/WidgetPerfSummaryView.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import java.awt.*;
2020
import java.awt.event.ActionEvent;
2121

22-
class WidgetPerfSummaryView extends JPanel {
22+
class WidgetPerfSummaryView extends JPanel implements Disposable {
2323
private static final int REFRESH_TABLE_DELAY = 100;
2424
private final FlutterApp app;
2525
private final FlutterWidgetPerfManager perfManager;
@@ -45,14 +45,19 @@ class WidgetPerfSummaryView extends JPanel {
4545

4646
table = new WidgetPerfTable(app, parentDisposable, metric);
4747

48-
perfManager.getCurrentStats().addPerfListener(table);
48+
Disposer.register(parentDisposable, this);
49+
50+
perfManager.addPerfListener(table);
4951

5052
add(ScrollPaneFactory.createScrollPane(table), BorderLayout.CENTER);
5153

5254
// Perf info and tips
5355
myWidgetPerfTipsPanel = new WidgetPerfTipsPanel(parentDisposable, app);
56+
}
5457

55-
Disposer.register(parentDisposable, refreshTableTimer::stop);
58+
public void dispose() {
59+
perfManager.removePerfListener(table);
60+
refreshTableTimer.stop();
5661
}
5762

5863
public WidgetPerfTipsPanel getWidgetPerfTipsPanel() {

testSrc/unit/io/flutter/perf/FlutterWidgetPerfTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,8 @@ public void testOverallStatsCalculation() throws InterruptedException, Execution
515515
// Verify that an idle event occurs once we wait the idle time delay.
516516
Thread.sleep(IDLE_DELAY_MILISECONDS);
517517
assertEquals(1, perfModel.idleCount);
518+
519+
flutterWidgetPerf.removePerfListener(perfModel);
518520
flutterWidgetPerf.dispose();
519521
}
520522
}

0 commit comments

Comments
 (0)