From 1b5778d119c4b440ee7ce4b35a1e5fb54d96c896 Mon Sep 17 00:00:00 2001 From: Suprabh Shukla Date: Tue, 18 Feb 2020 16:39:02 -0800 Subject: [PATCH] Add API constraints to ScheduledJobStateChanged atom This helps us know if jobs with a particular constraint are being starved or otherwise dysfunctional due to a bug. Test: make statsd_testdrive && ./out/host/linux-x86/bin/statsd_testdrive 8 Sample output: atom { scheduled_job_state_changed { attribution_node { uid: 10224 tag: "" } job_name: "android.jobscheduler.cts.jobtestapp/.TestJobService" state: SCHEDULED stop_reason: STOP_REASON_CANCELLED standby_bucket: RESTRICTED job_id: 691 has_charging_constraint: true has_battery_not_low_constraint: true has_storage_not_low_constraint: false has_timing_delay_constraint: false has_deadline_constraint: true has_idle_constraint: true has_connectivity_constraint: true has_content_trigger_constraint: false } Bug: 138239687 Change-Id: I175e5a0f5cc2cb3be447ccb58142006946092e75 --- .../server/job/JobSchedulerService.java | 10 +++++- .../android/server/job/JobServiceContext.java | 34 ++++++++++++++++--- cmds/statsd/src/atoms.proto | 11 ++++++ .../android/internal/app/IBatteryStats.aidl | 4 +-- .../server/am/BatteryStatsService.java | 13 ++----- 5 files changed, 53 insertions(+), 19 deletions(-) diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java index c1e529f3f9660..8fb1072204f43 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java @@ -1074,7 +1074,15 @@ public class JobSchedulerService extends com.android.server.SystemService uId, null, jobStatus.getBatteryName(), FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__SCHEDULED, JobProtoEnums.STOP_REASON_CANCELLED, jobStatus.getStandbyBucket(), - jobStatus.getJobId()); + jobStatus.getJobId(), + jobStatus.hasChargingConstraint(), + jobStatus.hasBatteryNotLowConstraint(), + jobStatus.hasStorageNotLowConstraint(), + jobStatus.hasTimingDelayConstraint(), + jobStatus.hasDeadlineConstraint(), + jobStatus.hasIdleConstraint(), + jobStatus.hasConnectivityConstraint(), + jobStatus.hasContentTriggerConstraint()); // If the job is immediately ready to run, then we can just immediately // put it in the pending list and try to schedule it. This is especially diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java index 26db4a30ebdaf..565ed959aeb4d 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java +++ b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java @@ -22,6 +22,7 @@ import android.app.job.IJobCallback; import android.app.job.IJobService; import android.app.job.JobInfo; import android.app.job.JobParameters; +import android.app.job.JobProtoEnums; import android.app.job.JobWorkItem; import android.app.usage.UsageStatsManagerInternal; import android.content.ComponentName; @@ -45,6 +46,7 @@ import android.util.TimeUtils; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.IBatteryStats; +import com.android.internal.util.FrameworkStatsLog; import com.android.server.EventLogTags; import com.android.server.LocalServices; import com.android.server.job.controllers.JobStatus; @@ -273,9 +275,20 @@ public final class JobServiceContext implements ServiceConnection { return false; } mJobPackageTracker.noteActive(job); + FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED, + job.getSourceUid(), null, job.getBatteryName(), + FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__STARTED, + JobProtoEnums.STOP_REASON_UNKNOWN, job.getStandbyBucket(), job.getJobId(), + job.hasChargingConstraint(), + job.hasBatteryNotLowConstraint(), + job.hasStorageNotLowConstraint(), + job.hasTimingDelayConstraint(), + job.hasDeadlineConstraint(), + job.hasIdleConstraint(), + job.hasConnectivityConstraint(), + job.hasContentTriggerConstraint()); try { - mBatteryStats.noteJobStart(job.getBatteryName(), job.getSourceUid(), - job.getStandbyBucket(), job.getJobId()); + mBatteryStats.noteJobStart(job.getBatteryName(), job.getSourceUid()); } catch (RemoteException e) { // Whatever. } @@ -779,10 +792,21 @@ public final class JobServiceContext implements ServiceConnection { applyStoppedReasonLocked(reason); completedJob = mRunningJob; mJobPackageTracker.noteInactive(completedJob, mParams.getStopReason(), reason); + FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED, + completedJob.getSourceUid(), null, completedJob.getBatteryName(), + FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__FINISHED, + mParams.getStopReason(), completedJob.getStandbyBucket(), completedJob.getJobId(), + completedJob.hasChargingConstraint(), + completedJob.hasBatteryNotLowConstraint(), + completedJob.hasStorageNotLowConstraint(), + completedJob.hasTimingDelayConstraint(), + completedJob.hasDeadlineConstraint(), + completedJob.hasIdleConstraint(), + completedJob.hasConnectivityConstraint(), + completedJob.hasContentTriggerConstraint()); try { - mBatteryStats.noteJobFinish(mRunningJob.getBatteryName(), - mRunningJob.getSourceUid(), mParams.getStopReason(), - mRunningJob.getStandbyBucket(), mRunningJob.getJobId()); + mBatteryStats.noteJobFinish(mRunningJob.getBatteryName(), mRunningJob.getSourceUid(), + mParams.getStopReason()); } catch (RemoteException e) { // Whatever. } diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index 257554207ef5d..a35be5ad98601 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -978,6 +978,17 @@ message ScheduledJobStateChanged { // The job id (as assigned by the app). optional int32 job_id = 6; + + // One flag for each of the API constraints defined by Jobscheduler. Does not include implcit + // constraints as they are always assumed to be set. + optional bool has_charging_constraint = 7; + optional bool has_battery_not_low_constraint = 8; + optional bool has_storage_not_low_constraint = 9; + optional bool has_timing_delay_constraint = 10; + optional bool has_deadline_constraint = 11; + optional bool has_idle_constraint = 12; + optional bool has_connectivity_constraint = 13; + optional bool has_content_trigger_constraint = 14; } /** diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl index dc6942cdc2c30..6a0b443b7df88 100644 --- a/core/java/com/android/internal/app/IBatteryStats.aidl +++ b/core/java/com/android/internal/app/IBatteryStats.aidl @@ -71,8 +71,8 @@ interface IBatteryStats { void noteSyncStart(String name, int uid); void noteSyncFinish(String name, int uid); - void noteJobStart(String name, int uid, int standbyBucket, int jobid); - void noteJobFinish(String name, int uid, int stopReason, int standbyBucket, int jobid); + void noteJobStart(String name, int uid); + void noteJobFinish(String name, int uid, int stopReason); void noteStartWakelock(int uid, int pid, String name, String historyName, int type, boolean unimportantForLogging); diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index 119394fdadb88..dbad562c02713 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -17,7 +17,6 @@ package com.android.server.am; import android.app.ActivityManager; -import android.app.job.JobProtoEnums; import android.bluetooth.BluetoothActivityEnergyInfo; import android.content.ContentResolver; import android.content.Context; @@ -468,26 +467,18 @@ public final class BatteryStatsService extends IBatteryStats.Stub } /** A scheduled job was started. */ - public void noteJobStart(String name, int uid, int standbyBucket, int jobid) { + public void noteJobStart(String name, int uid) { enforceCallingPermission(); synchronized (mStats) { mStats.noteJobStartLocked(name, uid); - FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED, - uid, null, name, - FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__STARTED, - JobProtoEnums.STOP_REASON_UNKNOWN, standbyBucket, jobid); } } /** A scheduled job was finished. */ - public void noteJobFinish(String name, int uid, int stopReason, int standbyBucket, int jobid) { + public void noteJobFinish(String name, int uid, int stopReason) { enforceCallingPermission(); synchronized (mStats) { mStats.noteJobFinishLocked(name, uid, stopReason); - FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED, - uid, null, name, - FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__FINISHED, stopReason, - standbyBucket, jobid); } }