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