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