1 // Copyright (c) 2011 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 "chrome/browser/chromeos/login/eula_view.h"
6
7 #include <signal.h>
8 #include <sys/types.h>
9 #include <string>
10
11 #include "base/basictypes.h"
12 #include "base/message_loop.h"
13 #include "base/task.h"
14 #include "base/utf_string_conversions.h"
15 #include "base/values.h"
16 #include "chrome/browser/browser_process.h"
17 #include "chrome/browser/chromeos/cros/cros_library.h"
18 #include "chrome/browser/chromeos/cros/cryptohome_library.h"
19 #include "chrome/browser/chromeos/customization_document.h"
20 #include "chrome/browser/chromeos/login/background_view.h"
21 #include "chrome/browser/chromeos/login/help_app_launcher.h"
22 #include "chrome/browser/chromeos/login/helper.h"
23 #include "chrome/browser/chromeos/login/login_utils.h"
24 #include "chrome/browser/chromeos/login/network_screen_delegate.h"
25 #include "chrome/browser/chromeos/login/rounded_rect_painter.h"
26 #include "chrome/browser/chromeos/login/wizard_controller.h"
27 #include "chrome/browser/profiles/profile_manager.h"
28 #include "chrome/browser/ui/views/dom_view.h"
29 #include "chrome/browser/ui/views/window.h"
30 #include "chrome/common/url_constants.h"
31 #include "content/browser/site_instance.h"
32 #include "content/browser/tab_contents/tab_contents.h"
33 #include "content/common/native_web_keyboard_event.h"
34 #include "grit/chromium_strings.h"
35 #include "grit/generated_resources.h"
36 #include "grit/locale_settings.h"
37 #include "grit/theme_resources.h"
38 #include "ui/base/l10n/l10n_util.h"
39 #include "ui/base/resource/resource_bundle.h"
40 #include "views/controls/button/checkbox.h"
41 #include "views/controls/button/native_button_gtk.h"
42 #include "views/controls/label.h"
43 #include "views/controls/throbber.h"
44 #include "views/events/event.h"
45 #include "views/layout/grid_layout.h"
46 #include "views/layout/layout_constants.h"
47 #include "views/layout/layout_manager.h"
48 #include "views/widget/widget_gtk.h"
49 #include "views/window/dialog_delegate.h"
50 #include "views/window/window.h"
51
52 using views::WidgetGtk;
53
54 namespace {
55
56 const int kBorderSize = 10;
57 const int kCheckboxWidth = 26;
58 const int kLastButtonHorizontalMargin = 10;
59 const int kMargin = 20;
60 const int kTextMargin = 10;
61 const int kTpmCheckIntervalMs = 500;
62
63 // TODO(glotov): this URL should be changed to actual Google ChromeOS EULA.
64 // See crbug.com/4647
65 const char kGoogleEulaUrl[] = "about:terms";
66
67 enum kLayoutColumnsets {
68 SINGLE_CONTROL_ROW,
69 SINGLE_CONTROL_WITH_SHIFT_ROW,
70 SINGLE_LINK_WITH_SHIFT_ROW,
71 LAST_ROW
72 };
73
74 // Helper class that disables using native label for subclassed GTK control.
75 class EULANativeCheckboxGtk : public views::NativeCheckboxGtk {
76 public:
EULANativeCheckboxGtk(views::Checkbox * checkbox)77 explicit EULANativeCheckboxGtk(views::Checkbox* checkbox)
78 : views::NativeCheckboxGtk(checkbox) {
79 set_fast_resize(true);
80 }
~EULANativeCheckboxGtk()81 virtual ~EULANativeCheckboxGtk() { }
UsesNativeLabel() const82 virtual bool UsesNativeLabel() const { return false; }
UpdateLabel()83 virtual void UpdateLabel() { }
84 };
85
86 // views::Checkbox specialization that uses its internal views::Label
87 // instead of native one. We need this because native label does not
88 // support multiline property and we need it for certain languages.
89 class EULACheckbox : public views::Checkbox {
90 public:
EULACheckbox()91 EULACheckbox() { }
~EULACheckbox()92 virtual ~EULACheckbox() { }
93
94 protected:
CreateWrapper()95 virtual views::NativeButtonWrapper* CreateWrapper() {
96 views::NativeButtonWrapper* native_wrapper =
97 new EULANativeCheckboxGtk(this);
98 native_wrapper->UpdateChecked();
99 return native_wrapper;
100 }
101 };
102
103 // A simple LayoutManager that causes the associated view's one child to be
104 // sized to match the bounds of its parent except the bounds, if set.
105 struct FillLayoutWithBorder : public views::LayoutManager {
106 // Overridden from LayoutManager:
Layout__anon880287960111::FillLayoutWithBorder107 virtual void Layout(views::View* host) {
108 DCHECK(host->has_children());
109 host->GetChildViewAt(0)->SetBoundsRect(host->GetContentsBounds());
110 }
GetPreferredSize__anon880287960111::FillLayoutWithBorder111 virtual gfx::Size GetPreferredSize(views::View* host) {
112 return gfx::Size(host->width(), host->height());
113 }
114 };
115
116 // System security setting dialog.
117 class TpmInfoView : public views::View,
118 public views::DialogDelegate {
119 public:
TpmInfoView(std::string * password)120 explicit TpmInfoView(std::string* password)
121 : ALLOW_THIS_IN_INITIALIZER_LIST(runnable_method_factory_(this)),
122 password_(password) {
123 DCHECK(password_);
124 }
125
126 void Init();
127
128 protected:
129 // views::DialogDelegate overrides:
Accept()130 virtual bool Accept() { return true; }
IsModal() const131 virtual bool IsModal() const { return true; }
GetContentsView()132 virtual views::View* GetContentsView() { return this; }
GetDialogButtons() const133 virtual int GetDialogButtons() const {
134 return MessageBoxFlags::DIALOGBUTTON_OK;
135 }
136
137 // views::View overrides:
GetWindowTitle() const138 virtual std::wstring GetWindowTitle() const {
139 return UTF16ToWide(
140 l10n_util::GetStringUTF16(IDS_EULA_SYSTEM_SECURITY_SETTING));
141 }
142
GetPreferredSize()143 gfx::Size GetPreferredSize() {
144 return gfx::Size(views::Window::GetLocalizedContentsSize(
145 IDS_TPM_INFO_DIALOG_WIDTH_CHARS,
146 IDS_TPM_INFO_DIALOG_HEIGHT_LINES));
147 }
148
149 private:
150 void PullPassword();
151
152 ScopedRunnableMethodFactory<TpmInfoView> runnable_method_factory_;
153
154 // Holds pointer to the password storage.
155 std::string* password_;
156
157 views::Label* busy_label_;
158 views::Label* password_label_;
159 views::Throbber* throbber_;
160
161 DISALLOW_COPY_AND_ASSIGN(TpmInfoView);
162 };
163
Init()164 void TpmInfoView::Init() {
165 views::GridLayout* layout = views::GridLayout::CreatePanel(this);
166 SetLayoutManager(layout);
167 views::ColumnSet* column_set = layout->AddColumnSet(0);
168 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
169 views::GridLayout::USE_PREF, 0, 0);
170 layout->StartRow(0, 0);
171 views::Label* label = new views::Label(UTF16ToWide(
172 l10n_util::GetStringUTF16(IDS_EULA_SYSTEM_SECURITY_SETTING_DESCRIPTION)));
173 label->SetMultiLine(true);
174 label->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
175 layout->AddView(label);
176 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
177
178 layout->StartRow(0, 0);
179 label = new views::Label(UTF16ToWide(l10n_util::GetStringUTF16(
180 IDS_EULA_SYSTEM_SECURITY_SETTING_DESCRIPTION_KEY)));
181 label->SetMultiLine(true);
182 label->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
183 layout->AddView(label);
184 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
185
186 column_set = layout->AddColumnSet(1);
187 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
188 views::GridLayout::USE_PREF, 0, 0);
189 layout->StartRow(0, 1);
190 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
191 gfx::Font password_font =
192 rb.GetFont(ResourceBundle::MediumFont).DeriveFont(0, gfx::Font::BOLD);
193 // Password will be set later.
194 password_label_ = new views::Label(L"", password_font);
195 password_label_->SetVisible(false);
196 layout->AddView(password_label_);
197 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
198
199 column_set = layout->AddColumnSet(2);
200 column_set->AddPaddingColumn(1, 0);
201 // Resize of the throbber and label is not allowed, since we want they to be
202 // placed in the center.
203 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 0,
204 views::GridLayout::USE_PREF, 0, 0);
205 column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing);
206 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 0,
207 views::GridLayout::USE_PREF, 0, 0);
208 column_set->AddPaddingColumn(1, 0);
209 // Border padding columns should have the same width. It guaranties that
210 // throbber and label will be placed in the center.
211 column_set->LinkColumnSizes(0, 4, -1);
212
213 layout->StartRow(0, 2);
214 throbber_ = chromeos::CreateDefaultThrobber();
215 throbber_->Start();
216 layout->AddView(throbber_);
217 busy_label_ = new views::Label(
218 UTF16ToWide(l10n_util::GetStringUTF16(IDS_EULA_TPM_BUSY)));
219 layout->AddView(busy_label_);
220 layout->AddPaddingRow(0, views::kRelatedControlHorizontalSpacing);
221
222 PullPassword();
223 }
224
PullPassword()225 void TpmInfoView::PullPassword() {
226 // Since this method is also called directly.
227 runnable_method_factory_.RevokeAll();
228
229 chromeos::CryptohomeLibrary* cryptohome =
230 chromeos::CrosLibrary::Get()->GetCryptohomeLibrary();
231
232 bool password_acquired = false;
233 if (password_->empty() && cryptohome->TpmIsReady()) {
234 password_acquired = cryptohome->TpmGetPassword(password_);
235 if (!password_acquired) {
236 password_->clear();
237 } else if (password_->empty()) {
238 // For a fresh OOBE flow TPM is uninitialized,
239 // ownership process is started at the EULA screen,
240 // password is cleared after EULA is accepted.
241 LOG(ERROR) << "TPM returned an empty password.";
242 }
243 }
244 if (password_->empty() && !password_acquired) {
245 // Password hasn't been acquired, reschedule pulling.
246 MessageLoop::current()->PostDelayedTask(
247 FROM_HERE,
248 runnable_method_factory_.NewRunnableMethod(&TpmInfoView::PullPassword),
249 kTpmCheckIntervalMs);
250 } else {
251 password_label_->SetText(ASCIIToWide(*password_));
252 password_label_->SetVisible(true);
253 busy_label_->SetVisible(false);
254 throbber_->Stop();
255 throbber_->SetVisible(false);
256 }
257 }
258
259 } // namespace
260
261 namespace chromeos {
262
263 ////////////////////////////////////////////////////////////////////////////////
264 // EulaView, public:
265
EulaView(chromeos::ScreenObserver * observer)266 EulaView::EulaView(chromeos::ScreenObserver* observer)
267 : google_eula_label_(NULL),
268 google_eula_view_(NULL),
269 usage_statistics_checkbox_(NULL),
270 learn_more_link_(NULL),
271 oem_eula_label_(NULL),
272 oem_eula_view_(NULL),
273 system_security_settings_link_(NULL),
274 back_button_(NULL),
275 continue_button_(NULL),
276 observer_(observer),
277 bubble_(NULL) {
278 }
279
~EulaView()280 EulaView::~EulaView() {
281 // bubble_ will be set to NULL in callback.
282 if (bubble_)
283 bubble_->Close();
284 }
285
286 // Convenience function to set layout's columnsets for this screen.
SetUpGridLayout(views::GridLayout * layout)287 static void SetUpGridLayout(views::GridLayout* layout) {
288 static const int kPadding = kBorderSize + kMargin;
289 views::ColumnSet* column_set = layout->AddColumnSet(SINGLE_CONTROL_ROW);
290 column_set->AddPaddingColumn(0, kPadding);
291 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
292 views::GridLayout::USE_PREF, 0, 0);
293 column_set->AddPaddingColumn(0, kPadding);
294
295 column_set = layout->AddColumnSet(SINGLE_CONTROL_WITH_SHIFT_ROW);
296 column_set->AddPaddingColumn(0, kPadding + kTextMargin);
297 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
298 views::GridLayout::USE_PREF, 0, 0);
299 column_set->AddPaddingColumn(0, kPadding);
300
301 column_set = layout->AddColumnSet(SINGLE_LINK_WITH_SHIFT_ROW);
302 column_set->AddPaddingColumn(0, kPadding + kTextMargin + kCheckboxWidth);
303 column_set->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL, 1,
304 views::GridLayout::USE_PREF, 0, 0);
305 column_set->AddPaddingColumn(0, kPadding);
306
307 column_set = layout->AddColumnSet(LAST_ROW);
308 column_set->AddPaddingColumn(0, kPadding + kTextMargin);
309 column_set->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL, 1,
310 views::GridLayout::USE_PREF, 0, 0);
311 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 0,
312 views::GridLayout::USE_PREF, 0, 0);
313 column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing);
314 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 0,
315 views::GridLayout::USE_PREF, 0, 0);
316 column_set->AddPaddingColumn(0, kLastButtonHorizontalMargin + kBorderSize);
317 }
318
319 // Convenience function. Returns URL of the OEM EULA page that should be
320 // displayed using current locale and manifest. Returns empty URL otherwise.
GetOemEulaPagePath()321 static GURL GetOemEulaPagePath() {
322 const StartupCustomizationDocument* customization =
323 StartupCustomizationDocument::GetInstance();
324 if (customization->IsReady()) {
325 std::string locale = customization->initial_locale();
326 std::string eula_page = customization->GetEULAPage(locale);
327 if (!eula_page.empty())
328 return GURL(eula_page);
329
330 VLOG(1) << "No eula found for locale: " << locale;
331 } else {
332 LOG(ERROR) << "No manifest found.";
333 }
334 return GURL();
335 }
336
Init()337 void EulaView::Init() {
338 // First, command to own the TPM.
339 if (chromeos::CrosLibrary::Get()->EnsureLoaded()) {
340 chromeos::CrosLibrary::Get()->
341 GetCryptohomeLibrary()->TpmCanAttemptOwnership();
342 } else {
343 LOG(ERROR) << "Cros library not loaded. "
344 << "We must have disabled the link that led here.";
345 }
346
347 // Use rounded rect background.
348 views::Painter* painter = CreateWizardPainter(
349 &BorderDefinition::kScreenBorder);
350 set_background(
351 views::Background::CreateBackgroundPainter(true, painter));
352
353 // Layout created controls.
354 views::GridLayout* layout = new views::GridLayout(this);
355 SetLayoutManager(layout);
356 SetUpGridLayout(layout);
357
358 static const int kPadding = kBorderSize + kMargin;
359 layout->AddPaddingRow(0, kPadding);
360 layout->StartRow(0, SINGLE_CONTROL_ROW);
361 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
362 gfx::Font label_font =
363 rb.GetFont(ResourceBundle::MediumFont).DeriveFont(0, gfx::Font::NORMAL);
364 google_eula_label_ = new views::Label(std::wstring(), label_font);
365 layout->AddView(google_eula_label_, 1, 1,
366 views::GridLayout::LEADING, views::GridLayout::FILL);
367
368 layout->AddPaddingRow(0, views::kRelatedControlSmallVerticalSpacing);
369 layout->StartRow(1, SINGLE_CONTROL_ROW);
370 views::View* box_view = new views::View();
371 box_view->set_border(views::Border::CreateSolidBorder(1, SK_ColorBLACK));
372 box_view->SetLayoutManager(new FillLayoutWithBorder());
373 layout->AddView(box_view);
374
375 google_eula_view_ = new DOMView();
376 box_view->AddChildView(google_eula_view_);
377
378 layout->AddPaddingRow(0, views::kRelatedControlSmallVerticalSpacing);
379 layout->StartRow(0, SINGLE_CONTROL_WITH_SHIFT_ROW);
380 usage_statistics_checkbox_ = new EULACheckbox();
381 usage_statistics_checkbox_->SetMultiLine(true);
382 usage_statistics_checkbox_->SetChecked(
383 observer_->usage_statistics_reporting());
384 layout->AddView(usage_statistics_checkbox_);
385
386 layout->StartRow(0, SINGLE_LINK_WITH_SHIFT_ROW);
387 learn_more_link_ = new views::Link();
388 learn_more_link_->SetController(this);
389 layout->AddView(learn_more_link_);
390
391 layout->AddPaddingRow(0, views::kRelatedControlSmallVerticalSpacing);
392 layout->StartRow(0, SINGLE_CONTROL_ROW);
393 oem_eula_label_ = new views::Label(std::wstring(), label_font);
394 layout->AddView(oem_eula_label_, 1, 1,
395 views::GridLayout::LEADING, views::GridLayout::FILL);
396
397 oem_eula_page_ = GetOemEulaPagePath();
398 if (!oem_eula_page_.is_empty()) {
399 layout->AddPaddingRow(0, views::kRelatedControlSmallVerticalSpacing);
400 layout->StartRow(1, SINGLE_CONTROL_ROW);
401 box_view = new views::View();
402 box_view->SetLayoutManager(new FillLayoutWithBorder());
403 box_view->set_border(views::Border::CreateSolidBorder(1, SK_ColorBLACK));
404 layout->AddView(box_view);
405
406 oem_eula_view_ = new DOMView();
407 box_view->AddChildView(oem_eula_view_);
408 }
409
410 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
411 layout->StartRow(0, LAST_ROW);
412 system_security_settings_link_ = new views::Link();
413 system_security_settings_link_->SetController(this);
414
415 if (!chromeos::CrosLibrary::Get()->EnsureLoaded() ||
416 !chromeos::CrosLibrary::Get()->GetCryptohomeLibrary()->
417 TpmIsEnabled()) {
418 system_security_settings_link_->SetEnabled(false);
419 }
420
421 layout->AddView(system_security_settings_link_);
422
423 back_button_ = new login::WideButton(this, std::wstring());
424 layout->AddView(back_button_);
425
426 continue_button_ = new login::WideButton(this, std::wstring());
427 layout->AddView(continue_button_);
428 layout->AddPaddingRow(0, kPadding);
429
430 UpdateLocalizedStrings();
431 }
432
UpdateLocalizedStrings()433 void EulaView::UpdateLocalizedStrings() {
434 // Load Google EULA and its title.
435 LoadEulaView(google_eula_view_, google_eula_label_, GURL(kGoogleEulaUrl));
436
437 // Load OEM EULA and its title.
438 if (!oem_eula_page_.is_empty())
439 LoadEulaView(oem_eula_view_, oem_eula_label_, oem_eula_page_);
440
441 // Set tooltip for usage statistics checkbox if the metric is unmanaged.
442 if (!usage_statistics_checkbox_->IsEnabled()) {
443 usage_statistics_checkbox_->SetTooltipText(
444 UTF16ToWide(l10n_util::GetStringUTF16(IDS_OPTION_DISABLED_BY_POLICY)));
445 }
446
447 // Set tooltip for system security settings link if TPM is disabled.
448 if (!system_security_settings_link_->IsEnabled()) {
449 system_security_settings_link_->SetTooltipText(
450 UTF16ToWide(l10n_util::GetStringUTF16(IDS_EULA_TPM_DISABLED)));
451 }
452
453 // Load other labels from resources.
454 usage_statistics_checkbox_->SetLabel(
455 UTF16ToWide(l10n_util::GetStringUTF16(IDS_EULA_CHECKBOX_ENABLE_LOGGING)));
456 learn_more_link_->SetText(
457 UTF16ToWide(l10n_util::GetStringUTF16(IDS_LEARN_MORE)));
458 system_security_settings_link_->SetText(
459 UTF16ToWide(l10n_util::GetStringUTF16(IDS_EULA_SYSTEM_SECURITY_SETTING)));
460 continue_button_->SetLabel(UTF16ToWide(
461 l10n_util::GetStringUTF16(IDS_EULA_ACCEPT_AND_CONTINUE_BUTTON)));
462 back_button_->SetLabel(
463 UTF16ToWide(l10n_util::GetStringUTF16(IDS_EULA_BACK_BUTTON)));
464 }
465
466 ////////////////////////////////////////////////////////////////////////////////
467 // EulaView, protected, views::View implementation:
468
OnLocaleChanged()469 void EulaView::OnLocaleChanged() {
470 UpdateLocalizedStrings();
471 Layout();
472 }
473
474 ////////////////////////////////////////////////////////////////////////////////
475 // views::ButtonListener implementation:
476
ButtonPressed(views::Button * sender,const views::Event & event)477 void EulaView::ButtonPressed(views::Button* sender, const views::Event& event) {
478 if (usage_statistics_checkbox_) {
479 observer_->set_usage_statistics_reporting(
480 usage_statistics_checkbox_->checked());
481 }
482 if (sender == continue_button_) {
483 observer_->OnExit(ScreenObserver::EULA_ACCEPTED);
484 } else if (sender == back_button_) {
485 observer_->OnExit(ScreenObserver::EULA_BACK);
486 }
487 }
488
489 ////////////////////////////////////////////////////////////////////////////////
490 // views::LinkController implementation:
491
LinkActivated(views::Link * source,int event_flags)492 void EulaView::LinkActivated(views::Link* source, int event_flags) {
493 gfx::NativeWindow parent_window =
494 LoginUtils::Get()->GetBackgroundView()->GetNativeWindow();
495 if (source == learn_more_link_) {
496 if (!help_app_.get())
497 help_app_ = new HelpAppLauncher(parent_window);
498 help_app_->ShowHelpTopic(HelpAppLauncher::HELP_STATS_USAGE);
499 } else if (source == system_security_settings_link_) {
500 TpmInfoView* view = new TpmInfoView(&tpm_password_);
501 view->Init();
502 views::Window* window = browser::CreateViewsWindow(parent_window,
503 gfx::Rect(),
504 view);
505 window->SetIsAlwaysOnTop(true);
506 window->Show();
507 }
508 }
509
510 ////////////////////////////////////////////////////////////////////////////////
511 // TabContentsDelegate implementation:
512
513 // Convenience function. Queries |eula_view| for HTML title and, if it
514 // is ready, assigns it to |eula_label| and returns true so the caller
515 // view calls Layout().
PublishTitleIfReady(const TabContents * contents,DOMView * eula_view,views::Label * eula_label)516 static bool PublishTitleIfReady(const TabContents* contents,
517 DOMView* eula_view,
518 views::Label* eula_label) {
519 if (contents != eula_view->tab_contents())
520 return false;
521 eula_label->SetText(UTF16ToWide(eula_view->tab_contents()->GetTitle()));
522 return true;
523 }
524
NavigationStateChanged(const TabContents * contents,unsigned changed_flags)525 void EulaView::NavigationStateChanged(const TabContents* contents,
526 unsigned changed_flags) {
527 if (changed_flags & TabContents::INVALIDATE_TITLE) {
528 if (PublishTitleIfReady(contents, google_eula_view_, google_eula_label_) ||
529 PublishTitleIfReady(contents, oem_eula_view_, oem_eula_label_)) {
530 Layout();
531 }
532 }
533 }
534
HandleKeyboardEvent(const NativeWebKeyboardEvent & event)535 void EulaView::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) {
536 views::Widget* widget = GetWidget();
537 if (widget && event.os_event && !event.skip_in_browser) {
538 views::KeyEvent views_event(reinterpret_cast<GdkEvent*>(event.os_event));
539 static_cast<views::WidgetGtk*>(widget)->HandleKeyboardEvent(views_event);
540 }
541 }
542
543 ////////////////////////////////////////////////////////////////////////////////
544 // EulaView, private:
545
LoadEulaView(DOMView * eula_view,views::Label * eula_label,const GURL & eula_url)546 void EulaView::LoadEulaView(DOMView* eula_view,
547 views::Label* eula_label,
548 const GURL& eula_url) {
549 Profile* profile = ProfileManager::GetDefaultProfile();
550 eula_view->Init(profile,
551 SiteInstance::CreateSiteInstanceForURL(profile, eula_url));
552 eula_view->LoadURL(eula_url);
553 eula_view->tab_contents()->set_delegate(this);
554 }
555
556 ////////////////////////////////////////////////////////////////////////////////
557 // EulaView, private, views::View implementation:
558
OnKeyPressed(const views::KeyEvent &)559 bool EulaView::OnKeyPressed(const views::KeyEvent&) {
560 // Close message bubble if shown. bubble_ will be set to NULL in callback.
561 if (bubble_) {
562 bubble_->Close();
563 return true;
564 }
565 return false;
566 }
567
568 } // namespace chromeos
569