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

Commit 8c0c3c10 authored by Wei Wang's avatar Wei Wang
Browse files

Throttle jobs when thermal status is in THROTTLING_SEVERE and above

Bug: 116541003
Test: manually lower thermal thresholds on Pixel3
Change-Id: I26344716e2b6d84a04d9da02493673cc48c2854d
parent efd355c1
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -47,6 +47,8 @@ public class JobParameters implements Parcelable {
    public static final int REASON_TIMEOUT = JobProtoEnums.STOP_REASON_TIMEOUT; // 3.
    /** @hide */
    public static final int REASON_DEVICE_IDLE = JobProtoEnums.STOP_REASON_DEVICE_IDLE; // 4.
    /** @hide */
    public static final int REASON_DEVICE_THERMAL = JobProtoEnums.STOP_REASON_DEVICE_THERMAL; // 5.

    /** @hide */
    public static String getReasonName(int reason) {
+1 −0
Original line number Diff line number Diff line
@@ -30,4 +30,5 @@ enum StopReasonEnum {
    STOP_REASON_PREEMPT = 2;
    STOP_REASON_TIMEOUT = 3;
    STOP_REASON_DEVICE_IDLE = 4;
    STOP_REASON_DEVICE_THERMAL = 5;
}
+1 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ message JobSchedulerServiceDumpProto {
    optional int64 last_heartbeat_time_millis = 16;
    optional int64 next_heartbeat_time_millis = 17;
    optional bool in_parole = 18;
    optional bool in_thermal = 19;

    repeated int32 started_users = 2;

+53 −1
Original line number Diff line number Diff line
@@ -54,6 +54,8 @@ import android.os.BatteryStats;
import android.os.BatteryStatsInternal;
import android.os.Binder;
import android.os.Handler;
import android.os.IThermalService;
import android.os.IThermalStatusListener;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
@@ -62,6 +64,7 @@ import android.os.ResultReceiver;
import android.os.ServiceManager;
import android.os.ShellCallback;
import android.os.SystemClock;
import android.os.Temperature;
import android.os.UserHandle;
import android.os.UserManagerInternal;
import android.provider.Settings;
@@ -75,6 +78,7 @@ import android.util.StatsLog;
import android.util.TimeUtils;
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.app.procstats.ProcessStats;
@@ -180,6 +184,11 @@ public class JobSchedulerService extends com.android.server.SystemService
    private final StorageController mStorageController;
    /** Need directly for sending uid state changes */
    private final DeviceIdleJobsController mDeviceIdleJobsController;
    /** Need directly for receiving thermal events */
    private IThermalService mThermalService;
    /** Thermal constraint. */
    @GuardedBy("mLock")
    private boolean mThermalConstraint = false;

    /**
     * Queue of pending jobs. The JobServiceContext class will receive jobs from this list
@@ -320,6 +329,19 @@ public class JobSchedulerService extends com.android.server.SystemService
        }
    }

    /**
     *  Thermal event received from Thermal Service
     */
    private final class ThermalStatusListener extends IThermalStatusListener.Stub {
        @Override public void onStatusChange(int status) {
            // Throttle for Temperature.THROTTLING_SEVERE and above
            synchronized (mLock) {
                mThermalConstraint = status >= Temperature.THROTTLING_SEVERE;
            }
            onControllerStateChanged();
        }
    }

    /**
     * All times are in milliseconds. These constants are kept synchronized with the system
     * global Settings. Any access to this class or its fields should be done while
@@ -1249,6 +1271,16 @@ public class JobSchedulerService extends com.android.server.SystemService
            }
            // Remove any jobs that are not associated with any of the current users.
            cancelJobsForNonExistentUsers();
            // Register thermal callback
            mThermalService = IThermalService.Stub.asInterface(
                    ServiceManager.getService(Context.THERMAL_SERVICE));
            if (mThermalService != null) {
                try {
                    mThermalService.registerThermalStatusListener(new ThermalStatusListener());
                } catch (RemoteException e) {
                    Slog.e(TAG, "Failed to register thermal callback.", e);
                }
            }
        } else if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
            synchronized (mLock) {
                // Let's go!
@@ -1672,14 +1704,26 @@ public class JobSchedulerService extends com.android.server.SystemService
        }
    }

    private boolean isJobThermalConstrainedLocked(JobStatus job) {
        return mThermalConstraint && job.hasConnectivityConstraint()
                && (evaluateJobPriorityLocked(job) < JobInfo.PRIORITY_FOREGROUND_APP);
    }

    private void stopNonReadyActiveJobsLocked() {
        for (int i=0; i<mActiveServices.size(); i++) {
            JobServiceContext serviceContext = mActiveServices.get(i);
            final JobStatus running = serviceContext.getRunningJobLocked();
            if (running != null && !running.isReady()) {
            if (running == null) {
                continue;
            }
            if (!running.isReady()) {
                serviceContext.cancelExecutingJobLocked(
                        JobParameters.REASON_CONSTRAINTS_NOT_SATISFIED,
                        "cancelled due to unsatisfied constraints");
            } else if (isJobThermalConstrainedLocked(running)) {
                serviceContext.cancelExecutingJobLocked(
                        JobParameters.REASON_DEVICE_THERMAL,
                        "cancelled due to thermal condition");
            }
        }
    }
@@ -1961,6 +2005,10 @@ public class JobSchedulerService extends com.android.server.SystemService
            return false;
        }

        if (isJobThermalConstrainedLocked(job)) {
            return false;
        }

        final boolean jobPending = mPendingJobs.contains(job);
        final boolean jobActive = isCurrentlyActiveLocked(job);

@@ -3112,6 +3160,9 @@ public class JobSchedulerService extends com.android.server.SystemService
            pw.print("    In parole?: ");
            pw.print(mInParole);
            pw.println();
            pw.print("    In thermal throttling?: ");
            pw.print(mThermalConstraint);
            pw.println();
            pw.println();

            pw.println("Started users: " + Arrays.toString(mStartedUsers));
@@ -3287,6 +3338,7 @@ public class JobSchedulerService extends com.android.server.SystemService
            proto.write(JobSchedulerServiceDumpProto.NEXT_HEARTBEAT_TIME_MILLIS,
                    mLastHeartbeatTime + mConstants.STANDBY_HEARTBEAT_TIME - nowUptime);
            proto.write(JobSchedulerServiceDumpProto.IN_PAROLE, mInParole);
            proto.write(JobSchedulerServiceDumpProto.IN_THERMAL, mThermalConstraint);

            for (int u : mStartedUsers) {
                proto.write(JobSchedulerServiceDumpProto.STARTED_USERS, u);