From 367e535ed110224f9bb16067515237c472e82d08 Mon Sep 17 00:00:00 2001 From: Kweku Adams Date: Fri, 9 Sep 2022 18:47:08 +0000 Subject: [PATCH] Log global JobScheduler state changes. Log state changes of constraints that apply to all jobs. These constraints only need to be logged once (when they change) instead of for each individual job and allow us to analyze behavior when JobScheduler believes the device is in various states. Keep the individual job constraint change logging off. Bug: 129954980 Bug: 242611030 Test: `statsd_testdrive 514` Change-Id: Idf331749601db6ed6f767d5649667519046208ae --- .../job/controllers/BatteryController.java | 20 ++++++++++++++++++- .../controllers/DeviceIdleJobsController.java | 2 ++ .../job/controllers/IdleController.java | 2 ++ .../server/job/controllers/JobStatus.java | 11 +++++++--- .../job/controllers/StateController.java | 10 ++++++++++ 5 files changed, 41 insertions(+), 4 deletions(-) diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/BatteryController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/BatteryController.java index 3bbc5a3696843..d284a99a45590 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/BatteryController.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/BatteryController.java @@ -69,6 +69,11 @@ public final class BatteryController extends RestrictingController { */ private final ArraySet mChangedJobs = new ArraySet<>(); + @GuardedBy("mLock") + private Boolean mLastReportedStatsdBatteryNotLow = null; + @GuardedBy("mLock") + private Boolean mLastReportedStatsdStablePower = null; + public BatteryController(JobSchedulerService service, FlexibilityController flexibilityController) { super(service); @@ -176,12 +181,25 @@ public final class BatteryController extends RestrictingController { Slog.d(TAG, "maybeReportNewChargingStateLocked: " + powerConnected + "/" + stablePower + "/" + batteryNotLow); } + + if (mLastReportedStatsdStablePower == null + || mLastReportedStatsdStablePower != stablePower) { + logDeviceWideConstraintStateToStatsd(JobStatus.CONSTRAINT_CHARGING, stablePower); + mLastReportedStatsdStablePower = stablePower; + } + if (mLastReportedStatsdBatteryNotLow == null + || mLastReportedStatsdBatteryNotLow != stablePower) { + logDeviceWideConstraintStateToStatsd(JobStatus.CONSTRAINT_BATTERY_NOT_LOW, + batteryNotLow); + mLastReportedStatsdBatteryNotLow = batteryNotLow; + } + final long nowElapsed = sElapsedRealtimeClock.millis(); mFlexibilityController.setConstraintSatisfied( JobStatus.CONSTRAINT_CHARGING, mService.isBatteryCharging(), nowElapsed); mFlexibilityController.setConstraintSatisfied( - JobStatus.CONSTRAINT_BATTERY_NOT_LOW, batteryNotLow, nowElapsed); + JobStatus.CONSTRAINT_BATTERY_NOT_LOW, batteryNotLow, nowElapsed); for (int i = mTrackedTasks.size() - 1; i >= 0; i--) { final JobStatus ts = mTrackedTasks.valueAt(i); diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/DeviceIdleJobsController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/DeviceIdleJobsController.java index f6de109d7ec9b..abbe177c5d493 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/DeviceIdleJobsController.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/DeviceIdleJobsController.java @@ -153,6 +153,8 @@ public final class DeviceIdleJobsController extends StateController { changed = true; } mDeviceIdleMode = enabled; + logDeviceWideConstraintStateToStatsd(JobStatus.CONSTRAINT_DEVICE_NOT_DOZING, + !mDeviceIdleMode); if (DEBUG) Slog.d(TAG, "mDeviceIdleMode=" + mDeviceIdleMode); mDeviceIdleUpdateFunctor.prepare(); if (enabled) { diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/IdleController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/IdleController.java index dd06217287249..926cfc192cd13 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/IdleController.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/IdleController.java @@ -96,6 +96,8 @@ public final class IdleController extends RestrictingController implements Idlen @Override public void reportNewIdleState(boolean isIdle) { synchronized (mLock) { + logDeviceWideConstraintStateToStatsd(JobStatus.CONSTRAINT_IDLE, isIdle); + final long nowElapsed = sElapsedRealtimeClock.millis(); mFlexibilityController.setConstraintSatisfied( JobStatus.CONSTRAINT_IDLE, isIdle, nowElapsed); diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java index 4320db09aef54..999a3c02b18cf 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java @@ -170,13 +170,12 @@ public final class JobStatus { */ private static final int STATSD_CONSTRAINTS_TO_LOG = CONSTRAINT_CONTENT_TRIGGER | CONSTRAINT_DEADLINE - | CONSTRAINT_IDLE | CONSTRAINT_PREFETCH | CONSTRAINT_TARE_WEALTH | CONSTRAINT_TIMING_DELAY | CONSTRAINT_WITHIN_QUOTA; - // TODO(b/129954980) + // TODO(b/129954980): ensure this doesn't spam statsd, especially at boot private static final boolean STATS_LOG_ENABLED = false; // No override. @@ -1982,7 +1981,7 @@ public final class JobStatus { } /** Returns a {@link JobServerProtoEnums.Constraint} enum value for the given constraint. */ - private int getProtoConstraint(int constraint) { + static int getProtoConstraint(int constraint) { switch (constraint) { case CONSTRAINT_BACKGROUND_NOT_RESTRICTED: return JobServerProtoEnums.CONSTRAINT_BACKGROUND_NOT_RESTRICTED; @@ -1998,10 +1997,16 @@ public final class JobStatus { return JobServerProtoEnums.CONSTRAINT_DEADLINE; case CONSTRAINT_DEVICE_NOT_DOZING: return JobServerProtoEnums.CONSTRAINT_DEVICE_NOT_DOZING; + case CONSTRAINT_FLEXIBLE: + return JobServerProtoEnums.CONSTRAINT_FLEXIBILITY; case CONSTRAINT_IDLE: return JobServerProtoEnums.CONSTRAINT_IDLE; + case CONSTRAINT_PREFETCH: + return JobServerProtoEnums.CONSTRAINT_PREFETCH; case CONSTRAINT_STORAGE_NOT_LOW: return JobServerProtoEnums.CONSTRAINT_STORAGE_NOT_LOW; + case CONSTRAINT_TARE_WEALTH: + return JobServerProtoEnums.CONSTRAINT_TARE_WEALTH; case CONSTRAINT_TIMING_DELAY: return JobServerProtoEnums.CONSTRAINT_TIMING_DELAY; case CONSTRAINT_WITHIN_QUOTA: diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/StateController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/StateController.java index 2a2d602b24bf2..8453e53782ca0 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/StateController.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/StateController.java @@ -26,6 +26,7 @@ import android.util.Slog; import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.GuardedBy; +import com.android.internal.util.FrameworkStatsLog; import com.android.server.job.JobSchedulerService; import com.android.server.job.JobSchedulerService.Constants; import com.android.server.job.StateChangedListener; @@ -165,6 +166,15 @@ public abstract class StateController { return mService.areComponentsInPlaceLocked(jobStatus); } + protected void logDeviceWideConstraintStateToStatsd(int constraint, boolean satisfied) { + FrameworkStatsLog.write( + FrameworkStatsLog.DEVICE_WIDE_JOB_CONSTRAINT_CHANGED, + JobStatus.getProtoConstraint(constraint), + satisfied + ? FrameworkStatsLog.DEVICE_WIDE_JOB_CONSTRAINT_CHANGED__STATE__SATISFIED + : FrameworkStatsLog.DEVICE_WIDE_JOB_CONSTRAINT_CHANGED__STATE__UNSATISFIED); + } + public abstract void dumpControllerStateLocked(IndentingPrintWriter pw, Predicate predicate); public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId,