1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Use of this source code is governed by a BSD-style license that can be
3bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// found in the LICENSE file.
4bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
5bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/utf_string_conversions.h"
6bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/speech/speech_input_bubble_controller.h"
772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/browser.h"
83f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "chrome/test/browser_with_test_window_test.h"
93f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "chrome/test/testing_profile.h"
10dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h"
11bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "testing/gtest/include/gtest/gtest.h"
1272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/rect.h"
13bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
14bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenclass SkBitmap;
15bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
16bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsennamespace speech_input {
17bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
18bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// A mock bubble class which fakes a focus change or recognition cancel by the
19bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// user and closing of the info bubble.
20bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenclass MockSpeechInputBubble : public SpeechInputBubbleBase {
21bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen public:
22bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  enum BubbleType {
23bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    BUBBLE_TEST_FOCUS_CHANGED,
24bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    BUBBLE_TEST_CLICK_CANCEL,
25bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    BUBBLE_TEST_CLICK_TRY_AGAIN,
26bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  };
27bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
283f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  MockSpeechInputBubble(TabContents* tab_contents,
293f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                        Delegate* delegate,
303f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                        const gfx::Rect&)
313f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      : SpeechInputBubbleBase(tab_contents) {
32731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    VLOG(1) << "MockSpeechInputBubble created";
33bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    MessageLoop::current()->PostTask(
34bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        FROM_HERE, NewRunnableFunction(&InvokeDelegate, delegate));
35bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
36bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
37bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  static void InvokeDelegate(Delegate* delegate) {
38731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    VLOG(1) << "MockSpeechInputBubble invoking delegate for type " << type_;
39bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    switch (type_) {
40bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      case BUBBLE_TEST_FOCUS_CHANGED:
41bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        delegate->InfoBubbleFocusChanged();
42bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        break;
43bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      case BUBBLE_TEST_CLICK_CANCEL:
44bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        delegate->InfoBubbleButtonClicked(SpeechInputBubble::BUTTON_CANCEL);
45bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        break;
46bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      case BUBBLE_TEST_CLICK_TRY_AGAIN:
47bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        delegate->InfoBubbleButtonClicked(SpeechInputBubble::BUTTON_TRY_AGAIN);
48bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        break;
49bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    }
50bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
51bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
52bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  static void set_type(BubbleType type) {
53bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    type_ = type;
54bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
55bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  static BubbleType type() {
56bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    return type_;
57bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
58bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
59bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  virtual void Show() {}
60bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  virtual void Hide() {}
61bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  virtual void UpdateLayout() {}
62ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void UpdateImage() {}
63bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
64bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen private:
65bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  static BubbleType type_;
66bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen};
67bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
68bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// The test fixture.
69bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenclass SpeechInputBubbleControllerTest
70bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    : public SpeechInputBubbleControllerDelegate,
713f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      public BrowserWithTestWindowTest {
72bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen public:
73bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  SpeechInputBubbleControllerTest()
743f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      : BrowserWithTestWindowTest(),
753f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        io_thread_(BrowserThread::IO),  // constructs a new thread and loop
76bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        cancel_clicked_(false),
77bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        try_again_clicked_(false),
78bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        focus_changed_(false),
79bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        controller_(ALLOW_THIS_IN_INITIALIZER_LIST(
80bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen            new SpeechInputBubbleController(this))) {
81bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    EXPECT_EQ(NULL, test_fixture_);
82bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    test_fixture_ = this;
83bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
84bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
85bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  ~SpeechInputBubbleControllerTest() {
86bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    test_fixture_ = NULL;
87bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
88bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
89bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // SpeechInputBubbleControllerDelegate methods.
90bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  virtual void InfoBubbleButtonClicked(int caller_id,
91bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                                       SpeechInputBubble::Button button) {
92731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    VLOG(1) << "Received InfoBubbleButtonClicked for button " << button;
93731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
94bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    if (button == SpeechInputBubble::BUTTON_CANCEL) {
95bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      cancel_clicked_ = true;
96bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    } else if (button == SpeechInputBubble::BUTTON_TRY_AGAIN) {
97bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      try_again_clicked_ = true;
98bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    }
993f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    message_loop()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
100bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
101bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
102bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  virtual void InfoBubbleFocusChanged(int caller_id) {
103731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    VLOG(1) << "Received InfoBubbleFocusChanged";
104731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
105bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    focus_changed_ = true;
1063f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    message_loop()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
107bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
108bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
109bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // testing::Test methods.
110bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  virtual void SetUp() {
1113f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    BrowserWithTestWindowTest::SetUp();
112bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    SpeechInputBubble::set_factory(
113bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        &SpeechInputBubbleControllerTest::CreateBubble);
1143f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    io_thread_.Start();
115bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
116bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
117bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  virtual void TearDown() {
118bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    SpeechInputBubble::set_factory(NULL);
1193f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    io_thread_.Stop();
1203f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    BrowserWithTestWindowTest::TearDown();
121bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
122bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
123bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  static void ActivateBubble() {
124bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    if (MockSpeechInputBubble::type() ==
125bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        MockSpeechInputBubble::BUBBLE_TEST_FOCUS_CHANGED) {
126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      test_fixture_->controller_->SetBubbleWarmUpMode(kBubbleCallerId);
127bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    } else {
128bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      test_fixture_->controller_->SetBubbleMessage(kBubbleCallerId,
129bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                                                   ASCIIToUTF16("Test"));
130bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    }
131bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
132bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
133bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  static SpeechInputBubble* CreateBubble(TabContents* tab_contents,
134bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                                         SpeechInputBubble::Delegate* delegate,
135bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                                         const gfx::Rect& element_rect) {
136731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
137bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    // Set up to activate the bubble soon after it gets created, since we test
138bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    // events sent by the bubble and those are handled only when the bubble is
139bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    // active.
140bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    MessageLoop::current()->PostTask(FROM_HERE,
141bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                                     NewRunnableFunction(&ActivateBubble));
1423f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1433f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // The |tab_contents| parameter would be NULL since the dummy caller id
1443f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // passed to CreateBubble would not have matched any active tab. So get a
1453f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // real TabContents pointer from the test fixture and pass that, because
1463f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // the bubble controller registers for tab close notifications which need
1473f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // a valid TabContents.
1483f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    tab_contents = test_fixture_->browser()->GetSelectedTabContents();
149bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    return new MockSpeechInputBubble(tab_contents, delegate, element_rect);
150bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
151bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
152bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen protected:
153bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // The main thread of the test is marked as the IO thread and we create a new
154bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // one for the UI thread.
155731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread io_thread_;
156bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  bool cancel_clicked_;
157bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  bool try_again_clicked_;
158bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  bool focus_changed_;
159bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  scoped_refptr<SpeechInputBubbleController> controller_;
160bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
161bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  static const int kBubbleCallerId;
162bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  static SpeechInputBubbleControllerTest* test_fixture_;
163bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen};
164bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
165bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian MonsenSpeechInputBubbleControllerTest*
166bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian MonsenSpeechInputBubbleControllerTest::test_fixture_ = NULL;
167bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
168bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst int SpeechInputBubbleControllerTest::kBubbleCallerId = 1;
169bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
170bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian MonsenMockSpeechInputBubble::BubbleType MockSpeechInputBubble::type_ =
171bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    MockSpeechInputBubble::BUBBLE_TEST_FOCUS_CHANGED;
172bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
173bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Test that the speech bubble UI gets created in the UI thread and that the
174bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// focus changed callback comes back in the IO thread.
175731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(SpeechInputBubbleControllerTest, TestFocusChanged) {
176bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  MockSpeechInputBubble::set_type(
177bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      MockSpeechInputBubble::BUBBLE_TEST_FOCUS_CHANGED);
178bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
179bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  controller_->CreateBubble(kBubbleCallerId, 1, 1, gfx::Rect(1, 1));
180bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  MessageLoop::current()->Run();
181bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  EXPECT_TRUE(focus_changed_);
182bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  EXPECT_FALSE(cancel_clicked_);
183bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  EXPECT_FALSE(try_again_clicked_);
184bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  controller_->CloseBubble(kBubbleCallerId);
185bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
186bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
187bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Test that the speech bubble UI gets created in the UI thread and that the
188bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// recognition cancelled callback comes back in the IO thread.
189bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian MonsenTEST_F(SpeechInputBubbleControllerTest, TestRecognitionCancelled) {
190bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  MockSpeechInputBubble::set_type(
191bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      MockSpeechInputBubble::BUBBLE_TEST_CLICK_CANCEL);
192bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
193bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  controller_->CreateBubble(kBubbleCallerId, 1, 1, gfx::Rect(1, 1));
194bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  MessageLoop::current()->Run();
195bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  EXPECT_TRUE(cancel_clicked_);
196bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  EXPECT_FALSE(try_again_clicked_);
197bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  EXPECT_FALSE(focus_changed_);
198bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  controller_->CloseBubble(kBubbleCallerId);
199bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
200bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
201bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Test that the speech bubble UI gets created in the UI thread and that the
202bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// try-again button click event comes back in the IO thread.
203bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian MonsenTEST_F(SpeechInputBubbleControllerTest, TestTryAgainClicked) {
204bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  MockSpeechInputBubble::set_type(
205bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      MockSpeechInputBubble::BUBBLE_TEST_CLICK_TRY_AGAIN);
206bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
207bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  controller_->CreateBubble(kBubbleCallerId, 1, 1, gfx::Rect(1, 1));
208bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  MessageLoop::current()->Run();
209bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  EXPECT_FALSE(cancel_clicked_);
210bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  EXPECT_TRUE(try_again_clicked_);
211bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  EXPECT_FALSE(focus_changed_);
212bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  controller_->CloseBubble(kBubbleCallerId);
213bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
214bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
215bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}  // namespace speech_input
216