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
5package org.chromium.android_webview;
6
7import android.os.CancellationSignal;
8import android.os.ParcelFileDescriptor;
9import android.util.Log;
10import android.view.ViewGroup;
11import android.webkit.ValueCallback;
12
13import java.io.OutputStream;
14
15import org.chromium.base.CalledByNative;
16import org.chromium.base.JNINamespace;
17
18/**
19 * Export the android webview as a PDF.
20 * @TODO(sgurun) explain the ownership of this class and its native counterpart
21 */
22@JNINamespace("android_webview")
23public class AwPdfExporter {
24
25    private static final String TAG = "AwPdfExporter";
26    private int mNativeAwPdfExporter;
27    // TODO(sgurun) result callback should return an int/object indicating errors.
28    // potential errors: invalid print parameters, already pending, IO error
29    private ValueCallback<Boolean> mResultCallback;
30    private AwPdfExportAttributes mAttributes;
31    private ParcelFileDescriptor mFd;
32    // Maintain a reference to the top level object (i.e. WebView) since in a common
33    // use case (offscreen webview) application may expect the framework's print manager
34    // to own the Webview (via PrintDocumentAdapter).
35    private final ViewGroup mContainerView;
36
37    AwPdfExporter(ViewGroup containerView) {
38        mContainerView = containerView;
39    }
40
41    public void exportToPdf(final ParcelFileDescriptor fd, AwPdfExportAttributes attributes,
42            ValueCallback<Boolean> resultCallback, CancellationSignal cancellationSignal) {
43
44        if (fd == null) {
45            throw new IllegalArgumentException("fd cannot be null");
46        }
47        if (resultCallback == null) {
48            throw new IllegalArgumentException("resultCallback cannot be null");
49        }
50        if (mResultCallback != null) {
51            throw new IllegalStateException("printing is already pending");
52        }
53        if (mNativeAwPdfExporter == 0) {
54            resultCallback.onReceiveValue(false);
55            return;
56        }
57        mResultCallback = resultCallback;
58        mAttributes = attributes;
59        mFd = fd;
60        nativeExportToPdf(mNativeAwPdfExporter, mFd.getFd(), cancellationSignal);
61    }
62
63    @CalledByNative
64    private void setNativeAwPdfExporter(int nativePdfExporter) {
65        mNativeAwPdfExporter = nativePdfExporter;
66        // Handle the cornercase that Webview.Destroy is called before the native side
67        // has a chance to complete the pdf exporting.
68        if (nativePdfExporter == 0 && mResultCallback != null) {
69            mResultCallback.onReceiveValue(false);
70            mResultCallback = null;
71        }
72    }
73
74    @CalledByNative
75    private void didExportPdf(boolean success) {
76        mResultCallback.onReceiveValue(success);
77        mResultCallback = null;
78        mAttributes = null;
79        // The caller should close the file.
80        mFd = null;
81    }
82
83    @CalledByNative
84    private int getPageWidth() {
85        return mAttributes.pageWidth;
86    }
87
88    @CalledByNative
89    private int getPageHeight() {
90        return mAttributes.pageHeight;
91    }
92
93    @CalledByNative
94    private int getDpi() {
95        return mAttributes.dpi;
96    }
97
98    @CalledByNative
99    private int getLeftMargin() {
100        return mAttributes.leftMargin;
101    }
102
103    @CalledByNative
104    private int getRightMargin() {
105        return mAttributes.rightMargin;
106    }
107
108    @CalledByNative
109    private int getTopMargin() {
110        return mAttributes.topMargin;
111    }
112
113    @CalledByNative
114    private int getBottomMargin() {
115        return mAttributes.bottomMargin;
116    }
117
118    private native void nativeExportToPdf(int nativeAwPdfExporter, int fd,
119            CancellationSignal cancellationSignal);
120}
121