| // Copyright (c) 2012 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. |
| |
| #ifndef CHROME_BROWSER_UI_WEBUI_PRINT_PREVIEW_PRINT_PREVIEW_UI_H_ |
| #define CHROME_BROWSER_UI_WEBUI_PRINT_PREVIEW_PRINT_PREVIEW_UI_H_ |
| |
| #include <stdint.h> |
| |
| #include <memory> |
| #include <string> |
| #include <vector> |
| |
| #include "base/callback_forward.h" |
| #include "base/gtest_prod_util.h" |
| #include "base/macros.h" |
| #include "base/memory/read_only_shared_memory_region.h" |
| #include "base/memory/ref_counted.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/optional.h" |
| #include "base/time/time.h" |
| #include "chrome/browser/ui/webui/constrained_web_dialog_ui.h" |
| #include "chrome/services/printing/public/mojom/pdf_nup_converter.mojom.h" |
| #include "components/printing/common/print.mojom.h" |
| #include "components/services/print_compositor/public/mojom/print_compositor.mojom.h" |
| #include "mojo/public/cpp/bindings/associated_receiver.h" |
| #include "printing/mojom/print.mojom-forward.h" |
| #include "ui/gfx/geometry/rect.h" |
| #include "ui/gfx/geometry/size.h" |
| |
| namespace base { |
| class DictionaryValue; |
| class FilePath; |
| class RefCountedMemory; |
| } |
| |
| namespace printing { |
| |
| class PrintPreviewHandler; |
| |
| class PrintPreviewUI : public ConstrainedWebDialogUI, |
| public mojom::PrintPreviewUI { |
| public: |
| explicit PrintPreviewUI(content::WebUI* web_ui); |
| |
| ~PrintPreviewUI() override; |
| |
| mojo::PendingAssociatedRemote<mojom::PrintPreviewUI> BindPrintPreviewUI(); |
| |
| // Gets the print preview |data|. |index| is zero-based, and can be |
| // |COMPLETE_PREVIEW_DOCUMENT_INDEX| to get the entire preview document. |
| virtual void GetPrintPreviewDataForIndex( |
| int index, |
| scoped_refptr<base::RefCountedMemory>* data) const; |
| |
| // printing::mojo::PrintPreviewUI: |
| void SetOptionsFromDocument(const mojom::OptionsFromDocumentParamsPtr params, |
| int32_t request_id) override; |
| void DidPrepareDocumentForPreview(int32_t document_cookie, |
| int32_t request_id) override; |
| void DidPreviewPage(mojom::DidPreviewPageParamsPtr params, |
| int32_t request_id) override; |
| void MetafileReadyForPrinting(mojom::DidPreviewDocumentParamsPtr params, |
| int32_t request_id) override; |
| void PrintPreviewFailed(int32_t document_cookie, int32_t request_id) override; |
| void PrintPreviewCancelled(int32_t document_cookie, |
| int32_t request_id) override; |
| void PrinterSettingsInvalid(int32_t document_cookie, |
| int32_t request_id) override; |
| void DidGetDefaultPageLayout(mojom::PageSizeMarginsPtr page_layout_in_points, |
| const gfx::Rect& printable_area_in_points, |
| bool has_custom_page_size_style, |
| int32_t request_id) override; |
| void DidStartPreview(mojom::DidStartPreviewParamsPtr params, |
| int32_t request_id) override; |
| |
| bool IsBound() const; |
| |
| // Setters |
| void SetInitiatorTitle(const std::u16string& initiator_title); |
| |
| const std::u16string& initiator_title() const { return initiator_title_; } |
| |
| bool source_is_arc() const { return source_is_arc_; } |
| |
| bool source_is_modifiable() const { return source_is_modifiable_; } |
| |
| bool source_is_pdf() const { return source_is_pdf_; } |
| |
| bool source_has_selection() const { return source_has_selection_; } |
| |
| bool print_selection_only() const { return print_selection_only_; } |
| |
| int pages_per_sheet() const { return pages_per_sheet_; } |
| |
| const gfx::Rect& printable_area() const { return printable_area_; } |
| |
| const gfx::Size& page_size() const { return page_size_; } |
| |
| PrintPreviewHandler* handler() const { return handler_; } |
| |
| // Returns true if |page_number| is the last page in |pages_to_render_|. |
| // |page_number| is a 0-based number. |
| bool LastPageComposited(uint32_t page_number) const; |
| |
| // Get the 0-based index of the |page_number| in |pages_to_render_|. |
| // Same as above, |page_number| is a 0-based number. |
| uint32_t GetPageToNupConvertIndex(uint32_t page_number) const; |
| |
| std::vector<base::ReadOnlySharedMemoryRegion> TakePagesForNupConvert(); |
| |
| // Save pdf pages temporarily before ready to do N-up conversion. |
| void AddPdfPageForNupConversion(base::ReadOnlySharedMemoryRegion pdf_page); |
| |
| // PrintPreviewUI serves data for chrome://print requests. |
| // |
| // The format for requesting PDF data is as follows: |
| // chrome://print/<PrintPreviewUIID>/<PageIndex>/print.pdf |
| // |
| // Required parameters: |
| // <PrintPreviewUIID> = PrintPreview UI ID |
| // <PageIndex> = Page index is zero-based or |
| // |COMPLETE_PREVIEW_DOCUMENT_INDEX| to represent |
| // a print ready PDF. |
| // |
| // Example: |
| // chrome://print/123/10/print.pdf |
| // |
| // ParseDataPath() takes a path (i.e. what comes after chrome://print/) and |
| // returns true if the path seems to be a valid data path. |ui_id| and |
| // |page_index| are set to the parsed values if the provided pointers aren't |
| // nullptr. |
| static bool ParseDataPath(const std::string& path, |
| int* ui_id, |
| int* page_index); |
| |
| // Set initial settings for PrintPreviewUI. |
| static void SetInitialParams(content::WebContents* print_preview_dialog, |
| const mojom::RequestPrintPreviewParams& params); |
| |
| // Determines whether to cancel a print preview request based on the request |
| // id. |
| // Can be called from any thread. |
| static bool ShouldCancelRequest(const base::Optional<int32_t>& preview_ui_id, |
| int request_id); |
| |
| // Returns an id to uniquely identify this PrintPreviewUI. |
| base::Optional<int32_t> GetIDForPrintPreviewUI() const; |
| |
| // Notifies the Web UI of a print preview request with |request_id|. |
| virtual void OnPrintPreviewRequest(int request_id); |
| |
| // Notifies the Web UI that the 0-based page |page_number| rendering is being |
| // processed and an OnPendingPreviewPage() call is imminent. Returns whether |
| // |page_number| is the expected page. |
| bool OnPendingPreviewPage(uint32_t page_number); |
| |
| // Notifies the Web UI that the print preview failed to render for the request |
| // with id = |request_id|. |
| void OnPrintPreviewFailed(int request_id); |
| |
| // Notified the Web UI that this print preview dialog's RenderProcess has been |
| // closed, which may occur for several reasons, e.g. tab closure or crash. |
| void OnPrintPreviewDialogClosed(); |
| |
| // Notifies the Web UI that initiator is closed, so we can disable all the |
| // controls that need the initiator for generating the preview data. |
| void OnInitiatorClosed(); |
| |
| // Notifies the Web UI to cancel the pending preview request. |
| virtual void OnCancelPendingPreviewRequest(); |
| |
| // Hides the print preview dialog. |
| virtual void OnHidePreviewDialog(); |
| |
| // Closes the print preview dialog. |
| virtual void OnClosePrintPreviewDialog(); |
| |
| // Allows tests to wait until the print preview dialog is loaded. |
| class TestDelegate { |
| public: |
| virtual void DidGetPreviewPageCount(uint32_t page_count) = 0; |
| virtual void DidRenderPreviewPage(content::WebContents* preview_dialog) = 0; |
| |
| protected: |
| virtual ~TestDelegate() = default; |
| }; |
| |
| static void SetDelegateForTesting(TestDelegate* delegate); |
| |
| // Allows for tests to set a file path to print a PDF to. This also initiates |
| // the printing without having to click a button on the print preview dialog. |
| void SetSelectedFileForTesting(const base::FilePath& path); |
| |
| // Passes |closure| to PrintPreviewHandler::SetPdfSavedClosureForTesting(). |
| void SetPdfSavedClosureForTesting(base::OnceClosure closure); |
| |
| // Tell the handler to send the enable-manipulate-settings-for-test WebUI |
| // event. |
| void SendEnableManipulateSettingsForTest(); |
| |
| // Tell the handler to send the manipulate-settings-for-test WebUI event |
| // to set the print preview settings contained in |settings|. |
| void SendManipulateSettingsForTest(const base::DictionaryValue& settings); |
| |
| // See SetPrintPreviewDataForIndex(). |
| void SetPrintPreviewDataForIndexForTest( |
| int index, |
| scoped_refptr<base::RefCountedMemory> data); |
| |
| // See ClearAllPreviewData(). |
| void ClearAllPreviewDataForTest(); |
| |
| // Sets a new valid Print Preview UI ID for this instance. Called by |
| // PrintPreviewHandler in OnJavascriptAllowed(). |
| void SetPreviewUIId(); |
| |
| // Clears the UI ID. Called by PrintPreviewHandler in |
| // OnJavascriptDisallowed(). |
| void ClearPreviewUIId(); |
| |
| protected: |
| // Alternate constructor for tests |
| PrintPreviewUI(content::WebUI* web_ui, |
| std::unique_ptr<PrintPreviewHandler> handler); |
| |
| private: |
| FRIEND_TEST_ALL_PREFIXES(PrintPreviewDialogControllerUnitTest, |
| TitleAfterReload); |
| |
| // Sets the print preview |data|. |index| is zero-based, and can be |
| // |COMPLETE_PREVIEW_DOCUMENT_INDEX| to set the entire preview document. |
| void SetPrintPreviewDataForIndex(int index, |
| scoped_refptr<base::RefCountedMemory> data); |
| |
| // Clear the existing print preview data. |
| void ClearAllPreviewData(); |
| |
| // Notifies the Web UI that the 0-based page |page_number| has been rendered. |
| // |request_id| indicates which request resulted in this response. |
| void NotifyUIPreviewPageReady( |
| uint32_t page_number, |
| int request_id, |
| scoped_refptr<base::RefCountedMemory> data_bytes); |
| |
| // Notifies the Web UI renderer that preview data is available. |request_id| |
| // indicates which request resulted in this response. |
| void NotifyUIPreviewDocumentReady( |
| int request_id, |
| scoped_refptr<base::RefCountedMemory> data_bytes); |
| |
| // Callbacks for print compositor client. |
| void OnPrepareForDocumentToPdfDone(int32_t request_id, |
| mojom::PrintCompositor::Status status); |
| void OnCompositePdfPageDone(uint32_t page_number, |
| int32_t document_cookie, |
| int32_t request_id, |
| mojom::PrintCompositor::Status status, |
| base::ReadOnlySharedMemoryRegion region); |
| void OnNupPdfConvertDone(uint32_t page_number, |
| int32_t request_id, |
| mojom::PdfNupConverter::Status status, |
| base::ReadOnlySharedMemoryRegion region); |
| void OnNupPdfDocumentConvertDone(int32_t request_id, |
| mojom::PdfNupConverter::Status status, |
| base::ReadOnlySharedMemoryRegion region); |
| void OnCompositeToPdfDone(int document_cookie, |
| int32_t request_id, |
| mojom::PrintCompositor::Status status, |
| base::ReadOnlySharedMemoryRegion region); |
| |
| base::TimeTicks initial_preview_start_time_; |
| |
| // The unique ID for this class instance. Stored here to avoid calling |
| // GetIDForPrintPreviewUI() everywhere. |
| base::Optional<int32_t> id_; |
| |
| // Weak pointer to the WebUI handler. |
| PrintPreviewHandler* const handler_; |
| |
| // Indicates whether the source document is from ARC. |
| bool source_is_arc_ = false; |
| |
| // Indicates whether the source document can be modified. |
| bool source_is_modifiable_ = true; |
| |
| // Indicates whether the source document is a PDF. |
| bool source_is_pdf_ = false; |
| |
| // Indicates whether the source document has selection. |
| bool source_has_selection_ = false; |
| |
| // Indicates whether only the selection should be printed. |
| bool print_selection_only_ = false; |
| |
| // Keeps track of whether OnClosePrintPreviewDialog() has been called or not. |
| bool dialog_closed_ = false; |
| |
| // Store the initiator title, used for populating the print preview dialog |
| // title. |
| std::u16string initiator_title_; |
| |
| // The list of 0-based page numbers that will be rendered. |
| std::vector<uint32_t> pages_to_render_; |
| |
| // The list of pages to be converted. |
| std::vector<base::ReadOnlySharedMemoryRegion> pages_for_nup_convert_; |
| |
| // Index into |pages_to_render_| for the page number to expect. |
| size_t pages_to_render_index_ = 0; |
| |
| // number of pages per sheet and should be greater or equal to 1. |
| int pages_per_sheet_ = 1; |
| |
| // Physical size of the page, including non-printable margins. |
| gfx::Size page_size_; |
| |
| // The printable area of the printed document pages. |
| gfx::Rect printable_area_; |
| |
| mojo::AssociatedReceiver<mojom::PrintPreviewUI> receiver_{this}; |
| |
| base::WeakPtrFactory<PrintPreviewUI> weak_ptr_factory_{this}; |
| |
| DISALLOW_COPY_AND_ASSIGN(PrintPreviewUI); |
| }; |
| |
| } // namespace printing |
| |
| #endif // CHROME_BROWSER_UI_WEBUI_PRINT_PREVIEW_PRINT_PREVIEW_UI_H_ |