|
15 | 15 | package com.google.firebase.perf.application;
|
16 | 16 |
|
17 | 17 | import android.app.Activity;
|
| 18 | +import android.os.Build; |
18 | 19 | import android.util.SparseIntArray;
|
19 | 20 | import androidx.core.app.FrameMetricsAggregator;
|
20 | 21 | import androidx.fragment.app.Fragment;
|
@@ -107,11 +108,22 @@ public Optional<PerfFrameMetrics> stop() {
|
107 | 108 | }
|
108 | 109 | Optional<PerfFrameMetrics> data = this.snapshot();
|
109 | 110 | try {
|
| 111 | + // No reliable way to check for hardware-acceleration, so we must catch retroactively (#2736). |
110 | 112 | frameMetricsAggregator.remove(activity);
|
111 |
| - } catch (IllegalArgumentException err) { |
| 113 | + } catch (IllegalArgumentException | NullPointerException ex) { |
| 114 | + // Both of these exceptions result from android.view.View.addFrameMetricsListener silently |
| 115 | + // failing when the view is not hardware-accelerated. Successful addFrameMetricsListener |
| 116 | + // stores an observer in a list, and initializes the list if it was uninitialized. Invoking |
| 117 | + // View.removeFrameMetricsListener(listener) throws IAE if it doesn't exist in the list, or |
| 118 | + // throws NPE if the list itself was never initialized (#4184). |
| 119 | + if (ex instanceof NullPointerException && Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { |
| 120 | + // Re-throw above API 28, since the NPE is fixed in API 29: |
| 121 | + // https://android.googlesource.com/platform/frameworks/base/+/140ff5ea8e2d99edc3fbe63a43239e459334c76b |
| 122 | + throw ex; |
| 123 | + } |
112 | 124 | logger.warn(
|
113 |
| - "View not hardware accelerated. Unable to collect FrameMetrics. %s", err.toString()); |
114 |
| - return Optional.absent(); |
| 125 | + "View not hardware accelerated. Unable to collect FrameMetrics. %s", ex.toString()); |
| 126 | + data = Optional.absent(); |
115 | 127 | }
|
116 | 128 | frameMetricsAggregator.reset();
|
117 | 129 | isRecording = false;
|
|
0 commit comments