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