| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/bind.h" | 5 #include "base/bind.h" |
| 6 #include "base/utf_string_conversions.h" | 6 #include "base/utf_string_conversions.h" |
| 7 #include "chrome/browser/speech/speech_input_bubble_controller.h" | 7 #include "chrome/browser/speech/speech_recognition_bubble_controller.h" |
| 8 #include "chrome/browser/ui/browser.h" | 8 #include "chrome/browser/ui/browser.h" |
| 9 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" | 9 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" |
| 10 #include "chrome/test/base/browser_with_test_window_test.h" | 10 #include "chrome/test/base/browser_with_test_window_test.h" |
| 11 #include "chrome/test/base/testing_profile.h" | 11 #include "chrome/test/base/testing_profile.h" |
| 12 #include "content/test/test_browser_thread.h" | 12 #include "content/test/test_browser_thread.h" |
| 13 #include "testing/gtest/include/gtest/gtest.h" | 13 #include "testing/gtest/include/gtest/gtest.h" |
| 14 #include "ui/gfx/rect.h" | 14 #include "ui/gfx/rect.h" |
| 15 | 15 |
| 16 using content::BrowserThread; | 16 using content::BrowserThread; |
| 17 using content::WebContents; | 17 using content::WebContents; |
| 18 | 18 |
| 19 class SkBitmap; | 19 class SkBitmap; |
| 20 | 20 |
| 21 namespace speech_input { | 21 namespace speech { |
| 22 | 22 |
| 23 // A mock bubble class which fakes a focus change or recognition cancel by the | 23 // A mock bubble class which fakes a focus change or recognition cancel by the |
| 24 // user and closing of the info bubble. | 24 // user and closing of the info bubble. |
| 25 class MockSpeechInputBubble : public SpeechInputBubbleBase { | 25 class MockSpeechRecognitionBubble : public SpeechRecognitionBubbleBase { |
| 26 public: | 26 public: |
| 27 enum BubbleType { | 27 enum BubbleType { |
| 28 BUBBLE_TEST_FOCUS_CHANGED, | 28 BUBBLE_TEST_FOCUS_CHANGED, |
| 29 BUBBLE_TEST_CLICK_CANCEL, | 29 BUBBLE_TEST_CLICK_CANCEL, |
| 30 BUBBLE_TEST_CLICK_TRY_AGAIN, | 30 BUBBLE_TEST_CLICK_TRY_AGAIN, |
| 31 }; | 31 }; |
| 32 | 32 |
| 33 MockSpeechInputBubble(WebContents* web_contents, | 33 MockSpeechRecognitionBubble(WebContents* web_contents, |
| 34 Delegate* delegate, | 34 Delegate* delegate, |
| 35 const gfx::Rect&) | 35 const gfx::Rect&) |
| 36 : SpeechInputBubbleBase(web_contents) { | 36 : SpeechRecognitionBubbleBase(web_contents) { |
| 37 VLOG(1) << "MockSpeechInputBubble created"; | 37 VLOG(1) << "MockSpeechRecognitionBubble created"; |
| 38 MessageLoop::current()->PostTask( | 38 MessageLoop::current()->PostTask( |
| 39 FROM_HERE, base::Bind(&InvokeDelegate, delegate)); | 39 FROM_HERE, base::Bind(&InvokeDelegate, delegate)); |
| 40 } | 40 } |
| 41 | 41 |
| 42 static void InvokeDelegate(Delegate* delegate) { | 42 static void InvokeDelegate(Delegate* delegate) { |
| 43 VLOG(1) << "MockSpeechInputBubble invoking delegate for type " << type_; | 43 VLOG(1) << "MockSpeechRecognitionBubble invoking delegate for type " |
| 44 << type_; |
| 44 switch (type_) { | 45 switch (type_) { |
| 45 case BUBBLE_TEST_FOCUS_CHANGED: | 46 case BUBBLE_TEST_FOCUS_CHANGED: |
| 46 delegate->InfoBubbleFocusChanged(); | 47 delegate->InfoBubbleFocusChanged(); |
| 47 break; | 48 break; |
| 48 case BUBBLE_TEST_CLICK_CANCEL: | 49 case BUBBLE_TEST_CLICK_CANCEL: |
| 49 delegate->InfoBubbleButtonClicked(SpeechInputBubble::BUTTON_CANCEL); | 50 delegate->InfoBubbleButtonClicked( |
| 51 SpeechRecognitionBubble::BUTTON_CANCEL); |
| 50 break; | 52 break; |
| 51 case BUBBLE_TEST_CLICK_TRY_AGAIN: | 53 case BUBBLE_TEST_CLICK_TRY_AGAIN: |
| 52 delegate->InfoBubbleButtonClicked(SpeechInputBubble::BUTTON_TRY_AGAIN); | 54 delegate->InfoBubbleButtonClicked( |
| 55 SpeechRecognitionBubble::BUTTON_TRY_AGAIN); |
| 53 break; | 56 break; |
| 54 } | 57 } |
| 55 } | 58 } |
| 56 | 59 |
| 57 static void set_type(BubbleType type) { | 60 static void set_type(BubbleType type) { |
| 58 type_ = type; | 61 type_ = type; |
| 59 } | 62 } |
| 60 static BubbleType type() { | 63 static BubbleType type() { |
| 61 return type_; | 64 return type_; |
| 62 } | 65 } |
| 63 | 66 |
| 64 virtual void Show() {} | 67 virtual void Show() {} |
| 65 virtual void Hide() {} | 68 virtual void Hide() {} |
| 66 virtual void UpdateLayout() {} | 69 virtual void UpdateLayout() {} |
| 67 virtual void UpdateImage() {} | 70 virtual void UpdateImage() {} |
| 68 | 71 |
| 69 private: | 72 private: |
| 70 static BubbleType type_; | 73 static BubbleType type_; |
| 71 }; | 74 }; |
| 72 | 75 |
| 73 // The test fixture. | 76 // The test fixture. |
| 74 class SpeechInputBubbleControllerTest | 77 class SpeechRecognitionBubbleControllerTest |
| 75 : public SpeechInputBubbleControllerDelegate, | 78 : public SpeechRecognitionBubbleControllerDelegate, |
| 76 public BrowserWithTestWindowTest { | 79 public BrowserWithTestWindowTest { |
| 77 public: | 80 public: |
| 78 SpeechInputBubbleControllerTest() | 81 SpeechRecognitionBubbleControllerTest() |
| 79 : BrowserWithTestWindowTest(), | 82 : BrowserWithTestWindowTest(), |
| 80 io_thread_(BrowserThread::IO), // constructs a new thread and loop | 83 io_thread_(BrowserThread::IO), // constructs a new thread and loop |
| 81 cancel_clicked_(false), | 84 cancel_clicked_(false), |
| 82 try_again_clicked_(false), | 85 try_again_clicked_(false), |
| 83 focus_changed_(false), | 86 focus_changed_(false), |
| 84 controller_(ALLOW_THIS_IN_INITIALIZER_LIST( | 87 controller_(ALLOW_THIS_IN_INITIALIZER_LIST( |
| 85 new SpeechInputBubbleController(this))) { | 88 new SpeechRecognitionBubbleController(this))) { |
| 86 EXPECT_EQ(NULL, test_fixture_); | 89 EXPECT_EQ(NULL, test_fixture_); |
| 87 test_fixture_ = this; | 90 test_fixture_ = this; |
| 88 } | 91 } |
| 89 | 92 |
| 90 ~SpeechInputBubbleControllerTest() { | 93 ~SpeechRecognitionBubbleControllerTest() { |
| 91 test_fixture_ = NULL; | 94 test_fixture_ = NULL; |
| 92 } | 95 } |
| 93 | 96 |
| 94 // SpeechInputBubbleControllerDelegate methods. | 97 // SpeechRecognitionBubbleControllerDelegate methods. |
| 95 virtual void InfoBubbleButtonClicked(int caller_id, | 98 virtual void InfoBubbleButtonClicked(int caller_id, |
| 96 SpeechInputBubble::Button button) { | 99 SpeechRecognitionBubble::Button button) { |
| 97 VLOG(1) << "Received InfoBubbleButtonClicked for button " << button; | 100 VLOG(1) << "Received InfoBubbleButtonClicked for button " << button; |
| 98 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 101 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 99 if (button == SpeechInputBubble::BUTTON_CANCEL) { | 102 if (button == SpeechRecognitionBubble::BUTTON_CANCEL) { |
| 100 cancel_clicked_ = true; | 103 cancel_clicked_ = true; |
| 101 } else if (button == SpeechInputBubble::BUTTON_TRY_AGAIN) { | 104 } else if (button == SpeechRecognitionBubble::BUTTON_TRY_AGAIN) { |
| 102 try_again_clicked_ = true; | 105 try_again_clicked_ = true; |
| 103 } | 106 } |
| 104 message_loop()->PostTask(FROM_HERE, MessageLoop::QuitClosure()); | 107 message_loop()->PostTask(FROM_HERE, MessageLoop::QuitClosure()); |
| 105 } | 108 } |
| 106 | 109 |
| 107 virtual void InfoBubbleFocusChanged(int caller_id) { | 110 virtual void InfoBubbleFocusChanged(int caller_id) { |
| 108 VLOG(1) << "Received InfoBubbleFocusChanged"; | 111 VLOG(1) << "Received InfoBubbleFocusChanged"; |
| 109 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 112 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 110 focus_changed_ = true; | 113 focus_changed_ = true; |
| 111 message_loop()->PostTask(FROM_HERE, MessageLoop::QuitClosure()); | 114 message_loop()->PostTask(FROM_HERE, MessageLoop::QuitClosure()); |
| 112 } | 115 } |
| 113 | 116 |
| 114 // testing::Test methods. | 117 // testing::Test methods. |
| 115 virtual void SetUp() { | 118 virtual void SetUp() { |
| 116 BrowserWithTestWindowTest::SetUp(); | 119 BrowserWithTestWindowTest::SetUp(); |
| 117 SpeechInputBubble::set_factory( | 120 SpeechRecognitionBubble::set_factory( |
| 118 &SpeechInputBubbleControllerTest::CreateBubble); | 121 &SpeechRecognitionBubbleControllerTest::CreateBubble); |
| 119 io_thread_.Start(); | 122 io_thread_.Start(); |
| 120 } | 123 } |
| 121 | 124 |
| 122 virtual void TearDown() { | 125 virtual void TearDown() { |
| 123 SpeechInputBubble::set_factory(NULL); | 126 SpeechRecognitionBubble::set_factory(NULL); |
| 124 io_thread_.Stop(); | 127 io_thread_.Stop(); |
| 125 BrowserWithTestWindowTest::TearDown(); | 128 BrowserWithTestWindowTest::TearDown(); |
| 126 } | 129 } |
| 127 | 130 |
| 128 static void ActivateBubble() { | 131 static void ActivateBubble() { |
| 129 if (MockSpeechInputBubble::type() == | 132 if (MockSpeechRecognitionBubble::type() == |
| 130 MockSpeechInputBubble::BUBBLE_TEST_FOCUS_CHANGED) { | 133 MockSpeechRecognitionBubble::BUBBLE_TEST_FOCUS_CHANGED) { |
| 131 test_fixture_->controller_->SetBubbleWarmUpMode(kBubbleCallerId); | 134 test_fixture_->controller_->SetBubbleWarmUpMode(kBubbleCallerId); |
| 132 } else { | 135 } else { |
| 133 test_fixture_->controller_->SetBubbleMessage(kBubbleCallerId, | 136 test_fixture_->controller_->SetBubbleMessage(kBubbleCallerId, |
| 134 ASCIIToUTF16("Test")); | 137 ASCIIToUTF16("Test")); |
| 135 } | 138 } |
| 136 } | 139 } |
| 137 | 140 |
| 138 static SpeechInputBubble* CreateBubble(WebContents* web_contents, | 141 static SpeechRecognitionBubble* CreateBubble( |
| 139 SpeechInputBubble::Delegate* delegate, | 142 WebContents* web_contents, |
| 140 const gfx::Rect& element_rect) { | 143 SpeechRecognitionBubble::Delegate* delegate, |
| 144 const gfx::Rect& element_rect) { |
| 141 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 145 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 142 // Set up to activate the bubble soon after it gets created, since we test | 146 // Set up to activate the bubble soon after it gets created, since we test |
| 143 // events sent by the bubble and those are handled only when the bubble is | 147 // events sent by the bubble and those are handled only when the bubble is |
| 144 // active. | 148 // active. |
| 145 MessageLoop::current()->PostTask(FROM_HERE, | 149 MessageLoop::current()->PostTask(FROM_HERE, |
| 146 base::Bind(&ActivateBubble)); | 150 base::Bind(&ActivateBubble)); |
| 147 | 151 |
| 148 // The |tab_contents| parameter would be NULL since the dummy caller id | 152 // The |tab_contents| parameter would be NULL since the dummy caller id |
| 149 // passed to CreateBubble would not have matched any active tab. So get a | 153 // passed to CreateBubble would not have matched any active tab. So get a |
| 150 // real WebContents pointer from the test fixture and pass that, because | 154 // real WebContents pointer from the test fixture and pass that, because |
| 151 // the bubble controller registers for tab close notifications which need | 155 // the bubble controller registers for tab close notifications which need |
| 152 // a valid WebContents. | 156 // a valid WebContents. |
| 153 TabContentsWrapper* wrapper = | 157 TabContentsWrapper* wrapper = |
| 154 test_fixture_->browser()->GetSelectedTabContentsWrapper(); | 158 test_fixture_->browser()->GetSelectedTabContentsWrapper(); |
| 155 if (wrapper) | 159 if (wrapper) |
| 156 web_contents = wrapper->web_contents(); | 160 web_contents = wrapper->web_contents(); |
| 157 return new MockSpeechInputBubble(web_contents, delegate, element_rect); | 161 return new MockSpeechRecognitionBubble(web_contents, delegate, |
| 162 element_rect); |
| 158 } | 163 } |
| 159 | 164 |
| 160 protected: | 165 protected: |
| 161 // The main thread of the test is marked as the IO thread and we create a new | 166 // The main thread of the test is marked as the IO thread and we create a new |
| 162 // one for the UI thread. | 167 // one for the UI thread. |
| 163 content::TestBrowserThread io_thread_; | 168 content::TestBrowserThread io_thread_; |
| 164 bool cancel_clicked_; | 169 bool cancel_clicked_; |
| 165 bool try_again_clicked_; | 170 bool try_again_clicked_; |
| 166 bool focus_changed_; | 171 bool focus_changed_; |
| 167 scoped_refptr<SpeechInputBubbleController> controller_; | 172 scoped_refptr<SpeechRecognitionBubbleController> controller_; |
| 168 | 173 |
| 169 static const int kBubbleCallerId; | 174 static const int kBubbleCallerId; |
| 170 static SpeechInputBubbleControllerTest* test_fixture_; | 175 static SpeechRecognitionBubbleControllerTest* test_fixture_; |
| 171 }; | 176 }; |
| 172 | 177 |
| 173 SpeechInputBubbleControllerTest* | 178 SpeechRecognitionBubbleControllerTest* |
| 174 SpeechInputBubbleControllerTest::test_fixture_ = NULL; | 179 SpeechRecognitionBubbleControllerTest::test_fixture_ = NULL; |
| 175 | 180 |
| 176 const int SpeechInputBubbleControllerTest::kBubbleCallerId = 1; | 181 const int SpeechRecognitionBubbleControllerTest::kBubbleCallerId = 1; |
| 177 | 182 |
| 178 MockSpeechInputBubble::BubbleType MockSpeechInputBubble::type_ = | 183 MockSpeechRecognitionBubble::BubbleType MockSpeechRecognitionBubble::type_ = |
| 179 MockSpeechInputBubble::BUBBLE_TEST_FOCUS_CHANGED; | 184 MockSpeechRecognitionBubble::BUBBLE_TEST_FOCUS_CHANGED; |
| 180 | 185 |
| 181 // Test that the speech bubble UI gets created in the UI thread and that the | 186 // Test that the speech bubble UI gets created in the UI thread and that the |
| 182 // focus changed callback comes back in the IO thread. | 187 // focus changed callback comes back in the IO thread. |
| 183 TEST_F(SpeechInputBubbleControllerTest, TestFocusChanged) { | 188 TEST_F(SpeechRecognitionBubbleControllerTest, TestFocusChanged) { |
| 184 MockSpeechInputBubble::set_type( | 189 MockSpeechRecognitionBubble::set_type( |
| 185 MockSpeechInputBubble::BUBBLE_TEST_FOCUS_CHANGED); | 190 MockSpeechRecognitionBubble::BUBBLE_TEST_FOCUS_CHANGED); |
| 186 | 191 |
| 187 controller_->CreateBubble(kBubbleCallerId, 1, 1, gfx::Rect(1, 1)); | 192 controller_->CreateBubble(kBubbleCallerId, 1, 1, gfx::Rect(1, 1)); |
| 188 MessageLoop::current()->Run(); | 193 MessageLoop::current()->Run(); |
| 189 EXPECT_TRUE(focus_changed_); | 194 EXPECT_TRUE(focus_changed_); |
| 190 EXPECT_FALSE(cancel_clicked_); | 195 EXPECT_FALSE(cancel_clicked_); |
| 191 EXPECT_FALSE(try_again_clicked_); | 196 EXPECT_FALSE(try_again_clicked_); |
| 192 controller_->CloseBubble(kBubbleCallerId); | 197 controller_->CloseBubble(kBubbleCallerId); |
| 193 } | 198 } |
| 194 | 199 |
| 195 // Test that the speech bubble UI gets created in the UI thread and that the | 200 // Test that the speech bubble UI gets created in the UI thread and that the |
| 196 // recognition cancelled callback comes back in the IO thread. | 201 // recognition cancelled callback comes back in the IO thread. |
| 197 TEST_F(SpeechInputBubbleControllerTest, TestRecognitionCancelled) { | 202 TEST_F(SpeechRecognitionBubbleControllerTest, TestRecognitionCancelled) { |
| 198 MockSpeechInputBubble::set_type( | 203 MockSpeechRecognitionBubble::set_type( |
| 199 MockSpeechInputBubble::BUBBLE_TEST_CLICK_CANCEL); | 204 MockSpeechRecognitionBubble::BUBBLE_TEST_CLICK_CANCEL); |
| 200 | 205 |
| 201 controller_->CreateBubble(kBubbleCallerId, 1, 1, gfx::Rect(1, 1)); | 206 controller_->CreateBubble(kBubbleCallerId, 1, 1, gfx::Rect(1, 1)); |
| 202 MessageLoop::current()->Run(); | 207 MessageLoop::current()->Run(); |
| 203 EXPECT_TRUE(cancel_clicked_); | 208 EXPECT_TRUE(cancel_clicked_); |
| 204 EXPECT_FALSE(try_again_clicked_); | 209 EXPECT_FALSE(try_again_clicked_); |
| 205 EXPECT_FALSE(focus_changed_); | 210 EXPECT_FALSE(focus_changed_); |
| 206 controller_->CloseBubble(kBubbleCallerId); | 211 controller_->CloseBubble(kBubbleCallerId); |
| 207 } | 212 } |
| 208 | 213 |
| 209 // Test that the speech bubble UI gets created in the UI thread and that the | 214 // Test that the speech bubble UI gets created in the UI thread and that the |
| 210 // try-again button click event comes back in the IO thread. | 215 // try-again button click event comes back in the IO thread. |
| 211 TEST_F(SpeechInputBubbleControllerTest, TestTryAgainClicked) { | 216 TEST_F(SpeechRecognitionBubbleControllerTest, TestTryAgainClicked) { |
| 212 MockSpeechInputBubble::set_type( | 217 MockSpeechRecognitionBubble::set_type( |
| 213 MockSpeechInputBubble::BUBBLE_TEST_CLICK_TRY_AGAIN); | 218 MockSpeechRecognitionBubble::BUBBLE_TEST_CLICK_TRY_AGAIN); |
| 214 | 219 |
| 215 controller_->CreateBubble(kBubbleCallerId, 1, 1, gfx::Rect(1, 1)); | 220 controller_->CreateBubble(kBubbleCallerId, 1, 1, gfx::Rect(1, 1)); |
| 216 MessageLoop::current()->Run(); | 221 MessageLoop::current()->Run(); |
| 217 EXPECT_FALSE(cancel_clicked_); | 222 EXPECT_FALSE(cancel_clicked_); |
| 218 EXPECT_TRUE(try_again_clicked_); | 223 EXPECT_TRUE(try_again_clicked_); |
| 219 EXPECT_FALSE(focus_changed_); | 224 EXPECT_FALSE(focus_changed_); |
| 220 controller_->CloseBubble(kBubbleCallerId); | 225 controller_->CloseBubble(kBubbleCallerId); |
| 221 } | 226 } |
| 222 | 227 |
| 223 } // namespace speech_input | 228 } // namespace speech |
| OLD | NEW |