Skip to content

Commit 5e745d1

Browse files
committed
undereference when activity is destroyed
1 parent 02fa988 commit 5e745d1

File tree

4 files changed

+32
-30
lines changed

4 files changed

+32
-30
lines changed

firebase-perf/src/main/java/com/google/firebase/perf/application/AppStateMonitor.java

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import android.content.Context;
2121
import android.os.Bundle;
2222
import androidx.annotation.NonNull;
23-
import androidx.core.app.FrameMetricsAggregator;
2423
import androidx.fragment.app.FragmentActivity;
2524
import com.google.android.gms.common.util.VisibleForTesting;
2625
import com.google.firebase.perf.config.ConfigResolver;
@@ -57,7 +56,10 @@ public class AppStateMonitor implements ActivityLifecycleCallbacks {
5756
private final boolean hasFrameMetricsAggregator;
5857

5958
private final WeakHashMap<Activity, Boolean> activityToResumedMap = new WeakHashMap<>();
60-
private final WeakHashMap<Activity, FrameMetricsRecorder> activityToRecorderMap = new WeakHashMap<>();
59+
private final WeakHashMap<Activity, FrameMetricsRecorder> activityToRecorderMap =
60+
new WeakHashMap<>();
61+
private final WeakHashMap<Activity, FragmentStateMonitor> activityToFragmentStateMonitorMap =
62+
new WeakHashMap<>();
6163
private final WeakHashMap<Activity, Trace> activityToScreenTraceMap = new WeakHashMap<>();
6264
private final Map<String, Long> metricToCountMap = new HashMap<>();
6365
private final Set<WeakReference<AppStateCallback>> appStateSubscribers = new HashSet<>();
@@ -90,11 +92,7 @@ public static AppStateMonitor getInstance() {
9092
}
9193

9294
AppStateMonitor(TransportManager transportManager, Clock clock) {
93-
this(
94-
transportManager,
95-
clock,
96-
ConfigResolver.getInstance(),
97-
hasFrameMetricsAggregatorClass());
95+
this(transportManager, clock, ConfigResolver.getInstance(), hasFrameMetricsAggregatorClass());
9896
}
9997

10098
AppStateMonitor(
@@ -153,19 +151,29 @@ public void incrementTsnsCount(int value) {
153151
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
154152
if (isScreenTraceSupported() && configResolver.isPerformanceMonitoringEnabled()) {
155153
FrameMetricsRecorder recorder = new FrameMetricsRecorder(activity);
154+
activityToRecorderMap.put(activity, recorder);
156155
if (activity instanceof FragmentActivity) {
156+
FragmentStateMonitor fragmentStateMonitor =
157+
new FragmentStateMonitor(clock, transportManager, this, recorder);
158+
activityToFragmentStateMonitorMap.put(activity, fragmentStateMonitor);
157159
FragmentActivity fragmentActivity = (FragmentActivity) activity;
158160
fragmentActivity
159161
.getSupportFragmentManager()
160-
.registerFragmentLifecycleCallbacks(
161-
new FragmentStateMonitor(clock, transportManager, this, recorder),
162-
true);
162+
.registerFragmentLifecycleCallbacks(fragmentStateMonitor, true);
163163
}
164164
}
165165
}
166166

167167
@Override
168-
public void onActivityDestroyed(Activity activity) {}
168+
public void onActivityDestroyed(Activity activity) {
169+
activityToRecorderMap.remove(activity);
170+
if (activityToFragmentStateMonitorMap.containsKey(activity)) {
171+
FragmentActivity fragmentActivity = (FragmentActivity) activity;
172+
fragmentActivity
173+
.getSupportFragmentManager()
174+
.unregisterFragmentLifecycleCallbacks(activityToFragmentStateMonitorMap.remove(activity));
175+
}
176+
}
169177

170178
@Override
171179
public synchronized void onActivityStarted(Activity activity) {
@@ -326,18 +334,16 @@ public void onActivityPaused(Activity activity) {}
326334
* @param activity activity object.
327335
*/
328336
private void sendScreenTrace(Activity activity) {
329-
if (!activityToScreenTraceMap.containsKey(activity)) {
330-
return;
331-
}
332337
Trace screenTrace = activityToScreenTraceMap.get(activity);
333338
if (screenTrace == null) {
334339
return;
335340
}
336341
activityToScreenTraceMap.remove(activity);
337342

338-
Optional<FrameMetricsCalculator.PerfFrameMetrics> perfFrameMetrics = activityToRecorderMap.get(activity).stop();
343+
Optional<FrameMetricsCalculator.PerfFrameMetrics> perfFrameMetrics =
344+
activityToRecorderMap.get(activity).stop();
339345
if (!perfFrameMetrics.isAvailable()) {
340-
logger.warn("Failed to record frame data for %s", activity.getClass().getSimpleName());
346+
logger.warn("Failed to record frame data for %s.", activity.getClass().getSimpleName());
341347
return;
342348
}
343349
ScreenTraceUtil.addFrameCounters(screenTrace, perfFrameMetrics.get());

firebase-perf/src/main/java/com/google/firebase/perf/application/FragmentStateMonitor.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
package com.google.firebase.perf.application;
1616

1717
import androidx.annotation.NonNull;
18-
import androidx.core.app.FrameMetricsAggregator;
1918
import androidx.fragment.app.Fragment;
2019
import androidx.fragment.app.FragmentManager;
2120
import com.google.android.gms.common.util.VisibleForTesting;
@@ -98,8 +97,7 @@ public void onFragmentPaused(@NonNull FragmentManager fm, @NonNull Fragment f) {
9897
logger.warn("onFragmentPaused: recorder failed to trace %s", f.getClass().getSimpleName());
9998
return;
10099
}
101-
ScreenTraceUtil.addFrameCounters(
102-
fragmentTrace, data.get());
100+
ScreenTraceUtil.addFrameCounters(fragmentTrace, data.get());
103101
fragmentTrace.stop();
104102
}
105103

firebase-perf/src/main/java/com/google/firebase/perf/application/FrameMetricsRecorder.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,8 @@ public Optional<PerfFrameMetrics> stop() {
9696
}
9797
Optional<PerfFrameMetrics> data = this.snapshot();
9898
/**
99-
* {@link FrameMetricsAggregator#remove(Activity)} will throw exceptions for hardware acceleration
100-
* disabled activities.
99+
* {@link FrameMetricsAggregator#remove(Activity)} will throw exceptions for hardware
100+
* acceleration disabled activities.
101101
*/
102102
try {
103103
frameMetricsAggregator.remove(activity);

firebase-perf/src/test/java/com/google/firebase/perf/application/FragmentStateMonitorTest.java

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,8 @@
2323
import static org.mockito.Mockito.spy;
2424
import static org.mockito.Mockito.times;
2525
import static org.mockito.Mockito.verify;
26-
import static org.mockito.Mockito.when;
2726
import static org.mockito.MockitoAnnotations.initMocks;
2827

29-
import android.app.Activity;
3028
import android.os.Bundle;
3129
import android.util.SparseIntArray;
3230
import androidx.appcompat.app.AppCompatActivity;
@@ -45,7 +43,6 @@
4543
import com.google.firebase.perf.util.Timer;
4644
import com.google.firebase.perf.v1.ApplicationProcessState;
4745
import com.google.firebase.perf.v1.TraceMetric;
48-
import com.google.testing.timing.FakeDirectExecutorService;
4946
import java.util.WeakHashMap;
5047
import org.junit.Assert;
5148
import org.junit.Before;
@@ -80,7 +77,6 @@ public class FragmentStateMonitorTest extends FirebasePerformanceTestBase {
8077
private static final String longFragmentName =
8178
"_st_NeverGonnaGiveYouUpNeverGonnaLetYouDownNeverGonnaRunAroundAndDesertYouNeverGonnaMakeYouCryNeverGonnaSayGoodbyeNeverGonnaTellALieAndHurtYou";
8279

83-
8480
/**
8581
* Array of SparseIntArray to mock the return value from {@link
8682
* FrameMetricsAggregator#getMetrics()}
@@ -97,11 +93,12 @@ public void setUp() {
9793

9894
DeviceCacheManager.clearInstance();
9995

100-
// ConfigResolver configResolver = ConfigResolver.getInstance();
101-
// configResolver.setDeviceCacheManager(new DeviceCacheManager(new FakeDirectExecutorService()));
102-
// ConfigResolver spyConfigResolver = spy(configResolver);
96+
// ConfigResolver configResolver = ConfigResolver.getInstance();
97+
// configResolver.setDeviceCacheManager(new DeviceCacheManager(new
98+
// FakeDirectExecutorService()));
99+
// ConfigResolver spyConfigResolver = spy(configResolver);
103100
doReturn(true).when(configResolver).isPerformanceMonitoringEnabled();
104-
// this.configResolver = spyConfigResolver;
101+
// this.configResolver = spyConfigResolver;
105102

106103
// fmaMetrics1 should have 1+3+1=5 total frames, 3+1=4 slow frames, and 1 frozen frames.
107104
SparseIntArray sparseIntArray = new SparseIntArray();
@@ -198,7 +195,8 @@ public void lifecycleCallbacks_onPausedCalledBeforeOnResume_doesNotLogFragmentSc
198195
public void lifecycleCallbacks_cleansUpMap_duringActivityTransitions() {
199196
// Simulate call order of activity + fragment lifecycle events
200197
Bundle savedInstanceState = mock(Bundle.class);
201-
AppStateMonitor appStateMonitor = new AppStateMonitor(mockTransportManager, clock, configResolver, true);
198+
AppStateMonitor appStateMonitor =
199+
new AppStateMonitor(mockTransportManager, clock, configResolver, true);
202200
FragmentStateMonitor fragmentMonitor =
203201
new FragmentStateMonitor(clock, mockTransportManager, appStateMonitor, recorder);
204202
doReturn(true).when(configResolver).isPerformanceMonitoringEnabled();

0 commit comments

Comments
 (0)