// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "android_webview/browser/aw_pdf_exporter.h" #include #include #include #include "android_webview/browser/aw_print_manager.h" #include "android_webview/browser_jni_headers/AwPdfExporter_jni.h" #include "base/android/jni_android.h" #include "base/android/jni_array.h" #include "base/bind.h" #include "content/public/browser/browser_thread.h" #include "printing/print_settings.h" #include "printing/units.h" using base::android::JavaParamRef; using base::android::JavaRef; using base::android::ScopedJavaLocalRef; namespace android_webview { namespace { void JNI_AwPdfExporter_GetPageRanges(JNIEnv* env, const JavaRef& int_arr, printing::PageRanges* range_vector) { std::vector pages; base::android::JavaIntArrayToIntVector(env, int_arr, &pages); for (int page : pages) { printing::PageRange range; range.from = page; range.to = page; range_vector->push_back(range); } } } // namespace AwPdfExporter::AwPdfExporter(JNIEnv* env, const JavaRef& obj, content::WebContents* web_contents) : java_ref_(env, obj), web_contents_(web_contents) { DCHECK(obj); Java_AwPdfExporter_setNativeAwPdfExporter(env, obj, reinterpret_cast(this)); } AwPdfExporter::~AwPdfExporter() { JNIEnv* env = base::android::AttachCurrentThread(); ScopedJavaLocalRef obj = java_ref_.get(env); if (!obj) return; // Clear the Java peer's weak pointer to |this| object. Java_AwPdfExporter_setNativeAwPdfExporter(env, obj, 0); } void AwPdfExporter::ExportToPdf(JNIEnv* env, const JavaParamRef& obj, int fd, const JavaParamRef& pages, const JavaParamRef& cancel_signal) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); printing::PageRanges page_ranges; JNI_AwPdfExporter_GetPageRanges(env, pages, &page_ranges); // Create an AwPrintManager for the provided WebContents if the // AwPrintManager doesn't exist. if (!AwPrintManager::FromWebContents(web_contents_)) AwPrintManager::CreateForWebContents(web_contents_); // Update the parameters of the current print manager. AwPrintManager* print_manager = AwPrintManager::FromWebContents(web_contents_); print_manager->UpdateParam(CreatePdfSettings(env, obj, page_ranges), fd, base::BindRepeating(&AwPdfExporter::DidExportPdf, base::Unretained(this))); if (!print_manager->PrintNow()) DidExportPdf(0); } namespace { // Converts from 1/1000 of inches to device units using DPI. int MilsToDots(int val, int dpi) { return static_cast(printing::ConvertUnitFloat(val, 1000, dpi)); } } // namespace std::unique_ptr AwPdfExporter::CreatePdfSettings( JNIEnv* env, const JavaRef& obj, const printing::PageRanges& page_ranges) { auto settings = std::make_unique(); int dpi = Java_AwPdfExporter_getDpi(env, obj); int width = Java_AwPdfExporter_getPageWidth(env, obj); int height = Java_AwPdfExporter_getPageHeight(env, obj); gfx::Size physical_size_device_units; int width_in_dots = MilsToDots(width, dpi); int height_in_dots = MilsToDots(height, dpi); physical_size_device_units.SetSize(width_in_dots, height_in_dots); gfx::Rect printable_area_device_units; // Assume full page is printable for now. printable_area_device_units.SetRect(0, 0, width_in_dots, height_in_dots); if (!page_ranges.empty()) settings->set_ranges(page_ranges); settings->set_dpi(dpi); // TODO(sgurun) verify that the value for newly added parameter for // (i.e. landscape_needs_flip) is correct. settings->SetPrinterPrintableArea(physical_size_device_units, printable_area_device_units, true); printing::PageMargins margins; margins.left = MilsToDots(Java_AwPdfExporter_getLeftMargin(env, obj), dpi); margins.right = MilsToDots(Java_AwPdfExporter_getRightMargin(env, obj), dpi); margins.top = MilsToDots(Java_AwPdfExporter_getTopMargin(env, obj), dpi); margins.bottom = MilsToDots(Java_AwPdfExporter_getBottomMargin(env, obj), dpi); settings->SetCustomMargins(margins); settings->set_should_print_backgrounds(true); return settings; } void AwPdfExporter::DidExportPdf(int page_count) { JNIEnv* env = base::android::AttachCurrentThread(); ScopedJavaLocalRef obj = java_ref_.get(env); if (!obj) return; Java_AwPdfExporter_didExportPdf(env, obj, page_count); } } // namespace android_webview