1 // 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 "android_webview/native/aw_pdf_exporter.h" 6 7 #include "android_webview/browser/renderer_host/print_manager.h" 8 #include "base/android/jni_android.h" 9 #include "base/logging.h" 10 #include "content/public/browser/browser_thread.h" 11 #include "content/public/browser/web_contents.h" 12 #include "jni/AwPdfExporter_jni.h" 13 #include "printing/print_settings.h" 14 #include "printing/units.h" 15 16 using base::android::AttachCurrentThread; 17 using base::android::ScopedJavaGlobalRef; 18 using content::BrowserThread; 19 using content::WebContents; 20 using printing::ConvertUnitDouble; 21 using printing::PageMargins; 22 using printing::PrintSettings; 23 24 namespace android_webview { 25 26 AwPdfExporter::AwPdfExporter(JNIEnv* env, 27 jobject obj, 28 WebContents* web_contents) 29 : java_ref_(env, obj), 30 web_contents_(web_contents) { 31 DCHECK(obj); 32 Java_AwPdfExporter_setNativeAwPdfExporter( 33 env, obj, reinterpret_cast<intptr_t>(this)); 34 } 35 36 AwPdfExporter::~AwPdfExporter() { 37 JNIEnv* env = AttachCurrentThread(); 38 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); 39 if (obj.is_null()) 40 return; 41 // Clear the Java peer's weak pointer to |this| object. 42 Java_AwPdfExporter_setNativeAwPdfExporter(env, obj.obj(), 0); 43 } 44 45 void AwPdfExporter::ExportToPdf(JNIEnv* env, 46 jobject obj, 47 int fd, 48 jobject cancel_signal) { 49 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 50 CreatePdfSettings(env, obj); 51 print_manager_.reset( 52 new PrintManager(web_contents_, print_settings_.get(), fd, this)); 53 if (!print_manager_->PrintNow()) 54 DidExportPdf(false); 55 } 56 57 namespace { 58 // Converts from 1/1000 of inches to device units using DPI. 59 int MilsToDots(int val, int dpi) { 60 return static_cast<int>(ConvertUnitDouble(val, 1000.0, dpi)); 61 } 62 63 } // anonymous namespace 64 65 void AwPdfExporter::CreatePdfSettings(JNIEnv* env, jobject obj) { 66 print_settings_.reset(new PrintSettings); 67 int dpi = Java_AwPdfExporter_getDpi(env, obj); 68 int width = Java_AwPdfExporter_getPageWidth(env, obj); 69 int height = Java_AwPdfExporter_getPageHeight(env, obj); 70 gfx::Size physical_size_device_units; 71 int width_in_dots = MilsToDots(width, dpi); 72 int height_in_dots = MilsToDots(height, dpi); 73 physical_size_device_units.SetSize(width_in_dots, height_in_dots); 74 75 gfx::Rect printable_area_device_units; 76 // Assume full page is printable for now. 77 printable_area_device_units.SetRect(0, 0, width_in_dots, height_in_dots); 78 79 print_settings_->set_dpi(dpi); 80 // TODO(sgurun) verify that the value for newly added parameter for 81 // (i.e. landscape_needs_flip) is correct. 82 print_settings_->SetPrinterPrintableArea(physical_size_device_units, 83 printable_area_device_units, 84 true); 85 86 PageMargins margins; 87 margins.left = 88 MilsToDots(Java_AwPdfExporter_getLeftMargin(env, obj), dpi); 89 margins.right = 90 MilsToDots(Java_AwPdfExporter_getRightMargin(env, obj), dpi); 91 margins.top = 92 MilsToDots(Java_AwPdfExporter_getTopMargin(env, obj), dpi); 93 margins.bottom = 94 MilsToDots(Java_AwPdfExporter_getBottomMargin(env, obj), dpi); 95 print_settings_->SetCustomMargins(margins); 96 print_settings_->set_should_print_backgrounds(true); 97 } 98 99 void AwPdfExporter::DidExportPdf(bool success) { 100 JNIEnv* env = AttachCurrentThread(); 101 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); 102 if (obj.is_null()) 103 return; 104 Java_AwPdfExporter_didExportPdf(env, obj.obj(), success); 105 } 106 107 bool AwPdfExporter::IsCancelled() { 108 // TODO(sgurun) implement. Needs connecting with the |cancel_signal| passed 109 // in the constructor. 110 return false; 111 } 112 113 bool RegisterAwPdfExporter(JNIEnv* env) { 114 return RegisterNativesImpl(env); 115 } 116 117 } // namespace android_webview 118