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

Commit a3284c39 authored by Kweku Adams's avatar Kweku Adams Committed by Android (Google) Code Review
Browse files

Merge "Move JobServiceContext handling to the concurrency manager." into tm-dev

parents ddf19a48 28565428
Loading
Loading
Loading
Loading
+160 −2
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.server.job;

import static com.android.server.job.JobSchedulerService.MAX_JOB_CONTEXTS_COUNT;
import static com.android.server.job.JobSchedulerService.RESTRICTED_INDEX;
import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock;

import android.annotation.IntDef;
@@ -32,9 +33,11 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.UserInfo;
import android.os.BatteryStats;
import android.os.Handler;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.util.ArraySet;
@@ -51,19 +54,24 @@ import android.util.proto.ProtoOutputStream;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IBatteryStats;
import com.android.internal.app.procstats.ProcessStats;
import com.android.internal.util.StatLogger;
import com.android.server.JobSchedulerBackgroundThread;
import com.android.server.LocalServices;
import com.android.server.job.controllers.JobStatus;
import com.android.server.job.controllers.StateController;
import com.android.server.job.restrictions.JobRestriction;
import com.android.server.pm.UserManagerInternal;

import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;

/**
 * This class decides, given the various configuration and the system status, which jobs can start
@@ -278,6 +286,11 @@ class JobConcurrencyManager {

    String[] mRecycledShouldStopJobReason = new String[MAX_JOB_CONTEXTS_COUNT];

    /**
     * Set of JobServiceContexts that we use to run jobs.
     */
    final List<JobServiceContext> mActiveServices = new ArrayList<>();

    private final ArraySet<JobStatus> mRunningJobs = new ArraySet<>();

    private final WorkCountTracker mWorkCountTracker = new WorkCountTracker();
@@ -358,6 +371,20 @@ class JobConcurrencyManager {
        onInteractiveStateChanged(mPowerManager.isInteractive());
    }

    /**
     * Called when the boot phase reaches
     * {@link com.android.server.SystemService#PHASE_THIRD_PARTY_APPS_CAN_START}.
     */
    void onThirdPartyAppsCanStart() {
        final IBatteryStats batteryStats = IBatteryStats.Stub.asInterface(
                ServiceManager.getService(BatteryStats.SERVICE_NAME));
        for (int i = 0; i < MAX_JOB_CONTEXTS_COUNT; i++) {
            mActiveServices.add(
                    new JobServiceContext(mService, this, batteryStats,
                            mService.mJobPackageTracker, mContext.getMainLooper()));
        }
    }

    @GuardedBy("mLock")
    void onAppRemovedLocked(String pkgName, int uid) {
        final PackageStats packageStats = mActivePkgStats.get(UserHandle.getUserId(uid), pkgName);
@@ -390,6 +417,7 @@ class JobConcurrencyManager {
                case PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED:
                    if (mPowerManager != null && mPowerManager.isDeviceIdleMode()) {
                        synchronized (mLock) {
                            stopUnexemptedJobsForDoze();
                            stopLongRunningJobsLocked("deep doze");
                        }
                    }
@@ -470,6 +498,11 @@ class JobConcurrencyManager {
        }
    }

    @GuardedBy("mLock")
    ArraySet<JobStatus> getRunningJobsLocked() {
        return mRunningJobs;
    }

    @GuardedBy("mLock")
    boolean isJobRunningLocked(JobStatus job) {
        return mRunningJobs.contains(job);
@@ -546,7 +579,7 @@ class JobConcurrencyManager {
        }

        final List<JobStatus> pendingJobs = mService.mPendingJobs;
        final List<JobServiceContext> activeServices = mService.mActiveServices;
        final List<JobServiceContext> activeServices = mActiveServices;

        // To avoid GC churn, we recycle the arrays.
        JobStatus[] contextIdToJobMap = mRecycledAssignContextIdToJobMap;
@@ -718,10 +751,45 @@ class JobConcurrencyManager {
        noteConcurrency();
    }

    @GuardedBy("mLock")
    boolean stopJobOnServiceContextLocked(JobStatus job,
            @JobParameters.StopReason int reason, int internalReasonCode, String debugReason) {
        if (!mRunningJobs.contains(job)) {
            return false;
        }

        for (int i = 0; i < mActiveServices.size(); i++) {
            JobServiceContext jsc = mActiveServices.get(i);
            final JobStatus executing = jsc.getRunningJobLocked();
            if (executing != null && executing.matches(job.getUid(), job.getJobId())) {
                jsc.cancelExecutingJobLocked(reason, internalReasonCode, debugReason);
                return true;
            }
        }
        Slog.wtf(TAG, "Couldn't find running job on a context");
        mRunningJobs.remove(job);
        return false;
    }

    @GuardedBy("mLock")
    private void stopUnexemptedJobsForDoze() {
        // When becoming idle, make sure no jobs are actively running,
        // except those using the idle exemption flag.
        for (int i = 0; i < mActiveServices.size(); i++) {
            JobServiceContext jsc = mActiveServices.get(i);
            final JobStatus executing = jsc.getRunningJobLocked();
            if (executing != null && !executing.canRunInDoze()) {
                jsc.cancelExecutingJobLocked(JobParameters.STOP_REASON_DEVICE_STATE,
                        JobParameters.INTERNAL_STOP_REASON_DEVICE_IDLE,
                        "cancelled due to doze");
            }
        }
    }

    @GuardedBy("mLock")
    private void stopLongRunningJobsLocked(@NonNull String debugReason) {
        for (int i = 0; i < MAX_JOB_CONTEXTS_COUNT; ++i) {
            final JobServiceContext jsc = mService.mActiveServices.get(i);
            final JobServiceContext jsc = mActiveServices.get(i);
            final JobStatus jobStatus = jsc.getRunningJobLocked();

            if (jobStatus != null && !jsc.isWithinExecutionGuaranteeTime()) {
@@ -731,6 +799,41 @@ class JobConcurrencyManager {
        }
    }

    @GuardedBy("mLock")
    void stopNonReadyActiveJobsLocked() {
        for (int i = 0; i < mActiveServices.size(); i++) {
            JobServiceContext serviceContext = mActiveServices.get(i);
            final JobStatus running = serviceContext.getRunningJobLocked();
            if (running == null) {
                continue;
            }
            if (!running.isReady()) {
                if (running.getEffectiveStandbyBucket() == RESTRICTED_INDEX
                        && running.getStopReason() == JobParameters.STOP_REASON_APP_STANDBY) {
                    serviceContext.cancelExecutingJobLocked(
                            running.getStopReason(),
                            JobParameters.INTERNAL_STOP_REASON_RESTRICTED_BUCKET,
                            "cancelled due to restricted bucket");
                } else {
                    serviceContext.cancelExecutingJobLocked(
                            running.getStopReason(),
                            JobParameters.INTERNAL_STOP_REASON_CONSTRAINTS_NOT_SATISFIED,
                            "cancelled due to unsatisfied constraints");
                }
            } else {
                final JobRestriction restriction = mService.checkIfRestricted(running);
                if (restriction != null) {
                    final int internalReasonCode = restriction.getInternalReason();
                    serviceContext.cancelExecutingJobLocked(restriction.getReason(),
                            internalReasonCode,
                            "restricted due to "
                                    + JobParameters.getInternalReasonCodeDescription(
                                    internalReasonCode));
                }
            }
        }
    }

    private void noteConcurrency() {
        mService.mJobPackageTracker.noteConcurrency(mRunningJobs.size(),
                // TODO: log per type instead of only TOP
@@ -1077,6 +1180,24 @@ class JobConcurrencyManager {
        return null;
    }

    @GuardedBy("mLock")
    boolean executeTimeoutCommandLocked(PrintWriter pw, String pkgName, int userId,
            boolean hasJobId, int jobId) {
        boolean foundSome = false;
        for (int i = 0; i < mActiveServices.size(); i++) {
            final JobServiceContext jc = mActiveServices.get(i);
            final JobStatus js = jc.getRunningJobLocked();
            if (jc.timeoutIfExecutingLocked(pkgName, userId, hasJobId, jobId, "shell")) {
                foundSome = true;
                pw.print("Timing out: ");
                js.printUniqueId(pw);
                pw.print(" ");
                pw.println(js.getServiceComponent().flattenToShortString());
            }
        }
        return foundSome;
    }

    @GuardedBy("mLock")
    private String printPendingQueueLocked() {
        StringBuilder s = new StringBuilder("Pending queue: ");
@@ -1200,6 +1321,43 @@ class JobConcurrencyManager {
        }
    }

    @GuardedBy("mLock")
    void dumpActiveJobsLocked(IndentingPrintWriter pw, Predicate<JobStatus> predicate,
            long nowElapsed, long nowUptime) {
        pw.println("Active jobs:");
        pw.increaseIndent();
        for (int i = 0; i < mActiveServices.size(); i++) {
            JobServiceContext jsc = mActiveServices.get(i);
            final JobStatus job = jsc.getRunningJobLocked();

            if (job != null && !predicate.test(job)) {
                continue;
            }

            pw.print("Slot #"); pw.print(i); pw.print(": ");
            jsc.dumpLocked(pw, nowElapsed);

            if (job != null) {
                pw.increaseIndent();

                pw.increaseIndent();
                job.dump(pw, false, nowElapsed);
                pw.decreaseIndent();

                pw.print("Evaluated bias: ");
                pw.println(JobInfo.getBiasString(job.lastEvaluatedBias));

                pw.print("Active at ");
                TimeUtils.formatDuration(job.madeActive - nowUptime, pw);
                pw.print(", pending for ");
                TimeUtils.formatDuration(job.madeActive - job.madePending, pw);
                pw.decreaseIndent();
                pw.println();
            }
        }
        pw.decreaseIndent();
    }

    public void dumpProtoLocked(ProtoOutputStream proto, long tag, long now, long nowRealtime) {
        final long token = proto.start(tag);

+21 −169
Original line number Diff line number Diff line
@@ -57,7 +57,6 @@ import android.content.pm.ServiceInfo;
import android.net.Uri;
import android.os.BatteryManager;
import android.os.BatteryManagerInternal;
import android.os.BatteryStats;
import android.os.BatteryStatsInternal;
import android.os.Binder;
import android.os.Handler;
@@ -67,7 +66,6 @@ import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.WorkSource;
@@ -90,7 +88,6 @@ import android.util.proto.ProtoOutputStream;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IBatteryStats;
import com.android.internal.os.SomeArgs;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.DumpUtils;
@@ -100,7 +97,6 @@ import com.android.server.AppStateTrackerImpl;
import com.android.server.DeviceIdleInternal;
import com.android.server.JobSchedulerBackgroundThread;
import com.android.server.LocalServices;
import com.android.server.job.JobSchedulerServiceDumpProto.ActiveJob;
import com.android.server.job.JobSchedulerServiceDumpProto.PendingJob;
import com.android.server.job.controllers.BackgroundJobsController;
import com.android.server.job.controllers.BatteryController;
@@ -243,12 +239,6 @@ public class JobSchedulerService extends com.android.server.SystemService
    static final int MSG_CHECK_CHANGED_JOB_LIST = 8;
    static final int MSG_CHECK_MEDIA_EXEMPTION = 9;

    /**
     * Track Services that have currently active or pending jobs. The index is provided by
     * {@link JobStatus#getServiceToken()}
     */
    final List<JobServiceContext> mActiveServices = new ArrayList<>();

    /** List of controllers that will notify this service of updates to jobs. */
    final List<StateController> mControllers;
    /**
@@ -307,7 +297,6 @@ public class JobSchedulerService extends com.android.server.SystemService

    PackageManagerInternal mLocalPM;
    ActivityManagerInternal mActivityManagerInternal;
    IBatteryStats mBatteryStats;
    DeviceIdleInternal mLocalDeviceIdleController;
    @VisibleForTesting
    AppStateTrackerImpl mAppStateTracker;
@@ -1578,7 +1567,8 @@ public class JobSchedulerService extends com.android.server.SystemService
            mJobPackageTracker.noteNonpending(cancelled);
        }
        // Cancel if running.
        stopJobOnServiceContextLocked(cancelled, reason, internalReasonCode, debugReason);
        mConcurrencyManager.stopJobOnServiceContextLocked(
                cancelled, reason, internalReasonCode, debugReason);
        // If this is a replacement, bring in the new version of the job
        if (incomingJob != null) {
            if (DEBUG) Slog.i(TAG, "Tracking replacement job " + incomingJob.toShortString());
@@ -1627,19 +1617,7 @@ public class JobSchedulerService extends com.android.server.SystemService
            if (DEBUG) {
                Slog.d(TAG, "Doze state changed: " + deviceIdle);
            }
            if (deviceIdle) {
                // When becoming idle, make sure no jobs are actively running,
                // except those using the idle exemption flag.
                for (int i=0; i<mActiveServices.size(); i++) {
                    JobServiceContext jsc = mActiveServices.get(i);
                    final JobStatus executing = jsc.getRunningJobLocked();
                    if (executing != null && !executing.canRunInDoze()) {
                        jsc.cancelExecutingJobLocked(JobParameters.STOP_REASON_DEVICE_STATE,
                                JobParameters.INTERNAL_STOP_REASON_DEVICE_IDLE,
                                "cancelled due to doze");
                    }
                }
            } else {
            if (!deviceIdle) {
                // When coming out of idle, allow thing to start back up.
                if (mReadyToRock) {
                    if (mLocalDeviceIdleController != null) {
@@ -1682,10 +1660,10 @@ public class JobSchedulerService extends com.android.server.SystemService
        // active is true if pending queue contains jobs OR some job is running.
        boolean active = mPendingJobs.size() > 0;
        if (mPendingJobs.size() <= 0) {
            for (int i=0; i<mActiveServices.size(); i++) {
                final JobServiceContext jsc = mActiveServices.get(i);
                final JobStatus job = jsc.getRunningJobLocked();
                if (job != null && !job.canRunInDoze()) {
            final ArraySet<JobStatus> runningJobs = mConcurrencyManager.getRunningJobsLocked();
            for (int i = runningJobs.size() - 1; i >= 0; --i) {
                final JobStatus job = runningJobs.valueAt(i);
                if (!job.canRunInDoze()) {
                    // We will report active if we have a job running and it does not have an
                    // exception that allows it to run in Doze.
                    active = true;
@@ -1895,16 +1873,9 @@ public class JobSchedulerService extends com.android.server.SystemService
            synchronized (mLock) {
                // Let's go!
                mReadyToRock = true;
                mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService(
                        BatteryStats.SERVICE_NAME));
                mLocalDeviceIdleController =
                        LocalServices.getService(DeviceIdleInternal.class);
                // Create the "runners".
                for (int i = 0; i < MAX_JOB_CONTEXTS_COUNT; i++) {
                    mActiveServices.add(
                            new JobServiceContext(this, mConcurrencyManager, mBatteryStats,
                                    mJobPackageTracker, getContext().getMainLooper()));
                }
                mConcurrencyManager.onThirdPartyAppsCanStart();
                // Attach jobs to their controllers.
                mJobs.forEachJob((job) -> {
                    for (int controller = 0; controller < mControllers.size(); controller++) {
@@ -1961,19 +1932,6 @@ public class JobSchedulerService extends com.android.server.SystemService
        return removed;
    }

    private boolean stopJobOnServiceContextLocked(JobStatus job,
            @JobParameters.StopReason int reason, int internalReasonCode, String debugReason) {
        for (int i = 0; i < mActiveServices.size(); i++) {
            JobServiceContext jsc = mActiveServices.get(i);
            final JobStatus executing = jsc.getRunningJobLocked();
            if (executing != null && executing.matches(job.getUid(), job.getJobId())) {
                jsc.cancelExecutingJobLocked(reason, internalReasonCode, debugReason);
                return true;
            }
        }
        return false;
    }

    /** Return {@code true} if the specified job is currently executing. */
    @GuardedBy("mLock")
    public boolean isCurrentlyRunningLocked(JobStatus job) {
@@ -2383,7 +2341,8 @@ public class JobSchedulerService extends com.android.server.SystemService
     * - if passes all the restrictions or has {@link JobInfo#BIAS_FOREGROUND_SERVICE} bias
     * or higher.
     */
    private JobRestriction checkIfRestricted(JobStatus job) {
    @GuardedBy("mLock")
    JobRestriction checkIfRestricted(JobStatus job) {
        if (evaluateJobBiasLocked(job) >= JobInfo.BIAS_FOREGROUND_SERVICE) {
            // Jobs with BIAS_FOREGROUND_SERVICE or higher should not be restricted
            return null;
@@ -2397,38 +2356,9 @@ public class JobSchedulerService extends com.android.server.SystemService
        return null;
    }

    @GuardedBy("mLock")
    private void stopNonReadyActiveJobsLocked() {
        for (int i=0; i<mActiveServices.size(); i++) {
            JobServiceContext serviceContext = mActiveServices.get(i);
            final JobStatus running = serviceContext.getRunningJobLocked();
            if (running == null) {
                continue;
            }
            if (!running.isReady()) {
                if (running.getEffectiveStandbyBucket() == RESTRICTED_INDEX
                        && running.getStopReason() == JobParameters.STOP_REASON_APP_STANDBY) {
                    serviceContext.cancelExecutingJobLocked(
                            running.getStopReason(),
                            JobParameters.INTERNAL_STOP_REASON_RESTRICTED_BUCKET,
                            "cancelled due to restricted bucket");
                } else {
                    serviceContext.cancelExecutingJobLocked(
                            running.getStopReason(),
                            JobParameters.INTERNAL_STOP_REASON_CONSTRAINTS_NOT_SATISFIED,
                            "cancelled due to unsatisfied constraints");
                }
            } else {
                final JobRestriction restriction = checkIfRestricted(running);
                if (restriction != null) {
                    final int internalReasonCode = restriction.getInternalReason();
                    serviceContext.cancelExecutingJobLocked(restriction.getReason(),
                            internalReasonCode,
                            "restricted due to "
                                    + JobParameters.getInternalReasonCodeDescription(
                                    internalReasonCode));
                }
            }
        }
        mConcurrencyManager.stopNonReadyActiveJobsLocked();
    }

    /**
@@ -2598,7 +2528,7 @@ public class JobSchedulerService extends com.android.server.SystemService
                            debugReason = "couldn't figure out why the job should stop running";
                        }
                    }
                    stopJobOnServiceContextLocked(job, job.getStopReason(),
                    mConcurrencyManager.stopJobOnServiceContextLocked(job, job.getStopReason(),
                            internalStopReason, debugReason);
                } else if (mPendingJobs.remove(job)) {
                    noteJobNonPending(job);
@@ -3516,9 +3446,11 @@ public class JobSchedulerService extends com.android.server.SystemService
            final ArrayList<JobInfo> runningJobs;

            synchronized (mLock) {
                runningJobs = new ArrayList<>(mActiveServices.size());
                for (JobServiceContext jsc : mActiveServices) {
                    final JobStatus job = jsc.getRunningJobLocked();
                final ArraySet<JobStatus> runningJobStatuses =
                        mConcurrencyManager.getRunningJobsLocked();
                runningJobs = new ArrayList<>(runningJobStatuses.size());
                for (int i = runningJobStatuses.size() - 1; i >= 0; --i) {
                    final JobStatus job = runningJobStatuses.valueAt(i);
                    if (job != null) {
                        runningJobs.add(job.getJob());
                    }
@@ -3599,18 +3531,8 @@ public class JobSchedulerService extends com.android.server.SystemService
        }

        synchronized (mLock) {
            boolean foundSome = false;
            for (int i = 0; i < mActiveServices.size(); i++) {
                final JobServiceContext jc = mActiveServices.get(i);
                final JobStatus js = jc.getRunningJobLocked();
                if (jc.timeoutIfExecutingLocked(pkgName, userId, hasJobId, jobId, "shell")) {
                    foundSome = true;
                    pw.print("Timing out: ");
                    js.printUniqueId(pw);
                    pw.print(" ");
                    pw.println(js.getServiceComponent().flattenToShortString());
                }
            }
            final boolean foundSome = mConcurrencyManager.executeTimeoutCommandLocked(pw,
                    pkgName, userId, hasJobId, jobId);
            if (!foundSome) {
                pw.println("No matching executing jobs found.");
            }
@@ -4037,38 +3959,7 @@ public class JobSchedulerService extends com.android.server.SystemService
            pw.decreaseIndent();

            pw.println();
            pw.println("Active jobs:");
            pw.increaseIndent();
            for (int i=0; i<mActiveServices.size(); i++) {
                JobServiceContext jsc = mActiveServices.get(i);
                final JobStatus job = jsc.getRunningJobLocked();

                if (job != null && !predicate.test(job)) {
                    continue;
                }

                pw.print("Slot #"); pw.print(i); pw.print(": ");
                jsc.dumpLocked(pw, nowElapsed);

                if (job != null) {
                    pw.increaseIndent();

                    pw.increaseIndent();
                    job.dump(pw, false, nowElapsed);
                    pw.decreaseIndent();

                    pw.print("Evaluated bias: ");
                    pw.println(JobInfo.getBiasString(job.lastEvaluatedBias));

                    pw.print("Active at ");
                    TimeUtils.formatDuration(job.madeActive - nowUptime, pw);
                    pw.print(", pending for ");
                    TimeUtils.formatDuration(job.madeActive - job.madePending, pw);
                    pw.decreaseIndent();
                    pw.println();
                }
            }
            pw.decreaseIndent();
            mConcurrencyManager.dumpActiveJobsLocked(pw, predicate, nowElapsed, nowUptime);

            pw.println();
            boolean recentPrinted = false;
@@ -4228,45 +4119,6 @@ public class JobSchedulerService extends com.android.server.SystemService

                proto.end(pjToken);
            }
            for (JobServiceContext jsc : mActiveServices) {
                final long ajToken = proto.start(JobSchedulerServiceDumpProto.ACTIVE_JOBS);
                final JobStatus job = jsc.getRunningJobLocked();

                if (job == null) {
                    final long ijToken = proto.start(ActiveJob.INACTIVE);

                    proto.write(ActiveJob.InactiveJob.TIME_SINCE_STOPPED_MS,
                            nowElapsed - jsc.mStoppedTime);
                    if (jsc.mStoppedReason != null) {
                        proto.write(ActiveJob.InactiveJob.STOPPED_REASON,
                                jsc.mStoppedReason);
                    }

                    proto.end(ijToken);
                } else {
                    final long rjToken = proto.start(ActiveJob.RUNNING);

                    job.writeToShortProto(proto, ActiveJob.RunningJob.INFO);

                    proto.write(ActiveJob.RunningJob.RUNNING_DURATION_MS,
                            nowElapsed - jsc.getExecutionStartTimeElapsed());
                    proto.write(ActiveJob.RunningJob.TIME_UNTIL_TIMEOUT_MS,
                            jsc.getTimeoutElapsed() - nowElapsed);

                    job.dump(proto, ActiveJob.RunningJob.DUMP, false, nowElapsed);

                    proto.write(ActiveJob.RunningJob.EVALUATED_PRIORITY,
                            evaluateJobBiasLocked(job));

                    proto.write(ActiveJob.RunningJob.TIME_SINCE_MADE_ACTIVE_MS,
                            nowUptime - job.madeActive);
                    proto.write(ActiveJob.RunningJob.PENDING_DURATION_MS,
                            job.madeActive - job.madePending);

                    proto.end(rjToken);
                }
                proto.end(ajToken);
            }
            if (filterUid == -1) {
                proto.write(JobSchedulerServiceDumpProto.IS_READY_TO_ROCK, mReadyToRock);
                proto.write(JobSchedulerServiceDumpProto.REPORTED_ACTIVE, mReportedActive);
+0 −5
Original line number Diff line number Diff line
@@ -441,11 +441,6 @@ public final class JobStatus {
    /** The reason a job most recently went from ready to not ready. */
    private int mReasonReadyToUnready = JobParameters.STOP_REASON_UNDEFINED;

    /** Provide a handle to the service that this job will be run on. */
    public int getServiceToken() {
        return callingUid;
    }

    /**
     * Core constructor for JobStatus instances.  All other ctors funnel down to this one.
     *