| Index: chrome/browser/ui/views/first_run_bubble_unittest.cc
 | 
| diff --git a/chrome/browser/ui/views/first_run_bubble_unittest.cc b/chrome/browser/ui/views/first_run_bubble_unittest.cc
 | 
| index 83c1b9c1f2b339b4325748a2b1ff66dd6e7f7f3d..9fe90ebc67b5dbe4f4dbea37e12539e6508e73c6 100644
 | 
| --- a/chrome/browser/ui/views/first_run_bubble_unittest.cc
 | 
| +++ b/chrome/browser/ui/views/first_run_bubble_unittest.cc
 | 
| @@ -9,11 +9,16 @@
 | 
|  #include "components/search_engines/template_url.h"
 | 
|  #include "components/search_engines/template_url_service.h"
 | 
|  #include "testing/gtest/include/gtest/gtest.h"
 | 
| +#include "ui/aura/window.h"
 | 
| +#include "ui/aura/window_tree_host.h"
 | 
| +#include "ui/events/event.h"
 | 
| +#include "ui/events/event_processor.h"
 | 
|  #include "ui/views/test/views_test_base.h"
 | 
|  #include "ui/views/view.h"
 | 
|  #include "ui/views/widget/widget.h"
 | 
|  
 | 
| -class FirstRunBubbleTest : public views::ViewsTestBase {
 | 
| +class FirstRunBubbleTest : public views::ViewsTestBase,
 | 
| +                           views::WidgetObserver {
 | 
|   public:
 | 
|    FirstRunBubbleTest();
 | 
|    ~FirstRunBubbleTest() override;
 | 
| @@ -32,6 +37,7 @@ class FirstRunBubbleTest : public views::ViewsTestBase {
 | 
|  };
 | 
|  
 | 
|  FirstRunBubbleTest::FirstRunBubbleTest() {}
 | 
| +
 | 
|  FirstRunBubbleTest::~FirstRunBubbleTest() {}
 | 
|  
 | 
|  void FirstRunBubbleTest::SetUp() {
 | 
| @@ -50,6 +56,39 @@ void FirstRunBubbleTest::TearDown() {
 | 
|    TestingBrowserProcess::DeleteInstance();
 | 
|  }
 | 
|  
 | 
| +// Provides functionality to observe the widget passed in the constructor for
 | 
| +// the widget closing event.
 | 
| +class WidgetClosingObserver : public views::WidgetObserver {
 | 
| + public:
 | 
| +  WidgetClosingObserver(views::Widget* widget)
 | 
| +      : widget_(widget),
 | 
| +        widget_destroyed_(false) {
 | 
| +    widget_->AddObserver(this);
 | 
| +  }
 | 
| +
 | 
| +  ~WidgetClosingObserver() override {
 | 
| +    if (widget_)
 | 
| +      widget_->RemoveObserver(this);
 | 
| +  }
 | 
| +
 | 
| +  void OnWidgetClosing(views::Widget* widget) override {
 | 
| +    DCHECK(widget == widget_);
 | 
| +    widget_->RemoveObserver(this);
 | 
| +    widget_destroyed_ = true;
 | 
| +    widget_ = nullptr;
 | 
| +  }
 | 
| +
 | 
| +  bool widget_destroyed() const {
 | 
| +    return widget_destroyed_;
 | 
| +  }
 | 
| +
 | 
| + private:
 | 
| +  views::Widget* widget_;
 | 
| +  bool widget_destroyed_;
 | 
| +
 | 
| +  DISALLOW_COPY_AND_ASSIGN(WidgetClosingObserver);
 | 
| +};
 | 
| +
 | 
|  TEST_F(FirstRunBubbleTest, CreateAndClose) {
 | 
|    // Create the anchor and parent widgets.
 | 
|    views::Widget::InitParams params =
 | 
| @@ -64,3 +103,34 @@ TEST_F(FirstRunBubbleTest, CreateAndClose) {
 | 
|    EXPECT_TRUE(delegate != NULL);
 | 
|    delegate->GetWidget()->CloseNow();
 | 
|  }
 | 
| +
 | 
| +// Tests that the first run bubble is closed when keyboard events are
 | 
| +// dispatched to the anchor widget.
 | 
| +TEST_F(FirstRunBubbleTest, CloseBubbleOnKeyEvent) {
 | 
| +  // Create the anchor and parent widgets.
 | 
| +  views::Widget::InitParams params =
 | 
| +      CreateParams(views::Widget::InitParams::TYPE_WINDOW);
 | 
| +  params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
 | 
| +  scoped_ptr<views::Widget> anchor_widget(new views::Widget);
 | 
| +  anchor_widget->Init(params);
 | 
| +  anchor_widget->Show();
 | 
| +
 | 
| +  FirstRunBubble* delegate =
 | 
| +      FirstRunBubble::ShowBubble(NULL, anchor_widget->GetContentsView());
 | 
| +  EXPECT_TRUE(delegate != NULL);
 | 
| +
 | 
| +  anchor_widget->GetFocusManager()->SetFocusedView(
 | 
| +      anchor_widget->GetContentsView());
 | 
| +
 | 
| +  scoped_ptr<WidgetClosingObserver> widget_observer(
 | 
| +      new WidgetClosingObserver(delegate->GetWidget()));
 | 
| +
 | 
| +  ui::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_ESCAPE, ui::EF_NONE);
 | 
| +
 | 
| +  ui::EventDispatchDetails details =
 | 
| +      anchor_widget->GetNativeWindow()->GetHost()->event_processor()->
 | 
| +          OnEventFromSource(&key_event);
 | 
| +  EXPECT_FALSE(details.dispatcher_destroyed);
 | 
| +
 | 
| +  EXPECT_TRUE(widget_observer->widget_destroyed());
 | 
| +}
 | 
| 
 |