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

Side by Side Diff: chrome/browser/apps/guest_view/web_view_browsertest.cc

Issue 1180503002: Force a GuestView's embedder to be focused on TouchStart. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Release observer on destruction. Make webview focused (for Windows). Created 5 years, 6 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
« no previous file with comments | « no previous file | content/browser/frame_host/render_widget_host_view_guest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 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 <queue>
6
5 #include "base/location.h" 7 #include "base/location.h"
6 #include "base/path_service.h" 8 #include "base/path_service.h"
7 #include "base/process/process.h" 9 #include "base/process/process.h"
8 #include "base/single_thread_task_runner.h" 10 #include "base/single_thread_task_runner.h"
9 #include "base/strings/stringprintf.h" 11 #include "base/strings/stringprintf.h"
10 #include "base/strings/utf_string_conversions.h" 12 #include "base/strings/utf_string_conversions.h"
11 #include "base/thread_task_runner_handle.h" 13 #include "base/thread_task_runner_handle.h"
12 #include "chrome/app/chrome_command_ids.h" 14 #include "chrome/app/chrome_command_ids.h"
13 #include "chrome/browser/apps/app_browsertest_util.h" 15 #include "chrome/browser/apps/app_browsertest_util.h"
14 #include "chrome/browser/chrome_content_browser_client.h" 16 #include "chrome/browser/chrome_content_browser_client.h"
(...skipping 30 matching lines...) Expand all
45 #include "extensions/browser/app_window/native_app_window.h" 47 #include "extensions/browser/app_window/native_app_window.h"
46 #include "extensions/browser/guest_view/extensions_guest_view_manager_delegate.h " 48 #include "extensions/browser/guest_view/extensions_guest_view_manager_delegate.h "
47 #include "extensions/browser/guest_view/web_view/web_view_guest.h" 49 #include "extensions/browser/guest_view/web_view/web_view_guest.h"
48 #include "extensions/common/extension.h" 50 #include "extensions/common/extension.h"
49 #include "extensions/common/extensions_client.h" 51 #include "extensions/common/extensions_client.h"
50 #include "extensions/test/extension_test_message_listener.h" 52 #include "extensions/test/extension_test_message_listener.h"
51 #include "media/base/media_switches.h" 53 #include "media/base/media_switches.h"
52 #include "net/test/embedded_test_server/embedded_test_server.h" 54 #include "net/test/embedded_test_server/embedded_test_server.h"
53 #include "net/test/embedded_test_server/http_request.h" 55 #include "net/test/embedded_test_server/http_request.h"
54 #include "net/test/embedded_test_server/http_response.h" 56 #include "net/test/embedded_test_server/http_response.h"
57 #include "ui/aura/window.h"
58 #include "ui/compositor/compositor.h"
59 #include "ui/compositor/compositor_observer.h"
60 #include "ui/events/event_switches.h"
55 #include "ui/gfx/switches.h" 61 #include "ui/gfx/switches.h"
56 #include "ui/gl/gl_switches.h" 62 #include "ui/gl/gl_switches.h"
63 #include "ui/views/view.h"
64 #include "ui/views/widget/widget.h"
57 65
58 #if defined(ENABLE_PLUGINS) 66 #if defined(ENABLE_PLUGINS)
59 #include "content/public/browser/plugin_service.h" 67 #include "content/public/browser/plugin_service.h"
60 #include "content/public/common/webplugininfo.h" 68 #include "content/public/common/webplugininfo.h"
61 #include "content/public/test/ppapi_test_utils.h" 69 #include "content/public/test/ppapi_test_utils.h"
62 #endif 70 #endif
63 71
64 #if defined(OS_CHROMEOS) 72 #if defined(OS_CHROMEOS)
65 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h" 73 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
66 #include "chrome/browser/chromeos/accessibility/speech_monitor.h" 74 #include "chrome/browser/chromeos/accessibility/speech_monitor.h"
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 const char* title) { 207 const char* title) {
200 base::string16 expected_title(base::ASCIIToUTF16(title)); 208 base::string16 expected_title(base::ASCIIToUTF16(title));
201 base::string16 error_title(base::ASCIIToUTF16("error")); 209 base::string16 error_title(base::ASCIIToUTF16("error"));
202 210
203 content::TitleWatcher title_watcher(web_contents, expected_title); 211 content::TitleWatcher title_watcher(web_contents, expected_title);
204 title_watcher.AlsoWaitForTitle(error_title); 212 title_watcher.AlsoWaitForTitle(error_title);
205 EXPECT_TRUE(content::ExecuteScript(web_contents, script)); 213 EXPECT_TRUE(content::ExecuteScript(web_contents, script));
206 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); 214 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
207 } 215 }
208 216
217 #if defined (USE_AURA)
218 views::View* FindWebView(views::View* view) {
219 std::queue<views::View*> queue;
220 queue.push(view);
221 while (!queue.empty()) {
222 views::View* current = queue.front();
223 queue.pop();
224 if (std::string(current->GetClassName()).find("WebView") !=
225 std::string::npos) {
226 return current;
227 }
228
229 for (int i = 0; i < current->child_count(); ++i)
230 queue.push(current->child_at(i));
231 }
232 return nullptr;
233 }
234 #endif
235
209 } // namespace 236 } // namespace
210 237
211 // This class intercepts media access request from the embedder. The request 238 // This class intercepts media access request from the embedder. The request
212 // should be triggered only if the embedder API (from tests) allows the request 239 // should be triggered only if the embedder API (from tests) allows the request
213 // in Javascript. 240 // in Javascript.
214 // We do not issue the actual media request; the fact that the request reached 241 // We do not issue the actual media request; the fact that the request reached
215 // embedder's WebContents is good enough for our tests. This is also to make 242 // embedder's WebContents is good enough for our tests. This is also to make
216 // the test run successfully on trybots. 243 // the test run successfully on trybots.
217 class MockWebContentsDelegate : public content::WebContentsDelegate { 244 class MockWebContentsDelegate : public content::WebContentsDelegate {
218 public: 245 public:
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after
652 browser()->profile())))); 679 browser()->profile()))));
653 } 680 }
654 return manager; 681 return manager;
655 } 682 }
656 683
657 WebViewTest() : guest_web_contents_(NULL), 684 WebViewTest() : guest_web_contents_(NULL),
658 embedder_web_contents_(NULL) { 685 embedder_web_contents_(NULL) {
659 GuestViewManager::set_factory_for_testing(&factory_); 686 GuestViewManager::set_factory_for_testing(&factory_);
660 } 687 }
661 688
689 protected:
690 scoped_refptr<content::FrameWatcher> frame_watcher_;
691
662 private: 692 private:
663 bool UsesFakeSpeech() { 693 bool UsesFakeSpeech() {
664 const testing::TestInfo* const test_info = 694 const testing::TestInfo* const test_info =
665 testing::UnitTest::GetInstance()->current_test_info(); 695 testing::UnitTest::GetInstance()->current_test_info();
666 696
667 // SpeechRecognition test specific SetUp. 697 // SpeechRecognition test specific SetUp.
668 return !strcmp(test_info->name(), 698 return !strcmp(test_info->name(),
669 "SpeechRecognitionAPI_HasPermissionAllow"); 699 "SpeechRecognitionAPI_HasPermissionAllow");
670 } 700 }
671 701
(...skipping 1693 matching lines...) Expand 10 before | Expand all | Expand 10 after
2365 ASSERT_TRUE(StartEmbeddedTestServer()); // For serving guest pages. 2395 ASSERT_TRUE(StartEmbeddedTestServer()); // For serving guest pages.
2366 ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view/post_message/basic")) 2396 ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view/post_message/basic"))
2367 << message_; 2397 << message_;
2368 } 2398 }
2369 2399
2370 // Tests that webviews do get garbage collected. 2400 // Tests that webviews do get garbage collected.
2371 IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestGarbageCollect) { 2401 IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestGarbageCollect) {
2372 TestHelper("testGarbageCollect", "web_view/shim", NO_TEST_SERVER); 2402 TestHelper("testGarbageCollect", "web_view/shim", NO_TEST_SERVER);
2373 GetGuestViewManager()->WaitForSingleViewGarbageCollected(); 2403 GetGuestViewManager()->WaitForSingleViewGarbageCollected();
2374 } 2404 }
2405
2406 #if defined(USE_AURA)
2407 class WebViewFocusTest : public WebViewTest {
2408 public:
2409 ~WebViewFocusTest() override {}
2410
2411 void SetUpCommandLine(base::CommandLine* command_line) override {
2412 WebViewTest::SetUpCommandLine(command_line);
2413
2414 command_line->AppendSwitchASCII(switches::kTouchEvents,
2415 switches::kTouchEventsEnabled);
2416 }
2417
2418 void ForceCompositorFrame() {
2419 if (!frame_watcher_) {
2420 frame_watcher_ = new content::FrameWatcher();
2421 frame_watcher_->AttachTo(GetEmbedderWebContents());
2422 }
2423
2424 while (!RequestFrame(GetEmbedderWebContents())) {
2425 // RequestFrame failed because we were waiting on an ack ... wait a short
2426 // time and retry.
2427 base::RunLoop run_loop;
2428 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
2429 FROM_HERE, run_loop.QuitClosure(),
2430 base::TimeDelta::FromMilliseconds(10));
2431 run_loop.Run();
2432 }
2433 frame_watcher_->WaitFrames(1);
2434 }
2435
2436 private:
2437 scoped_refptr<content::FrameWatcher> frame_watcher_;
2438 };
2439
2440 class FocusWaiter : public views::FocusChangeListener {
2441 public:
2442 explicit FocusWaiter(views::View* view_to_wait_for)
2443 : view_to_wait_for_(view_to_wait_for) {
2444 view_to_wait_for_->GetFocusManager()->AddFocusChangeListener(this);
2445 }
2446 ~FocusWaiter() override {
2447 view_to_wait_for_->GetFocusManager()->RemoveFocusChangeListener(this);
2448 }
2449
2450 void Wait() {
2451 if (view_to_wait_for_->HasFocus())
2452 return;
2453
2454 base::MessageLoop::current()->Run();
2455 }
2456
2457 // FocusChangeListener implementation.
2458 void OnWillChangeFocus(views::View* focused_before,
2459 views::View* focused_now) override {}
2460 void OnDidChangeFocus(views::View* focused_before,
2461 views::View* focused_now) override {
2462 if (view_to_wait_for_ == focused_now)
2463 base::MessageLoop::current()->QuitWhenIdle();
2464 }
2465
2466 private:
2467 views::View* view_to_wait_for_;
2468
2469 DISALLOW_COPY_AND_ASSIGN(FocusWaiter);
2470 };
2471
2472 // The following test verifies that a views::WebView hosting an embedder
2473 // gains focus on touchstart.
2474 IN_PROC_BROWSER_TEST_F(WebViewFocusTest, TouchFocusesEmbedder) {
2475 LoadAppWithGuest("web_view/accept_touch_events");
2476
2477 content::WebContents* web_contents = GetEmbedderWebContents();
2478 content::RenderViewHost* embedder_rvh = web_contents->GetRenderViewHost();
2479
2480 bool embedder_has_touch_handler =
2481 content::RenderViewHostTester::HasTouchEventHandler(embedder_rvh);
2482 EXPECT_FALSE(embedder_has_touch_handler);
2483
2484 SendMessageToGuestAndWait("install-touch-handler", "installed-touch-handler");
2485
2486 // Note that we need to wait for the installed/registered touch handler to
2487 // appear in browser process before querying |embedder_rvh|.
2488 // In practice, since we do a roundrtip from browser process to guest and
2489 // back, this is sufficient.
2490 embedder_has_touch_handler =
2491 content::RenderViewHostTester::HasTouchEventHandler(embedder_rvh);
2492 EXPECT_TRUE(embedder_has_touch_handler);
2493
2494 extensions::AppWindow* app_window = GetFirstAppWindowForBrowser(browser());
2495 aura::Window* window = app_window->GetNativeWindow();
2496 EXPECT_TRUE(app_window);
2497 EXPECT_TRUE(window);
2498 views::Widget* widget = views::Widget::GetWidgetForNativeView(window);
2499 EXPECT_TRUE(widget->GetRootView());
2500 // We only expect a single views::webview in the view hierarchy.
2501 views::View* aura_webview = FindWebView(widget->GetRootView());
2502 ASSERT_TRUE(aura_webview);
2503 gfx::Rect bounds(aura_webview->bounds());
2504 EXPECT_TRUE(aura_webview->IsFocusable());
2505
2506 views::View* other_focusable_view = new views::View();
2507 other_focusable_view->SetBounds(bounds.x() + bounds.width(), bounds.y(), 100,
2508 100);
2509 other_focusable_view->SetFocusable(true);
2510 aura_webview->parent()->AddChildView(other_focusable_view);
2511 other_focusable_view->SetPosition(gfx::Point(bounds.x() + bounds.width(), 0));
2512
2513 // Sync changes to compositor.
2514 ForceCompositorFrame();
2515
2516 aura_webview->RequestFocus();
2517 // Verify that other_focusable_view can steal focus from aura_webview.
2518 EXPECT_TRUE(aura_webview->HasFocus());
2519 other_focusable_view->RequestFocus();
2520 EXPECT_TRUE(other_focusable_view->HasFocus());
2521 EXPECT_FALSE(aura_webview->HasFocus());
2522
2523 // Generate and send synthetic touch event.
2524 // TODO(wjmaclean): This is fragile ... if anyone alters the location/size
2525 // of the webview in accept_touch_events then this may miss its target.
2526 FocusWaiter waiter(aura_webview);
2527 content::SimulateTouchPressAt(GetEmbedderWebContents(), gfx::Point(10, 10));
2528
2529 // Wait for the TouchStart to propagate and restore focus. Test times out
2530 // on failure.
2531 waiter.Wait();
2532 }
2533 #endif
OLDNEW
« no previous file with comments | « no previous file | content/browser/frame_host/render_widget_host_view_guest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698