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

Side by Side Diff: content/browser/renderer_host/render_widget_host_view_mac_unittest.mm

Issue 2229223002: Route IME-related IPCs to the active/focused RenderWidget (Mac) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed erickchen@ comments + Making RWHVMacTest -> InputMethodMacTest. Created 4 years, 4 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
OLDNEW
1 // Copyright (c) 2012 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 "content/browser/renderer_host/render_widget_host_view_mac.h" 5 #include "content/browser/renderer_host/render_widget_host_view_mac.h"
6 6
7 #include <Cocoa/Cocoa.h> 7 #include <Cocoa/Cocoa.h>
8 #include <stddef.h> 8 #include <stddef.h>
9 #include <stdint.h> 9 #include <stdint.h>
10 #include <tuple> 10 #include <tuple>
11 11
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/mac/scoped_nsautorelease_pool.h" 13 #include "base/mac/scoped_nsautorelease_pool.h"
14 #include "base/mac/sdk_forward_declarations.h" 14 #include "base/mac/sdk_forward_declarations.h"
15 #include "base/macros.h" 15 #include "base/macros.h"
16 #include "base/run_loop.h" 16 #include "base/run_loop.h"
17 #include "base/strings/utf_string_conversions.h" 17 #include "base/strings/utf_string_conversions.h"
18 #include "base/test/histogram_tester.h" 18 #include "base/test/histogram_tester.h"
19 #include "base/test/simple_test_tick_clock.h" 19 #include "base/test/simple_test_tick_clock.h"
20 #include "content/browser/browser_thread_impl.h" 20 #include "content/browser/browser_thread_impl.h"
21 #include "content/browser/compositor/test/no_transport_image_transport_factory.h " 21 #include "content/browser/compositor/test/no_transport_image_transport_factory.h "
22 #include "content/browser/frame_host/render_widget_host_view_guest.h" 22 #include "content/browser/frame_host/render_widget_host_view_guest.h"
23 #include "content/browser/gpu/compositor_util.h" 23 #include "content/browser/gpu/compositor_util.h"
24 #include "content/browser/renderer_host/render_widget_host_delegate.h" 24 #include "content/browser/renderer_host/render_widget_host_delegate.h"
25 #include "content/browser/renderer_host/text_input_manager.h"
25 #include "content/common/input/web_input_event_traits.h" 26 #include "content/common/input/web_input_event_traits.h"
26 #include "content/common/input_messages.h" 27 #include "content/common/input_messages.h"
28 #include "content/common/text_input_state.h"
27 #include "content/common/view_messages.h" 29 #include "content/common/view_messages.h"
28 #include "content/public/browser/notification_types.h" 30 #include "content/public/browser/notification_types.h"
29 #include "content/public/browser/render_widget_host_view_mac_delegate.h" 31 #include "content/public/browser/render_widget_host_view_mac_delegate.h"
30 #include "content/public/common/content_switches.h" 32 #include "content/public/common/content_switches.h"
31 #include "content/public/test/mock_render_process_host.h" 33 #include "content/public/test/mock_render_process_host.h"
32 #include "content/public/test/test_browser_context.h" 34 #include "content/public/test/test_browser_context.h"
33 #include "content/public/test/test_utils.h" 35 #include "content/public/test/test_utils.h"
34 #include "content/test/test_render_view_host.h" 36 #include "content/test/test_render_view_host.h"
35 #include "gpu/ipc/common/gpu_messages.h" 37 #include "gpu/ipc/common/gpu_messages.h"
36 #include "testing/gmock/include/gmock/gmock.h" 38 #include "testing/gmock/include/gmock/gmock.h"
(...skipping 1203 matching lines...) Expand 10 before | Expand all | Expand 10 after
1240 // Send an initial wheel event for scrolling by 3 lines. 1242 // Send an initial wheel event for scrolling by 3 lines.
1241 // Verify that Event.Latency.OS.MOUSE_WHEEL histogram is computed properly. 1243 // Verify that Event.Latency.OS.MOUSE_WHEEL histogram is computed properly.
1242 NSEvent* wheelEvent = MockScrollWheelEventWithPhase(@selector(phaseBegan),3); 1244 NSEvent* wheelEvent = MockScrollWheelEventWithPhase(@selector(phaseBegan),3);
1243 [view->cocoa_view() scrollWheel:wheelEvent]; 1245 [view->cocoa_view() scrollWheel:wheelEvent];
1244 histogram_tester.ExpectTotalCount("Event.Latency.OS.MOUSE_WHEEL", 1); 1246 histogram_tester.ExpectTotalCount("Event.Latency.OS.MOUSE_WHEEL", 1);
1245 1247
1246 // Clean up. 1248 // Clean up.
1247 host->ShutdownAndDestroyWidget(true); 1249 host->ShutdownAndDestroyWidget(true);
1248 } 1250 }
1249 1251
1252 // This class is used for IME-related unit tests which verify correctness of IME
1253 // for pages with multiple RWHVs.
1254 class InputMethodMacTest : public RenderWidgetHostViewMacTest {
1255 public:
1256 InputMethodMacTest() {}
1257 ~InputMethodMacTest() override {}
1258 void SetUp() override {
1259 RenderWidgetHostViewMacTest::SetUp();
1260
1261 // Initializing a child frame's view.
1262 child_process_host_ = new MockRenderProcessHost(&browser_context_);
1263 RenderWidgetHostDelegate* rwh_delegate =
1264 RenderWidgetHostImpl::From(rvh()->GetWidget())->delegate();
1265 child_widget_ = new RenderWidgetHostImpl(
1266 rwh_delegate, child_process_host_,
1267 child_process_host_->GetNextRoutingID(), false);
1268 child_view_ = new TestRenderWidgetHostView(child_widget_);
1269 text_input_manager_ = rwh_delegate->GetTextInputManager();
1270 tab_widget_ = RenderWidgetHostImpl::From(rvh()->GetWidget());
1271 }
1272
1273 void TearDown() override {
1274 child_widget_->ShutdownAndDestroyWidget(true);
1275
1276 RenderWidgetHostViewMacTest::TearDown();
1277 }
1278
1279 void SetTextInputType(RenderWidgetHostViewBase* view,
1280 ui::TextInputType type) {
1281 TextInputState state;
1282 state.type = type;
1283 view->TextInputStateChanged(state);
1284 }
1285
1286 IPC::TestSink& tab_sink() { return process()->sink(); }
1287 IPC::TestSink& child_sink() { return child_process_host_->sink(); }
1288 TextInputManager* text_input_manager() { return text_input_manager_; }
1289 RenderWidgetHostViewBase* tab_view() { return rwhv_mac_; }
1290 RenderWidgetHostImpl* tab_widget() { return tab_widget_; }
1291
1292 protected:
1293 MockRenderProcessHost* child_process_host_;
1294 RenderWidgetHostImpl* child_widget_;
1295 TestRenderWidgetHostView* child_view_;
1296
1297 private:
1298 TestBrowserContext browser_context_;
1299 TextInputManager* text_input_manager_;
1300 RenderWidgetHostImpl* tab_widget_;
1301
1302 DISALLOW_COPY_AND_ASSIGN(InputMethodMacTest);
1303 };
1304
1305 // This test will verify that calling unmarkText on the cocoa view will lead to
1306 // a confirm composition IPC for the corresponding active widget.
1307 TEST_F(InputMethodMacTest, UnmarkText) {
1308 // Make the child view active and then call unmarkText on the view (Note that
1309 // |RenderWidgetHostViewCocoa::handlingKeyDown_| is false so calling
1310 // unmarkText would lead to an IPC. This assumption is made in other similar
1311 // tests as well). We should observe an IPC being sent to the |child_widget_|.
1312 SetTextInputType(child_view_, ui::TEXT_INPUT_TYPE_TEXT);
1313 EXPECT_EQ(child_widget_, text_input_manager()->GetActiveWidget());
1314 child_sink().ClearMessages();
1315 [rwhv_cocoa_ unmarkText];
1316 EXPECT_TRUE(!!child_sink().GetFirstMessageMatching(
1317 InputMsg_ImeConfirmComposition::ID));
1318
1319 // Repeat the same steps for the tab's view .
1320 SetTextInputType(tab_view(), ui::TEXT_INPUT_TYPE_TEXT);
1321 EXPECT_EQ(tab_widget(), text_input_manager()->GetActiveWidget());
1322 tab_sink().ClearMessages();
1323 [rwhv_cocoa_ unmarkText];
1324 EXPECT_TRUE(
1325 !!tab_sink().GetFirstMessageMatching(InputMsg_ImeConfirmComposition::ID));
1326 }
1327
1328 // This test makes sure that calling setMarkedText on the cocoa view will lead
1329 // to a set composition IPC for the corresponding active widget.
1330 TEST_F(InputMethodMacTest, SetMarkedText) {
1331 // Some values for the call to setMarkedText.
1332 base::scoped_nsobject<NSString> text(
1333 [[NSString alloc] initWithString:@"sample text"]);
1334 NSRange selectedRange = NSMakeRange(0, 4);
1335 NSRange replacementRange = NSMakeRange(0, 1);
1336
1337 // Make the child view active and then call setMarkedText with some values. We
1338 // should observe an IPC being sent to the |child_widget_|.
1339 SetTextInputType(child_view_, ui::TEXT_INPUT_TYPE_TEXT);
1340 EXPECT_EQ(child_widget_, text_input_manager()->GetActiveWidget());
1341 child_sink().ClearMessages();
1342 [rwhv_cocoa_ setMarkedText:text
1343 selectedRange:selectedRange
1344 replacementRange:replacementRange];
1345 EXPECT_TRUE(
1346 !!child_sink().GetFirstMessageMatching(InputMsg_ImeSetComposition::ID));
1347
1348 // Repeat the same steps for the tab's view.
1349 SetTextInputType(tab_view(), ui::TEXT_INPUT_TYPE_TEXT);
1350 EXPECT_EQ(tab_widget(), text_input_manager()->GetActiveWidget());
1351 tab_sink().ClearMessages();
1352 [rwhv_cocoa_ setMarkedText:text
1353 selectedRange:selectedRange
1354 replacementRange:replacementRange];
1355 EXPECT_TRUE(
1356 !!tab_sink().GetFirstMessageMatching(InputMsg_ImeSetComposition::ID));
1357 }
1358
1359 // This test verifies that calling insertText on the cocoa view will lead to a
1360 // confirm composition IPC sent to the active widget.
1361 TEST_F(InputMethodMacTest, InsetText) {
1362 // Some values for the call to insertText.
1363 base::scoped_nsobject<NSString> text(
1364 [[NSString alloc] initWithString:@"sample text"]);
1365 NSRange replacementRange = NSMakeRange(0, 1);
1366
1367 // Make the child view active and then call insertText with some values. We
1368 // should observe an IPC being sent to the |child_widget_|.
1369 SetTextInputType(child_view_, ui::TEXT_INPUT_TYPE_TEXT);
1370 EXPECT_EQ(child_widget_, text_input_manager()->GetActiveWidget());
1371 child_sink().ClearMessages();
1372 [rwhv_cocoa_ insertText:text replacementRange:replacementRange];
1373 EXPECT_TRUE(!!child_sink().GetFirstMessageMatching(
1374 InputMsg_ImeConfirmComposition::ID));
1375
1376 // Repeat the same steps for the tab's view.
1377 SetTextInputType(tab_view(), ui::TEXT_INPUT_TYPE_TEXT);
1378 EXPECT_EQ(tab_widget(), text_input_manager()->GetActiveWidget());
1379 [rwhv_cocoa_ insertText:text replacementRange:replacementRange];
1380 EXPECT_TRUE(
1381 !!tab_sink().GetFirstMessageMatching(InputMsg_ImeConfirmComposition::ID));
1382 }
1383
1384 // This test makes sure that calling confirmComposition on the cocoa view will
1385 // lead to a confirm composition IPC for a the corresponding active widget.
1386 TEST_F(InputMethodMacTest, ConfirmComposition) {
1387 // Some values for the call to setMarkedText.
1388 base::scoped_nsobject<NSString> text(
1389 [[NSString alloc] initWithString:@"sample text"]);
1390 NSRange selectedRange = NSMakeRange(0, 4);
1391 NSRange replacementRange = NSMakeRange(0, 1);
1392
1393 // Make child view active and then call confirmComposition. We should observe
1394 // an IPC being sent to the |child_widget_|.
1395 SetTextInputType(child_view_, ui::TEXT_INPUT_TYPE_TEXT);
1396 EXPECT_EQ(child_widget_, text_input_manager()->GetActiveWidget());
1397 child_sink().ClearMessages();
1398 // In order to confirm composition, we must first have some marked text. So,
1399 // we will first call setMarkedText on cocoa view. This would lead to a set
1400 // composition IPC in the sink, but it doesn't matter since we will be looking
1401 // for a confirm composition IPC for this test.
1402 [rwhv_cocoa_ setMarkedText:text
1403 selectedRange:selectedRange
1404 replacementRange:replacementRange];
1405 [rwhv_cocoa_ confirmComposition];
1406 EXPECT_TRUE(!!child_sink().GetFirstMessageMatching(
1407 InputMsg_ImeConfirmComposition::ID));
1408
1409 // Repeat the same steps for the tab's view.
1410 SetTextInputType(tab_view(), ui::TEXT_INPUT_TYPE_TEXT);
1411 EXPECT_EQ(tab_widget(), text_input_manager()->GetActiveWidget());
1412 tab_sink().ClearMessages();
1413 [rwhv_cocoa_ setMarkedText:text
1414 selectedRange:selectedRange
1415 replacementRange:replacementRange];
1416 [rwhv_cocoa_ confirmComposition];
1417 EXPECT_TRUE(
1418 !!tab_sink().GetFirstMessageMatching(InputMsg_ImeConfirmComposition::ID));
1419 }
1420
1250 // This test creates a test view to mimic a child frame's view and verifies that 1421 // This test creates a test view to mimic a child frame's view and verifies that
1251 // calling ImeCancelComposition on either the child view or the tab's view will 1422 // calling ImeCancelComposition on either the child view or the tab's view will
1252 // always lead to a call to cancelComposition on the cocoa view. 1423 // always lead to a call to cancelComposition on the cocoa view.
1253 TEST_F(RenderWidgetHostViewMacTest, ImeCancelCompositionForAllViews) { 1424 TEST_F(InputMethodMacTest, ImeCancelCompositionForAllViews) {
1254 TestRenderWidgetHostView* child_view = 1425 // Some values for the call to setMarkedText.
1255 new TestRenderWidgetHostView(rvh()->GetWidget()); 1426 base::scoped_nsobject<NSString> text(
1256 // Set the marked test on cocoa view. 1427 [[NSString alloc] initWithString:@"sample text"]);
1257 NSString* text = [[NSString alloc] initWithString:@"sample text"];
1258 NSRange selectedRange = NSMakeRange(0, 1); 1428 NSRange selectedRange = NSMakeRange(0, 1);
1259 NSRange replacementRange = NSMakeRange(0, 1); 1429 NSRange replacementRange = NSMakeRange(0, 1);
1430
1260 // Make Cocoa view assume there is marked text. 1431 // Make Cocoa view assume there is marked text.
1261 [rwhv_cocoa_ setMarkedText:text 1432 [rwhv_cocoa_ setMarkedText:text
1262 selectedRange:selectedRange 1433 selectedRange:selectedRange
1263 replacementRange:replacementRange]; 1434 replacementRange:replacementRange];
1264 EXPECT_TRUE([rwhv_cocoa_ hasMarkedText]); 1435 EXPECT_TRUE([rwhv_cocoa_ hasMarkedText]);
1265 child_view->ImeCancelComposition(); 1436 child_view_->ImeCancelComposition();
1266 EXPECT_FALSE([rwhv_cocoa_ hasMarkedText]); 1437 EXPECT_FALSE([rwhv_cocoa_ hasMarkedText]);
1267 1438
1268 // Repeat for the tab's view. 1439 // Repeat for the tab's view.
1269 [rwhv_cocoa_ setMarkedText:text 1440 [rwhv_cocoa_ setMarkedText:text
1270 selectedRange:selectedRange 1441 selectedRange:selectedRange
1271 replacementRange:replacementRange]; 1442 replacementRange:replacementRange];
1272 EXPECT_TRUE([rwhv_cocoa_ hasMarkedText]); 1443 EXPECT_TRUE([rwhv_cocoa_ hasMarkedText]);
1273 rwhv_mac_->ImeCancelComposition(); 1444 rwhv_mac_->ImeCancelComposition();
1274 EXPECT_FALSE([rwhv_cocoa_ hasMarkedText]); 1445 EXPECT_FALSE([rwhv_cocoa_ hasMarkedText]);
1275 } 1446 }
1276 1447
1277 } // namespace content 1448 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/renderer_host/render_widget_host_view_mac.mm ('k') | content/browser/renderer_host/text_input_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698