• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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