• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  * Copyright (C) 2014-2016 Mopria Alliance, Inc.
4  * Copyright (C) 2013 Hewlett-Packard Development Company, L.P.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 #include <jni.h>
20 #include "lib_wprint.h"
21 #include "wprint_debug.h"
22 #include <errno.h>
23 #include "../plugins/wprint_mupdf.h"
24 
25 #define TAG "wprintJNI"
26 
27 #define MAX_NUM_PAGES 2000
28 
29 static jclass _LocalJobParamsClass;
30 static jfieldID _LocalJobParamsField__borderless;
31 static jfieldID _LocalJobParamsField__duplex;
32 static jfieldID _LocalJobParamsField__media_size;
33 static jfieldID _LocalJobParamsField__media_type;
34 static jfieldID _LocalJobParamsField__media_tray;
35 static jfieldID _LocalJobParamsField__color_space;
36 static jfieldID _LocalJobParamsField__render_flags;
37 static jfieldID _LocalJobParamsField__num_copies;
38 static jfieldID _LocalJobParamsField__page_range;
39 static jfieldID _LocalJobParamsField__print_resolution;
40 static jfieldID _LocalJobParamsField__printable_width;
41 static jfieldID _LocalJobParamsField__printable_height;
42 static jfieldID _LocalJobParamsField__page_width;
43 static jfieldID _LocalJobParamsField__page_height;
44 static jfieldID _LocalJobParamsField__page_margin_top;
45 static jfieldID _LocalJobParamsField__page_margin_left;
46 static jfieldID _LocalJobParamsField__page_margin_right;
47 static jfieldID _LocalJobParamsField__page_margin_bottom;
48 static jfieldID _LocalJobParamsField__job_margin_top;
49 static jfieldID _LocalJobParamsField__job_margin_left;
50 static jfieldID _LocalJobParamsField__job_margin_right;
51 static jfieldID _LocalJobParamsField__job_margin_bottom;
52 static jfieldID _LocalJobParamsField__fit_to_page;
53 static jfieldID _LocalJobParamsField__fill_page;
54 static jfieldID _LocalJobParamsField__auto_rotate;
55 static jfieldID _LocalJobParamsField__portrait_mode;
56 static jfieldID _LocalJobParamsField__landscape_mode;
57 static jfieldID _LocalJobParamsField__nativeData;
58 static jfieldID _LocalJobParamsField__document_category;
59 static jfieldID _LocalJobParamsField__alignment;
60 static jfieldID _LocalJobParamsField__document_scaling;
61 static jfieldID _LocalJobParamsField__job_name;
62 static jfieldID _LocalJobParamsField__job_originating_user_name;
63 static jfieldID _LocalJobParamsField__pdf_render_resolution;
64 static jfieldID _LocalJobParamsField__source_width;
65 static jfieldID _LocalJobParamsField__source_height;
66 
67 static jclass _LocalPrinterCapabilitiesClass;
68 static jfieldID _LocalPrinterCapabilitiesField__name;
69 static jfieldID _LocalPrinterCapabilitiesField__path;
70 static jfieldID _LocalPrinterCapabilitiesField__uuid;
71 static jfieldID _LocalPrinterCapabilitiesField__location;
72 static jfieldID _LocalPrinterCapabilitiesField__duplex;
73 static jfieldID _LocalPrinterCapabilitiesField__borderless;
74 static jfieldID _LocalPrinterCapabilitiesField__color;
75 static jfieldID _LocalPrinterCapabilitiesField__isSupported;
76 static jfieldID _LocalPrinterCapabilitiesField__mediaDefault;
77 static jfieldID _LocalPrinterCapabilitiesField__supportedMediaTypes;
78 static jfieldID _LocalPrinterCapabilitiesField__supportedMediaSizes;
79 static jfieldID _LocalPrinterCapabilitiesField__nativeData;
80 static jfieldID _LocalPrinterCapabilitiesField__certificate;
81 
82 static jclass _JobCallbackClass;
83 static jobject _callbackReceiver;
84 static jmethodID _JobCallbackMethod__jobCallback;
85 
86 static jclass _JobCallbackParamsClass;
87 static jmethodID _JobCallbackParamsMethod__init;
88 static jfieldID _JobCallbackParamsField__jobId;
89 static jfieldID _JobCallbackParamsField__jobState;
90 static jfieldID _JobCallbackParamsField__jobDoneResult;
91 static jfieldID _JobCallbackParamsField__blockedReasons;
92 static jfieldID _JobCallbackParamsField__certificate;
93 
94 static jclass _PrintServiceStringsClass;
95 static jfieldID _PrintServiceStringsField__JOB_STATE_QUEUED;
96 static jfieldID _PrintServiceStringsField__JOB_STATE_RUNNING;
97 static jfieldID _PrintServiceStringsField__JOB_STATE_BLOCKED;
98 static jfieldID _PrintServiceStringsField__JOB_STATE_DONE;
99 static jfieldID _PrintServiceStringsField__JOB_STATE_OTHER;
100 static jfieldID _PrintServiceStringsField__JOB_DONE_OK;
101 static jfieldID _PrintServiceStringsField__JOB_DONE_ERROR;
102 static jfieldID _PrintServiceStringsField__JOB_DONE_CANCELLED;
103 static jfieldID _PrintServiceStringsField__JOB_DONE_CORRUPT;
104 static jfieldID _PrintServiceStringsField__JOB_DONE_OTHER;
105 static jfieldID _PrintServiceStringsField__JOB_DONE_AUTHENTICATION_CANCELED;
106 static jfieldID _PrintServiceStringsField__JOB_DONE_ACCOUNT_INFO_NEEDED;
107 static jfieldID _PrintServiceStringsField__JOB_DONE_ACCOUNT_CLOSED;
108 static jfieldID _PrintServiceStringsField__JOB_DONE_ACCOUNT_LIMIT_REACHED;
109 static jfieldID _PrintServiceStringsField__JOB_DONE_AUTHORIZATION_FAILED;
110 static jfieldID _PrintServiceStringsField__JOB_DONE_SIDES_UNSUPPORTED;
111 static jfieldID _PrintServiceStringsField__JOB_DONE_BAD_CERTIFICATE;
112 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__OFFLINE;
113 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__BUSY;
114 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__CANCELLED;
115 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__OUT_OF_PAPER;
116 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__OUT_OF_INK;
117 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__OUT_OF_TONER;
118 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__JAMMED;
119 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__DOOR_OPEN;
120 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__SERVICE_REQUEST;
121 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__LOW_ON_INK;
122 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__LOW_ON_TONER;
123 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__REALLY_LOW_ON_INK;
124 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__BAD_CERTIFICATE;
125 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__UNKNOWN;
126 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__PAUSED;
127 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__STOPPED;
128 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__INPUT_CANNOT_FEED_SIZE_SELECTED;
129 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__INTERLOCK_ERROR;
130 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__OUTPUT_MAILBOX_SELECT_FAILURE;
131 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__OUTPUT_TRAY_MISSING;
132 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__BANDER_ERROR;
133 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__BINDER_ERROR;
134 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__POWER_ERROR;
135 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__CLEANER_ERROR;
136 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__DIE_CUTTER_ERROR;
137 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__FOLDER_ERROR;
138 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__IMPRINTER_ERROR;
139 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__INPUT_TRAY_ERROR;
140 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__INSERTER_ERROR;
141 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__INTERPRETER_ERROR;
142 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__MAKE_ENVELOPE_ERROR;
143 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__MARKER_ERROR;
144 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__MEDIA_ERROR;
145 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__PERFORATER_ERROR;
146 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__PUNCHER_ERROR;
147 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__SEPARATION_CUTTER_ERROR;
148 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__SHEET_ROTATOR_ERROR;
149 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__SLITTER_ERROR;
150 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__STACKER_ERROR;
151 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__STAPLER_ERROR;
152 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__STITCHER_ERROR;
153 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__SUBUNIT_ERROR;
154 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__TRIMMER_ERROR;
155 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__WRAPPER_ERROR;
156 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__CLIENT_ERROR;
157 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__SERVER_ERROR;
158 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__ALERT_REMOVAL_OF_BINARY_CHANGE_ENTRY;
159 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__CONFIGURATION_CHANGED;
160 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__CONNECTING_TO_DEVICE;
161 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__DEACTIVATED;
162 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__DEVELOPER_ERROR;
163 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__HOLD_NEW_JOBS;
164 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__OPC_LIFE_OVER;
165 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__SPOOL_AREA_FULL;
166 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__TIMED_OUT;
167 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__SHUTDOWN;
168 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__PRINTER_NMS_RESET;
169 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__PRINTER_MANUAL_RESET;
170 
171 static jfieldID _PrintServiceStringsField__ALIGNMENT__CENTER;
172 static jfieldID _PrintServiceStringsField__ALIGNMENT__CENTER_HORIZONTAL;
173 static jfieldID _PrintServiceStringsField__ALIGNMENT__CENTER_VERTICAL;
174 static jfieldID _PrintServiceStringsField__ALIGNMENT__CENTER_HORIZONTAL_ON_ORIENTATION;
175 
176 static jfieldID _PrintServiceStringField__JOB_FAIL_REASON__ABORTED_BY_SYSTEM;
177 static jfieldID _PrintServiceStringField__JOB_FAIL_REASON__UNSUPPORTED_COMPRESSION;
178 static jfieldID _PrintServiceStringField__JOB_FAIL_REASON__COMPRESSION_ERROR;
179 static jfieldID _PrintServiceStringField__JOB_FAIL_REASON__UNSUPPORTED_DOCUMENT_FORMAT;
180 static jfieldID _PrintServiceStringField__JOB_FAIL_REASON__DOCUMENT_FORMAT_ERROR;
181 static jfieldID _PrintServiceStringField__JOB_FAIL_REASON__SERVICE_OFFLINE;
182 static jfieldID _PrintServiceStringField__JOB_FAIL_REASON__DOCUMENT_PASSWORD_ERROR;
183 static jfieldID _PrintServiceStringField__JOB_FAIL_REASON__DOCUMENT_PERMISSION_ERROR;
184 static jfieldID _PrintServiceStringField__JOB_FAIL_REASON__DOCUMENT_SECURITY_ERROR;
185 static jfieldID _PrintServiceStringField__JOB_FAIL_REASON__DOCUMENT_UNPRINTABLE_ERROR;
186 static jfieldID _PrintServiceStringField__JOB_FAIL_REASON__DOCUMENT_ACCESS_ERROR;
187 static jfieldID _PrintServiceStringField__JOB_FAIL_REASON__SUBMISSION_INTERRUPTED;
188 
189 // Global so it can be used in PDF render code
190 JavaVM *_JVM = NULL;
191 
192 static jstring _fakeDir;
193 
194 int g_API_version = 0;
195 
196 /*
197  * Convert char * to a java object
198  */
199 static void stringToJava(JNIEnv *env, jobject obj, jfieldID id, const char *str);
200 
201 /*
202  * Retuns if the mime type is MIME_TYPE_PDF
203  */
_is_pdf_doc(const char * mime_type,const char * pathname)204 static bool _is_pdf_doc(const char *mime_type, const char *pathname) {
205     if (mime_type == NULL || pathname == NULL) {
206         return false;
207     }
208 
209     if (strcmp(mime_type, MIME_TYPE_PDF) == 0) {
210         return true;
211     }
212 
213     return false;
214 }
215 
216 /*
217  * Returns if the string is numeric
218  */
_isNumeric(const char * s)219 static int _isNumeric(const char *s) {
220     if (s == NULL || *s == '\0' || isspace(*s)) {
221         return 0;
222     }
223     char *p;
224     strtod(s, &p);
225     return *p == '\0';
226 }
227 
228 /*
229  * Outputs the number of pages in a pdf to page_count. Returns False if an error ocurred
230  */
_get_pdf_page_count(const char * mime_type,int * page_count,const char * pathname)231 static bool _get_pdf_page_count(const char *mime_type, int *page_count, const char *pathname) {
232     *page_count = 0;
233 
234     if (!_is_pdf_doc(mime_type, pathname)) {
235         return false;
236     }
237 
238     pdf_render_ifc_t *pdf_render_ifc = create_pdf_render_ifc();
239     *page_count = pdf_render_ifc->openDocument(pdf_render_ifc, pathname);
240     pdf_render_ifc->destroy(pdf_render_ifc);
241 
242     LOGI("pdf page count for %s: %d", pathname, *page_count);
243     if (*page_count < 0) {
244         LOGE("page count error");
245         *page_count = 0;
246     }
247     return true;
248 }
249 
250 /*
251  * Reorders pdf pages before sending to the printer. In general the last page is printed first.
252  * Removes pages from pages_ary if they are not in the specified range.
253  */
_order_pdf_pages(int num_pages,int * pages_ary,int * num_index,char * page_range_split)254 static bool _order_pdf_pages(int num_pages, int *pages_ary, int *num_index,
255         char *page_range_split) {
256     bool succeeded = false;
257     char num_begin_ary[5] = "";
258     char num_end_ary[5] = "";
259     int num_counter = 0;
260     bool dash_encountered = false;
261     int range_count = 0;
262 
263     // initialize to 0
264     memset(num_begin_ary, 0, 5);
265     memset(num_end_ary, 0, 5);
266 
267     for (range_count = 0; range_count < (int) strlen(page_range_split); range_count++) {
268         // skip spaces
269         if (!isspace(page_range_split[range_count])) {
270             // store first number found in range in num_begin_ary
271             // and second number (after the dash '-') in num_end_ary
272             // skip the dash ('-') character
273             if (page_range_split[range_count] == '-') {
274                 dash_encountered = true;
275                 num_counter = 0;
276                 continue;
277             }
278 
279             if (!dash_encountered) {
280                 num_begin_ary[num_counter++] = page_range_split[range_count];
281             } else {
282                 num_end_ary[num_counter++] = page_range_split[range_count];
283             }
284         }
285     }
286 
287     // fill in first cell of end num with 0 so array has a valid number
288     if (!dash_encountered) {
289         num_end_ary[0] = '0';
290     }
291 
292     // make sure numeric values are stored in num_begin_ary and num_end_ary
293     if (_isNumeric(num_begin_ary) && _isNumeric(num_end_ary)) {
294         // convert to integers
295         int num_begin = atoi(num_begin_ary);
296         int num_end = atoi(num_end_ary);
297 
298         // if ending number was 0, there was no range, only a single page number
299         // so, set it to the value of the beginning number
300         if (num_end == 0) {
301             num_end = num_begin;
302         }
303 
304         // make sure beginning and ending numbers are at least 1
305         if (num_begin > 0 && num_end > 0) {
306             // make sure the beginning and ending numbers are not greater than the page count
307             if (num_begin <= num_pages && num_end <= num_pages) {
308                 if (num_end >= num_begin) {
309                     // make sure the upper bound does not exceed the number of pages
310                     if (num_end > num_pages) {
311                         num_end = num_pages;
312                     }
313                     // store range in pages_ary in ascending order
314                     int count = 0;
315                     for (count = *num_index; count <= (*num_index + num_end - num_begin); count++) {
316                         *(pages_ary + count) = num_begin++;
317                         *num_index += 1;
318                     }
319                 } else {
320                     // reverse order
321                     // make sure the upper bound does not exceed the number of pages
322                     if (num_begin > num_pages) {
323                         num_begin = num_pages;
324                     }
325                     // store range in pages_ary in descending order
326                     int count = 0;
327                     for (count = *num_index; count <= *num_index + num_begin - num_end; count++) {
328                         *(pages_ary + count) = num_begin--;
329                         *num_index += 1;
330                     }
331                 }
332                 succeeded = true;
333             } else {
334                 LOGE("_order_pdf_pages(), ERROR: first and/or last numbers are not greater than "
335                         "%d: first num=%d, second num=%d", num_pages, num_begin, num_end);
336             }
337         } else {
338             LOGE("_order_pdf_pages(), ERROR: first and/or last numbers are not greater than 0: "
339                     "first num=%d, second num=%d", num_begin, num_end);
340         }
341     } else {
342         LOGE("_order_pdf_pages(), ERROR: first and/or last numbers are not numeric: first num=%s, "
343                 "second num=%s", num_begin_ary, num_end_ary);
344     }
345     return succeeded;
346 }
347 
348 /*
349  * Outputs page range of a pdf to page_range_str
350  */
_get_pdf_page_range(JNIEnv * env,jobject javaJobParams,int * pages_ary,int num_pages,int * num_index,char * page_range_str)351 static void _get_pdf_page_range(JNIEnv *env, jobject javaJobParams, int *pages_ary, int num_pages,
352         int *num_index, char *page_range_str) {
353     char *page_range = NULL;
354     jstring pageRangeObject = (jstring) (*env)->GetObjectField(env, javaJobParams,
355             _LocalJobParamsField__page_range);
356     if (pageRangeObject) {
357         int page_range_size = (*env)->GetStringLength(env, pageRangeObject);
358         const jbyte *pageRange = (jbyte *) (*env)->GetStringUTFChars(env, pageRangeObject, 0);
359         if (strcmp((char *) pageRange, "") != 0) {
360             page_range = (char *) malloc(page_range_size + 1);
361             memset(page_range, 0, page_range_size + 1);
362             strncpy(page_range, (char *) pageRange, page_range_size);
363 
364             // no empty strings
365             if (strcmp(page_range, "") == 0) {
366                 free(page_range);
367                 page_range = NULL;
368             }
369 
370             (*env)->ReleaseStringUTFChars(env, pageRangeObject, (const char *) pageRange);
371             LOGD("_get_pdf_page_range(), page_range from JNI environment=%s", page_range);
372         }
373     }
374 
375     if (!page_range) {
376         page_range = (char *) malloc(MAX_NUM_PAGES + 1);
377         memset(page_range, 0, MAX_NUM_PAGES + 1);
378 
379         snprintf(page_range_str, MAX_NUM_PAGES, "1-%d", num_pages);
380         snprintf(page_range, MAX_NUM_PAGES, "1-%d", num_pages);
381     } else {
382         strncpy(page_range_str, page_range, MAX_NUM_PAGES);
383     }
384 
385     LOGD("_get_pdf_page_range(), range: %s, pages in document: %d", page_range_str, num_pages);
386 
387     // get the first token in page_range_str
388     memset(pages_ary, 0, MAX_NUM_PAGES);
389     char *page_range_split = strtok(page_range, ",");
390     while (page_range_split != NULL) {
391         if (!_order_pdf_pages(num_pages, pages_ary, num_index, page_range_split)) {
392             snprintf(page_range_str, MAX_NUM_PAGES, "1-%d", num_pages);
393             LOGD("_get_pdf_page_range(), setting page_range to: %s", page_range_str);
394             _order_pdf_pages(num_pages, pages_ary, num_index, page_range_str);
395             break;
396         }
397 
398         // get next range token
399         page_range_split = strtok(NULL, ",");
400     }
401 
402     if (page_range) {
403         free(page_range);
404     }
405 }
406 
407 /*
408  * Sends a pdf to a printer
409  */
_print_pdf_pages(wJob_t job_handle,printer_capabilities_t * printer_cap,duplex_t duplex,char * pathname,int num_index,int * pages_ary)410 static jint _print_pdf_pages(wJob_t job_handle, printer_capabilities_t *printer_cap,
411         duplex_t duplex, char *pathname, int num_index, int *pages_ary) {
412     int num_pages = num_index;
413 
414     // now, print the pages
415     int page_index;
416     jint result = ERROR;
417 
418     // print forward direction if printer prints pages face down; otherwise print backward
419     // NOTE: last page is sent from calling function
420     if (printer_cap->faceDownTray || duplex) {
421         LOGD("_print_pdf_pages(), pages print face down or duplex, printing in normal order");
422         page_index = 0;
423         while (page_index < num_pages) {
424             LOGD("_print_pdf_pages(), PRINTING PDF: %d", *(pages_ary + page_index));
425             result = wprintPage(job_handle, *(pages_ary + page_index++), pathname, false, true,
426                     0, 0, 0, 0);
427 
428             if (result != OK) {
429                 break;
430             }
431         }
432     } else {
433         LOGI("   _print_pdf_pages(), pages print face up, printing in reverse");
434         page_index = num_pages - 1;
435         while (page_index >= 0) {
436             LOGD("_print_pdf_pages(), PRINTING PDF: %s, page: %d", pathname,
437                     *(pages_ary + page_index));
438             result = wprintPage(job_handle, *(pages_ary + page_index--), pathname, false, true,
439                     0, 0, 0, 0);
440             if (result != OK) {
441                 break;
442             }
443         }
444     }
445 
446     LOGI("   _print_pdf_pages(), printing result: %s", result == OK ? "OK" : "ERROR");
447     return result;
448 }
449 
450 /*
451  * Initialize JNI. Maps java values to jni values.
452  */
_initJNI(JNIEnv * env,jobject callbackReceiver,jstring fakeDir)453 static void _initJNI(JNIEnv *env, jobject callbackReceiver, jstring fakeDir) {
454     _fakeDir = (jstring) (*env)->NewGlobalRef(env, fakeDir);
455 
456     // fill out static accessors for wPrintJobParameters
457     _LocalJobParamsClass = (jclass) (*env)->NewGlobalRef(
458             env, (*env)->FindClass(env, "com/android/bips/jni/LocalJobParams"));
459     _LocalJobParamsField__borderless = (*env)->GetFieldID(env, _LocalJobParamsClass, "borderless",
460             "I");
461     _LocalJobParamsField__duplex = (*env)->GetFieldID(env, _LocalJobParamsClass, "duplex", "I");
462     _LocalJobParamsField__media_size = (*env)->GetFieldID(env, _LocalJobParamsClass, "media_size",
463             "I");
464     _LocalJobParamsField__media_type = (*env)->GetFieldID(env, _LocalJobParamsClass, "media_type",
465             "I");
466     _LocalJobParamsField__media_tray = (*env)->GetFieldID(env, _LocalJobParamsClass, "media_tray",
467             "I");
468     _LocalJobParamsField__color_space = (*env)->GetFieldID(env, _LocalJobParamsClass, "color_space",
469             "I");
470     _LocalJobParamsField__render_flags = (*env)->GetFieldID(env, _LocalJobParamsClass,
471             "render_flags", "I");
472     _LocalJobParamsField__num_copies = (*env)->GetFieldID(env, _LocalJobParamsClass, "num_copies",
473             "I");
474     _LocalJobParamsField__page_range = (*env)->GetFieldID(env, _LocalJobParamsClass, "page_range",
475             "Ljava/lang/String;");
476     _LocalJobParamsField__print_resolution = (*env)->GetFieldID(env, _LocalJobParamsClass,
477             "print_resolution", "I");
478     _LocalJobParamsField__printable_width = (*env)->GetFieldID(env, _LocalJobParamsClass,
479             "printable_width", "I");
480     _LocalJobParamsField__printable_height = (*env)->GetFieldID(env, _LocalJobParamsClass,
481             "printable_height", "I");
482     _LocalJobParamsField__page_width = (*env)->GetFieldID(env, _LocalJobParamsClass, "page_width",
483             "F");
484     _LocalJobParamsField__page_height = (*env)->GetFieldID(env, _LocalJobParamsClass, "page_height",
485             "F");
486     _LocalJobParamsField__page_margin_top = (*env)->GetFieldID(env, _LocalJobParamsClass,
487             "page_margin_top", "F");
488     _LocalJobParamsField__page_margin_left = (*env)->GetFieldID(env, _LocalJobParamsClass,
489             "page_margin_left", "F");
490     _LocalJobParamsField__page_margin_right = (*env)->GetFieldID(env, _LocalJobParamsClass,
491             "page_margin_right", "F");
492     _LocalJobParamsField__page_margin_bottom = (*env)->GetFieldID(env, _LocalJobParamsClass,
493             "page_margin_bottom", "F");
494     _LocalJobParamsField__nativeData = (*env)->GetFieldID(env, _LocalJobParamsClass, "nativeData",
495             "[B");
496     _LocalJobParamsField__fit_to_page = (*env)->GetFieldID(env, _LocalJobParamsClass, "fit_to_page",
497             "Z");
498     _LocalJobParamsField__fill_page = (*env)->GetFieldID(env, _LocalJobParamsClass, "fill_page",
499             "Z");
500     _LocalJobParamsField__auto_rotate = (*env)->GetFieldID(env, _LocalJobParamsClass, "auto_rotate",
501             "Z");
502     _LocalJobParamsField__portrait_mode = (*env)->GetFieldID(env, _LocalJobParamsClass,
503             "portrait_mode", "Z");
504     _LocalJobParamsField__landscape_mode = (*env)->GetFieldID(env, _LocalJobParamsClass,
505             "landscape_mode", "Z");
506     _LocalJobParamsField__document_category = (*env)->GetFieldID(env, _LocalJobParamsClass,
507             "document_category",
508             "Ljava/lang/String;");
509     _LocalJobParamsField__alignment = (*env)->GetFieldID(env, _LocalJobParamsClass, "alignment",
510             "I");
511     _LocalJobParamsField__job_margin_top = (*env)->GetFieldID(env, _LocalJobParamsClass,
512             "job_margin_top", "F");
513     _LocalJobParamsField__job_margin_left = (*env)->GetFieldID(env, _LocalJobParamsClass,
514             "job_margin_left", "F");
515     _LocalJobParamsField__job_margin_right = (*env)->GetFieldID(env, _LocalJobParamsClass,
516             "job_margin_right", "F");
517     _LocalJobParamsField__job_margin_bottom = (*env)->GetFieldID(env, _LocalJobParamsClass,
518             "job_margin_bottom", "F");
519     _LocalJobParamsField__document_scaling = (*env)->GetFieldID(env, _LocalJobParamsClass,
520             "document_scaling", "Z");
521     _LocalJobParamsField__job_name = (*env)->GetFieldID(env, _LocalJobParamsClass, "job_name",
522             "Ljava/lang/String;");
523     _LocalJobParamsField__job_originating_user_name = (*env)->GetFieldID(
524             env, _LocalJobParamsClass, "job_originating_user_name", "Ljava/lang/String;");
525     _LocalJobParamsField__pdf_render_resolution = (*env)->GetFieldID(env, _LocalJobParamsClass,
526             "pdf_render_resolution", "I");
527     _LocalJobParamsField__source_width = (*env)->GetFieldID(env, _LocalJobParamsClass,
528                                                             "source_width", "F");
529     _LocalJobParamsField__source_height = (*env)->GetFieldID(env, _LocalJobParamsClass,
530                                                              "source_height", "F");
531 
532     // fill out static accessors for LocalPrinterCapabilities
533     _LocalPrinterCapabilitiesClass = (jclass) (*env)->NewGlobalRef(env, (*env)->FindClass(
534             env, "com/android/bips/jni/LocalPrinterCapabilities"));
535     _LocalPrinterCapabilitiesField__path = (*env)->GetFieldID(
536             env, _LocalPrinterCapabilitiesClass, "path", "Ljava/lang/String;");
537     _LocalPrinterCapabilitiesField__name = (*env)->GetFieldID(
538             env, _LocalPrinterCapabilitiesClass, "name", "Ljava/lang/String;");
539     _LocalPrinterCapabilitiesField__uuid = (*env)->GetFieldID(
540             env, _LocalPrinterCapabilitiesClass, "uuid", "Ljava/lang/String;");
541     _LocalPrinterCapabilitiesField__location = (*env)->GetFieldID(
542             env, _LocalPrinterCapabilitiesClass, "location", "Ljava/lang/String;");
543     _LocalPrinterCapabilitiesField__duplex = (*env)->GetFieldID(
544             env, _LocalPrinterCapabilitiesClass, "duplex", "Z");
545     _LocalPrinterCapabilitiesField__borderless = (*env)->GetFieldID(
546             env, _LocalPrinterCapabilitiesClass, "borderless", "Z");
547     _LocalPrinterCapabilitiesField__color = (*env)->GetFieldID(
548             env, _LocalPrinterCapabilitiesClass, "color", "Z");
549     _LocalPrinterCapabilitiesField__isSupported = (*env)->GetFieldID(
550             env, _LocalPrinterCapabilitiesClass, "isSupported", "Z");
551     _LocalPrinterCapabilitiesField__mediaDefault = (*env)->GetFieldID(
552             env, _LocalPrinterCapabilitiesClass, "mediaDefault", "Ljava/lang/String;");
553     _LocalPrinterCapabilitiesField__supportedMediaTypes = (*env)->GetFieldID(
554             env, _LocalPrinterCapabilitiesClass, "supportedMediaTypes", "[I");
555     _LocalPrinterCapabilitiesField__supportedMediaSizes = (*env)->GetFieldID(
556             env, _LocalPrinterCapabilitiesClass, "supportedMediaSizes", "[I");
557     _LocalPrinterCapabilitiesField__nativeData = (*env)->GetFieldID(
558             env, _LocalPrinterCapabilitiesClass, "nativeData", "[B");
559     _LocalPrinterCapabilitiesField__certificate = (*env)->GetFieldID(
560             env, _LocalPrinterCapabilitiesClass, "certificate", "[B");
561 
562     _JobCallbackParamsClass = (jclass) (*env)->NewGlobalRef(env, (*env)->FindClass(
563             env, "com/android/bips/jni/JobCallbackParams"));
564     _JobCallbackParamsMethod__init = (*env)->GetMethodID(env, _JobCallbackParamsClass,
565             "<init>", "()V");
566     _JobCallbackParamsField__jobId = (*env)->GetFieldID(env, _JobCallbackParamsClass, "jobId",
567             "I");
568     _JobCallbackParamsField__jobState = (*env)->GetFieldID(
569             env, _JobCallbackParamsClass, "jobState", "Ljava/lang/String;");
570     _JobCallbackParamsField__jobDoneResult = (*env)->GetFieldID(
571             env, _JobCallbackParamsClass, "jobDoneResult", "Ljava/lang/String;");
572     _JobCallbackParamsField__blockedReasons = (*env)->GetFieldID(
573             env, _JobCallbackParamsClass, "blockedReasons", "[Ljava/lang/String;");
574     _JobCallbackParamsField__certificate = (*env)->GetFieldID(
575             env, _JobCallbackParamsClass, "certificate", "[B");
576 
577     if (callbackReceiver) {
578         _callbackReceiver = (jobject) (*env)->NewGlobalRef(env, callbackReceiver);
579     }
580     if (_callbackReceiver) {
581         _JobCallbackClass = (jclass) (*env)->NewGlobalRef(env, (*env)->GetObjectClass(
582                 env, _callbackReceiver));
583         _JobCallbackMethod__jobCallback = (*env)->GetMethodID(
584                 env, _JobCallbackClass, "jobCallback",
585                 "(ILcom/android/bips/jni/JobCallbackParams;)V");
586     } else {
587         _callbackReceiver = 0;
588     }
589 
590     _PrintServiceStringsClass = (jclass) (*env)->NewGlobalRef(env, (*env)->FindClass(
591             env, "com/android/bips/jni/BackendConstants"));
592     _PrintServiceStringsField__JOB_STATE_QUEUED = (*env)->GetStaticFieldID(
593             env, _PrintServiceStringsClass, "JOB_STATE_QUEUED", "Ljava/lang/String;");
594     _PrintServiceStringsField__JOB_STATE_RUNNING = (*env)->GetStaticFieldID(
595             env, _PrintServiceStringsClass, "JOB_STATE_RUNNING", "Ljava/lang/String;");
596     _PrintServiceStringsField__JOB_STATE_BLOCKED = (*env)->GetStaticFieldID(
597             env, _PrintServiceStringsClass, "JOB_STATE_BLOCKED", "Ljava/lang/String;");
598     _PrintServiceStringsField__JOB_STATE_DONE = (*env)->GetStaticFieldID(
599             env, _PrintServiceStringsClass, "JOB_STATE_DONE", "Ljava/lang/String;");
600     _PrintServiceStringsField__JOB_STATE_OTHER = (*env)->GetStaticFieldID(
601             env, _PrintServiceStringsClass, "JOB_STATE_OTHER", "Ljava/lang/String;");
602     _PrintServiceStringsField__JOB_DONE_OK = (*env)->GetStaticFieldID(
603             env, _PrintServiceStringsClass, "JOB_DONE_OK", "Ljava/lang/String;");
604     _PrintServiceStringsField__JOB_DONE_ERROR = (*env)->GetStaticFieldID(
605             env, _PrintServiceStringsClass, "JOB_DONE_ERROR", "Ljava/lang/String;");
606     _PrintServiceStringsField__JOB_DONE_CANCELLED = (*env)->GetStaticFieldID(
607             env, _PrintServiceStringsClass, "JOB_DONE_CANCELLED", "Ljava/lang/String;");
608     _PrintServiceStringsField__JOB_DONE_CORRUPT = (*env)->GetStaticFieldID(
609             env, _PrintServiceStringsClass, "JOB_DONE_CORRUPT", "Ljava/lang/String;");
610     _PrintServiceStringsField__JOB_DONE_OTHER = (*env)->GetStaticFieldID(
611             env, _PrintServiceStringsClass, "JOB_DONE_OTHER", "Ljava/lang/String;");
612     _PrintServiceStringsField__JOB_DONE_AUTHENTICATION_CANCELED = (*env)->GetStaticFieldID(env,
613             _PrintServiceStringsClass, "JOB_DONE_AUTHENTICATION_CANCELED", "Ljava/lang/String;");
614     _PrintServiceStringsField__JOB_DONE_ACCOUNT_INFO_NEEDED = (*env)->GetStaticFieldID(env,
615             _PrintServiceStringsClass, "JOB_DONE_ACCOUNT_INFO_NEEDED", "Ljava/lang/String;");
616     _PrintServiceStringsField__JOB_DONE_ACCOUNT_CLOSED = (*env)->GetStaticFieldID(env,
617             _PrintServiceStringsClass, "JOB_DONE_ACCOUNT_CLOSED", "Ljava/lang/String;");
618     _PrintServiceStringsField__JOB_DONE_ACCOUNT_LIMIT_REACHED = (*env)->GetStaticFieldID(env,
619             _PrintServiceStringsClass, "JOB_DONE_ACCOUNT_LIMIT_REACHED", "Ljava/lang/String;");
620     _PrintServiceStringsField__JOB_DONE_AUTHORIZATION_FAILED = (*env)->GetStaticFieldID(env,
621             _PrintServiceStringsClass, "JOB_DONE_AUTHORIZATION_FAILED", "Ljava/lang/String;");
622     _PrintServiceStringsField__JOB_DONE_SIDES_UNSUPPORTED = (*env)->GetStaticFieldID(env,
623             _PrintServiceStringsClass, "JOB_DONE_SIDES_UNSUPPORTED", "Ljava/lang/String;");
624     _PrintServiceStringsField__JOB_DONE_BAD_CERTIFICATE = (*env)->GetStaticFieldID(env,
625             _PrintServiceStringsClass, "JOB_DONE_BAD_CERTIFICATE", "Ljava/lang/String;");
626     _PrintServiceStringsField__BLOCKED_REASON__OFFLINE = (*env)->GetStaticFieldID(
627             env, _PrintServiceStringsClass, "BLOCKED_REASON__OFFLINE", "Ljava/lang/String;");
628     _PrintServiceStringsField__BLOCKED_REASON__BUSY = (*env)->GetStaticFieldID(
629             env, _PrintServiceStringsClass, "BLOCKED_REASON__BUSY", "Ljava/lang/String;");
630     _PrintServiceStringsField__BLOCKED_REASON__CANCELLED = (*env)->GetStaticFieldID(
631             env, _PrintServiceStringsClass, "BLOCKED_REASON__CANCELLED", "Ljava/lang/String;");
632     _PrintServiceStringsField__BLOCKED_REASON__OUT_OF_PAPER = (*env)->GetStaticFieldID(
633             env, _PrintServiceStringsClass, "BLOCKED_REASON__OUT_OF_PAPER", "Ljava/lang/String;");
634     _PrintServiceStringsField__BLOCKED_REASON__OUT_OF_INK = (*env)->GetStaticFieldID(
635             env, _PrintServiceStringsClass, "BLOCKED_REASON__OUT_OF_INK", "Ljava/lang/String;");
636     _PrintServiceStringsField__BLOCKED_REASON__OUT_OF_TONER = (*env)->GetStaticFieldID(
637             env, _PrintServiceStringsClass, "BLOCKED_REASON__OUT_OF_TONER", "Ljava/lang/String;");
638     _PrintServiceStringsField__BLOCKED_REASON__JAMMED = (*env)->GetStaticFieldID(
639             env, _PrintServiceStringsClass, "BLOCKED_REASON__JAMMED", "Ljava/lang/String;");
640     _PrintServiceStringsField__BLOCKED_REASON__DOOR_OPEN = (*env)->GetStaticFieldID(
641             env, _PrintServiceStringsClass, "BLOCKED_REASON__DOOR_OPEN", "Ljava/lang/String;");
642     _PrintServiceStringsField__BLOCKED_REASON__SERVICE_REQUEST = (*env)->GetStaticFieldID(
643             env, _PrintServiceStringsClass, "BLOCKED_REASON__SERVICE_REQUEST",
644             "Ljava/lang/String;");
645     _PrintServiceStringsField__BLOCKED_REASON__LOW_ON_INK = (*env)->GetStaticFieldID(
646             env, _PrintServiceStringsClass, "BLOCKED_REASON__LOW_ON_INK", "Ljava/lang/String;");
647     _PrintServiceStringsField__BLOCKED_REASON__LOW_ON_TONER = (*env)->GetStaticFieldID(
648             env, _PrintServiceStringsClass, "BLOCKED_REASON__LOW_ON_TONER", "Ljava/lang/String;");
649     _PrintServiceStringsField__BLOCKED_REASON__REALLY_LOW_ON_INK = (*env)->GetStaticFieldID(
650             env, _PrintServiceStringsClass, "BLOCKED_REASON__REALLY_LOW_ON_INK",
651             "Ljava/lang/String;");
652     _PrintServiceStringsField__BLOCKED_REASON__BAD_CERTIFICATE = (*env)->GetStaticFieldID(
653             env, _PrintServiceStringsClass, "BLOCKED_REASON__BAD_CERTIFICATE",
654             "Ljava/lang/String;");
655     _PrintServiceStringsField__BLOCKED_REASON__UNKNOWN = (*env)->GetStaticFieldID(
656             env, _PrintServiceStringsClass, "BLOCKED_REASON__UNKNOWN", "Ljava/lang/String;");
657     _PrintServiceStringsField__BLOCKED_REASON__PAUSED = (*env)->GetStaticFieldID(env,
658             _PrintServiceStringsClass, "BLOCKED_REASON__PAUSED", "Ljava/lang/String;");
659     _PrintServiceStringsField__BLOCKED_REASON__STOPPED = (*env)->GetStaticFieldID(env,
660             _PrintServiceStringsClass, "BLOCKED_REASON__STOPPED", "Ljava/lang/String;");
661     _PrintServiceStringsField__BLOCKED_REASON__INPUT_CANNOT_FEED_SIZE_SELECTED =
662             (*env)->GetStaticFieldID(env, _PrintServiceStringsClass,
663             "BLOCKED_REASON__INPUT_CANNOT_FEED_SIZE_SELECTED", "Ljava/lang/String;");
664     _PrintServiceStringsField__BLOCKED_REASON__INTERLOCK_ERROR = (*env)->GetStaticFieldID(env,
665             _PrintServiceStringsClass, "BLOCKED_REASON__INTERLOCK_ERROR", "Ljava/lang/String;");
666     _PrintServiceStringsField__BLOCKED_REASON__OUTPUT_MAILBOX_SELECT_FAILURE =
667             (*env)->GetStaticFieldID(env, _PrintServiceStringsClass,
668             "BLOCKED_REASON__OUTPUT_MAILBOX_SELECT_FAILURE", "Ljava/lang/String;");
669     _PrintServiceStringsField__BLOCKED_REASON__OUTPUT_TRAY_MISSING = (*env)->GetStaticFieldID(env,
670             _PrintServiceStringsClass, "BLOCKED_REASON__OUTPUT_TRAY_MISSING", "Ljava/lang/String;");
671     _PrintServiceStringsField__BLOCKED_REASON__BANDER_ERROR = (*env)->GetStaticFieldID(env,
672             _PrintServiceStringsClass, "BLOCKED_REASON__BANDER_ERROR", "Ljava/lang/String;");
673     _PrintServiceStringsField__BLOCKED_REASON__BINDER_ERROR = (*env)->GetStaticFieldID(env,
674             _PrintServiceStringsClass, "BLOCKED_REASON__BINDER_ERROR", "Ljava/lang/String;");
675     _PrintServiceStringsField__BLOCKED_REASON__POWER_ERROR = (*env)->GetStaticFieldID(env,
676             _PrintServiceStringsClass, "BLOCKED_REASON__POWER_ERROR", "Ljava/lang/String;");
677     _PrintServiceStringsField__BLOCKED_REASON__CLEANER_ERROR = (*env)->GetStaticFieldID(env,
678             _PrintServiceStringsClass, "BLOCKED_REASON__CLEANER_ERROR", "Ljava/lang/String;");
679     _PrintServiceStringsField__BLOCKED_REASON__DIE_CUTTER_ERROR = (*env)->GetStaticFieldID(env,
680             _PrintServiceStringsClass, "BLOCKED_REASON__DIE_CUTTER_ERROR", "Ljava/lang/String;");
681     _PrintServiceStringsField__BLOCKED_REASON__FOLDER_ERROR = (*env)->GetStaticFieldID(env,
682             _PrintServiceStringsClass, "BLOCKED_REASON__FOLDER_ERROR", "Ljava/lang/String;");
683     _PrintServiceStringsField__BLOCKED_REASON__IMPRINTER_ERROR = (*env)->GetStaticFieldID(env,
684             _PrintServiceStringsClass, "BLOCKED_REASON__IMPRINTER_ERROR", "Ljava/lang/String;");
685     _PrintServiceStringsField__BLOCKED_REASON__INPUT_TRAY_ERROR = (*env)->GetStaticFieldID(env,
686             _PrintServiceStringsClass, "BLOCKED_REASON__INPUT_TRAY_ERROR", "Ljava/lang/String;");
687     _PrintServiceStringsField__BLOCKED_REASON__INSERTER_ERROR = (*env)->GetStaticFieldID(env,
688             _PrintServiceStringsClass, "BLOCKED_REASON__INSERTER_ERROR", "Ljava/lang/String;");
689     _PrintServiceStringsField__BLOCKED_REASON__INTERPRETER_ERROR = (*env)->GetStaticFieldID(env,
690             _PrintServiceStringsClass, "BLOCKED_REASON__INTERPRETER_ERROR", "Ljava/lang/String;");
691     _PrintServiceStringsField__BLOCKED_REASON__MAKE_ENVELOPE_ERROR = (*env)->GetStaticFieldID(env,
692             _PrintServiceStringsClass, "BLOCKED_REASON__MAKE_ENVELOPE_ERROR", "Ljava/lang/String;");
693     _PrintServiceStringsField__BLOCKED_REASON__MARKER_ERROR = (*env)->GetStaticFieldID(env,
694             _PrintServiceStringsClass, "BLOCKED_REASON__MARKER_ERROR", "Ljava/lang/String;");
695     _PrintServiceStringsField__BLOCKED_REASON__MEDIA_ERROR = (*env)->GetStaticFieldID(env,
696             _PrintServiceStringsClass, "BLOCKED_REASON__MEDIA_ERROR", "Ljava/lang/String;");
697     _PrintServiceStringsField__BLOCKED_REASON__PERFORATER_ERROR = (*env)->GetStaticFieldID(env,
698             _PrintServiceStringsClass, "BLOCKED_REASON__PERFORATER_ERROR", "Ljava/lang/String;");
699     _PrintServiceStringsField__BLOCKED_REASON__PUNCHER_ERROR = (*env)->GetStaticFieldID(env,
700             _PrintServiceStringsClass, "BLOCKED_REASON__PUNCHER_ERROR", "Ljava/lang/String;");
701     _PrintServiceStringsField__BLOCKED_REASON__SEPARATION_CUTTER_ERROR = (*env)->GetStaticFieldID(
702             env, _PrintServiceStringsClass, "BLOCKED_REASON__SEPARATION_CUTTER_ERROR",
703             "Ljava/lang/String;");
704     _PrintServiceStringsField__BLOCKED_REASON__SHEET_ROTATOR_ERROR = (*env)->GetStaticFieldID(env,
705             _PrintServiceStringsClass, "BLOCKED_REASON__SHEET_ROTATOR_ERROR", "Ljava/lang/String;");
706     _PrintServiceStringsField__BLOCKED_REASON__SLITTER_ERROR = (*env)->GetStaticFieldID(env,
707             _PrintServiceStringsClass, "BLOCKED_REASON__SLITTER_ERROR", "Ljava/lang/String;");
708     _PrintServiceStringsField__BLOCKED_REASON__STACKER_ERROR = (*env)->GetStaticFieldID(env,
709             _PrintServiceStringsClass, "BLOCKED_REASON__STACKER_ERROR", "Ljava/lang/String;");
710     _PrintServiceStringsField__BLOCKED_REASON__STAPLER_ERROR = (*env)->GetStaticFieldID(env,
711             _PrintServiceStringsClass, "BLOCKED_REASON__STAPLER_ERROR", "Ljava/lang/String;");
712     _PrintServiceStringsField__BLOCKED_REASON__STITCHER_ERROR = (*env)->GetStaticFieldID(env,
713             _PrintServiceStringsClass, "BLOCKED_REASON__STITCHER_ERROR", "Ljava/lang/String;");
714     _PrintServiceStringsField__BLOCKED_REASON__SUBUNIT_ERROR = (*env)->GetStaticFieldID(env,
715             _PrintServiceStringsClass, "BLOCKED_REASON__SUBUNIT_ERROR", "Ljava/lang/String;");
716     _PrintServiceStringsField__BLOCKED_REASON__TRIMMER_ERROR = (*env)->GetStaticFieldID(env,
717             _PrintServiceStringsClass, "BLOCKED_REASON__TRIMMER_ERROR", "Ljava/lang/String;");
718     _PrintServiceStringsField__BLOCKED_REASON__WRAPPER_ERROR = (*env)->GetStaticFieldID(env,
719             _PrintServiceStringsClass, "BLOCKED_REASON__WRAPPER_ERROR", "Ljava/lang/String;");
720     _PrintServiceStringsField__BLOCKED_REASON__CLIENT_ERROR = (*env)->GetStaticFieldID(env,
721             _PrintServiceStringsClass, "BLOCKED_REASON__CLIENT_ERROR", "Ljava/lang/String;");
722     _PrintServiceStringsField__BLOCKED_REASON__SERVER_ERROR = (*env)->GetStaticFieldID(env,
723             _PrintServiceStringsClass, "BLOCKED_REASON__SERVER_ERROR", "Ljava/lang/String;");
724     _PrintServiceStringsField__BLOCKED_REASON__ALERT_REMOVAL_OF_BINARY_CHANGE_ENTRY =
725             (*env)->GetStaticFieldID(env, _PrintServiceStringsClass,
726             "BLOCKED_REASON__ALERT_REMOVAL_OF_BINARY_CHANGE_ENTRY", "Ljava/lang/String;");
727     _PrintServiceStringsField__BLOCKED_REASON__CONFIGURATION_CHANGED = (*env)->GetStaticFieldID(env,
728             _PrintServiceStringsClass, "BLOCKED_REASON__CONFIGURATION_CHANGED",
729             "Ljava/lang/String;");
730     _PrintServiceStringsField__BLOCKED_REASON__CONNECTING_TO_DEVICE = (*env)->GetStaticFieldID(env,
731             _PrintServiceStringsClass, "BLOCKED_REASON__CONNECTING_TO_DEVICE",
732             "Ljava/lang/String;");
733     _PrintServiceStringsField__BLOCKED_REASON__DEACTIVATED = (*env)->GetStaticFieldID(env,
734             _PrintServiceStringsClass, "BLOCKED_REASON__DEACTIVATED", "Ljava/lang/String;");
735     _PrintServiceStringsField__BLOCKED_REASON__DEVELOPER_ERROR = (*env)->GetStaticFieldID(env,
736             _PrintServiceStringsClass, "BLOCKED_REASON__DEVELOPER_ERROR", "Ljava/lang/String;");
737     _PrintServiceStringsField__BLOCKED_REASON__HOLD_NEW_JOBS = (*env)->GetStaticFieldID(env,
738             _PrintServiceStringsClass, "BLOCKED_REASON__HOLD_NEW_JOBS", "Ljava/lang/String;");
739     _PrintServiceStringsField__BLOCKED_REASON__OPC_LIFE_OVER = (*env)->GetStaticFieldID(env,
740             _PrintServiceStringsClass, "BLOCKED_REASON__OPC_LIFE_OVER", "Ljava/lang/String;");
741     _PrintServiceStringsField__BLOCKED_REASON__SPOOL_AREA_FULL = (*env)->GetStaticFieldID(env,
742             _PrintServiceStringsClass, "BLOCKED_REASON__SPOOL_AREA_FULL", "Ljava/lang/String;");
743     _PrintServiceStringsField__BLOCKED_REASON__SHUTDOWN = (*env)->GetStaticFieldID(env,
744             _PrintServiceStringsClass, "BLOCKED_REASON__SHUTDOWN", "Ljava/lang/String;");
745     _PrintServiceStringsField__BLOCKED_REASON__TIMED_OUT = (*env)->GetStaticFieldID(env,
746             _PrintServiceStringsClass, "BLOCKED_REASON__TIMED_OUT", "Ljava/lang/String;");
747     _PrintServiceStringsField__BLOCKED_REASON__PRINTER_MANUAL_RESET = (*env)->GetStaticFieldID(env,
748             _PrintServiceStringsClass, "BLOCKED_REASON__PRINTER_MANUAL_RESET",
749             "Ljava/lang/String;");
750     _PrintServiceStringsField__BLOCKED_REASON__PRINTER_NMS_RESET = (*env)->GetStaticFieldID(env,
751             _PrintServiceStringsClass, "BLOCKED_REASON__PRINTER_NMS_RESET", "Ljava/lang/String;");
752 
753 
754     _PrintServiceStringsField__ALIGNMENT__CENTER = (*env)->GetStaticFieldID(
755             env, _PrintServiceStringsClass, "ALIGN_CENTER", "I");
756     _PrintServiceStringsField__ALIGNMENT__CENTER_HORIZONTAL = (*env)->GetStaticFieldID(
757             env, _PrintServiceStringsClass, "ALIGN_CENTER_HORIZONTAL", "I");
758     _PrintServiceStringsField__ALIGNMENT__CENTER_VERTICAL = (*env)->GetStaticFieldID(
759             env, _PrintServiceStringsClass, "ALIGN_CENTER_VERTICIAL", "I");
760     _PrintServiceStringsField__ALIGNMENT__CENTER_HORIZONTAL_ON_ORIENTATION =
761             (*env)->GetStaticFieldID(env, _PrintServiceStringsClass,
762                     "ALIGN_CENTER_HORIZONTAL_ON_ORIENTATION", "I");
763 
764     _PrintServiceStringField__JOB_FAIL_REASON__ABORTED_BY_SYSTEM = (*env)->GetStaticFieldID(env,
765             _PrintServiceStringsClass, "JOB_FAIL_REASON__ABORTED_BY_SYSTEM", "Ljava/lang/String;");
766     _PrintServiceStringField__JOB_FAIL_REASON__UNSUPPORTED_COMPRESSION = (*env)->GetStaticFieldID(
767             env, _PrintServiceStringsClass, "JOB_FAIL_REASON__UNSUPPORTED_COMPRESSION",
768             "Ljava/lang/String;");
769     _PrintServiceStringField__JOB_FAIL_REASON__COMPRESSION_ERROR = (*env)->GetStaticFieldID(env,
770             _PrintServiceStringsClass, "JOB_FAIL_REASON__COMPRESSION_ERROR", "Ljava/lang/String;");
771     _PrintServiceStringField__JOB_FAIL_REASON__UNSUPPORTED_DOCUMENT_FORMAT =
772             (*env)->GetStaticFieldID(env, _PrintServiceStringsClass,
773             "JOB_FAIL_REASON__UNSUPPORTED_DOCUMENT_FORMAT", "Ljava/lang/String;");
774     _PrintServiceStringField__JOB_FAIL_REASON__DOCUMENT_FORMAT_ERROR = (*env)->GetStaticFieldID(env,
775             _PrintServiceStringsClass, "JOB_FAIL_REASON__DOCUMENT_FORMAT_ERROR",
776             "Ljava/lang/String;");
777     _PrintServiceStringField__JOB_FAIL_REASON__SERVICE_OFFLINE = (*env)->GetStaticFieldID(env,
778             _PrintServiceStringsClass, "JOB_FAIL_REASON__SERVICE_OFFLINE", "Ljava/lang/String;");
779     _PrintServiceStringField__JOB_FAIL_REASON__DOCUMENT_PASSWORD_ERROR = (*env)->GetStaticFieldID(
780             env, _PrintServiceStringsClass, "JOB_FAIL_REASON__DOCUMENT_PASSWORD_ERROR",
781             "Ljava/lang/String;");
782     _PrintServiceStringField__JOB_FAIL_REASON__DOCUMENT_PERMISSION_ERROR = (*env)->GetStaticFieldID(
783             env, _PrintServiceStringsClass, "JOB_FAIL_REASON__DOCUMENT_PERMISSION_ERROR",
784             "Ljava/lang/String;");
785     _PrintServiceStringField__JOB_FAIL_REASON__DOCUMENT_SECURITY_ERROR = (*env)->GetStaticFieldID(
786             env, _PrintServiceStringsClass, "JOB_FAIL_REASON__DOCUMENT_SECURITY_ERROR",
787             "Ljava/lang/String;");
788     _PrintServiceStringField__JOB_FAIL_REASON__DOCUMENT_UNPRINTABLE_ERROR =
789             (*env)->GetStaticFieldID(env, _PrintServiceStringsClass,
790             "JOB_FAIL_REASON__DOCUMENT_UNPRINTABLE_ERROR", "Ljava/lang/String;");
791     _PrintServiceStringField__JOB_FAIL_REASON__DOCUMENT_ACCESS_ERROR = (*env)->GetStaticFieldID(
792             env, _PrintServiceStringsClass, "JOB_FAIL_REASON__DOCUMENT_ACCESS_ERROR",
793             "Ljava/lang/String;");
794     _PrintServiceStringField__JOB_FAIL_REASON__SUBMISSION_INTERRUPTED = (*env)->GetStaticFieldID(
795             env, _PrintServiceStringsClass, "JOB_FAIL_REASON__SUBMISSION_INTERRUPTED",
796             "Ljava/lang/String;");
797 
798     pdf_render_init(env);
799 }
800 
801 /*
802  * Converts java printer caps to c and saves them to wprintPrinterCaps
803  */
_convertPrinterCaps_to_C(JNIEnv * env,jobject javaPrinterCaps,printer_capabilities_t * wprintPrinterCaps)804 static int _convertPrinterCaps_to_C(JNIEnv *env, jobject javaPrinterCaps,
805         printer_capabilities_t *wprintPrinterCaps) {
806     if (!javaPrinterCaps || !wprintPrinterCaps) {
807         return ERROR;
808     }
809 
810     jbyteArray nativeDataObject = (jbyteArray) (*env)->GetObjectField(
811             env, javaPrinterCaps, _LocalPrinterCapabilitiesField__nativeData);
812     if (!nativeDataObject) {
813         return ERROR;
814     }
815     jbyte *nativeDataPtr = (*env)->GetByteArrayElements(env, nativeDataObject, NULL);
816     memcpy(wprintPrinterCaps, (const void *) nativeDataPtr, sizeof(printer_capabilities_t));
817     (*env)->ReleaseByteArrayElements(env, nativeDataObject, nativeDataPtr, 0);
818 
819     return OK;
820 }
821 
822 /*
823  * Converts printer caps to java and saves them to javaPrinterCaps
824  */
_convertPrinterCaps_to_Java(JNIEnv * env,jobject javaPrinterCaps,const printer_capabilities_t * wprintPrinterCaps)825 static int _convertPrinterCaps_to_Java(JNIEnv *env, jobject javaPrinterCaps,
826         const printer_capabilities_t *wprintPrinterCaps) {
827     if (!javaPrinterCaps || !wprintPrinterCaps) {
828         return ERROR;
829     }
830 
831     int arrayCreated = 0;
832     jbyteArray nativeDataObject = (jbyteArray) (*env)->GetObjectField(
833             env, javaPrinterCaps, _LocalPrinterCapabilitiesField__nativeData);
834     if (!nativeDataObject) {
835         arrayCreated = 1;
836         nativeDataObject = (*env)->NewByteArray(env, sizeof(printer_capabilities_t));
837     }
838 
839     jbyte *nativeDataPtr = (*env)->GetByteArrayElements(env, nativeDataObject, NULL);
840     memcpy((void *) nativeDataPtr, wprintPrinterCaps, sizeof(printer_capabilities_t));
841     (*env)->ReleaseByteArrayElements(env, nativeDataObject, nativeDataPtr, 0);
842 
843     if (arrayCreated) {
844         (*env)->SetObjectField(env, javaPrinterCaps, _LocalPrinterCapabilitiesField__nativeData,
845                 nativeDataObject);
846         (*env)->DeleteLocalRef(env, nativeDataObject);
847     }
848 
849     (*env)->SetBooleanField(env, javaPrinterCaps, _LocalPrinterCapabilitiesField__duplex,
850             (jboolean) wprintPrinterCaps->duplex);
851     (*env)->SetBooleanField(env, javaPrinterCaps,
852             _LocalPrinterCapabilitiesField__borderless,
853             (jboolean) wprintPrinterCaps->borderless);
854     (*env)->SetBooleanField(env, javaPrinterCaps, _LocalPrinterCapabilitiesField__color,
855             (jboolean) wprintPrinterCaps->color);
856     (*env)->SetBooleanField(env, javaPrinterCaps, _LocalPrinterCapabilitiesField__isSupported,
857             (jboolean) wprintPrinterCaps->isSupported);
858 
859     stringToJava(env, javaPrinterCaps, _LocalPrinterCapabilitiesField__mediaDefault,
860             wprintPrinterCaps->mediaDefault);
861     stringToJava(env, javaPrinterCaps, _LocalPrinterCapabilitiesField__path,
862             wprintPrinterCaps->printerUri);
863     stringToJava(env, javaPrinterCaps, _LocalPrinterCapabilitiesField__name,
864             wprintPrinterCaps->name);
865     stringToJava(env, javaPrinterCaps, _LocalPrinterCapabilitiesField__uuid,
866             wprintPrinterCaps->uuid);
867     stringToJava(env, javaPrinterCaps, _LocalPrinterCapabilitiesField__location,
868             wprintPrinterCaps->location);
869 
870     jintArray intArray;
871     int *intArrayPtr;
872     int index;
873 
874     intArray = (*env)->NewIntArray(env, wprintPrinterCaps->numSupportedMediaTypes);
875     intArrayPtr = (*env)->GetIntArrayElements(env, intArray, NULL);
876     for (index = 0; index < wprintPrinterCaps->numSupportedMediaTypes; index++) {
877         intArrayPtr[index] = (int) wprintPrinterCaps->supportedMediaTypes[index];
878     }
879     (*env)->ReleaseIntArrayElements(env, intArray, intArrayPtr, 0);
880     (*env)->SetObjectField(env, javaPrinterCaps,
881             _LocalPrinterCapabilitiesField__supportedMediaTypes, intArray);
882     (*env)->DeleteLocalRef(env, intArray);
883 
884     intArray = (*env)->NewIntArray(env, wprintPrinterCaps->numSupportedMediaSizes);
885     intArrayPtr = (*env)->GetIntArrayElements(env, intArray, NULL);
886     for (index = 0; index < wprintPrinterCaps->numSupportedMediaSizes; index++) {
887         intArrayPtr[index] = (int) wprintPrinterCaps->supportedMediaSizes[index];
888     }
889     (*env)->ReleaseIntArrayElements(env, intArray, intArrayPtr, 0);
890     (*env)->SetObjectField(env, javaPrinterCaps,
891             _LocalPrinterCapabilitiesField__supportedMediaSizes, intArray);
892     (*env)->DeleteLocalRef(env, intArray);
893 
894     int count;
895     for (count = index = 0; index < (sizeof(int) * 8); index++) {
896         if ((wprintPrinterCaps->supportedInputMimeTypes & (1 << index)) != 0) {
897             count++;
898         }
899     }
900 
901     return OK;
902 }
903 
904 /*
905  * Converts str to a java string
906  */
stringToJava(JNIEnv * env,jobject obj,jfieldID id,const char * str)907 static void stringToJava(JNIEnv *env, jobject obj, jfieldID id, const char *str) {
908     jstring jStr;
909 
910     // If null, copy an empty string
911     if (!str) str = "";
912 
913     jStr = (*env)->NewStringUTF(env, str);
914     (*env)->SetObjectField(env, obj, id, jStr);
915     (*env)->DeleteLocalRef(env, jStr);
916 }
917 
918 /*
919  * Converts javaJobParams to C and saves them to wprintJobParams
920  */
_convertJobParams_to_C(JNIEnv * env,jobject javaJobParams,wprint_job_params_t * wprintJobParams)921 static int _convertJobParams_to_C(JNIEnv *env, jobject javaJobParams,
922         wprint_job_params_t *wprintJobParams) {
923     if (!javaJobParams || !wprintJobParams) {
924         return ERROR;
925     }
926 
927     jbyteArray nativeDataObject = (jbyteArray) (*env)->GetObjectField(
928             env, javaJobParams, _LocalJobParamsField__nativeData);
929     if (nativeDataObject == 0) {
930         return ERROR;
931     }
932 
933     jbyte *nativeDataPtr = (*env)->GetByteArrayElements(env, nativeDataObject, NULL);
934     memcpy(wprintJobParams, (const void *) nativeDataPtr, sizeof(wprint_job_params_t));
935     (*env)->ReleaseByteArrayElements(env, nativeDataObject, nativeDataPtr, JNI_ABORT);
936 
937     wprintJobParams->media_size = (media_size_t) (*env)->GetIntField(
938             env, javaJobParams, _LocalJobParamsField__media_size);
939     wprintJobParams->media_type = (media_type_t) (*env)->GetIntField(
940             env, javaJobParams, _LocalJobParamsField__media_type);
941     wprintJobParams->duplex = (duplex_t) (*env)->GetIntField(
942             env, javaJobParams, _LocalJobParamsField__duplex);
943     wprintJobParams->color_space = (color_space_t) (*env)->GetIntField(
944             env, javaJobParams, _LocalJobParamsField__color_space);
945     wprintJobParams->media_tray = (media_tray_t) (*env)->GetIntField(
946             env, javaJobParams, _LocalJobParamsField__media_tray);
947     wprintJobParams->num_copies = (unsigned int) (*env)->GetIntField(
948             env, javaJobParams, _LocalJobParamsField__num_copies);
949     wprintJobParams->borderless = (bool) (*env)->GetIntField(env, javaJobParams,
950             _LocalJobParamsField__borderless);
951     wprintJobParams->render_flags = (unsigned int) (*env)->GetIntField(
952             env, javaJobParams, _LocalJobParamsField__render_flags);
953     wprintJobParams->pdf_render_resolution =
954             (unsigned int) (*env)->GetIntField(env, javaJobParams,
955                     _LocalJobParamsField__pdf_render_resolution);
956     // job margin setting
957     wprintJobParams->job_top_margin = (float) (*env)->GetFloatField(
958             env, javaJobParams, _LocalJobParamsField__job_margin_top);
959     wprintJobParams->job_left_margin = (float) (*env)->GetFloatField(
960             env, javaJobParams, _LocalJobParamsField__job_margin_left);
961     wprintJobParams->job_right_margin = (float) (*env)->GetFloatField(
962             env, javaJobParams, _LocalJobParamsField__job_margin_right);
963     wprintJobParams->job_bottom_margin = (float) (*env)->GetFloatField(
964             env, javaJobParams, _LocalJobParamsField__job_margin_bottom);
965     wprintJobParams->source_height = (float) (*env)->GetFloatField(
966             env, javaJobParams, _LocalJobParamsField__source_height);
967     wprintJobParams->source_width = (float) (*env)->GetFloatField(
968             env, javaJobParams, _LocalJobParamsField__source_width);
969 
970     if ((*env)->GetBooleanField(env, javaJobParams, _LocalJobParamsField__portrait_mode)) {
971         wprintJobParams->render_flags |= RENDER_FLAG_PORTRAIT_MODE;
972     } else if ((*env)->GetBooleanField(env, javaJobParams, _LocalJobParamsField__landscape_mode)) {
973         wprintJobParams->render_flags |= RENDER_FLAG_LANDSCAPE_MODE;
974     } else if ((*env)->GetBooleanField(env, javaJobParams, _LocalJobParamsField__auto_rotate)) {
975         wprintJobParams->render_flags |= RENDER_FLAG_AUTO_ROTATE;
976     }
977     if ((*env)->GetBooleanField(env, javaJobParams, _LocalJobParamsField__fill_page)) {
978         wprintJobParams->render_flags |= AUTO_SCALE_RENDER_FLAGS;
979     } else if ((*env)->GetBooleanField(env, javaJobParams, _LocalJobParamsField__fit_to_page)) {
980         wprintJobParams->render_flags |= AUTO_FIT_RENDER_FLAGS;
981         if ((*env)->GetBooleanField(env, javaJobParams, _LocalJobParamsField__document_scaling)) {
982             wprintJobParams->render_flags |= RENDER_FLAG_DOCUMENT_SCALING;
983         }
984     }
985 
986     int alignment = ((*env)->GetIntField(env, javaJobParams, _LocalJobParamsField__alignment));
987     if (alignment != 0) {
988         LOGD("Alignment value %d", alignment);
989         wprintJobParams->render_flags &= ~(RENDER_FLAG_CENTER_VERTICAL |
990                 RENDER_FLAG_CENTER_HORIZONTAL |
991                 RENDER_FLAG_CENTER_ON_ORIENTATION);
992         if (alignment & ((*env)->GetStaticIntField(
993                 env, _PrintServiceStringsClass,
994                 _PrintServiceStringsField__ALIGNMENT__CENTER_HORIZONTAL))) {
995             wprintJobParams->render_flags |= RENDER_FLAG_CENTER_HORIZONTAL;
996         }
997         if (alignment & ((*env)->GetStaticIntField(
998                 env, _PrintServiceStringsClass,
999                 _PrintServiceStringsField__ALIGNMENT__CENTER_VERTICAL))) {
1000             wprintJobParams->render_flags |= RENDER_FLAG_CENTER_VERTICAL;
1001         }
1002         if (alignment & ((*env)->GetStaticIntField(
1003                 env, _PrintServiceStringsClass,
1004                 _PrintServiceStringsField__ALIGNMENT__CENTER_HORIZONTAL_ON_ORIENTATION))) {
1005             wprintJobParams->render_flags |= RENDER_FLAG_CENTER_ON_ORIENTATION;
1006         }
1007         if ((alignment & ((*env)->GetStaticIntField(
1008                 env, _PrintServiceStringsClass, _PrintServiceStringsField__ALIGNMENT__CENTER))) ==
1009                 ((*env)->GetStaticIntField(env, _PrintServiceStringsClass,
1010                         _PrintServiceStringsField__ALIGNMENT__CENTER))) {
1011             wprintJobParams->render_flags &= ~RENDER_FLAG_CENTER_ON_ORIENTATION;
1012             wprintJobParams->render_flags |= (RENDER_FLAG_CENTER_VERTICAL |
1013                     RENDER_FLAG_CENTER_HORIZONTAL);
1014         }
1015     }
1016 
1017     jstring docCategory = (jstring) (*env)->GetObjectField(env, javaJobParams,
1018             _LocalJobParamsField__document_category);
1019     if (docCategory != NULL) {
1020         const char *category = (*env)->GetStringUTFChars(env, docCategory, NULL);
1021         if (category != NULL) {
1022             strncpy(wprintJobParams->docCategory, category,
1023                     sizeof(wprintJobParams->docCategory) - 1);
1024             (*env)->ReleaseStringUTFChars(env, docCategory, category);
1025         }
1026     }
1027     // job name
1028     jstring jobName = (jstring) (*env)->GetObjectField(env, javaJobParams,
1029             _LocalJobParamsField__job_name);
1030     if (jobName != NULL) {
1031         const char *name = (*env)->GetStringUTFChars(env, jobName, NULL);
1032         if (name != NULL) {
1033             strncpy(wprintJobParams->job_name, name, sizeof(wprintJobParams->job_name) - 1);
1034             (*env)->ReleaseStringUTFChars(env, jobName, name);
1035         }
1036     }
1037     // job originating user name
1038     jstring jobOriginatingUserName = (jstring) (*env)->GetObjectField(
1039             env, javaJobParams, _LocalJobParamsField__job_originating_user_name);
1040     if (jobOriginatingUserName != NULL) {
1041         const char *name = (*env)->GetStringUTFChars(env, jobOriginatingUserName, NULL);
1042         if (name != NULL) {
1043             strncpy(wprintJobParams->job_originating_user_name, name,
1044                     sizeof(wprintJobParams->job_originating_user_name) - 1);
1045             (*env)->ReleaseStringUTFChars(env, jobOriginatingUserName, name);
1046         }
1047     }
1048 
1049     free(wprintJobParams->page_range);
1050     wprintJobParams->page_range = NULL;
1051     jstring pageRangeObject = (jstring) (*env)->GetObjectField(env, javaJobParams,
1052             _LocalJobParamsField__page_range);
1053     if (pageRangeObject) {
1054         int page_range_size = (*env)->GetStringLength(env, pageRangeObject);
1055         const jbyte *pageRange = (jbyte *) (*env)->GetStringUTFChars(env, pageRangeObject, 0);
1056         if (strcmp((char *) pageRange, "") != 0) {
1057             wprintJobParams->page_range = (char *) malloc(page_range_size + 1);
1058             memset(wprintJobParams->page_range, 0, page_range_size + 1);
1059             strncpy(wprintJobParams->page_range, (char *) pageRange, page_range_size);
1060 
1061             (*env)->ReleaseStringUTFChars(env, pageRangeObject, (const char *) pageRange);
1062         }
1063     }
1064 
1065     return OK;
1066 }
1067 
1068 /*
1069  * Converts wprintJobParams to java and saves them to javaJobParams
1070  */
_covertJobParams_to_Java(JNIEnv * env,jobject javaJobParams,wprint_job_params_t * wprintJobParams)1071 static int _covertJobParams_to_Java(JNIEnv *env, jobject javaJobParams,
1072         wprint_job_params_t *wprintJobParams) {
1073     if (!javaJobParams || !wprintJobParams) {
1074         return ERROR;
1075     }
1076 
1077     jbyteArray nativeDataObject = (jbyteArray) (*env)->GetObjectField(
1078             env, javaJobParams, _LocalJobParamsField__nativeData);
1079     if (!nativeDataObject) {
1080         nativeDataObject = (*env)->NewByteArray(env, sizeof(wprint_job_params_t));
1081         (*env)->SetObjectField(env, javaJobParams, _LocalJobParamsField__nativeData,
1082                 nativeDataObject);
1083         nativeDataObject = (jbyteArray) (*env)->GetObjectField(env, javaJobParams,
1084                 _LocalJobParamsField__nativeData);
1085     }
1086 
1087     jbyte *nativeDataPtr = (*env)->GetByteArrayElements(env, nativeDataObject, NULL);
1088     memcpy((void *) nativeDataPtr, wprintJobParams, sizeof(wprint_job_params_t));
1089     (*env)->ReleaseByteArrayElements(env, nativeDataObject, nativeDataPtr, 0);
1090 
1091     // update job parameters
1092     (*env)->SetIntField(env, javaJobParams, _LocalJobParamsField__media_size,
1093             (int) wprintJobParams->media_size);
1094     (*env)->SetIntField(env, javaJobParams, _LocalJobParamsField__media_type,
1095             (int) wprintJobParams->media_type);
1096     (*env)->SetIntField(env, javaJobParams, _LocalJobParamsField__duplex,
1097             (int) wprintJobParams->duplex);
1098     (*env)->SetIntField(env, javaJobParams, _LocalJobParamsField__color_space,
1099             (int) wprintJobParams->color_space);
1100     (*env)->SetIntField(env, javaJobParams, _LocalJobParamsField__media_tray,
1101             (int) wprintJobParams->media_tray);
1102     (*env)->SetIntField(env, javaJobParams, _LocalJobParamsField__num_copies,
1103             (int) wprintJobParams->num_copies);
1104     (*env)->SetIntField(env, javaJobParams, _LocalJobParamsField__borderless,
1105             (int) wprintJobParams->borderless);
1106     (*env)->SetIntField(env, javaJobParams, _LocalJobParamsField__render_flags,
1107             (int) wprintJobParams->render_flags);
1108     (*env)->SetIntField(env, javaJobParams, _LocalJobParamsField__pdf_render_resolution,
1109             wprintJobParams->pdf_render_resolution);
1110     (*env)->SetBooleanField(env, javaJobParams, _LocalJobParamsField__fit_to_page,
1111             (jboolean) ((wprintJobParams->render_flags & AUTO_FIT_RENDER_FLAGS) ==
1112                     AUTO_FIT_RENDER_FLAGS));
1113     (*env)->SetBooleanField(env, javaJobParams, _LocalJobParamsField__fill_page,
1114             (jboolean) ((wprintJobParams->render_flags & AUTO_SCALE_RENDER_FLAGS) ==
1115                     AUTO_SCALE_RENDER_FLAGS));
1116     (*env)->SetBooleanField(env, javaJobParams, _LocalJobParamsField__auto_rotate,
1117             (jboolean) ((wprintJobParams->render_flags & RENDER_FLAG_AUTO_ROTATE) != 0));
1118     (*env)->SetBooleanField(env, javaJobParams, _LocalJobParamsField__portrait_mode, (jboolean) (
1119             (wprintJobParams->render_flags & RENDER_FLAG_PORTRAIT_MODE) != 0));
1120     (*env)->SetBooleanField(env, javaJobParams, _LocalJobParamsField__landscape_mode, (jboolean) (
1121             (wprintJobParams->render_flags & RENDER_FLAG_LANDSCAPE_MODE) != 0));
1122 
1123     // update the printable area & DPI information
1124     (*env)->SetIntField(env, javaJobParams, _LocalJobParamsField__print_resolution,
1125             (int) wprintJobParams->pixel_units);
1126     (*env)->SetIntField(env, javaJobParams, _LocalJobParamsField__printable_width,
1127             (int) wprintJobParams->width);
1128     (*env)->SetIntField(env, javaJobParams, _LocalJobParamsField__printable_height,
1129             (int) wprintJobParams->height);
1130 
1131     // update the page size information
1132     (*env)->SetFloatField(env, javaJobParams, _LocalJobParamsField__page_width,
1133             wprintJobParams->page_width);
1134     (*env)->SetFloatField(env, javaJobParams, _LocalJobParamsField__page_height,
1135             wprintJobParams->page_height);
1136     (*env)->SetFloatField(env, javaJobParams, _LocalJobParamsField__page_margin_top,
1137             wprintJobParams->page_top_margin);
1138     (*env)->SetFloatField(env, javaJobParams, _LocalJobParamsField__page_margin_left,
1139             wprintJobParams->page_left_margin);
1140     (*env)->SetFloatField(env, javaJobParams, _LocalJobParamsField__page_margin_right,
1141             wprintJobParams->page_right_margin);
1142     (*env)->SetFloatField(env, javaJobParams, _LocalJobParamsField__page_margin_bottom,
1143             wprintJobParams->page_bottom_margin);
1144 
1145     (*env)->SetFloatField(env, javaJobParams, _LocalJobParamsField__job_margin_top,
1146             wprintJobParams->job_top_margin);
1147     (*env)->SetFloatField(env, javaJobParams, _LocalJobParamsField__job_margin_left,
1148             wprintJobParams->job_left_margin);
1149     (*env)->SetFloatField(env, javaJobParams, _LocalJobParamsField__job_margin_right,
1150             wprintJobParams->job_right_margin);
1151     (*env)->SetFloatField(env, javaJobParams, _LocalJobParamsField__job_margin_bottom,
1152             wprintJobParams->job_bottom_margin);
1153     (*env)->SetFloatField(env, javaJobParams, _LocalJobParamsField__source_width,
1154             wprintJobParams->source_width);
1155     (*env)->SetFloatField(env, javaJobParams, _LocalJobParamsField__source_height,
1156             wprintJobParams->source_height);
1157 
1158     return OK;
1159 }
1160 
1161 /*
1162  * Process fail reasons. Converts them to strings from BackendConstants.java
1163  */
processFailReasons(JNIEnv * env,unsigned long long fail_reasons,unsigned int count)1164 static jobjectArray processFailReasons(JNIEnv *env, unsigned long long fail_reasons,
1165                                        unsigned int count) {
1166     LOGI("entering _process_fail_reasons()");
1167     unsigned int i, reasonCount;
1168 
1169     jstring jStr = (*env)->NewStringUTF(env, "");
1170     jobjectArray stringArray = (*env)->NewObjectArray(env, count,
1171                                                       (*env)->FindClass(env, "java/lang/String"),
1172                                                       jStr);
1173     (*env)->DeleteLocalRef(env, jStr);
1174 
1175     // Note : The fail reason determination conditions should appear in the same sequence
1176     // as defined by enum job_state_reason_t from which they are derived from
1177 
1178     for (reasonCount = i = 0; i < IPP_JOB_STATE_REASON_MAX_VALUE; i++) {
1179         jStr = NULL;
1180 
1181         if ((fail_reasons & (LONG_ONE << i)) == 0) {
1182             jStr = NULL;
1183         } else if (fail_reasons & JOB_FAIL_REASON_UNABLE_TO_CONNECT) {
1184             jStr = (jstring) (*env)->
1185                     GetStaticObjectField(env, _PrintServiceStringsClass,
1186                                          _PrintServiceStringsField__BLOCKED_REASON__OFFLINE);
1187         } else if (fail_reasons & JOB_FAIL_REASON_ABORTED_BY_SYSTEM) {
1188             jStr = (jstring) (*env)->
1189                     GetStaticObjectField(env, _PrintServiceStringsClass,
1190                                      _PrintServiceStringField__JOB_FAIL_REASON__ABORTED_BY_SYSTEM);
1191         } else if (fail_reasons & JOB_FAIL_REASON_UNSUPPORTED_COMPRESSION) {
1192             jStr = (jstring) (*env)->
1193                     GetStaticObjectField(env, _PrintServiceStringsClass,
1194                              _PrintServiceStringField__JOB_FAIL_REASON__UNSUPPORTED_COMPRESSION);
1195         } else if (fail_reasons & JOB_FAIL_REASON_COMPRESSION_ERROR) {
1196             jStr = (jstring) (*env)->
1197                     GetStaticObjectField(env, _PrintServiceStringsClass,
1198                                    _PrintServiceStringField__JOB_FAIL_REASON__COMPRESSION_ERROR);
1199         } else if (fail_reasons & JOB_FAIL_REASON_UNSUPPORTED_DOCUMENT_FORMAT) {
1200             jStr = (jstring) (*env)->
1201                     GetStaticObjectField(env, _PrintServiceStringsClass,
1202                            _PrintServiceStringField__JOB_FAIL_REASON__UNSUPPORTED_DOCUMENT_FORMAT);
1203         } else if (fail_reasons & JOB_FAIL_REASON_DOCUMENT_FORMAT_ERROR) {
1204             jStr = (jstring) (*env)->
1205                     GetStaticObjectField(env, _PrintServiceStringsClass,
1206                                _PrintServiceStringField__JOB_FAIL_REASON__DOCUMENT_FORMAT_ERROR);
1207         } else if (fail_reasons & JOB_FAIL_REASON_SERVICE_OFFLINE) {
1208             jStr = (jstring) (*env)->
1209                     GetStaticObjectField(env, _PrintServiceStringsClass,
1210                                        _PrintServiceStringField__JOB_FAIL_REASON__SERVICE_OFFLINE);
1211         } else if (fail_reasons & JOB_FAIL_REASON_DOCUMENT_PASSWORD_ERROR) {
1212             jStr = (jstring) (*env)->
1213                     GetStaticObjectField(env, _PrintServiceStringsClass,
1214                               _PrintServiceStringField__JOB_FAIL_REASON__DOCUMENT_PASSWORD_ERROR);
1215         } else if (fail_reasons & JOB_FAIL_REASON_DOCUMENT_PERMISSION_ERROR) {
1216             jStr = (jstring) (*env)->
1217                     GetStaticObjectField(env, _PrintServiceStringsClass,
1218                               _PrintServiceStringField__JOB_FAIL_REASON__DOCUMENT_PERMISSION_ERROR);
1219         } else if (fail_reasons & JOB_FAIL_REASON_DOCUMENT_SECURITY_ERROR) {
1220             jStr = (jstring) (*env)->
1221                     GetStaticObjectField(env, _PrintServiceStringsClass,
1222                               _PrintServiceStringField__JOB_FAIL_REASON__DOCUMENT_SECURITY_ERROR);
1223         } else if (fail_reasons & JOB_FAIL_REASON_DOCUMENT_UNPRINTABLE_ERROR) {
1224             jStr = (jstring) (*env)->
1225                     GetStaticObjectField(env, _PrintServiceStringsClass,
1226                           _PrintServiceStringField__JOB_FAIL_REASON__DOCUMENT_UNPRINTABLE_ERROR);
1227         } else if (fail_reasons & JOB_FAIL_REASON_DOCUMENT_ACCESS_ERROR) {
1228             jStr = (jstring) (*env)->
1229                     GetStaticObjectField(env, _PrintServiceStringsClass,
1230                                  _PrintServiceStringField__JOB_FAIL_REASON__DOCUMENT_ACCESS_ERROR);
1231         } else if (fail_reasons & JOB_FAIL_REASON_SUBMISSION_INTERRUPTED) {
1232             jStr = (jstring) (*env)->
1233                     GetStaticObjectField(env, _PrintServiceStringsClass,
1234                                  _PrintServiceStringField__JOB_FAIL_REASON__SUBMISSION_INTERRUPTED);
1235         } else if (fail_reasons & JOB_FAIL_REASON_AUTHORIZATION_FAILED) {
1236             jStr = (jstring) (*env)->
1237                     GetStaticObjectField(env, _PrintServiceStringsClass,
1238                                          _PrintServiceStringsField__JOB_DONE_AUTHORIZATION_FAILED);
1239         } else if (fail_reasons & JOB_FAIL_REASON_ACCOUNT_CLOSED) {
1240             jStr = (jstring) (*env)->
1241                     GetStaticObjectField(env, _PrintServiceStringsClass,
1242                                          _PrintServiceStringsField__JOB_DONE_ACCOUNT_CLOSED);
1243         } else if (fail_reasons & JOB_FAIL_REASON_ACCOUNT_INFO_NEEDED) {
1244             jStr = (jstring) (*env)->
1245                     GetStaticObjectField(env, _PrintServiceStringsClass,
1246                                          _PrintServiceStringsField__JOB_DONE_ACCOUNT_INFO_NEEDED);
1247         } else if (fail_reasons & JOB_FAIL_REASON_ACCOUNT_LIMIT_REACHED) {
1248             jStr = (jstring) (*env)->
1249                     GetStaticObjectField(env, _PrintServiceStringsClass,
1250                                          _PrintServiceStringsField__JOB_DONE_ACCOUNT_LIMIT_REACHED);
1251         }
1252 
1253         fail_reasons &= ~(LONG_ONE << i);
1254 
1255         if (jStr != NULL) {
1256             (*env)->SetObjectArrayElement(env, stringArray, reasonCount++, jStr);
1257         }
1258     }
1259     return stringArray;
1260 }
1261 
1262 /*
1263  * Process block status. Converts the blocked reasons to strings from BackendConstants.java
1264  */
processBlockStatus(JNIEnv * env,unsigned long long blocked_reasons,unsigned int count)1265 static jobjectArray processBlockStatus(JNIEnv *env, unsigned long long blocked_reasons,
1266                                        unsigned int count) {
1267     LOGI("entering process_block_status()");
1268     unsigned int i, reasonCount;
1269 
1270     jstring jStr = (*env)->NewStringUTF(env, "");
1271     jobjectArray stringArray = (*env)->NewObjectArray(env, count,
1272                                                       (*env)->FindClass(env, "java/lang/String"),
1273                                                       jStr);
1274     (*env)->DeleteLocalRef(env, jStr);
1275 
1276     // Note : The block reason determination  conditions should appear in the same sequence
1277     // as defined by enum print_status_t from which they are derived from
1278     for (reasonCount = i = 0; i < PRINT_STATUS_MAX_STATE; i++) {
1279         jStr = NULL;
1280 
1281         if ((blocked_reasons & (LONG_ONE << i)) == 0) {
1282             jStr = NULL;
1283         } else if (blocked_reasons & BLOCKED_REASON_UNABLE_TO_CONNECT) {
1284             jStr = (jstring) (*env)->
1285                     GetStaticObjectField(env, _PrintServiceStringsClass,
1286                                          _PrintServiceStringsField__BLOCKED_REASON__OFFLINE);
1287         } else if (blocked_reasons & BLOCKED_REASON_BUSY) {
1288             jStr = (jstring) (*env)->
1289                     GetStaticObjectField(env, _PrintServiceStringsClass,
1290                                           _PrintServiceStringsField__BLOCKED_REASON__BUSY);
1291         } else if (blocked_reasons & BLOCKED_REASONS_CANCELLED) {
1292             jStr = (jstring) (*env)->
1293                     GetStaticObjectField(env, _PrintServiceStringsClass,
1294                                          _PrintServiceStringsField__BLOCKED_REASON__CANCELLED);
1295         } else if (blocked_reasons & BLOCKED_REASON_OUT_OF_PAPER) {
1296             jStr = (jstring) (*env)->
1297                     GetStaticObjectField(env, _PrintServiceStringsClass,
1298                                          _PrintServiceStringsField__BLOCKED_REASON__OUT_OF_PAPER);
1299         } else if (blocked_reasons & BLOCKED_REASON_OUT_OF_INK) {
1300             jStr = (jstring) (*env)->
1301                     GetStaticObjectField(env, _PrintServiceStringsClass,
1302                                          _PrintServiceStringsField__BLOCKED_REASON__OUT_OF_INK);
1303         } else if (blocked_reasons & BLOCKED_REASON_OUT_OF_TONER) {
1304             jStr = (jstring) (*env)->
1305                     GetStaticObjectField(env, _PrintServiceStringsClass,
1306                                          _PrintServiceStringsField__BLOCKED_REASON__OUT_OF_TONER);
1307         } else if (blocked_reasons & BLOCKED_REASON_JAMMED) {
1308             jStr = (jstring) (*env)->
1309                     GetStaticObjectField(env, _PrintServiceStringsClass,
1310                                          _PrintServiceStringsField__BLOCKED_REASON__JAMMED);
1311         } else if (blocked_reasons & BLOCKED_REASON_DOOR_OPEN) {
1312             jStr = (jstring) (*env)->
1313                     GetStaticObjectField(env, _PrintServiceStringsClass,
1314                                          _PrintServiceStringsField__BLOCKED_REASON__DOOR_OPEN);
1315         } else if (blocked_reasons & BLOCKED_REASON_SVC_REQUEST) {
1316             jStr = (jstring) (*env)->
1317                     GetStaticObjectField(env, _PrintServiceStringsClass,
1318                                      _PrintServiceStringsField__BLOCKED_REASON__SERVICE_REQUEST);
1319         } else if (blocked_reasons & BLOCKED_REASON_PAUSED) {
1320             jStr = (jstring) (*env)->
1321                     GetStaticObjectField(env, _PrintServiceStringsClass,
1322                                          _PrintServiceStringsField__BLOCKED_REASON__PAUSED);
1323         } else if (blocked_reasons & BLOCKED_REASON_STOPPED) {
1324             jStr = (jstring) (*env)->
1325                     GetStaticObjectField(env, _PrintServiceStringsClass,
1326                                          _PrintServiceStringsField__BLOCKED_REASON__STOPPED);
1327         } else if (blocked_reasons & BLOCKED_REASON_LOW_ON_INK) {
1328             jStr = (jstring) (*env)->
1329                     GetStaticObjectField(env, _PrintServiceStringsClass,
1330                                          _PrintServiceStringsField__BLOCKED_REASON__LOW_ON_INK);
1331         } else if (blocked_reasons & BLOCKED_REASON_LOW_ON_TONER) {
1332             jStr = (jstring) (*env)->
1333                     GetStaticObjectField(env, _PrintServiceStringsClass,
1334                                          _PrintServiceStringsField__BLOCKED_REASON__LOW_ON_TONER);
1335         } else if (blocked_reasons & BLOCKED_REASON_INPUT_CANNOT_FEED_SIZE_SELECTED) {
1336             jStr = (jstring) (*env)->
1337                     GetStaticObjectField(env, _PrintServiceStringsClass,
1338                         _PrintServiceStringsField__BLOCKED_REASON__INPUT_CANNOT_FEED_SIZE_SELECTED);
1339         } else if (blocked_reasons & BLOCKED_REASON_INTERLOCK_ERROR) {
1340             jStr = (jstring) (*env)->
1341                     GetStaticObjectField(env, _PrintServiceStringsClass,
1342                                      _PrintServiceStringsField__BLOCKED_REASON__INTERLOCK_ERROR);
1343         } else if (blocked_reasons & BLOCKED_REASON_OUTPUT_TRAY_MISSING) {
1344             jStr = (jstring) (*env)->
1345                     GetStaticObjectField(env, _PrintServiceStringsClass,
1346                                  _PrintServiceStringsField__BLOCKED_REASON__OUTPUT_TRAY_MISSING);
1347         } else if (blocked_reasons & BLOCKED_REASON_BANDER_ERROR) {
1348             jStr = (jstring) (*env)->
1349                     GetStaticObjectField(env, _PrintServiceStringsClass,
1350                                          _PrintServiceStringsField__BLOCKED_REASON__BANDER_ERROR);
1351         } else if (blocked_reasons & BLOCKED_REASON_BINDER_ERROR) {
1352             jStr = (jstring) (*env)->
1353                     GetStaticObjectField(env, _PrintServiceStringsClass,
1354                                          _PrintServiceStringsField__BLOCKED_REASON__BINDER_ERROR);
1355         } else if (blocked_reasons & BLOCKED_REASON_POWER_ERROR) {
1356             jStr = (jstring) (*env)->
1357                     GetStaticObjectField(env, _PrintServiceStringsClass,
1358                                          _PrintServiceStringsField__BLOCKED_REASON__POWER_ERROR);
1359         } else if (blocked_reasons & BLOCKED_REASON_CLEANER_ERROR) {
1360             jStr = (jstring) (*env)->
1361                     GetStaticObjectField(env, _PrintServiceStringsClass,
1362                                          _PrintServiceStringsField__BLOCKED_REASON__CLEANER_ERROR);
1363         } else if (blocked_reasons & BLOCKED_REASON_INPUT_TRAY_ERROR) {
1364             jStr = (jstring) (*env)->
1365                     GetStaticObjectField(env, _PrintServiceStringsClass,
1366                                      _PrintServiceStringsField__BLOCKED_REASON__INPUT_TRAY_ERROR);
1367         } else if (blocked_reasons & BLOCKED_REASON_INSERTER_ERROR) {
1368             jStr = (jstring) (*env)->
1369                     GetStaticObjectField(env, _PrintServiceStringsClass,
1370                                          _PrintServiceStringsField__BLOCKED_REASON__INSERTER_ERROR);
1371         } else if (blocked_reasons & BLOCKED_REASON_INTERPRETER_ERROR) {
1372             jStr = (jstring) (*env)->
1373                     GetStaticObjectField(env, _PrintServiceStringsClass,
1374                                      _PrintServiceStringsField__BLOCKED_REASON__INTERPRETER_ERROR);
1375         } else if (blocked_reasons & BLOCKED_REASON_MAKE_ENVELOPE_ERROR) {
1376             jStr = (jstring) (*env)->
1377                     GetStaticObjectField(env, _PrintServiceStringsClass,
1378                                  _PrintServiceStringsField__BLOCKED_REASON__MAKE_ENVELOPE_ERROR);
1379         } else if (blocked_reasons & BLOCKED_REASON_MARKER_ERROR) {
1380             jStr = (jstring) (*env)->
1381                     GetStaticObjectField(env, _PrintServiceStringsClass,
1382                                          _PrintServiceStringsField__BLOCKED_REASON__MARKER_ERROR);
1383         } else if (blocked_reasons & BLOCKED_REASON_MEDIA_ERROR) {
1384             jStr = (jstring) (*env)->
1385                     GetStaticObjectField(env, _PrintServiceStringsClass,
1386                                          _PrintServiceStringsField__BLOCKED_REASON__MEDIA_ERROR);
1387         } else if (blocked_reasons & BLOCKED_REASON_PERFORATER_ERROR) {
1388             jStr = (jstring) (*env)->
1389                     GetStaticObjectField(env, _PrintServiceStringsClass,
1390                                      _PrintServiceStringsField__BLOCKED_REASON__PERFORATER_ERROR);
1391         } else if (blocked_reasons & BLOCKED_REASON_PUNCHER_ERROR) {
1392             jStr = (jstring) (*env)->
1393                     GetStaticObjectField(env, _PrintServiceStringsClass,
1394                                          _PrintServiceStringsField__BLOCKED_REASON__PUNCHER_ERROR);
1395         } else if (blocked_reasons & BLOCKED_REASON_SEPARATION_CUTTER_ERROR) {
1396             jStr = (jstring) (*env)->
1397                     GetStaticObjectField(env, _PrintServiceStringsClass,
1398                              _PrintServiceStringsField__BLOCKED_REASON__SEPARATION_CUTTER_ERROR);
1399         } else if (blocked_reasons & BLOCKED_REASON_SHEET_ROTATOR_ERROR) {
1400             jStr = (jstring) (*env)->
1401                     GetStaticObjectField(env, _PrintServiceStringsClass,
1402                                  _PrintServiceStringsField__BLOCKED_REASON__SHEET_ROTATOR_ERROR);
1403         } else if (blocked_reasons & BLOCKED_REASON_SLITTER_ERROR) {
1404             jStr = (jstring) (*env)->
1405                     GetStaticObjectField(env, _PrintServiceStringsClass,
1406                                          _PrintServiceStringsField__BLOCKED_REASON__SLITTER_ERROR);
1407         } else if (blocked_reasons & BLOCKED_REASON_STACKER_ERROR) {
1408             jStr = (jstring) (*env)->
1409                     GetStaticObjectField(env, _PrintServiceStringsClass,
1410                                          _PrintServiceStringsField__BLOCKED_REASON__STACKER_ERROR);
1411         } else if (blocked_reasons & BLOCKED_REASON_STAPLER_ERROR) {
1412             jStr = (jstring) (*env)->
1413                     GetStaticObjectField(env, _PrintServiceStringsClass,
1414                                          _PrintServiceStringsField__BLOCKED_REASON__STAPLER_ERROR);
1415         } else if (blocked_reasons & BLOCKED_REASON_STITCHER_ERROR) {
1416             jStr = (jstring) (*env)->
1417                     GetStaticObjectField(env, _PrintServiceStringsClass,
1418                                          _PrintServiceStringsField__BLOCKED_REASON__STITCHER_ERROR);
1419         } else if (blocked_reasons & BLOCKED_REASON_SUBUNIT_ERROR) {
1420             jStr = (jstring) (*env)->
1421                     GetStaticObjectField(env, _PrintServiceStringsClass,
1422                                          _PrintServiceStringsField__BLOCKED_REASON__SUBUNIT_ERROR);
1423         } else if (blocked_reasons & BLOCKED_REASON_TRIMMER_ERROR) {
1424             jStr = (jstring) (*env)->
1425                     GetStaticObjectField(env, _PrintServiceStringsClass,
1426                                          _PrintServiceStringsField__BLOCKED_REASON__TRIMMER_ERROR);
1427         } else if (blocked_reasons & BLOCKED_REASON_WRAPPER_ERROR) {
1428             jStr = (jstring) (*env)->
1429                     GetStaticObjectField(env, _PrintServiceStringsClass,
1430                                          _PrintServiceStringsField__BLOCKED_REASON__WRAPPER_ERROR);
1431         } else if (blocked_reasons & BLOCKED_REASON_CLIENT_ERROR) {
1432             jStr = (jstring) (*env)->
1433                     GetStaticObjectField(env, _PrintServiceStringsClass,
1434                                          _PrintServiceStringsField__BLOCKED_REASON__CLIENT_ERROR);
1435         } else if (blocked_reasons & BLOCKED_REASON_SERVER_ERROR) {
1436             jStr = (jstring) (*env)->
1437                     GetStaticObjectField(env, _PrintServiceStringsClass,
1438                                          _PrintServiceStringsField__BLOCKED_REASON__SERVER_ERROR);
1439         } else if (blocked_reasons & BLOCKED_REASON_ALERT_REMOVAL_OF_BINARY_CHANGE_ENTRY) {
1440             jStr = (jstring) (*env)->
1441                     GetStaticObjectField(
1442                             env,
1443                             _PrintServiceStringsClass,
1444                      _PrintServiceStringsField__BLOCKED_REASON__ALERT_REMOVAL_OF_BINARY_CHANGE_ENTRY
1445                    );
1446         } else if (blocked_reasons & BLOCKED_REASON_CONFIGURATION_CHANGED) {
1447             jStr = (jstring) (*env)->
1448                     GetStaticObjectField(env, _PrintServiceStringsClass,
1449                                  _PrintServiceStringsField__BLOCKED_REASON__CONFIGURATION_CHANGED);
1450         } else if (blocked_reasons & BLOCKED_REASON_CONNECTING_TO_DEVICE) {
1451             jStr = (jstring) (*env)->
1452                     GetStaticObjectField(env, _PrintServiceStringsClass,
1453                                  _PrintServiceStringsField__BLOCKED_REASON__CONNECTING_TO_DEVICE);
1454         } else if (blocked_reasons & BLOCKED_REASON_DEVELOPER_ERROR) {
1455             jStr = (jstring) (*env)->
1456                 GetStaticObjectField(env, _PrintServiceStringsClass,
1457                                      _PrintServiceStringsField__BLOCKED_REASON__DEVELOPER_ERROR);
1458         } else if (blocked_reasons & BLOCKED_REASON_HOLD_NEW_JOBS) {
1459             jStr = (jstring) (*env)->
1460                     GetStaticObjectField(env, _PrintServiceStringsClass,
1461                                          _PrintServiceStringsField__BLOCKED_REASON__HOLD_NEW_JOBS);
1462         } else if (blocked_reasons & BLOCKED_REASON_OPC_LIFE_OVER) {
1463             jStr = (jstring) (*env)->
1464                     GetStaticObjectField(env, _PrintServiceStringsClass,
1465                                          _PrintServiceStringsField__BLOCKED_REASON__OPC_LIFE_OVER);
1466         } else if (blocked_reasons & BLOCKED_REASON_SPOOL_AREA_FULL) {
1467             jStr = (jstring) (*env)->
1468                     GetStaticObjectField(env, _PrintServiceStringsClass,
1469                                      _PrintServiceStringsField__BLOCKED_REASON__SPOOL_AREA_FULL);
1470         } else if (blocked_reasons & BLOCKED_REASON_TIMED_OUT) {
1471             jStr = (jstring) (*env)->
1472                     GetStaticObjectField(env, _PrintServiceStringsClass,
1473                                          _PrintServiceStringsField__BLOCKED_REASON__TIMED_OUT);
1474         } else if (blocked_reasons & BLOCKED_REASON_SHUTDOWN) {
1475             jStr = (jstring) (*env)->
1476                     GetStaticObjectField(env, _PrintServiceStringsClass,
1477                                          _PrintServiceStringsField__BLOCKED_REASON__SHUTDOWN);
1478         } else if (blocked_reasons & BLOCKED_REASON_PRINTER_MANUAL_RESET) {
1479             jStr = (jstring) (*env)->
1480                     GetStaticObjectField(env, _PrintServiceStringsClass,
1481                                  _PrintServiceStringsField__BLOCKED_REASON__PRINTER_MANUAL_RESET);
1482         } else if (blocked_reasons & BLOCKED_REASON_PRINTER_NMS_RESET) {
1483             jStr = (jstring) (*env)->
1484                     GetStaticObjectField(env, _PrintServiceStringsClass,
1485                                      _PrintServiceStringsField__BLOCKED_REASON__PRINTER_NMS_RESET);
1486         }
1487 
1488         blocked_reasons &= ~(LONG_ONE << i);
1489 
1490         if (jStr != NULL) {
1491             (*env)->SetObjectArrayElement(env, stringArray, reasonCount++, jStr);
1492         }
1493     }
1494     return stringArray;
1495 }
1496 
1497 /*
1498  * Handles print job callbacks. Handles job states and blocked reasons
1499  */
_wprint_callback_fn(wJob_t job_handle,void * param)1500 static void _wprint_callback_fn(wJob_t job_handle, void *param) {
1501     jstring jStr;
1502     wprint_job_callback_params_t *cb_param = (wprint_job_callback_params_t *) param;
1503     if (!cb_param) {
1504         return;
1505     }
1506 
1507     int needDetach = 0;
1508     JNIEnv *env;
1509     if ((*_JVM)->GetEnv(_JVM, (void **) &env, JNI_VERSION_1_6) < 0) {
1510         needDetach = 1;
1511         if ((*_JVM)->AttachCurrentThread(_JVM, &env, NULL) < 0) {
1512             return;
1513         }
1514     }
1515 
1516     jobject callbackParams = (*env)->NewObject(env, _JobCallbackParamsClass,
1517             _JobCallbackParamsMethod__init);
1518     if (callbackParams != 0) {
1519         switch (cb_param->param.state) {
1520             case JOB_QUEUED:
1521                 jStr = (jstring) (*env)->GetStaticObjectField(
1522                         env, _PrintServiceStringsClass,
1523                         _PrintServiceStringsField__JOB_STATE_QUEUED);
1524                 break;
1525             case JOB_RUNNING:
1526                 jStr = (jstring) (*env)->GetStaticObjectField(
1527                         env, _PrintServiceStringsClass,
1528                         _PrintServiceStringsField__JOB_STATE_RUNNING);
1529                 break;
1530             case JOB_BLOCKED:
1531                 jStr = (jstring) (*env)->GetStaticObjectField(
1532                         env, _PrintServiceStringsClass,
1533                         _PrintServiceStringsField__JOB_STATE_BLOCKED);
1534                 break;
1535             case JOB_DONE:
1536                 jStr = (jstring) (*env)->GetStaticObjectField(
1537                         env, _PrintServiceStringsClass,
1538                         _PrintServiceStringsField__JOB_STATE_DONE);
1539                 break;
1540             default:
1541                 jStr = (jstring) (*env)->GetStaticObjectField(
1542                         env, _PrintServiceStringsClass,
1543                         _PrintServiceStringsField__JOB_STATE_OTHER);
1544                 break;
1545         }
1546         (*env)->SetObjectField(env, callbackParams, _JobCallbackParamsField__jobState, jStr);
1547 
1548         bool print_job_failed = false;
1549         if (cb_param->param.state == JOB_DONE) {
1550             switch (cb_param->job_done_result) {
1551                 case OK:
1552                     jStr = (jstring) (*env)->GetStaticObjectField(
1553                             env, _PrintServiceStringsClass,
1554                             _PrintServiceStringsField__JOB_DONE_OK);
1555                     break;
1556                 case ERROR:
1557                     print_job_failed = true;
1558                     jStr = (jstring) (*env)->GetStaticObjectField(
1559                             env, _PrintServiceStringsClass,
1560                             _PrintServiceStringsField__JOB_DONE_ERROR);
1561                     break;
1562                 case CANCELLED:
1563                     jStr = (jstring) (*env)->GetStaticObjectField(
1564                             env, _PrintServiceStringsClass,
1565                             _PrintServiceStringsField__JOB_DONE_CANCELLED);
1566                     break;
1567                 case CORRUPT:
1568                     print_job_failed = true;
1569                     jStr = (jstring) (*env)->GetStaticObjectField(
1570                             env, _PrintServiceStringsClass,
1571                             _PrintServiceStringsField__JOB_DONE_CORRUPT);
1572                     break;
1573                 default:
1574                     jStr = (jstring) (*env)->GetStaticObjectField(
1575                             env, _PrintServiceStringsClass,
1576                             _PrintServiceStringsField__JOB_DONE_OTHER);
1577                     break;
1578             }
1579 
1580             (*env)->SetObjectField(env, callbackParams,
1581                     _JobCallbackParamsField__jobDoneResult, jStr);
1582         }
1583 
1584         int i, count;
1585         int max_value_reasons;
1586 
1587         if (print_job_failed) {
1588             max_value_reasons = IPP_JOB_STATE_REASON_MAX_VALUE;
1589         } else {
1590             max_value_reasons = PRINT_STATUS_MAX_STATE;
1591         }
1592 
1593         for (count = i = 0; i < max_value_reasons; i++) {
1594             if (cb_param->blocked_reasons & (1 << i)) {
1595                 count++;
1596             }
1597         }
1598 
1599         // Add any failed or block reasons to blocked_reasons
1600         if (count > 0) {
1601             jobjectArray stringArray;
1602             if (print_job_failed) {
1603                 stringArray = processFailReasons(env, cb_param->blocked_reasons, count);
1604             } else {
1605                 stringArray = processBlockStatus(env, cb_param->blocked_reasons, count);
1606             }
1607             (*env)->SetObjectField(env, callbackParams, _JobCallbackParamsField__blockedReasons,
1608                                    stringArray);
1609             (*env)->DeleteLocalRef(env, stringArray);
1610         }
1611 
1612         (*env)->SetIntField(env, callbackParams, _JobCallbackParamsField__jobId,
1613                 (jint) job_handle);
1614 
1615         if (cb_param->certificate) {
1616             LOGI("_wprint_callback_fn: copying certificate len=%d", cb_param->certificate_len);
1617             jbyteArray certificate = (*env)->NewByteArray(env, cb_param->certificate_len);
1618             jbyte *certificateBytes = (*env)->GetByteArrayElements(env, certificate, 0);
1619             memcpy(certificateBytes, (const void *) cb_param->certificate,
1620                 cb_param->certificate_len);
1621             (*env)->ReleaseByteArrayElements(env, certificate, certificateBytes, 0);
1622             (*env)->SetObjectField(env, callbackParams, _JobCallbackParamsField__certificate,
1623                 certificate);
1624             (*env)->DeleteLocalRef(env, certificate);
1625         } else {
1626             LOGI("_wprint_callback_fn: there is no certificate");
1627             // No cert, set NULL
1628             (*env)->SetObjectField(env, callbackParams, _JobCallbackParamsField__certificate,
1629                 NULL);
1630         }
1631 
1632         (*env)->CallVoidMethod(env, _callbackReceiver, _JobCallbackMethod__jobCallback,
1633                 (jint) job_handle, callbackParams);
1634         (*env)->DeleteLocalRef(env, callbackParams);
1635     }
1636 
1637     if (needDetach) {
1638         (*_JVM)->DetachCurrentThread(_JVM);
1639     }
1640 }
1641 
1642 /*
1643  * Initialize wprint JNI
1644  */
Java_com_android_bips_ipp_Backend_nativeInit(JNIEnv * env,jobject obj,jobject callbackReceiver,jstring fakeDir,jint apiVersion)1645 JNIEXPORT jint JNICALL Java_com_android_bips_ipp_Backend_nativeInit(
1646         JNIEnv *env, jobject obj, jobject callbackReceiver, jstring fakeDir,
1647         jint apiVersion) {
1648     LOGI("nativeInit JNIenv is %p", env);
1649     int result;
1650 
1651     // Setup the global JavaVM reference first.
1652     (*env)->GetJavaVM(env, &_JVM);
1653 
1654     // Initialize the Android API version value
1655     g_API_version = apiVersion;
1656 
1657     _initJNI(env, callbackReceiver, fakeDir);
1658 
1659     // initialize wprint library
1660     result = wprintInit();
1661 
1662     // return the result
1663     return result;
1664 }
1665 
1666 /*
1667  * Copies a given string and returns the copy
1668  */
copyToNewString(JNIEnv * env,jstring source)1669 static char *copyToNewString(JNIEnv *env, jstring source) {
1670     const char *fromJava;
1671     char *newString;
1672 
1673     fromJava = (*env)->GetStringUTFChars(env, source, NULL);
1674     if (fromJava == NULL) return NULL;
1675 
1676     newString = (char *) malloc(strlen(fromJava) + 1);
1677     strcpy(newString, fromJava);
1678     (*env)->ReleaseStringUTFChars(env, source, fromJava);
1679 
1680     return newString;
1681 }
1682 
1683 /*
1684  * JNI call to wprint to get capabilities. Returns caps converted to java.
1685  */
Java_com_android_bips_ipp_Backend_nativeGetCapabilities(JNIEnv * env,jobject obj,jstring address,jint port,jstring httpResource,jstring uriScheme,jlong timeout,jobject printerCaps)1686 JNIEXPORT jint JNICALL Java_com_android_bips_ipp_Backend_nativeGetCapabilities(
1687         JNIEnv *env, jobject obj, jstring address, jint port, jstring httpResource,
1688         jstring uriScheme, jlong timeout, jobject printerCaps) {
1689     jint result;
1690     printer_capabilities_t caps;
1691     wprint_connect_info_t connect_info;
1692 
1693     connect_info.printer_addr = copyToNewString(env, address);
1694     connect_info.uri_path = copyToNewString(env, httpResource);
1695     connect_info.uri_scheme = copyToNewString(env, uriScheme);
1696     connect_info.port_num = port;
1697     connect_info.timeout = timeout;
1698     connect_info.validate_certificate = NULL;
1699 
1700     LOGI("nativeGetCapabilities for %s JNIenv is %p", connect_info.printer_addr, env);
1701 
1702     // This call may take a while, and the JNI may be torn down when we return
1703     result = wprintGetCapabilities(&connect_info, &caps);
1704 
1705     if (connect_info.printer_addr) free((char *) connect_info.printer_addr);
1706     if (connect_info.uri_path) free((char *) connect_info.uri_path);
1707     if (connect_info.uri_scheme) free((char *) connect_info.uri_scheme);
1708 
1709     if (!wprintIsRunning() && result == 0) {
1710         result = ERROR;
1711     }
1712 
1713     // additional IPP checks
1714     if (result == 0) {
1715         if (caps.isSupported && (caps.ippVersionMajor < 1)) {
1716             caps.isSupported = 0;
1717         }
1718         _convertPrinterCaps_to_Java(env, printerCaps, &caps);
1719     }
1720 
1721     return result;
1722 }
1723 
1724 /*
1725  * JNI call to wprint to get default job params. Returns job params converted to java.
1726  */
Java_com_android_bips_ipp_Backend_nativeGetDefaultJobParameters(JNIEnv * env,jobject obj,jobject jobParams)1727 JNIEXPORT jint JNICALL Java_com_android_bips_ipp_Backend_nativeGetDefaultJobParameters(
1728         JNIEnv *env, jobject obj, jobject jobParams) {
1729     LOGI("nativeGetDefaultJobParameters, JNIenv is %p", env);
1730     jint result;
1731     wprint_job_params_t params;
1732 
1733     result = wprintGetDefaultJobParams(&params);
1734 
1735     _covertJobParams_to_Java(env, jobParams, &params);
1736     return result;
1737 }
1738 
1739 /*
1740  * JNI call to wprint to get final job params. Returns final params converted to java.
1741  */
Java_com_android_bips_ipp_Backend_nativeGetFinalJobParameters(JNIEnv * env,jobject obj,jobject jobParams,jobject printerCaps)1742 JNIEXPORT jint JNICALL Java_com_android_bips_ipp_Backend_nativeGetFinalJobParameters(
1743         JNIEnv *env, jobject obj, jobject jobParams, jobject printerCaps) {
1744     LOGI("nativeGetFinalJobParameters, JNIenv is %p", env);
1745     jint result;
1746     wprint_job_params_t params;
1747     printer_capabilities_t caps;
1748 
1749     _convertJobParams_to_C(env, jobParams, &params);
1750     _convertPrinterCaps_to_C(env, printerCaps, &caps);
1751 
1752     LOGD("nativeGetFinalJobParameters: After _convertJobParams_to_C: res=%d, name=%s",
1753             params.pdf_render_resolution, params.job_name);
1754     result = wprintGetFinalJobParams(&params, &caps);
1755 
1756     _covertJobParams_to_Java(env, jobParams, &params);
1757     return result;
1758 }
1759 
1760 /*
1761  * Convert certificate (if present) from printer capabilities into job_params.
1762  */
_convertCertificate(JNIEnv * env,jobject printerCaps,wprint_job_params_t * params)1763 static void _convertCertificate(JNIEnv *env, jobject printerCaps, wprint_job_params_t *params) {
1764     params->certificate = NULL;
1765     jbyteArray certificate = (jbyteArray) (*env)->GetObjectField(env, printerCaps,
1766             _LocalPrinterCapabilitiesField__certificate);
1767     if (certificate) {
1768         params->certificate_len = (*env)->GetArrayLength(env, certificate);
1769         params->certificate = malloc(params->certificate_len);
1770         if (params->certificate) {
1771             jbyte *certificateBytes = (*env)->GetByteArrayElements(env, certificate, NULL);
1772             memcpy(params->certificate, certificateBytes, params->certificate_len);
1773             (*env)->ReleaseByteArrayElements(env, certificate, certificateBytes, JNI_ABORT);
1774         }
1775     }
1776 }
1777 
1778 /*
1779  * JNI call to wprint to start a print job. Takes connection params, job params, caps, and file
1780  * array to complete the job
1781  */
Java_com_android_bips_ipp_Backend_nativeStartJob(JNIEnv * env,jobject obj,jstring address,jint port,jstring mimeType,jobject jobParams,jobject printerCaps,jobject fileArray,jstring jobDebugDir,jstring scheme)1782 JNIEXPORT jint JNICALL Java_com_android_bips_ipp_Backend_nativeStartJob(
1783         JNIEnv *env, jobject obj, jstring address, jint port, jstring mimeType, jobject jobParams,
1784         jobject printerCaps, jobject fileArray, jstring jobDebugDir, jstring scheme) {
1785     LOGI("nativeStartJob, JNIenv is %p", env);
1786     jint result = ERROR;
1787     wJob_t job_handle = ERROR;
1788     bool hasFiles = false;
1789 
1790     wprint_job_params_t params;
1791     printer_capabilities_t caps;
1792 
1793     _convertJobParams_to_C(env, jobParams, &params);
1794     _convertPrinterCaps_to_C(env, printerCaps, &caps);
1795     _convertCertificate(env, printerCaps, &params);
1796 
1797     LOGD("nativeStartJob: After _convertJobParams_to_C: res=%d, name=%s",
1798             params.pdf_render_resolution, params.job_name);
1799 
1800     const char *addressStr = (*env)->GetStringUTFChars(env, address, NULL);
1801     const char *mimeTypeStr = (*env)->GetStringUTFChars(env, mimeType, NULL);
1802     const char *dataDirStr = (*env)->GetStringUTFChars(env, _fakeDir, NULL);
1803     const char *schemeStr = (*env)->GetStringUTFChars(env, scheme, NULL);
1804 
1805     jsize len = 0;
1806     jobjectArray array;
1807 
1808     if (fileArray) {
1809         array = (jobjectArray) fileArray;
1810         len = (*env)->GetArrayLength(env, array);
1811         hasFiles = (len > 0);
1812     }
1813 
1814     int index = 0, pageIndex, incrementor;
1815     int page_range_arr[len];
1816 
1817     // Initialize page_range_arr (address defect reported by Coverity scans)
1818     memset((char *) page_range_arr, 0, sizeof(int) * len);
1819 
1820     int pdf_pages_ary[len];
1821     int pages_ary[len][MAX_NUM_PAGES];
1822 
1823     if (hasFiles) {
1824         result = OK;
1825         for (pageIndex = 0; ((result == OK) && (pageIndex < len)); pageIndex++) {
1826             jstring page = (jstring) (*env)->GetObjectArrayElement(env, array, pageIndex);
1827             const char *pageStr = (*env)->GetStringUTFChars(env, page, NULL);
1828             if (pageStr == NULL) {
1829                 result = ERROR;
1830             } else {
1831                 int page_count = 0;
1832                 if (_get_pdf_page_count(mimeTypeStr, &page_count, pageStr)) {
1833                     pdf_pages_ary[pageIndex] = page_count;
1834                     page_range_arr[pageIndex] = 0;
1835                     char page_range_str[MAX_NUM_PAGES];
1836                     memset(page_range_str, 0, MAX_NUM_PAGES);
1837                     _get_pdf_page_range(env, jobParams, &pages_ary[pageIndex][0],
1838                             pdf_pages_ary[pageIndex], &page_range_arr[pageIndex], page_range_str);
1839                 }
1840             }
1841             (*env)->ReleaseStringUTFChars(env, page, pageStr);
1842         }
1843 
1844         jstring page = (jstring) (*env)->GetObjectArrayElement(env, array, index);
1845         const char *pageStr = (*env)->GetStringUTFChars(env, page, NULL);
1846         if (pageStr == NULL) {
1847             result = ERROR;
1848         }
1849 
1850         if (len == 1) {
1851             if (_is_pdf_doc((char *) mimeTypeStr, (char *) pageStr)) {
1852                 if (page_range_arr[0] == 1) {
1853                     LOGI("smart duplex, disabling duplex");
1854                     params.duplex = DUPLEX_MODE_NONE;
1855                 }
1856             } else {
1857                 LOGI("smart duplex, disabling duplex");
1858                 params.duplex = DUPLEX_MODE_NONE;
1859             }
1860         }
1861 
1862         (*env)->ReleaseStringUTFChars(env, page, pageStr);
1863         const char *jobDebugDirStr = NULL;
1864         if (jobDebugDir != NULL) {
1865             jobDebugDirStr = (*env)->GetStringUTFChars(env, jobDebugDir, NULL);
1866         }
1867         result = wprintStartJob(addressStr, port, &params, &caps, (char *) mimeTypeStr,
1868                 (char *) dataDirStr, _wprint_callback_fn, jobDebugDirStr, schemeStr);
1869         if (result == ERROR) {
1870             LOGE("failed to start job: error code :%d", errno);
1871         }
1872         if ((jobDebugDir != NULL) && (jobDebugDirStr != NULL)) {
1873             (*env)->ReleaseStringUTFChars(env, jobDebugDir, jobDebugDirStr);
1874         }
1875     } else {
1876         LOGE("empty file list");
1877     }
1878     if (result != ERROR) {
1879         job_handle = (wJob_t) result;
1880 
1881         // register job handle with service
1882         if (caps.faceDownTray || params.duplex) {
1883             index = 0;
1884             incrementor = 1;
1885         } else {
1886             index = len - 1;
1887             incrementor = -1;
1888         }
1889 
1890         result = OK;
1891         for (pageIndex = 1; ((result == OK) && (pageIndex <= len)); pageIndex++) {
1892             jstring page = (jstring) (*env)->GetObjectArrayElement(env, array, index);
1893             const char *pageStr = (*env)->GetStringUTFChars(env, page, NULL);
1894             if (pageStr == NULL) {
1895                 result = ERROR;
1896             } else {
1897                 if (_is_pdf_doc((char *) mimeTypeStr, (char *) pageStr)) {
1898                     result = _print_pdf_pages(job_handle, &caps, params.duplex, (char *) pageStr,
1899                             page_range_arr[index], pages_ary[index]);
1900                 } else {
1901                     result = wprintPage(job_handle, pageIndex, (char *) pageStr, false, false,
1902                             0, 0, 0, 0);
1903                 }
1904             }
1905             (*env)->ReleaseStringUTFChars(env, page, pageStr);
1906             index += incrementor;
1907         }
1908 
1909         wprintPage(job_handle, pageIndex, NULL, true, false, 0, 0, 0, 0);
1910         if (result != OK) {
1911             LOGE("failed to add some pages, aborting job");
1912             wprintCancelJob(job_handle);
1913             wprintEndJob(job_handle);
1914             job_handle = ERROR;
1915         }
1916     }
1917 
1918     if (params.certificate) {
1919         free(params.certificate);
1920     }
1921     (*env)->ReleaseStringUTFChars(env, mimeType, mimeTypeStr);
1922     (*env)->ReleaseStringUTFChars(env, address, addressStr);
1923     (*env)->ReleaseStringUTFChars(env, _fakeDir, dataDirStr);
1924     (*env)->ReleaseStringUTFChars(env, scheme, schemeStr);
1925     return job_handle;
1926 }
1927 
1928 /*
1929  * JNI call to wprint to end a print job
1930  */
Java_com_android_bips_ipp_Backend_nativeEndJob(JNIEnv * env,jobject obj,jint job_handle)1931 JNIEXPORT jint JNICALL Java_com_android_bips_ipp_Backend_nativeEndJob(
1932         JNIEnv *env, jobject obj, jint job_handle) {
1933     LOGI("nativeEndJob, JNIenv is %p", env);
1934     return wprintEndJob((wJob_t) job_handle);
1935 }
1936 
1937 /*
1938  * JNI call to wprint to cancel a print job
1939  */
Java_com_android_bips_ipp_Backend_nativeCancelJob(JNIEnv * env,jobject obj,jint job_handle)1940 JNIEXPORT jint JNICALL Java_com_android_bips_ipp_Backend_nativeCancelJob(
1941         JNIEnv *env, jobject obj, jint job_handle) {
1942     LOGI("nativeCancelJob, JNIenv is %p", env);
1943     return wprintCancelJob((wJob_t) job_handle);
1944 }
1945 
1946 /*
1947  * JNI call to wprint to exit
1948  */
Java_com_android_bips_ipp_Backend_nativeExit(JNIEnv * env,jobject obj)1949 JNIEXPORT jint JNICALL Java_com_android_bips_ipp_Backend_nativeExit(JNIEnv *env, jobject obj) {
1950     LOGI("nativeExit, JNIenv is %p", env);
1951 
1952     (*env)->DeleteGlobalRef(env, _LocalJobParamsClass);
1953     (*env)->DeleteGlobalRef(env, _LocalPrinterCapabilitiesClass);
1954     (*env)->DeleteGlobalRef(env, _JobCallbackParamsClass);
1955     if (_callbackReceiver) {
1956         (*env)->DeleteGlobalRef(env, _callbackReceiver);
1957     }
1958     if (_JobCallbackClass) {
1959         (*env)->DeleteGlobalRef(env, _JobCallbackClass);
1960     }
1961     (*env)->DeleteGlobalRef(env, _fakeDir);
1962     (*env)->DeleteGlobalRef(env, _PrintServiceStringsClass);
1963 
1964     pdf_render_deinit(env);
1965     return wprintExit();
1966 }
1967 
1968 /*
1969  * Sets app name/version and os name
1970  */
Java_com_android_bips_ipp_Backend_nativeSetSourceInfo(JNIEnv * env,jobject obj,jstring appName,jstring appVersion,jstring osName)1971 JNIEXPORT void JNICALL Java_com_android_bips_ipp_Backend_nativeSetSourceInfo(
1972         JNIEnv *env, jobject obj, jstring appName, jstring appVersion, jstring osName) {
1973     LOGI("nativeSetSourceInfo, JNIenv is %p", env);
1974     const char *appNameStr = (*env)->GetStringUTFChars(env, appName, NULL);
1975     const char *appVersionStr = (*env)->GetStringUTFChars(env, appVersion, NULL);
1976     const char *osNameStr = (*env)->GetStringUTFChars(env, osName, NULL);
1977     wprintSetSourceInfo(appNameStr, appVersionStr, osNameStr);
1978     (*env)->ReleaseStringUTFChars(env, appName, appNameStr);
1979     (*env)->ReleaseStringUTFChars(env, appVersion, appVersionStr);
1980     (*env)->ReleaseStringUTFChars(env, osName, osNameStr);
1981 }