Merge "Log foreground service start/stop in system trace"

This commit is contained in:
Jing Ji
2022-11-17 07:23:50 +00:00
committed by Android (Google) Code Review

View File

@@ -17,6 +17,8 @@
package android.app;
import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MANIFEST;
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
import static android.text.TextUtils.formatSimple;
import android.annotation.IntDef;
import android.annotation.NonNull;
@@ -34,6 +36,7 @@ import android.content.res.Configuration;
import android.os.Build;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.Trace;
import android.util.ArrayMap;
import android.util.Log;
import android.view.contentcapture.ContentCaptureManager;
@@ -763,10 +766,12 @@ public abstract class Service extends ContextWrapper implements ComponentCallbac
*/
public final void startForeground(int id, Notification notification) {
try {
final ComponentName comp = new ComponentName(this, mClassName);
mActivityManager.setServiceForeground(
new ComponentName(this, mClassName), mToken, id,
comp, mToken, id,
notification, 0, FOREGROUND_SERVICE_TYPE_MANIFEST);
clearStartForegroundServiceStackTrace();
logForegroundServiceStart(comp, FOREGROUND_SERVICE_TYPE_MANIFEST);
} catch (RemoteException ex) {
}
}
@@ -843,10 +848,12 @@ public abstract class Service extends ContextWrapper implements ComponentCallbac
public final void startForeground(int id, @NonNull Notification notification,
@RequiresPermission @ForegroundServiceType int foregroundServiceType) {
try {
final ComponentName comp = new ComponentName(this, mClassName);
mActivityManager.setServiceForeground(
new ComponentName(this, mClassName), mToken, id,
comp, mToken, id,
notification, 0, foregroundServiceType);
clearStartForegroundServiceStackTrace();
logForegroundServiceStart(comp, foregroundServiceType);
} catch (RemoteException ex) {
}
}
@@ -897,6 +904,7 @@ public abstract class Service extends ContextWrapper implements ComponentCallbac
mActivityManager.setServiceForeground(
new ComponentName(this, mClassName), mToken, 0, null,
notificationBehavior, 0);
logForegroundServiceStopIfNecessary();
} catch (RemoteException ex) {
}
}
@@ -992,6 +1000,7 @@ public abstract class Service extends ContextWrapper implements ComponentCallbac
*/
public final void detachAndCleanUp() {
mToken = null;
logForegroundServiceStopIfNecessary();
}
final String getClassName() {
@@ -1024,6 +1033,50 @@ public abstract class Service extends ContextWrapper implements ComponentCallbac
@UnsupportedAppUsage
private boolean mStartCompatibility = false;
/**
* This will be set to the title of the system trace when this service is started as
* a foreground service, and will be set to null when it's no longer in foreground
* service state.
*/
@GuardedBy("mForegroundServiceTraceTitleLock")
private @Nullable String mForegroundServiceTraceTitle = null;
private final Object mForegroundServiceTraceTitleLock = new Object();
private static final String TRACE_TRACK_NAME_FOREGROUND_SERVICE = "FGS";
private void logForegroundServiceStart(ComponentName comp,
@ForegroundServiceType int foregroundServiceType) {
synchronized (mForegroundServiceTraceTitleLock) {
if (mForegroundServiceTraceTitle == null) {
mForegroundServiceTraceTitle = formatSimple("comp=%s type=%s",
comp.toShortString(), Integer.toHexString(foregroundServiceType));
// The service is not in foreground state, emit a start event.
Trace.asyncTraceForTrackBegin(TRACE_TAG_ACTIVITY_MANAGER,
TRACE_TRACK_NAME_FOREGROUND_SERVICE,
mForegroundServiceTraceTitle,
System.identityHashCode(this));
} else {
// The service is already in foreground state, emit an one-off event.
Trace.instantForTrack(TRACE_TAG_ACTIVITY_MANAGER,
TRACE_TRACK_NAME_FOREGROUND_SERVICE,
mForegroundServiceTraceTitle);
}
}
}
private void logForegroundServiceStopIfNecessary() {
synchronized (mForegroundServiceTraceTitleLock) {
if (mForegroundServiceTraceTitle != null) {
Trace.asyncTraceForTrackEnd(TRACE_TAG_ACTIVITY_MANAGER,
TRACE_TRACK_NAME_FOREGROUND_SERVICE,
mForegroundServiceTraceTitle,
System.identityHashCode(this));
mForegroundServiceTraceTitle = null;
}
}
}
/**
* This keeps track of the stacktrace where Context.startForegroundService() was called
* for each service class. We use that when we crash the app for not calling