Home | History | Annotate | Download | only in printing
      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 #ifndef CHROME_BROWSER_PRINTING_PRINT_DIALOG_CLOUD_INTERNAL_H_
      6 #define CHROME_BROWSER_PRINTING_PRINT_DIALOG_CLOUD_INTERNAL_H_
      7 
      8 #include <string>
      9 #include <vector>
     10 
     11 #include "base/callback.h"
     12 #include "base/files/file_path.h"
     13 #include "base/memory/scoped_ptr.h"
     14 #include "base/synchronization/lock.h"
     15 #include "content/public/browser/notification_observer.h"
     16 #include "content/public/browser/notification_registrar.h"
     17 #include "content/public/browser/web_ui_message_handler.h"
     18 #include "ui/web_dialogs/web_dialog_delegate.h"
     19 #include "ui/web_dialogs/web_dialog_ui.h"
     20 
     21 class GURL;
     22 class CloudPrintWebDialogDelegateTest;
     23 
     24 namespace base {
     25 class ListValue;
     26 class StringValue;
     27 class Value;
     28 }
     29 
     30 namespace internal_cloud_print_helpers {
     31 
     32 // Small class to virtualize a few functions to aid with unit testing.
     33 class CloudPrintDataSenderHelper {
     34  public:
     35   explicit CloudPrintDataSenderHelper(content::WebUI* web_ui)
     36       : web_ui_(web_ui) {}
     37   virtual ~CloudPrintDataSenderHelper() {}
     38 
     39   // Virtualize the overrides of these three functions from WebUI to
     40   // facilitate unit testing.
     41   virtual void CallJavascriptFunction(const std::wstring& function_name);
     42   virtual void CallJavascriptFunction(const std::wstring& function_name,
     43                                       const base::Value& arg);
     44   virtual void CallJavascriptFunction(const std::wstring& function_name,
     45                                       const base::Value& arg1,
     46                                       const base::Value& arg2);
     47   virtual void CallJavascriptFunction(const std::wstring& function_name,
     48                                       const base::Value& arg1,
     49                                       const base::Value& arg2,
     50                                       const base::Value& arg3);
     51 
     52  private:
     53   content::WebUI* web_ui_;
     54 
     55   DISALLOW_COPY_AND_ASSIGN(CloudPrintDataSenderHelper);
     56 };
     57 
     58 // Small helper class to get the print data loaded in from the PDF
     59 // file (on the FILE thread) and send it to the print dialog contents
     60 // (on the IO thread), allowing for cancellation.
     61 class CloudPrintDataSender
     62     : public base::RefCountedThreadSafe<CloudPrintDataSender> {
     63  public:
     64   // The owner of this object is also expected to own and control the
     65   // lifetime of the helper.
     66   CloudPrintDataSender(CloudPrintDataSenderHelper* helper,
     67                        const string16& print_job_title,
     68                        const string16& print_ticket,
     69                        const std::string& file_type,
     70                        const base::RefCountedMemory* data);
     71 
     72   // Send print data (on the IO thread).  We know that the WebUI pointer
     73   // lifetime will outlast us, so we should be good.
     74   void SendPrintData();
     75 
     76   // Cancels any ramining part of the task by clearing out the WebUI
     77   // helper_ ptr.
     78   void CancelPrintDataFile();
     79 
     80  private:
     81   friend class base::RefCountedThreadSafe<CloudPrintDataSender>;
     82   virtual ~CloudPrintDataSender();
     83 
     84   base::Lock lock_;
     85   CloudPrintDataSenderHelper* volatile helper_;
     86   string16 print_job_title_;
     87   string16 print_ticket_;
     88   std::string file_type_;
     89   scoped_refptr<const base::RefCountedMemory> data_;
     90 
     91   DISALLOW_COPY_AND_ASSIGN(CloudPrintDataSender);
     92 };
     93 
     94 class CloudPrintWebDialogDelegate;
     95 
     96 // The CloudPrintFlowHandler connects the state machine (the UI delegate)
     97 // to the dialog backing HTML and JS by providing WebUIMessageHandler
     98 // functions for the JS to use.  This include refreshing the page
     99 // setup parameters (which will cause a re-generation of the PDF in
    100 // the renderer process - do we want a progress throbber shown?
    101 // Probably..), and packing up the PDF and job parameters and sending
    102 // them to the cloud.
    103 class CloudPrintFlowHandler : public content::WebUIMessageHandler,
    104                               public content::NotificationObserver {
    105  public:
    106   CloudPrintFlowHandler(const base::RefCountedMemory* data,
    107                         const string16& print_job_title,
    108                         const string16& print_ticket,
    109                         const std::string& file_type,
    110                         bool close_after_signin,
    111                         const base::Closure& callback);
    112   virtual ~CloudPrintFlowHandler();
    113 
    114   // WebUIMessageHandler implementation.
    115   virtual void RegisterMessages() OVERRIDE;
    116 
    117   // content::NotificationObserver implementation.
    118   virtual void Observe(int type,
    119                        const content::NotificationSource& source,
    120                        const content::NotificationDetails& details) OVERRIDE;
    121 
    122   // Callbacks from the page.
    123   void HandleShowDebugger(const base::ListValue* args);
    124   void HandleSendPrintData(const base::ListValue* args);
    125   void HandleSetPageParameters(const base::ListValue* args);
    126 
    127   virtual void SetDialogDelegate(CloudPrintWebDialogDelegate *delegate);
    128   void StoreDialogClientSize() const;
    129 
    130   bool NavigationToURLDidCloseDialog(const GURL& url);
    131 
    132  private:
    133   virtual scoped_refptr<CloudPrintDataSender> CreateCloudPrintDataSender();
    134 
    135   // Call to get the debugger loaded on our hosted dialog page
    136   // specifically.  Since we're not in an official browser tab, only
    137   // way to get the debugger going.
    138   void ShowDebugger();
    139 
    140   void CancelAnyRunningTask();
    141   bool IsCloudPrintDialogUrl(const GURL& url);
    142 
    143   CloudPrintWebDialogDelegate* dialog_delegate_;
    144   content::NotificationRegistrar registrar_;
    145   scoped_refptr<const base::RefCountedMemory> data_;
    146   string16 print_job_title_;
    147   string16 print_ticket_;
    148   std::string file_type_;
    149   scoped_refptr<CloudPrintDataSender> print_data_sender_;
    150   scoped_ptr<CloudPrintDataSenderHelper> print_data_helper_;
    151   bool close_after_signin_;
    152   base::Closure callback_;
    153 
    154   DISALLOW_COPY_AND_ASSIGN(CloudPrintFlowHandler);
    155 };
    156 
    157 // State machine used to run the printing dialog.  This class is used
    158 // to open and run the web dialog and deletes itself when the dialog
    159 // is closed.
    160 class CloudPrintWebDialogDelegate : public ui::WebDialogDelegate {
    161  public:
    162   CloudPrintWebDialogDelegate(content::BrowserContext* browser_context,
    163                               gfx::NativeWindow modal_parent,
    164                               const base::RefCountedMemory* data,
    165                               const std::string& json_arguments,
    166                               const string16& print_job_title,
    167                               const string16& print_ticket,
    168                               const std::string& file_type,
    169                               bool close_after_signin,
    170                               const base::Closure& callback);
    171   virtual ~CloudPrintWebDialogDelegate();
    172 
    173   // ui::WebDialogDelegate implementation:
    174   virtual ui::ModalType GetDialogModalType() const OVERRIDE;
    175   virtual string16 GetDialogTitle() const OVERRIDE;
    176   virtual GURL GetDialogContentURL() const OVERRIDE;
    177   virtual void GetWebUIMessageHandlers(
    178       std::vector<content::WebUIMessageHandler*>* handlers) const OVERRIDE;
    179   virtual void GetDialogSize(gfx::Size* size) const OVERRIDE;
    180   virtual std::string GetDialogArgs() const OVERRIDE;
    181   virtual void OnDialogClosed(const std::string& json_retval) OVERRIDE;
    182   virtual void OnCloseContents(content::WebContents* source,
    183                                bool* out_close_dialog) OVERRIDE;
    184   virtual bool ShouldShowDialogTitle() const OVERRIDE;
    185   virtual bool HandleContextMenu(
    186       const content::ContextMenuParams& params) OVERRIDE;
    187   virtual bool HandleOpenURLFromTab(
    188       content::WebContents* source,
    189       const content::OpenURLParams& params,
    190       content::WebContents** out_new_contents) OVERRIDE;
    191 
    192  private:
    193   friend class ::CloudPrintWebDialogDelegateTest;
    194 
    195   // For unit testing.
    196   CloudPrintWebDialogDelegate(CloudPrintFlowHandler* flow_handler,
    197                               const std::string& json_arguments);
    198   void Init(content::BrowserContext* browser_context,
    199             const std::string& json_arguments);
    200 
    201   CloudPrintFlowHandler* flow_handler_;
    202   gfx::NativeWindow modal_parent_;
    203   mutable bool owns_flow_handler_;
    204   bool keep_alive_when_non_modal_;
    205 
    206   // The parameters needed to display a modal web dialog.
    207   ui::WebDialogUI::WebDialogParams params_;
    208 
    209   DISALLOW_COPY_AND_ASSIGN(CloudPrintWebDialogDelegate);
    210 };
    211 
    212 void CreateDialogForFileImpl(content::BrowserContext* browser_context,
    213                              gfx::NativeWindow modal_parent,
    214                              const base::FilePath& path_to_file,
    215                              const string16& print_job_title,
    216                              const string16& print_ticket,
    217                              const std::string& file_type,
    218                              bool delete_on_close);
    219 void CreateDialogSigninImpl(content::BrowserContext* browser_context,
    220                             gfx::NativeWindow modal_parent,
    221                             const base::Closure& callback);
    222 
    223 }  // namespace internal_cloud_print_helpers
    224 
    225 #endif  // CHROME_BROWSER_PRINTING_PRINT_DIALOG_CLOUD_INTERNAL_H_
    226