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