- Added realracing3-community.apk (71.57 MB) - Removed 32-bit support (armeabi-v7a) - Only includes arm64-v8a libraries - Decompiled source code included - Added README-community.md with analysis
324 lines
13 KiB
Java
324 lines
13 KiB
Java
package com.google.firebase.perf.application;
|
|
|
|
import android.app.Activity;
|
|
import android.app.Application;
|
|
import android.content.Context;
|
|
import android.os.Bundle;
|
|
import androidx.fragment.app.FragmentActivity;
|
|
import androidx.fragment.app.FragmentManager;
|
|
import com.google.firebase.perf.config.ConfigResolver;
|
|
import com.google.firebase.perf.logging.AndroidLogger;
|
|
import com.google.firebase.perf.metrics.FrameMetricsCalculator;
|
|
import com.google.firebase.perf.metrics.Trace;
|
|
import com.google.firebase.perf.session.SessionManager;
|
|
import com.google.firebase.perf.transport.TransportManager;
|
|
import com.google.firebase.perf.util.Clock;
|
|
import com.google.firebase.perf.util.Constants$CounterNames;
|
|
import com.google.firebase.perf.util.Constants$TraceNames;
|
|
import com.google.firebase.perf.util.Optional;
|
|
import com.google.firebase.perf.util.ScreenTraceUtil;
|
|
import com.google.firebase.perf.util.Timer;
|
|
import com.google.firebase.perf.v1.ApplicationProcessState;
|
|
import com.google.firebase.perf.v1.TraceMetric;
|
|
import java.lang.ref.WeakReference;
|
|
import java.util.HashMap;
|
|
import java.util.HashSet;
|
|
import java.util.Iterator;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
import java.util.WeakHashMap;
|
|
import java.util.concurrent.atomic.AtomicInteger;
|
|
|
|
/* loaded from: classes3.dex */
|
|
public class AppStateMonitor implements Application.ActivityLifecycleCallbacks {
|
|
public static volatile AppStateMonitor instance;
|
|
public static final AndroidLogger logger = AndroidLogger.getInstance();
|
|
public final WeakHashMap activityToFragmentStateMonitorMap;
|
|
public final WeakHashMap activityToRecorderMap;
|
|
public final WeakHashMap activityToResumedMap;
|
|
public final WeakHashMap activityToScreenTraceMap;
|
|
public Set appColdStartSubscribers;
|
|
public final Set appStateSubscribers;
|
|
public final Clock clock;
|
|
public final ConfigResolver configResolver;
|
|
public ApplicationProcessState currentAppState;
|
|
public boolean isColdStart;
|
|
public boolean isRegisteredForLifecycleCallbacks;
|
|
public final Map metricToCountMap;
|
|
public Timer resumeTime;
|
|
public final boolean screenPerformanceRecordingSupported;
|
|
public Timer stopTime;
|
|
public final TransportManager transportManager;
|
|
public final AtomicInteger tsnsCount;
|
|
|
|
public interface AppColdStartCallback {
|
|
void onAppColdStart();
|
|
}
|
|
|
|
public interface AppStateCallback {
|
|
void onUpdateAppState(ApplicationProcessState applicationProcessState);
|
|
}
|
|
|
|
public ApplicationProcessState getAppState() {
|
|
return this.currentAppState;
|
|
}
|
|
|
|
public boolean isColdStart() {
|
|
return this.isColdStart;
|
|
}
|
|
|
|
public boolean isScreenTraceSupported() {
|
|
return this.screenPerformanceRecordingSupported;
|
|
}
|
|
|
|
@Override // android.app.Application.ActivityLifecycleCallbacks
|
|
public void onActivityPaused(Activity activity) {
|
|
}
|
|
|
|
@Override // android.app.Application.ActivityLifecycleCallbacks
|
|
public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
|
|
}
|
|
|
|
public static AppStateMonitor getInstance() {
|
|
if (instance == null) {
|
|
synchronized (AppStateMonitor.class) {
|
|
try {
|
|
if (instance == null) {
|
|
instance = new AppStateMonitor(TransportManager.getInstance(), new Clock());
|
|
}
|
|
} finally {
|
|
}
|
|
}
|
|
}
|
|
return instance;
|
|
}
|
|
|
|
public AppStateMonitor(TransportManager transportManager, Clock clock) {
|
|
this(transportManager, clock, ConfigResolver.getInstance(), isScreenPerformanceRecordingSupported());
|
|
}
|
|
|
|
public AppStateMonitor(TransportManager transportManager, Clock clock, ConfigResolver configResolver, boolean z) {
|
|
this.activityToResumedMap = new WeakHashMap();
|
|
this.activityToRecorderMap = new WeakHashMap();
|
|
this.activityToFragmentStateMonitorMap = new WeakHashMap();
|
|
this.activityToScreenTraceMap = new WeakHashMap();
|
|
this.metricToCountMap = new HashMap();
|
|
this.appStateSubscribers = new HashSet();
|
|
this.appColdStartSubscribers = new HashSet();
|
|
this.tsnsCount = new AtomicInteger(0);
|
|
this.currentAppState = ApplicationProcessState.BACKGROUND;
|
|
this.isRegisteredForLifecycleCallbacks = false;
|
|
this.isColdStart = true;
|
|
this.transportManager = transportManager;
|
|
this.clock = clock;
|
|
this.configResolver = configResolver;
|
|
this.screenPerformanceRecordingSupported = z;
|
|
}
|
|
|
|
public synchronized void registerActivityLifecycleCallbacks(Context context) {
|
|
if (this.isRegisteredForLifecycleCallbacks) {
|
|
return;
|
|
}
|
|
Context applicationContext = context.getApplicationContext();
|
|
if (applicationContext instanceof Application) {
|
|
((Application) applicationContext).registerActivityLifecycleCallbacks(this);
|
|
this.isRegisteredForLifecycleCallbacks = true;
|
|
}
|
|
}
|
|
|
|
public void incrementCount(String str, long j) {
|
|
synchronized (this.metricToCountMap) {
|
|
try {
|
|
Long l = (Long) this.metricToCountMap.get(str);
|
|
if (l == null) {
|
|
this.metricToCountMap.put(str, Long.valueOf(j));
|
|
} else {
|
|
this.metricToCountMap.put(str, Long.valueOf(l.longValue() + j));
|
|
}
|
|
} catch (Throwable th) {
|
|
throw th;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void incrementTsnsCount(int i) {
|
|
this.tsnsCount.addAndGet(i);
|
|
}
|
|
|
|
public final void startFrameMonitoring(Activity activity) {
|
|
if (isScreenTraceSupported() && this.configResolver.isPerformanceMonitoringEnabled()) {
|
|
FrameMetricsRecorder frameMetricsRecorder = new FrameMetricsRecorder(activity);
|
|
this.activityToRecorderMap.put(activity, frameMetricsRecorder);
|
|
if (activity instanceof FragmentActivity) {
|
|
FragmentStateMonitor fragmentStateMonitor = new FragmentStateMonitor(this.clock, this.transportManager, this, frameMetricsRecorder);
|
|
this.activityToFragmentStateMonitorMap.put(activity, fragmentStateMonitor);
|
|
((FragmentActivity) activity).getSupportFragmentManager().registerFragmentLifecycleCallbacks(fragmentStateMonitor, true);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override // android.app.Application.ActivityLifecycleCallbacks
|
|
public void onActivityCreated(Activity activity, Bundle bundle) {
|
|
startFrameMonitoring(activity);
|
|
}
|
|
|
|
@Override // android.app.Application.ActivityLifecycleCallbacks
|
|
public void onActivityDestroyed(Activity activity) {
|
|
this.activityToRecorderMap.remove(activity);
|
|
if (this.activityToFragmentStateMonitorMap.containsKey(activity)) {
|
|
((FragmentActivity) activity).getSupportFragmentManager().unregisterFragmentLifecycleCallbacks((FragmentManager.FragmentLifecycleCallbacks) this.activityToFragmentStateMonitorMap.remove(activity));
|
|
}
|
|
}
|
|
|
|
@Override // android.app.Application.ActivityLifecycleCallbacks
|
|
public synchronized void onActivityStarted(Activity activity) {
|
|
try {
|
|
if (isScreenTraceSupported() && this.configResolver.isPerformanceMonitoringEnabled()) {
|
|
if (!this.activityToRecorderMap.containsKey(activity)) {
|
|
startFrameMonitoring(activity);
|
|
}
|
|
((FrameMetricsRecorder) this.activityToRecorderMap.get(activity)).start();
|
|
Trace trace = new Trace(getScreenTraceName(activity), this.transportManager, this.clock, this);
|
|
trace.start();
|
|
this.activityToScreenTraceMap.put(activity, trace);
|
|
}
|
|
} catch (Throwable th) {
|
|
throw th;
|
|
}
|
|
}
|
|
|
|
@Override // android.app.Application.ActivityLifecycleCallbacks
|
|
public synchronized void onActivityStopped(Activity activity) {
|
|
try {
|
|
if (isScreenTraceSupported()) {
|
|
sendScreenTrace(activity);
|
|
}
|
|
if (this.activityToResumedMap.containsKey(activity)) {
|
|
this.activityToResumedMap.remove(activity);
|
|
if (this.activityToResumedMap.isEmpty()) {
|
|
this.stopTime = this.clock.getTime();
|
|
sendSessionLog(Constants$TraceNames.FOREGROUND_TRACE_NAME.toString(), this.resumeTime, this.stopTime);
|
|
updateAppState(ApplicationProcessState.BACKGROUND);
|
|
}
|
|
}
|
|
} catch (Throwable th) {
|
|
throw th;
|
|
}
|
|
}
|
|
|
|
@Override // android.app.Application.ActivityLifecycleCallbacks
|
|
public synchronized void onActivityResumed(Activity activity) {
|
|
try {
|
|
if (this.activityToResumedMap.isEmpty()) {
|
|
this.resumeTime = this.clock.getTime();
|
|
this.activityToResumedMap.put(activity, Boolean.TRUE);
|
|
if (this.isColdStart) {
|
|
updateAppState(ApplicationProcessState.FOREGROUND);
|
|
sendAppColdStartUpdate();
|
|
this.isColdStart = false;
|
|
} else {
|
|
sendSessionLog(Constants$TraceNames.BACKGROUND_TRACE_NAME.toString(), this.stopTime, this.resumeTime);
|
|
updateAppState(ApplicationProcessState.FOREGROUND);
|
|
}
|
|
} else {
|
|
this.activityToResumedMap.put(activity, Boolean.TRUE);
|
|
}
|
|
} catch (Throwable th) {
|
|
throw th;
|
|
}
|
|
}
|
|
|
|
public void registerForAppState(WeakReference weakReference) {
|
|
synchronized (this.appStateSubscribers) {
|
|
this.appStateSubscribers.add(weakReference);
|
|
}
|
|
}
|
|
|
|
public void unregisterForAppState(WeakReference weakReference) {
|
|
synchronized (this.appStateSubscribers) {
|
|
this.appStateSubscribers.remove(weakReference);
|
|
}
|
|
}
|
|
|
|
public void registerForAppColdStart(AppColdStartCallback appColdStartCallback) {
|
|
synchronized (this.appColdStartSubscribers) {
|
|
this.appColdStartSubscribers.add(appColdStartCallback);
|
|
}
|
|
}
|
|
|
|
public final void updateAppState(ApplicationProcessState applicationProcessState) {
|
|
this.currentAppState = applicationProcessState;
|
|
synchronized (this.appStateSubscribers) {
|
|
try {
|
|
Iterator it = this.appStateSubscribers.iterator();
|
|
while (it.hasNext()) {
|
|
AppStateCallback appStateCallback = (AppStateCallback) ((WeakReference) it.next()).get();
|
|
if (appStateCallback != null) {
|
|
appStateCallback.onUpdateAppState(this.currentAppState);
|
|
} else {
|
|
it.remove();
|
|
}
|
|
}
|
|
} catch (Throwable th) {
|
|
throw th;
|
|
}
|
|
}
|
|
}
|
|
|
|
public final void sendAppColdStartUpdate() {
|
|
synchronized (this.appColdStartSubscribers) {
|
|
try {
|
|
for (AppColdStartCallback appColdStartCallback : this.appColdStartSubscribers) {
|
|
if (appColdStartCallback != null) {
|
|
appColdStartCallback.onAppColdStart();
|
|
}
|
|
}
|
|
} catch (Throwable th) {
|
|
throw th;
|
|
}
|
|
}
|
|
}
|
|
|
|
public final void sendScreenTrace(Activity activity) {
|
|
Trace trace = (Trace) this.activityToScreenTraceMap.get(activity);
|
|
if (trace == null) {
|
|
return;
|
|
}
|
|
this.activityToScreenTraceMap.remove(activity);
|
|
Optional stop = ((FrameMetricsRecorder) this.activityToRecorderMap.get(activity)).stop();
|
|
if (!stop.isAvailable()) {
|
|
logger.warn("Failed to record frame data for %s.", activity.getClass().getSimpleName());
|
|
} else {
|
|
ScreenTraceUtil.addFrameCounters(trace, (FrameMetricsCalculator.PerfFrameMetrics) stop.get());
|
|
trace.stop();
|
|
}
|
|
}
|
|
|
|
public final void sendSessionLog(String str, Timer timer, Timer timer2) {
|
|
if (this.configResolver.isPerformanceMonitoringEnabled()) {
|
|
TraceMetric.Builder addPerfSessions = TraceMetric.newBuilder().setName(str).setClientStartTimeUs(timer.getMicros()).setDurationUs(timer.getDurationMicros(timer2)).addPerfSessions(SessionManager.getInstance().perfSession().build());
|
|
int andSet = this.tsnsCount.getAndSet(0);
|
|
synchronized (this.metricToCountMap) {
|
|
try {
|
|
addPerfSessions.putAllCounters(this.metricToCountMap);
|
|
if (andSet != 0) {
|
|
addPerfSessions.putCounters(Constants$CounterNames.TRACE_STARTED_NOT_STOPPED.toString(), andSet);
|
|
}
|
|
this.metricToCountMap.clear();
|
|
} catch (Throwable th) {
|
|
throw th;
|
|
}
|
|
}
|
|
this.transportManager.log((TraceMetric) addPerfSessions.build(), ApplicationProcessState.FOREGROUND_BACKGROUND);
|
|
}
|
|
}
|
|
|
|
public static boolean isScreenPerformanceRecordingSupported() {
|
|
return FrameMetricsRecorder.isFrameMetricsRecordingSupported();
|
|
}
|
|
|
|
public static String getScreenTraceName(Activity activity) {
|
|
return "_st_" + activity.getClass().getSimpleName();
|
|
}
|
|
}
|