• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 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 "chrome/browser/ui/webui/print_preview/print_preview_ui.h"
6 
7 #include <map>
8 
9 #include "base/id_map.h"
10 #include "base/lazy_instance.h"
11 #include "base/memory/ref_counted_memory.h"
12 #include "base/metrics/histogram.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/string_split.h"
15 #include "base/strings/string_util.h"
16 #include "base/strings/utf_string_conversions.h"
17 #include "base/synchronization/lock.h"
18 #include "base/values.h"
19 #include "chrome/browser/browser_process.h"
20 #include "chrome/browser/printing/background_printing_manager.h"
21 #include "chrome/browser/printing/print_preview_data_service.h"
22 #include "chrome/browser/profiles/profile.h"
23 #include "chrome/browser/ui/webui/print_preview/print_preview_handler.h"
24 #include "chrome/browser/ui/webui/theme_source.h"
25 #include "chrome/common/print_messages.h"
26 #include "chrome/common/url_constants.h"
27 #include "content/public/browser/url_data_source.h"
28 #include "content/public/browser/web_contents.h"
29 #include "content/public/browser/web_ui_data_source.h"
30 #include "grit/browser_resources.h"
31 #include "grit/chromium_strings.h"
32 #include "grit/generated_resources.h"
33 #include "grit/google_chrome_strings.h"
34 #include "printing/page_size_margins.h"
35 #include "printing/print_job_constants.h"
36 #include "ui/base/l10n/l10n_util.h"
37 #include "ui/gfx/rect.h"
38 #include "ui/web_dialogs/web_dialog_delegate.h"
39 #include "ui/web_dialogs/web_dialog_ui.h"
40 
41 using content::WebContents;
42 using printing::PageSizeMargins;
43 
44 namespace {
45 
46 #if defined(OS_MACOSX)
47 // U+0028 U+21E7 U+2318 U+0050 U+0029 in UTF8
48 const char kAdvancedPrintShortcut[] = "\x28\xE2\x8c\xA5\xE2\x8C\x98\x50\x29";
49 #elif defined(OS_WIN) || defined(OS_CHROMEOS)
50 const char kAdvancedPrintShortcut[] = "(Ctrl+Shift+P)";
51 #else
52 const char kAdvancedPrintShortcut[] = "(Shift+Ctrl+P)";
53 #endif
54 
55 // Thread-safe wrapper around a std::map to keep track of mappings from
56 // PrintPreviewUI IDs to most recent print preview request IDs.
57 class PrintPreviewRequestIdMapWithLock {
58  public:
PrintPreviewRequestIdMapWithLock()59   PrintPreviewRequestIdMapWithLock() {}
~PrintPreviewRequestIdMapWithLock()60   ~PrintPreviewRequestIdMapWithLock() {}
61 
62   // Gets the value for |preview_id|.
63   // Returns true and sets |out_value| on success.
Get(int32 preview_id,int * out_value)64   bool Get(int32 preview_id, int* out_value) {
65     base::AutoLock lock(lock_);
66     PrintPreviewRequestIdMap::const_iterator it = map_.find(preview_id);
67     if (it == map_.end())
68       return false;
69     *out_value = it->second;
70     return true;
71   }
72 
73   // Sets the |value| for |preview_id|.
Set(int32 preview_id,int value)74   void Set(int32 preview_id, int value) {
75     base::AutoLock lock(lock_);
76     map_[preview_id] = value;
77   }
78 
79   // Erases the entry for |preview_id|.
Erase(int32 preview_id)80   void Erase(int32 preview_id) {
81     base::AutoLock lock(lock_);
82     map_.erase(preview_id);
83   }
84 
85  private:
86   // Mapping from PrintPreviewUI ID to print preview request ID.
87   typedef std::map<int, int> PrintPreviewRequestIdMap;
88 
89   PrintPreviewRequestIdMap map_;
90   base::Lock lock_;
91 
92   DISALLOW_COPY_AND_ASSIGN(PrintPreviewRequestIdMapWithLock);
93 };
94 
95 // Written to on the UI thread, read from any thread.
96 base::LazyInstance<PrintPreviewRequestIdMapWithLock>
97     g_print_preview_request_id_map = LAZY_INSTANCE_INITIALIZER;
98 
99 // PrintPreviewUI IDMap used to avoid exposing raw pointer addresses to WebUI.
100 // Only accessed on the UI thread.
101 base::LazyInstance<IDMap<PrintPreviewUI> >
102     g_print_preview_ui_id_map = LAZY_INSTANCE_INITIALIZER;
103 
104 // PrintPreviewUI serves data for chrome://print requests.
105 //
106 // The format for requesting PDF data is as follows:
107 // chrome://print/<PrintPreviewUIID>/<PageIndex>/print.pdf
108 //
109 // Parameters (< > required):
110 //    <PrintPreviewUIID> = PrintPreview UI ID
111 //    <PageIndex> = Page index is zero-based or
112 //                  |printing::COMPLETE_PREVIEW_DOCUMENT_INDEX| to represent
113 //                  a print ready PDF.
114 //
115 // Example:
116 //    chrome://print/123/10/print.pdf
117 //
118 // Requests to chrome://print with paths not ending in /print.pdf are used
119 // to return the markup or other resources for the print preview page itself.
HandleRequestCallback(const std::string & path,const content::WebUIDataSource::GotDataCallback & callback)120 bool HandleRequestCallback(
121     const std::string& path,
122     const content::WebUIDataSource::GotDataCallback& callback) {
123   // ChromeWebUIDataSource handles most requests except for the print preview
124   // data.
125   if (!EndsWith(path, "/print.pdf", true))
126     return false;
127 
128   // Print Preview data.
129   scoped_refptr<base::RefCountedBytes> data;
130   std::vector<std::string> url_substr;
131   base::SplitString(path, '/', &url_substr);
132   int preview_ui_id = -1;
133   int page_index = 0;
134   if (url_substr.size() == 3 &&
135       base::StringToInt(url_substr[0], &preview_ui_id),
136       base::StringToInt(url_substr[1], &page_index) &&
137       preview_ui_id >= 0) {
138     PrintPreviewDataService::GetInstance()->GetDataEntry(
139         preview_ui_id, page_index, &data);
140   }
141   if (data.get()) {
142     callback.Run(data.get());
143     return true;
144   }
145   // Invalid request.
146   scoped_refptr<base::RefCountedBytes> empty_bytes(new base::RefCountedBytes);
147   callback.Run(empty_bytes.get());
148   return true;
149 }
150 
CreatePrintPreviewUISource()151 content::WebUIDataSource* CreatePrintPreviewUISource() {
152   content::WebUIDataSource* source =
153       content::WebUIDataSource::Create(chrome::kChromeUIPrintHost);
154 #if defined(OS_CHROMEOS)
155   source->AddLocalizedString("title",
156                              IDS_PRINT_PREVIEW_GOOGLE_CLOUD_PRINT_TITLE);
157 #else
158   source->AddLocalizedString("title", IDS_PRINT_PREVIEW_TITLE);
159 #endif
160   source->AddLocalizedString("loading", IDS_PRINT_PREVIEW_LOADING);
161   source->AddLocalizedString("noPlugin", IDS_PRINT_PREVIEW_NO_PLUGIN);
162   source->AddLocalizedString("launchNativeDialog",
163                              IDS_PRINT_PREVIEW_NATIVE_DIALOG);
164   source->AddLocalizedString("previewFailed", IDS_PRINT_PREVIEW_FAILED);
165   source->AddLocalizedString("invalidPrinterSettings",
166                              IDS_PRINT_INVALID_PRINTER_SETTINGS);
167   source->AddLocalizedString("printButton", IDS_PRINT_PREVIEW_PRINT_BUTTON);
168   source->AddLocalizedString("saveButton", IDS_PRINT_PREVIEW_SAVE_BUTTON);
169   source->AddLocalizedString("cancelButton", IDS_PRINT_PREVIEW_CANCEL_BUTTON);
170   source->AddLocalizedString("printing", IDS_PRINT_PREVIEW_PRINTING);
171   source->AddLocalizedString("printingToPDFInProgress",
172                              IDS_PRINT_PREVIEW_PRINTING_TO_PDF_IN_PROGRESS);
173 #if defined(OS_MACOSX)
174   source->AddLocalizedString("openingPDFInPreview",
175                              IDS_PRINT_PREVIEW_OPENING_PDF_IN_PREVIEW);
176 #endif
177   source->AddLocalizedString("destinationLabel",
178                              IDS_PRINT_PREVIEW_DESTINATION_LABEL);
179   source->AddLocalizedString("copiesLabel", IDS_PRINT_PREVIEW_COPIES_LABEL);
180   source->AddLocalizedString("examplePageRangeText",
181                              IDS_PRINT_PREVIEW_EXAMPLE_PAGE_RANGE_TEXT);
182   source->AddLocalizedString("layoutLabel", IDS_PRINT_PREVIEW_LAYOUT_LABEL);
183   source->AddLocalizedString("optionAllPages",
184                              IDS_PRINT_PREVIEW_OPTION_ALL_PAGES);
185   source->AddLocalizedString("optionBw", IDS_PRINT_PREVIEW_OPTION_BW);
186   source->AddLocalizedString("optionCollate", IDS_PRINT_PREVIEW_OPTION_COLLATE);
187   source->AddLocalizedString("optionColor", IDS_PRINT_PREVIEW_OPTION_COLOR);
188   source->AddLocalizedString("optionLandscape",
189                              IDS_PRINT_PREVIEW_OPTION_LANDSCAPE);
190   source->AddLocalizedString("optionPortrait",
191                              IDS_PRINT_PREVIEW_OPTION_PORTRAIT);
192   source->AddLocalizedString("optionTwoSided",
193                              IDS_PRINT_PREVIEW_OPTION_TWO_SIDED);
194   source->AddLocalizedString("pagesLabel", IDS_PRINT_PREVIEW_PAGES_LABEL);
195   source->AddLocalizedString("pageRangeTextBox",
196                              IDS_PRINT_PREVIEW_PAGE_RANGE_TEXT);
197   source->AddLocalizedString("pageRangeRadio",
198                              IDS_PRINT_PREVIEW_PAGE_RANGE_RADIO);
199   source->AddLocalizedString("printToPDF", IDS_PRINT_PREVIEW_PRINT_TO_PDF);
200   source->AddLocalizedString("printPreviewSummaryFormatShort",
201                              IDS_PRINT_PREVIEW_SUMMARY_FORMAT_SHORT);
202   source->AddLocalizedString("printPreviewSummaryFormatLong",
203                              IDS_PRINT_PREVIEW_SUMMARY_FORMAT_LONG);
204   source->AddLocalizedString("printPreviewSheetsLabelSingular",
205                              IDS_PRINT_PREVIEW_SHEETS_LABEL_SINGULAR);
206   source->AddLocalizedString("printPreviewSheetsLabelPlural",
207                              IDS_PRINT_PREVIEW_SHEETS_LABEL_PLURAL);
208   source->AddLocalizedString("printPreviewPageLabelSingular",
209                              IDS_PRINT_PREVIEW_PAGE_LABEL_SINGULAR);
210   source->AddLocalizedString("printPreviewPageLabelPlural",
211                              IDS_PRINT_PREVIEW_PAGE_LABEL_PLURAL);
212   const base::string16 shortcut_text(base::UTF8ToUTF16(kAdvancedPrintShortcut));
213 #if defined(OS_CHROMEOS)
214   source->AddString(
215       "systemDialogOption",
216       l10n_util::GetStringFUTF16(
217           IDS_PRINT_PREVIEW_CLOUD_DIALOG_OPTION,
218           l10n_util::GetStringUTF16(IDS_GOOGLE_CLOUD_PRINT),
219           shortcut_text));
220 #else
221   source->AddString(
222       "systemDialogOption",
223       l10n_util::GetStringFUTF16(
224           IDS_PRINT_PREVIEW_SYSTEM_DIALOG_OPTION,
225           shortcut_text));
226 #endif
227   source->AddString(
228       "cloudPrintDialogOption",
229       l10n_util::GetStringFUTF16(
230           IDS_PRINT_PREVIEW_CLOUD_DIALOG_OPTION_NO_SHORTCUT,
231           l10n_util::GetStringUTF16(IDS_GOOGLE_CLOUD_PRINT)));
232 #if defined(OS_MACOSX)
233   source->AddLocalizedString("openPdfInPreviewOption",
234                              IDS_PRINT_PREVIEW_OPEN_PDF_IN_PREVIEW_APP);
235 #endif
236   source->AddString(
237       "printWithCloudPrintWait",
238       l10n_util::GetStringFUTF16(
239           IDS_PRINT_PREVIEW_PRINT_WITH_CLOUD_PRINT_WAIT,
240           l10n_util::GetStringUTF16(IDS_GOOGLE_CLOUD_PRINT)));
241   source->AddString(
242       "noDestsPromoLearnMoreUrl",
243       chrome::kCloudPrintNoDestinationsLearnMoreURL);
244   source->AddLocalizedString("pageRangeInstruction",
245                              IDS_PRINT_PREVIEW_PAGE_RANGE_INSTRUCTION);
246   source->AddLocalizedString("copiesInstruction",
247                              IDS_PRINT_PREVIEW_COPIES_INSTRUCTION);
248   source->AddLocalizedString("incrementTitle",
249                              IDS_PRINT_PREVIEW_INCREMENT_TITLE);
250   source->AddLocalizedString("decrementTitle",
251                              IDS_PRINT_PREVIEW_DECREMENT_TITLE);
252   source->AddLocalizedString("printPagesLabel",
253                              IDS_PRINT_PREVIEW_PRINT_PAGES_LABEL);
254   source->AddLocalizedString("optionsLabel", IDS_PRINT_PREVIEW_OPTIONS_LABEL);
255   source->AddLocalizedString("optionHeaderFooter",
256                              IDS_PRINT_PREVIEW_OPTION_HEADER_FOOTER);
257   source->AddLocalizedString("optionFitToPage",
258                              IDS_PRINT_PREVIEW_OPTION_FIT_TO_PAGE);
259   source->AddLocalizedString(
260       "optionBackgroundColorsAndImages",
261       IDS_PRINT_PREVIEW_OPTION_BACKGROUND_COLORS_AND_IMAGES);
262   source->AddLocalizedString("optionSelectionOnly",
263                              IDS_PRINT_PREVIEW_OPTION_SELECTION_ONLY);
264   source->AddLocalizedString("marginsLabel", IDS_PRINT_PREVIEW_MARGINS_LABEL);
265   source->AddLocalizedString("defaultMargins",
266                              IDS_PRINT_PREVIEW_DEFAULT_MARGINS);
267   source->AddLocalizedString("noMargins", IDS_PRINT_PREVIEW_NO_MARGINS);
268   source->AddLocalizedString("customMargins", IDS_PRINT_PREVIEW_CUSTOM_MARGINS);
269   source->AddLocalizedString("minimumMargins",
270                              IDS_PRINT_PREVIEW_MINIMUM_MARGINS);
271   source->AddLocalizedString("top", IDS_PRINT_PREVIEW_TOP_MARGIN_LABEL);
272   source->AddLocalizedString("bottom", IDS_PRINT_PREVIEW_BOTTOM_MARGIN_LABEL);
273   source->AddLocalizedString("left", IDS_PRINT_PREVIEW_LEFT_MARGIN_LABEL);
274   source->AddLocalizedString("right", IDS_PRINT_PREVIEW_RIGHT_MARGIN_LABEL);
275   source->AddLocalizedString("mediaSizeLabel",
276                              IDS_PRINT_PREVIEW_MEDIA_SIZE_LABEL);
277   source->AddLocalizedString("destinationSearchTitle",
278                              IDS_PRINT_PREVIEW_DESTINATION_SEARCH_TITLE);
279   source->AddLocalizedString("userInfo", IDS_PRINT_PREVIEW_USER_INFO);
280   source->AddLocalizedString("accountSelectTitle",
281                              IDS_PRINT_PREVIEW_ACCOUNT_SELECT_TITLE);
282   source->AddLocalizedString("addAccountTitle",
283                              IDS_PRINT_PREVIEW_ADD_ACCOUNT_TITLE);
284   source->AddLocalizedString("cloudPrintPromotion",
285                              IDS_PRINT_PREVIEW_CLOUD_PRINT_PROMOTION);
286   source->AddLocalizedString("searchBoxPlaceholder",
287                              IDS_PRINT_PREVIEW_SEARCH_BOX_PLACEHOLDER);
288   source->AddLocalizedString("noDestinationsMessage",
289                              IDS_PRINT_PREVIEW_NO_DESTINATIONS_MESSAGE);
290   source->AddLocalizedString("showAllButtonText",
291                              IDS_PRINT_PREVIEW_SHOW_ALL_BUTTON_TEXT);
292   source->AddLocalizedString("destinationCount",
293                              IDS_PRINT_PREVIEW_DESTINATION_COUNT);
294   source->AddLocalizedString("recentDestinationsTitle",
295                              IDS_PRINT_PREVIEW_RECENT_DESTINATIONS_TITLE);
296   source->AddLocalizedString("localDestinationsTitle",
297                              IDS_PRINT_PREVIEW_LOCAL_DESTINATIONS_TITLE);
298   source->AddLocalizedString("cloudDestinationsTitle",
299                              IDS_PRINT_PREVIEW_CLOUD_DESTINATIONS_TITLE);
300   source->AddLocalizedString("manage", IDS_PRINT_PREVIEW_MANAGE);
301   source->AddLocalizedString("setupCloudPrinters",
302                              IDS_PRINT_PREVIEW_SETUP_CLOUD_PRINTERS);
303   source->AddLocalizedString("changeDestination",
304                              IDS_PRINT_PREVIEW_CHANGE_DESTINATION);
305   source->AddLocalizedString("offlineForYear",
306                              IDS_PRINT_PREVIEW_OFFLINE_FOR_YEAR);
307   source->AddLocalizedString("offlineForMonth",
308                              IDS_PRINT_PREVIEW_OFFLINE_FOR_MONTH);
309   source->AddLocalizedString("offlineForWeek",
310                              IDS_PRINT_PREVIEW_OFFLINE_FOR_WEEK);
311   source->AddLocalizedString("offline", IDS_PRINT_PREVIEW_OFFLINE);
312   source->AddLocalizedString("fedexTos", IDS_PRINT_PREVIEW_FEDEX_TOS);
313   source->AddLocalizedString("tosCheckboxLabel",
314                              IDS_PRINT_PREVIEW_TOS_CHECKBOX_LABEL);
315   source->AddLocalizedString("noDestsPromoTitle",
316                              IDS_PRINT_PREVIEW_NO_DESTS_PROMO_TITLE);
317   source->AddLocalizedString("noDestsPromoBody",
318                              IDS_PRINT_PREVIEW_NO_DESTS_PROMO_BODY);
319   source->AddLocalizedString("noDestsPromoGcpDesc",
320                              IDS_PRINT_PREVIEW_NO_DESTS_GCP_DESC);
321   source->AddLocalizedString("learnMore",
322                              IDS_LEARN_MORE);
323   source->AddLocalizedString(
324       "noDestsPromoAddPrinterButtonLabel",
325       IDS_PRINT_PREVIEW_NO_DESTS_PROMO_ADD_PRINTER_BUTTON_LABEL);
326   source->AddLocalizedString(
327       "noDestsPromoNotNowButtonLabel",
328       IDS_PRINT_PREVIEW_NO_DESTS_PROMO_NOT_NOW_BUTTON_LABEL);
329   source->AddLocalizedString("couldNotPrint",
330                              IDS_PRINT_PREVIEW_COULD_NOT_PRINT);
331   source->AddLocalizedString("registerPromoButtonText",
332                              IDS_PRINT_PREVIEW_REGISTER_PROMO_BUTTON_TEXT);
333 
334   source->SetJsonPath("strings.js");
335   source->AddResourcePath("print_preview.js", IDR_PRINT_PREVIEW_JS);
336   source->AddResourcePath("images/printer.png",
337                           IDR_PRINT_PREVIEW_IMAGES_PRINTER);
338   source->AddResourcePath("images/printer_shared.png",
339                           IDR_PRINT_PREVIEW_IMAGES_PRINTER_SHARED);
340   source->AddResourcePath("images/third_party.png",
341                           IDR_PRINT_PREVIEW_IMAGES_THIRD_PARTY);
342   source->AddResourcePath("images/third_party_fedex.png",
343                           IDR_PRINT_PREVIEW_IMAGES_THIRD_PARTY_FEDEX);
344   source->AddResourcePath("images/google_doc.png",
345                           IDR_PRINT_PREVIEW_IMAGES_GOOGLE_DOC);
346   source->AddResourcePath("images/pdf.png", IDR_PRINT_PREVIEW_IMAGES_PDF);
347   source->AddResourcePath("images/mobile.png", IDR_PRINT_PREVIEW_IMAGES_MOBILE);
348   source->AddResourcePath("images/mobile_shared.png",
349                           IDR_PRINT_PREVIEW_IMAGES_MOBILE_SHARED);
350   source->SetDefaultResource(IDR_PRINT_PREVIEW_HTML);
351   source->SetRequestFilter(base::Bind(&HandleRequestCallback));
352   source->OverrideContentSecurityPolicyObjectSrc("object-src 'self';");
353   return source;
354 }
355 
356 PrintPreviewUI::TestingDelegate* g_testing_delegate = NULL;
357 
358 }  // namespace
359 
PrintPreviewUI(content::WebUI * web_ui)360 PrintPreviewUI::PrintPreviewUI(content::WebUI* web_ui)
361     : ConstrainedWebDialogUI(web_ui),
362       initial_preview_start_time_(base::TimeTicks::Now()),
363       id_(g_print_preview_ui_id_map.Get().Add(this)),
364       handler_(NULL),
365       source_is_modifiable_(true),
366       source_has_selection_(false),
367       dialog_closed_(false) {
368   // Set up the chrome://print/ data source.
369   Profile* profile = Profile::FromWebUI(web_ui);
370   content::WebUIDataSource::Add(profile, CreatePrintPreviewUISource());
371 
372   // Set up the chrome://theme/ source.
373   content::URLDataSource::Add(profile, new ThemeSource(profile));
374 
375   // WebUI owns |handler_|.
376   handler_ = new PrintPreviewHandler();
377   web_ui->AddMessageHandler(handler_);
378 
379   g_print_preview_request_id_map.Get().Set(id_, -1);
380 }
381 
~PrintPreviewUI()382 PrintPreviewUI::~PrintPreviewUI() {
383   print_preview_data_service()->RemoveEntry(id_);
384   g_print_preview_request_id_map.Get().Erase(id_);
385   g_print_preview_ui_id_map.Get().Remove(id_);
386 }
387 
GetPrintPreviewDataForIndex(int index,scoped_refptr<base::RefCountedBytes> * data)388 void PrintPreviewUI::GetPrintPreviewDataForIndex(
389     int index,
390     scoped_refptr<base::RefCountedBytes>* data) {
391   print_preview_data_service()->GetDataEntry(id_, index, data);
392 }
393 
SetPrintPreviewDataForIndex(int index,const base::RefCountedBytes * data)394 void PrintPreviewUI::SetPrintPreviewDataForIndex(
395     int index,
396     const base::RefCountedBytes* data) {
397   print_preview_data_service()->SetDataEntry(id_, index, data);
398 }
399 
ClearAllPreviewData()400 void PrintPreviewUI::ClearAllPreviewData() {
401   print_preview_data_service()->RemoveEntry(id_);
402 }
403 
GetAvailableDraftPageCount()404 int PrintPreviewUI::GetAvailableDraftPageCount() {
405   return print_preview_data_service()->GetAvailableDraftPageCount(id_);
406 }
407 
SetInitiatorTitle(const base::string16 & job_title)408 void PrintPreviewUI::SetInitiatorTitle(
409     const base::string16& job_title) {
410   initiator_title_ = job_title;
411 }
412 
413 // static
SetInitialParams(content::WebContents * print_preview_dialog,const PrintHostMsg_RequestPrintPreview_Params & params)414 void PrintPreviewUI::SetInitialParams(
415     content::WebContents* print_preview_dialog,
416     const PrintHostMsg_RequestPrintPreview_Params& params) {
417   if (!print_preview_dialog || !print_preview_dialog->GetWebUI())
418     return;
419   PrintPreviewUI* print_preview_ui = static_cast<PrintPreviewUI*>(
420       print_preview_dialog->GetWebUI()->GetController());
421   print_preview_ui->source_is_modifiable_ = params.is_modifiable;
422   print_preview_ui->source_has_selection_ = params.has_selection;
423   print_preview_ui->print_selection_only_ = params.selection_only;
424 }
425 
426 // static
GetCurrentPrintPreviewStatus(int32 preview_ui_id,int request_id,bool * cancel)427 void PrintPreviewUI::GetCurrentPrintPreviewStatus(int32 preview_ui_id,
428                                                   int request_id,
429                                                   bool* cancel) {
430   int current_id = -1;
431   if (!g_print_preview_request_id_map.Get().Get(preview_ui_id, &current_id)) {
432     *cancel = true;
433     return;
434   }
435   *cancel = (request_id != current_id);
436 }
437 
GetIDForPrintPreviewUI() const438 int32 PrintPreviewUI::GetIDForPrintPreviewUI() const {
439   return id_;
440 }
441 
OnPrintPreviewDialogClosed()442 void PrintPreviewUI::OnPrintPreviewDialogClosed() {
443   WebContents* preview_dialog = web_ui()->GetWebContents();
444   printing::BackgroundPrintingManager* background_printing_manager =
445       g_browser_process->background_printing_manager();
446   if (background_printing_manager->HasPrintPreviewDialog(preview_dialog))
447     return;
448   OnClosePrintPreviewDialog();
449 }
450 
OnInitiatorClosed()451 void PrintPreviewUI::OnInitiatorClosed() {
452   WebContents* preview_dialog = web_ui()->GetWebContents();
453   printing::BackgroundPrintingManager* background_printing_manager =
454       g_browser_process->background_printing_manager();
455   if (background_printing_manager->HasPrintPreviewDialog(preview_dialog))
456     web_ui()->CallJavascriptFunction("cancelPendingPrintRequest");
457   else
458     OnClosePrintPreviewDialog();
459 }
460 
OnPrintPreviewRequest(int request_id)461 void PrintPreviewUI::OnPrintPreviewRequest(int request_id) {
462   if (!initial_preview_start_time_.is_null()) {
463     UMA_HISTOGRAM_TIMES("PrintPreview.InitializationTime",
464                         base::TimeTicks::Now() - initial_preview_start_time_);
465   }
466   g_print_preview_request_id_map.Get().Set(id_, request_id);
467 }
468 
OnShowSystemDialog()469 void PrintPreviewUI::OnShowSystemDialog() {
470   web_ui()->CallJavascriptFunction("onSystemDialogLinkClicked");
471 }
472 
OnDidGetPreviewPageCount(const PrintHostMsg_DidGetPreviewPageCount_Params & params)473 void PrintPreviewUI::OnDidGetPreviewPageCount(
474     const PrintHostMsg_DidGetPreviewPageCount_Params& params) {
475   DCHECK_GT(params.page_count, 0);
476   if (g_testing_delegate)
477     g_testing_delegate->DidGetPreviewPageCount(params.page_count);
478   base::FundamentalValue count(params.page_count);
479   base::FundamentalValue request_id(params.preview_request_id);
480   web_ui()->CallJavascriptFunction("onDidGetPreviewPageCount",
481                                    count,
482                                    request_id);
483 }
484 
OnDidGetDefaultPageLayout(const PageSizeMargins & page_layout,const gfx::Rect & printable_area,bool has_custom_page_size_style)485 void PrintPreviewUI::OnDidGetDefaultPageLayout(
486     const PageSizeMargins& page_layout, const gfx::Rect& printable_area,
487     bool has_custom_page_size_style) {
488   if (page_layout.margin_top < 0 || page_layout.margin_left < 0 ||
489       page_layout.margin_bottom < 0 || page_layout.margin_right < 0 ||
490       page_layout.content_width < 0 || page_layout.content_height < 0 ||
491       printable_area.width() <= 0 || printable_area.height() <= 0) {
492     NOTREACHED();
493     return;
494   }
495 
496   base::DictionaryValue layout;
497   layout.SetDouble(printing::kSettingMarginTop, page_layout.margin_top);
498   layout.SetDouble(printing::kSettingMarginLeft, page_layout.margin_left);
499   layout.SetDouble(printing::kSettingMarginBottom, page_layout.margin_bottom);
500   layout.SetDouble(printing::kSettingMarginRight, page_layout.margin_right);
501   layout.SetDouble(printing::kSettingContentWidth, page_layout.content_width);
502   layout.SetDouble(printing::kSettingContentHeight, page_layout.content_height);
503   layout.SetInteger(printing::kSettingPrintableAreaX, printable_area.x());
504   layout.SetInteger(printing::kSettingPrintableAreaY, printable_area.y());
505   layout.SetInteger(printing::kSettingPrintableAreaWidth,
506                     printable_area.width());
507   layout.SetInteger(printing::kSettingPrintableAreaHeight,
508                     printable_area.height());
509 
510   base::FundamentalValue has_page_size_style(has_custom_page_size_style);
511   web_ui()->CallJavascriptFunction("onDidGetDefaultPageLayout", layout,
512                                    has_page_size_style);
513 }
514 
OnDidPreviewPage(int page_number,int preview_request_id)515 void PrintPreviewUI::OnDidPreviewPage(int page_number,
516                                       int preview_request_id) {
517   DCHECK_GE(page_number, 0);
518   base::FundamentalValue number(page_number);
519   base::FundamentalValue ui_identifier(id_);
520   base::FundamentalValue request_id(preview_request_id);
521   if (g_testing_delegate)
522     g_testing_delegate->DidRenderPreviewPage(web_ui()->GetWebContents());
523   web_ui()->CallJavascriptFunction(
524       "onDidPreviewPage", number, ui_identifier, request_id);
525   if (g_testing_delegate && g_testing_delegate->IsAutoCancelEnabled())
526     web_ui()->CallJavascriptFunction("autoCancelForTesting");
527 }
528 
OnPreviewDataIsAvailable(int expected_pages_count,int preview_request_id)529 void PrintPreviewUI::OnPreviewDataIsAvailable(int expected_pages_count,
530                                               int preview_request_id) {
531   VLOG(1) << "Print preview request finished with "
532           << expected_pages_count << " pages";
533 
534   if (!initial_preview_start_time_.is_null()) {
535     UMA_HISTOGRAM_TIMES("PrintPreview.InitialDisplayTime",
536                         base::TimeTicks::Now() - initial_preview_start_time_);
537     UMA_HISTOGRAM_COUNTS("PrintPreview.PageCount.Initial",
538                          expected_pages_count);
539     UMA_HISTOGRAM_COUNTS(
540         "PrintPreview.RegeneratePreviewRequest.BeforeFirstData",
541         handler_->regenerate_preview_request_count());
542     initial_preview_start_time_ = base::TimeTicks();
543   }
544   base::FundamentalValue ui_identifier(id_);
545   base::FundamentalValue ui_preview_request_id(preview_request_id);
546   web_ui()->CallJavascriptFunction("updatePrintPreview", ui_identifier,
547                                    ui_preview_request_id);
548 }
549 
OnPrintPreviewDialogDestroyed()550 void PrintPreviewUI::OnPrintPreviewDialogDestroyed() {
551   handler_->OnPrintPreviewDialogDestroyed();
552 }
553 
OnFileSelectionCancelled()554 void PrintPreviewUI::OnFileSelectionCancelled() {
555   web_ui()->CallJavascriptFunction("fileSelectionCancelled");
556 }
557 
OnCancelPendingPreviewRequest()558 void PrintPreviewUI::OnCancelPendingPreviewRequest() {
559   g_print_preview_request_id_map.Get().Set(id_, -1);
560 }
561 
OnPrintPreviewFailed()562 void PrintPreviewUI::OnPrintPreviewFailed() {
563   handler_->OnPrintPreviewFailed();
564   web_ui()->CallJavascriptFunction("printPreviewFailed");
565 }
566 
OnInvalidPrinterSettings()567 void PrintPreviewUI::OnInvalidPrinterSettings() {
568   web_ui()->CallJavascriptFunction("invalidPrinterSettings");
569 }
570 
print_preview_data_service()571 PrintPreviewDataService* PrintPreviewUI::print_preview_data_service() {
572   return PrintPreviewDataService::GetInstance();
573 }
574 
OnHidePreviewDialog()575 void PrintPreviewUI::OnHidePreviewDialog() {
576   WebContents* preview_dialog = web_ui()->GetWebContents();
577   printing::BackgroundPrintingManager* background_printing_manager =
578       g_browser_process->background_printing_manager();
579   if (background_printing_manager->HasPrintPreviewDialog(preview_dialog))
580     return;
581 
582   ConstrainedWebDialogDelegate* delegate = GetConstrainedDelegate();
583   if (!delegate)
584     return;
585   delegate->ReleaseWebContentsOnDialogClose();
586   background_printing_manager->OwnPrintPreviewDialog(preview_dialog);
587   OnClosePrintPreviewDialog();
588 }
589 
OnClosePrintPreviewDialog()590 void PrintPreviewUI::OnClosePrintPreviewDialog() {
591   if (dialog_closed_)
592     return;
593   dialog_closed_ = true;
594   ConstrainedWebDialogDelegate* delegate = GetConstrainedDelegate();
595   if (!delegate)
596     return;
597   delegate->GetWebDialogDelegate()->OnDialogClosed(std::string());
598   delegate->OnDialogCloseFromWebUI();
599 }
600 
OnReloadPrintersList()601 void PrintPreviewUI::OnReloadPrintersList() {
602   web_ui()->CallJavascriptFunction("reloadPrintersList");
603 }
604 
OnPrintPreviewScalingDisabled()605 void PrintPreviewUI::OnPrintPreviewScalingDisabled() {
606   web_ui()->CallJavascriptFunction("printScalingDisabledForSourcePDF");
607 }
608 
609 // static
SetDelegateForTesting(TestingDelegate * delegate)610 void PrintPreviewUI::SetDelegateForTesting(TestingDelegate* delegate) {
611   g_testing_delegate = delegate;
612 }
613