Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 13127b81 authored by Hui Yu's avatar Hui Yu
Browse files

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
parent a7e6b948
Loading
Loading
Loading
Loading
+51 −10
Original line number Diff line number Diff line
@@ -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);
    }
}
+11 −0
Original line number Diff line number Diff line
@@ -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.