Loading services/core/java/com/android/server/am/ActiveServices.java +68 −8 Original line number Diff line number Diff line Loading @@ -76,6 +76,7 @@ import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; import android.Manifest; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UptimeMillisLong; Loading Loading @@ -174,6 +175,8 @@ import java.io.FileDescriptor; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; Loading Loading @@ -211,6 +214,24 @@ public final class ActiveServices { | ServiceInfo.FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE | ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION; // Foreground service is stopped for unknown reason. static final int FGS_STOP_REASON_UNKNOWN = 0; // Foreground service is stopped by app calling Service.stopForeground(). static final int FGS_STOP_REASON_STOP_FOREGROUND = 1; // Foreground service is stopped because service is brought down either by app calling // stopService() or unbindService(), or service process is killed by the system. static final int FGS_STOP_REASON_STOP_SERVICE = 2; /** * The list of FGS stop reasons. */ @IntDef(flag = true, prefix = { "FGS_STOP_REASON_" }, value = { FGS_STOP_REASON_UNKNOWN, FGS_STOP_REASON_STOP_FOREGROUND, FGS_STOP_REASON_STOP_SERVICE, }) @Retention(RetentionPolicy.SOURCE) @interface FgsStopReason {} final ActivityManagerService mAm; // Maximum number of services that we allow to start in the background Loading Loading @@ -721,7 +742,7 @@ public final class ActiveServices { showFgsBgRestrictedNotificationLocked(r); logFGSStateChangeLocked(r, FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__DENIED, 0); 0, FGS_STOP_REASON_UNKNOWN); if (CompatChanges.isChangeEnabled(FGS_START_EXCEPTION_CHANGE_ID, callingUid)) { throw new ForegroundServiceStartNotAllowedException(msg); } Loading Loading @@ -1909,7 +1930,7 @@ public final class ActiveServices { ignoreForeground = true; logFGSStateChangeLocked(r, FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__DENIED, 0); 0, FGS_STOP_REASON_UNKNOWN); if (CompatChanges.isChangeEnabled(FGS_START_EXCEPTION_CHANGE_ID, r.appInfo.uid)) { throw new ForegroundServiceStartNotAllowedException(msg); Loading Loading @@ -1984,7 +2005,7 @@ public final class ActiveServices { mAm.updateForegroundServiceUsageStats(r.name, r.userId, true); logFGSStateChangeLocked(r, FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__ENTER, 0); 0, FGS_STOP_REASON_UNKNOWN); } // Even if the service is already a FGS, we need to update the notification, // so we need to call it again. Loading Loading @@ -2066,7 +2087,8 @@ public final class ActiveServices { logFGSStateChangeLocked(r, FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__EXIT, r.mFgsExitTime > r.mFgsEnterTime ? (int)(r.mFgsExitTime - r.mFgsEnterTime) : 0); ? (int) (r.mFgsExitTime - r.mFgsEnterTime) : 0, FGS_STOP_REASON_STOP_FOREGROUND); r.mFgsNotificationWasDeferred = false; signalForegroundServiceObserversLocked(r); resetFgsRestrictionLocked(r); Loading Loading @@ -4652,7 +4674,8 @@ public final class ActiveServices { logFGSStateChangeLocked(r, FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__EXIT, r.mFgsExitTime > r.mFgsEnterTime ? (int)(r.mFgsExitTime - r.mFgsEnterTime) : 0); ? (int) (r.mFgsExitTime - r.mFgsEnterTime) : 0, FGS_STOP_REASON_STOP_SERVICE); mAm.updateForegroundServiceUsageStats(r.name, r.userId, false); } Loading Loading @@ -6846,7 +6869,8 @@ public final class ActiveServices { * @param state one of ENTER/EXIT/DENIED event. * @param durationMs Only meaningful for EXIT event, the duration from ENTER and EXIT state. */ private void logFGSStateChangeLocked(ServiceRecord r, int state, int durationMs) { private void logFGSStateChangeLocked(ServiceRecord r, int state, int durationMs, @FgsStopReason int fgsStopReason) { if (!ActivityManagerUtils.shouldSamplePackageForAtom( r.packageName, mAm.mConstants.mFgsAtomSampleRate)) { return; Loading @@ -6861,6 +6885,8 @@ public final class ActiveServices { allowWhileInUsePermissionInFgs = r.mAllowWhileInUsePermissionInFgs; fgsStartReasonCode = r.mAllowStartForeground; } final int callerTargetSdkVersion = r.mRecentCallerApplicationInfo != null ? r.mRecentCallerApplicationInfo.targetSdkVersion : 0; FrameworkStatsLog.write(FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED, r.appInfo.uid, r.shortInstanceName, Loading @@ -6869,8 +6895,7 @@ public final class ActiveServices { fgsStartReasonCode, r.appInfo.targetSdkVersion, r.mRecentCallingUid, r.mRecentCallerApplicationInfo != null ? r.mRecentCallerApplicationInfo.targetSdkVersion : 0, callerTargetSdkVersion, r.mInfoTempFgsAllowListReason != null ? r.mInfoTempFgsAllowListReason.mCallingUid : INVALID_UID, r.mFgsNotificationWasDeferred, Loading @@ -6879,6 +6904,30 @@ public final class ActiveServices { r.mStartForegroundCount, ActivityManagerUtils.hashComponentNameForAtom(r.shortInstanceName), r.mFgsHasNotificationPermission); int event = 0; if (state == FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__ENTER) { event = EventLogTags.AM_FOREGROUND_SERVICE_START; } else if (state == FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__EXIT) { event = EventLogTags.AM_FOREGROUND_SERVICE_STOP; } else if (state == FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__DENIED) { event = EventLogTags.AM_FOREGROUND_SERVICE_DENIED; } else { // Unknown event. return; } EventLog.writeEvent(event, r.userId, r.shortInstanceName, allowWhileInUsePermissionInFgs ? 1 : 0, reasonCodeToString(fgsStartReasonCode), r.appInfo.targetSdkVersion, callerTargetSdkVersion, r.mFgsNotificationWasDeferred ? 1 : 0, r.mFgsNotificationShown ? 1 : 0, durationMs, r.mStartForegroundCount, fgsStopReasonToString(fgsStopReason)); } boolean canAllowWhileInUsePermissionInFgsLocked(int callingPid, int callingUid, Loading @@ -6903,4 +6952,15 @@ public final class ActiveServices { return mAm.getPackageManagerInternal().isSameApp(packageName, uid, UserHandle.getUserId(uid)); } private static String fgsStopReasonToString(@FgsStopReason int stopReason) { switch (stopReason) { case FGS_STOP_REASON_STOP_SERVICE: return "STOP_SERVICE"; case FGS_STOP_REASON_STOP_FOREGROUND: return "STOP_FOREGROUND"; default: return "UNKNOWN"; } } } services/core/java/com/android/server/am/EventLogTags.logtags +8 −0 Original line number Diff line number Diff line Loading @@ -116,3 +116,11 @@ option java_package com.android.server.am 30086 ssm_user_stopping (userId|1|5) 30087 ssm_user_stopped (userId|1|5) 30088 ssm_user_completed_event (userId|1|5),(eventFlag|1|5) # Foreground service start/stop events. 30100 am_foreground_service_start (User|1|5),(Component Name|3),(allowWhileInUse|1),(startReasonCode|3),(targetSdk|1|1),(callerTargetSdk|1|1),(notificationWasDeferred|1),(notificationShown|1),(durationMs|1|3),(startForegroundCount|1|1),(stopReason|3) 30101 am_foreground_service_denied (User|1|5),(Component Name|3),(allowWhileInUse|1),(startReasonCode|3),(targetSdk|1|1),(callerTargetSdk|1|1),(notificationWasDeferred|1),(notificationShown|1),(durationMs|1|3),(startForegroundCount|1|1),(stopReason|3) 30102 am_foreground_service_stop (User|1|5),(Component Name|3),(allowWhileInUse|1),(startReasonCode|3),(targetSdk|1|1),(callerTargetSdk|1|1),(notificationWasDeferred|1),(notificationShown|1),(durationMs|1|3),(startForegroundCount|1|1),(stopReason|3) Loading
services/core/java/com/android/server/am/ActiveServices.java +68 −8 Original line number Diff line number Diff line Loading @@ -76,6 +76,7 @@ import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; import android.Manifest; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UptimeMillisLong; Loading Loading @@ -174,6 +175,8 @@ import java.io.FileDescriptor; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; Loading Loading @@ -211,6 +214,24 @@ public final class ActiveServices { | ServiceInfo.FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE | ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION; // Foreground service is stopped for unknown reason. static final int FGS_STOP_REASON_UNKNOWN = 0; // Foreground service is stopped by app calling Service.stopForeground(). static final int FGS_STOP_REASON_STOP_FOREGROUND = 1; // Foreground service is stopped because service is brought down either by app calling // stopService() or unbindService(), or service process is killed by the system. static final int FGS_STOP_REASON_STOP_SERVICE = 2; /** * The list of FGS stop reasons. */ @IntDef(flag = true, prefix = { "FGS_STOP_REASON_" }, value = { FGS_STOP_REASON_UNKNOWN, FGS_STOP_REASON_STOP_FOREGROUND, FGS_STOP_REASON_STOP_SERVICE, }) @Retention(RetentionPolicy.SOURCE) @interface FgsStopReason {} final ActivityManagerService mAm; // Maximum number of services that we allow to start in the background Loading Loading @@ -721,7 +742,7 @@ public final class ActiveServices { showFgsBgRestrictedNotificationLocked(r); logFGSStateChangeLocked(r, FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__DENIED, 0); 0, FGS_STOP_REASON_UNKNOWN); if (CompatChanges.isChangeEnabled(FGS_START_EXCEPTION_CHANGE_ID, callingUid)) { throw new ForegroundServiceStartNotAllowedException(msg); } Loading Loading @@ -1909,7 +1930,7 @@ public final class ActiveServices { ignoreForeground = true; logFGSStateChangeLocked(r, FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__DENIED, 0); 0, FGS_STOP_REASON_UNKNOWN); if (CompatChanges.isChangeEnabled(FGS_START_EXCEPTION_CHANGE_ID, r.appInfo.uid)) { throw new ForegroundServiceStartNotAllowedException(msg); Loading Loading @@ -1984,7 +2005,7 @@ public final class ActiveServices { mAm.updateForegroundServiceUsageStats(r.name, r.userId, true); logFGSStateChangeLocked(r, FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__ENTER, 0); 0, FGS_STOP_REASON_UNKNOWN); } // Even if the service is already a FGS, we need to update the notification, // so we need to call it again. Loading Loading @@ -2066,7 +2087,8 @@ public final class ActiveServices { logFGSStateChangeLocked(r, FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__EXIT, r.mFgsExitTime > r.mFgsEnterTime ? (int)(r.mFgsExitTime - r.mFgsEnterTime) : 0); ? (int) (r.mFgsExitTime - r.mFgsEnterTime) : 0, FGS_STOP_REASON_STOP_FOREGROUND); r.mFgsNotificationWasDeferred = false; signalForegroundServiceObserversLocked(r); resetFgsRestrictionLocked(r); Loading Loading @@ -4652,7 +4674,8 @@ public final class ActiveServices { logFGSStateChangeLocked(r, FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__EXIT, r.mFgsExitTime > r.mFgsEnterTime ? (int)(r.mFgsExitTime - r.mFgsEnterTime) : 0); ? (int) (r.mFgsExitTime - r.mFgsEnterTime) : 0, FGS_STOP_REASON_STOP_SERVICE); mAm.updateForegroundServiceUsageStats(r.name, r.userId, false); } Loading Loading @@ -6846,7 +6869,8 @@ public final class ActiveServices { * @param state one of ENTER/EXIT/DENIED event. * @param durationMs Only meaningful for EXIT event, the duration from ENTER and EXIT state. */ private void logFGSStateChangeLocked(ServiceRecord r, int state, int durationMs) { private void logFGSStateChangeLocked(ServiceRecord r, int state, int durationMs, @FgsStopReason int fgsStopReason) { if (!ActivityManagerUtils.shouldSamplePackageForAtom( r.packageName, mAm.mConstants.mFgsAtomSampleRate)) { return; Loading @@ -6861,6 +6885,8 @@ public final class ActiveServices { allowWhileInUsePermissionInFgs = r.mAllowWhileInUsePermissionInFgs; fgsStartReasonCode = r.mAllowStartForeground; } final int callerTargetSdkVersion = r.mRecentCallerApplicationInfo != null ? r.mRecentCallerApplicationInfo.targetSdkVersion : 0; FrameworkStatsLog.write(FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED, r.appInfo.uid, r.shortInstanceName, Loading @@ -6869,8 +6895,7 @@ public final class ActiveServices { fgsStartReasonCode, r.appInfo.targetSdkVersion, r.mRecentCallingUid, r.mRecentCallerApplicationInfo != null ? r.mRecentCallerApplicationInfo.targetSdkVersion : 0, callerTargetSdkVersion, r.mInfoTempFgsAllowListReason != null ? r.mInfoTempFgsAllowListReason.mCallingUid : INVALID_UID, r.mFgsNotificationWasDeferred, Loading @@ -6879,6 +6904,30 @@ public final class ActiveServices { r.mStartForegroundCount, ActivityManagerUtils.hashComponentNameForAtom(r.shortInstanceName), r.mFgsHasNotificationPermission); int event = 0; if (state == FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__ENTER) { event = EventLogTags.AM_FOREGROUND_SERVICE_START; } else if (state == FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__EXIT) { event = EventLogTags.AM_FOREGROUND_SERVICE_STOP; } else if (state == FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__DENIED) { event = EventLogTags.AM_FOREGROUND_SERVICE_DENIED; } else { // Unknown event. return; } EventLog.writeEvent(event, r.userId, r.shortInstanceName, allowWhileInUsePermissionInFgs ? 1 : 0, reasonCodeToString(fgsStartReasonCode), r.appInfo.targetSdkVersion, callerTargetSdkVersion, r.mFgsNotificationWasDeferred ? 1 : 0, r.mFgsNotificationShown ? 1 : 0, durationMs, r.mStartForegroundCount, fgsStopReasonToString(fgsStopReason)); } boolean canAllowWhileInUsePermissionInFgsLocked(int callingPid, int callingUid, Loading @@ -6903,4 +6952,15 @@ public final class ActiveServices { return mAm.getPackageManagerInternal().isSameApp(packageName, uid, UserHandle.getUserId(uid)); } private static String fgsStopReasonToString(@FgsStopReason int stopReason) { switch (stopReason) { case FGS_STOP_REASON_STOP_SERVICE: return "STOP_SERVICE"; case FGS_STOP_REASON_STOP_FOREGROUND: return "STOP_FOREGROUND"; default: return "UNKNOWN"; } } }
services/core/java/com/android/server/am/EventLogTags.logtags +8 −0 Original line number Diff line number Diff line Loading @@ -116,3 +116,11 @@ option java_package com.android.server.am 30086 ssm_user_stopping (userId|1|5) 30087 ssm_user_stopped (userId|1|5) 30088 ssm_user_completed_event (userId|1|5),(eventFlag|1|5) # Foreground service start/stop events. 30100 am_foreground_service_start (User|1|5),(Component Name|3),(allowWhileInUse|1),(startReasonCode|3),(targetSdk|1|1),(callerTargetSdk|1|1),(notificationWasDeferred|1),(notificationShown|1),(durationMs|1|3),(startForegroundCount|1|1),(stopReason|3) 30101 am_foreground_service_denied (User|1|5),(Component Name|3),(allowWhileInUse|1),(startReasonCode|3),(targetSdk|1|1),(callerTargetSdk|1|1),(notificationWasDeferred|1),(notificationShown|1),(durationMs|1|3),(startForegroundCount|1|1),(stopReason|3) 30102 am_foreground_service_stop (User|1|5),(Component Name|3),(allowWhileInUse|1),(startReasonCode|3),(targetSdk|1|1),(callerTargetSdk|1|1),(notificationWasDeferred|1),(notificationShown|1),(durationMs|1|3),(startForegroundCount|1|1),(stopReason|3)