Add fgsStartReasonCode and other fields into metric ForegroundServiceStateChanged.

1. Besides ENTER and EXIT state, add a new state DENIED.
2. Add more fields inth the metric:
    int32 fgs_start_reason_code = 5;
    int32 target_sdk_version = 6;
    int32 calling_uid = 7;
    int32 caller_target_sdk_version = 8;
    int32 temp_allow_list_calling_uid = 9;
    bool fgs_notification_deferred = 10;
    bool fgs_notification_shown = 11;
    int32 fgs_duration_ms = 12;
    int32 fgs_start_count = 13;

Bug: 171305836
Test: build and run.
Change-Id: I049070f343f578fa3e9f6bb4dab914da5b23672a
This commit is contained in:
Hui Yu
2021-04-08 13:57:02 -07:00
parent a7e6b9481b
commit 13127b8153
2 changed files with 62 additions and 10 deletions

View File

@@ -1850,6 +1850,9 @@ public final class ActiveServices {
showFgsBgRestrictedNotificationLocked(r);
updateServiceForegroundLocked(psr, true);
ignoreForeground = true;
logForegroundServiceStateChanged(r,
FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__DENIED,
0);
if (CompatChanges.isChangeEnabled(FGS_START_EXCEPTION_CHANGE_ID,
r.appInfo.uid)) {
throw new ForegroundServiceStartNotAllowedException(msg);
@@ -1895,6 +1898,7 @@ public final class ActiveServices {
}
r.isForeground = true;
r.mStartForegroundCount++;
r.mFgsEnterTime = SystemClock.uptimeMillis();
if (!stopProcStatsOp) {
ServiceState stracker = r.getTracker();
if (stracker != null) {
@@ -1904,18 +1908,17 @@ public final class ActiveServices {
} else {
stopProcStatsOp = false;
}
postFgsNotificationLocked(r);
mAm.mAppOpsService.startOperation(
AppOpsManager.getToken(mAm.mAppOpsService),
AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName,
null, true, false, "", false);
FrameworkStatsLog.write(FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED,
r.appInfo.uid, r.shortInstanceName,
logForegroundServiceStateChanged(r,
FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__ENTER,
r.mAllowWhileInUsePermissionInFgs);
0);
registerAppOpCallbackLocked(r);
mAm.updateForegroundServiceUsageStats(r.name, r.userId, true);
}
postFgsNotificationLocked(r);
if (r.app != null) {
updateServiceForegroundLocked(psr, true);
}
@@ -1954,6 +1957,7 @@ public final class ActiveServices {
}
r.isForeground = false;
resetFgsRestrictionLocked(r);
r.mFgsExitTime = SystemClock.uptimeMillis();
ServiceState stracker = r.getTracker();
if (stracker != null) {
stracker.setForeground(false, mAm.mProcessStats.getMemFactorLocked(),
@@ -1963,10 +1967,10 @@ public final class ActiveServices {
AppOpsManager.getToken(mAm.mAppOpsService),
AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName, null);
unregisterAppOpCallbackLocked(r);
FrameworkStatsLog.write(FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED,
r.appInfo.uid, r.shortInstanceName,
logForegroundServiceStateChanged(r,
FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__EXIT,
r.mAllowWhileInUsePermissionInFgs);
r.mFgsExitTime > r.mFgsEnterTime
? (int)(r.mFgsExitTime - r.mFgsEnterTime) : 0);
mAm.updateForegroundServiceUsageStats(r.name, r.userId, false);
if (r.app != null) {
mAm.updateLruProcessLocked(r.app, false, null);
@@ -2050,9 +2054,13 @@ public final class ActiveServices {
Slog.d(TAG_SERVICE, "FGS " + r + " non-deferred notification");
}
r.postNotification();
r.mFgsNotificationDeferred = false;
r.mFgsNotificationShown = true;
return;
}
r.mFgsNotificationDeferred = true;
r.mFgsNotificationShown = false;
// schedule the actual notification post
long when = now + mAm.mConstants.mFgsNotificationDeferralInterval;
// If there are already deferred FGS notifications for this app,
@@ -2110,6 +2118,7 @@ public final class ActiveServices {
// the notification.
if (r.isForeground && r.app != null) {
r.postNotification();
r.mFgsNotificationShown = true;
} else if (DEBUG_FOREGROUND_SERVICE) {
Slog.d(TAG_SERVICE, " - service no longer running/fg, ignoring");
}
@@ -3085,6 +3094,12 @@ public final class ActiveServices {
if (r != null) {
r.mRecentCallingPackage = callingPackage;
r.mRecentCallingUid = callingUid;
try {
r.mRecentCallerApplicationInfo =
mAm.mContext.getPackageManager().getApplicationInfoAsUser(callingPackage,
0, userId);
} catch (PackageManager.NameNotFoundException e) {
}
if (!mAm.validateAssociationAllowedLocked(callingPackage, callingUid, r.packageName,
r.appInfo.uid)) {
String msg = "association not allowed between packages "
@@ -4021,10 +4036,11 @@ public final class ActiveServices {
AppOpsManager.getToken(mAm.mAppOpsService),
AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName, null);
unregisterAppOpCallbackLocked(r);
FrameworkStatsLog.write(FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED,
r.appInfo.uid, r.shortInstanceName,
r.mFgsExitTime = SystemClock.uptimeMillis();
logForegroundServiceStateChanged(r,
FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__EXIT,
r.mAllowWhileInUsePermissionInFgs);
r.mFgsExitTime > r.mFgsEnterTime
? (int)(r.mFgsExitTime - r.mFgsEnterTime) : 0);
mAm.updateForegroundServiceUsageStats(r.name, r.userId, false);
}
@@ -5970,4 +5986,29 @@ public final class ActiveServices {
r.mLoggedInfoAllowStartForeground = true;
}
}
/**
* Log the statsd event for FGS.
* @param r ServiceRecord
* @param state one of ENTER/EXIT/DENIED event.
* @param durationMs Only meaningful for EXIT event, the duration from ENTER and EXIT state.
*/
private void logForegroundServiceStateChanged(ServiceRecord r, int state, int durationMs) {
FrameworkStatsLog.write(FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED,
r.appInfo.uid,
r.shortInstanceName,
state,
r.mAllowWhileInUsePermissionInFgs,
r.mAllowStartForeground,
r.appInfo.targetSdkVersion,
r.mRecentCallingUid,
r.mRecentCallerApplicationInfo != null
? r.mRecentCallerApplicationInfo.targetSdkVersion : 0,
r.mInfoTempFgsAllowListReason != null
? r.mInfoTempFgsAllowListReason.mCallingUid : INVALID_UID,
r.mFgsNotificationDeferred,
r.mFgsNotificationShown,
durationMs,
r.mStartForegroundCount);
}
}

View File

@@ -161,6 +161,17 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
String mRecentCallingPackage;
// the most recent uid that start/bind this service.
int mRecentCallingUid;
// ApplicationInfo of the most recent callingPackage that start/bind this service.
@Nullable ApplicationInfo mRecentCallerApplicationInfo;
// The uptime when the service enters FGS state.
long mFgsEnterTime = 0;
// The uptime when the service exits FGS state.
long mFgsExitTime = 0;
// FGS notification was deferred.
boolean mFgsNotificationDeferred;
// FGS notification was shown before the FGS finishes, or it wasn't deferred in the first place.
boolean mFgsNotificationShown;
// allow the service becomes foreground service? Service started from background may not be
// allowed to become a foreground service.