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

Commit 65a72578 authored by Suprabh Shukla's avatar Suprabh Shukla
Browse files

Log when job quota is reduced for buggy apps

Count the times job scheduler artificially lowers quota for a job
because it considers the caller buggy due to excessive job timeouts.

The logic is refactored to allow simpler logging, but no other
functional change is intended.

Test: statsd_testdrive 528

Existing job tests:
Test: atest FrameworksMockingServicesTests:JobSchedulerServiceTest
Test: atest FrameworksMockingServicesTests:JobStatusTest

Bug: 291146667
Change-Id: I62654be0a0cdc713a17146c3ec612b37e8283b3e
Merged-In: I62654be0a0cdc713a17146c3ec612b37e8283b3e
parent 5791ab0d
Loading
Loading
Loading
Loading
+26 −8
Original line number Original line Diff line number Diff line
@@ -56,6 +56,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.FrameworkStatsLog;
import com.android.modules.expresslog.Counter;
import com.android.server.LocalServices;
import com.android.server.LocalServices;
import com.android.server.job.GrantedUriPermissions;
import com.android.server.job.GrantedUriPermissions;
import com.android.server.job.JobSchedulerInternal;
import com.android.server.job.JobSchedulerInternal;
@@ -161,6 +162,9 @@ public final class JobStatus {
    /** If the job is going to be passed an unmetered network. */
    /** If the job is going to be passed an unmetered network. */
    private boolean mHasAccessToUnmetered;
    private boolean mHasAccessToUnmetered;


    /** If the effective bucket has been downgraded once due to being buggy. */
    private boolean mIsDowngradedDueToBuggyApp;

    /**
    /**
     * The additional set of dynamic constraints that must be met if this is an expedited job that
     * The additional set of dynamic constraints that must be met if this is an expedited job that
     * had a long enough run while the device was Dozing or in battery saver.
     * had a long enough run while the device was Dozing or in battery saver.
@@ -1173,18 +1177,32 @@ public final class JobStatus {
            // like other ACTIVE apps.
            // like other ACTIVE apps.
            return ACTIVE_INDEX;
            return ACTIVE_INDEX;
        }
        }

        final int bucketWithMediaExemption;
        if (actualBucket != RESTRICTED_INDEX && actualBucket != NEVER_INDEX
                && mHasMediaBackupExemption) {
            // Treat it as if it's at most WORKING_INDEX (lower index grants higher quota) since
            // media backup jobs are important to the user, and the source package may not have
            // been used directly in a while.
            bucketWithMediaExemption = Math.min(WORKING_INDEX, actualBucket);
        } else {
            bucketWithMediaExemption = actualBucket;
        }

        // If the app is considered buggy, but hasn't yet been put in the RESTRICTED bucket
        // If the app is considered buggy, but hasn't yet been put in the RESTRICTED bucket
        // (potentially because it's used frequently by the user), limit its effective bucket
        // (potentially because it's used frequently by the user), limit its effective bucket
        // so that it doesn't get to run as much as a normal ACTIVE app.
        // so that it doesn't get to run as much as a normal ACTIVE app.
        final int highestBucket = isBuggy ? WORKING_INDEX : ACTIVE_INDEX;
        if (isBuggy && bucketWithMediaExemption < WORKING_INDEX) {
        if (actualBucket != RESTRICTED_INDEX && actualBucket != NEVER_INDEX
            if (!mIsDowngradedDueToBuggyApp) {
                && mHasMediaBackupExemption) {
                // Safety check to avoid logging multiple times for the same job.
            // Treat it as if it's at least WORKING_INDEX since media backup jobs are important
                Counter.logIncrementWithUid(
            // to the user, and the
                        "job_scheduler.value_job_quota_reduced_due_to_buggy_uid",
            // source package may not have been used directly in a while.
                        getTimeoutBlameUid());
            return Math.max(highestBucket, Math.min(WORKING_INDEX, actualBucket));
                mIsDowngradedDueToBuggyApp = true;
            }
            return WORKING_INDEX;
        }
        }
        return Math.max(highestBucket, actualBucket);
        return bucketWithMediaExemption;
    }
    }


    /** Returns the real standby bucket of the job. */
    /** Returns the real standby bucket of the job. */