Merge "Fix NPE in JobServiceContext when closing job."
diff --git a/services/core/java/com/android/server/job/JobServiceContext.java b/services/core/java/com/android/server/job/JobServiceContext.java
index 63c8d92..d07fb13 100644
--- a/services/core/java/com/android/server/job/JobServiceContext.java
+++ b/services/core/java/com/android/server/job/JobServiceContext.java
@@ -73,7 +73,7 @@
     private static final long OP_TIMEOUT_MILLIS = 8 * 1000;
 
     private static final String[] VERB_STRINGS = {
-            "VERB_BINDING", "VERB_STARTING", "VERB_EXECUTING", "VERB_STOPPING"
+            "VERB_BINDING", "VERB_STARTING", "VERB_EXECUTING", "VERB_STOPPING", "VERB_FINISHED"
     };
 
     // States that a job occupies while interacting with the client.
@@ -81,6 +81,7 @@
     static final int VERB_STARTING = 1;
     static final int VERB_EXECUTING = 2;
     static final int VERB_STOPPING = 3;
+    static final int VERB_FINISHED = 4;
 
     // Messages that result from interactions with the client service.
     /** System timed out waiting for a response. */
@@ -170,6 +171,7 @@
                 mRunningJob = null;
                 mParams = null;
                 mExecutionStartTimeElapsed = 0L;
+                mVerb = VERB_FINISHED;
                 removeOpTimeOut();
                 return false;
             }
@@ -305,8 +307,8 @@
                     break;
                 case MSG_CALLBACK:
                     if (DEBUG) {
-                        Slog.d(TAG, "MSG_CALLBACK of : " + mRunningJob + " v:" +
-                                (mVerb >= 0 ? VERB_STRINGS[mVerb] : "[invalid]"));
+                        Slog.d(TAG, "MSG_CALLBACK of : " + mRunningJob
+                                + " v:" + VERB_STRINGS[mVerb]);
                     }
                     removeOpTimeOut();
 
@@ -522,8 +524,12 @@
          * we want to clean up internally.
          */
         private void closeAndCleanupJobH(boolean reschedule) {
-            final JobStatus completedJob = mRunningJob;
+            final JobStatus completedJob;
             synchronized (mLock) {
+                if (mVerb == VERB_FINISHED) {
+                    return;
+                }
+                completedJob = mRunningJob;
                 try {
                     mBatteryStats.noteJobFinish(mRunningJob.getName(), mRunningJob.getUid());
                 } catch (RemoteException e) {
@@ -536,7 +542,7 @@
                 mWakeLock = null;
                 mRunningJob = null;
                 mParams = null;
-                mVerb = -1;
+                mVerb = VERB_FINISHED;
                 mCancelled.set(false);
                 service = null;
                 mAvailable = true;