blob: 167ae20b596097c78276030f0562872de15bf697 [file] [log] [blame]
[email protected]b6f76a12013-11-14 17:29:241// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "printing/printing_context_android.h"
6
avi126e93c2015-12-21 21:48:167#include <stdint.h>
8
[email protected]b6f76a12013-11-14 17:29:249#include <vector>
10
11#include "base/android/jni_android.h"
12#include "base/android/jni_array.h"
13#include "base/android/jni_string.h"
14#include "base/logging.h"
dchengc3df9ba2016-04-07 23:09:3215#include "base/memory/ptr_util.h"
[email protected]b6f76a12013-11-14 17:29:2416#include "base/strings/string_number_conversions.h"
17#include "base/values.h"
18#include "jni/PrintingContext_jni.h"
19#include "printing/metafile.h"
20#include "printing/print_job_constants.h"
21#include "printing/units.h"
22#include "third_party/icu/source/i18n/unicode/ulocdata.h"
23
torne86560112016-08-04 15:59:0424using base::android::JavaParamRef;
Torne (Richard Coles)1b8b5152018-10-02 18:37:3225using base::android::JavaRef;
torne86560112016-08-04 15:59:0426using base::android::ScopedJavaLocalRef;
27
thestig5f683912016-09-30 22:42:1628namespace printing {
29
[email protected]b6f76a12013-11-14 17:29:2430namespace {
31
[email protected]b6f76a12013-11-14 17:29:2432// Sets the page sizes for a |PrintSettings| object. |width| and |height|
33// arguments should be in device units.
thestig5f683912016-09-30 22:42:1634void SetSizes(PrintSettings* settings, int dpi, int width, int height) {
[email protected]b6f76a12013-11-14 17:29:2435 gfx::Size physical_size_device_units(width, height);
36 // Assume full page is printable for now.
37 gfx::Rect printable_area_device_units(0, 0, width, height);
38
39 settings->set_dpi(dpi);
40 settings->SetPrinterPrintableArea(physical_size_device_units,
41 printable_area_device_units,
42 false);
43}
44
Torne (Richard Coles)1b8b5152018-10-02 18:37:3245void GetPageRanges(JNIEnv* env,
46 const JavaRef<jintArray>& int_arr,
47 PageRanges* range_vector) {
[email protected]b6f76a12013-11-14 17:29:2448 std::vector<int> pages;
Torne (Richard Coles)1b8b5152018-10-02 18:37:3249 base::android::JavaIntArrayToIntVector(env, int_arr.obj(), &pages);
thestig5f683912016-09-30 22:42:1650 for (int page : pages) {
51 PageRange range;
52 range.from = page;
53 range.to = page;
54 range_vector->push_back(range);
[email protected]b6f76a12013-11-14 17:29:2455 }
56}
57
58} // namespace
59
[email protected]b6f76a12013-11-14 17:29:2460// static
dchengc3df9ba2016-04-07 23:09:3261std::unique_ptr<PrintingContext> PrintingContext::Create(Delegate* delegate) {
62 return base::WrapUnique(new PrintingContextAndroid(delegate));
[email protected]b6f76a12013-11-14 17:29:2463}
64
65// static
Shimi Zhang5b8fb7c2018-09-27 01:20:4966void PrintingContextAndroid::PdfWritingDone(int page_count) {
[email protected]b6f76a12013-11-14 17:29:2467 JNIEnv* env = base::android::AttachCurrentThread();
Shimi Zhang5b8fb7c2018-09-27 01:20:4968 Java_PrintingContext_pdfWritingDone(env, page_count);
[email protected]b6f76a12013-11-14 17:29:2469}
70
Vitaly Bukabd7c9812014-08-26 08:57:5471PrintingContextAndroid::PrintingContextAndroid(Delegate* delegate)
72 : PrintingContext(delegate) {
[email protected]b6f76a12013-11-14 17:29:2473 // The constructor is run in the IO thread.
74}
75
76PrintingContextAndroid::~PrintingContextAndroid() {
77}
78
79void PrintingContextAndroid::AskUserForSettings(
[email protected]b6f76a12013-11-14 17:29:2480 int max_pages,
81 bool has_selection,
dgn4c172eea2014-12-15 21:11:2382 bool is_scripted,
Vladislav Kuzkokov48ceab22018-02-14 16:29:2883 PrintSettingsCallback callback) {
[email protected]b6f76a12013-11-14 17:29:2484 // This method is always run in the UI thread.
Vladislav Kuzkokov48ceab22018-02-14 16:29:2885 callback_ = std::move(callback);
[email protected]b6f76a12013-11-14 17:29:2486
87 JNIEnv* env = base::android::AttachCurrentThread();
88 if (j_printing_context_.is_null()) {
89 j_printing_context_.Reset(Java_PrintingContext_create(
90 env,
[email protected]879517bd2013-11-22 20:36:3191 reinterpret_cast<intptr_t>(this)));
[email protected]b6f76a12013-11-14 17:29:2492 }
93
dgn4c172eea2014-12-15 21:11:2394 if (is_scripted) {
torne948f3662016-08-16 15:10:4495 Java_PrintingContext_showPrintDialog(env, j_printing_context_);
dgn4c172eea2014-12-15 21:11:2396 } else {
Shimi Zhang30899822017-06-16 01:49:5597 Java_PrintingContext_askUserForSettings(env, j_printing_context_,
98 max_pages);
dgn4c172eea2014-12-15 21:11:2399 }
[email protected]b6f76a12013-11-14 17:29:24100}
101
torne6f3f0972015-11-25 18:04:30102void PrintingContextAndroid::AskUserForSettingsReply(
103 JNIEnv* env,
104 const JavaParamRef<jobject>& obj,
105 jboolean success) {
Vladislav Kuzkokov48ceab22018-02-14 16:29:28106 DCHECK(callback_);
[email protected]b6f76a12013-11-14 17:29:24107 if (!success) {
108 // TODO(cimamoglu): Differentiate between FAILED And CANCEL.
Vladislav Kuzkokov48ceab22018-02-14 16:29:28109 std::move(callback_).Run(FAILED);
[email protected]b6f76a12013-11-14 17:29:24110 return;
111 }
112
113 // We use device name variable to store the file descriptor. This is hacky
114 // but necessary. Since device name is not necessary for the upstream
115 // printing code for Android, this is harmless.
torne948f3662016-08-16 15:10:44116 int fd = Java_PrintingContext_getFileDescriptor(env, j_printing_context_);
[email protected]b6f76a12013-11-14 17:29:24117 settings_.set_device_name(base::IntToString16(fd));
118
119 ScopedJavaLocalRef<jintArray> intArr =
torne948f3662016-08-16 15:10:44120 Java_PrintingContext_getPages(env, j_printing_context_);
Torne (Richard Coles)1b8b5152018-10-02 18:37:32121 if (!intArr.is_null()) {
[email protected]b6f76a12013-11-14 17:29:24122 PageRanges range_vector;
Torne (Richard Coles)1b8b5152018-10-02 18:37:32123 GetPageRanges(env, intArr, &range_vector);
[email protected]b6f76a12013-11-14 17:29:24124 settings_.set_ranges(range_vector);
125 }
126
torne948f3662016-08-16 15:10:44127 int dpi = Java_PrintingContext_getDpi(env, j_printing_context_);
128 int width = Java_PrintingContext_getWidth(env, j_printing_context_);
129 int height = Java_PrintingContext_getHeight(env, j_printing_context_);
Shimi Zhang9c970fc72018-10-01 22:24:17130 width = ConvertUnit(width, kMilsPerInch, dpi);
131 height = ConvertUnit(height, kMilsPerInch, dpi);
[email protected]b6f76a12013-11-14 17:29:24132 SetSizes(&settings_, dpi, width, height);
133
Vladislav Kuzkokov48ceab22018-02-14 16:29:28134 std::move(callback_).Run(OK);
[email protected]b6f76a12013-11-14 17:29:24135}
136
torne6f3f0972015-11-25 18:04:30137void PrintingContextAndroid::ShowSystemDialogDone(
138 JNIEnv* env,
139 const JavaParamRef<jobject>& obj) {
Vladislav Kuzkokov48ceab22018-02-14 16:29:28140 DCHECK(callback_);
dgn4c172eea2014-12-15 21:11:23141 // Settings are not updated, callback is called only to unblock javascript.
Vladislav Kuzkokov48ceab22018-02-14 16:29:28142 std::move(callback_).Run(CANCEL);
dgn4c172eea2014-12-15 21:11:23143}
144
[email protected]b6f76a12013-11-14 17:29:24145PrintingContext::Result PrintingContextAndroid::UseDefaultSettings() {
146 DCHECK(!in_print_job_);
147
148 ResetSettings();
[email protected]c19b6a62013-11-18 21:53:11149 settings_.set_dpi(kDefaultPdfDpi);
[email protected]b6f76a12013-11-14 17:29:24150 gfx::Size physical_size = GetPdfPaperSizeDeviceUnits();
151 SetSizes(&settings_, kDefaultPdfDpi, physical_size.width(),
152 physical_size.height());
153 return OK;
154}
155
156gfx::Size PrintingContextAndroid::GetPdfPaperSizeDeviceUnits() {
157 // NOTE: This implementation is the same as in PrintingContextNoSystemDialog.
158 int32_t width = 0;
159 int32_t height = 0;
160 UErrorCode error = U_ZERO_ERROR;
Vitaly Bukabd7c9812014-08-26 08:57:54161 ulocdata_getPaperSize(
162 delegate_->GetAppLocale().c_str(), &height, &width, &error);
[email protected]b6f76a12013-11-14 17:29:24163 if (error > U_ZERO_ERROR) {
164 // If the call failed, assume a paper size of 8.5 x 11 inches.
165 LOG(WARNING) << "ulocdata_getPaperSize failed, using 8.5 x 11, error: "
166 << error;
167 width = static_cast<int>(
168 kLetterWidthInch * settings_.device_units_per_inch());
169 height = static_cast<int>(
170 kLetterHeightInch * settings_.device_units_per_inch());
171 } else {
172 // ulocdata_getPaperSize returns the width and height in mm.
173 // Convert this to pixels based on the dpi.
Lei Zhangd11ab162018-06-26 04:28:50174 float multiplier = settings_.device_units_per_inch() / kMicronsPerMil;
[email protected]b6f76a12013-11-14 17:29:24175 width *= multiplier;
176 height *= multiplier;
177 }
178 return gfx::Size(width, height);
179}
180
181PrintingContext::Result PrintingContextAndroid::UpdatePrinterSettings(
vitalybuka92ab8ce2014-08-26 23:41:45182 bool external_preview,
vitalybuka95fa3c92015-05-05 03:03:32183 bool show_system_dialog,
184 int page_count) {
vitalybuka92ab8ce2014-08-26 23:41:45185 DCHECK(!show_system_dialog);
[email protected]b6f76a12013-11-14 17:29:24186 DCHECK(!in_print_job_);
187
188 // Intentional No-op.
189
190 return OK;
191}
192
[email protected]b6f76a12013-11-14 17:29:24193PrintingContext::Result PrintingContextAndroid::NewDocument(
[email protected]90007a52013-12-19 23:28:07194 const base::string16& document_name) {
[email protected]b6f76a12013-11-14 17:29:24195 DCHECK(!in_print_job_);
196 in_print_job_ = true;
197
198 return OK;
199}
200
201PrintingContext::Result PrintingContextAndroid::NewPage() {
202 if (abort_printing_)
203 return CANCEL;
204 DCHECK(in_print_job_);
205
206 // Intentional No-op.
207
208 return OK;
209}
210
211PrintingContext::Result PrintingContextAndroid::PageDone() {
212 if (abort_printing_)
213 return CANCEL;
214 DCHECK(in_print_job_);
215
216 // Intentional No-op.
217
218 return OK;
219}
220
221PrintingContext::Result PrintingContextAndroid::DocumentDone() {
222 if (abort_printing_)
223 return CANCEL;
224 DCHECK(in_print_job_);
225
226 ResetSettings();
227 return OK;
228}
229
230void PrintingContextAndroid::Cancel() {
231 abort_printing_ = true;
232 in_print_job_ = false;
233}
234
235void PrintingContextAndroid::ReleaseContext() {
236 // Intentional No-op.
237}
238
Nico Weber8e559562017-10-03 01:25:26239printing::NativeDrawingContext PrintingContextAndroid::context() const {
[email protected]b6f76a12013-11-14 17:29:24240 // Intentional No-op.
thestig5f683912016-09-30 22:42:16241 return nullptr;
[email protected]b6f76a12013-11-14 17:29:24242}
243
[email protected]b6f76a12013-11-14 17:29:24244} // namespace printing