Merge "ScheduledJobStateChanged: add stop reason" into pi-dev
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 40eff4c..99611f4 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -23,6 +23,7 @@
 
 import "frameworks/base/cmds/statsd/src/atom_field_options.proto";
 import "frameworks/base/core/proto/android/app/enums.proto";
+import "frameworks/base/core/proto/android/app/job/enums.proto";
 import "frameworks/base/core/proto/android/bluetooth/enums.proto";
 import "frameworks/base/core/proto/android/os/enums.proto";
 import "frameworks/base/core/proto/android/server/enums.proto";
@@ -362,7 +363,10 @@
     }
     optional State state = 3;
 
-    // TODO: Consider adding the stopReason (int)
+    // The reason a job has stopped.
+    // This is only applicable when the state is FINISHED.
+    // The default value is CANCELED.
+    optional android.app.job.StopReasonEnum stop_reason = 4;
 }
 
 /**
diff --git a/core/java/android/app/job/JobParameters.java b/core/java/android/app/job/JobParameters.java
index c71bf2e..d67f11b 100644
--- a/core/java/android/app/job/JobParameters.java
+++ b/core/java/android/app/job/JobParameters.java
@@ -36,15 +36,16 @@
 public class JobParameters implements Parcelable {
 
     /** @hide */
-    public static final int REASON_CANCELED = 0;
+    public static final int REASON_CANCELED = JobProtoEnums.STOP_REASON_CANCELLED; // 0.
     /** @hide */
-    public static final int REASON_CONSTRAINTS_NOT_SATISFIED = 1;
+    public static final int REASON_CONSTRAINTS_NOT_SATISFIED =
+            JobProtoEnums.STOP_REASON_CONSTRAINTS_NOT_SATISFIED; //1.
     /** @hide */
-    public static final int REASON_PREEMPT = 2;
+    public static final int REASON_PREEMPT = JobProtoEnums.STOP_REASON_PREEMPT; // 2.
     /** @hide */
-    public static final int REASON_TIMEOUT = 3;
+    public static final int REASON_TIMEOUT = JobProtoEnums.STOP_REASON_TIMEOUT; // 3.
     /** @hide */
-    public static final int REASON_DEVICE_IDLE = 4;
+    public static final int REASON_DEVICE_IDLE = JobProtoEnums.STOP_REASON_DEVICE_IDLE; // 4.
 
     /** @hide */
     public static String getReasonName(int reason) {
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 06230c1..bbff515 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -19,6 +19,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
+import android.app.job.JobProtoEnums;
 import android.bluetooth.BluetoothActivityEnergyInfo;
 import android.bluetooth.UidTraffic;
 import android.content.ContentResolver;
@@ -10045,7 +10046,8 @@
             if (t != null) {
                 t.startRunningLocked(elapsedRealtimeMs);
                 StatsLog.write_non_chained(StatsLog.SCHEDULED_JOB_STATE_CHANGED, getUid(), null,
-                        name, StatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__STARTED);
+                        name, StatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__STARTED,
+                        JobProtoEnums.STOP_REASON_CANCELLED);
             }
         }
 
@@ -10055,7 +10057,8 @@
                 t.stopRunningLocked(elapsedRealtimeMs);
                 if (!t.isRunningLocked()) { // only tell statsd if truly stopped
                     StatsLog.write_non_chained(StatsLog.SCHEDULED_JOB_STATE_CHANGED, getUid(), null,
-                            name, StatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__FINISHED);
+                            name, StatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__FINISHED,
+                            stopReason);
                 }
             }
             if (mBsi.mOnBatteryTimeBase.isRunning()) {
diff --git a/core/proto/android/app/jobparameters.proto b/core/proto/android/app/job/enums.proto
similarity index 66%
rename from core/proto/android/app/jobparameters.proto
rename to core/proto/android/app/job/enums.proto
index 4f6a2a2..0f14f20 100644
--- a/core/proto/android/app/jobparameters.proto
+++ b/core/proto/android/app/job/enums.proto
@@ -15,19 +15,18 @@
  */
 
 syntax = "proto2";
+
+package android.app.job;
+
+option java_outer_classname = "JobProtoEnums";
 option java_multiple_files = true;
 
-package android.app;
-
-/**
- * An android.app.JobParameters object.
- */
-message JobParametersProto {
-    enum CancelReason {
-        REASON_CANCELLED = 0;
-        REASON_CONSTRAINTS_NOT_SATISFIED = 1;
-        REASON_PREEMPT = 2;
-        REASON_TIMEOUT = 3;
-        REASON_DEVICE_IDLE = 4;
-    }
+// Reasons a job is stopped.
+// Primarily used in android.app.job.JobParameters.java.
+enum StopReasonEnum {
+  STOP_REASON_CANCELLED = 0;
+  STOP_REASON_CONSTRAINTS_NOT_SATISFIED = 1;
+  STOP_REASON_PREEMPT = 2;
+  STOP_REASON_TIMEOUT = 3;
+  STOP_REASON_DEVICE_IDLE = 4;
 }
diff --git a/core/proto/android/os/batterystats.proto b/core/proto/android/os/batterystats.proto
index 345c8ef..8e98ac9 100644
--- a/core/proto/android/os/batterystats.proto
+++ b/core/proto/android/os/batterystats.proto
@@ -19,7 +19,7 @@
 
 package android.os;
 
-import "frameworks/base/core/proto/android/app/jobparameters.proto";
+import "frameworks/base/core/proto/android/app/job/enums.proto";
 import "frameworks/base/core/proto/android/os/powermanager.proto";
 import "frameworks/base/core/proto/android/telephony/enums.proto";
 import "frameworks/base/libs/incident/proto/android/privacy.proto";
@@ -637,7 +637,7 @@
     message ReasonCount {
       option (android.msg_privacy).dest = DEST_AUTOMATIC;
 
-      optional android.app.JobParametersProto.CancelReason name = 1;
+      optional android.app.job.StopReasonEnum name = 1;
       optional int32 count = 2;
     }
     repeated ReasonCount reason_count = 2;
diff --git a/core/proto/android/server/jobscheduler.proto b/core/proto/android/server/jobscheduler.proto
index 9193129..122e5c4 100644
--- a/core/proto/android/server/jobscheduler.proto
+++ b/core/proto/android/server/jobscheduler.proto
@@ -20,7 +20,7 @@
 
 option java_multiple_files = true;
 
-import "frameworks/base/core/proto/android/app/jobparameters.proto";
+import "frameworks/base/core/proto/android/app/job/enums.proto";
 import "frameworks/base/core/proto/android/content/clipdata.proto";
 import "frameworks/base/core/proto/android/content/component_name.proto";
 import "frameworks/base/core/proto/android/content/intent.proto";
@@ -465,7 +465,7 @@
         message StopReasonCount {
             option (.android.msg_privacy).dest = DEST_AUTOMATIC;
 
-            optional .android.app.JobParametersProto.CancelReason reason = 1;
+            optional .android.app.job.StopReasonEnum reason = 1;
             optional int32 count = 2;
         }
         repeated StopReasonCount stop_reasons = 9;
@@ -516,7 +516,7 @@
         optional int32 job_id = 4;
         optional string tag = 5 [ (.android.privacy).dest = DEST_EXPLICIT ];
         // Only valid for STOP_JOB or STOP_PERIODIC_JOB Events.
-        optional .android.app.JobParametersProto.CancelReason stop_reason = 6;
+        optional .android.app.job.StopReasonEnum stop_reason = 6;
     }
     repeated HistoryEvent history_event = 1;
 }
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index 0b1f9a6..66817fa 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -29,6 +29,7 @@
 import android.app.job.IJobScheduler;
 import android.app.job.JobInfo;
 import android.app.job.JobParameters;
+import android.app.job.JobProtoEnums;
 import android.app.job.JobScheduler;
 import android.app.job.JobService;
 import android.app.job.JobWorkItem;
@@ -880,7 +881,8 @@
             startTrackingJobLocked(jobStatus, toCancel);
             StatsLog.write_non_chained(StatsLog.SCHEDULED_JOB_STATE_CHANGED,
                     uId, null, jobStatus.getBatteryName(),
-                    StatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__SCHEDULED);
+                    StatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__SCHEDULED,
+                    JobProtoEnums.STOP_REASON_CANCELLED);
 
             // 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