Merge "Fixed initial blocking conditions when job-id is not generated." into main
diff --git a/jni/include/wprint_status_types.h b/jni/include/wprint_status_types.h
index b1449bc..4dd0ed6 100644
--- a/jni/include/wprint_status_types.h
+++ b/jni/include/wprint_status_types.h
@@ -209,6 +209,8 @@
 
     // all current print status events
     print_status_t printer_reasons[PRINT_STATUS_MAX_STATE + 1];
+
+    int job_id;
 } printer_state_dyn_t;
 
 typedef enum {
diff --git a/jni/ipphelper/ippstatus_monitor.c b/jni/ipphelper/ippstatus_monitor.c
index 81d41f2..01f6cd9 100644
--- a/jni/ipphelper/ippstatus_monitor.c
+++ b/jni/ipphelper/ippstatus_monitor.c
@@ -210,9 +210,11 @@
 
     last_status.printer_status = PRINT_STATUS_UNKNOWN;
     last_status.printer_reasons[0] = PRINT_STATUS_INITIALIZING;
+    last_status.job_id = 0;
 
     curr_status.printer_status = PRINT_STATUS_UNKNOWN;
     curr_status.printer_reasons[0] = PRINT_STATUS_INITIALIZING;
+    curr_status.job_id = 0;
 
     // send out the first callback
     if (status_cb != NULL) {
@@ -264,6 +266,7 @@
         } else {
             while (!monitor->stop_monitor) {
                 pthread_mutex_lock(&monitor->mutex);
+                curr_status.job_id = job_id;
                 _get_status(this_p, &curr_status);
                 pthread_mutex_unlock(&monitor->mutex);
                 if ((status_cb != NULL) &&
diff --git a/jni/lib/lib_wprint.c b/jni/lib/lib_wprint.c
index f2f7d2e..8ceab2e 100755
--- a/jni/lib/lib_wprint.c
+++ b/jni/lib/lib_wprint.c
@@ -523,6 +523,20 @@
 }
 
 /*
+ * Helper function to send job status callbacks to wprintJNI
+ */
+static void _send_status_callback(_job_queue_t *jq, wprint_job_callback_params_t cb_param,
+                                  int state, unsigned int blocked_reasons, int job_done_result) {
+    if (jq->cb_fn) {
+        cb_param.id = WPRINT_CB_PARAM_JOB_STATE;
+        cb_param.param.state = state;
+        cb_param.blocked_reasons = blocked_reasons;
+        cb_param.job_done_result = job_done_result;
+        jq->cb_fn(jq->job_handle, (void *) &cb_param);
+    }
+}
+
+/*
  * Handles a new status message from the printer. Based on the status of wprint and the printer,
  * this function will start/end a job, send another page, or return blocking errors.
  */
@@ -573,11 +587,24 @@
             }
             break;
 
+        case PRINT_STATUS_PRINTING:
+            // print job is unblocked but job-id is not generated
+            if (new_status->job_id == -1) {
+                sem_post(&_job_start_wait_sem);
+                _lock();
+                if ((jq->job_state != JOB_STATE_RUNNING) ||
+                    (jq->blocked_reasons != blocked_reasons)) {
+                    jq->job_state = JOB_STATE_RUNNING;
+                    jq->blocked_reasons = blocked_reasons;
+                    _send_status_callback(jq, cb_param, JOB_RUNNING, jq->blocked_reasons, OK);
+                }
+                _unlock();
+            }
+            break;
+
         /* all is well, handled in job status */
         case PRINT_STATUS_CANCELLED:
         /* all is well, handled in job status */
-        case PRINT_STATUS_PRINTING:
-        /* all is well, handled in job status */
         case PRINT_STATUS_UNABLE_TO_CONNECT:
             break;
 
@@ -589,6 +616,10 @@
             if ((jq->job_state != JOB_STATE_BLOCKED) || (jq->blocked_reasons != blocked_reasons)) {
                 jq->job_state = JOB_STATE_BLOCKED;
                 jq->blocked_reasons = blocked_reasons;
+                // print job is blocked at the initial stage and job-id is not generated
+                if (new_status->job_id == -1) {
+                    _send_status_callback(jq, cb_param, JOB_BLOCKED, blocked_reasons, OK);
+                }
             }
             _unlock();
             break;
@@ -638,26 +669,14 @@
             _lock();
             if (jq->job_state != JOB_STATE_RUNNING) {
                 jq->job_state = JOB_STATE_RUNNING;
-                if (jq->cb_fn) {
-                    cb_param.id = WPRINT_CB_PARAM_JOB_STATE;
-                    cb_param.param.state = JOB_RUNNING;
-                    cb_param.job_done_result = OK;
-                    jq->cb_fn(jq->job_handle, (void *) &cb_param);
-                }
+                _send_status_callback(jq, cb_param, JOB_RUNNING, 0, OK);
             }
             _unlock();
             break;
 
         case IPP_JOB_STATE_PROCESSING_STOPPED:
             if (jq->job_state == JOB_STATE_BLOCKED) {
-                if (jq->cb_fn) {
-                    cb_param.id = WPRINT_CB_PARAM_JOB_STATE;
-                    cb_param.param.state = JOB_BLOCKED;
-                    cb_param.blocked_reasons = jq->blocked_reasons;
-                    cb_param.job_done_result = OK;
-
-                    jq->cb_fn(jq->job_handle, (void *) &cb_param);
-                }
+                _send_status_callback(jq, cb_param, JOB_BLOCKED, jq->blocked_reasons, OK);
             }
             break;
 
@@ -921,14 +940,7 @@
                                 || (jq->blocked_reasons != blocked_reasons)) {
                             jq->job_state = JOB_STATE_BLOCKED;
                             jq->blocked_reasons = blocked_reasons;
-                            if (jq->cb_fn) {
-                                cb_param.id = WPRINT_CB_PARAM_JOB_STATE;
-                                cb_param.param.state = JOB_BLOCKED;
-                                cb_param.blocked_reasons = blocked_reasons;
-                                cb_param.job_done_result = OK;
-
-                                jq->cb_fn(jq->job_handle, (void *) &cb_param);
-                            }
+                            _send_status_callback(jq, cb_param, JOB_BLOCKED, blocked_reasons, OK);
                         }
                         _unlock();
                         sleep(1);
@@ -965,13 +977,8 @@
             /*  call the plugin's start_job method, if no other job is running
              use callback to notify the client */
 
-            if ((job_result == OK) && jq->cb_fn) {
-                cb_param.id = WPRINT_CB_PARAM_JOB_STATE;
-                cb_param.param.state = JOB_RUNNING;
-                cb_param.blocked_reasons = 0;
-                cb_param.job_done_result = OK;
-
-                jq->cb_fn(job_handle, (void *) &cb_param);
+            if (job_result == OK) {
+                _send_status_callback(jq, cb_param, JOB_RUNNING, 0, OK);
             }
 
             memcpy(&printer_caps, &g_printer_caps, sizeof(printer_capabilities_t));
@@ -1247,6 +1254,7 @@
                 }
                 if ((jq->print_ifc != NULL) && (jq->print_ifc->end_job) &&
                         (strcmp(jq->job_params.print_format, PRINT_FORMAT_PDF) != 0)) {
+                    _unlock();
                     int end_job_result = jq->print_ifc->end_job(jq->print_ifc);
                     if (job_result == OK) {
                         if (end_job_result == ERROR) {
@@ -1255,6 +1263,7 @@
                             job_result = CANCELLED;
                         }
                     }
+                    _lock();
                 }
             }
 
@@ -1356,13 +1365,7 @@
             }
 
             // end of job callback
-            if (jq->cb_fn) {
-                cb_param.id = WPRINT_CB_PARAM_JOB_STATE;
-                cb_param.param.state = JOB_DONE;
-                cb_param.blocked_reasons = jq->blocked_reasons;
-                cb_param.job_done_result = job_result;
-                jq->cb_fn(job_handle, (void *) &cb_param);
-            }
+            _send_status_callback(jq, cb_param, JOB_DONE, jq->blocked_reasons, job_result);
 
             if (jq->print_ifc != NULL) {
                 jq->print_ifc->destroy(jq->print_ifc);