Loading apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +7 −0 Original line number Diff line number Diff line Loading @@ -1559,6 +1559,13 @@ public class JobSchedulerService extends com.android.server.SystemService } } /** Return the current bias of the given UID. */ public int getUidBias(int uid) { synchronized (mLock) { return mUidBiasOverride.get(uid, JobInfo.BIAS_DEFAULT); } } @Override public void onDeviceIdleStateChanged(boolean deviceIdle) { synchronized (mLock) { Loading apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java +0 −25 Original line number Diff line number Diff line Loading @@ -366,9 +366,6 @@ public final class JobServiceContext implements ServiceConnection { } catch (RemoteException e) { // Whatever. } mEconomyManagerInternal.noteOngoingEventStarted( job.getSourceUserId(), job.getSourcePackageName(), getRunningActionId(job), String.valueOf(job.getJobId())); final String jobPackage = job.getSourcePackageName(); final int jobUserId = job.getSourceUserId(); UsageStatsManagerInternal usageStats = Loading Loading @@ -401,25 +398,6 @@ public final class JobServiceContext implements ServiceConnection { } } @EconomicPolicy.AppAction private static int getRunningActionId(@NonNull JobStatus job) { switch (job.getEffectivePriority()) { case JobInfo.PRIORITY_MAX: return JobSchedulerEconomicPolicy.ACTION_JOB_MAX_RUNNING; case JobInfo.PRIORITY_HIGH: return JobSchedulerEconomicPolicy.ACTION_JOB_HIGH_RUNNING; case JobInfo.PRIORITY_LOW: return JobSchedulerEconomicPolicy.ACTION_JOB_LOW_RUNNING; case JobInfo.PRIORITY_MIN: return JobSchedulerEconomicPolicy.ACTION_JOB_MIN_RUNNING; default: Slog.wtf(TAG, "Unknown priority: " + getPriorityString(job.getEffectivePriority())); // Intentional fallthrough case JobInfo.PRIORITY_DEFAULT: return JobSchedulerEconomicPolicy.ACTION_JOB_DEFAULT_RUNNING; } } /** * Used externally to query the running job. Will return null if there is no job running. */ Loading Loading @@ -1043,9 +1021,6 @@ public final class JobServiceContext implements ServiceConnection { } catch (RemoteException e) { // Whatever. } mEconomyManagerInternal.noteOngoingEventStopped( mRunningJob.getSourceUserId(), mRunningJob.getSourcePackageName(), getRunningActionId(mRunningJob), String.valueOf(mRunningJob.getJobId())); if (mParams.getStopReason() == JobParameters.STOP_REASON_TIMEOUT) { mEconomyManagerInternal.noteInstantaneousEvent( mRunningJob.getSourceUserId(), mRunningJob.getSourcePackageName(), Loading apex/jobscheduler/service/java/com/android/server/job/controllers/TareController.java +89 −2 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.server.job.controllers; import static android.app.job.JobInfo.getPriorityString; import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock; import android.annotation.NonNull; Loading @@ -31,6 +33,7 @@ import com.android.internal.annotations.GuardedBy; import com.android.server.JobSchedulerBackgroundThread; import com.android.server.LocalServices; import com.android.server.job.JobSchedulerService; import com.android.server.tare.EconomicPolicy; import com.android.server.tare.EconomyManagerInternal; import com.android.server.tare.EconomyManagerInternal.ActionBill; import com.android.server.tare.JobSchedulerEconomicPolicy; Loading Loading @@ -285,6 +288,14 @@ public class TareController extends StateController { } }; /** * List of jobs that started while the UID was in the TOP state. There will be no more than * 16 ({@link JobSchedulerService#MAX_JOB_CONTEXTS_COUNT}) running at once, so an ArraySet is * fine. */ @GuardedBy("mLock") private final ArraySet<JobStatus> mTopStartedJobs = new ArraySet<>(); @GuardedBy("mLock") private boolean mIsEnabled; Loading @@ -299,6 +310,7 @@ public class TareController extends StateController { } @Override @GuardedBy("mLock") public void maybeStartTrackingJobLocked(JobStatus jobStatus, JobStatus lastJob) { final long nowElapsed = sElapsedRealtimeClock.millis(); jobStatus.setTareWealthConstraintSatisfied(nowElapsed, hasEnoughWealthLocked(jobStatus)); Loading @@ -312,6 +324,7 @@ public class TareController extends StateController { } @Override @GuardedBy("mLock") public void prepareForExecutionLocked(JobStatus jobStatus) { final int userId = jobStatus.getSourceUserId(); final String pkgName = jobStatus.getSourcePackageName(); Loading @@ -325,12 +338,29 @@ public class TareController extends StateController { } } addJobToBillList(jobStatus, getRunningBill(jobStatus)); final int uid = jobStatus.getSourceUid(); if (mService.getUidBias(uid) == JobInfo.BIAS_TOP_APP) { if (DEBUG) { Slog.d(TAG, jobStatus.toShortString() + " is top started job"); } mTopStartedJobs.add(jobStatus); // Top jobs won't count towards quota so there's no need to involve the EconomyManager. } else { mEconomyManagerInternal.noteOngoingEventStarted(userId, pkgName, getRunningActionId(jobStatus), String.valueOf(jobStatus.getJobId())); } } @Override @GuardedBy("mLock") public void unprepareFromExecutionLocked(JobStatus jobStatus) { final int userId = jobStatus.getSourceUserId(); final String pkgName = jobStatus.getSourcePackageName(); mEconomyManagerInternal.noteOngoingEventStopped(userId, pkgName, getRunningActionId(jobStatus), String.valueOf(jobStatus.getJobId())); mTopStartedJobs.remove(jobStatus); final ArraySet<ActionBill> bills = getPossibleStartBills(jobStatus); ArrayMap<ActionBill, ArraySet<JobStatus>> billToJobMap = mRegisteredBillsAndJobs.get(userId, pkgName); Loading @@ -347,10 +377,14 @@ public class TareController extends StateController { } @Override @GuardedBy("mLock") public void maybeStopTrackingJobLocked(JobStatus jobStatus, JobStatus incomingJob, boolean forUpdate) { final int userId = jobStatus.getSourceUserId(); final String pkgName = jobStatus.getSourcePackageName(); mEconomyManagerInternal.noteOngoingEventStopped(userId, pkgName, getRunningActionId(jobStatus), String.valueOf(jobStatus.getJobId())); mTopStartedJobs.remove(jobStatus); ArrayMap<ActionBill, ArraySet<JobStatus>> billToJobMap = mRegisteredBillsAndJobs.get(userId, pkgName); if (billToJobMap != null) { Loading Loading @@ -391,8 +425,17 @@ public class TareController extends StateController { if (!mIsEnabled) { return true; } if (jobStatus.getEffectivePriority() == JobInfo.PRIORITY_MAX) { return canAffordBillLocked(jobStatus, BILL_JOB_START_MAX_EXPEDITED); } return canAffordBillLocked(jobStatus, BILL_JOB_START_HIGH_EXPEDITED); } /** @return true if the job was started while the app was in the TOP state. */ @GuardedBy("mLock") private boolean isTopStartedJobLocked(@NonNull final JobStatus jobStatus) { return mTopStartedJobs.contains(jobStatus); } @GuardedBy("mLock") public long getMaxJobExecutionTimeMsLocked(@NonNull JobStatus jobStatus) { Loading Loading @@ -459,6 +502,9 @@ public class TareController extends StateController { } } switch (jobStatus.getEffectivePriority()) { case JobInfo.PRIORITY_MAX: bills.add(BILL_JOB_START_MAX); break; case JobInfo.PRIORITY_HIGH: bills.add(BILL_JOB_START_HIGH); break; Loading @@ -471,6 +517,10 @@ public class TareController extends StateController { case JobInfo.PRIORITY_MIN: bills.add(BILL_JOB_START_MIN); break; default: Slog.wtf(TAG, "Unexpected priority: " + JobInfo.getPriorityString(jobStatus.getEffectivePriority())); break; } return bills; } Loading Loading @@ -502,11 +552,36 @@ public class TareController extends StateController { } } @EconomicPolicy.AppAction private static int getRunningActionId(@NonNull JobStatus job) { switch (job.getEffectivePriority()) { case JobInfo.PRIORITY_MAX: return JobSchedulerEconomicPolicy.ACTION_JOB_MAX_RUNNING; case JobInfo.PRIORITY_HIGH: return JobSchedulerEconomicPolicy.ACTION_JOB_HIGH_RUNNING; case JobInfo.PRIORITY_LOW: return JobSchedulerEconomicPolicy.ACTION_JOB_LOW_RUNNING; case JobInfo.PRIORITY_MIN: return JobSchedulerEconomicPolicy.ACTION_JOB_MIN_RUNNING; default: Slog.wtf(TAG, "Unknown priority: " + getPriorityString(job.getEffectivePriority())); // Intentional fallthrough case JobInfo.PRIORITY_DEFAULT: return JobSchedulerEconomicPolicy.ACTION_JOB_DEFAULT_RUNNING; } } @GuardedBy("mLock") private boolean canAffordBillLocked(@NonNull JobStatus jobStatus, @NonNull ActionBill bill) { if (!mIsEnabled) { return true; } if (mService.getUidBias(jobStatus.getSourceUid()) == JobInfo.BIAS_TOP_APP || isTopStartedJobLocked(jobStatus)) { // Jobs for the top app should always be allowed to run, and any jobs started while // the app is on top shouldn't consume any credits. return true; } final int userId = jobStatus.getSourceUserId(); final String pkgName = jobStatus.getSourcePackageName(); ArrayMap<ActionBill, Boolean> actionAffordability = Loading @@ -533,6 +608,12 @@ public class TareController extends StateController { if (!jobStatus.isRequestedExpeditedJob()) { return false; } if (mService.getUidBias(jobStatus.getSourceUid()) == JobInfo.BIAS_TOP_APP || isTopStartedJobLocked(jobStatus)) { // Jobs for the top app should always be allowed to run, and any jobs started while // the app is on top shouldn't consume any credits. return true; } if (mService.isCurrentlyRunningLocked(jobStatus)) { return canAffordBillLocked(jobStatus, getRunningBill(jobStatus)); } Loading @@ -548,6 +629,12 @@ public class TareController extends StateController { if (!mIsEnabled) { return true; } if (mService.getUidBias(jobStatus.getSourceUid()) == JobInfo.BIAS_TOP_APP || isTopStartedJobLocked(jobStatus)) { // Jobs for the top app should always be allowed to run, and any jobs started while // the app is on top shouldn't consume any credits. return true; } if (mService.isCurrentlyRunningLocked(jobStatus)) { if (jobStatus.isRequestedExpeditedJob()) { return canAffordBillLocked(jobStatus, getRunningBill(jobStatus)) Loading Loading
apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +7 −0 Original line number Diff line number Diff line Loading @@ -1559,6 +1559,13 @@ public class JobSchedulerService extends com.android.server.SystemService } } /** Return the current bias of the given UID. */ public int getUidBias(int uid) { synchronized (mLock) { return mUidBiasOverride.get(uid, JobInfo.BIAS_DEFAULT); } } @Override public void onDeviceIdleStateChanged(boolean deviceIdle) { synchronized (mLock) { Loading
apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java +0 −25 Original line number Diff line number Diff line Loading @@ -366,9 +366,6 @@ public final class JobServiceContext implements ServiceConnection { } catch (RemoteException e) { // Whatever. } mEconomyManagerInternal.noteOngoingEventStarted( job.getSourceUserId(), job.getSourcePackageName(), getRunningActionId(job), String.valueOf(job.getJobId())); final String jobPackage = job.getSourcePackageName(); final int jobUserId = job.getSourceUserId(); UsageStatsManagerInternal usageStats = Loading Loading @@ -401,25 +398,6 @@ public final class JobServiceContext implements ServiceConnection { } } @EconomicPolicy.AppAction private static int getRunningActionId(@NonNull JobStatus job) { switch (job.getEffectivePriority()) { case JobInfo.PRIORITY_MAX: return JobSchedulerEconomicPolicy.ACTION_JOB_MAX_RUNNING; case JobInfo.PRIORITY_HIGH: return JobSchedulerEconomicPolicy.ACTION_JOB_HIGH_RUNNING; case JobInfo.PRIORITY_LOW: return JobSchedulerEconomicPolicy.ACTION_JOB_LOW_RUNNING; case JobInfo.PRIORITY_MIN: return JobSchedulerEconomicPolicy.ACTION_JOB_MIN_RUNNING; default: Slog.wtf(TAG, "Unknown priority: " + getPriorityString(job.getEffectivePriority())); // Intentional fallthrough case JobInfo.PRIORITY_DEFAULT: return JobSchedulerEconomicPolicy.ACTION_JOB_DEFAULT_RUNNING; } } /** * Used externally to query the running job. Will return null if there is no job running. */ Loading Loading @@ -1043,9 +1021,6 @@ public final class JobServiceContext implements ServiceConnection { } catch (RemoteException e) { // Whatever. } mEconomyManagerInternal.noteOngoingEventStopped( mRunningJob.getSourceUserId(), mRunningJob.getSourcePackageName(), getRunningActionId(mRunningJob), String.valueOf(mRunningJob.getJobId())); if (mParams.getStopReason() == JobParameters.STOP_REASON_TIMEOUT) { mEconomyManagerInternal.noteInstantaneousEvent( mRunningJob.getSourceUserId(), mRunningJob.getSourcePackageName(), Loading
apex/jobscheduler/service/java/com/android/server/job/controllers/TareController.java +89 −2 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.server.job.controllers; import static android.app.job.JobInfo.getPriorityString; import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock; import android.annotation.NonNull; Loading @@ -31,6 +33,7 @@ import com.android.internal.annotations.GuardedBy; import com.android.server.JobSchedulerBackgroundThread; import com.android.server.LocalServices; import com.android.server.job.JobSchedulerService; import com.android.server.tare.EconomicPolicy; import com.android.server.tare.EconomyManagerInternal; import com.android.server.tare.EconomyManagerInternal.ActionBill; import com.android.server.tare.JobSchedulerEconomicPolicy; Loading Loading @@ -285,6 +288,14 @@ public class TareController extends StateController { } }; /** * List of jobs that started while the UID was in the TOP state. There will be no more than * 16 ({@link JobSchedulerService#MAX_JOB_CONTEXTS_COUNT}) running at once, so an ArraySet is * fine. */ @GuardedBy("mLock") private final ArraySet<JobStatus> mTopStartedJobs = new ArraySet<>(); @GuardedBy("mLock") private boolean mIsEnabled; Loading @@ -299,6 +310,7 @@ public class TareController extends StateController { } @Override @GuardedBy("mLock") public void maybeStartTrackingJobLocked(JobStatus jobStatus, JobStatus lastJob) { final long nowElapsed = sElapsedRealtimeClock.millis(); jobStatus.setTareWealthConstraintSatisfied(nowElapsed, hasEnoughWealthLocked(jobStatus)); Loading @@ -312,6 +324,7 @@ public class TareController extends StateController { } @Override @GuardedBy("mLock") public void prepareForExecutionLocked(JobStatus jobStatus) { final int userId = jobStatus.getSourceUserId(); final String pkgName = jobStatus.getSourcePackageName(); Loading @@ -325,12 +338,29 @@ public class TareController extends StateController { } } addJobToBillList(jobStatus, getRunningBill(jobStatus)); final int uid = jobStatus.getSourceUid(); if (mService.getUidBias(uid) == JobInfo.BIAS_TOP_APP) { if (DEBUG) { Slog.d(TAG, jobStatus.toShortString() + " is top started job"); } mTopStartedJobs.add(jobStatus); // Top jobs won't count towards quota so there's no need to involve the EconomyManager. } else { mEconomyManagerInternal.noteOngoingEventStarted(userId, pkgName, getRunningActionId(jobStatus), String.valueOf(jobStatus.getJobId())); } } @Override @GuardedBy("mLock") public void unprepareFromExecutionLocked(JobStatus jobStatus) { final int userId = jobStatus.getSourceUserId(); final String pkgName = jobStatus.getSourcePackageName(); mEconomyManagerInternal.noteOngoingEventStopped(userId, pkgName, getRunningActionId(jobStatus), String.valueOf(jobStatus.getJobId())); mTopStartedJobs.remove(jobStatus); final ArraySet<ActionBill> bills = getPossibleStartBills(jobStatus); ArrayMap<ActionBill, ArraySet<JobStatus>> billToJobMap = mRegisteredBillsAndJobs.get(userId, pkgName); Loading @@ -347,10 +377,14 @@ public class TareController extends StateController { } @Override @GuardedBy("mLock") public void maybeStopTrackingJobLocked(JobStatus jobStatus, JobStatus incomingJob, boolean forUpdate) { final int userId = jobStatus.getSourceUserId(); final String pkgName = jobStatus.getSourcePackageName(); mEconomyManagerInternal.noteOngoingEventStopped(userId, pkgName, getRunningActionId(jobStatus), String.valueOf(jobStatus.getJobId())); mTopStartedJobs.remove(jobStatus); ArrayMap<ActionBill, ArraySet<JobStatus>> billToJobMap = mRegisteredBillsAndJobs.get(userId, pkgName); if (billToJobMap != null) { Loading Loading @@ -391,8 +425,17 @@ public class TareController extends StateController { if (!mIsEnabled) { return true; } if (jobStatus.getEffectivePriority() == JobInfo.PRIORITY_MAX) { return canAffordBillLocked(jobStatus, BILL_JOB_START_MAX_EXPEDITED); } return canAffordBillLocked(jobStatus, BILL_JOB_START_HIGH_EXPEDITED); } /** @return true if the job was started while the app was in the TOP state. */ @GuardedBy("mLock") private boolean isTopStartedJobLocked(@NonNull final JobStatus jobStatus) { return mTopStartedJobs.contains(jobStatus); } @GuardedBy("mLock") public long getMaxJobExecutionTimeMsLocked(@NonNull JobStatus jobStatus) { Loading Loading @@ -459,6 +502,9 @@ public class TareController extends StateController { } } switch (jobStatus.getEffectivePriority()) { case JobInfo.PRIORITY_MAX: bills.add(BILL_JOB_START_MAX); break; case JobInfo.PRIORITY_HIGH: bills.add(BILL_JOB_START_HIGH); break; Loading @@ -471,6 +517,10 @@ public class TareController extends StateController { case JobInfo.PRIORITY_MIN: bills.add(BILL_JOB_START_MIN); break; default: Slog.wtf(TAG, "Unexpected priority: " + JobInfo.getPriorityString(jobStatus.getEffectivePriority())); break; } return bills; } Loading Loading @@ -502,11 +552,36 @@ public class TareController extends StateController { } } @EconomicPolicy.AppAction private static int getRunningActionId(@NonNull JobStatus job) { switch (job.getEffectivePriority()) { case JobInfo.PRIORITY_MAX: return JobSchedulerEconomicPolicy.ACTION_JOB_MAX_RUNNING; case JobInfo.PRIORITY_HIGH: return JobSchedulerEconomicPolicy.ACTION_JOB_HIGH_RUNNING; case JobInfo.PRIORITY_LOW: return JobSchedulerEconomicPolicy.ACTION_JOB_LOW_RUNNING; case JobInfo.PRIORITY_MIN: return JobSchedulerEconomicPolicy.ACTION_JOB_MIN_RUNNING; default: Slog.wtf(TAG, "Unknown priority: " + getPriorityString(job.getEffectivePriority())); // Intentional fallthrough case JobInfo.PRIORITY_DEFAULT: return JobSchedulerEconomicPolicy.ACTION_JOB_DEFAULT_RUNNING; } } @GuardedBy("mLock") private boolean canAffordBillLocked(@NonNull JobStatus jobStatus, @NonNull ActionBill bill) { if (!mIsEnabled) { return true; } if (mService.getUidBias(jobStatus.getSourceUid()) == JobInfo.BIAS_TOP_APP || isTopStartedJobLocked(jobStatus)) { // Jobs for the top app should always be allowed to run, and any jobs started while // the app is on top shouldn't consume any credits. return true; } final int userId = jobStatus.getSourceUserId(); final String pkgName = jobStatus.getSourcePackageName(); ArrayMap<ActionBill, Boolean> actionAffordability = Loading @@ -533,6 +608,12 @@ public class TareController extends StateController { if (!jobStatus.isRequestedExpeditedJob()) { return false; } if (mService.getUidBias(jobStatus.getSourceUid()) == JobInfo.BIAS_TOP_APP || isTopStartedJobLocked(jobStatus)) { // Jobs for the top app should always be allowed to run, and any jobs started while // the app is on top shouldn't consume any credits. return true; } if (mService.isCurrentlyRunningLocked(jobStatus)) { return canAffordBillLocked(jobStatus, getRunningBill(jobStatus)); } Loading @@ -548,6 +629,12 @@ public class TareController extends StateController { if (!mIsEnabled) { return true; } if (mService.getUidBias(jobStatus.getSourceUid()) == JobInfo.BIAS_TOP_APP || isTopStartedJobLocked(jobStatus)) { // Jobs for the top app should always be allowed to run, and any jobs started while // the app is on top shouldn't consume any credits. return true; } if (mService.isCurrentlyRunningLocked(jobStatus)) { if (jobStatus.isRequestedExpeditedJob()) { return canAffordBillLocked(jobStatus, getRunningBill(jobStatus)) Loading