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