Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(220)

Side by Side Diff: ui/keyboard/keyboard_controller_unittest.cc

Issue 22831045: Delay virtual keyboard hiding for 100ms (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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/memory/scoped_ptr.h" 6 #include "base/memory/scoped_ptr.h"
6 #include "base/message_loop/message_loop.h" 7 #include "base/message_loop/message_loop.h"
7 #include "testing/gtest/include/gtest/gtest.h" 8 #include "testing/gtest/include/gtest/gtest.h"
8 #include "ui/aura/client/focus_client.h" 9 #include "ui/aura/client/focus_client.h"
9 #include "ui/aura/root_window.h" 10 #include "ui/aura/root_window.h"
10 #include "ui/aura/test/aura_test_helper.h" 11 #include "ui/aura/test/aura_test_helper.h"
11 #include "ui/aura/test/event_generator.h" 12 #include "ui/aura/test/event_generator.h"
12 #include "ui/aura/test/test_window_delegate.h" 13 #include "ui/aura/test/test_window_delegate.h"
13 #include "ui/aura/window.h" 14 #include "ui/aura/window.h"
14 #include "ui/base/ime/input_method.h" 15 #include "ui/base/ime/input_method.h"
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 virtual bool ChangeTextDirectionAndLayoutAlignment( 152 virtual bool ChangeTextDirectionAndLayoutAlignment(
152 base::i18n::TextDirection direction) OVERRIDE { return false; } 153 base::i18n::TextDirection direction) OVERRIDE { return false; }
153 virtual void ExtendSelectionAndDelete(size_t before, size_t after) OVERRIDE {} 154 virtual void ExtendSelectionAndDelete(size_t before, size_t after) OVERRIDE {}
154 virtual void EnsureCaretInRect(const gfx::Rect& rect) OVERRIDE {} 155 virtual void EnsureCaretInRect(const gfx::Rect& rect) OVERRIDE {}
155 156
156 ui::TextInputType type_; 157 ui::TextInputType type_;
157 158
158 DISALLOW_COPY_AND_ASSIGN(TestTextInputClient); 159 DISALLOW_COPY_AND_ASSIGN(TestTextInputClient);
159 }; 160 };
160 161
162 class KeyboardContainerObserver : public aura::WindowObserver {
163 public:
164 explicit KeyboardContainerObserver(aura::Window* window) : window_(window) {
165 window_->AddObserver(this);
166 }
167 virtual ~KeyboardContainerObserver() {
168 window_->RemoveObserver(this);
169 }
170
171 private:
172 virtual void OnWindowVisibilityChanged(aura::Window* window,
173 bool visible) OVERRIDE {
sadrul 2013/08/29 23:43:54 Fix indent
bshe 2013/08/30 15:54:19 Done.
174 if (!visible)
175 base::MessageLoop::current()->Quit();
176 }
177
178 aura::Window* window_;
179
180 DISALLOW_COPY_AND_ASSIGN(KeyboardContainerObserver);
181 };
182
161 } // namespace 183 } // namespace
162 184
163 class KeyboardControllerTest : public testing::Test { 185 class KeyboardControllerTest : public testing::Test {
164 public: 186 public:
165 KeyboardControllerTest() {} 187 KeyboardControllerTest() {}
166 virtual ~KeyboardControllerTest() {} 188 virtual ~KeyboardControllerTest() {}
167 189
168 virtual void SetUp() OVERRIDE { 190 virtual void SetUp() OVERRIDE {
169 aura_test_helper_.reset(new aura::test::AuraTestHelper(&message_loop_)); 191 aura_test_helper_.reset(new aura::test::AuraTestHelper(&message_loop_));
170 aura_test_helper_->SetUp(); 192 aura_test_helper_->SetUp();
171 ui::SetUpInputMethodFactoryForTesting(); 193 ui::SetUpInputMethodFactoryForTesting();
172 focus_controller_.reset(new TestFocusController(root_window())); 194 focus_controller_.reset(new TestFocusController(root_window()));
195 proxy_ = new TestKeyboardControllerProxy();
196 controller_.reset(new KeyboardController(proxy_));
173 } 197 }
174 198
175 virtual void TearDown() OVERRIDE { 199 virtual void TearDown() OVERRIDE {
176 focus_controller_.reset(); 200 focus_controller_.reset();
177 aura_test_helper_->TearDown(); 201 aura_test_helper_->TearDown();
178 } 202 }
179 203
180 aura::RootWindow* root_window() { return aura_test_helper_->root_window(); } 204 aura::RootWindow* root_window() { return aura_test_helper_->root_window(); }
205 KeyboardControllerProxy* proxy() { return proxy_; }
206 KeyboardController* controller() { return controller_.get(); }
181 207
182 void ShowKeyboard(KeyboardController* controller) { 208 void ShowKeyboard() {
183 TestTextInputClient test_text_input_client(ui::TEXT_INPUT_TYPE_TEXT); 209 TestTextInputClient test_text_input_client(ui::TEXT_INPUT_TYPE_TEXT);
184 controller->OnTextInputStateChanged(&test_text_input_client); 210 controller_->OnTextInputStateChanged(&test_text_input_client);
185 } 211 }
186 212
187 protected: 213 protected:
214 bool WillHideKeyboard() {
215 return controller_->WillHideKeyboard();
216 }
217
188 base::MessageLoopForUI message_loop_; 218 base::MessageLoopForUI message_loop_;
189 scoped_ptr<aura::test::AuraTestHelper> aura_test_helper_; 219 scoped_ptr<aura::test::AuraTestHelper> aura_test_helper_;
190 scoped_ptr<TestFocusController> focus_controller_; 220 scoped_ptr<TestFocusController> focus_controller_;
191 221
192 private: 222 private:
223 KeyboardControllerProxy* proxy_;
224 scoped_ptr<KeyboardController> controller_;
225
193 DISALLOW_COPY_AND_ASSIGN(KeyboardControllerTest); 226 DISALLOW_COPY_AND_ASSIGN(KeyboardControllerTest);
194 }; 227 };
195 228
196 TEST_F(KeyboardControllerTest, KeyboardSize) { 229 TEST_F(KeyboardControllerTest, KeyboardSize) {
197 KeyboardControllerProxy* proxy = new TestKeyboardControllerProxy(); 230 scoped_ptr<aura::Window> container(controller()->GetContainerWindow());
198 KeyboardController controller(proxy);
199
200 scoped_ptr<aura::Window> container(controller.GetContainerWindow());
201 gfx::Rect bounds(0, 0, 100, 100); 231 gfx::Rect bounds(0, 0, 100, 100);
202 container->SetBounds(bounds); 232 container->SetBounds(bounds);
203 233
204 const gfx::Rect& before_bounds = proxy->GetKeyboardWindow()->bounds(); 234 const gfx::Rect& before_bounds = proxy()->GetKeyboardWindow()->bounds();
205 gfx::Rect new_bounds( 235 gfx::Rect new_bounds(
206 before_bounds.x(), before_bounds.y(), 236 before_bounds.x(), before_bounds.y(),
207 before_bounds.width() / 2, before_bounds.height() / 2); 237 before_bounds.width() / 2, before_bounds.height() / 2);
208 238
209 // The KeyboardController's LayoutManager shouldn't let this happen 239 // The KeyboardController's LayoutManager shouldn't let this happen
210 proxy->GetKeyboardWindow()->SetBounds(new_bounds); 240 proxy()->GetKeyboardWindow()->SetBounds(new_bounds);
211 ASSERT_EQ(before_bounds, proxy->GetKeyboardWindow()->bounds()); 241 ASSERT_EQ(before_bounds, proxy()->GetKeyboardWindow()->bounds());
212 } 242 }
213 243
214 // Tests that tapping/clicking inside the keyboard does not give it focus. 244 // Tests that tapping/clicking inside the keyboard does not give it focus.
215 TEST_F(KeyboardControllerTest, ClickDoesNotFocusKeyboard) { 245 TEST_F(KeyboardControllerTest, ClickDoesNotFocusKeyboard) {
216 const gfx::Rect& root_bounds = root_window()->bounds(); 246 const gfx::Rect& root_bounds = root_window()->bounds();
217 aura::test::EventCountDelegate delegate; 247 aura::test::EventCountDelegate delegate;
218 scoped_ptr<aura::Window> window(new aura::Window(&delegate)); 248 scoped_ptr<aura::Window> window(new aura::Window(&delegate));
219 window->Init(ui::LAYER_NOT_DRAWN); 249 window->Init(ui::LAYER_NOT_DRAWN);
220 window->SetBounds(root_bounds); 250 window->SetBounds(root_bounds);
221 root_window()->AddChild(window.get()); 251 root_window()->AddChild(window.get());
222 window->Show(); 252 window->Show();
223 window->Focus(); 253 window->Focus();
224 254
225 KeyboardControllerProxy* proxy = new TestKeyboardControllerProxy(); 255 scoped_ptr<aura::Window> keyboard_container(
226 KeyboardController controller(proxy); 256 controller()->GetContainerWindow());
227
228 scoped_ptr<aura::Window> keyboard_container(controller.GetContainerWindow());
229 keyboard_container->SetBounds(root_bounds); 257 keyboard_container->SetBounds(root_bounds);
230 258
231 root_window()->AddChild(keyboard_container.get()); 259 root_window()->AddChild(keyboard_container.get());
232 keyboard_container->Show(); 260 keyboard_container->Show();
233 261
234 ShowKeyboard(&controller); 262 ShowKeyboard();
235 263
236 EXPECT_TRUE(window->IsVisible()); 264 EXPECT_TRUE(window->IsVisible());
237 EXPECT_TRUE(keyboard_container->IsVisible()); 265 EXPECT_TRUE(keyboard_container->IsVisible());
238 EXPECT_TRUE(window->HasFocus()); 266 EXPECT_TRUE(window->HasFocus());
239 EXPECT_FALSE(keyboard_container->HasFocus()); 267 EXPECT_FALSE(keyboard_container->HasFocus());
240 268
241 // Click on the keyboard. Make sure the keyboard receives the event, but does 269 // Click on the keyboard. Make sure the keyboard receives the event, but does
242 // not get focus. 270 // not get focus.
243 EventObserver observer; 271 EventObserver observer;
244 keyboard_container->AddPreTargetHandler(&observer); 272 keyboard_container->AddPreTargetHandler(&observer);
245 273
246 aura::test::EventGenerator generator(root_window()); 274 aura::test::EventGenerator generator(root_window());
247 generator.MoveMouseTo(proxy->GetKeyboardWindow()->bounds().CenterPoint()); 275 generator.MoveMouseTo(proxy()->GetKeyboardWindow()->bounds().CenterPoint());
248 generator.ClickLeftButton(); 276 generator.ClickLeftButton();
249 EXPECT_TRUE(window->HasFocus()); 277 EXPECT_TRUE(window->HasFocus());
250 EXPECT_FALSE(keyboard_container->HasFocus()); 278 EXPECT_FALSE(keyboard_container->HasFocus());
251 EXPECT_EQ("0 0", delegate.GetMouseButtonCountsAndReset()); 279 EXPECT_EQ("0 0", delegate.GetMouseButtonCountsAndReset());
252 EXPECT_EQ(1, observer.GetEventCount(ui::ET_MOUSE_PRESSED)); 280 EXPECT_EQ(1, observer.GetEventCount(ui::ET_MOUSE_PRESSED));
253 EXPECT_EQ(1, observer.GetEventCount(ui::ET_MOUSE_RELEASED)); 281 EXPECT_EQ(1, observer.GetEventCount(ui::ET_MOUSE_RELEASED));
254 282
255 // Click outside of the keyboard. It should reach the window behind. 283 // Click outside of the keyboard. It should reach the window behind.
256 generator.MoveMouseTo(gfx::Point()); 284 generator.MoveMouseTo(gfx::Point());
257 generator.ClickLeftButton(); 285 generator.ClickLeftButton();
258 EXPECT_EQ("1 1", delegate.GetMouseButtonCountsAndReset()); 286 EXPECT_EQ("1 1", delegate.GetMouseButtonCountsAndReset());
259 } 287 }
260 288
261 TEST_F(KeyboardControllerTest, VisibilityChangeWithTextInputTypeChange) { 289 TEST_F(KeyboardControllerTest, VisibilityChangeWithTextInputTypeChange) {
262 const gfx::Rect& root_bounds = root_window()->bounds(); 290 const gfx::Rect& root_bounds = root_window()->bounds();
263 aura::test::EventCountDelegate delegate;
264 scoped_ptr<aura::Window> window(new aura::Window(&delegate));
265 window->Init(ui::LAYER_NOT_DRAWN);
266 window->SetBounds(root_bounds);
267 root_window()->AddChild(window.get());
268 window->Show();
269 window->Focus();
270 291
271 KeyboardControllerProxy* proxy = new TestKeyboardControllerProxy(); 292 ui::InputMethod* input_method = proxy()->GetInputMethod();
272 ui::InputMethod* input_method = proxy->GetInputMethod(); 293 TestTextInputClient input_client_0(ui::TEXT_INPUT_TYPE_TEXT);
273 TestTextInputClient input_client(ui::TEXT_INPUT_TYPE_TEXT); 294 TestTextInputClient input_client_1(ui::TEXT_INPUT_TYPE_TEXT);
274 TestTextInputClient no_input_client(ui::TEXT_INPUT_TYPE_NONE); 295 TestTextInputClient input_client_2(ui::TEXT_INPUT_TYPE_TEXT);
275 input_method->SetFocusedTextInputClient(&input_client); 296 TestTextInputClient no_input_client_0(ui::TEXT_INPUT_TYPE_NONE);
297 TestTextInputClient no_input_client_1(ui::TEXT_INPUT_TYPE_NONE);
298 input_method->SetFocusedTextInputClient(&input_client_0);
276 299
277 KeyboardController controller(proxy); 300 scoped_ptr<aura::Window> keyboard_container(
278 301 controller()->GetContainerWindow());
279 scoped_ptr<aura::Window> keyboard_container(controller.GetContainerWindow()); 302 scoped_ptr<KeyboardContainerObserver> keyboard_container_observer(
303 new KeyboardContainerObserver(keyboard_container.get()));
280 keyboard_container->SetBounds(root_bounds); 304 keyboard_container->SetBounds(root_bounds);
281 root_window()->AddChild(keyboard_container.get()); 305 root_window()->AddChild(keyboard_container.get());
282 306
283 EXPECT_TRUE(keyboard_container->IsVisible()); 307 EXPECT_TRUE(keyboard_container->IsVisible());
284 308
285 input_method->SetFocusedTextInputClient(&no_input_client); 309 input_method->SetFocusedTextInputClient(&no_input_client_0);
310 // Keyboard should not immediately hide itself. It is delayed to avoid layout
311 // flicker when the focus of input field quickly change.
312 EXPECT_TRUE(keyboard_container->IsVisible());
sadrul 2013/08/29 23:43:54 Also, EXPECT_TRUE(WillHideKeyboard());
bshe 2013/08/30 15:54:19 Done.
313 // Wait for hide keyboard to finish.
314 base::MessageLoop::current()->Run();
286 EXPECT_FALSE(keyboard_container->IsVisible()); 315 EXPECT_FALSE(keyboard_container->IsVisible());
287 316
288 input_method->SetFocusedTextInputClient(&input_client); 317 input_method->SetFocusedTextInputClient(&input_client_1);
318 EXPECT_TRUE(keyboard_container->IsVisible());
319
320 // Schedule to hide keyboard.
321 input_method->SetFocusedTextInputClient(&no_input_client_1);
sadrul 2013/08/29 23:43:54 EXPECT_TRUE(WillHideKeyboard());
bshe 2013/08/30 15:54:19 Done.
322 // Cancel keyboard hide.
323 input_method->SetFocusedTextInputClient(&input_client_2);
324
325 EXPECT_FALSE(WillHideKeyboard());
289 EXPECT_TRUE(keyboard_container->IsVisible()); 326 EXPECT_TRUE(keyboard_container->IsVisible());
290 } 327 }
291 328
292 } // namespace keyboard 329 } // namespace keyboard
OLDNEW
« ui/keyboard/keyboard_controller.h ('K') | « ui/keyboard/keyboard_controller.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698