Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / resources / print_preview / native_layer.js
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 cr.exportPath('print_preview');
6
7 /**
8  * @typedef {{selectSaveAsPdfDestination: boolean,
9  *            layoutSettings.portrait: boolean,
10  *            pageRange: string,
11  *            headersAndFooters: boolean,
12  *            backgroundColorsAndImages: boolean,
13  *            margins: number}}
14  * @see chrome/browser/printing/print_preview_pdf_generated_browsertest.cc
15  */
16 print_preview.PreviewSettings;
17
18 cr.define('print_preview', function() {
19   'use strict';
20
21   /**
22    * An interface to the native Chromium printing system layer.
23    * @constructor
24    * @extends {cr.EventTarget}
25    */
26   function NativeLayer() {
27     cr.EventTarget.call(this);
28
29     // Bind global handlers
30     global.setInitialSettings = this.onSetInitialSettings_.bind(this);
31     global.setUseCloudPrint = this.onSetUseCloudPrint_.bind(this);
32     global.setPrinters = this.onSetPrinters_.bind(this);
33     global.updateWithPrinterCapabilities =
34         this.onUpdateWithPrinterCapabilities_.bind(this);
35     global.failedToGetPrinterCapabilities =
36         this.onFailedToGetPrinterCapabilities_.bind(this);
37     global.failedToGetPrivetPrinterCapabilities =
38       this.onFailedToGetPrivetPrinterCapabilities_.bind(this);
39     global.reloadPrintersList = this.onReloadPrintersList_.bind(this);
40     global.printToCloud = this.onPrintToCloud_.bind(this);
41     global.fileSelectionCancelled =
42         this.onFileSelectionCancelled_.bind(this);
43     global.fileSelectionCompleted =
44         this.onFileSelectionCompleted_.bind(this);
45     global.printPreviewFailed = this.onPrintPreviewFailed_.bind(this);
46     global.invalidPrinterSettings =
47         this.onInvalidPrinterSettings_.bind(this);
48     global.onDidGetDefaultPageLayout =
49         this.onDidGetDefaultPageLayout_.bind(this);
50     global.onDidGetPreviewPageCount =
51         this.onDidGetPreviewPageCount_.bind(this);
52     global.onDidPreviewPage = this.onDidPreviewPage_.bind(this);
53     global.updatePrintPreview = this.onUpdatePrintPreview_.bind(this);
54     global.printScalingDisabledForSourcePDF =
55         this.onPrintScalingDisabledForSourcePDF_.bind(this);
56     global.onDidGetAccessToken = this.onDidGetAccessToken_.bind(this);
57     global.autoCancelForTesting = this.autoCancelForTesting_.bind(this);
58     global.onPrivetPrinterChanged = this.onPrivetPrinterChanged_.bind(this);
59     global.onPrivetCapabilitiesSet =
60         this.onPrivetCapabilitiesSet_.bind(this);
61     global.onPrivetPrintFailed = this.onPrivetPrintFailed_.bind(this);
62     global.onEnableManipulateSettingsForTest =
63         this.onEnableManipulateSettingsForTest_.bind(this);
64   };
65
66   /**
67    * Event types dispatched from the Chromium native layer.
68    * @enum {string}
69    * @const
70    */
71   NativeLayer.EventType = {
72     ACCESS_TOKEN_READY: 'print_preview.NativeLayer.ACCESS_TOKEN_READY',
73     CAPABILITIES_SET: 'print_preview.NativeLayer.CAPABILITIES_SET',
74     CLOUD_PRINT_ENABLE: 'print_preview.NativeLayer.CLOUD_PRINT_ENABLE',
75     DESTINATIONS_RELOAD: 'print_preview.NativeLayer.DESTINATIONS_RELOAD',
76     DISABLE_SCALING: 'print_preview.NativeLayer.DISABLE_SCALING',
77     FILE_SELECTION_CANCEL: 'print_preview.NativeLayer.FILE_SELECTION_CANCEL',
78     FILE_SELECTION_COMPLETE:
79         'print_preview.NativeLayer.FILE_SELECTION_COMPLETE',
80     GET_CAPABILITIES_FAIL: 'print_preview.NativeLayer.GET_CAPABILITIES_FAIL',
81     INITIAL_SETTINGS_SET: 'print_preview.NativeLayer.INITIAL_SETTINGS_SET',
82     LOCAL_DESTINATIONS_SET: 'print_preview.NativeLayer.LOCAL_DESTINATIONS_SET',
83     MANIPULATE_SETTINGS_FOR_TEST:
84         'print_preview.NativeLayer.MANIPULATE_SETTINGS_FOR_TEST',
85     PAGE_COUNT_READY: 'print_preview.NativeLayer.PAGE_COUNT_READY',
86     PAGE_LAYOUT_READY: 'print_preview.NativeLayer.PAGE_LAYOUT_READY',
87     PAGE_PREVIEW_READY: 'print_preview.NativeLayer.PAGE_PREVIEW_READY',
88     PREVIEW_GENERATION_DONE:
89         'print_preview.NativeLayer.PREVIEW_GENERATION_DONE',
90     PREVIEW_GENERATION_FAIL:
91         'print_preview.NativeLayer.PREVIEW_GENERATION_FAIL',
92     PRINT_TO_CLOUD: 'print_preview.NativeLayer.PRINT_TO_CLOUD',
93     SETTINGS_INVALID: 'print_preview.NativeLayer.SETTINGS_INVALID',
94     PRIVET_PRINTER_CHANGED: 'print_preview.NativeLayer.PRIVET_PRINTER_CHANGED',
95     PRIVET_CAPABILITIES_SET:
96         'print_preview.NativeLayer.PRIVET_CAPABILITIES_SET',
97     PRIVET_PRINT_FAILED: 'print_preview.NativeLayer.PRIVET_PRINT_FAILED',
98   };
99
100   /**
101    * Constant values matching printing::DuplexMode enum.
102    * @enum {number}
103    */
104   NativeLayer.DuplexMode = {
105     SIMPLEX: 0,
106     LONG_EDGE: 1,
107     UNKNOWN_DUPLEX_MODE: -1
108   };
109
110   /**
111    * Enumeration of color modes used by Chromium.
112    * @enum {number}
113    * @private
114    */
115   NativeLayer.ColorMode_ = {
116     GRAY: 1,
117     COLOR: 2
118   };
119
120   /**
121    * Version of the serialized state of the print preview.
122    * @type {number}
123    * @const
124    * @private
125    */
126   NativeLayer.SERIALIZED_STATE_VERSION_ = 1;
127
128   NativeLayer.prototype = {
129     __proto__: cr.EventTarget.prototype,
130
131     /**
132      * Requests access token for cloud print requests.
133      * @param {string} authType type of access token.
134      */
135     startGetAccessToken: function(authType) {
136       chrome.send('getAccessToken', [authType]);
137     },
138
139     /** Gets the initial settings to initialize the print preview with. */
140     startGetInitialSettings: function() {
141       chrome.send('getInitialSettings');
142     },
143
144     /**
145      * Requests the system's local print destinations. A LOCAL_DESTINATIONS_SET
146      * event will be dispatched in response.
147      */
148     startGetLocalDestinations: function() {
149       chrome.send('getPrinters');
150     },
151
152     /**
153      * Requests the network's privet print destinations. A number of
154      * PRIVET_PRINTER_CHANGED events will be fired in response, followed by a
155      * PRIVET_SEARCH_ENDED.
156      */
157     startGetPrivetDestinations: function() {
158       chrome.send('getPrivetPrinters');
159     },
160
161     /**
162      * Requests that the privet print stack stop searching for privet print
163      * destinations.
164      */
165     stopGetPrivetDestinations: function() {
166       chrome.send('stopGetPrivetPrinters');
167     },
168
169     /**
170      * Requests the privet destination's printing capabilities. A
171      * PRIVET_CAPABILITIES_SET event will be dispatched in response.
172      * @param {string} destinationId ID of the destination.
173      */
174     startGetPrivetDestinationCapabilities: function(destinationId) {
175       chrome.send('getPrivetPrinterCapabilities', [destinationId]);
176     },
177
178     /**
179      * Requests the destination's printing capabilities. A CAPABILITIES_SET
180      * event will be dispatched in response.
181      * @param {string} destinationId ID of the destination.
182      */
183     startGetLocalDestinationCapabilities: function(destinationId) {
184       chrome.send('getPrinterCapabilities', [destinationId]);
185     },
186
187     /**
188      * @param {!print_preview.Destination} destination Destination to print to.
189      * @param {!print_preview.ticket_items.Color} color Color ticket item.
190      * @return {number} Native layer color model.
191      * @private
192      */
193     getNativeColorModel_: function(destination, color) {
194       // For non-local printers native color model is ignored anyway.
195       var option = destination.isLocal ? color.getSelectedOption() : null;
196       var nativeColorModel = parseInt(option ? option.vendor_id : null, 10);
197       if (isNaN(nativeColorModel)) {
198         return color.getValue() ?
199             NativeLayer.ColorMode_.COLOR : NativeLayer.ColorMode_.GRAY;
200       }
201       return nativeColorModel;
202     },
203
204     /**
205      * Requests that a preview be generated. The following events may be
206      * dispatched in response:
207      *   - PAGE_COUNT_READY
208      *   - PAGE_LAYOUT_READY
209      *   - PAGE_PREVIEW_READY
210      *   - PREVIEW_GENERATION_DONE
211      *   - PREVIEW_GENERATION_FAIL
212      * @param {print_preview.Destination} destination Destination to print to.
213      * @param {!print_preview.PrintTicketStore} printTicketStore Used to get the
214      *     state of the print ticket.
215      * @param {!print_preview.DocumentInfo} documentInfo Document data model.
216      * @param {number} requestId ID of the preview request.
217      */
218     startGetPreview: function(
219         destination, printTicketStore, documentInfo, requestId) {
220       assert(printTicketStore.isTicketValidForPreview(),
221              'Trying to generate preview when ticket is not valid');
222
223       var ticket = {
224         'pageRange': printTicketStore.pageRange.getDocumentPageRanges(),
225         'mediaSize': printTicketStore.mediaSize.getValue(),
226         'landscape': printTicketStore.landscape.getValue(),
227         'color': this.getNativeColorModel_(destination, printTicketStore.color),
228         'headerFooterEnabled': printTicketStore.headerFooter.getValue(),
229         'marginsType': printTicketStore.marginsType.getValue(),
230         'isFirstRequest': requestId == 0,
231         'requestID': requestId,
232         'previewModifiable': documentInfo.isModifiable,
233         'printToPDF':
234             destination != null &&
235             destination.id ==
236                 print_preview.Destination.GooglePromotedId.SAVE_AS_PDF,
237         'printWithCloudPrint': destination != null && !destination.isLocal,
238         'printWithPrivet': destination != null && destination.isPrivet,
239         'deviceName': destination == null ? 'foo' : destination.id,
240         'generateDraftData': documentInfo.isModifiable,
241         'fitToPageEnabled': printTicketStore.fitToPage.getValue(),
242
243         // NOTE: Even though the following fields don't directly relate to the
244         // preview, they still need to be included.
245         'duplex': printTicketStore.duplex.getValue() ?
246             NativeLayer.DuplexMode.LONG_EDGE : NativeLayer.DuplexMode.SIMPLEX,
247         'copies': 1,
248         'collate': true,
249         'shouldPrintBackgrounds': printTicketStore.cssBackground.getValue(),
250         'shouldPrintSelectionOnly': printTicketStore.selectionOnly.getValue()
251       };
252
253       // Set 'cloudPrintID' only if the destination is not local.
254       if (destination && !destination.isLocal) {
255         ticket['cloudPrintID'] = destination.id;
256       }
257
258       if (printTicketStore.marginsType.isCapabilityAvailable() &&
259           printTicketStore.marginsType.getValue() ==
260               print_preview.ticket_items.MarginsType.Value.CUSTOM) {
261         var customMargins = printTicketStore.customMargins.getValue();
262         var orientationEnum =
263             print_preview.ticket_items.CustomMargins.Orientation;
264         ticket['marginsCustom'] = {
265           'marginTop': customMargins.get(orientationEnum.TOP),
266           'marginRight': customMargins.get(orientationEnum.RIGHT),
267           'marginBottom': customMargins.get(orientationEnum.BOTTOM),
268           'marginLeft': customMargins.get(orientationEnum.LEFT)
269         };
270       }
271
272       chrome.send(
273           'getPreview',
274           [JSON.stringify(ticket),
275            requestId > 0 ? documentInfo.pageCount : -1,
276            documentInfo.isModifiable]);
277     },
278
279     /**
280      * Requests that the document be printed.
281      * @param {!print_preview.Destination} destination Destination to print to.
282      * @param {!print_preview.PrintTicketStore} printTicketStore Used to get the
283      *     state of the print ticket.
284      * @param {cloudprint.CloudPrintInterface} cloudPrintInterface Interface
285      *     to Google Cloud Print.
286      * @param {!print_preview.DocumentInfo} documentInfo Document data model.
287      * @param {boolean=} opt_isOpenPdfInPreview Whether to open the PDF in the
288      *     system's preview application.
289      * @param {boolean=} opt_showSystemDialog Whether to open system dialog for
290      *     advanced settings.
291      */
292     startPrint: function(destination, printTicketStore, cloudPrintInterface,
293                          documentInfo, opt_isOpenPdfInPreview,
294                          opt_showSystemDialog) {
295       assert(printTicketStore.isTicketValid(),
296              'Trying to print when ticket is not valid');
297
298       assert(!opt_showSystemDialog || (cr.isWindows && destination.isLocal),
299              'Implemented for Windows only');
300
301       var ticket = {
302         'pageRange': printTicketStore.pageRange.getDocumentPageRanges(),
303         'mediaSize': printTicketStore.mediaSize.getValue(),
304         'pageCount': printTicketStore.pageRange.getPageNumberSet().size,
305         'landscape': printTicketStore.landscape.getValue(),
306         'color': this.getNativeColorModel_(destination, printTicketStore.color),
307         'headerFooterEnabled': printTicketStore.headerFooter.getValue(),
308         'marginsType': printTicketStore.marginsType.getValue(),
309         'generateDraftData': true, // TODO(rltoscano): What should this be?
310         'duplex': printTicketStore.duplex.getValue() ?
311             NativeLayer.DuplexMode.LONG_EDGE : NativeLayer.DuplexMode.SIMPLEX,
312         'copies': printTicketStore.copies.getValueAsNumber(),
313         'collate': printTicketStore.collate.getValue(),
314         'shouldPrintBackgrounds': printTicketStore.cssBackground.getValue(),
315         'shouldPrintSelectionOnly': printTicketStore.selectionOnly.getValue(),
316         'previewModifiable': documentInfo.isModifiable,
317         'printToPDF': destination.id ==
318             print_preview.Destination.GooglePromotedId.SAVE_AS_PDF,
319         'printWithCloudPrint': !destination.isLocal,
320         'printWithPrivet': destination.isPrivet,
321         'deviceName': destination.id,
322         'isFirstRequest': false,
323         'requestID': -1,
324         'fitToPageEnabled': printTicketStore.fitToPage.getValue(),
325         'pageWidth': documentInfo.pageSize.width,
326         'pageHeight': documentInfo.pageSize.height,
327         'showSystemDialog': opt_showSystemDialog
328       };
329
330       if (!destination.isLocal) {
331         // We can't set cloudPrintID if the destination is "Print with Cloud
332         // Print" because the native system will try to print to Google Cloud
333         // Print with this ID instead of opening a Google Cloud Print dialog.
334         ticket['cloudPrintID'] = destination.id;
335       }
336
337       if (printTicketStore.marginsType.isCapabilityAvailable() &&
338           printTicketStore.marginsType.isValueEqual(
339               print_preview.ticket_items.MarginsType.Value.CUSTOM)) {
340         var customMargins = printTicketStore.customMargins.getValue();
341         var orientationEnum =
342             print_preview.ticket_items.CustomMargins.Orientation;
343         ticket['marginsCustom'] = {
344           'marginTop': customMargins.get(orientationEnum.TOP),
345           'marginRight': customMargins.get(orientationEnum.RIGHT),
346           'marginBottom': customMargins.get(orientationEnum.BOTTOM),
347           'marginLeft': customMargins.get(orientationEnum.LEFT)
348         };
349       }
350
351       if (destination.isPrivet) {
352         ticket['ticket'] = printTicketStore.createPrintTicket(destination);
353         ticket['capabilities'] = JSON.stringify(destination.capabilities);
354       }
355
356       if (opt_isOpenPdfInPreview) {
357         ticket['OpenPDFInPreview'] = true;
358       }
359
360       chrome.send('print', [JSON.stringify(ticket)]);
361     },
362
363     /** Requests that the current pending print request be cancelled. */
364     startCancelPendingPrint: function() {
365       chrome.send('cancelPendingPrintRequest');
366     },
367
368     /** Shows the system's native printing dialog. */
369     startShowSystemDialog: function() {
370       assert(!cr.isWindows);
371       chrome.send('showSystemDialog');
372     },
373
374     /** Closes the print preview dialog. */
375     startCloseDialog: function() {
376       chrome.send('closePrintPreviewDialog');
377       chrome.send('dialogClose');
378     },
379
380     /** Hide the print preview dialog and allow the native layer to close it. */
381     startHideDialog: function() {
382       chrome.send('hidePreview');
383     },
384
385     /**
386      * Opens the Google Cloud Print sign-in tab. The DESTINATIONS_RELOAD event
387      *     will be dispatched in response.
388      * @param {boolean} addAccount Whether to open an 'add a new account' or
389      *     default sign in page.
390      */
391     startCloudPrintSignIn: function(addAccount) {
392       chrome.send('signIn', [addAccount]);
393     },
394
395     /** Navigates the user to the system printer settings interface. */
396     startManageLocalDestinations: function() {
397       chrome.send('manageLocalPrinters');
398     },
399
400     /** Navigates the user to the Google Cloud Print management page. */
401     startManageCloudDestinations: function() {
402       chrome.send('manageCloudPrinters');
403     },
404
405     /** Forces browser to open a new tab with the given URL address. */
406     startForceOpenNewTab: function(url) {
407       chrome.send('forceOpenNewTab', [url]);
408     },
409
410     /**
411      * @param {!Object} initialSettings Object containing all initial settings.
412      */
413     onSetInitialSettings_: function(initialSettings) {
414       var numberFormatSymbols =
415           print_preview.MeasurementSystem.parseNumberFormat(
416               initialSettings['numberFormat']);
417       var unitType = print_preview.MeasurementSystem.UnitType.IMPERIAL;
418       if (initialSettings['measurementSystem'] != null) {
419         unitType = initialSettings['measurementSystem'];
420       }
421
422       var nativeInitialSettings = new print_preview.NativeInitialSettings(
423           initialSettings['printAutomaticallyInKioskMode'] || false,
424           initialSettings['appKioskMode'] || false,
425           initialSettings['hidePrintWithSystemDialogLink'] || false,
426           numberFormatSymbols[0] || ',',
427           numberFormatSymbols[1] || '.',
428           unitType,
429           initialSettings['previewModifiable'] || false,
430           initialSettings['initiatorTitle'] || '',
431           initialSettings['documentHasSelection'] || false,
432           initialSettings['shouldPrintSelectionOnly'] || false,
433           initialSettings['printerName'] || null,
434           initialSettings['appState'] || null);
435
436       var initialSettingsSetEvent = new Event(
437           NativeLayer.EventType.INITIAL_SETTINGS_SET);
438       initialSettingsSetEvent.initialSettings = nativeInitialSettings;
439       this.dispatchEvent(initialSettingsSetEvent);
440     },
441
442     /**
443      * Turn on the integration of Cloud Print.
444      * @param {{cloudPrintURL: string, appKioskMode: string}} settings
445      *     cloudPrintUrl: The URL to use for cloud print servers.
446      * @private
447      */
448     onSetUseCloudPrint_: function(settings) {
449       var cloudPrintEnableEvent = new Event(
450           NativeLayer.EventType.CLOUD_PRINT_ENABLE);
451       cloudPrintEnableEvent.baseCloudPrintUrl = settings['cloudPrintUrl'] || '';
452       cloudPrintEnableEvent.appKioskMode = settings['appKioskMode'] || false;
453       this.dispatchEvent(cloudPrintEnableEvent);
454     },
455
456     /**
457      * Updates the print preview with local printers.
458      * Called from PrintPreviewHandler::SetupPrinterList().
459      * @param {Array} printers Array of printer info objects.
460      * @private
461      */
462     onSetPrinters_: function(printers) {
463       var localDestsSetEvent = new Event(
464           NativeLayer.EventType.LOCAL_DESTINATIONS_SET);
465       localDestsSetEvent.destinationInfos = printers;
466       this.dispatchEvent(localDestsSetEvent);
467     },
468
469     /**
470      * Called when native layer gets settings information for a requested local
471      * destination.
472      * @param {Object} settingsInfo printer setting information.
473      * @private
474      */
475     onUpdateWithPrinterCapabilities_: function(settingsInfo) {
476       var capsSetEvent = new Event(NativeLayer.EventType.CAPABILITIES_SET);
477       capsSetEvent.settingsInfo = settingsInfo;
478       this.dispatchEvent(capsSetEvent);
479     },
480
481     /**
482      * Called when native layer gets settings information for a requested local
483      * destination.
484      * @param {string} destinationId Printer affected by error.
485      * @private
486      */
487     onFailedToGetPrinterCapabilities_: function(destinationId) {
488       var getCapsFailEvent = new Event(
489           NativeLayer.EventType.GET_CAPABILITIES_FAIL);
490       getCapsFailEvent.destinationId = destinationId;
491       getCapsFailEvent.destinationOrigin =
492           print_preview.Destination.Origin.LOCAL;
493       this.dispatchEvent(getCapsFailEvent);
494     },
495
496     /**
497      * Called when native layer gets settings information for a requested privet
498      * destination.
499      * @param {string} destinationId Printer affected by error.
500      * @private
501      */
502     onFailedToGetPrivetPrinterCapabilities_: function(destinationId) {
503       var getCapsFailEvent = new Event(
504           NativeLayer.EventType.GET_CAPABILITIES_FAIL);
505       getCapsFailEvent.destinationId = destinationId;
506       getCapsFailEvent.destinationOrigin =
507           print_preview.Destination.Origin.PRIVET;
508       this.dispatchEvent(getCapsFailEvent);
509     },
510
511     /** Reloads the printer list. */
512     onReloadPrintersList_: function() {
513       cr.dispatchSimpleEvent(this, NativeLayer.EventType.DESTINATIONS_RELOAD);
514     },
515
516     /**
517      * Called from the C++ layer.
518      * Take the PDF data handed to us and submit it to the cloud, closing the
519      * print preview dialog once the upload is successful.
520      * @param {string} data Data to send as the print job.
521      * @private
522      */
523     onPrintToCloud_: function(data) {
524       var printToCloudEvent = new Event(
525           NativeLayer.EventType.PRINT_TO_CLOUD);
526       printToCloudEvent.data = data;
527       this.dispatchEvent(printToCloudEvent);
528     },
529
530     /**
531      * Called from PrintPreviewUI::OnFileSelectionCancelled to notify the print
532      * preview dialog regarding the file selection cancel event.
533      * @private
534      */
535     onFileSelectionCancelled_: function() {
536       cr.dispatchSimpleEvent(this, NativeLayer.EventType.FILE_SELECTION_CANCEL);
537     },
538
539     /**
540      * Called from PrintPreviewUI::OnFileSelectionCompleted to notify the print
541      * preview dialog regarding the file selection completed event.
542      * @private
543      */
544     onFileSelectionCompleted_: function() {
545       // If the file selection is completed and the dialog is not already closed
546       // it means that a pending print to pdf request exists.
547       cr.dispatchSimpleEvent(
548           this, NativeLayer.EventType.FILE_SELECTION_COMPLETE);
549     },
550
551     /**
552      * Display an error message when print preview fails.
553      * Called from PrintPreviewMessageHandler::OnPrintPreviewFailed().
554      * @private
555      */
556     onPrintPreviewFailed_: function() {
557       cr.dispatchSimpleEvent(
558           this, NativeLayer.EventType.PREVIEW_GENERATION_FAIL);
559     },
560
561     /**
562      * Display an error message when encountered invalid printer settings.
563      * Called from PrintPreviewMessageHandler::OnInvalidPrinterSettings().
564      * @private
565      */
566     onInvalidPrinterSettings_: function() {
567       cr.dispatchSimpleEvent(this, NativeLayer.EventType.SETTINGS_INVALID);
568     },
569
570     /**
571      * @param {{contentWidth: number, contentHeight: number, marginLeft: number,
572      *          marginRight: number, marginTop: number, marginBottom: number,
573      *          printableAreaX: number, printableAreaY: number,
574      *          printableAreaWidth: number, printableAreaHeight: number}}
575      *          pageLayout Specifies default page layout details in points.
576      * @param {boolean} hasCustomPageSizeStyle Indicates whether the previewed
577      *     document has a custom page size style.
578      * @private
579      */
580     onDidGetDefaultPageLayout_: function(pageLayout, hasCustomPageSizeStyle) {
581       var pageLayoutChangeEvent = new Event(
582           NativeLayer.EventType.PAGE_LAYOUT_READY);
583       pageLayoutChangeEvent.pageLayout = pageLayout;
584       pageLayoutChangeEvent.hasCustomPageSizeStyle = hasCustomPageSizeStyle;
585       this.dispatchEvent(pageLayoutChangeEvent);
586     },
587
588     /**
589      * Update the page count and check the page range.
590      * Called from PrintPreviewUI::OnDidGetPreviewPageCount().
591      * @param {number} pageCount The number of pages.
592      * @param {number} previewResponseId The preview request id that resulted in
593      *      this response.
594      * @private
595      */
596     onDidGetPreviewPageCount_: function(pageCount, previewResponseId) {
597       var pageCountChangeEvent = new Event(
598           NativeLayer.EventType.PAGE_COUNT_READY);
599       pageCountChangeEvent.pageCount = pageCount;
600       pageCountChangeEvent.previewResponseId = previewResponseId;
601       this.dispatchEvent(pageCountChangeEvent);
602     },
603
604     /**
605      * Notification that a print preview page has been rendered.
606      * Check if the settings have changed and request a regeneration if needed.
607      * Called from PrintPreviewUI::OnDidPreviewPage().
608      * @param {number} pageNumber The page number, 0-based.
609      * @param {number} previewUid Preview unique identifier.
610      * @param {number} previewResponseId The preview request id that resulted in
611      *     this response.
612      * @private
613      */
614     onDidPreviewPage_: function(pageNumber, previewUid, previewResponseId) {
615       var pagePreviewGenEvent = new Event(
616           NativeLayer.EventType.PAGE_PREVIEW_READY);
617       pagePreviewGenEvent.pageIndex = pageNumber;
618       pagePreviewGenEvent.previewUid = previewUid;
619       pagePreviewGenEvent.previewResponseId = previewResponseId;
620       this.dispatchEvent(pagePreviewGenEvent);
621     },
622
623     /**
624      * Notification that access token is ready.
625      * @param {string} authType Type of access token.
626      * @param {string} accessToken Access token.
627      * @private
628      */
629     onDidGetAccessToken_: function(authType, accessToken) {
630       var getAccessTokenEvent = new Event(
631           NativeLayer.EventType.ACCESS_TOKEN_READY);
632       getAccessTokenEvent.authType = authType;
633       getAccessTokenEvent.accessToken = accessToken;
634       this.dispatchEvent(getAccessTokenEvent);
635     },
636
637     /**
638      * Update the print preview when new preview data is available.
639      * Create the PDF plugin as needed.
640      * Called from PrintPreviewUI::PreviewDataIsAvailable().
641      * @param {number} previewUid Preview unique identifier.
642      * @param {number} previewResponseId The preview request id that resulted in
643      *     this response.
644      * @private
645      */
646     onUpdatePrintPreview_: function(previewUid, previewResponseId) {
647       var previewGenDoneEvent = new Event(
648           NativeLayer.EventType.PREVIEW_GENERATION_DONE);
649       previewGenDoneEvent.previewUid = previewUid;
650       previewGenDoneEvent.previewResponseId = previewResponseId;
651       this.dispatchEvent(previewGenDoneEvent);
652     },
653
654     /**
655      * Updates the fit to page option state based on the print scaling option of
656      * source pdf. PDF's have an option to enable/disable print scaling. When we
657      * find out that the print scaling option is disabled for the source pdf, we
658      * uncheck the fitToPage_ to page checkbox. This function is called from C++
659      * code.
660      * @private
661      */
662     onPrintScalingDisabledForSourcePDF_: function() {
663       cr.dispatchSimpleEvent(this, NativeLayer.EventType.DISABLE_SCALING);
664     },
665
666     /**
667      * Simulates a user click on the print preview dialog cancel button. Used
668      * only for testing.
669      * @private
670      */
671     autoCancelForTesting_: function() {
672       var properties = {view: window, bubbles: true, cancelable: true};
673       var click = new MouseEvent('click', properties);
674       document.querySelector('#print-header .cancel').dispatchEvent(click);
675     },
676
677     /**
678      * @param {{serviceName: string, name: string}} printer Specifies
679      *     information about the printer that was added.
680      * @private
681      */
682     onPrivetPrinterChanged_: function(printer) {
683       var privetPrinterChangedEvent =
684             new Event(NativeLayer.EventType.PRIVET_PRINTER_CHANGED);
685       privetPrinterChangedEvent.printer = printer;
686       this.dispatchEvent(privetPrinterChangedEvent);
687     },
688
689     /**
690      * @param {Object} printer Specifies information about the printer that was
691      *    added.
692      * @private
693      */
694     onPrivetCapabilitiesSet_: function(printer, capabilities) {
695       var privetCapabilitiesSetEvent =
696             new Event(NativeLayer.EventType.PRIVET_CAPABILITIES_SET);
697       privetCapabilitiesSetEvent.printer = printer;
698       privetCapabilitiesSetEvent.capabilities = capabilities;
699       this.dispatchEvent(privetCapabilitiesSetEvent);
700     },
701
702     /**
703      * @param {string} http_error The HTTP response code or -1 if not an HTTP
704      *    error.
705      * @private
706      */
707     onPrivetPrintFailed_: function(http_error) {
708       var privetPrintFailedEvent =
709             new Event(NativeLayer.EventType.PRIVET_PRINT_FAILED);
710       privetPrintFailedEvent.httpError = http_error;
711       this.dispatchEvent(privetPrintFailedEvent);
712     },
713
714     /**
715      * Allows for onManipulateSettings to be called
716      * from the native layer.
717      * @private
718      */
719     onEnableManipulateSettingsForTest_: function() {
720       global.onManipulateSettingsForTest =
721           this.onManipulateSettingsForTest_.bind(this);
722     },
723
724     /**
725      * Dispatches an event to print_preview.js to change
726      * a particular setting for print preview.
727      * @param {!print_preview.PreviewSettings} settings Object containing the
728      *     value to be changed and that value should be set to.
729      * @private
730      */
731     onManipulateSettingsForTest_: function(settings) {
732       var manipulateSettingsEvent =
733           new Event(NativeLayer.EventType.MANIPULATE_SETTINGS_FOR_TEST);
734       manipulateSettingsEvent.settings = settings;
735       this.dispatchEvent(manipulateSettingsEvent);
736     },
737
738     /**
739      * Sends a message to the test, letting it know that an
740      * option has been set to a particular value and that the change has
741      * finished modifying the preview area.
742      */
743     previewReadyForTest: function() {
744       if (global.onManipulateSettingsForTest)
745         chrome.send('UILoadedForTest');
746     },
747
748     /**
749      * Notifies the test that the option it tried to change
750      * had not been changed successfully.
751      */
752     previewFailedForTest: function() {
753       if (global.onManipulateSettingsForTest)
754         chrome.send('UIFailedLoadingForTest');
755     }
756   };
757
758   /**
759    * Initial settings retrieved from the native layer.
760    * @param {boolean} isInKioskAutoPrintMode Whether the print preview should be
761    *     in auto-print mode.
762    * @param {boolean} isInAppKioskMode Whether the print preview is in App Kiosk
763    *     mode.
764    * @param {string} thousandsDelimeter Character delimeter of thousands digits.
765    * @param {string} decimalDelimeter Character delimeter of the decimal point.
766    * @param {!print_preview.MeasurementSystem.UnitType} unitType Unit type of
767    *     local machine's measurement system.
768    * @param {boolean} isDocumentModifiable Whether the document to print is
769    *     modifiable.
770    * @param {string} documentTitle Title of the document.
771    * @param {boolean} documentHasSelection Whether the document has selected
772    *     content.
773    * @param {boolean} selectionOnly Whether only selected content should be
774    *     printed.
775    * @param {?string} systemDefaultDestinationId ID of the system default
776    *     destination.
777    * @param {?string} serializedAppStateStr Serialized app state.
778    * @constructor
779    */
780   function NativeInitialSettings(
781       isInKioskAutoPrintMode,
782       isInAppKioskMode,
783       hidePrintWithSystemDialogLink,
784       thousandsDelimeter,
785       decimalDelimeter,
786       unitType,
787       isDocumentModifiable,
788       documentTitle,
789       documentHasSelection,
790       selectionOnly,
791       systemDefaultDestinationId,
792       serializedAppStateStr) {
793
794     /**
795      * Whether the print preview should be in auto-print mode.
796      * @type {boolean}
797      * @private
798      */
799     this.isInKioskAutoPrintMode_ = isInKioskAutoPrintMode;
800
801     /**
802      * Whether the print preview should switch to App Kiosk mode.
803      * @type {boolean}
804      * @private
805      */
806     this.isInAppKioskMode_ = isInAppKioskMode;
807
808     /**
809      * Whether we should hide the link which shows the system print dialog.
810      * @type {boolean}
811      * @private
812      */
813     this.hidePrintWithSystemDialogLink_ = hidePrintWithSystemDialogLink;
814
815     /**
816      * Character delimeter of thousands digits.
817      * @type {string}
818      * @private
819      */
820     this.thousandsDelimeter_ = thousandsDelimeter;
821
822     /**
823      * Character delimeter of the decimal point.
824      * @type {string}
825      * @private
826      */
827     this.decimalDelimeter_ = decimalDelimeter;
828
829     /**
830      * Unit type of local machine's measurement system.
831      * @type {string}
832      * @private
833      */
834     this.unitType_ = unitType;
835
836     /**
837      * Whether the document to print is modifiable.
838      * @type {boolean}
839      * @private
840      */
841     this.isDocumentModifiable_ = isDocumentModifiable;
842
843     /**
844      * Title of the document.
845      * @type {string}
846      * @private
847      */
848     this.documentTitle_ = documentTitle;
849
850     /**
851      * Whether the document has selection.
852      * @type {string}
853      * @private
854      */
855     this.documentHasSelection_ = documentHasSelection;
856
857     /**
858      * Whether selection only should be printed.
859      * @type {string}
860      * @private
861      */
862     this.selectionOnly_ = selectionOnly;
863
864     /**
865      * ID of the system default destination.
866      * @type {?string}
867      * @private
868      */
869     this.systemDefaultDestinationId_ = systemDefaultDestinationId;
870
871     /**
872      * Serialized app state.
873      * @type {?string}
874      * @private
875      */
876     this.serializedAppStateStr_ = serializedAppStateStr;
877   };
878
879   NativeInitialSettings.prototype = {
880     /**
881      * @return {boolean} Whether the print preview should be in auto-print mode.
882      */
883     get isInKioskAutoPrintMode() {
884       return this.isInKioskAutoPrintMode_;
885     },
886
887     /**
888      * @return {boolean} Whether the print preview should switch to App Kiosk
889      *     mode.
890      */
891     get isInAppKioskMode() {
892       return this.isInAppKioskMode_;
893     },
894
895     /**
896      * @return {boolean} Whether we should hide the link which shows the
897            system print dialog.
898      */
899     get hidePrintWithSystemDialogLink() {
900       return this.hidePrintWithSystemDialogLink_;
901     },
902
903     /** @return {string} Character delimeter of thousands digits. */
904     get thousandsDelimeter() {
905       return this.thousandsDelimeter_;
906     },
907
908     /** @return {string} Character delimeter of the decimal point. */
909     get decimalDelimeter() {
910       return this.decimalDelimeter_;
911     },
912
913     /**
914      * @return {!print_preview.MeasurementSystem.UnitType} Unit type of local
915      *     machine's measurement system.
916      */
917     get unitType() {
918       return this.unitType_;
919     },
920
921     /** @return {boolean} Whether the document to print is modifiable. */
922     get isDocumentModifiable() {
923       return this.isDocumentModifiable_;
924     },
925
926     /** @return {string} Document title. */
927     get documentTitle() {
928       return this.documentTitle_;
929     },
930
931     /** @return {boolean} Whether the document has selection. */
932     get documentHasSelection() {
933       return this.documentHasSelection_;
934     },
935
936     /** @return {boolean} Whether selection only should be printed. */
937     get selectionOnly() {
938       return this.selectionOnly_;
939     },
940
941     /** @return {?string} ID of the system default destination. */
942     get systemDefaultDestinationId() {
943       return this.systemDefaultDestinationId_;
944     },
945
946     /** @return {?string} Serialized app state. */
947     get serializedAppStateStr() {
948       return this.serializedAppStateStr_;
949     }
950   };
951
952   // Export
953   return {
954     NativeInitialSettings: NativeInitialSettings,
955     NativeLayer: NativeLayer
956   };
957 });