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
65 static jclass _LocalPrinterCapabilitiesClass;
66 static jfieldID _LocalPrinterCapabilitiesField__name;
67 static jfieldID _LocalPrinterCapabilitiesField__path;
68 static jfieldID _LocalPrinterCapabilitiesField__uuid;
69 static jfieldID _LocalPrinterCapabilitiesField__location;
70 static jfieldID _LocalPrinterCapabilitiesField__duplex;
71 static jfieldID _LocalPrinterCapabilitiesField__borderless;
72 static jfieldID _LocalPrinterCapabilitiesField__color;
73 static jfieldID _LocalPrinterCapabilitiesField__isSupported;
74 static jfieldID _LocalPrinterCapabilitiesField__mediaDefault;
75 static jfieldID _LocalPrinterCapabilitiesField__supportedMediaTypes;
76 static jfieldID _LocalPrinterCapabilitiesField__supportedMediaSizes;
77 static jfieldID _LocalPrinterCapabilitiesField__nativeData;
78 static jfieldID _LocalPrinterCapabilitiesField__certificate;
79
80 static jclass _JobCallbackClass;
81 static jobject _callbackReceiver;
82 static jmethodID _JobCallbackMethod__jobCallback;
83
84 static jclass _JobCallbackParamsClass;
85 static jmethodID _JobCallbackParamsMethod__init;
86 static jfieldID _JobCallbackParamsField__jobId;
87 static jfieldID _JobCallbackParamsField__jobState;
88 static jfieldID _JobCallbackParamsField__jobDoneResult;
89 static jfieldID _JobCallbackParamsField__blockedReasons;
90 static jfieldID _JobCallbackParamsField__certificate;
91
92 static jclass _PrintServiceStringsClass;
93 static jfieldID _PrintServiceStringsField__JOB_STATE_QUEUED;
94 static jfieldID _PrintServiceStringsField__JOB_STATE_RUNNING;
95 static jfieldID _PrintServiceStringsField__JOB_STATE_BLOCKED;
96 static jfieldID _PrintServiceStringsField__JOB_STATE_DONE;
97 static jfieldID _PrintServiceStringsField__JOB_STATE_OTHER;
98 static jfieldID _PrintServiceStringsField__JOB_DONE_OK;
99 static jfieldID _PrintServiceStringsField__JOB_DONE_ERROR;
100 static jfieldID _PrintServiceStringsField__JOB_DONE_CANCELLED;
101 static jfieldID _PrintServiceStringsField__JOB_DONE_CORRUPT;
102 static jfieldID _PrintServiceStringsField__JOB_DONE_OTHER;
103 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__OFFLINE;
104 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__BUSY;
105 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__CANCELLED;
106 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__OUT_OF_PAPER;
107 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__OUT_OF_INK;
108 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__OUT_OF_TONER;
109 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__JAMMED;
110 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__DOOR_OPEN;
111 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__SERVICE_REQUEST;
112 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__LOW_ON_INK;
113 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__LOW_ON_TONER;
114 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__REALLY_LOW_ON_INK;
115 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__BAD_CERTIFICATE;
116 static jfieldID _PrintServiceStringsField__BLOCKED_REASON__UNKNOWN;
117 static jfieldID _PrintServiceStringsField__ALIGNMENT__CENTER;
118 static jfieldID _PrintServiceStringsField__ALIGNMENT__CENTER_HORIZONTAL;
119 static jfieldID _PrintServiceStringsField__ALIGNMENT__CENTER_VERTICAL;
120 static jfieldID _PrintServiceStringsField__ALIGNMENT__CENTER_HORIZONTAL_ON_ORIENTATION;
121
122 // Global so it can be used in PDF render code
123 JavaVM *_JVM = NULL;
124
125 static jstring _fakeDir;
126
127 int g_API_version = 0;
128
129 /*
130 * Convert char * to a java object
131 */
132 static void stringToJava(JNIEnv *env, jobject obj, jfieldID id, const char *str);
133
134 /*
135 * Retuns if the mime type is MIME_TYPE_PDF
136 */
_is_pdf_doc(const char * mime_type,const char * pathname)137 static bool _is_pdf_doc(const char *mime_type, const char *pathname) {
138 if (mime_type == NULL || pathname == NULL) {
139 return false;
140 }
141
142 if (strcmp(mime_type, MIME_TYPE_PDF) == 0) {
143 return true;
144 }
145
146 return false;
147 }
148
149 /*
150 * Returns if the string is numeric
151 */
_isNumeric(const char * s)152 static int _isNumeric(const char *s) {
153 if (s == NULL || *s == '\0' || isspace(*s)) {
154 return 0;
155 }
156 char *p;
157 strtod(s, &p);
158 return *p == '\0';
159 }
160
161 /*
162 * Outputs the number of pages in a pdf to page_count. Returns False if an error ocurred
163 */
_get_pdf_page_count(const char * mime_type,int * page_count,const char * pathname)164 static bool _get_pdf_page_count(const char *mime_type, int *page_count, const char *pathname) {
165 *page_count = 0;
166
167 if (!_is_pdf_doc(mime_type, pathname)) {
168 return false;
169 }
170
171 pdf_render_ifc_t *pdf_render_ifc = create_pdf_render_ifc();
172 *page_count = pdf_render_ifc->openDocument(pdf_render_ifc, pathname);
173 pdf_render_ifc->destroy(pdf_render_ifc);
174
175 LOGI("pdf page count for %s: %d", pathname, *page_count);
176 if (*page_count < 0) {
177 LOGE("page count error");
178 *page_count = 0;
179 }
180 return true;
181 }
182
183 /*
184 * Reorders pdf pages before sending to the printer. In general the last page is printed first.
185 * Removes pages from pages_ary if they are not in the specified range.
186 */
_order_pdf_pages(int num_pages,int * pages_ary,int * num_index,char * page_range_split)187 static bool _order_pdf_pages(int num_pages, int *pages_ary, int *num_index,
188 char *page_range_split) {
189 bool succeeded = false;
190 char num_begin_ary[5] = "";
191 char num_end_ary[5] = "";
192 int num_counter = 0;
193 bool dash_encountered = false;
194 int range_count = 0;
195
196 // initialize to 0
197 memset(num_begin_ary, 0, 5);
198 memset(num_end_ary, 0, 5);
199
200 for (range_count = 0; range_count < (int) strlen(page_range_split); range_count++) {
201 // skip spaces
202 if (!isspace(page_range_split[range_count])) {
203 // store first number found in range in num_begin_ary
204 // and second number (after the dash '-') in num_end_ary
205 // skip the dash ('-') character
206 if (page_range_split[range_count] == '-') {
207 dash_encountered = true;
208 num_counter = 0;
209 continue;
210 }
211
212 if (!dash_encountered) {
213 num_begin_ary[num_counter++] = page_range_split[range_count];
214 } else {
215 num_end_ary[num_counter++] = page_range_split[range_count];
216 }
217 }
218 }
219
220 // fill in first cell of end num with 0 so array has a valid number
221 if (!dash_encountered) {
222 num_end_ary[0] = '0';
223 }
224
225 // make sure numeric values are stored in num_begin_ary and num_end_ary
226 if (_isNumeric(num_begin_ary) && _isNumeric(num_end_ary)) {
227 // convert to integers
228 int num_begin = atoi(num_begin_ary);
229 int num_end = atoi(num_end_ary);
230
231 // if ending number was 0, there was no range, only a single page number
232 // so, set it to the value of the beginning number
233 if (num_end == 0) {
234 num_end = num_begin;
235 }
236
237 // make sure beginning and ending numbers are at least 1
238 if (num_begin > 0 && num_end > 0) {
239 // make sure the beginning and ending numbers are not greater than the page count
240 if (num_begin <= num_pages && num_end <= num_pages) {
241 if (num_end >= num_begin) {
242 // make sure the upper bound does not exceed the number of pages
243 if (num_end > num_pages) {
244 num_end = num_pages;
245 }
246 // store range in pages_ary in ascending order
247 int count = 0;
248 for (count = *num_index; count <= (*num_index + num_end - num_begin); count++) {
249 *(pages_ary + count) = num_begin++;
250 *num_index += 1;
251 }
252 } else {
253 // reverse order
254 // make sure the upper bound does not exceed the number of pages
255 if (num_begin > num_pages) {
256 num_begin = num_pages;
257 }
258 // store range in pages_ary in descending order
259 int count = 0;
260 for (count = *num_index; count <= *num_index + num_begin - num_end; count++) {
261 *(pages_ary + count) = num_begin--;
262 *num_index += 1;
263 }
264 }
265 succeeded = true;
266 } else {
267 LOGE("_order_pdf_pages(), ERROR: first and/or last numbers are not greater than "
268 "%d: first num=%d, second num=%d", num_pages, num_begin, num_end);
269 }
270 } else {
271 LOGE("_order_pdf_pages(), ERROR: first and/or last numbers are not greater than 0: "
272 "first num=%d, second num=%d", num_begin, num_end);
273 }
274 } else {
275 LOGE("_order_pdf_pages(), ERROR: first and/or last numbers are not numeric: first num=%s, "
276 "second num=%s", num_begin_ary, num_end_ary);
277 }
278 return succeeded;
279 }
280
281 /*
282 * Outputs page range of a pdf to page_range_str
283 */
_get_pdf_page_range(JNIEnv * env,jobject javaJobParams,int * pages_ary,int num_pages,int * num_index,char * page_range_str)284 static void _get_pdf_page_range(JNIEnv *env, jobject javaJobParams, int *pages_ary, int num_pages,
285 int *num_index, char *page_range_str) {
286 char *page_range = NULL;
287 jstring pageRangeObject = (jstring) (*env)->GetObjectField(env, javaJobParams,
288 _LocalJobParamsField__page_range);
289 if (pageRangeObject) {
290 int page_range_size = (*env)->GetStringLength(env, pageRangeObject);
291 const jbyte *pageRange = (jbyte *) (*env)->GetStringUTFChars(env, pageRangeObject, 0);
292 if (strcmp((char *) pageRange, "") != 0) {
293 page_range = (char *) malloc(page_range_size + 1);
294 memset(page_range, 0, page_range_size + 1);
295 strncpy(page_range, (char *) pageRange, page_range_size);
296
297 // no empty strings
298 if (strcmp(page_range, "") == 0) {
299 free(page_range);
300 page_range = NULL;
301 }
302
303 (*env)->ReleaseStringUTFChars(env, pageRangeObject, (const char *) pageRange);
304 LOGD("_get_pdf_page_range(), page_range from JNI environment=%s", page_range);
305 }
306 }
307
308 if (!page_range) {
309 page_range = (char *) malloc(MAX_NUM_PAGES + 1);
310 memset(page_range, 0, MAX_NUM_PAGES + 1);
311
312 snprintf(page_range_str, MAX_NUM_PAGES, "1-%d", num_pages);
313 snprintf(page_range, MAX_NUM_PAGES, "1-%d", num_pages);
314 } else {
315 strncpy(page_range_str, page_range, MAX_NUM_PAGES);
316 }
317
318 LOGD("_get_pdf_page_range(), range: %s, pages in document: %d", page_range_str, num_pages);
319
320 // get the first token in page_range_str
321 memset(pages_ary, 0, MAX_NUM_PAGES);
322 char *page_range_split = strtok(page_range, ",");
323 while (page_range_split != NULL) {
324 if (!_order_pdf_pages(num_pages, pages_ary, num_index, page_range_split)) {
325 snprintf(page_range_str, MAX_NUM_PAGES, "1-%d", num_pages);
326 LOGD("_get_pdf_page_range(), setting page_range to: %s", page_range_str);
327 _order_pdf_pages(num_pages, pages_ary, num_index, page_range_str);
328 break;
329 }
330
331 // get next range token
332 page_range_split = strtok(NULL, ",");
333 }
334
335 if (page_range) {
336 free(page_range);
337 }
338 }
339
340 /*
341 * Sends a pdf to a printer
342 */
_print_pdf_pages(wJob_t job_handle,printer_capabilities_t * printer_cap,duplex_t duplex,char * pathname,int num_index,int * pages_ary)343 static jint _print_pdf_pages(wJob_t job_handle, printer_capabilities_t *printer_cap,
344 duplex_t duplex, char *pathname, int num_index, int *pages_ary) {
345 int num_pages = num_index;
346
347 // now, print the pages
348 int page_index;
349 jint result = ERROR;
350
351 // print forward direction if printer prints pages face down; otherwise print backward
352 // NOTE: last page is sent from calling function
353 if (printer_cap->faceDownTray || duplex) {
354 LOGD("_print_pdf_pages(), pages print face down or duplex, printing in normal order");
355 page_index = 0;
356 while (page_index < num_pages) {
357 LOGD("_print_pdf_pages(), PRINTING PDF: %d", *(pages_ary + page_index));
358 result = wprintPage(job_handle, *(pages_ary + page_index++), pathname, false, true,
359 0, 0, 0, 0);
360
361 if (result != OK) {
362 break;
363 }
364 }
365 } else {
366 LOGI(" _print_pdf_pages(), pages print face up, printing in reverse");
367 page_index = num_pages - 1;
368 while (page_index >= 0) {
369 LOGD("_print_pdf_pages(), PRINTING PDF: %s, page: %d", pathname,
370 *(pages_ary + page_index));
371 result = wprintPage(job_handle, *(pages_ary + page_index--), pathname, false, true,
372 0, 0, 0, 0);
373 if (result != OK) {
374 break;
375 }
376 }
377 }
378
379 LOGI(" _print_pdf_pages(), printing result: %s", result == OK ? "OK" : "ERROR");
380 return result;
381 }
382
383 /*
384 * Initialize JNI. Maps java values to jni values.
385 */
_initJNI(JNIEnv * env,jobject callbackReceiver,jstring fakeDir)386 static void _initJNI(JNIEnv *env, jobject callbackReceiver, jstring fakeDir) {
387 _fakeDir = (jstring) (*env)->NewGlobalRef(env, fakeDir);
388
389 // fill out static accessors for wPrintJobParameters
390 _LocalJobParamsClass = (jclass) (*env)->NewGlobalRef(
391 env, (*env)->FindClass(env, "com/android/bips/jni/LocalJobParams"));
392 _LocalJobParamsField__borderless = (*env)->GetFieldID(env, _LocalJobParamsClass, "borderless",
393 "I");
394 _LocalJobParamsField__duplex = (*env)->GetFieldID(env, _LocalJobParamsClass, "duplex", "I");
395 _LocalJobParamsField__media_size = (*env)->GetFieldID(env, _LocalJobParamsClass, "media_size",
396 "I");
397 _LocalJobParamsField__media_type = (*env)->GetFieldID(env, _LocalJobParamsClass, "media_type",
398 "I");
399 _LocalJobParamsField__media_tray = (*env)->GetFieldID(env, _LocalJobParamsClass, "media_tray",
400 "I");
401 _LocalJobParamsField__color_space = (*env)->GetFieldID(env, _LocalJobParamsClass, "color_space",
402 "I");
403 _LocalJobParamsField__render_flags = (*env)->GetFieldID(env, _LocalJobParamsClass,
404 "render_flags", "I");
405 _LocalJobParamsField__num_copies = (*env)->GetFieldID(env, _LocalJobParamsClass, "num_copies",
406 "I");
407 _LocalJobParamsField__page_range = (*env)->GetFieldID(env, _LocalJobParamsClass, "page_range",
408 "Ljava/lang/String;");
409 _LocalJobParamsField__print_resolution = (*env)->GetFieldID(env, _LocalJobParamsClass,
410 "print_resolution", "I");
411 _LocalJobParamsField__printable_width = (*env)->GetFieldID(env, _LocalJobParamsClass,
412 "printable_width", "I");
413 _LocalJobParamsField__printable_height = (*env)->GetFieldID(env, _LocalJobParamsClass,
414 "printable_height", "I");
415 _LocalJobParamsField__page_width = (*env)->GetFieldID(env, _LocalJobParamsClass, "page_width",
416 "F");
417 _LocalJobParamsField__page_height = (*env)->GetFieldID(env, _LocalJobParamsClass, "page_height",
418 "F");
419 _LocalJobParamsField__page_margin_top = (*env)->GetFieldID(env, _LocalJobParamsClass,
420 "page_margin_top", "F");
421 _LocalJobParamsField__page_margin_left = (*env)->GetFieldID(env, _LocalJobParamsClass,
422 "page_margin_left", "F");
423 _LocalJobParamsField__page_margin_right = (*env)->GetFieldID(env, _LocalJobParamsClass,
424 "page_margin_right", "F");
425 _LocalJobParamsField__page_margin_bottom = (*env)->GetFieldID(env, _LocalJobParamsClass,
426 "page_margin_bottom", "F");
427 _LocalJobParamsField__nativeData = (*env)->GetFieldID(env, _LocalJobParamsClass, "nativeData",
428 "[B");
429 _LocalJobParamsField__fit_to_page = (*env)->GetFieldID(env, _LocalJobParamsClass, "fit_to_page",
430 "Z");
431 _LocalJobParamsField__fill_page = (*env)->GetFieldID(env, _LocalJobParamsClass, "fill_page",
432 "Z");
433 _LocalJobParamsField__auto_rotate = (*env)->GetFieldID(env, _LocalJobParamsClass, "auto_rotate",
434 "Z");
435 _LocalJobParamsField__portrait_mode = (*env)->GetFieldID(env, _LocalJobParamsClass,
436 "portrait_mode", "Z");
437 _LocalJobParamsField__landscape_mode = (*env)->GetFieldID(env, _LocalJobParamsClass,
438 "landscape_mode", "Z");
439 _LocalJobParamsField__document_category = (*env)->GetFieldID(env, _LocalJobParamsClass,
440 "document_category",
441 "Ljava/lang/String;");
442 _LocalJobParamsField__alignment = (*env)->GetFieldID(env, _LocalJobParamsClass, "alignment",
443 "I");
444 _LocalJobParamsField__job_margin_top = (*env)->GetFieldID(env, _LocalJobParamsClass,
445 "job_margin_top", "F");
446 _LocalJobParamsField__job_margin_left = (*env)->GetFieldID(env, _LocalJobParamsClass,
447 "job_margin_left", "F");
448 _LocalJobParamsField__job_margin_right = (*env)->GetFieldID(env, _LocalJobParamsClass,
449 "job_margin_right", "F");
450 _LocalJobParamsField__job_margin_bottom = (*env)->GetFieldID(env, _LocalJobParamsClass,
451 "job_margin_bottom", "F");
452 _LocalJobParamsField__document_scaling = (*env)->GetFieldID(env, _LocalJobParamsClass,
453 "document_scaling", "Z");
454 _LocalJobParamsField__job_name = (*env)->GetFieldID(env, _LocalJobParamsClass, "job_name",
455 "Ljava/lang/String;");
456 _LocalJobParamsField__job_originating_user_name = (*env)->GetFieldID(
457 env, _LocalJobParamsClass, "job_originating_user_name", "Ljava/lang/String;");
458 _LocalJobParamsField__pdf_render_resolution = (*env)->GetFieldID(env, _LocalJobParamsClass,
459 "pdf_render_resolution", "I");
460
461 // fill out static accessors for LocalPrinterCapabilities
462 _LocalPrinterCapabilitiesClass = (jclass) (*env)->NewGlobalRef(env, (*env)->FindClass(
463 env, "com/android/bips/jni/LocalPrinterCapabilities"));
464 _LocalPrinterCapabilitiesField__path = (*env)->GetFieldID(
465 env, _LocalPrinterCapabilitiesClass, "path", "Ljava/lang/String;");
466 _LocalPrinterCapabilitiesField__name = (*env)->GetFieldID(
467 env, _LocalPrinterCapabilitiesClass, "name", "Ljava/lang/String;");
468 _LocalPrinterCapabilitiesField__uuid = (*env)->GetFieldID(
469 env, _LocalPrinterCapabilitiesClass, "uuid", "Ljava/lang/String;");
470 _LocalPrinterCapabilitiesField__location = (*env)->GetFieldID(
471 env, _LocalPrinterCapabilitiesClass, "location", "Ljava/lang/String;");
472 _LocalPrinterCapabilitiesField__duplex = (*env)->GetFieldID(
473 env, _LocalPrinterCapabilitiesClass, "duplex", "Z");
474 _LocalPrinterCapabilitiesField__borderless = (*env)->GetFieldID(
475 env, _LocalPrinterCapabilitiesClass, "borderless", "Z");
476 _LocalPrinterCapabilitiesField__color = (*env)->GetFieldID(
477 env, _LocalPrinterCapabilitiesClass, "color", "Z");
478 _LocalPrinterCapabilitiesField__isSupported = (*env)->GetFieldID(
479 env, _LocalPrinterCapabilitiesClass, "isSupported", "Z");
480 _LocalPrinterCapabilitiesField__mediaDefault = (*env)->GetFieldID(
481 env, _LocalPrinterCapabilitiesClass, "mediaDefault", "Ljava/lang/String;");
482 _LocalPrinterCapabilitiesField__supportedMediaTypes = (*env)->GetFieldID(
483 env, _LocalPrinterCapabilitiesClass, "supportedMediaTypes", "[I");
484 _LocalPrinterCapabilitiesField__supportedMediaSizes = (*env)->GetFieldID(
485 env, _LocalPrinterCapabilitiesClass, "supportedMediaSizes", "[I");
486 _LocalPrinterCapabilitiesField__nativeData = (*env)->GetFieldID(
487 env, _LocalPrinterCapabilitiesClass, "nativeData", "[B");
488 _LocalPrinterCapabilitiesField__certificate = (*env)->GetFieldID(
489 env, _LocalPrinterCapabilitiesClass, "certificate", "[B");
490
491 _JobCallbackParamsClass = (jclass) (*env)->NewGlobalRef(env, (*env)->FindClass(
492 env, "com/android/bips/jni/JobCallbackParams"));
493 _JobCallbackParamsMethod__init = (*env)->GetMethodID(env, _JobCallbackParamsClass,
494 "<init>", "()V");
495 _JobCallbackParamsField__jobId = (*env)->GetFieldID(env, _JobCallbackParamsClass, "jobId",
496 "I");
497 _JobCallbackParamsField__jobState = (*env)->GetFieldID(
498 env, _JobCallbackParamsClass, "jobState", "Ljava/lang/String;");
499 _JobCallbackParamsField__jobDoneResult = (*env)->GetFieldID(
500 env, _JobCallbackParamsClass, "jobDoneResult", "Ljava/lang/String;");
501 _JobCallbackParamsField__blockedReasons = (*env)->GetFieldID(
502 env, _JobCallbackParamsClass, "blockedReasons", "[Ljava/lang/String;");
503 _JobCallbackParamsField__certificate = (*env)->GetFieldID(
504 env, _JobCallbackParamsClass, "certificate", "[B");
505
506 if (callbackReceiver) {
507 _callbackReceiver = (jobject) (*env)->NewGlobalRef(env, callbackReceiver);
508 }
509 if (_callbackReceiver) {
510 _JobCallbackClass = (jclass) (*env)->NewGlobalRef(env, (*env)->GetObjectClass(
511 env, _callbackReceiver));
512 _JobCallbackMethod__jobCallback = (*env)->GetMethodID(
513 env, _JobCallbackClass, "jobCallback",
514 "(ILcom/android/bips/jni/JobCallbackParams;)V");
515 } else {
516 _callbackReceiver = 0;
517 }
518
519 _PrintServiceStringsClass = (jclass) (*env)->NewGlobalRef(env, (*env)->FindClass(
520 env, "com/android/bips/jni/BackendConstants"));
521 _PrintServiceStringsField__JOB_STATE_QUEUED = (*env)->GetStaticFieldID(
522 env, _PrintServiceStringsClass, "JOB_STATE_QUEUED", "Ljava/lang/String;");
523 _PrintServiceStringsField__JOB_STATE_RUNNING = (*env)->GetStaticFieldID(
524 env, _PrintServiceStringsClass, "JOB_STATE_RUNNING", "Ljava/lang/String;");
525 _PrintServiceStringsField__JOB_STATE_BLOCKED = (*env)->GetStaticFieldID(
526 env, _PrintServiceStringsClass, "JOB_STATE_BLOCKED", "Ljava/lang/String;");
527 _PrintServiceStringsField__JOB_STATE_DONE = (*env)->GetStaticFieldID(
528 env, _PrintServiceStringsClass, "JOB_STATE_DONE", "Ljava/lang/String;");
529 _PrintServiceStringsField__JOB_STATE_OTHER = (*env)->GetStaticFieldID(
530 env, _PrintServiceStringsClass, "JOB_STATE_OTHER", "Ljava/lang/String;");
531 _PrintServiceStringsField__JOB_DONE_OK = (*env)->GetStaticFieldID(
532 env, _PrintServiceStringsClass, "JOB_DONE_OK", "Ljava/lang/String;");
533 _PrintServiceStringsField__JOB_DONE_ERROR = (*env)->GetStaticFieldID(
534 env, _PrintServiceStringsClass, "JOB_DONE_ERROR", "Ljava/lang/String;");
535 _PrintServiceStringsField__JOB_DONE_CANCELLED = (*env)->GetStaticFieldID(
536 env, _PrintServiceStringsClass, "JOB_DONE_CANCELLED", "Ljava/lang/String;");
537 _PrintServiceStringsField__JOB_DONE_CORRUPT = (*env)->GetStaticFieldID(
538 env, _PrintServiceStringsClass, "JOB_DONE_CORRUPT", "Ljava/lang/String;");
539 _PrintServiceStringsField__JOB_DONE_OTHER = (*env)->GetStaticFieldID(
540 env, _PrintServiceStringsClass, "JOB_DONE_OTHER", "Ljava/lang/String;");
541 _PrintServiceStringsField__BLOCKED_REASON__OFFLINE = (*env)->GetStaticFieldID(
542 env, _PrintServiceStringsClass, "BLOCKED_REASON__OFFLINE", "Ljava/lang/String;");
543 _PrintServiceStringsField__BLOCKED_REASON__BUSY = (*env)->GetStaticFieldID(
544 env, _PrintServiceStringsClass, "BLOCKED_REASON__BUSY", "Ljava/lang/String;");
545 _PrintServiceStringsField__BLOCKED_REASON__CANCELLED = (*env)->GetStaticFieldID(
546 env, _PrintServiceStringsClass, "BLOCKED_REASON__CANCELLED", "Ljava/lang/String;");
547 _PrintServiceStringsField__BLOCKED_REASON__OUT_OF_PAPER = (*env)->GetStaticFieldID(
548 env, _PrintServiceStringsClass, "BLOCKED_REASON__OUT_OF_PAPER", "Ljava/lang/String;");
549 _PrintServiceStringsField__BLOCKED_REASON__OUT_OF_INK = (*env)->GetStaticFieldID(
550 env, _PrintServiceStringsClass, "BLOCKED_REASON__OUT_OF_INK", "Ljava/lang/String;");
551 _PrintServiceStringsField__BLOCKED_REASON__OUT_OF_TONER = (*env)->GetStaticFieldID(
552 env, _PrintServiceStringsClass, "BLOCKED_REASON__OUT_OF_TONER", "Ljava/lang/String;");
553 _PrintServiceStringsField__BLOCKED_REASON__JAMMED = (*env)->GetStaticFieldID(
554 env, _PrintServiceStringsClass, "BLOCKED_REASON__JAMMED", "Ljava/lang/String;");
555 _PrintServiceStringsField__BLOCKED_REASON__DOOR_OPEN = (*env)->GetStaticFieldID(
556 env, _PrintServiceStringsClass, "BLOCKED_REASON__DOOR_OPEN", "Ljava/lang/String;");
557 _PrintServiceStringsField__BLOCKED_REASON__SERVICE_REQUEST = (*env)->GetStaticFieldID(
558 env, _PrintServiceStringsClass, "BLOCKED_REASON__SERVICE_REQUEST",
559 "Ljava/lang/String;");
560 _PrintServiceStringsField__BLOCKED_REASON__LOW_ON_INK = (*env)->GetStaticFieldID(
561 env, _PrintServiceStringsClass, "BLOCKED_REASON__LOW_ON_INK", "Ljava/lang/String;");
562 _PrintServiceStringsField__BLOCKED_REASON__LOW_ON_TONER = (*env)->GetStaticFieldID(
563 env, _PrintServiceStringsClass, "BLOCKED_REASON__LOW_ON_TONER", "Ljava/lang/String;");
564 _PrintServiceStringsField__BLOCKED_REASON__REALLY_LOW_ON_INK = (*env)->GetStaticFieldID(
565 env, _PrintServiceStringsClass, "BLOCKED_REASON__REALLY_LOW_ON_INK",
566 "Ljava/lang/String;");
567 _PrintServiceStringsField__BLOCKED_REASON__BAD_CERTIFICATE = (*env)->GetStaticFieldID(
568 env, _PrintServiceStringsClass, "BLOCKED_REASON__BAD_CERTIFICATE",
569 "Ljava/lang/String;");
570 _PrintServiceStringsField__BLOCKED_REASON__UNKNOWN = (*env)->GetStaticFieldID(
571 env, _PrintServiceStringsClass, "BLOCKED_REASON__UNKNOWN", "Ljava/lang/String;");
572
573 _PrintServiceStringsField__ALIGNMENT__CENTER = (*env)->GetStaticFieldID(
574 env, _PrintServiceStringsClass, "ALIGN_CENTER", "I");
575 _PrintServiceStringsField__ALIGNMENT__CENTER_HORIZONTAL = (*env)->GetStaticFieldID(
576 env, _PrintServiceStringsClass, "ALIGN_CENTER_HORIZONTAL", "I");
577 _PrintServiceStringsField__ALIGNMENT__CENTER_VERTICAL = (*env)->GetStaticFieldID(
578 env, _PrintServiceStringsClass, "ALIGN_CENTER_VERTICIAL", "I");
579 _PrintServiceStringsField__ALIGNMENT__CENTER_HORIZONTAL_ON_ORIENTATION =
580 (*env)->GetStaticFieldID(env, _PrintServiceStringsClass,
581 "ALIGN_CENTER_HORIZONTAL_ON_ORIENTATION", "I");
582
583 pdf_render_init(env);
584 }
585
586 /*
587 * Converts java printer caps to c and saves them to wprintPrinterCaps
588 */
_convertPrinterCaps_to_C(JNIEnv * env,jobject javaPrinterCaps,printer_capabilities_t * wprintPrinterCaps)589 static int _convertPrinterCaps_to_C(JNIEnv *env, jobject javaPrinterCaps,
590 printer_capabilities_t *wprintPrinterCaps) {
591 if (!javaPrinterCaps || !wprintPrinterCaps) {
592 return ERROR;
593 }
594
595 jbyteArray nativeDataObject = (jbyteArray) (*env)->GetObjectField(
596 env, javaPrinterCaps, _LocalPrinterCapabilitiesField__nativeData);
597 if (!nativeDataObject) {
598 return ERROR;
599 }
600 jbyte *nativeDataPtr = (*env)->GetByteArrayElements(env, nativeDataObject, NULL);
601 memcpy(wprintPrinterCaps, (const void *) nativeDataPtr, sizeof(printer_capabilities_t));
602 (*env)->ReleaseByteArrayElements(env, nativeDataObject, nativeDataPtr, 0);
603
604 return OK;
605 }
606
607 /*
608 * Converts printer caps to java and saves them to javaPrinterCaps
609 */
_convertPrinterCaps_to_Java(JNIEnv * env,jobject javaPrinterCaps,const printer_capabilities_t * wprintPrinterCaps)610 static int _convertPrinterCaps_to_Java(JNIEnv *env, jobject javaPrinterCaps,
611 const printer_capabilities_t *wprintPrinterCaps) {
612 if (!javaPrinterCaps || !wprintPrinterCaps) {
613 return ERROR;
614 }
615
616 int arrayCreated = 0;
617 jbyteArray nativeDataObject = (jbyteArray) (*env)->GetObjectField(
618 env, javaPrinterCaps, _LocalPrinterCapabilitiesField__nativeData);
619 if (!nativeDataObject) {
620 arrayCreated = 1;
621 nativeDataObject = (*env)->NewByteArray(env, sizeof(printer_capabilities_t));
622 }
623
624 jbyte *nativeDataPtr = (*env)->GetByteArrayElements(env, nativeDataObject, NULL);
625 memcpy((void *) nativeDataPtr, wprintPrinterCaps, sizeof(printer_capabilities_t));
626 (*env)->ReleaseByteArrayElements(env, nativeDataObject, nativeDataPtr, 0);
627
628 if (arrayCreated) {
629 (*env)->SetObjectField(env, javaPrinterCaps, _LocalPrinterCapabilitiesField__nativeData,
630 nativeDataObject);
631 (*env)->DeleteLocalRef(env, nativeDataObject);
632 }
633
634 (*env)->SetBooleanField(env, javaPrinterCaps, _LocalPrinterCapabilitiesField__duplex,
635 (jboolean) wprintPrinterCaps->duplex);
636 (*env)->SetBooleanField(env, javaPrinterCaps,
637 _LocalPrinterCapabilitiesField__borderless,
638 (jboolean) wprintPrinterCaps->borderless);
639 (*env)->SetBooleanField(env, javaPrinterCaps, _LocalPrinterCapabilitiesField__color,
640 (jboolean) wprintPrinterCaps->color);
641 (*env)->SetBooleanField(env, javaPrinterCaps, _LocalPrinterCapabilitiesField__isSupported,
642 (jboolean) wprintPrinterCaps->isSupported);
643
644 stringToJava(env, javaPrinterCaps, _LocalPrinterCapabilitiesField__mediaDefault,
645 wprintPrinterCaps->mediaDefault);
646 stringToJava(env, javaPrinterCaps, _LocalPrinterCapabilitiesField__path,
647 wprintPrinterCaps->printerUri);
648 stringToJava(env, javaPrinterCaps, _LocalPrinterCapabilitiesField__name,
649 wprintPrinterCaps->name);
650 stringToJava(env, javaPrinterCaps, _LocalPrinterCapabilitiesField__uuid,
651 wprintPrinterCaps->uuid);
652 stringToJava(env, javaPrinterCaps, _LocalPrinterCapabilitiesField__location,
653 wprintPrinterCaps->location);
654
655 jintArray intArray;
656 int *intArrayPtr;
657 int index;
658
659 intArray = (*env)->NewIntArray(env, wprintPrinterCaps->numSupportedMediaTypes);
660 intArrayPtr = (*env)->GetIntArrayElements(env, intArray, NULL);
661 for (index = 0; index < wprintPrinterCaps->numSupportedMediaTypes; index++) {
662 intArrayPtr[index] = (int) wprintPrinterCaps->supportedMediaTypes[index];
663 }
664 (*env)->ReleaseIntArrayElements(env, intArray, intArrayPtr, 0);
665 (*env)->SetObjectField(env, javaPrinterCaps,
666 _LocalPrinterCapabilitiesField__supportedMediaTypes, intArray);
667 (*env)->DeleteLocalRef(env, intArray);
668
669 intArray = (*env)->NewIntArray(env, wprintPrinterCaps->numSupportedMediaSizes);
670 intArrayPtr = (*env)->GetIntArrayElements(env, intArray, NULL);
671 for (index = 0; index < wprintPrinterCaps->numSupportedMediaSizes; index++) {
672 intArrayPtr[index] = (int) wprintPrinterCaps->supportedMediaSizes[index];
673 }
674 (*env)->ReleaseIntArrayElements(env, intArray, intArrayPtr, 0);
675 (*env)->SetObjectField(env, javaPrinterCaps,
676 _LocalPrinterCapabilitiesField__supportedMediaSizes, intArray);
677 (*env)->DeleteLocalRef(env, intArray);
678
679 int count;
680 for (count = index = 0; index < (sizeof(int) * 8); index++) {
681 if ((wprintPrinterCaps->supportedInputMimeTypes & (1 << index)) != 0) {
682 count++;
683 }
684 }
685
686 return OK;
687 }
688
689 /*
690 * Converts str to a java string
691 */
stringToJava(JNIEnv * env,jobject obj,jfieldID id,const char * str)692 static void stringToJava(JNIEnv *env, jobject obj, jfieldID id, const char *str) {
693 jstring jStr;
694
695 // If null, copy an empty string
696 if (!str) str = "";
697
698 jStr = (*env)->NewStringUTF(env, str);
699 (*env)->SetObjectField(env, obj, id, jStr);
700 (*env)->DeleteLocalRef(env, jStr);
701 }
702
703 /*
704 * Converts javaJobParams to C and saves them to wprintJobParams
705 */
_convertJobParams_to_C(JNIEnv * env,jobject javaJobParams,wprint_job_params_t * wprintJobParams)706 static int _convertJobParams_to_C(JNIEnv *env, jobject javaJobParams,
707 wprint_job_params_t *wprintJobParams) {
708 if (!javaJobParams || !wprintJobParams) {
709 return ERROR;
710 }
711
712 jbyteArray nativeDataObject = (jbyteArray) (*env)->GetObjectField(
713 env, javaJobParams, _LocalJobParamsField__nativeData);
714 if (nativeDataObject == 0) {
715 return ERROR;
716 }
717
718 jbyte *nativeDataPtr = (*env)->GetByteArrayElements(env, nativeDataObject, NULL);
719 memcpy(wprintJobParams, (const void *) nativeDataPtr, sizeof(wprint_job_params_t));
720 (*env)->ReleaseByteArrayElements(env, nativeDataObject, nativeDataPtr, JNI_ABORT);
721
722 wprintJobParams->media_size = (media_size_t) (*env)->GetIntField(
723 env, javaJobParams, _LocalJobParamsField__media_size);
724 wprintJobParams->media_type = (media_type_t) (*env)->GetIntField(
725 env, javaJobParams, _LocalJobParamsField__media_type);
726 wprintJobParams->duplex = (duplex_t) (*env)->GetIntField(
727 env, javaJobParams, _LocalJobParamsField__duplex);
728 wprintJobParams->color_space = (color_space_t) (*env)->GetIntField(
729 env, javaJobParams, _LocalJobParamsField__color_space);
730 wprintJobParams->media_tray = (media_tray_t) (*env)->GetIntField(
731 env, javaJobParams, _LocalJobParamsField__media_tray);
732 wprintJobParams->num_copies = (unsigned int) (*env)->GetIntField(
733 env, javaJobParams, _LocalJobParamsField__num_copies);
734 wprintJobParams->borderless = (bool) (*env)->GetIntField(env, javaJobParams,
735 _LocalJobParamsField__borderless);
736 wprintJobParams->render_flags = (unsigned int) (*env)->GetIntField(
737 env, javaJobParams, _LocalJobParamsField__render_flags);
738 wprintJobParams->pdf_render_resolution =
739 (unsigned int) (*env)->GetIntField(env, javaJobParams,
740 _LocalJobParamsField__pdf_render_resolution);
741 // job margin setting
742 wprintJobParams->job_top_margin = (float) (*env)->GetFloatField(
743 env, javaJobParams, _LocalJobParamsField__job_margin_top);
744 wprintJobParams->job_left_margin = (float) (*env)->GetFloatField(
745 env, javaJobParams, _LocalJobParamsField__job_margin_left);
746 wprintJobParams->job_right_margin = (float) (*env)->GetFloatField(
747 env, javaJobParams, _LocalJobParamsField__job_margin_right);
748 wprintJobParams->job_bottom_margin = (float) (*env)->GetFloatField(
749 env, javaJobParams, _LocalJobParamsField__job_margin_bottom);
750
751 if ((*env)->GetBooleanField(env, javaJobParams, _LocalJobParamsField__portrait_mode)) {
752 wprintJobParams->render_flags |= RENDER_FLAG_PORTRAIT_MODE;
753 } else if ((*env)->GetBooleanField(env, javaJobParams, _LocalJobParamsField__landscape_mode)) {
754 wprintJobParams->render_flags |= RENDER_FLAG_LANDSCAPE_MODE;
755 } else if ((*env)->GetBooleanField(env, javaJobParams, _LocalJobParamsField__auto_rotate)) {
756 wprintJobParams->render_flags |= RENDER_FLAG_AUTO_ROTATE;
757 }
758 if ((*env)->GetBooleanField(env, javaJobParams, _LocalJobParamsField__fill_page)) {
759 wprintJobParams->render_flags |= AUTO_SCALE_RENDER_FLAGS;
760 } else if ((*env)->GetBooleanField(env, javaJobParams, _LocalJobParamsField__fit_to_page)) {
761 wprintJobParams->render_flags |= AUTO_FIT_RENDER_FLAGS;
762 if ((*env)->GetBooleanField(env, javaJobParams, _LocalJobParamsField__document_scaling)) {
763 wprintJobParams->render_flags |= RENDER_FLAG_DOCUMENT_SCALING;
764 }
765 }
766
767 int alignment = ((*env)->GetIntField(env, javaJobParams, _LocalJobParamsField__alignment));
768 if (alignment != 0) {
769 wprintJobParams->render_flags &= ~(RENDER_FLAG_CENTER_VERTICAL |
770 RENDER_FLAG_CENTER_HORIZONTAL |
771 RENDER_FLAG_CENTER_ON_ORIENTATION);
772 if (alignment & ((*env)->GetStaticIntField(
773 env, _PrintServiceStringsClass,
774 _PrintServiceStringsField__ALIGNMENT__CENTER_HORIZONTAL))) {
775 wprintJobParams->render_flags |= RENDER_FLAG_CENTER_HORIZONTAL;
776 }
777 if (alignment & ((*env)->GetStaticIntField(
778 env, _PrintServiceStringsClass,
779 _PrintServiceStringsField__ALIGNMENT__CENTER_VERTICAL))) {
780 wprintJobParams->render_flags |= RENDER_FLAG_CENTER_VERTICAL;
781 }
782 if (alignment & ((*env)->GetStaticIntField(
783 env, _PrintServiceStringsClass,
784 _PrintServiceStringsField__ALIGNMENT__CENTER_HORIZONTAL_ON_ORIENTATION))) {
785 wprintJobParams->render_flags |= RENDER_FLAG_CENTER_ON_ORIENTATION;
786 }
787 if ((alignment & ((*env)->GetStaticIntField(
788 env, _PrintServiceStringsClass, _PrintServiceStringsField__ALIGNMENT__CENTER))) ==
789 ((*env)->GetStaticIntField(env, _PrintServiceStringsClass,
790 _PrintServiceStringsField__ALIGNMENT__CENTER))) {
791 wprintJobParams->render_flags &= ~RENDER_FLAG_CENTER_ON_ORIENTATION;
792 wprintJobParams->render_flags |= (RENDER_FLAG_CENTER_VERTICAL |
793 RENDER_FLAG_CENTER_HORIZONTAL);
794 }
795 }
796
797 jstring docCategory = (jstring) (*env)->GetObjectField(env, javaJobParams,
798 _LocalJobParamsField__document_category);
799 if (docCategory != NULL) {
800 const char *category = (*env)->GetStringUTFChars(env, docCategory, NULL);
801 if (category != NULL) {
802 strncpy(wprintJobParams->docCategory, category,
803 sizeof(wprintJobParams->docCategory) - 1);
804 (*env)->ReleaseStringUTFChars(env, docCategory, category);
805 }
806 }
807 // job name
808 jstring jobName = (jstring) (*env)->GetObjectField(env, javaJobParams,
809 _LocalJobParamsField__job_name);
810 if (jobName != NULL) {
811 const char *name = (*env)->GetStringUTFChars(env, jobName, NULL);
812 if (name != NULL) {
813 strncpy(wprintJobParams->job_name, name, sizeof(wprintJobParams->job_name) - 1);
814 (*env)->ReleaseStringUTFChars(env, jobName, name);
815 }
816 }
817 // job originating user name
818 jstring jobOriginatingUserName = (jstring) (*env)->GetObjectField(
819 env, javaJobParams, _LocalJobParamsField__job_originating_user_name);
820 if (jobOriginatingUserName != NULL) {
821 const char *name = (*env)->GetStringUTFChars(env, jobOriginatingUserName, NULL);
822 if (name != NULL) {
823 strncpy(wprintJobParams->job_originating_user_name, name,
824 sizeof(wprintJobParams->job_originating_user_name) - 1);
825 (*env)->ReleaseStringUTFChars(env, jobOriginatingUserName, name);
826 }
827 }
828
829 free(wprintJobParams->page_range);
830 wprintJobParams->page_range = NULL;
831 jstring pageRangeObject = (jstring) (*env)->GetObjectField(env, javaJobParams,
832 _LocalJobParamsField__page_range);
833 if (pageRangeObject) {
834 int page_range_size = (*env)->GetStringLength(env, pageRangeObject);
835 const jbyte *pageRange = (jbyte *) (*env)->GetStringUTFChars(env, pageRangeObject, 0);
836 if (strcmp((char *) pageRange, "") != 0) {
837 wprintJobParams->page_range = (char *) malloc(page_range_size + 1);
838 memset(wprintJobParams->page_range, 0, page_range_size + 1);
839 strncpy(wprintJobParams->page_range, (char *) pageRange, page_range_size);
840
841 (*env)->ReleaseStringUTFChars(env, pageRangeObject, (const char *) pageRange);
842 }
843 }
844
845 return OK;
846 }
847
848 /*
849 * Converts wprintJobParams to java and saves them to javaJobParams
850 */
_covertJobParams_to_Java(JNIEnv * env,jobject javaJobParams,wprint_job_params_t * wprintJobParams)851 static int _covertJobParams_to_Java(JNIEnv *env, jobject javaJobParams,
852 wprint_job_params_t *wprintJobParams) {
853 if (!javaJobParams || !wprintJobParams) {
854 return ERROR;
855 }
856
857 jbyteArray nativeDataObject = (jbyteArray) (*env)->GetObjectField(
858 env, javaJobParams, _LocalJobParamsField__nativeData);
859 if (!nativeDataObject) {
860 nativeDataObject = (*env)->NewByteArray(env, sizeof(wprint_job_params_t));
861 (*env)->SetObjectField(env, javaJobParams, _LocalJobParamsField__nativeData,
862 nativeDataObject);
863 nativeDataObject = (jbyteArray) (*env)->GetObjectField(env, javaJobParams,
864 _LocalJobParamsField__nativeData);
865 }
866
867 jbyte *nativeDataPtr = (*env)->GetByteArrayElements(env, nativeDataObject, NULL);
868 memcpy((void *) nativeDataPtr, wprintJobParams, sizeof(wprint_job_params_t));
869 (*env)->ReleaseByteArrayElements(env, nativeDataObject, nativeDataPtr, 0);
870
871 // update job parameters
872 (*env)->SetIntField(env, javaJobParams, _LocalJobParamsField__media_size,
873 (int) wprintJobParams->media_size);
874 (*env)->SetIntField(env, javaJobParams, _LocalJobParamsField__media_type,
875 (int) wprintJobParams->media_type);
876 (*env)->SetIntField(env, javaJobParams, _LocalJobParamsField__duplex,
877 (int) wprintJobParams->duplex);
878 (*env)->SetIntField(env, javaJobParams, _LocalJobParamsField__color_space,
879 (int) wprintJobParams->color_space);
880 (*env)->SetIntField(env, javaJobParams, _LocalJobParamsField__media_tray,
881 (int) wprintJobParams->media_tray);
882 (*env)->SetIntField(env, javaJobParams, _LocalJobParamsField__num_copies,
883 (int) wprintJobParams->num_copies);
884 (*env)->SetIntField(env, javaJobParams, _LocalJobParamsField__borderless,
885 (int) wprintJobParams->borderless);
886 (*env)->SetIntField(env, javaJobParams, _LocalJobParamsField__render_flags,
887 (int) wprintJobParams->render_flags);
888 (*env)->SetIntField(env, javaJobParams, _LocalJobParamsField__pdf_render_resolution,
889 wprintJobParams->pdf_render_resolution);
890 (*env)->SetBooleanField(env, javaJobParams, _LocalJobParamsField__fit_to_page,
891 (jboolean) ((wprintJobParams->render_flags & AUTO_FIT_RENDER_FLAGS) ==
892 AUTO_FIT_RENDER_FLAGS));
893 (*env)->SetBooleanField(env, javaJobParams, _LocalJobParamsField__fill_page,
894 (jboolean) ((wprintJobParams->render_flags & AUTO_SCALE_RENDER_FLAGS) ==
895 AUTO_SCALE_RENDER_FLAGS));
896 (*env)->SetBooleanField(env, javaJobParams, _LocalJobParamsField__auto_rotate,
897 (jboolean) ((wprintJobParams->render_flags & RENDER_FLAG_AUTO_ROTATE) != 0));
898 (*env)->SetBooleanField(env, javaJobParams, _LocalJobParamsField__portrait_mode, (jboolean) (
899 (wprintJobParams->render_flags & RENDER_FLAG_PORTRAIT_MODE) != 0));
900 (*env)->SetBooleanField(env, javaJobParams, _LocalJobParamsField__landscape_mode, (jboolean) (
901 (wprintJobParams->render_flags & RENDER_FLAG_LANDSCAPE_MODE) != 0));
902
903 // update the printable area & DPI information
904 (*env)->SetIntField(env, javaJobParams, _LocalJobParamsField__print_resolution,
905 (int) wprintJobParams->pixel_units);
906 (*env)->SetIntField(env, javaJobParams, _LocalJobParamsField__printable_width,
907 (int) wprintJobParams->width);
908 (*env)->SetIntField(env, javaJobParams, _LocalJobParamsField__printable_height,
909 (int) wprintJobParams->height);
910
911 // update the page size information
912 (*env)->SetFloatField(env, javaJobParams, _LocalJobParamsField__page_width,
913 wprintJobParams->page_width);
914 (*env)->SetFloatField(env, javaJobParams, _LocalJobParamsField__page_height,
915 wprintJobParams->page_height);
916 (*env)->SetFloatField(env, javaJobParams, _LocalJobParamsField__page_margin_top,
917 wprintJobParams->page_top_margin);
918 (*env)->SetFloatField(env, javaJobParams, _LocalJobParamsField__page_margin_left,
919 wprintJobParams->page_left_margin);
920 (*env)->SetFloatField(env, javaJobParams, _LocalJobParamsField__page_margin_right,
921 wprintJobParams->page_right_margin);
922 (*env)->SetFloatField(env, javaJobParams, _LocalJobParamsField__page_margin_bottom,
923 wprintJobParams->page_bottom_margin);
924
925 (*env)->SetFloatField(env, javaJobParams, _LocalJobParamsField__job_margin_top,
926 wprintJobParams->job_top_margin);
927 (*env)->SetFloatField(env, javaJobParams, _LocalJobParamsField__job_margin_left,
928 wprintJobParams->job_left_margin);
929 (*env)->SetFloatField(env, javaJobParams, _LocalJobParamsField__job_margin_right,
930 wprintJobParams->job_right_margin);
931 (*env)->SetFloatField(env, javaJobParams, _LocalJobParamsField__job_margin_bottom,
932 wprintJobParams->job_bottom_margin);
933
934 return OK;
935 }
936
937 /*
938 * Handles print job callbacks. Handles job states and blocked reasons
939 */
_wprint_callback_fn(wJob_t job_handle,void * param)940 static void _wprint_callback_fn(wJob_t job_handle, void *param) {
941 jstring jStr;
942 wprint_job_callback_params_t *cb_param = (wprint_job_callback_params_t *) param;
943 if (!cb_param) {
944 return;
945 }
946
947 int needDetach = 0;
948 JNIEnv *env;
949 if ((*_JVM)->GetEnv(_JVM, (void **) &env, JNI_VERSION_1_6) < 0) {
950 needDetach = 1;
951 if ((*_JVM)->AttachCurrentThread(_JVM, &env, NULL) < 0) {
952 return;
953 }
954 }
955
956 jobject callbackParams = (*env)->NewObject(env, _JobCallbackParamsClass,
957 _JobCallbackParamsMethod__init);
958 if (callbackParams != 0) {
959 switch (cb_param->state) {
960 case JOB_QUEUED:
961 jStr = (jstring) (*env)->GetStaticObjectField(
962 env, _PrintServiceStringsClass,
963 _PrintServiceStringsField__JOB_STATE_QUEUED);
964 break;
965 case JOB_RUNNING:
966 jStr = (jstring) (*env)->GetStaticObjectField(
967 env, _PrintServiceStringsClass,
968 _PrintServiceStringsField__JOB_STATE_RUNNING);
969 break;
970 case JOB_BLOCKED:
971 jStr = (jstring) (*env)->GetStaticObjectField(
972 env, _PrintServiceStringsClass,
973 _PrintServiceStringsField__JOB_STATE_BLOCKED);
974 break;
975 case JOB_DONE:
976 jStr = (jstring) (*env)->GetStaticObjectField(
977 env, _PrintServiceStringsClass,
978 _PrintServiceStringsField__JOB_STATE_DONE);
979 break;
980 default:
981 jStr = (jstring) (*env)->GetStaticObjectField(
982 env, _PrintServiceStringsClass,
983 _PrintServiceStringsField__JOB_STATE_OTHER);
984 break;
985 }
986 (*env)->SetObjectField(env, callbackParams, _JobCallbackParamsField__jobState, jStr);
987
988 if (cb_param->state == JOB_DONE) {
989 switch (cb_param->job_done_result) {
990 case OK:
991 jStr = (jstring) (*env)->GetStaticObjectField(
992 env, _PrintServiceStringsClass,
993 _PrintServiceStringsField__JOB_DONE_OK);
994 break;
995 case ERROR:
996 jStr = (jstring) (*env)->GetStaticObjectField(
997 env, _PrintServiceStringsClass,
998 _PrintServiceStringsField__JOB_DONE_ERROR);
999 break;
1000 case CANCELLED:
1001 jStr = (jstring) (*env)->GetStaticObjectField(
1002 env, _PrintServiceStringsClass,
1003 _PrintServiceStringsField__JOB_DONE_CANCELLED);
1004 break;
1005 case CORRUPT:
1006 jStr = (jstring) (*env)->GetStaticObjectField(
1007 env, _PrintServiceStringsClass,
1008 _PrintServiceStringsField__JOB_DONE_CORRUPT);
1009 break;
1010 default:
1011 jStr = (jstring) (*env)->GetStaticObjectField(
1012 env, _PrintServiceStringsClass,
1013 _PrintServiceStringsField__JOB_DONE_OTHER);
1014 break;
1015 }
1016
1017 (*env)->SetObjectField(env, callbackParams,
1018 _JobCallbackParamsField__jobDoneResult, jStr);
1019 }
1020
1021 int i, count;
1022 for (count = i = 0; i < PRINT_STATUS_MAX_STATE; i++) {
1023 if (cb_param->blocked_reasons & (1 << i)) {
1024 count++;
1025 }
1026 }
1027
1028 if (count > 0) {
1029 jStr = (*env)->NewStringUTF(env, "");
1030 jobjectArray stringArray = (*env)->NewObjectArray(env, count, (*env)->FindClass(
1031 env, "java/lang/String"), jStr);
1032 (*env)->DeleteLocalRef(env, jStr);
1033
1034 unsigned int blocked_reasons = cb_param->blocked_reasons;
1035 for (count = i = 0; i < PRINT_STATUS_MAX_STATE; i++) {
1036 jStr = NULL;
1037
1038 if ((blocked_reasons & (1 << i)) == 0) {
1039 jStr = NULL;
1040 } else if (blocked_reasons & BLOCKED_REASON_UNABLE_TO_CONNECT) {
1041 jStr = (jstring) (*env)->GetStaticObjectField(
1042 env, _PrintServiceStringsClass,
1043 _PrintServiceStringsField__BLOCKED_REASON__OFFLINE);
1044 } else if (blocked_reasons & BLOCKED_REASON_BUSY) {
1045 jStr = (jstring) (*env)->GetStaticObjectField(
1046 env, _PrintServiceStringsClass,
1047 _PrintServiceStringsField__BLOCKED_REASON__BUSY);
1048 } else if (blocked_reasons & BLOCKED_REASONS_CANCELLED) {
1049 jStr = (jstring) (*env)->GetStaticObjectField(
1050 env, _PrintServiceStringsClass,
1051 _PrintServiceStringsField__BLOCKED_REASON__CANCELLED);
1052 } else if (blocked_reasons & BLOCKED_REASON_JAMMED) {
1053 jStr = (jstring) (*env)->GetStaticObjectField(
1054 env, _PrintServiceStringsClass,
1055 _PrintServiceStringsField__BLOCKED_REASON__JAMMED);
1056 } else if (blocked_reasons & BLOCKED_REASON_OUT_OF_PAPER) {
1057 jStr = (jstring) (*env)->GetStaticObjectField(
1058 env, _PrintServiceStringsClass,
1059 _PrintServiceStringsField__BLOCKED_REASON__OUT_OF_PAPER);
1060 } else if (blocked_reasons & BLOCKED_REASON_OUT_OF_INK) {
1061 jStr = (jstring) (*env)->GetStaticObjectField(
1062 env, _PrintServiceStringsClass,
1063 _PrintServiceStringsField__BLOCKED_REASON__OUT_OF_INK);
1064 } else if (blocked_reasons & BLOCKED_REASON_OUT_OF_TONER) {
1065 jStr = (jstring) (*env)->GetStaticObjectField(
1066 env, _PrintServiceStringsClass,
1067 _PrintServiceStringsField__BLOCKED_REASON__OUT_OF_TONER);
1068 } else if (blocked_reasons & BLOCKED_REASON_DOOR_OPEN) {
1069 jStr = (jstring) (*env)->GetStaticObjectField(
1070 env, _PrintServiceStringsClass,
1071 _PrintServiceStringsField__BLOCKED_REASON__DOOR_OPEN);
1072 } else if (blocked_reasons & BLOCKED_REASON_SVC_REQUEST) {
1073 jStr = (jstring) (*env)->GetStaticObjectField(
1074 env, _PrintServiceStringsClass,
1075 _PrintServiceStringsField__BLOCKED_REASON__SERVICE_REQUEST);
1076 } else if (blocked_reasons & BLOCKED_REASON_LOW_ON_INK) {
1077 jStr = (jstring) (*env)->GetStaticObjectField(
1078 env, _PrintServiceStringsClass,
1079 _PrintServiceStringsField__BLOCKED_REASON__LOW_ON_INK);
1080 } else if (blocked_reasons & BLOCKED_REASON_LOW_ON_TONER) {
1081 jStr = (jstring) (*env)->GetStaticObjectField(
1082 env, _PrintServiceStringsClass,
1083 _PrintServiceStringsField__BLOCKED_REASON__LOW_ON_TONER);
1084 } else if (blocked_reasons &
1085 BLOCKED_REASON_PRINT_STATUS_VERY_LOW_ON_INK) {
1086 jStr = (jstring) (*env)->GetStaticObjectField(
1087 env, _PrintServiceStringsClass,
1088 _PrintServiceStringsField__BLOCKED_REASON__REALLY_LOW_ON_INK);
1089 } else if (blocked_reasons & BLOCKED_REASON_BAD_CERTIFICATE) {
1090 jStr = (jstring) (*env)->GetStaticObjectField(
1091 env, _PrintServiceStringsClass,
1092 _PrintServiceStringsField__BLOCKED_REASON__BAD_CERTIFICATE);
1093 } else if (blocked_reasons & BLOCKED_REASON_UNKNOWN) {
1094 jStr = (jstring) (*env)->GetStaticObjectField(
1095 env, _PrintServiceStringsClass,
1096 _PrintServiceStringsField__BLOCKED_REASON__UNKNOWN);
1097 }
1098
1099 blocked_reasons &= ~(1 << i);
1100 if (jStr != 0) {
1101 (*env)->SetObjectArrayElement(env, stringArray, count++, jStr);
1102 }
1103 }
1104
1105 (*env)->SetObjectField(env, callbackParams, _JobCallbackParamsField__blockedReasons,
1106 stringArray);
1107 }
1108
1109 (*env)->SetIntField(env, callbackParams, _JobCallbackParamsField__jobId,
1110 (jint) job_handle);
1111
1112 if (cb_param->certificate) {
1113 LOGI("_wprint_callback_fn: copying certificate len=%d", cb_param->certificate_len);
1114 jbyteArray certificate = (*env)->NewByteArray(env, cb_param->certificate_len);
1115 jbyte *certificateBytes = (*env)->GetByteArrayElements(env, certificate, 0);
1116 memcpy(certificateBytes, (const void *) cb_param->certificate,
1117 cb_param->certificate_len);
1118 (*env)->ReleaseByteArrayElements(env, certificate, certificateBytes, 0);
1119 (*env)->SetObjectField(env, callbackParams, _JobCallbackParamsField__certificate,
1120 certificate);
1121 (*env)->DeleteLocalRef(env, certificate);
1122 } else {
1123 LOGI("_wprint_callback_fn: there is no certificate");
1124 // No cert, set NULL
1125 (*env)->SetObjectField(env, callbackParams, _JobCallbackParamsField__certificate,
1126 NULL);
1127 }
1128
1129 (*env)->CallVoidMethod(env, _callbackReceiver, _JobCallbackMethod__jobCallback,
1130 (jint) job_handle, callbackParams);
1131 (*env)->DeleteLocalRef(env, callbackParams);
1132 }
1133
1134 if (needDetach) {
1135 (*_JVM)->DetachCurrentThread(_JVM);
1136 }
1137 }
1138
1139 /*
1140 * Initialize wprint JNI
1141 */
Java_com_android_bips_ipp_Backend_nativeInit(JNIEnv * env,jobject obj,jobject callbackReceiver,jstring fakeDir,jint apiVersion)1142 JNIEXPORT jint JNICALL Java_com_android_bips_ipp_Backend_nativeInit(
1143 JNIEnv *env, jobject obj, jobject callbackReceiver, jstring fakeDir,
1144 jint apiVersion) {
1145 LOGI("nativeInit JNIenv is %p", env);
1146 int result;
1147
1148 // Setup the global JavaVM reference first.
1149 (*env)->GetJavaVM(env, &_JVM);
1150
1151 // Initialize the Android API version value
1152 g_API_version = apiVersion;
1153
1154 _initJNI(env, callbackReceiver, fakeDir);
1155
1156 // initialize wprint library
1157 result = wprintInit();
1158
1159 // return the result
1160 return result;
1161 }
1162
1163 /*
1164 * Copies a given string and returns the copy
1165 */
copyToNewString(JNIEnv * env,jstring source)1166 static char *copyToNewString(JNIEnv *env, jstring source) {
1167 const char *fromJava;
1168 char *newString;
1169
1170 fromJava = (*env)->GetStringUTFChars(env, source, NULL);
1171 if (fromJava == NULL) return NULL;
1172
1173 newString = (char *) malloc(strlen(fromJava) + 1);
1174 strcpy(newString, fromJava);
1175 (*env)->ReleaseStringUTFChars(env, source, fromJava);
1176
1177 return newString;
1178 }
1179
1180 /*
1181 * JNI call to wprint to get capabilities. Returns caps converted to java.
1182 */
Java_com_android_bips_ipp_Backend_nativeGetCapabilities(JNIEnv * env,jobject obj,jstring address,jint port,jstring httpResource,jstring uriScheme,jlong timeout,jobject printerCaps)1183 JNIEXPORT jint JNICALL Java_com_android_bips_ipp_Backend_nativeGetCapabilities(
1184 JNIEnv *env, jobject obj, jstring address, jint port, jstring httpResource,
1185 jstring uriScheme, jlong timeout, jobject printerCaps) {
1186 jint result;
1187 printer_capabilities_t caps;
1188 wprint_connect_info_t connect_info;
1189
1190 connect_info.printer_addr = copyToNewString(env, address);
1191 connect_info.uri_path = copyToNewString(env, httpResource);
1192 connect_info.uri_scheme = copyToNewString(env, uriScheme);
1193 connect_info.port_num = port;
1194 connect_info.timeout = timeout;
1195 connect_info.validate_certificate = NULL;
1196
1197 LOGI("nativeGetCapabilities for %s JNIenv is %p", connect_info.printer_addr, env);
1198
1199 // This call may take a while, and the JNI may be torn down when we return
1200 result = wprintGetCapabilities(&connect_info, &caps);
1201
1202 if (connect_info.printer_addr) free((char *) connect_info.printer_addr);
1203 if (connect_info.uri_path) free((char *) connect_info.uri_path);
1204 if (connect_info.uri_scheme) free((char *) connect_info.uri_scheme);
1205
1206 if (!wprintIsRunning() && result == 0) {
1207 result = ERROR;
1208 }
1209
1210 // additional IPP checks
1211 if (result == 0) {
1212 if (caps.isSupported && (caps.ippVersionMajor < 1)) {
1213 caps.isSupported = 0;
1214 }
1215 _convertPrinterCaps_to_Java(env, printerCaps, &caps);
1216 }
1217
1218 return result;
1219 }
1220
1221 /*
1222 * JNI call to wprint to get default job params. Returns job params converted to java.
1223 */
Java_com_android_bips_ipp_Backend_nativeGetDefaultJobParameters(JNIEnv * env,jobject obj,jobject jobParams)1224 JNIEXPORT jint JNICALL Java_com_android_bips_ipp_Backend_nativeGetDefaultJobParameters(
1225 JNIEnv *env, jobject obj, jobject jobParams) {
1226 LOGI("nativeGetDefaultJobParameters, JNIenv is %p", env);
1227 jint result;
1228 wprint_job_params_t params;
1229
1230 result = wprintGetDefaultJobParams(¶ms);
1231
1232 _covertJobParams_to_Java(env, jobParams, ¶ms);
1233 return result;
1234 }
1235
1236 /*
1237 * JNI call to wprint to get final job params. Returns final params converted to java.
1238 */
Java_com_android_bips_ipp_Backend_nativeGetFinalJobParameters(JNIEnv * env,jobject obj,jobject jobParams,jobject printerCaps)1239 JNIEXPORT jint JNICALL Java_com_android_bips_ipp_Backend_nativeGetFinalJobParameters(
1240 JNIEnv *env, jobject obj, jobject jobParams, jobject printerCaps) {
1241 LOGI("nativeGetFinalJobParameters, JNIenv is %p", env);
1242 jint result;
1243 wprint_job_params_t params;
1244 printer_capabilities_t caps;
1245
1246 _convertJobParams_to_C(env, jobParams, ¶ms);
1247 _convertPrinterCaps_to_C(env, printerCaps, &caps);
1248
1249 LOGD("nativeGetFinalJobParameters: After _convertJobParams_to_C: res=%d, name=%s",
1250 params.pdf_render_resolution, params.job_name);
1251 result = wprintGetFinalJobParams(¶ms, &caps);
1252
1253 _covertJobParams_to_Java(env, jobParams, ¶ms);
1254 return result;
1255 }
1256
1257 /*
1258 * Convert certificate (if present) from printer capabilities into job_params.
1259 */
_convertCertificate(JNIEnv * env,jobject printerCaps,wprint_job_params_t * params)1260 static void _convertCertificate(JNIEnv *env, jobject printerCaps, wprint_job_params_t *params) {
1261 params->certificate = NULL;
1262 jbyteArray certificate = (jbyteArray) (*env)->GetObjectField(env, printerCaps,
1263 _LocalPrinterCapabilitiesField__certificate);
1264 if (certificate) {
1265 params->certificate_len = (*env)->GetArrayLength(env, certificate);
1266 params->certificate = malloc(params->certificate_len);
1267 if (params->certificate) {
1268 jbyte *certificateBytes = (*env)->GetByteArrayElements(env, certificate, NULL);
1269 memcpy(params->certificate, certificateBytes, params->certificate_len);
1270 (*env)->ReleaseByteArrayElements(env, certificate, certificateBytes, JNI_ABORT);
1271 }
1272 }
1273 }
1274
1275 /*
1276 * JNI call to wprint to start a print job. Takes connection params, job params, caps, and file
1277 * array to complete the job
1278 */
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)1279 JNIEXPORT jint JNICALL Java_com_android_bips_ipp_Backend_nativeStartJob(
1280 JNIEnv *env, jobject obj, jstring address, jint port, jstring mimeType, jobject jobParams,
1281 jobject printerCaps, jobject fileArray, jstring jobDebugDir, jstring scheme) {
1282 LOGI("nativeStartJob, JNIenv is %p", env);
1283 jint result = ERROR;
1284 wJob_t job_handle = ERROR;
1285 bool hasFiles = false;
1286
1287 wprint_job_params_t params;
1288 printer_capabilities_t caps;
1289
1290 _convertJobParams_to_C(env, jobParams, ¶ms);
1291 _convertPrinterCaps_to_C(env, printerCaps, &caps);
1292 _convertCertificate(env, printerCaps, ¶ms);
1293
1294 LOGD("nativeStartJob: After _convertJobParams_to_C: res=%d, name=%s",
1295 params.pdf_render_resolution, params.job_name);
1296
1297 const char *addressStr = (*env)->GetStringUTFChars(env, address, NULL);
1298 const char *mimeTypeStr = (*env)->GetStringUTFChars(env, mimeType, NULL);
1299 const char *dataDirStr = (*env)->GetStringUTFChars(env, _fakeDir, NULL);
1300 const char *schemeStr = (*env)->GetStringUTFChars(env, scheme, NULL);
1301
1302 jsize len = 0;
1303 jobjectArray array;
1304
1305 if (fileArray) {
1306 array = (jobjectArray) fileArray;
1307 len = (*env)->GetArrayLength(env, array);
1308 hasFiles = (len > 0);
1309 }
1310
1311 int index = 0, pageIndex, incrementor;
1312 int page_range_arr[len];
1313
1314 // Initialize page_range_arr (address defect reported by Coverity scans)
1315 memset((char *) page_range_arr, 0, sizeof(int) * len);
1316
1317 int pdf_pages_ary[len];
1318 int pages_ary[len][MAX_NUM_PAGES];
1319
1320 if (hasFiles) {
1321 result = OK;
1322 for (pageIndex = 0; ((result == OK) && (pageIndex < len)); pageIndex++) {
1323 jstring page = (jstring) (*env)->GetObjectArrayElement(env, array, pageIndex);
1324 const char *pageStr = (*env)->GetStringUTFChars(env, page, NULL);
1325 if (pageStr == NULL) {
1326 result = ERROR;
1327 } else {
1328 int page_count = 0;
1329 if (_get_pdf_page_count(mimeTypeStr, &page_count, pageStr)) {
1330 pdf_pages_ary[pageIndex] = page_count;
1331 page_range_arr[pageIndex] = 0;
1332 char page_range_str[MAX_NUM_PAGES];
1333 memset(page_range_str, 0, MAX_NUM_PAGES);
1334 _get_pdf_page_range(env, jobParams, &pages_ary[pageIndex][0],
1335 pdf_pages_ary[pageIndex], &page_range_arr[pageIndex], page_range_str);
1336 }
1337 }
1338 (*env)->ReleaseStringUTFChars(env, page, pageStr);
1339 }
1340
1341 jstring page = (jstring) (*env)->GetObjectArrayElement(env, array, index);
1342 const char *pageStr = (*env)->GetStringUTFChars(env, page, NULL);
1343 if (pageStr == NULL) {
1344 result = ERROR;
1345 }
1346
1347 if (len == 1) {
1348 if (_is_pdf_doc((char *) mimeTypeStr, (char *) pageStr)) {
1349 if (page_range_arr[0] == 1) {
1350 LOGI("smart duplex, disabling duplex");
1351 params.duplex = DUPLEX_MODE_NONE;
1352 }
1353 } else {
1354 LOGI("smart duplex, disabling duplex");
1355 params.duplex = DUPLEX_MODE_NONE;
1356 }
1357 }
1358
1359 (*env)->ReleaseStringUTFChars(env, page, pageStr);
1360 const char *jobDebugDirStr = NULL;
1361 if (jobDebugDir != NULL) {
1362 jobDebugDirStr = (*env)->GetStringUTFChars(env, jobDebugDir, NULL);
1363 }
1364 result = wprintStartJob(addressStr, port, ¶ms, &caps, (char *) mimeTypeStr,
1365 (char *) dataDirStr, _wprint_callback_fn, jobDebugDirStr, schemeStr);
1366 if (result == ERROR) {
1367 LOGE("failed to start job: error code :%d", errno);
1368 }
1369 if ((jobDebugDir != NULL) && (jobDebugDirStr != NULL)) {
1370 (*env)->ReleaseStringUTFChars(env, jobDebugDir, jobDebugDirStr);
1371 }
1372 } else {
1373 LOGE("empty file list");
1374 }
1375 if (result != ERROR) {
1376 job_handle = (wJob_t) result;
1377
1378 // register job handle with service
1379 if (caps.faceDownTray || params.duplex) {
1380 index = 0;
1381 incrementor = 1;
1382 } else {
1383 index = len - 1;
1384 incrementor = -1;
1385 }
1386
1387 result = OK;
1388 for (pageIndex = 1; ((result == OK) && (pageIndex <= len)); pageIndex++) {
1389 jstring page = (jstring) (*env)->GetObjectArrayElement(env, array, index);
1390 const char *pageStr = (*env)->GetStringUTFChars(env, page, NULL);
1391 if (pageStr == NULL) {
1392 result = ERROR;
1393 } else {
1394 if (_is_pdf_doc((char *) mimeTypeStr, (char *) pageStr)) {
1395 result = _print_pdf_pages(job_handle, &caps, params.duplex, (char *) pageStr,
1396 page_range_arr[index], pages_ary[index]);
1397 } else {
1398 result = wprintPage(job_handle, pageIndex, (char *) pageStr, false, false,
1399 0, 0, 0, 0);
1400 }
1401 }
1402 (*env)->ReleaseStringUTFChars(env, page, pageStr);
1403 index += incrementor;
1404 }
1405
1406 wprintPage(job_handle, pageIndex, NULL, true, false, 0, 0, 0, 0);
1407 if (result != OK) {
1408 LOGE("failed to add some pages, aborting job");
1409 wprintCancelJob(job_handle);
1410 wprintEndJob(job_handle);
1411 job_handle = ERROR;
1412 }
1413 }
1414
1415 if (params.certificate) {
1416 free(params.certificate);
1417 }
1418 (*env)->ReleaseStringUTFChars(env, mimeType, mimeTypeStr);
1419 (*env)->ReleaseStringUTFChars(env, address, addressStr);
1420 (*env)->ReleaseStringUTFChars(env, _fakeDir, dataDirStr);
1421 (*env)->ReleaseStringUTFChars(env, scheme, schemeStr);
1422 return job_handle;
1423 }
1424
1425 /*
1426 * JNI call to wprint to end a print job
1427 */
Java_com_android_bips_ipp_Backend_nativeEndJob(JNIEnv * env,jobject obj,jint job_handle)1428 JNIEXPORT jint JNICALL Java_com_android_bips_ipp_Backend_nativeEndJob(
1429 JNIEnv *env, jobject obj, jint job_handle) {
1430 LOGI("nativeEndJob, JNIenv is %p", env);
1431 return wprintEndJob((wJob_t) job_handle);
1432 }
1433
1434 /*
1435 * JNI call to wprint to cancel a print job
1436 */
Java_com_android_bips_ipp_Backend_nativeCancelJob(JNIEnv * env,jobject obj,jint job_handle)1437 JNIEXPORT jint JNICALL Java_com_android_bips_ipp_Backend_nativeCancelJob(
1438 JNIEnv *env, jobject obj, jint job_handle) {
1439 LOGI("nativeCancelJob, JNIenv is %p", env);
1440 return wprintCancelJob((wJob_t) job_handle);
1441 }
1442
1443 /*
1444 * JNI call to wprint to exit
1445 */
Java_com_android_bips_ipp_Backend_nativeExit(JNIEnv * env,jobject obj)1446 JNIEXPORT jint JNICALL Java_com_android_bips_ipp_Backend_nativeExit(JNIEnv *env, jobject obj) {
1447 LOGI("nativeExit, JNIenv is %p", env);
1448
1449 (*env)->DeleteGlobalRef(env, _LocalJobParamsClass);
1450 (*env)->DeleteGlobalRef(env, _LocalPrinterCapabilitiesClass);
1451 (*env)->DeleteGlobalRef(env, _JobCallbackParamsClass);
1452 if (_callbackReceiver) {
1453 (*env)->DeleteGlobalRef(env, _callbackReceiver);
1454 }
1455 if (_JobCallbackClass) {
1456 (*env)->DeleteGlobalRef(env, _JobCallbackClass);
1457 }
1458 (*env)->DeleteGlobalRef(env, _fakeDir);
1459 (*env)->DeleteGlobalRef(env, _PrintServiceStringsClass);
1460
1461 pdf_render_deinit(env);
1462 return wprintExit();
1463 }
1464
1465 /*
1466 * Sets app name/version and os name
1467 */
Java_com_android_bips_ipp_Backend_nativeSetSourceInfo(JNIEnv * env,jobject obj,jstring appName,jstring appVersion,jstring osName)1468 JNIEXPORT void JNICALL Java_com_android_bips_ipp_Backend_nativeSetSourceInfo(
1469 JNIEnv *env, jobject obj, jstring appName, jstring appVersion, jstring osName) {
1470 LOGI("nativeSetSourceInfo, JNIenv is %p", env);
1471 const char *appNameStr = (*env)->GetStringUTFChars(env, appName, NULL);
1472 const char *appVersionStr = (*env)->GetStringUTFChars(env, appVersion, NULL);
1473 const char *osNameStr = (*env)->GetStringUTFChars(env, osName, NULL);
1474 wprintSetSourceInfo(appNameStr, appVersionStr, osNameStr);
1475 (*env)->ReleaseStringUTFChars(env, appName, appNameStr);
1476 (*env)->ReleaseStringUTFChars(env, appVersion, appVersionStr);
1477 (*env)->ReleaseStringUTFChars(env, osName, osNameStr);
1478 }