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

Commit e5c0cbfc authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add perf tests for JobStore file reading & writing."

parents 610f4fc1 8843a281
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -1498,16 +1498,16 @@ public class JobSchedulerService extends com.android.server.SystemService
    }

    /**
     * Called when we want to remove a JobStatus object that we've finished executing. Returns the
     * object removed.
     * Called when we want to remove a JobStatus object that we've finished executing.
     * @return true if the job was removed.
     */
    private boolean stopTrackingJobLocked(JobStatus jobStatus, JobStatus incomingJob,
            boolean writeBack) {
            boolean removeFromPersisted) {
        // Deal with any remaining work items in the old job.
        jobStatus.stopTrackingJobLocked(ActivityManager.getService(), incomingJob);

        // Remove from store as well as controllers.
        final boolean removed = mJobs.remove(jobStatus, writeBack);
        final boolean removed = mJobs.remove(jobStatus, removeFromPersisted);
        if (removed && mReadyToRock) {
            for (int i=0; i<mControllers.size(); i++) {
                StateController controller = mControllers.get(i);
+20 −4
Original line number Diff line number Diff line
@@ -235,10 +235,11 @@ public final class JobStore {

    /**
     * Remove the provided job. Will also delete the job if it was persisted.
     * @param writeBack If true, the job will be deleted (if it was persisted) immediately.
     * @param removeFromPersisted If true, the job will be removed from the persisted job list
     *                            immediately (if it was persisted).
     * @return Whether or not the job existed to be removed.
     */
    public boolean remove(JobStatus jobStatus, boolean writeBack) {
    public boolean remove(JobStatus jobStatus, boolean removeFromPersisted) {
        boolean removed = mJobSet.remove(jobStatus);
        if (!removed) {
            if (DEBUG) {
@@ -246,7 +247,7 @@ public final class JobStore {
            }
            return false;
        }
        if (writeBack && jobStatus.isPersisted()) {
        if (removeFromPersisted && jobStatus.isPersisted()) {
            maybeWriteStatusToDiskAsync();
        }
        return removed;
@@ -344,6 +345,19 @@ public final class JobStore {
        new ReadJobMapFromDiskRunnable(jobSet, rtcGood).run();
    }

    /** Write persisted JobStore state to disk synchronously. Should only be used for testing. */
    @VisibleForTesting
    public void writeStatusToDiskForTesting() {
        synchronized (mWriteScheduleLock) {
            if (mWriteScheduled) {
                throw new IllegalStateException("An asynchronous write is already scheduled.");
            }

            mWriteScheduled = mWriteInProgress = true;
            mWriteRunnable.run();
        }
    }

    /**
     * Wait for any pending write to the persistent store to clear
     * @param maxWaitMillis Maximum time from present to wait
@@ -1049,7 +1063,9 @@ public final class JobStore {
        }
    }

    static final class JobSet {
    /** Set of all tracked jobs. */
    @VisibleForTesting
    public static final class JobSet {
        @VisibleForTesting // Key is the getUid() originator of the jobs in each sheaf
        final SparseArray<ArraySet<JobStatus>> mJobs;

+5 −18
Original line number Diff line number Diff line
@@ -24,7 +24,6 @@ import android.app.job.JobInfo;
import android.app.job.JobWorkItem;
import android.content.ClipData;
import android.content.ComponentName;
import android.content.pm.PackageManagerInternal;
import android.net.Network;
import android.net.Uri;
import android.os.RemoteException;
@@ -131,7 +130,6 @@ public final class JobStatus {
     * that underly Sync Manager operation.
     */
    final int callingUid;
    final int targetSdkVersion;
    final String batteryName;

    /**
@@ -344,7 +342,6 @@ public final class JobStatus {
     * @param job The actual requested parameters for the job
     * @param callingUid Identity of the app that is scheduling the job.  This may not be the
     *     app in which the job is implemented; such as with sync jobs.
     * @param targetSdkVersion The targetSdkVersion of the app in which the job will run.
     * @param sourcePackageName The package name of the app in which the job will run.
     * @param sourceUserId The user in which the job will run
     * @param standbyBucket The standby bucket that the source package is currently assigned to,
@@ -363,13 +360,12 @@ public final class JobStatus {
     * @param lastFailedRunTime When did we last run this job only to have it stop incomplete?
     * @param internalFlags Non-API property flags about this job
     */
    private JobStatus(JobInfo job, int callingUid, int targetSdkVersion, String sourcePackageName,
    private JobStatus(JobInfo job, int callingUid, String sourcePackageName,
            int sourceUserId, int standbyBucket, long heartbeat, String tag, int numFailures,
            long earliestRunTimeElapsedMillis, long latestRunTimeElapsedMillis,
            long lastSuccessfulRunTime, long lastFailedRunTime, int internalFlags) {
        this.job = job;
        this.callingUid = callingUid;
        this.targetSdkVersion = targetSdkVersion;
        this.standbyBucket = standbyBucket;
        this.baseHeartbeat = heartbeat;

@@ -439,7 +435,7 @@ public final class JobStatus {
    /** Copy constructor: used specifically when cloning JobStatus objects for persistence,
     *   so we preserve RTC window bounds if the source object has them. */
    public JobStatus(JobStatus jobStatus) {
        this(jobStatus.getJob(), jobStatus.getUid(), jobStatus.targetSdkVersion,
        this(jobStatus.getJob(), jobStatus.getUid(),
                jobStatus.getSourcePackageName(), jobStatus.getSourceUserId(),
                jobStatus.getStandbyBucket(), jobStatus.getBaseHeartbeat(),
                jobStatus.getSourceTag(), jobStatus.getNumFailures(),
@@ -468,7 +464,7 @@ public final class JobStatus {
            long lastSuccessfulRunTime, long lastFailedRunTime,
            Pair<Long, Long> persistedExecutionTimesUTC,
            int innerFlags) {
        this(job, callingUid, resolveTargetSdkVersion(job), sourcePkgName, sourceUserId,
        this(job, callingUid, sourcePkgName, sourceUserId,
                standbyBucket, baseHeartbeat,
                sourceTag, 0,
                earliestRunTimeElapsedMillis, latestRunTimeElapsedMillis,
@@ -491,7 +487,7 @@ public final class JobStatus {
            long newEarliestRuntimeElapsedMillis,
            long newLatestRuntimeElapsedMillis, int backoffAttempt,
            long lastSuccessfulRunTime, long lastFailedRunTime) {
        this(rescheduling.job, rescheduling.getUid(), resolveTargetSdkVersion(rescheduling.job),
        this(rescheduling.job, rescheduling.getUid(),
                rescheduling.getSourcePackageName(), rescheduling.getSourceUserId(),
                rescheduling.getStandbyBucket(), newBaseHeartbeat,
                rescheduling.getSourceTag(), backoffAttempt, newEarliestRuntimeElapsedMillis,
@@ -533,7 +529,7 @@ public final class JobStatus {
        long currentHeartbeat = js != null
                ? js.baseHeartbeatForApp(jobPackage, sourceUserId, standbyBucket)
                : 0;
        return new JobStatus(job, callingUid, resolveTargetSdkVersion(job), sourcePkg, sourceUserId,
        return new JobStatus(job, callingUid, sourcePkg, sourceUserId,
                standbyBucket, currentHeartbeat, tag, 0,
                earliestRunTimeElapsedMillis, latestRunTimeElapsedMillis,
                0 /* lastSuccessfulRunTime */, 0 /* lastFailedRunTime */,
@@ -681,10 +677,6 @@ public final class JobStatus {
        return job.getId();
    }

    public int getTargetSdkVersion() {
        return targetSdkVersion;
    }

    public void printUniqueId(PrintWriter pw) {
        UserHandle.formatUid(pw, callingUid);
        pw.print("/");
@@ -1441,11 +1433,6 @@ public final class JobStatus {
        }
    }

    private static int resolveTargetSdkVersion(JobInfo job) {
        return LocalServices.getService(PackageManagerInternal.class)
                .getPackageTargetSdkVersion(job.getService().getPackageName());
    }

    // Dumpsys infrastructure
    public void dump(PrintWriter pw, String prefix, boolean full, long elapsedRealtimeMillis) {
        pw.print(prefix); UserHandle.formatUid(pw, callingUid);
+25 −0
Original line number Diff line number Diff line
// Copyright (C) 2019 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

android_test {
    name: "JobSchedulerPerfTests",
    srcs: ["src/**/*.java"],
    static_libs: [
        "androidx.test.rules",
        "apct-perftests-utils",
        "services",
    ],
    platform_apis: true,
    certificate: "platform",
}
+27 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2018 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.android.frameworks.perftests.job">
    <uses-sdk
            android:minSdkVersion="21" />

    <application>
        <uses-library android:name="android.test.runner" />
    </application>

    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
                     android:targetPackage="com.android.frameworks.perftests.job"/>
</manifest>
Loading