OLD | NEW |
| (Empty) |
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 <gdk/gdk.h> | |
6 #include <gtk/gtk.h> | |
7 #include <webkit/webkitwebview.h> | |
8 | |
9 #include "base/at_exit.h" | |
10 #include "base/basictypes.h" | |
11 #include "base/command_line.h" | |
12 #include "base/message_loop.h" | |
13 #include "base/run_loop.h" | |
14 #include "base/threading/thread.h" | |
15 #include "net/base/net_util.h" | |
16 #include "remoting/base/common_resources.h" | |
17 #include "remoting/base/resources.h" | |
18 #include "remoting/base/string_resources.h" | |
19 #include "remoting/host/setup/host_starter.h" | |
20 #include "remoting/host/setup/oauth_helper.h" | |
21 #include "remoting/host/setup/pin_validator.h" | |
22 #include "remoting/host/url_request_context.h" | |
23 #include "ui/base/gtk/gtk_signal.h" | |
24 #include "ui/base/gtk/scoped_gobject.h" | |
25 #include "ui/base/l10n/l10n_util.h" | |
26 #include "ui/base/resource/resource_bundle.h" | |
27 #include "ui/base/ui_base_paths.h" | |
28 | |
29 namespace remoting { | |
30 | |
31 class LinuxHostSetupWizard { | |
32 public: | |
33 enum Pages { | |
34 kAuthPage = 0, | |
35 kPinPage = 1, | |
36 kProgressPage = 2, | |
37 kStartedPage = 3, | |
38 kErrorPage = 4, | |
39 kStoppedPage = 5, | |
40 }; | |
41 | |
42 LinuxHostSetupWizard(); | |
43 ~LinuxHostSetupWizard(); | |
44 | |
45 void Init(); | |
46 void Run(); | |
47 | |
48 private: | |
49 CHROMEGTK_CALLBACK_1(LinuxHostSetupWizard, gboolean, OnDelete, GdkEvent*); | |
50 CHROMEGTK_CALLBACK_1(LinuxHostSetupWizard, void, OnAuthUriChanged, | |
51 GParamSpec*); | |
52 CHROMEGTK_CALLBACK_0(LinuxHostSetupWizard, void, OnPinOkClicked); | |
53 | |
54 GtkWidget* AddPage(int expected_index); | |
55 GtkWidget* AddTextFieldWithLabel(GtkContainer* container, | |
56 const std::string& message); | |
57 void AddButtonsBox(GtkContainer* container, GCallback ok_callback); | |
58 | |
59 void ShowAuthenticationPrompt(); | |
60 void ShowProgressMessage(const std::string& message); | |
61 void ShowErrorMessage(const std::string& message); | |
62 | |
63 void ShowMessageBox(const std::string& message); | |
64 | |
65 void OnHostStarted(HostStarter::Result result); | |
66 | |
67 MessageLoopForUI main_message_loop_; | |
68 base::RunLoop run_loop_; | |
69 | |
70 scoped_ptr<base::Thread> io_thread_; | |
71 | |
72 scoped_refptr<URLRequestContextGetter> url_context_getter_; | |
73 | |
74 GtkWidget* main_window_; | |
75 GtkWidget* notebook_; | |
76 | |
77 // TODO(sergeyu): Replace auth code with authentication. | |
78 GtkWidget* auth_web_view_; | |
79 GtkWidget* pin_entry_; | |
80 GtkWidget* pin_repeat_entry_; | |
81 GtkWidget* progress_message_; | |
82 GtkWidget* error_message_; | |
83 | |
84 std::string auth_code_; | |
85 | |
86 scoped_ptr<HostStarter> starter_; | |
87 | |
88 DISALLOW_COPY_AND_ASSIGN(LinuxHostSetupWizard); | |
89 }; | |
90 | |
91 LinuxHostSetupWizard::LinuxHostSetupWizard() { | |
92 } | |
93 | |
94 LinuxHostSetupWizard::~LinuxHostSetupWizard() { | |
95 gtk_widget_destroy(main_window_); | |
96 } | |
97 | |
98 void LinuxHostSetupWizard::Init() { | |
99 io_thread_.reset(new base::Thread("IOThread")); | |
100 io_thread_->StartWithOptions( | |
101 base::Thread::Options(MessageLoop::TYPE_IO, 0)); | |
102 | |
103 url_context_getter_ = new URLRequestContextGetter( | |
104 main_message_loop_.message_loop_proxy(), | |
105 io_thread_->message_loop_proxy()); | |
106 | |
107 main_window_ = gtk_window_new(GTK_WINDOW_TOPLEVEL); | |
108 g_signal_connect(main_window_, "delete-event", | |
109 G_CALLBACK(OnDeleteThunk), this); | |
110 gtk_window_set_title( | |
111 GTK_WINDOW(main_window_), | |
112 l10n_util::GetStringUTF8(IDR_PRODUCT_NAME).c_str()); | |
113 gtk_window_set_resizable(GTK_WINDOW(main_window_), FALSE); | |
114 | |
115 gfx::Image logo = ui::ResourceBundle::GetSharedInstance().GetImageNamed( | |
116 IDR_PRODUCT_LOGO_32); | |
117 ui::ScopedGObject<GdkPixbuf>::Type pixbuf(logo.ToGdkPixbuf()); | |
118 gtk_window_set_icon(GTK_WINDOW(main_window_), pixbuf.get()); | |
119 | |
120 notebook_ = gtk_notebook_new(); | |
121 gtk_container_add(GTK_CONTAINER(main_window_), notebook_); | |
122 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(notebook_), FALSE); | |
123 gtk_notebook_set_show_border(GTK_NOTEBOOK(notebook_), FALSE); | |
124 | |
125 GtkWidget* auth_page = AddPage(kAuthPage); | |
126 auth_web_view_ = webkit_web_view_new(); | |
127 gtk_container_add(GTK_CONTAINER(auth_page), auth_web_view_); | |
128 g_signal_connect(auth_web_view_, "notify::uri", | |
129 G_CALLBACK(OnAuthUriChangedThunk), this); | |
130 | |
131 GtkWidget* pin_page = AddPage(kPinPage); | |
132 pin_entry_ = AddTextFieldWithLabel( | |
133 GTK_CONTAINER(pin_page), | |
134 l10n_util::GetStringUTF8(IDR_ASK_PIN_DIALOG_LABEL)); | |
135 pin_repeat_entry_ = AddTextFieldWithLabel( | |
136 GTK_CONTAINER(pin_page), | |
137 l10n_util::GetStringUTF8(IDR_ASK_PIN_DIALOG_CONFIRM_LABEL)); | |
138 AddButtonsBox(GTK_CONTAINER(pin_page), G_CALLBACK(OnPinOkClickedThunk)); | |
139 | |
140 GtkWidget* progress_page = AddPage(kProgressPage); | |
141 progress_message_ = gtk_label_new(""); | |
142 gtk_container_add(GTK_CONTAINER(progress_page), progress_message_); | |
143 | |
144 GtkWidget* started_page = AddPage(kStartedPage); | |
145 GtkWidget* started_message = gtk_label_new( | |
146 l10n_util::GetStringUTF8(IDR_HOST_SETUP_STARTED).c_str()); | |
147 gtk_container_add(GTK_CONTAINER(started_page), started_message); | |
148 | |
149 GtkWidget* error_page = AddPage(kErrorPage); | |
150 error_message_ = gtk_label_new(""); | |
151 gtk_container_add(GTK_CONTAINER(error_page), error_message_); | |
152 | |
153 GtkWidget* stopped_page = AddPage(kStoppedPage); | |
154 GtkWidget* stopped_message = gtk_label_new( | |
155 l10n_util::GetStringUTF8(IDR_HOST_NOT_STARTED).c_str()); | |
156 gtk_container_add(GTK_CONTAINER(stopped_page), stopped_message); | |
157 | |
158 gtk_widget_show_all(main_window_); | |
159 | |
160 ShowAuthenticationPrompt(); | |
161 } | |
162 | |
163 void LinuxHostSetupWizard::Run() { | |
164 gtk_widget_show_all(main_window_); | |
165 run_loop_.Run(); | |
166 } | |
167 | |
168 GtkWidget* LinuxHostSetupWizard::AddPage(int expected_index) { | |
169 GtkWidget* page = gtk_vbox_new(FALSE, 8); | |
170 | |
171 int page_index = | |
172 gtk_notebook_append_page(GTK_NOTEBOOK(notebook_), page, NULL); | |
173 DCHECK_EQ(page_index, expected_index); | |
174 | |
175 return page; | |
176 } | |
177 | |
178 GtkWidget* LinuxHostSetupWizard::AddTextFieldWithLabel( | |
179 GtkContainer* container, | |
180 const std::string& message) { | |
181 GtkWidget* box = gtk_hbox_new(FALSE, 8); | |
182 gtk_container_add(container, box); | |
183 | |
184 GtkWidget* label = gtk_label_new(message.c_str()); | |
185 gtk_container_add(GTK_CONTAINER(box), label); | |
186 | |
187 GtkWidget* entry = gtk_entry_new(); | |
188 gtk_container_add(GTK_CONTAINER(box), entry); | |
189 | |
190 return entry; | |
191 } | |
192 | |
193 void LinuxHostSetupWizard::AddButtonsBox(GtkContainer* container, | |
194 GCallback ok_callback) { | |
195 GtkWidget* box = gtk_hbox_new(FALSE, 8); | |
196 gtk_container_add(container, box); | |
197 | |
198 GtkWidget* button = | |
199 gtk_button_new_with_label(l10n_util::GetStringUTF8(IDR_OK).c_str()); | |
200 gtk_container_add(GTK_CONTAINER(box), button); | |
201 g_signal_connect(button, "clicked", ok_callback, this); | |
202 } | |
203 | |
204 void LinuxHostSetupWizard::ShowAuthenticationPrompt() { | |
205 std::string url = GetOauthStartUrl(GetDefaultOauthRedirectUrl()); | |
206 webkit_web_view_load_uri(WEBKIT_WEB_VIEW(auth_web_view_), url.c_str()); | |
207 gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook_), kAuthPage); | |
208 } | |
209 | |
210 void LinuxHostSetupWizard::ShowProgressMessage(const std::string& message) { | |
211 gtk_label_set_text(GTK_LABEL(progress_message_), message.c_str()); | |
212 gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook_), kProgressPage); | |
213 } | |
214 | |
215 void LinuxHostSetupWizard::ShowErrorMessage(const std::string& message) { | |
216 gtk_label_set_text(GTK_LABEL(error_message_), message.c_str()); | |
217 gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook_), kErrorPage); | |
218 } | |
219 | |
220 void LinuxHostSetupWizard::ShowMessageBox(const std::string& message) { | |
221 GtkWidget* dialog = gtk_message_dialog_new( | |
222 GTK_WINDOW(main_window_), static_cast<GtkDialogFlags>( | |
223 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT), | |
224 GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "%s", message.c_str()); | |
225 g_signal_connect(dialog, "response", G_CALLBACK(gtk_widget_destroy), NULL); | |
226 gtk_widget_show_all(dialog); | |
227 } | |
228 | |
229 gboolean LinuxHostSetupWizard::OnDelete(GtkWidget* window, GdkEvent* event) { | |
230 run_loop_.Quit(); | |
231 return TRUE; | |
232 } | |
233 | |
234 void LinuxHostSetupWizard::OnAuthUriChanged(GtkWidget* web_view, | |
235 GParamSpec* param_spec) { | |
236 std::string url(webkit_web_view_get_uri(WEBKIT_WEB_VIEW(auth_web_view_))); | |
237 std::string auth_code = GetOauthCodeInUrl(url, GetDefaultOauthRedirectUrl()); | |
238 if (!auth_code.empty()) { | |
239 auth_code_ = auth_code; | |
240 gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook_), kPinPage); | |
241 } | |
242 } | |
243 | |
244 void LinuxHostSetupWizard::OnPinOkClicked(GtkWidget* button) { | |
245 std::string host_name = net::GetHostName(); | |
246 std::string pin = gtk_entry_get_text(GTK_ENTRY(pin_entry_)); | |
247 std::string pin_repeat = gtk_entry_get_text(GTK_ENTRY(pin_repeat_entry_)); | |
248 | |
249 if (!IsPinValid(pin)) { | |
250 ShowMessageBox(l10n_util::GetStringUTF8(IDR_INVALID_PIN)); | |
251 return; | |
252 } | |
253 | |
254 if (pin != pin_repeat) { | |
255 ShowMessageBox(l10n_util::GetStringUTF8(IDR_PINS_NOT_EQUAL)); | |
256 return; | |
257 } | |
258 | |
259 starter_ = HostStarter::Create(url_context_getter_.get()); | |
260 | |
261 starter_->StartHost(host_name, pin, false, auth_code_, | |
262 GetDefaultOauthRedirectUrl(), | |
263 base::Bind(&LinuxHostSetupWizard::OnHostStarted, | |
264 base::Unretained(this))); | |
265 ShowProgressMessage(l10n_util::GetStringUTF8(IDR_HOST_SETUP_STARTING)); | |
266 } | |
267 | |
268 void LinuxHostSetupWizard::OnHostStarted(HostStarter::Result result) { | |
269 switch (result) { | |
270 case HostStarter::START_COMPLETE: | |
271 gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook_), kStartedPage); | |
272 break; | |
273 | |
274 case HostStarter::NETWORK_ERROR: | |
275 case HostStarter::OAUTH_ERROR: | |
276 ShowErrorMessage(l10n_util::GetStringUTF8( | |
277 IDR_HOST_SETUP_REGISTRATION_FAILED)); | |
278 break; | |
279 | |
280 case HostStarter::START_ERROR: | |
281 ShowErrorMessage(l10n_util::GetStringUTF8(IDR_HOST_SETUP_HOST_FAILED)); | |
282 break; | |
283 } | |
284 } | |
285 | |
286 } // namespace remoting | |
287 | |
288 int main(int argc, char** argv) { | |
289 CommandLine::Init(argc, argv); | |
290 base::AtExitManager at_exit_manager; | |
291 ui::RegisterPathProvider(); | |
292 | |
293 remoting::LoadResources(std::string()); | |
294 | |
295 InitLogging(NULL, | |
296 logging::LOG_ONLY_TO_SYSTEM_DEBUG_LOG, | |
297 logging::DONT_LOCK_LOG_FILE, | |
298 logging::APPEND_TO_OLD_LOG_FILE, | |
299 logging::DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS); | |
300 | |
301 gtk_init(&argc, &argv); | |
302 | |
303 remoting::LinuxHostSetupWizard setup_ui; | |
304 setup_ui.Init(); | |
305 setup_ui.Run(); | |
306 | |
307 return 0; | |
308 } | |
OLD | NEW |