diff --git a/AUTHORS b/AUTHORS index f43d3a3..e6615048 100644 --- a/AUTHORS +++ b/AUTHORS
@@ -439,6 +439,7 @@ Marco Rodrigues <gothicx@gmail.com> Mario Pistrich <m.pistrich@gmail.com> Mario Sanchez Prada <mario.prada@samsung.com> +Marcin Wiacek <marcin@mwiacek.com> Mariusz Mlynski <marius.mlynski@gmail.com> Mark Hahnenberg <mhahnenb@andrew.cmu.edu> Mark Seaborn <mrs@mythic-beasts.com>
diff --git a/DEPS b/DEPS index 5c14e0f3..6308819 100644 --- a/DEPS +++ b/DEPS
@@ -40,7 +40,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '2be687af58ec1f445c6380457d136562ef27155e', + 'skia_revision': '0bd783f951a004ccca175b166f2b30a0fd18a6f6', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -64,7 +64,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': 'dc39e377e1a3923e63569020beb29f9662c1a3ee', + 'pdfium_revision': '0ef7ba086f9e48100f9caebd0a52de478f0ada0a', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling openmax_dl # and whatever else without interference from each other.
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 87f968a..aa46412 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -1027,6 +1027,8 @@ "shell/bubble.cc", "shell/context_menu.cc", "shell/context_menu.h", + "shell/example_app_list_presenter.cc", + "shell/example_app_list_presenter.h", "shell/example_factory.h", "shell/lock_view.cc", "shell/panel_window.cc", @@ -1058,6 +1060,7 @@ "//components/user_manager", "//skia", "//ui/app_list/presenter", + "//ui/app_list/presenter:test_support", "//ui/aura", "//ui/base", "//ui/gfx", @@ -1096,6 +1099,7 @@ "//device/bluetooth", "//net", "//skia", + "//ui/app_list/presenter:test_support", "//ui/aura", "//ui/base", "//ui/base/ime", @@ -1364,7 +1368,9 @@ "//testing/gtest", "//third_party/icu", "//ui/accessibility", + "//ui/app_list:test_support", "//ui/app_list/presenter", + "//ui/app_list/presenter:test_support", "//ui/aura", "//ui/aura:test_support", "//ui/base",
diff --git a/ash/accelerators/DEPS b/ash/accelerators/DEPS index 5471592..b6b2ae6 100644 --- a/ash/accelerators/DEPS +++ b/ash/accelerators/DEPS
@@ -2,4 +2,7 @@ "accelerator_controller_delegate_aura\.cc": [ "+ash/host" ], + "accelerator_interactive_uitest_chromeos\.cc": [ + "+mojo/edk/embedder/embedder.h" + ], }
diff --git a/ash/accelerators/accelerator_controller_unittest.cc b/ash/accelerators/accelerator_controller_unittest.cc index abf2ab7..84aacdd 100644 --- a/ash/accelerators/accelerator_controller_unittest.cc +++ b/ash/accelerators/accelerator_controller_unittest.cc
@@ -30,6 +30,8 @@ #include "ash/wm/window_util.h" #include "base/test/user_action_tester.cc" #include "services/ui/public/interfaces/window_manager_constants.mojom.h" +#include "ui/app_list/presenter/app_list.h" +#include "ui/app_list/presenter/test/test_app_list_presenter.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/test/test_window_delegate.h" #include "ui/aura/test/test_windows.h" @@ -274,7 +276,6 @@ return WmShell::Get()->accelerator_controller(); } -#if !defined(OS_WIN) // Double press of exit shortcut => exiting TEST_F(AcceleratorControllerTest, ExitWarningHandlerTestDoublePress) { ui::Accelerator press(ui::VKEY_Q, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN); @@ -330,7 +331,6 @@ // Exit ash and there should be no crash } -#endif // !defined(OS_WIN) TEST_F(AcceleratorControllerTest, Register) { const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE); @@ -743,15 +743,8 @@ } // TODO(oshima): Fix this test to use EventGenerator. -#if defined(OS_WIN) -// crbug.com/317592 -#define MAYBE_ProcessOnce DISABLED_ProcessOnce -#else -#define MAYBE_ProcessOnce ProcessOnce -#endif - -#if defined(OS_WIN) || defined(USE_X11) -TEST_F(AcceleratorControllerTest, MAYBE_ProcessOnce) { +#if defined(USE_X11) +TEST_F(AcceleratorControllerTest, ProcessOnce) { // The IME event filter interferes with the basic key event propagation we // attempt to do here, so we disable it. DisableIME(); @@ -762,22 +755,7 @@ // The accelerator is processed only once. ui::EventProcessor* dispatcher = Shell::GetPrimaryRootWindow()->GetHost()->event_processor(); -#if defined(OS_WIN) - MSG msg1 = {NULL, WM_KEYDOWN, ui::VKEY_A, 0}; - ui::KeyEvent key_event1(msg1); - ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&key_event1); - EXPECT_TRUE(key_event1.handled() || details.dispatcher_destroyed); - MSG msg2 = {NULL, WM_CHAR, L'A', 0}; - ui::KeyEvent key_event2(msg2); - details = dispatcher->OnEventFromSource(&key_event2); - EXPECT_FALSE(key_event2.handled() || details.dispatcher_destroyed); - - MSG msg3 = {NULL, WM_KEYUP, ui::VKEY_A, 0}; - ui::KeyEvent key_event3(msg3); - details = dispatcher->OnEventFromSource(&key_event3); - EXPECT_FALSE(key_event3.handled() || details.dispatcher_destroyed); -#elif defined(USE_X11) ui::ScopedXI2Event key_event; key_event.InitKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_A, 0); ui::KeyEvent key_event1(key_event); @@ -792,7 +770,6 @@ ui::KeyEvent key_event3(key_event); details = dispatcher->OnEventFromSource(&key_event3); EXPECT_FALSE(key_event3.handled() || details.dispatcher_destroyed); -#endif EXPECT_EQ(1, target.accelerator_pressed_count()); } #endif @@ -808,7 +785,6 @@ EXPECT_TRUE(ProcessInController( ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_NONE))); -#if defined(OS_CHROMEOS) // The "Take Screenshot", "Take Partial Screenshot", volume, brightness, and // keyboard brightness accelerators are only defined on ChromeOS. { @@ -895,9 +871,7 @@ EXPECT_EQ(1, delegate->handle_keyboard_brightness_up_count()); EXPECT_EQ(alt_brightness_up, delegate->last_accelerator()); } -#endif -#if !defined(OS_WIN) // Exit ExitWarningHandler* ewh = GetController()->GetExitWarningHandlerForTest(); ASSERT_TRUE(ewh); @@ -912,7 +886,6 @@ EXPECT_TRUE(is_idle(ewh)); EXPECT_FALSE(is_ui_shown(ewh)); Reset(ewh); -#endif // New tab EXPECT_TRUE( @@ -934,7 +907,6 @@ EXPECT_TRUE( ProcessInController(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_SHIFT_DOWN))); -#if defined(OS_CHROMEOS) // Open file manager EXPECT_TRUE(ProcessInController( ui::Accelerator(ui::VKEY_M, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN))); @@ -945,24 +917,25 @@ // effect of locking the screen. EXPECT_TRUE( ProcessInController(ui::Accelerator(ui::VKEY_L, ui::EF_COMMAND_DOWN))); -#endif } TEST_F(AcceleratorControllerTest, GlobalAcceleratorsToggleAppList) { + app_list::test::TestAppListPresenter test_app_list_presenter; + WmShell::Get()->app_list()->SetAppListPresenter( + test_app_list_presenter.CreateInterfacePtrAndBind()); AccessibilityDelegate* delegate = WmShell::Get()->accessibility_delegate(); - EXPECT_FALSE(WmShell::Get()->GetAppListTargetVisibility()); - // The press event should not open the AppList, the release should instead. + // The press event should not toggle the AppList, the release should instead. EXPECT_FALSE( ProcessInController(ui::Accelerator(ui::VKEY_LWIN, ui::EF_NONE))); + RunAllPendingInMessageLoop(); EXPECT_EQ(ui::VKEY_LWIN, GetCurrentAccelerator().key_code()); - - EXPECT_FALSE(WmShell::Get()->GetAppListTargetVisibility()); + EXPECT_EQ(0u, test_app_list_presenter.toggle_count()); EXPECT_TRUE( ProcessInController(ReleaseAccelerator(ui::VKEY_LWIN, ui::EF_NONE))); - EXPECT_TRUE(WmShell::Get()->GetAppListTargetVisibility()); - + RunAllPendingInMessageLoop(); + EXPECT_EQ(1u, test_app_list_presenter.toggle_count()); EXPECT_EQ(ui::VKEY_LWIN, GetPreviousAccelerator().key_code()); // When spoken feedback is on, the AppList should not toggle. @@ -972,32 +945,26 @@ EXPECT_FALSE( ProcessInController(ReleaseAccelerator(ui::VKEY_LWIN, ui::EF_NONE))); delegate->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE); - EXPECT_TRUE(WmShell::Get()->GetAppListTargetVisibility()); + RunAllPendingInMessageLoop(); + EXPECT_EQ(1u, test_app_list_presenter.toggle_count()); + // Turning off spoken feedback should allow the AppList to toggle again. EXPECT_FALSE( ProcessInController(ui::Accelerator(ui::VKEY_LWIN, ui::EF_NONE))); EXPECT_TRUE( ProcessInController(ReleaseAccelerator(ui::VKEY_LWIN, ui::EF_NONE))); - EXPECT_FALSE(WmShell::Get()->GetAppListTargetVisibility()); + RunAllPendingInMessageLoop(); + EXPECT_EQ(2u, test_app_list_presenter.toggle_count()); - // When spoken feedback is on, the AppList should not toggle. - delegate->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE); - EXPECT_FALSE( - ProcessInController(ui::Accelerator(ui::VKEY_LWIN, ui::EF_NONE))); - EXPECT_FALSE( - ProcessInController(ReleaseAccelerator(ui::VKEY_LWIN, ui::EF_NONE))); - delegate->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE); - EXPECT_FALSE(WmShell::Get()->GetAppListTargetVisibility()); - -#if defined(OS_CHROMEOS) // The press of VKEY_BROWSER_SEARCH should toggle the AppList EXPECT_TRUE(ProcessInController( ui::Accelerator(ui::VKEY_BROWSER_SEARCH, ui::EF_NONE))); - EXPECT_TRUE(WmShell::Get()->GetAppListTargetVisibility()); + RunAllPendingInMessageLoop(); + EXPECT_EQ(3u, test_app_list_presenter.toggle_count()); EXPECT_FALSE(ProcessInController( ReleaseAccelerator(ui::VKEY_BROWSER_SEARCH, ui::EF_NONE))); - EXPECT_TRUE(WmShell::Get()->GetAppListTargetVisibility()); -#endif + RunAllPendingInMessageLoop(); + EXPECT_EQ(3u, test_app_list_presenter.toggle_count()); } TEST_F(AcceleratorControllerTest, ImeGlobalAccelerators) { @@ -1052,13 +1019,12 @@ } TEST_F(AcceleratorControllerTest, PreferredReservedAccelerators) { -#if defined(OS_CHROMEOS) // Power key is reserved on chromeos. EXPECT_TRUE(GetController()->IsReserved( ui::Accelerator(ui::VKEY_POWER, ui::EF_NONE))); EXPECT_FALSE(GetController()->IsPreferred( ui::Accelerator(ui::VKEY_POWER, ui::EF_NONE))); -#endif + // ALT+Tab are not reserved but preferred. EXPECT_FALSE(GetController()->IsReserved( ui::Accelerator(ui::VKEY_TAB, ui::EF_ALT_DOWN))); @@ -1115,14 +1081,13 @@ ASSERT_TRUE(w1_state->IsFullscreen()); ui::test::EventGenerator& generator = GetEventGenerator(); -#if defined(OS_CHROMEOS) + // Power key (reserved) should always be handled. test::LockStateControllerTestApi test_api( Shell::GetInstance()->lock_state_controller()); EXPECT_FALSE(test_api.is_animating_lock()); generator.PressKey(ui::VKEY_POWER, ui::EF_NONE); EXPECT_TRUE(test_api.is_animating_lock()); -#endif auto press_and_release_alt_tab = [&generator]() { generator.PressKey(ui::VKEY_TAB, ui::EF_ALT_DOWN); @@ -1165,14 +1130,13 @@ } ui::test::EventGenerator& generator = GetEventGenerator(); -#if defined(OS_CHROMEOS) + // Power key (reserved) should always be handled. test::LockStateControllerTestApi test_api( Shell::GetInstance()->lock_state_controller()); EXPECT_FALSE(test_api.is_animating_lock()); generator.PressKey(ui::VKEY_POWER, ui::EF_NONE); EXPECT_TRUE(test_api.is_animating_lock()); -#endif // A pinned window can consume ALT-TAB (preferred), but no side effect. ASSERT_EQ(w1, wm::GetActiveWindow()); @@ -1182,7 +1146,6 @@ ASSERT_NE(w2, wm::GetActiveWindow()); } -#if defined(OS_CHROMEOS) TEST_F(AcceleratorControllerTest, DisallowedAtModalWindow) { std::set<AcceleratorAction> all_actions; for (size_t i = 0; i < kAcceleratorDataLength; ++i) @@ -1282,7 +1245,6 @@ EXPECT_EQ(1, user_action_tester.GetActionCount("Accel_VolumeUp_F10")); } } -#endif TEST_F(AcceleratorControllerTest, DisallowedWithNoWindow) { AccessibilityDelegate* delegate = WmShell::Get()->accessibility_delegate(); @@ -1315,7 +1277,6 @@ } } -#if defined(OS_CHROMEOS) namespace { // defines a class to test the behavior of deprecated accelerators. @@ -1417,6 +1378,5 @@ ResetStateIfNeeded(); } } -#endif // defined(OS_CHROMEOS) } // namespace ash
diff --git a/ash/accelerators/accelerator_interactive_uitest_chromeos.cc b/ash/accelerators/accelerator_interactive_uitest_chromeos.cc index 7663fc47..69755878 100644 --- a/ash/accelerators/accelerator_interactive_uitest_chromeos.cc +++ b/ash/accelerators/accelerator_interactive_uitest_chromeos.cc
@@ -18,6 +18,9 @@ #include "base/run_loop.h" #include "base/test/user_action_tester.cc" #include "chromeos/network/network_handler.h" +#include "mojo/edk/embedder/embedder.h" +#include "ui/app_list/presenter/app_list.h" +#include "ui/app_list/presenter/test/test_app_list_presenter.h" #include "ui/base/test/ui_controls.h" namespace ash { @@ -195,11 +198,18 @@ // Tests the app list accelerator. TEST_F(AcceleratorInteractiveUITest, MAYBE_ToggleAppList) { - EXPECT_FALSE(WmShell::Get()->GetAppListTargetVisibility()); + mojo::edk::Init(); + app_list::test::TestAppListPresenter test_app_list_presenter; + WmShell::Get()->app_list()->SetAppListPresenter( + test_app_list_presenter.CreateInterfacePtrAndBind()); + + EXPECT_EQ(0u, test_app_list_presenter.toggle_count()); SendKeyPressSync(ui::VKEY_LWIN, false, false, false); - EXPECT_TRUE(WmShell::Get()->GetAppListTargetVisibility()); + RunAllPendingInMessageLoop(); + EXPECT_EQ(1u, test_app_list_presenter.toggle_count()); SendKeyPressSync(ui::VKEY_LWIN, false, false, false); - EXPECT_FALSE(WmShell::Get()->GetAppListTargetVisibility()); + RunAllPendingInMessageLoop(); + EXPECT_EQ(2u, test_app_list_presenter.toggle_count()); } } // namespace test
diff --git a/ash/app_list/app_list_presenter_delegate.cc b/ash/app_list/app_list_presenter_delegate.cc index a9d89e1..14e9b3d5 100644 --- a/ash/app_list/app_list_presenter_delegate.cc +++ b/ash/app_list/app_list_presenter_delegate.cc
@@ -24,7 +24,7 @@ #include "base/command_line.h" #include "ui/app_list/app_list_constants.h" #include "ui/app_list/app_list_switches.h" -#include "ui/app_list/presenter/app_list_presenter.h" +#include "ui/app_list/presenter/app_list_presenter_impl.h" #include "ui/app_list/presenter/app_list_view_delegate_factory.h" #include "ui/app_list/views/app_list_view.h" #include "ui/aura/window.h" @@ -75,7 +75,7 @@ // AppListPresenterDelegate, public: AppListPresenterDelegate::AppListPresenterDelegate( - app_list::AppListPresenter* presenter, + app_list::AppListPresenterImpl* presenter, app_list::AppListViewDelegateFactory* view_delegate_factory) : presenter_(presenter), view_delegate_factory_(view_delegate_factory) { WmShell::Get()->AddShellObserver(this);
diff --git a/ash/app_list/app_list_presenter_delegate.h b/ash/app_list/app_list_presenter_delegate.h index be6c897f..44130d5 100644 --- a/ash/app_list/app_list_presenter_delegate.h +++ b/ash/app_list/app_list_presenter_delegate.h
@@ -16,7 +16,7 @@ #include "ui/keyboard/keyboard_controller_observer.h" namespace app_list { -class AppListPresenter; +class AppListPresenterImpl; class AppListView; class AppListViewDelegateFactory; } @@ -40,7 +40,7 @@ public WmShelfObserver { public: AppListPresenterDelegate( - app_list::AppListPresenter* presenter, + app_list::AppListPresenterImpl* presenter, app_list::AppListViewDelegateFactory* view_delegate_factory); ~AppListPresenterDelegate() override; @@ -78,7 +78,7 @@ bool is_visible_ = false; // Not owned. Pointer is guaranteed to be valid while this object is alive. - app_list::AppListPresenter* presenter_; + app_list::AppListPresenterImpl* presenter_; // Not owned. Pointer is guaranteed to be valid while this object is alive. app_list::AppListViewDelegateFactory* view_delegate_factory_;
diff --git a/ash/app_list/app_list_presenter_delegate_factory.cc b/ash/app_list/app_list_presenter_delegate_factory.cc index 0c312e72..e8275b1 100644 --- a/ash/app_list/app_list_presenter_delegate_factory.cc +++ b/ash/app_list/app_list_presenter_delegate_factory.cc
@@ -18,7 +18,7 @@ std::unique_ptr<app_list::AppListPresenterDelegate> AppListPresenterDelegateFactory::GetDelegate( - app_list::AppListPresenter* presenter) { + app_list::AppListPresenterImpl* presenter) { return base::MakeUnique<AppListPresenterDelegate>( presenter, view_delegate_factory_.get()); }
diff --git a/ash/app_list/app_list_presenter_delegate_factory.h b/ash/app_list/app_list_presenter_delegate_factory.h index c50f06b..382a1df 100644 --- a/ash/app_list/app_list_presenter_delegate_factory.h +++ b/ash/app_list/app_list_presenter_delegate_factory.h
@@ -12,7 +12,6 @@ #include "ui/app_list/presenter/app_list_presenter_delegate_factory.h" namespace app_list { -class AppListPresenter; class AppListViewDelegateFactory; } @@ -26,7 +25,7 @@ ~AppListPresenterDelegateFactory() override; std::unique_ptr<app_list::AppListPresenterDelegate> GetDelegate( - app_list::AppListPresenter* presenter) override; + app_list::AppListPresenterImpl* presenter) override; private: std::unique_ptr<app_list::AppListViewDelegateFactory> view_delegate_factory_;
diff --git a/ash/app_list/app_list_presenter_delegate_unittest.cc b/ash/app_list/app_list_presenter_delegate_unittest.cc index 106b83b..71324ae 100644 --- a/ash/app_list/app_list_presenter_delegate_unittest.cc +++ b/ash/app_list/app_list_presenter_delegate_unittest.cc
@@ -9,67 +9,57 @@ #include "ash/public/cpp/shell_window_ids.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" -#include "ash/test/ash_test_helper.h" -#include "ash/test/test_shell_delegate.h" +#include "ash/test/test_app_list_view_presenter_impl.h" #include "ash/wm/window_util.h" -#include "base/command_line.h" -#include "ui/app_list/app_list_switches.h" -#include "ui/app_list/presenter/app_list_presenter_impl.h" +#include "base/macros.h" #include "ui/app_list/views/app_list_view.h" #include "ui/aura/test/test_windows.h" #include "ui/aura/window.h" +#include "ui/display/manager/display_manager.h" #include "ui/events/test/event_generator.h" namespace ash { -namespace { -const int kMinimalAppListMargin = 10; -} - class AppListPresenterDelegateTest : public test::AshTestBase { public: - AppListPresenterDelegateTest(); - ~AppListPresenterDelegateTest() override; + AppListPresenterDelegateTest() {} + ~AppListPresenterDelegateTest() override {} + + app_list::AppListPresenterImpl* app_list_presenter_impl() { + return &app_list_presenter_impl_; + } // testing::Test: - void SetUp() override; + void SetUp() override { + AshTestBase::SetUp(); - app_list::AppListPresenterImpl* GetAppListPresenter(); + // Make the display big enough to hold the app list. + UpdateDisplay("1024x768"); + } + + private: + test::TestAppListViewPresenterImpl app_list_presenter_impl_; + + DISALLOW_COPY_AND_ASSIGN(AppListPresenterDelegateTest); }; -AppListPresenterDelegateTest::AppListPresenterDelegateTest() {} - -AppListPresenterDelegateTest::~AppListPresenterDelegateTest() {} - -void AppListPresenterDelegateTest::SetUp() { - AshTestBase::SetUp(); - - // Make the display big enough to hold the app list. - UpdateDisplay("1024x768"); -} - -app_list::AppListPresenterImpl* -AppListPresenterDelegateTest::GetAppListPresenter() { - return ash_test_helper()->test_shell_delegate()->app_list_presenter(); -} - // Tests that app launcher hides when focus moves to a normal window. TEST_F(AppListPresenterDelegateTest, HideOnFocusOut) { - WmShell::Get()->ShowAppList(); - EXPECT_TRUE(WmShell::Get()->GetAppListTargetVisibility()); + app_list_presenter_impl()->Show(display_manager()->first_display_id()); + EXPECT_TRUE(app_list_presenter_impl()->GetTargetVisibility()); std::unique_ptr<aura::Window> window(CreateTestWindowInShellWithId(0)); wm::ActivateWindow(window.get()); - EXPECT_FALSE(WmShell::Get()->GetAppListTargetVisibility()); + EXPECT_FALSE(app_list_presenter_impl()->GetTargetVisibility()); } // Tests that app launcher remains visible when focus is moved to a different // window in kShellWindowId_AppListContainer. TEST_F(AppListPresenterDelegateTest, RemainVisibleWhenFocusingToApplistContainer) { - WmShell::Get()->ShowAppList(); - EXPECT_TRUE(WmShell::Get()->GetAppListTargetVisibility()); + app_list_presenter_impl()->Show(display_manager()->first_display_id()); + EXPECT_TRUE(app_list_presenter_impl()->GetTargetVisibility()); aura::Window* applist_container = Shell::GetContainer( Shell::GetPrimaryRootWindow(), kShellWindowId_AppListContainer); @@ -77,19 +67,19 @@ aura::test::CreateTestWindowWithId(0, applist_container)); wm::ActivateWindow(window.get()); - EXPECT_TRUE(WmShell::Get()->GetAppListTargetVisibility()); + EXPECT_TRUE(app_list_presenter_impl()->GetTargetVisibility()); } // Tests that clicking outside the app-list bubble closes it. TEST_F(AppListPresenterDelegateTest, ClickOutsideBubbleClosesBubble) { - WmShell::Get()->ShowAppList(); - aura::Window* app_window = GetAppListPresenter()->GetWindow(); + app_list_presenter_impl()->Show(display_manager()->first_display_id()); + aura::Window* app_window = app_list_presenter_impl()->GetWindow(); ASSERT_TRUE(app_window); ui::test::EventGenerator& generator = GetEventGenerator(); // Click on the bubble itself. The bubble should remain visible. generator.MoveMouseToCenterOf(app_window); generator.ClickLeftButton(); - EXPECT_TRUE(WmShell::Get()->GetAppListTargetVisibility()); + EXPECT_TRUE(app_list_presenter_impl()->GetTargetVisibility()); // Click outside the bubble. This should close it. gfx::Rect app_window_bounds = app_window->GetBoundsInRootWindow(); @@ -98,28 +88,28 @@ gfx::Vector2d(10, 0); generator.MoveMouseToInHost(point_outside); generator.ClickLeftButton(); - EXPECT_FALSE(WmShell::Get()->GetAppListTargetVisibility()); + EXPECT_FALSE(app_list_presenter_impl()->GetTargetVisibility()); } // Tests that clicking outside the app-list bubble closes it. TEST_F(AppListPresenterDelegateTest, TapOutsideBubbleClosesBubble) { - WmShell::Get()->ShowAppList(); + app_list_presenter_impl()->Show(display_manager()->first_display_id()); - aura::Window* app_window = GetAppListPresenter()->GetWindow(); + aura::Window* app_window = app_list_presenter_impl()->GetWindow(); ASSERT_TRUE(app_window); gfx::Rect app_window_bounds = app_window->GetBoundsInRootWindow(); ui::test::EventGenerator& generator = GetEventGenerator(); // Click on the bubble itself. The bubble should remain visible. generator.GestureTapAt(app_window_bounds.CenterPoint()); - EXPECT_TRUE(WmShell::Get()->GetAppListTargetVisibility()); + EXPECT_TRUE(app_list_presenter_impl()->GetTargetVisibility()); // Click outside the bubble. This should close it. gfx::Point point_outside = gfx::Point(app_window_bounds.right(), app_window_bounds.y()) + gfx::Vector2d(10, 0); generator.GestureTapAt(point_outside); - EXPECT_FALSE(WmShell::Get()->GetAppListTargetVisibility()); + EXPECT_FALSE(app_list_presenter_impl()->GetTargetVisibility()); } // Tests opening the app launcher on a non-primary display, then deleting the @@ -136,15 +126,15 @@ WmWindow* secondary_root = root_windows[1]; EXPECT_EQ("1024,0 1024x768", secondary_root->GetBoundsInScreen().ToString()); - WmShell::Get()->delegate()->GetAppListPresenter()->Show( + app_list_presenter_impl()->Show( secondary_root->GetDisplayNearestWindow().id()); - EXPECT_TRUE(WmShell::Get()->GetAppListTargetVisibility()); + EXPECT_TRUE(app_list_presenter_impl()->GetTargetVisibility()); // Remove the secondary display. Shouldn't crash (http://crbug.com/368990). UpdateDisplay("1024x768"); // Updating the displays should close the app list. - EXPECT_FALSE(WmShell::Get()->GetAppListTargetVisibility()); + EXPECT_FALSE(app_list_presenter_impl()->GetTargetVisibility()); } // Tests opening the app launcher on a tiny display that is too small to contain @@ -153,17 +143,18 @@ // Set up a screen with a tiny display (height smaller than the app list). UpdateDisplay("400x300"); - WmShell::Get()->ShowAppList(); - EXPECT_TRUE(WmShell::Get()->GetAppListTargetVisibility()); + app_list_presenter_impl()->Show(display_manager()->first_display_id()); + EXPECT_TRUE(app_list_presenter_impl()->GetTargetVisibility()); // The top of the app list should be on-screen (even if the bottom is not). // We need to manually calculate the Y coordinate of the top of the app list // from the anchor (center) and height. There isn't a bounds rect that gives // the actual app list position (the widget bounds include the bubble border // which is much bigger than the actual app list size). - app_list::AppListView* app_list = GetAppListPresenter()->GetView(); + app_list::AppListView* app_list = app_list_presenter_impl()->GetView(); int app_list_view_top = app_list->anchor_rect().y() - app_list->bounds().height() / 2; + const int kMinimalAppListMargin = 10; EXPECT_GE(app_list_view_top, kMinimalAppListMargin); }
diff --git a/ash/common/shell_delegate.h b/ash/common/shell_delegate.h index c007086..f584cf7 100644 --- a/ash/common/shell_delegate.h +++ b/ash/common/shell_delegate.h
@@ -14,10 +14,6 @@ class GURL; -namespace app_list { -class AppListPresenter; -} - namespace gfx { class Image; } @@ -93,11 +89,7 @@ // Opens the |url| in a new browser tab. virtual void OpenUrlFromArc(const GURL& url) = 0; - // Get the AppListPresenter. Ownership stays with Chrome. - virtual app_list::AppListPresenter* GetAppListPresenter() = 0; - - // Creates a new ShelfDelegate. Shell takes ownership of the returned - // value. + // Creates a new ShelfDelegate. Shell takes ownership of the returned value. virtual ShelfDelegate* CreateShelfDelegate(ShelfModel* model) = 0; // Creates a system-tray delegate. Shell takes ownership of the delegate.
diff --git a/ash/common/wm_shell.cc b/ash/common/wm_shell.cc index 5e80f334..5a8c34b 100644 --- a/ash/common/wm_shell.cc +++ b/ash/common/wm_shell.cc
@@ -52,7 +52,6 @@ #include "services/preferences/public/interfaces/preferences.mojom.h" #include "services/service_manager/public/cpp/connector.h" #include "ui/app_list/presenter/app_list.h" -#include "ui/app_list/presenter/app_list_presenter.h" #include "ui/display/display.h" #include "ui/views/focus/focus_manager_factory.h" @@ -344,28 +343,25 @@ void WmShell::ShowAppList() { // Show the app list on the default display for new windows. - int64_t display_id = - GetRootWindowForNewWindows()->GetDisplayNearestWindow().id(); - delegate_->GetAppListPresenter()->Show(display_id); + app_list_->Show(GetRootWindowForNewWindows()->GetDisplayNearestWindow().id()); } void WmShell::DismissAppList() { - delegate_->GetAppListPresenter()->Dismiss(); + app_list_->Dismiss(); } void WmShell::ToggleAppList() { - // Show the app list on the default display for new windows. - int64_t display_id = - GetRootWindowForNewWindows()->GetDisplayNearestWindow().id(); - delegate_->GetAppListPresenter()->ToggleAppList(display_id); + // Toggle the app list on the default display for new windows. + app_list_->ToggleAppList( + GetRootWindowForNewWindows()->GetDisplayNearestWindow().id()); } bool WmShell::IsApplistVisible() const { - return delegate_->GetAppListPresenter()->IsVisible(); + return app_list_->IsVisible(); } bool WmShell::GetAppListTargetVisibility() const { - return delegate_->GetAppListPresenter()->GetTargetVisibility(); + return app_list_->GetTargetVisibility(); } void WmShell::SetKeyboardUI(std::unique_ptr<KeyboardUI> keyboard_ui) {
diff --git a/ash/mus/BUILD.gn b/ash/mus/BUILD.gn index 9b3847c..893c2ae 100644 --- a/ash/mus/BUILD.gn +++ b/ash/mus/BUILD.gn
@@ -20,8 +20,6 @@ "accelerators/accelerator_ids.h", "accessibility_delegate_mus.cc", "accessibility_delegate_mus.h", - "app_list_presenter_mus.cc", - "app_list_presenter_mus.h", "bridge/immersive_handler_factory_mus.cc", "bridge/immersive_handler_factory_mus.h", "bridge/wm_lookup_mus.cc",
diff --git a/ash/mus/app_list_presenter_mus.cc b/ash/mus/app_list_presenter_mus.cc deleted file mode 100644 index 86d2cac..0000000 --- a/ash/mus/app_list_presenter_mus.cc +++ /dev/null
@@ -1,49 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ash/mus/app_list_presenter_mus.h" - -#include "ash/common/wm_shell.h" -#include "ui/app_list/presenter/app_list.h" - -namespace ash { - -AppListPresenterMus::AppListPresenterMus() {} - -AppListPresenterMus::~AppListPresenterMus() {} - -void AppListPresenterMus::Show(int64_t display_id) { - app_list::mojom::AppListPresenter* app_list_presenter = - WmShell::Get()->app_list()->GetAppListPresenter(); - if (app_list_presenter) - app_list_presenter->Show(display_id); -} - -void AppListPresenterMus::Dismiss() { - app_list::mojom::AppListPresenter* app_list_presenter = - WmShell::Get()->app_list()->GetAppListPresenter(); - if (app_list_presenter) - app_list_presenter->Dismiss(); -} - -void AppListPresenterMus::ToggleAppList(int64_t display_id) { - app_list::mojom::AppListPresenter* app_list_presenter = - WmShell::Get()->app_list()->GetAppListPresenter(); - if (app_list_presenter) - app_list_presenter->ToggleAppList(display_id); -} - -bool AppListPresenterMus::IsVisible() const { - return false; -} - -bool AppListPresenterMus::GetTargetVisibility() const { - // TODO(mfomitchev): we have GetTargetVisibility() in mojom, but this - // shouldn't be a synchronous method. We should go through the call sites and - // either teach them to use a callback, or perhaps use a visibility observer. - // NOTIMPLEMENTED(); - return false; -} - -} // namespace ash
diff --git a/ash/mus/app_list_presenter_mus.h b/ash/mus/app_list_presenter_mus.h deleted file mode 100644 index 5127557..0000000 --- a/ash/mus/app_list_presenter_mus.h +++ /dev/null
@@ -1,33 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef ASH_MUS_APP_LIST_PRESENTER_MUS_H_ -#define ASH_MUS_APP_LIST_PRESENTER_MUS_H_ - -#include "base/macros.h" -#include "ui/app_list/presenter/app_list_presenter.h" - -namespace ash { - -// Mus+ash implementation of the AppListPresenter interface for mash, which -// talks to the app list presenter service in chrome. -class AppListPresenterMus : public app_list::AppListPresenter { - public: - AppListPresenterMus(); - ~AppListPresenterMus() override; - - // app_list::AppListPresenter: - void Show(int64_t display_id) override; - void Dismiss() override; - void ToggleAppList(int64_t display_id) override; - bool IsVisible() const override; - bool GetTargetVisibility() const override; - - private: - DISALLOW_COPY_AND_ASSIGN(AppListPresenterMus); -}; - -} // namespace ash - -#endif // ASH_MUS_APP_LIST_PRESENTER_MUS_H_
diff --git a/ash/mus/shell_delegate_mus.cc b/ash/mus/shell_delegate_mus.cc index 37ec044..0d0ad713 100644 --- a/ash/mus/shell_delegate_mus.cc +++ b/ash/mus/shell_delegate_mus.cc
@@ -146,10 +146,6 @@ NOTIMPLEMENTED(); } -app_list::AppListPresenter* ShellDelegateMus::GetAppListPresenter() { - return &app_list_presenter_; -} - ShelfDelegate* ShellDelegateMus::CreateShelfDelegate(ShelfModel* model) { return new ShelfDelegateMus(); }
diff --git a/ash/mus/shell_delegate_mus.h b/ash/mus/shell_delegate_mus.h index a876c8ba..fd88232 100644 --- a/ash/mus/shell_delegate_mus.h +++ b/ash/mus/shell_delegate_mus.h
@@ -8,7 +8,6 @@ #include <memory> #include "ash/common/shell_delegate.h" -#include "ash/mus/app_list_presenter_mus.h" #include "base/macros.h" namespace service_manager { @@ -34,7 +33,6 @@ void Exit() override; keyboard::KeyboardUI* CreateKeyboardUI() override; void OpenUrlFromArc(const GURL& url) override; - app_list::AppListPresenter* GetAppListPresenter() override; ShelfDelegate* CreateShelfDelegate(ShelfModel* model) override; SystemTrayDelegate* CreateSystemTrayDelegate() override; std::unique_ptr<WallpaperDelegate> CreateWallpaperDelegate() override; @@ -53,7 +51,6 @@ private: service_manager::Connector* connector_; - AppListPresenterMus app_list_presenter_; DISALLOW_COPY_AND_ASSIGN(ShellDelegateMus); };
diff --git a/ash/mus/window_manager.cc b/ash/mus/window_manager.cc index 6ff5d61..a2630f2 100644 --- a/ash/mus/window_manager.cc +++ b/ash/mus/window_manager.cc
@@ -14,7 +14,6 @@ #include "ash/display/screen_position_controller.h" #include "ash/mus/accelerators/accelerator_handler.h" #include "ash/mus/accelerators/accelerator_ids.h" -#include "ash/mus/app_list_presenter_mus.h" #include "ash/mus/bridge/wm_lookup_mus.h" #include "ash/mus/bridge/wm_root_window_controller_mus.h" #include "ash/mus/bridge/wm_shell_mus.h"
diff --git a/ash/shelf/shelf_layout_manager_unittest.cc b/ash/shelf/shelf_layout_manager_unittest.cc index cd63f30..e7a3205 100644 --- a/ash/shelf/shelf_layout_manager_unittest.cc +++ b/ash/shelf/shelf_layout_manager_unittest.cc
@@ -25,6 +25,7 @@ #include "ash/root_window_controller.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" +#include "ash/test/test_app_list_view_presenter_impl.h" #include "ash/test/test_system_tray_item.h" #include "ash/wm/window_state_aura.h" #include "ash/wm/window_util.h" @@ -947,62 +948,63 @@ EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState()); } -// Makes sure shelf will be visible when app list opens as shelf is in -// SHELF_VISIBLE state,and toggling app list won't change shelf -// visibility state. +// Ensure a SHELF_VISIBLE shelf stays visible when the app list is shown. TEST_F(ShelfLayoutManagerTest, OpenAppListWithShelfVisibleState) { - WmShell* shell = WmShell::Get(); WmShelf* shelf = GetPrimaryShelf(); - ShelfLayoutManager* layout_manager = GetShelfLayoutManager(); - layout_manager->LayoutShelf(); shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); - // Create a normal unmaximized window, shelf should be visible. + // The tested behavior relies on the app list presenter implementation. + test::TestAppListViewPresenterImpl app_list_presenter_impl; + + // Create a normal unmaximized window; the shelf should be visible. aura::Window* window = CreateTestWindow(); window->SetBounds(gfx::Rect(0, 0, 100, 100)); window->Show(); - EXPECT_FALSE(shell->GetAppListTargetVisibility()); + EXPECT_FALSE(app_list_presenter_impl.GetTargetVisibility()); EXPECT_EQ(SHELF_VISIBLE, shelf->GetVisibilityState()); - // Show app list and the shelf stays visible. - shell->ShowAppList(); - EXPECT_TRUE(shell->GetAppListTargetVisibility()); + // Show the app list and the shelf stays visible. + app_list_presenter_impl.Show(display_manager()->first_display_id()); + EXPECT_TRUE(app_list_presenter_impl.GetTargetVisibility()); EXPECT_EQ(SHELF_VISIBLE, shelf->GetVisibilityState()); - // Hide app list and the shelf stays visible. - shell->DismissAppList(); - EXPECT_FALSE(shell->GetAppListTargetVisibility()); + // Hide the app list and the shelf stays visible. + app_list_presenter_impl.Dismiss(); + EXPECT_FALSE(app_list_presenter_impl.GetTargetVisibility()); EXPECT_EQ(SHELF_VISIBLE, shelf->GetVisibilityState()); } -// Makes sure shelf will be shown with SHELF_AUTO_HIDE_SHOWN state -// when app list opens as shelf is in SHELF_AUTO_HIDE state, and -// toggling app list won't change shelf visibility state. +// Ensure a SHELF_AUTO_HIDE shelf is shown temporarily (SHELF_AUTO_HIDE_SHOWN) +// when the app list is shown, but the visibility state doesn't change. TEST_F(ShelfLayoutManagerTest, OpenAppListWithShelfAutoHideState) { - WmShell* shell = WmShell::Get(); WmShelf* shelf = GetPrimaryShelf(); - ShelfLayoutManager* layout_manager = GetShelfLayoutManager(); - layout_manager->LayoutShelf(); shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); - EXPECT_FALSE(shell->GetAppListTargetVisibility()); - EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState()); - EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState()); + // The tested behavior relies on the app list presenter implementation. + test::TestAppListViewPresenterImpl app_list_presenter_impl; - // Show app list. - shell->ShowAppList(); + // Create a normal unmaximized window; the shelf should be hidden. + aura::Window* window = CreateTestWindow(); + window->SetBounds(gfx::Rect(0, 0, 100, 100)); + window->Show(); + EXPECT_FALSE(app_list_presenter_impl.GetTargetVisibility()); + EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState()); + EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->GetAutoHideState()); + + // Show the app list and the shelf should be temporarily visible. + app_list_presenter_impl.Show(display_manager()->first_display_id()); // The shelf's auto hide state won't be changed until the timer fires, so // force it to update now. - layout_manager->UpdateVisibilityState(); - EXPECT_TRUE(shell->GetAppListTargetVisibility()); + GetShelfLayoutManager()->UpdateVisibilityState(); + EXPECT_TRUE(app_list_presenter_impl.GetTargetVisibility()); EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState()); EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState()); - // Hide app list. - shell->DismissAppList(); - EXPECT_FALSE(shell->GetAppListTargetVisibility()); + // Hide the app list and the shelf should be hidden again. + app_list_presenter_impl.Dismiss(); + EXPECT_FALSE(app_list_presenter_impl.GetTargetVisibility()); EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState()); - EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState()); + EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->GetAutoHideState()); } // Makes sure that when we have dual displays, with one or both shelves are set @@ -1043,65 +1045,63 @@ EXPECT_EQ(shelf_2->GetWindow()->GetRootWindow(), WmWindowAura::Get(window_2)->GetRootWindow()); - // Activate one window in one display and manually trigger the update of shelf - // visibility. + // Activate one window in one display. wm::ActivateWindow(window_1); - Shell::GetInstance()->UpdateShelfVisibility(); - EXPECT_FALSE(WmShell::Get()->GetAppListTargetVisibility()); + // The tested behavior relies on the app list presenter implementation. + test::TestAppListViewPresenterImpl app_list_presenter_impl; + + Shell::GetInstance()->UpdateShelfVisibility(); + EXPECT_FALSE(app_list_presenter_impl.GetTargetVisibility()); EXPECT_EQ(SHELF_AUTO_HIDE, shelf_1->GetVisibilityState()); EXPECT_EQ(SHELF_AUTO_HIDE, shelf_2->GetVisibilityState()); EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf_1->GetAutoHideState()); EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf_2->GetAutoHideState()); - // Show app list. - WmShell::Get()->ShowAppList(); + // Show the app list; only the shelf on the same display should be shown. + app_list_presenter_impl.Show(display_manager()->first_display_id()); Shell::GetInstance()->UpdateShelfVisibility(); - - // Only the shelf in the active display should be shown, the other is hidden. - EXPECT_TRUE(WmShell::Get()->GetAppListTargetVisibility()); + EXPECT_TRUE(app_list_presenter_impl.GetTargetVisibility()); EXPECT_EQ(SHELF_AUTO_HIDE, shelf_1->GetVisibilityState()); EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf_1->GetAutoHideState()); EXPECT_EQ(SHELF_AUTO_HIDE, shelf_2->GetVisibilityState()); EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf_2->GetAutoHideState()); - // Hide app list, both shelves should be hidden. - WmShell::Get()->DismissAppList(); - EXPECT_FALSE(WmShell::Get()->GetAppListTargetVisibility()); + // Hide the app list, both shelves should be hidden. + app_list_presenter_impl.Dismiss(); + Shell::GetInstance()->UpdateShelfVisibility(); + EXPECT_FALSE(app_list_presenter_impl.GetTargetVisibility()); EXPECT_EQ(SHELF_AUTO_HIDE, shelf_1->GetVisibilityState()); EXPECT_EQ(SHELF_AUTO_HIDE, shelf_2->GetVisibilityState()); EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf_1->GetAutoHideState()); EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf_2->GetAutoHideState()); } -// Makes sure the shelf will be hidden when we have a fullscreen window, and it -// will unhide when we open the app list. +// Ensure a SHELF_HIDDEN shelf (for a fullscreen window) is shown temporarily +// when the app list is shown, and hidden again when the app list is dismissed. TEST_F(ShelfLayoutManagerTest, OpenAppListWithShelfHiddenState) { - WmShell* shell = WmShell::Get(); WmShelf* shelf = GetPrimaryShelf(); - ShelfLayoutManager* layout_manager = GetShelfLayoutManager(); - // For shelf to be visible, app list is not open in initial state. - layout_manager->LayoutShelf(); - // Create a window and make it full screen. + // The tested behavior relies on the app list presenter implementation. + test::TestAppListViewPresenterImpl app_list_presenter_impl; + + // Create a window and make it full screen; the shelf should be hidden. aura::Window* window = CreateTestWindow(); window->SetBounds(gfx::Rect(0, 0, 100, 100)); window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN); window->Show(); wm::ActivateWindow(window); - - // App list and shelf is not shown. - EXPECT_FALSE(shell->GetAppListTargetVisibility()); + EXPECT_FALSE(app_list_presenter_impl.GetTargetVisibility()); EXPECT_EQ(SHELF_HIDDEN, shelf->GetVisibilityState()); - // Show app list. - shell->ShowAppList(); - EXPECT_TRUE(shell->GetAppListTargetVisibility()); + // Show the app list and the shelf should be temporarily visible. + app_list_presenter_impl.Show(display_manager()->first_display_id()); + EXPECT_TRUE(app_list_presenter_impl.GetTargetVisibility()); EXPECT_EQ(SHELF_VISIBLE, shelf->GetVisibilityState()); - // Hide app list. - shell->DismissAppList(); - EXPECT_FALSE(shell->GetAppListTargetVisibility()); + // Hide the app list and the shelf should be hidden again. + app_list_presenter_impl.Dismiss(); + EXPECT_FALSE(app_list_presenter_impl.GetTargetVisibility()); EXPECT_EQ(SHELF_HIDDEN, shelf->GetVisibilityState()); }
diff --git a/ash/shelf/shelf_view_unittest.cc b/ash/shelf/shelf_view_unittest.cc index d5be149..d0f85d62 100644 --- a/ash/shelf/shelf_view_unittest.cc +++ b/ash/shelf/shelf_view_unittest.cc
@@ -48,7 +48,7 @@ #include "base/test/user_action_tester.h" #include "base/time/time.h" #include "testing/gmock/include/gmock/gmock.h" -#include "ui/app_list/presenter/app_list_presenter.h" +#include "ui/app_list/presenter/app_list.h" #include "ui/aura/test/aura_test_base.h" #include "ui/aura/window.h" #include "ui/aura/window_event_dispatcher.h" @@ -1470,8 +1470,11 @@ } TEST_F(ShelfViewTest, ShouldHideTooltipWithAppListWindowTest) { - WmShell::Get()->ShowAppList(); - ASSERT_TRUE(WmShell::Get()->GetAppListTargetVisibility()); + // Trigger mock notifications that the app list was shown. + WmShell::Get()->app_list()->OnTargetVisibilityChanged(true); + WmShell::Get()->app_list()->OnVisibilityChanged(true); + AppListButton* app_list_button = shelf_view_->GetAppListButton(); + app_list_button->OnAppListShown(); // The tooltip shouldn't hide if the mouse is on normal buttons. for (int i = 1; i < test_api_->GetButtonCount(); i++) { @@ -1484,8 +1487,7 @@ << "ShelfView tries to hide on button " << i; } - // The tooltip should hide on the app-list button. - AppListButton* app_list_button = shelf_view_->GetAppListButton(); + // The tooltip should hide on the app list button if the app list is visible. EXPECT_TRUE(shelf_view_->ShouldHideTooltip( app_list_button->GetMirroredBounds().CenterPoint())); } @@ -2052,61 +2054,6 @@ DISALLOW_COPY_AND_ASSIGN(ListMenuShelfItemDelegate); }; -// A test implementation for AppListPresenter that does not change visibility -// state immediately to simulate an in-flight animation. Calling -// FinishVisibilityChange() will change the visibility to the requested one, -// simulating end of the animation. Similar to the actual AppListPresenter, this -// class toggles app list visibility based on the actual visibility rather than -// the target visibility (which might be different due to in-flight animation). -class TestAppListPresenter : public app_list::AppListPresenter { - public: - TestAppListPresenter() {} - ~TestAppListPresenter() override {} - - void FinishVisibilityChange() { is_visible_ = target_visibility_; } - - // app_list::AppListPresenter: - void Show(int64_t display_id) override { target_visibility_ = true; } - void Dismiss() override { target_visibility_ = false; } - void ToggleAppList(int64_t display_id) override { - if (is_visible_) - Dismiss(); - else - Show(display_id); - } - bool IsVisible() const override { return is_visible_; } - bool GetTargetVisibility() const override { return target_visibility_; } - - private: - bool is_visible_ = false; - bool target_visibility_ = false; - - DISALLOW_COPY_AND_ASSIGN(TestAppListPresenter); -}; - -// A test ShellDelegate implementation that returns a TestAppListPresenter as -// the app list presenter. -class TestAppListShellDelegate : public TestShellDelegate { - public: - TestAppListShellDelegate() - : app_list_presenter_(new TestAppListPresenter()) {} - ~TestAppListShellDelegate() override {} - - TestAppListPresenter* app_list_presenter() const { - return app_list_presenter_.get(); - } - - // TestShellDelegate: - app_list::AppListPresenter* GetAppListPresenter() override { - return app_list_presenter(); - } - - private: - std::unique_ptr<TestAppListPresenter> app_list_presenter_; - - DISALLOW_COPY_AND_ASSIGN(TestAppListShellDelegate); -}; - } // namespace // Test fixture that forces material design mode in order to test ink drop @@ -2129,8 +2076,7 @@ // before calling base class's SetUp(). Shell will take ownership of the // returned object. virtual TestShellDelegate* CreateTestShellDelegate() { - shell_delegate_ = new TestAppListShellDelegate; - return shell_delegate_; + return new TestShellDelegate; } void InitAppListButtonInkDrop() { @@ -2156,28 +2102,23 @@ } void ShowAppList() { - DCHECK(shelf_delegate_); - shell_delegate_->app_list_presenter()->Show(0); - // Similar to real AppListPresenter, notify button that the app list is - // shown. + // Trigger a mock notification that the app list was shown. + WmShell::Get()->app_list()->OnTargetVisibilityChanged(true); app_list_button_->OnAppListShown(); } void DismissAppList() { - DCHECK(shelf_delegate_); - shell_delegate_->app_list_presenter()->Dismiss(); - // Similar to real AppListPresenter, notify button that the app list is - // dismissed. + // Trigger a mock notification that the app list was dismissed. + WmShell::Get()->app_list()->OnTargetVisibilityChanged(false); app_list_button_->OnAppListDismissed(); } void FinishAppListVisibilityChange() { - DCHECK(shelf_delegate_); - shell_delegate_->app_list_presenter()->FinishVisibilityChange(); + // Trigger a mock notification that the app list finished animating. + app_list::AppList* app_list = WmShell::Get()->app_list(); + app_list->OnVisibilityChanged(app_list->GetTargetVisibility()); } - TestAppListShellDelegate* shell_delegate_ = nullptr; // Owned by Shell. - AppListButton* app_list_button_ = nullptr; InkDropSpy* app_list_button_ink_drop_ = nullptr; ShelfButton* browser_button_ = nullptr; @@ -2219,7 +2160,7 @@ // Mouse press on the button, which shows the app list, should end up in the // activated state. generator.PressLeftButton(); - // Similar to real AppListPresenter, notify button that the app list is shown. + // Trigger a mock button notification that the app list was shown. app_list_button_->OnAppListShown(); FinishAppListVisibilityChange(); EXPECT_EQ(views::InkDropState::ACTIVATED, @@ -2245,7 +2186,6 @@ TEST_F(ShelfViewInkDropTest, AppListButtonMouseEventsWhenVisible) { InitAppListButtonInkDrop(); - // Show the app list. ShowAppList(); FinishAppListVisibilityChange(); EXPECT_EQ(views::InkDropState::ACTIVATED, @@ -2258,7 +2198,6 @@ // Mouse press on the button, which dismisses the app list, should end up in // the hidden state. - // Dismiss app list similar to pre-target handler in real AppListPresenter. DismissAppList(); generator.PressLeftButton(); FinishAppListVisibilityChange(); @@ -2298,7 +2237,7 @@ // Touch release on the button, which shows the app list, should end up in the // activated state. generator.ReleaseTouch(); - // Similar to real AppListPresenter, notify button that the app list is shown. + // Trigger a mock button notification that the app list was shown. app_list_button_->OnAppListShown(); FinishAppListVisibilityChange(); EXPECT_EQ(views::InkDropState::ACTIVATED, @@ -2312,7 +2251,6 @@ TEST_F(ShelfViewInkDropTest, AppListButtonGestureTapWhenVisible) { InitAppListButtonInkDrop(); - // Show the app list. ShowAppList(); FinishAppListVisibilityChange(); EXPECT_EQ(views::InkDropState::ACTIVATED, @@ -2325,7 +2263,6 @@ // Touch press on the button, which dismisses the app list, should end up in // the hidden state. - // Dismiss app list similar to pre-target handler in real AppListPresenter. DismissAppList(); generator.PressTouch(); EXPECT_EQ(views::InkDropState::HIDDEN, @@ -2380,7 +2317,6 @@ TEST_F(ShelfViewInkDropTest, AppListButtonGestureTapDragWhenVisible) { InitAppListButtonInkDrop(); - // Show the app list. ShowAppList(); FinishAppListVisibilityChange(); EXPECT_EQ(views::InkDropState::ACTIVATED, @@ -2395,7 +2331,6 @@ // Touch press on the button, which dismisses the app list, should end up in // the hidden state. - // Dismiss app list similar to pre-target handler in real AppListPresenter. DismissAppList(); generator.PressTouch(); EXPECT_EQ(views::InkDropState::HIDDEN,
diff --git a/ash/shell/content/client/shell_browser_main_parts.cc b/ash/shell/content/client/shell_browser_main_parts.cc index 7fac63e..bb85840 100644 --- a/ash/shell/content/client/shell_browser_main_parts.cc +++ b/ash/shell/content/client/shell_browser_main_parts.cc
@@ -10,6 +10,7 @@ #include "ash/content/shell_content_state.h" #include "ash/shell.h" #include "ash/shell/content/shell_content_state_impl.h" +#include "ash/shell/example_app_list_presenter.h" #include "ash/shell/shell_delegate_impl.h" #include "ash/shell/window_watcher.h" #include "ash/shell_init_params.h" @@ -27,6 +28,7 @@ #include "content/shell/browser/shell_browser_context.h" #include "content/shell/browser/shell_net_log.h" #include "net/base/net_module.h" +#include "ui/app_list/presenter/app_list.h" #include "ui/aura/env.h" #include "ui/aura/window.h" #include "ui/aura/window_tree_host.h" @@ -146,6 +148,11 @@ ash::shell::InitWindowTypeLauncher(); + // Initialize the example app list presenter. + example_app_list_presenter_ = base::MakeUnique<ExampleAppListPresenter>(); + WmShell::Get()->app_list()->SetAppListPresenter( + example_app_list_presenter_->CreateInterfacePtrAndBind()); + ash::Shell::GetPrimaryRootWindow()->GetHost()->Show(); }
diff --git a/ash/shell/content/client/shell_browser_main_parts.h b/ash/shell/content/client/shell_browser_main_parts.h index d633848..a6fe25ee 100644 --- a/ash/shell/content/client/shell_browser_main_parts.h +++ b/ash/shell/content/client/shell_browser_main_parts.h
@@ -30,6 +30,7 @@ namespace ash { namespace shell { +class ExampleAppListPresenter; class ShellDelegateImpl; class WindowWatcher; @@ -57,6 +58,7 @@ std::unique_ptr<ash::shell::WindowWatcher> window_watcher_; ShellDelegateImpl* delegate_; // owned by Shell std::unique_ptr<wm::WMState> wm_state_; + std::unique_ptr<ExampleAppListPresenter> example_app_list_presenter_; DISALLOW_COPY_AND_ASSIGN(ShellBrowserMainParts); };
diff --git a/ash/shell/example_app_list_presenter.cc b/ash/shell/example_app_list_presenter.cc new file mode 100644 index 0000000..0ade6d2 --- /dev/null +++ b/ash/shell/example_app_list_presenter.cc
@@ -0,0 +1,66 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/shell/example_app_list_presenter.h" + +#include "ash/app_list/app_list_presenter_delegate_factory.h" +#include "ash/shell/example_factory.h" +#include "ui/app_list/presenter/app_list_view_delegate_factory.h" + +namespace { + +// An example app list view delegate factory. +class ExampleAppListViewDelegateFactory + : public app_list::AppListViewDelegateFactory { + public: + ExampleAppListViewDelegateFactory() + : app_list_view_delegate_(ash::shell::CreateAppListViewDelegate()) {} + ~ExampleAppListViewDelegateFactory() override {} + + // app_list::AppListViewDelegateFactory: + app_list::AppListViewDelegate* GetDelegate() override { + return app_list_view_delegate_.get(); + } + + private: + std::unique_ptr<app_list::AppListViewDelegate> app_list_view_delegate_; + + DISALLOW_COPY_AND_ASSIGN(ExampleAppListViewDelegateFactory); +}; + +} // namespace + +namespace ash { +namespace shell { + +ExampleAppListPresenter::ExampleAppListPresenter() + : binding_(this), + app_list_presenter_impl_( + base::MakeUnique<AppListPresenterDelegateFactory>( + base::MakeUnique<ExampleAppListViewDelegateFactory>())) { + // Note: This example |app_list_presenter_impl_| does not report visibility + // changes to the app_list::mojom::AppList implementation owned by WmShell. +} + +ExampleAppListPresenter::~ExampleAppListPresenter() {} + +app_list::mojom::AppListPresenterPtr +ExampleAppListPresenter::CreateInterfacePtrAndBind() { + return binding_.CreateInterfacePtrAndBind(); +} + +void ExampleAppListPresenter::Show(int64_t display_id) { + app_list_presenter_impl_.Show(display_id); +} + +void ExampleAppListPresenter::Dismiss() { + app_list_presenter_impl_.Dismiss(); +} + +void ExampleAppListPresenter::ToggleAppList(int64_t display_id) { + app_list_presenter_impl_.ToggleAppList(display_id); +} + +} // namespace shell +} // namespace ash
diff --git a/ash/shell/example_app_list_presenter.h b/ash/shell/example_app_list_presenter.h new file mode 100644 index 0000000..d6c2bff --- /dev/null +++ b/ash/shell/example_app_list_presenter.h
@@ -0,0 +1,40 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_SHELL_EXAMPLE_APP_LIST_PRESENTER_H_ +#define ASH_SHELL_EXAMPLE_APP_LIST_PRESENTER_H_ + +#include "base/macros.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "ui/app_list/presenter/app_list_presenter.mojom.h" +#include "ui/app_list/presenter/app_list_presenter_impl.h" +#include "ui/app_list/presenter/test/test_app_list_view_delegate_factory.h" + +namespace ash { +namespace shell { + +// An example implementation of AppListPresenter used for ash_shell. +class ExampleAppListPresenter : public app_list::mojom::AppListPresenter { + public: + ExampleAppListPresenter(); + ~ExampleAppListPresenter() override; + + app_list::mojom::AppListPresenterPtr CreateInterfacePtrAndBind(); + + // app_list::mojom::AppListPresenter: + void Show(int64_t display_id) override; + void Dismiss() override; + void ToggleAppList(int64_t display_id) override; + + private: + mojo::Binding<app_list::mojom::AppListPresenter> binding_; + app_list::AppListPresenterImpl app_list_presenter_impl_; + + DISALLOW_COPY_AND_ASSIGN(ExampleAppListPresenter); +}; + +} // namespace shell +} // namespace ash + +#endif // ASH_SHELL_EXAMPLE_APP_LIST_PRESENTER_H_
diff --git a/ash/shell/shell_delegate_impl.cc b/ash/shell/shell_delegate_impl.cc index 5670f7d4..ccb54f5 100644 --- a/ash/shell/shell_delegate_impl.cc +++ b/ash/shell/shell_delegate_impl.cc
@@ -4,7 +4,6 @@ #include "ash/shell/shell_delegate_impl.h" -#include "ash/app_list/app_list_presenter_delegate_factory.h" #include "ash/common/accessibility_delegate.h" #include "ash/common/default_accessibility_delegate.h" #include "ash/common/gpu_support_stub.h" @@ -24,9 +23,6 @@ #include "base/message_loop/message_loop.h" #include "base/strings/utf_string_conversions.h" #include "components/user_manager/user_info_impl.h" -#include "ui/app_list/app_list_view_delegate.h" -#include "ui/app_list/presenter/app_list_presenter_impl.h" -#include "ui/app_list/presenter/app_list_view_delegate_factory.h" #include "ui/aura/window.h" #include "ui/gfx/image/image.h" #include "ui/gfx/image/image_skia.h" @@ -125,31 +121,9 @@ DISALLOW_COPY_AND_ASSIGN(SessionStateDelegateImpl); }; -class AppListViewDelegateFactoryImpl - : public app_list::AppListViewDelegateFactory { - public: - AppListViewDelegateFactoryImpl() {} - ~AppListViewDelegateFactoryImpl() override {} - - // app_list::AppListViewDelegateFactory: - app_list::AppListViewDelegate* GetDelegate() override { - if (!app_list_view_delegate_.get()) - app_list_view_delegate_.reset(CreateAppListViewDelegate()); - return app_list_view_delegate_.get(); - } - - private: - std::unique_ptr<app_list::AppListViewDelegate> app_list_view_delegate_; - - DISALLOW_COPY_AND_ASSIGN(AppListViewDelegateFactoryImpl); -}; - } // namespace -ShellDelegateImpl::ShellDelegateImpl() - : shelf_delegate_(nullptr), - app_list_presenter_delegate_factory_(new AppListPresenterDelegateFactory( - base::WrapUnique(new AppListViewDelegateFactoryImpl))) {} +ShellDelegateImpl::ShellDelegateImpl() {} ShellDelegateImpl::~ShellDelegateImpl() {} @@ -191,14 +165,6 @@ void ShellDelegateImpl::OpenUrlFromArc(const GURL& url) {} -app_list::AppListPresenter* ShellDelegateImpl::GetAppListPresenter() { - if (!app_list_presenter_) { - app_list_presenter_.reset(new app_list::AppListPresenterImpl( - app_list_presenter_delegate_factory_.get())); - } - return app_list_presenter_.get(); -} - ShelfDelegate* ShellDelegateImpl::CreateShelfDelegate(ShelfModel* model) { shelf_delegate_ = new test::TestShelfDelegate(model); return shelf_delegate_;
diff --git a/ash/shell/shell_delegate_impl.h b/ash/shell/shell_delegate_impl.h index 7d8ae41..4836b3a 100644 --- a/ash/shell/shell_delegate_impl.h +++ b/ash/shell/shell_delegate_impl.h
@@ -11,11 +11,6 @@ #include "ash/common/shell_delegate.h" #include "base/macros.h" -namespace app_list { -class AppListPresenterDelegateFactory; -class AppListPresenterImpl; -} - namespace keyboard { class KeyboardUI; } @@ -40,7 +35,6 @@ void Exit() override; keyboard::KeyboardUI* CreateKeyboardUI() override; void OpenUrlFromArc(const GURL& url) override; - app_list::AppListPresenter* GetAppListPresenter() override; ShelfDelegate* CreateShelfDelegate(ShelfModel* model) override; SystemTrayDelegate* CreateSystemTrayDelegate() override; std::unique_ptr<WallpaperDelegate> CreateWallpaperDelegate() override; @@ -58,10 +52,7 @@ void UpdateTouchscreenStatusFromPrefs() override; private: - ShelfDelegate* shelf_delegate_; - std::unique_ptr<app_list::AppListPresenterDelegateFactory> - app_list_presenter_delegate_factory_; - std::unique_ptr<app_list::AppListPresenterImpl> app_list_presenter_; + ShelfDelegate* shelf_delegate_ = nullptr; DISALLOW_COPY_AND_ASSIGN(ShellDelegateImpl); };
diff --git a/ash/test/BUILD.gn b/ash/test/BUILD.gn index d90861d7..a7baad0 100644 --- a/ash/test/BUILD.gn +++ b/ash/test/BUILD.gn
@@ -108,6 +108,8 @@ "task_switch_time_tracker_test_api.h", "test_activation_delegate.cc", "test_activation_delegate.h", + "test_app_list_view_presenter_impl.cc", + "test_app_list_view_presenter_impl.h", "test_keyboard_ui.cc", "test_keyboard_ui.h", "test_overlay_delegate.cc", @@ -156,6 +158,7 @@ "//ui/accessibility", "//ui/app_list:test_support", "//ui/app_list/presenter", + "//ui/app_list/presenter:test_support", "//ui/aura", "//ui/aura:test_support", "//ui/base:test_support",
diff --git a/ash/test/test_app_list_view_presenter_impl.cc b/ash/test/test_app_list_view_presenter_impl.cc new file mode 100644 index 0000000..579babf --- /dev/null +++ b/ash/test/test_app_list_view_presenter_impl.cc
@@ -0,0 +1,23 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/test/test_app_list_view_presenter_impl.h" + +#include "ash/app_list/app_list_presenter_delegate_factory.h" +#include "base/memory/ptr_util.h" +#include "ui/app_list/presenter/test/test_app_list_view_delegate_factory.h" + +namespace ash { +namespace test { + +TestAppListViewPresenterImpl::TestAppListViewPresenterImpl() + : app_list::AppListPresenterImpl(base::MakeUnique< + AppListPresenterDelegateFactory>( + base::MakeUnique<app_list::test::TestAppListViewDelegateFactory>())) { +} + +TestAppListViewPresenterImpl::~TestAppListViewPresenterImpl() {} + +} // namespace test +} // namespace ash
diff --git a/ash/test/test_app_list_view_presenter_impl.h b/ash/test/test_app_list_view_presenter_impl.h new file mode 100644 index 0000000..6d414f9 --- /dev/null +++ b/ash/test/test_app_list_view_presenter_impl.h
@@ -0,0 +1,29 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_TEST_TEST_APP_LIST_VIEW_PRESENTER_IMPL_H_ +#define ASH_TEST_TEST_APP_LIST_VIEW_PRESENTER_IMPL_H_ + +#include "ash/ash_export.h" +#include "base/macros.h" +#include "ui/app_list/presenter/app_list_presenter_impl.h" + +namespace ash { +namespace test { + +// An app list presenter impl subclass that presents a no-op test app list view. +// Some tests rely on the presenter and delegate implementations' behavior. +class TestAppListViewPresenterImpl : public app_list::AppListPresenterImpl { + public: + TestAppListViewPresenterImpl(); + ~TestAppListViewPresenterImpl() override; + + private: + DISALLOW_COPY_AND_ASSIGN(TestAppListViewPresenterImpl); +}; + +} // namespace test +} // namespace ash + +#endif // ASH_TEST_TEST_APP_LIST_VIEW_PRESENTER_IMPL_H_
diff --git a/ash/test/test_shell_delegate.cc b/ash/test/test_shell_delegate.cc index 3402d6a..133a98b3 100644 --- a/ash/test/test_shell_delegate.cc +++ b/ash/test/test_shell_delegate.cc
@@ -6,8 +6,6 @@ #include <limits> -#include "ash/app_list/app_list_presenter_delegate.h" -#include "ash/app_list/app_list_presenter_delegate_factory.h" #include "ash/common/default_accessibility_delegate.h" #include "ash/common/gpu_support_stub.h" #include "ash/common/palette_delegate.h" @@ -23,9 +21,6 @@ #include "ash/wm/window_util.h" #include "base/logging.h" #include "base/memory/ptr_util.h" -#include "ui/app_list/presenter/app_list_presenter_impl.h" -#include "ui/app_list/presenter/app_list_view_delegate_factory.h" -#include "ui/app_list/test/app_list_test_view_delegate.h" #include "ui/aura/window.h" #include "ui/gfx/image/image.h" @@ -35,38 +30,12 @@ namespace ash { namespace test { -namespace { - -class AppListViewDelegateFactoryImpl - : public app_list::AppListViewDelegateFactory { - public: - AppListViewDelegateFactoryImpl() {} - ~AppListViewDelegateFactoryImpl() override {} - - // app_list::AppListViewDelegateFactory: - app_list::AppListViewDelegate* GetDelegate() override { - if (!app_list_view_delegate_.get()) { - app_list_view_delegate_.reset( - new app_list::test::AppListTestViewDelegate); - } - return app_list_view_delegate_.get(); - } - - private: - std::unique_ptr<app_list::AppListViewDelegate> app_list_view_delegate_; - - DISALLOW_COPY_AND_ASSIGN(AppListViewDelegateFactoryImpl); -}; - -} // namespace TestShellDelegate::TestShellDelegate() : num_exit_requests_(0), multi_profiles_enabled_(false), force_maximize_on_first_run_(false), - touchscreen_enabled_in_local_pref_(true), - app_list_presenter_delegate_factory_(new AppListPresenterDelegateFactory( - base::WrapUnique(new AppListViewDelegateFactoryImpl))) {} + touchscreen_enabled_in_local_pref_(true) {} TestShellDelegate::~TestShellDelegate() {} @@ -108,14 +77,6 @@ void TestShellDelegate::OpenUrlFromArc(const GURL& url) {} -app_list::AppListPresenter* TestShellDelegate::GetAppListPresenter() { - if (!app_list_presenter_) { - app_list_presenter_.reset(new app_list::AppListPresenterImpl( - app_list_presenter_delegate_factory_.get())); - } - return app_list_presenter_.get(); -} - ShelfDelegate* TestShellDelegate::CreateShelfDelegate(ShelfModel* model) { return new TestShelfDelegate(model); }
diff --git a/ash/test/test_shell_delegate.h b/ash/test/test_shell_delegate.h index a2722be..fe30c3c 100644 --- a/ash/test/test_shell_delegate.h +++ b/ash/test/test_shell_delegate.h
@@ -12,11 +12,6 @@ #include "ash/common/test/test_session_state_delegate.h" #include "base/macros.h" -namespace app_list { -class AppListPresenterDelegateFactory; -class AppListPresenterImpl; -} - namespace keyboard { class KeyboardUI; } @@ -45,7 +40,6 @@ void Exit() override; keyboard::KeyboardUI* CreateKeyboardUI() override; void OpenUrlFromArc(const GURL& url) override; - app_list::AppListPresenter* GetAppListPresenter() override; ShelfDelegate* CreateShelfDelegate(ShelfModel* model) override; SystemTrayDelegate* CreateSystemTrayDelegate() override; std::unique_ptr<WallpaperDelegate> CreateWallpaperDelegate() override; @@ -65,10 +59,6 @@ int num_exit_requests() const { return num_exit_requests_; } - app_list::AppListPresenterImpl* app_list_presenter() { - return app_list_presenter_.get(); - } - void SetForceMaximizeOnFirstRun(bool maximize) { force_maximize_on_first_run_ = maximize; } @@ -79,10 +69,6 @@ bool force_maximize_on_first_run_; bool touchscreen_enabled_in_local_pref_; - std::unique_ptr<app_list::AppListPresenterDelegateFactory> - app_list_presenter_delegate_factory_; - std::unique_ptr<app_list::AppListPresenterImpl> app_list_presenter_; - DISALLOW_COPY_AND_ASSIGN(TestShellDelegate); };
diff --git a/ash/wm/overview/window_selector_unittest.cc b/ash/wm/overview/window_selector_unittest.cc index 4be3a09..915d253 100644 --- a/ash/wm/overview/window_selector_unittest.cc +++ b/ash/wm/overview/window_selector_unittest.cc
@@ -36,6 +36,7 @@ #include "ash/test/ash_test_base.h" #include "ash/test/shelf_view_test_api.h" #include "ash/test/shell_test_api.h" +#include "ash/test/test_app_list_view_presenter_impl.h" #include "ash/wm/window_state_aura.h" #include "ash/wm/window_util.h" #include "base/command_line.h" @@ -1207,10 +1208,15 @@ gfx::Rect bounds(0, 0, 400, 400); std::unique_ptr<aura::Window> window1(CreateWindow(bounds)); std::unique_ptr<aura::Window> window2(CreateWindow(bounds)); - WmShell::Get()->ShowAppList(); - EXPECT_TRUE(WmShell::Get()->GetAppListTargetVisibility()); + + // The tested behavior relies on the app list presenter delegate. + test::TestAppListViewPresenterImpl app_list_presenter_impl; + + app_list_presenter_impl.Show(display_manager()->first_display_id()); + EXPECT_TRUE(app_list_presenter_impl.IsVisible()); + ToggleOverview(); - EXPECT_FALSE(WmShell::Get()->GetAppListTargetVisibility()); + EXPECT_FALSE(app_list_presenter_impl.IsVisible()); ToggleOverview(); }
diff --git a/ash/wm/window_cycle_controller_unittest.cc b/ash/wm/window_cycle_controller_unittest.cc index 2223ec5e..ed72e1c 100644 --- a/ash/wm/window_cycle_controller_unittest.cc +++ b/ash/wm/window_cycle_controller_unittest.cc
@@ -22,6 +22,7 @@ #include "ash/shell.h" #include "ash/test/ash_test_base.h" #include "ash/test/shelf_view_test_api.h" +#include "ash/test/test_app_list_view_presenter_impl.h" #include "ash/test/test_shell_delegate.h" #include "ash/wm/window_state_aura.h" #include "ash/wm/window_util.h" @@ -31,6 +32,7 @@ #include "ui/aura/test/test_windows.h" #include "ui/aura/window.h" #include "ui/aura/window_event_dispatcher.h" +#include "ui/display/manager/display_manager.h" #include "ui/events/event_handler.h" #include "ui/events/test/event_generator.h" #include "ui/gfx/geometry/rect.h" @@ -473,14 +475,17 @@ // Tests that beginning window selection hides the app list. TEST_F(WindowCycleControllerTest, SelectingHidesAppList) { + // The tested behavior relies on the app list presenter implementation. + test::TestAppListViewPresenterImpl app_list_presenter_impl; + WindowCycleController* controller = WmShell::Get()->window_cycle_controller(); std::unique_ptr<aura::Window> window0(CreateTestWindowInShellWithId(0)); std::unique_ptr<aura::Window> window1(CreateTestWindowInShellWithId(1)); - WmShell::Get()->ShowAppList(); - EXPECT_TRUE(WmShell::Get()->GetAppListTargetVisibility()); + app_list_presenter_impl.Show(display_manager()->first_display_id()); + EXPECT_TRUE(app_list_presenter_impl.IsVisible()); controller->HandleCycleWindow(WindowCycleController::FORWARD); - EXPECT_FALSE(WmShell::Get()->GetAppListTargetVisibility()); + EXPECT_FALSE(app_list_presenter_impl.IsVisible()); // Make sure that dismissing the app list this way doesn't pass activation // to a different window.
diff --git a/base/trace_event/heap_profiler_allocation_register.cc b/base/trace_event/heap_profiler_allocation_register.cc index 2c2cd378..63d4061 100644 --- a/base/trace_event/heap_profiler_allocation_register.cc +++ b/base/trace_event/heap_profiler_allocation_register.cc
@@ -60,12 +60,12 @@ // The multiplicative hashing scheme from [Knuth 1998]. The value of |a| has // been chosen carefully based on measurements with real-word data (addresses // recorded from a Chrome trace run). It is the first prime after 2^17. For - // |shift|, 13, 14 and 15 yield good results. These values are tuned to 2^18 - // buckets. Microbenchmarks show that this simple scheme outperforms fancy - // hashes like Murmur3 by 20 to 40 percent. + // |shift|, 15 yield good results for both 2^18 and 2^19 bucket sizes. + // Microbenchmarks show that this simple scheme outperforms fancy hashes like + // Murmur3 by 20 to 40 percent. const uintptr_t key = reinterpret_cast<uintptr_t>(address); const uintptr_t a = 131101; - const uintptr_t shift = 14; + const uintptr_t shift = 15; const uintptr_t h = (key * a) >> shift; return h; }
diff --git a/base/trace_event/heap_profiler_allocation_register.h b/base/trace_event/heap_profiler_allocation_register.h index 873aebfc..d6a02fae 100644 --- a/base/trace_event/heap_profiler_allocation_register.h +++ b/base/trace_event/heap_profiler_allocation_register.h
@@ -16,6 +16,7 @@ #include "base/process/process_metrics.h" #include "base/template_util.h" #include "base/trace_event/heap_profiler_allocation_context.h" +#include "build/build_config.h" namespace base { namespace trace_event { @@ -198,7 +199,9 @@ // the simplest solution is to just allocate a humongous chunk of address // space. - DCHECK_LT(next_unused_cell_, num_cells_ + 1); + CHECK_LT(next_unused_cell_, num_cells_ + 1) + << "Allocation Register hash table has too little capacity. Increase " + "the capacity to run heap profiler in large sessions."; return &cells_[idx]; } @@ -299,10 +302,16 @@ private: friend AllocationRegisterTest; - // Expect max 1.5M allocations. Number of buckets is 2^18 for optimal - // hashing and should be changed together with AddressHasher. +// Expect lower number of allocations from mobile platforms. Load factor +// (capacity / bucket count) is kept less than 10 for optimal hashing. The +// number of buckets should be changed together with AddressHasher. +#if defined(OS_ANDROID) || defined(OS_IOS) static const size_t kAllocationBuckets = 1 << 18; static const size_t kAllocationCapacity = 1500000; +#else + static const size_t kAllocationBuckets = 1 << 19; + static const size_t kAllocationCapacity = 5000000; +#endif // 2^16 works well with BacktraceHasher. When increasing this number make // sure BacktraceHasher still produces low number of collisions.
diff --git a/blimp/engine/BUILD.gn b/blimp/engine/BUILD.gn index 6007542..f321db4 100644 --- a/blimp/engine/BUILD.gn +++ b/blimp/engine/BUILD.gn
@@ -93,7 +93,7 @@ "//base", "//blimp/common", "//blimp/common/proto", - "//blimp/engine:blob_channel_mojo_cpp_sources", + "//blimp/engine:blob_channel_mojo", "//blimp/net", "//components/crash/content/app:app_breakpad_mac_win_to_be_deleted", "//components/crash/content/app:lib", @@ -588,7 +588,7 @@ "//base", "//blimp/common", "//blimp/common:test_support", - "//blimp/engine:blob_channel_mojo_cpp_sources", + "//blimp/engine:blob_channel_mojo", "//blimp/engine:blob_channel_service", "//blimp/net:test_support", "//blimp/test:support",
diff --git a/build/install-build-deps-android.sh b/build/install-build-deps-android.sh index 0261b37..37f4244 100755 --- a/build/install-build-deps-android.sh +++ b/build/install-build-deps-android.sh
@@ -22,7 +22,7 @@ lsb_release=$(lsb_release --codename --short) case $lsb_release in - xenial) + xenial|yakkety) java_alternative="java-1.8.0-openjdk-amd64" java_pkgs="openjdk-8-jre openjdk-8-jdk" ;;
diff --git a/build/install-build-deps.sh b/build/install-build-deps.sh index dcc4108..a7651bf 100755 --- a/build/install-build-deps.sh +++ b/build/install-build-deps.sh
@@ -111,12 +111,12 @@ fi lsb_release=$(lsb_release --codename --short) -supported_releases="(precise|trusty|utopic|vivid|wily|xenial|jessie)" +supported_releases="(precise|trusty|utopic|vivid|wily|xenial|yakkety|jessie)" if [ 0 -eq "${do_unsupported-0}" ] && [ 0 -eq "${do_quick_check-0}" ] ; then if [[ ! $lsb_release =~ $supported_releases ]]; then echo "ERROR: Only Ubuntu 12.04 (precise), 14.04 (trusty), " \ - "14.10 (utopic), 15.04 (vivid), 15.10 (wily) and 16.04 (xenial), " \ - "and Debian 8 (jessie) are currently supported" >&2 + "14.10 (utopic), 15.04 (vivid), 15.10 (wily), 16.04 (xenial), " \ + "16.10 (yakkety) and Debian 8 (jessie) are currently supported" >&2 exit 1 fi @@ -163,7 +163,7 @@ lib_list="libatk1.0-0 libc6 libasound2 libcairo2 libcap2 libcups2 libexpat1 libffi6 libfontconfig1 libfreetype6 libglib2.0-0 libgnome-keyring0 libgtk2.0-0 libpam0g libpango1.0-0 libpci3 libpcre3 libpixman-1-0 - libpng12-0 libspeechd2 libstdc++6 libsqlite3-0 libx11-6 libx11-xcb1 + libspeechd2 libstdc++6 libsqlite3-0 libx11-6 libx11-xcb1 libxau6 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxdmcp6 libxext6 libxfixes3 libxi6 libxinerama1 libxrandr2 libxrender1 libxtst6 zlib1g $chromeos_lib_list" @@ -236,12 +236,7 @@ arm_list+=" g++-4.8-multilib-arm-linux-gnueabihf gcc-4.8-multilib-arm-linux-gnueabihf" ;; - wily) - arm_list+=" g++-5-multilib-arm-linux-gnueabihf - gcc-5-multilib-arm-linux-gnueabihf - gcc-arm-linux-gnueabihf" - ;; - xenial) + wily|xenial|yakkety) arm_list+=" g++-5-multilib-arm-linux-gnueabihf gcc-5-multilib-arm-linux-gnueabihf gcc-arm-linux-gnueabihf" @@ -284,6 +279,11 @@ nacl_list="${nacl_list} libgl1-mesa-glx${mesa_variant}:i386" # Some package names have changed over time +if package_exists libpng12-0; then + lib_list="${lib_list} libpng12-0" +else + lib_list="${lib_list} libpng16-16" +fi if package_exists libnspr4-dbg; then dbg_list="${dbg_list} libnspr4-dbg libnss3-dbg" lib_list="${lib_list} libnspr4 libnss3"
diff --git a/cc/output/shader.cc b/cc/output/shader.cc index ee0e6a7..ea5288b 100644 --- a/cc/output/shader.cc +++ b/cc/output/shader.cc
@@ -29,7 +29,6 @@ // Shaders are passed in with lambda syntax, which tricks clang-format into // handling them correctly. StipLambda removes this. #define SHADER0(Src) StripLambda(#Src) -#define VERTEX_SHADER(Head, Body) SetVertexShaderDefines(Head + Body) using gpu::gles2::GLES2Interface; @@ -76,18 +75,6 @@ return shader_string; } -static std::string SetVertexShaderDefines(const std::string& shader_string) { - // We unconditionally use highp in the vertex shader since - // we are unlikely to be vertex shader bound when drawing large quads. - // Also, some vertex shaders mutate the texture coordinate in such a - // way that the effective precision might be lower than expected. - return base::StringPrintf( - "#define TexCoordPrecision highp\n" - "#define NUM_STATIC_QUADS %d\n", - StaticGeometryBinding::NUM_QUADS) + - shader_string; -} - TexCoordPrecision TexCoordPrecisionRequired(GLES2Interface* context, int* highp_threshold_cache, int highp_threshold_min, @@ -173,41 +160,93 @@ max_size.height()); } -VertexShaderPosTex::VertexShaderPosTex() : matrix_location_(-1) { +VertexShaderBase::VertexShaderBase() {} + +void VertexShaderBase::Init(GLES2Interface* context, + unsigned program, + int* base_uniform_index) { + std::vector<const char*> uniforms; + std::vector<int> locations; + + if (has_tex_transform_) + uniforms.push_back("texTransform"); + if (has_vertex_tex_transform_) + uniforms.push_back("vertexTexTransform"); + if (has_tex_matrix_) + uniforms.push_back("texMatrix"); + if (has_ya_uv_tex_scale_offset_) { + uniforms.push_back("yaTexScale"); + uniforms.push_back("yaTexOffset"); + uniforms.push_back("uvTexScale"); + uniforms.push_back("uvTexOffset"); + } + if (has_matrix_) + uniforms.push_back("matrix"); + if (has_vertex_opacity_) + uniforms.push_back("opacity"); + if (has_aa_) { + uniforms.push_back("viewport"); + uniforms.push_back("edge"); + } + if (has_quad_) + uniforms.push_back("quad"); + + locations.resize(uniforms.size()); + + GetProgramUniformLocations(context, program, uniforms.size(), uniforms.data(), + locations.data(), base_uniform_index); + + size_t index = 0; + if (has_tex_transform_) + tex_transform_location_ = locations[index++]; + if (has_vertex_tex_transform_) + vertex_tex_transform_location_ = locations[index++]; + if (has_tex_matrix_) + tex_matrix_location_ = locations[index++]; + if (has_ya_uv_tex_scale_offset_) { + ya_tex_scale_location_ = locations[index++]; + ya_tex_offset_location_ = locations[index++]; + uv_tex_scale_location_ = locations[index++]; + uv_tex_offset_location_ = locations[index++]; + } + if (has_matrix_) + matrix_location_ = locations[index++]; + if (has_vertex_opacity_) + vertex_opacity_location_ = locations[index++]; + if (has_aa_) { + viewport_location_ = locations[index++]; + edge_location_ = locations[index++]; + } + if (has_quad_) + quad_location_ = locations[index++]; } -void VertexShaderPosTex::Init(GLES2Interface* context, - unsigned program, - int* base_uniform_index) { - static const char* uniforms[] = { - "matrix", - }; - int locations[arraysize(uniforms)]; - - GetProgramUniformLocations(context, - program, - arraysize(uniforms), - uniforms, - locations, - base_uniform_index); - matrix_location_ = locations[0]; +void VertexShaderBase::FillLocations(ShaderLocations* locations) const { + locations->quad = quad_location(); + locations->edge = edge_location(); + locations->viewport = viewport_location(); + locations->matrix = matrix_location(); + locations->tex_transform = tex_transform_location(); } -std::string VertexShaderPosTex::GetShaderString() const { - return VERTEX_SHADER(GetShaderHead(), GetShaderBody()); +std::string VertexShaderBase::GetShaderString() const { + // We unconditionally use highp in the vertex shader since + // we are unlikely to be vertex shader bound when drawing large quads. + // Also, some vertex shaders mutate the texture coordinate in such a + // way that the effective precision might be lower than expected. + return base::StringPrintf( + "#define TexCoordPrecision highp\n" + "#define NUM_STATIC_QUADS %d\n", + StaticGeometryBinding::NUM_QUADS) + + GetShaderSource(); } -std::string VertexShaderPosTex::GetShaderHead() { +std::string VertexShaderPosTex::GetShaderSource() const { return SHADER0([]() { attribute vec4 a_position; attribute TexCoordPrecision vec2 a_texCoord; uniform mat4 matrix; varying TexCoordPrecision vec2 v_texCoord; - }); -} - -std::string VertexShaderPosTex::GetShaderBody() { - return SHADER0([]() { void main() { gl_Position = matrix * a_position; v_texCoord = a_texCoord; @@ -215,40 +254,7 @@ }); } -VertexShaderPosTexYUVStretchOffset::VertexShaderPosTexYUVStretchOffset() - : matrix_location_(-1), - ya_tex_scale_location_(-1), - ya_tex_offset_location_(-1), - uv_tex_scale_location_(-1), - uv_tex_offset_location_(-1) { -} - -void VertexShaderPosTexYUVStretchOffset::Init(GLES2Interface* context, - unsigned program, - int* base_uniform_index) { - static const char* uniforms[] = { - "matrix", "yaTexScale", "yaTexOffset", "uvTexScale", "uvTexOffset", - }; - int locations[arraysize(uniforms)]; - - GetProgramUniformLocations(context, - program, - arraysize(uniforms), - uniforms, - locations, - base_uniform_index); - matrix_location_ = locations[0]; - ya_tex_scale_location_ = locations[1]; - ya_tex_offset_location_ = locations[2]; - uv_tex_scale_location_ = locations[3]; - uv_tex_offset_location_ = locations[4]; -} - -std::string VertexShaderPosTexYUVStretchOffset::GetShaderString() const { - return VERTEX_SHADER(GetShaderHead(), GetShaderBody()); -} - -std::string VertexShaderPosTexYUVStretchOffset::GetShaderHead() { +std::string VertexShaderPosTexYUVStretchOffset::GetShaderSource() const { return SHADER0([]() { precision mediump float; attribute vec4 a_position; @@ -260,11 +266,6 @@ uniform TexCoordPrecision vec2 yaTexOffset; uniform TexCoordPrecision vec2 uvTexScale; uniform TexCoordPrecision vec2 uvTexOffset; - }); -} - -std::string VertexShaderPosTexYUVStretchOffset::GetShaderBody() { - return SHADER0([]() { void main() { gl_Position = matrix * a_position; v_yaTexCoord = a_texCoord * yaTexScale + yaTexOffset; @@ -273,73 +274,15 @@ }); } -VertexShaderPos::VertexShaderPos() : matrix_location_(-1) { -} - -void VertexShaderPos::Init(GLES2Interface* context, - unsigned program, - int* base_uniform_index) { - static const char* uniforms[] = { - "matrix", - }; - int locations[arraysize(uniforms)]; - - GetProgramUniformLocations(context, - program, - arraysize(uniforms), - uniforms, - locations, - base_uniform_index); - matrix_location_ = locations[0]; -} - -std::string VertexShaderPos::GetShaderString() const { - return VERTEX_SHADER(GetShaderHead(), GetShaderBody()); -} - -std::string VertexShaderPos::GetShaderHead() { +std::string VertexShaderPos::GetShaderSource() const { return SHADER0([]() { attribute vec4 a_position; uniform mat4 matrix; - }); -} - -std::string VertexShaderPos::GetShaderBody() { - return SHADER0([]() { void main() { gl_Position = matrix * a_position; } }); } -VertexShaderPosTexTransform::VertexShaderPosTexTransform() - : matrix_location_(-1), - tex_transform_location_(-1), - vertex_opacity_location_(-1) { -} - -void VertexShaderPosTexTransform::Init(GLES2Interface* context, - unsigned program, - int* base_uniform_index) { - static const char* uniforms[] = { - "matrix", "texTransform", "opacity", - }; - int locations[arraysize(uniforms)]; - - GetProgramUniformLocations(context, - program, - arraysize(uniforms), - uniforms, - locations, - base_uniform_index); - matrix_location_ = locations[0]; - tex_transform_location_ = locations[1]; - vertex_opacity_location_ = locations[2]; -} - -std::string VertexShaderPosTexTransform::GetShaderString() const { - return VERTEX_SHADER(GetShaderHead(), GetShaderBody()); -} - -std::string VertexShaderPosTexTransform::GetShaderHead() { +std::string VertexShaderPosTexTransform::GetShaderSource() const { return SHADER0([]() { attribute vec4 a_position; attribute TexCoordPrecision vec2 a_texCoord; @@ -349,11 +292,6 @@ uniform float opacity[NUM_STATIC_QUADS * 4]; varying TexCoordPrecision vec2 v_texCoord; varying float v_alpha; - }); -} - -std::string VertexShaderPosTexTransform::GetShaderBody() { - return SHADER0([]() { void main() { int quad_index = int(a_index * 0.25); // NOLINT gl_Position = matrix[quad_index] * a_position; @@ -364,25 +302,10 @@ }); } -void VertexShaderPosTexTransform::FillLocations( - ShaderLocations* locations) const { - locations->matrix = matrix_location(); - locations->tex_transform = tex_transform_location(); -} - -std::string VertexShaderPosTexIdentity::GetShaderString() const { - return VERTEX_SHADER(GetShaderHead(), GetShaderBody()); -} - -std::string VertexShaderPosTexIdentity::GetShaderHead() { +std::string VertexShaderPosTexIdentity::GetShaderSource() const { return SHADER0([]() { attribute vec4 a_position; varying TexCoordPrecision vec2 v_texCoord; - }); -} - -std::string VertexShaderPosTexIdentity::GetShaderBody() { - return SHADER0([]() { void main() { gl_Position = a_position; v_texCoord = (a_position.xy + vec2(1.0)) * 0.5; @@ -390,33 +313,7 @@ }); } -VertexShaderQuad::VertexShaderQuad() - : matrix_location_(-1), quad_location_(-1) { -} - -void VertexShaderQuad::Init(GLES2Interface* context, - unsigned program, - int* base_uniform_index) { - static const char* uniforms[] = { - "matrix", "quad", - }; - int locations[arraysize(uniforms)]; - - GetProgramUniformLocations(context, - program, - arraysize(uniforms), - uniforms, - locations, - base_uniform_index); - matrix_location_ = locations[0]; - quad_location_ = locations[1]; -} - -std::string VertexShaderQuad::GetShaderString() const { - return VERTEX_SHADER(GetShaderHead(), GetShaderBody()); -} - -std::string VertexShaderQuad::GetShaderHead() { +std::string VertexShaderQuad::GetShaderSource() const { #if defined(OS_ANDROID) // TODO(epenner): Find the cause of this 'quad' uniform // being missing if we don't add dummy variables. @@ -428,20 +325,6 @@ uniform TexCoordPrecision vec2 quad[4]; uniform TexCoordPrecision vec2 dummy_uniform; varying TexCoordPrecision vec2 dummy_varying; - }); -#else - return SHADER0([]() { - attribute TexCoordPrecision vec4 a_position; - attribute float a_index; - uniform mat4 matrix; - uniform TexCoordPrecision vec2 quad[4]; - }); -#endif -} - -std::string VertexShaderQuad::GetShaderBody() { -#if defined(OS_ANDROID) - return SHADER0([]() { void main() { vec2 pos = quad[int(a_index)]; // NOLINT gl_Position = matrix * vec4(pos, a_position.z, a_position.w); @@ -450,6 +333,10 @@ }); #else return SHADER0([]() { + attribute TexCoordPrecision vec4 a_position; + attribute float a_index; + uniform mat4 matrix; + uniform TexCoordPrecision vec2 quad[4]; void main() { vec2 pos = quad[int(a_index)]; // NOLINT gl_Position = matrix * vec4(pos, a_position.z, a_position.w); @@ -458,38 +345,7 @@ #endif } -VertexShaderQuadAA::VertexShaderQuadAA() - : matrix_location_(-1), - viewport_location_(-1), - quad_location_(-1), - edge_location_(-1) { -} - -void VertexShaderQuadAA::Init(GLES2Interface* context, - unsigned program, - int* base_uniform_index) { - static const char* uniforms[] = { - "matrix", "viewport", "quad", "edge", - }; - int locations[arraysize(uniforms)]; - - GetProgramUniformLocations(context, - program, - arraysize(uniforms), - uniforms, - locations, - base_uniform_index); - matrix_location_ = locations[0]; - viewport_location_ = locations[1]; - quad_location_ = locations[2]; - edge_location_ = locations[3]; -} - -std::string VertexShaderQuadAA::GetShaderString() const { - return VERTEX_SHADER(GetShaderHead(), GetShaderBody()); -} - -std::string VertexShaderQuadAA::GetShaderHead() { +std::string VertexShaderQuadAA::GetShaderSource() const { return SHADER0([]() { attribute TexCoordPrecision vec4 a_position; attribute float a_index; @@ -498,11 +354,6 @@ uniform TexCoordPrecision vec2 quad[4]; uniform TexCoordPrecision vec3 edge[8]; varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances. - }); -} - -std::string VertexShaderQuadAA::GetShaderBody() { - return SHADER0([]() { void main() { vec2 pos = quad[int(a_index)]; // NOLINT gl_Position = matrix * vec4(pos, a_position.z, a_position.w); @@ -518,40 +369,7 @@ }); } -VertexShaderQuadTexTransformAA::VertexShaderQuadTexTransformAA() - : matrix_location_(-1), - viewport_location_(-1), - quad_location_(-1), - edge_location_(-1), - tex_transform_location_(-1) { -} - -void VertexShaderQuadTexTransformAA::Init(GLES2Interface* context, - unsigned program, - int* base_uniform_index) { - static const char* uniforms[] = { - "matrix", "viewport", "quad", "edge", "texTrans", - }; - int locations[arraysize(uniforms)]; - - GetProgramUniformLocations(context, - program, - arraysize(uniforms), - uniforms, - locations, - base_uniform_index); - matrix_location_ = locations[0]; - viewport_location_ = locations[1]; - quad_location_ = locations[2]; - edge_location_ = locations[3]; - tex_transform_location_ = locations[4]; -} - -std::string VertexShaderQuadTexTransformAA::GetShaderString() const { - return VERTEX_SHADER(GetShaderHead(), GetShaderBody()); -} - -std::string VertexShaderQuadTexTransformAA::GetShaderHead() { +std::string VertexShaderQuadTexTransformAA::GetShaderSource() const { return SHADER0([]() { attribute TexCoordPrecision vec4 a_position; attribute float a_index; @@ -559,14 +377,9 @@ uniform vec4 viewport; uniform TexCoordPrecision vec2 quad[4]; uniform TexCoordPrecision vec3 edge[8]; - uniform TexCoordPrecision vec4 texTrans; + uniform TexCoordPrecision vec4 texTransform; varying TexCoordPrecision vec2 v_texCoord; varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances. - }); -} - -std::string VertexShaderQuadTexTransformAA::GetShaderBody() { - return SHADER0([]() { void main() { vec2 pos = quad[int(a_index)]; // NOLINT gl_Position = matrix * vec4(pos, a_position.z, a_position.w); @@ -578,51 +391,12 @@ edge_dist[1] = vec4(dot(edge[4], screen_pos), dot(edge[5], screen_pos), dot(edge[6], screen_pos), dot(edge[7], screen_pos)) * gl_Position.w; - v_texCoord = (pos.xy + vec2(0.5)) * texTrans.zw + texTrans.xy; + v_texCoord = (pos.xy + vec2(0.5)) * texTransform.zw + texTransform.xy; } }); } -void VertexShaderQuadTexTransformAA::FillLocations( - ShaderLocations* locations) const { - locations->quad = quad_location(); - locations->edge = edge_location(); - locations->viewport = viewport_location(); - locations->matrix = matrix_location(); - locations->tex_transform = tex_transform_location(); -} - - -VertexShaderTile::VertexShaderTile() - : matrix_location_(-1), - quad_location_(-1), - vertex_tex_transform_location_(-1) { -} - -void VertexShaderTile::Init(GLES2Interface* context, - unsigned program, - int* base_uniform_index) { - static const char* uniforms[] = { - "matrix", "quad", "vertexTexTransform", - }; - int locations[arraysize(uniforms)]; - - GetProgramUniformLocations(context, - program, - arraysize(uniforms), - uniforms, - locations, - base_uniform_index); - matrix_location_ = locations[0]; - quad_location_ = locations[1]; - vertex_tex_transform_location_ = locations[2]; -} - -std::string VertexShaderTile::GetShaderString() const { - return VERTEX_SHADER(GetShaderHead(), GetShaderBody()); -} - -std::string VertexShaderTile::GetShaderHead() { +std::string VertexShaderTile::GetShaderSource() const { return SHADER0([]() { attribute TexCoordPrecision vec4 a_position; attribute TexCoordPrecision vec2 a_texCoord; @@ -631,11 +405,6 @@ uniform TexCoordPrecision vec2 quad[4]; uniform TexCoordPrecision vec4 vertexTexTransform; varying TexCoordPrecision vec2 v_texCoord; - }); -} - -std::string VertexShaderTile::GetShaderBody() { - return SHADER0([]() { void main() { vec2 pos = quad[int(a_index)]; // NOLINT gl_Position = matrix * vec4(pos, a_position.z, a_position.w); @@ -644,40 +413,7 @@ }); } -VertexShaderTileAA::VertexShaderTileAA() - : matrix_location_(-1), - viewport_location_(-1), - quad_location_(-1), - edge_location_(-1), - vertex_tex_transform_location_(-1) { -} - -void VertexShaderTileAA::Init(GLES2Interface* context, - unsigned program, - int* base_uniform_index) { - static const char* uniforms[] = { - "matrix", "viewport", "quad", "edge", "vertexTexTransform", - }; - int locations[arraysize(uniforms)]; - - GetProgramUniformLocations(context, - program, - arraysize(uniforms), - uniforms, - locations, - base_uniform_index); - matrix_location_ = locations[0]; - viewport_location_ = locations[1]; - quad_location_ = locations[2]; - edge_location_ = locations[3]; - vertex_tex_transform_location_ = locations[4]; -} - -std::string VertexShaderTileAA::GetShaderString() const { - return VERTEX_SHADER(GetShaderHead(), GetShaderBody()); -} - -std::string VertexShaderTileAA::GetShaderHead() { +std::string VertexShaderTileAA::GetShaderSource() const { return SHADER0([]() { attribute TexCoordPrecision vec4 a_position; attribute float a_index; @@ -688,11 +424,6 @@ uniform TexCoordPrecision vec4 vertexTexTransform; varying TexCoordPrecision vec2 v_texCoord; varying TexCoordPrecision vec4 edge_dist[2]; // 8 edge distances. - }); -} - -std::string VertexShaderTileAA::GetShaderBody() { - return SHADER0([]() { void main() { vec2 pos = quad[int(a_index)]; // NOLINT gl_Position = matrix * vec4(pos, a_position.z, a_position.w); @@ -709,44 +440,13 @@ }); } -VertexShaderVideoTransform::VertexShaderVideoTransform() - : matrix_location_(-1), tex_matrix_location_(-1) { -} - -void VertexShaderVideoTransform::Init(GLES2Interface* context, - unsigned program, - int* base_uniform_index) { - static const char* uniforms[] = { - "matrix", "texMatrix", - }; - int locations[arraysize(uniforms)]; - - GetProgramUniformLocations(context, - program, - arraysize(uniforms), - uniforms, - locations, - base_uniform_index); - matrix_location_ = locations[0]; - tex_matrix_location_ = locations[1]; -} - -std::string VertexShaderVideoTransform::GetShaderString() const { - return VERTEX_SHADER(GetShaderHead(), GetShaderBody()); -} - -std::string VertexShaderVideoTransform::GetShaderHead() { +std::string VertexShaderVideoTransform::GetShaderSource() const { return SHADER0([]() { attribute vec4 a_position; attribute TexCoordPrecision vec2 a_texCoord; uniform mat4 matrix; uniform TexCoordPrecision mat4 texMatrix; varying TexCoordPrecision vec2 v_texCoord; - }); -} - -std::string VertexShaderVideoTransform::GetShaderBody() { - return SHADER0([]() { void main() { gl_Position = matrix * a_position; v_texCoord = (texMatrix * vec4(a_texCoord.xy, 0.0, 1.0)).xy; @@ -1319,20 +1019,7 @@ return header + source; } -FragmentShaderYUVVideo::FragmentShaderYUVVideo() - : y_texture_location_(-1), - u_texture_location_(-1), - v_texture_location_(-1), - uv_texture_location_(-1), - a_texture_location_(-1), - lut_texture_location_(-1), - alpha_location_(-1), - yuv_matrix_location_(-1), - yuv_adj_location_(-1), - ya_clamp_rect_location_(-1), - uv_clamp_rect_location_(-1), - resource_multiplier_location_(-1), - resource_offset_location_(-1) {} +FragmentShaderYUVVideo::FragmentShaderYUVVideo() {} void FragmentShaderYUVVideo::SetFeatures(bool use_alpha_texture, bool use_nv12,
diff --git a/cc/output/shader.h b/cc/output/shader.h index c0cb758..6afd22b 100644 --- a/cc/output/shader.h +++ b/cc/output/shader.h
@@ -113,257 +113,163 @@ int highp_threshold_min, const gfx::Size& max_size); -class VertexShaderPosTex { +class VertexShaderBase { public: - VertexShaderPosTex(); - + VertexShaderBase(); void Init(gpu::gles2::GLES2Interface* context, unsigned program, int* base_uniform_index); std::string GetShaderString() const; - static std::string GetShaderHead(); - static std::string GetShaderBody(); + void FillLocations(ShaderLocations* locations) const; - int matrix_location() const { return matrix_location_; } + int tex_transform_location() const { return tex_transform_location_; } - private: - int matrix_location_; + int vertex_tex_transform_location() const { + return vertex_tex_transform_location_; + } - DISALLOW_COPY_AND_ASSIGN(VertexShaderPosTex); -}; + int tex_matrix_location() const { return tex_matrix_location_; } -class VertexShaderPosTexYUVStretchOffset { - public: - VertexShaderPosTexYUVStretchOffset(); - - void Init(gpu::gles2::GLES2Interface* context, - unsigned program, - int* base_uniform_index); - std::string GetShaderString() const; - static std::string GetShaderHead(); - static std::string GetShaderBody(); - - int matrix_location() const { return matrix_location_; } int ya_tex_scale_location() const { return ya_tex_scale_location_; } int ya_tex_offset_location() const { return ya_tex_offset_location_; } int uv_tex_scale_location() const { return uv_tex_scale_location_; } int uv_tex_offset_location() const { return uv_tex_offset_location_; } - private: - int matrix_location_; - int ya_tex_scale_location_; - int ya_tex_offset_location_; - int uv_tex_scale_location_; - int uv_tex_offset_location_; - - DISALLOW_COPY_AND_ASSIGN(VertexShaderPosTexYUVStretchOffset); -}; - -class VertexShaderPos { - public: - VertexShaderPos(); - - void Init(gpu::gles2::GLES2Interface* context, - unsigned program, - int* base_uniform_index); - std::string GetShaderString() const; - static std::string GetShaderHead(); - static std::string GetShaderBody(); - int matrix_location() const { return matrix_location_; } - private: - int matrix_location_; - - DISALLOW_COPY_AND_ASSIGN(VertexShaderPos); -}; - -class VertexShaderPosTexIdentity { - public: - void Init(gpu::gles2::GLES2Interface* context, - unsigned program, - int* base_uniform_index) {} - std::string GetShaderString() const; - static std::string GetShaderHead(); - static std::string GetShaderBody(); -}; - -class VertexShaderPosTexTransform { - public: - VertexShaderPosTexTransform(); - - void Init(gpu::gles2::GLES2Interface* context, - unsigned program, - int* base_uniform_index); - std::string GetShaderString() const; - static std::string GetShaderHead(); - static std::string GetShaderBody(); - void FillLocations(ShaderLocations* locations) const; - - int matrix_location() const { return matrix_location_; } - int tex_transform_location() const { return tex_transform_location_; } int vertex_opacity_location() const { return vertex_opacity_location_; } - private: - int matrix_location_; - int tex_transform_location_; - int vertex_opacity_location_; - - DISALLOW_COPY_AND_ASSIGN(VertexShaderPosTexTransform); -}; - -class VertexShaderQuad { - public: - VertexShaderQuad(); - - void Init(gpu::gles2::GLES2Interface* context, - unsigned program, - int* base_uniform_index); - std::string GetShaderString() const; - static std::string GetShaderHead(); - static std::string GetShaderBody(); - - int matrix_location() const { return matrix_location_; } - int viewport_location() const { return -1; } - int quad_location() const { return quad_location_; } - int edge_location() const { return -1; } - - private: - int matrix_location_; - int quad_location_; - - DISALLOW_COPY_AND_ASSIGN(VertexShaderQuad); -}; - -class VertexShaderQuadAA { - public: - VertexShaderQuadAA(); - - void Init(gpu::gles2::GLES2Interface* context, - unsigned program, - int* base_uniform_index); - std::string GetShaderString() const; - static std::string GetShaderHead(); - static std::string GetShaderBody(); - - int matrix_location() const { return matrix_location_; } int viewport_location() const { return viewport_location_; } - int quad_location() const { return quad_location_; } int edge_location() const { return edge_location_; } - private: - int matrix_location_; - int viewport_location_; - int quad_location_; - int edge_location_; + int quad_location() const { return quad_location_; } - DISALLOW_COPY_AND_ASSIGN(VertexShaderQuadAA); + protected: + virtual std::string GetShaderSource() const = 0; + + bool has_tex_transform_ = false; + int tex_transform_location_ = -1; + + bool has_vertex_tex_transform_ = false; + int vertex_tex_transform_location_ = -1; + + bool has_tex_matrix_ = false; + int tex_matrix_location_ = -1; + + bool has_ya_uv_tex_scale_offset_ = false; + int ya_tex_scale_location_ = -1; + int ya_tex_offset_location_ = -1; + int uv_tex_scale_location_ = -1; + int uv_tex_offset_location_ = -1; + + bool has_matrix_ = false; + int matrix_location_ = -1; + + bool has_vertex_opacity_ = false; + int vertex_opacity_location_ = -1; + + bool has_aa_ = false; + int viewport_location_ = -1; + int edge_location_ = -1; + + bool has_quad_ = false; + int quad_location_ = -1; }; - -class VertexShaderQuadTexTransformAA { +class VertexShaderPosTex : public VertexShaderBase { public: - VertexShaderQuadTexTransformAA(); - - void Init(gpu::gles2::GLES2Interface* context, - unsigned program, - int* base_uniform_index); - std::string GetShaderString() const; - static std::string GetShaderHead(); - static std::string GetShaderBody(); - void FillLocations(ShaderLocations* locations) const; - - int matrix_location() const { return matrix_location_; } - int viewport_location() const { return viewport_location_; } - int quad_location() const { return quad_location_; } - int edge_location() const { return edge_location_; } - int tex_transform_location() const { return tex_transform_location_; } - - private: - int matrix_location_; - int viewport_location_; - int quad_location_; - int edge_location_; - int tex_transform_location_; - - DISALLOW_COPY_AND_ASSIGN(VertexShaderQuadTexTransformAA); + VertexShaderPosTex() { has_matrix_ = true; } + std::string GetShaderSource() const override; }; -class VertexShaderTile { +class VertexShaderPosTexYUVStretchOffset : public VertexShaderBase { public: - VertexShaderTile(); - - void Init(gpu::gles2::GLES2Interface* context, - unsigned program, - int* base_uniform_index); - std::string GetShaderString() const; - static std::string GetShaderHead(); - static std::string GetShaderBody(); - - int matrix_location() const { return matrix_location_; } - int viewport_location() const { return -1; } - int quad_location() const { return quad_location_; } - int edge_location() const { return -1; } - int vertex_tex_transform_location() const { - return vertex_tex_transform_location_; + VertexShaderPosTexYUVStretchOffset() { + has_matrix_ = true; + has_ya_uv_tex_scale_offset_ = true; } - - private: - int matrix_location_; - int quad_location_; - int vertex_tex_transform_location_; - - DISALLOW_COPY_AND_ASSIGN(VertexShaderTile); + std::string GetShaderSource() const override; }; -class VertexShaderTileAA { +class VertexShaderPos : public VertexShaderBase { public: - VertexShaderTileAA(); + VertexShaderPos() { has_matrix_ = true; } + std::string GetShaderSource() const override; +}; - void Init(gpu::gles2::GLES2Interface* context, - unsigned program, - int* base_uniform_index); - std::string GetShaderString() const; - static std::string GetShaderHead(); - static std::string GetShaderBody(); +class VertexShaderPosTexIdentity : public VertexShaderBase { + public: + std::string GetShaderSource() const override; +}; - int matrix_location() const { return matrix_location_; } - int viewport_location() const { return viewport_location_; } - int quad_location() const { return quad_location_; } - int edge_location() const { return edge_location_; } - int vertex_tex_transform_location() const { - return vertex_tex_transform_location_; +class VertexShaderPosTexTransform : public VertexShaderBase { + public: + VertexShaderPosTexTransform() { + has_matrix_ = true; + has_tex_transform_ = true; + has_vertex_opacity_ = true; } - - private: - int matrix_location_; - int viewport_location_; - int quad_location_; - int edge_location_; - int vertex_tex_transform_location_; - - DISALLOW_COPY_AND_ASSIGN(VertexShaderTileAA); + std::string GetShaderSource() const override; }; -class VertexShaderVideoTransform { +class VertexShaderQuad : public VertexShaderBase { public: - VertexShaderVideoTransform(); + VertexShaderQuad() { + has_matrix_ = true; + has_quad_ = true; + } + std::string GetShaderSource() const override; +}; - void Init(gpu::gles2::GLES2Interface* context, - unsigned program, - int* base_uniform_index); - std::string GetShaderString() const; - static std::string GetShaderHead(); - static std::string GetShaderBody(); +class VertexShaderQuadAA : public VertexShaderBase { + public: + VertexShaderQuadAA() { + has_matrix_ = true; + has_aa_ = true; + has_quad_ = true; + } + std::string GetShaderSource() const override; +}; - int matrix_location() const { return matrix_location_; } - int tex_matrix_location() const { return tex_matrix_location_; } +class VertexShaderQuadTexTransformAA : public VertexShaderBase { + public: + VertexShaderQuadTexTransformAA() { + has_matrix_ = true; + has_aa_ = true; + has_quad_ = true; + has_tex_transform_ = true; + } + std::string GetShaderSource() const override; +}; - private: - int matrix_location_; - int tex_matrix_location_; +class VertexShaderTile : public VertexShaderBase { + public: + VertexShaderTile() { + has_matrix_ = true; + has_quad_ = true; + has_vertex_tex_transform_ = true; + } + std::string GetShaderSource() const override; +}; - DISALLOW_COPY_AND_ASSIGN(VertexShaderVideoTransform); +class VertexShaderTileAA : public VertexShaderBase { + public: + VertexShaderTileAA() { + has_matrix_ = true; + has_quad_ = true; + has_vertex_tex_transform_ = true; + has_aa_ = true; + } + std::string GetShaderSource() const override; +}; + +class VertexShaderVideoTransform : public VertexShaderBase { + public: + VertexShaderVideoTransform() { + has_matrix_ = true; + has_tex_matrix_ = true; + } + std::string GetShaderSource() const override; }; class FragmentShaderBase {
diff --git a/chrome/android/java/res/layout/multiline_spinner_item.xml b/chrome/android/java/res/layout/multiline_spinner_item.xml index e83c6d8..1fecc30 100644 --- a/chrome/android/java/res/layout/multiline_spinner_item.xml +++ b/chrome/android/java/res/layout/multiline_spinner_item.xml
@@ -5,8 +5,10 @@ --> <TextView xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/spinner_item" style="?android:attr/spinnerItemStyle" android:singleLine="false" android:layout_width="match_parent" android:layout_height="wrap_content" + android:paddingEnd="24dp" android:textAlignment="inherit" />
diff --git a/chrome/android/java/res/layout/payment_request_dropdown_item.xml b/chrome/android/java/res/layout/payment_request_dropdown_item.xml new file mode 100644 index 0000000..67be520 --- /dev/null +++ b/chrome/android/java/res/layout/payment_request_dropdown_item.xml
@@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2016 The Chromium Authors. All rights reserved. + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. +--> + +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <TextView + android:id="@+id/spinner_item" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingStart="24dp" + android:paddingEnd="24dp" + android:minHeight="48dp" + style="?android:attr/spinnerDropDownItemStyle" /> + +</FrameLayout> \ No newline at end of file
diff --git a/chrome/android/java/res/layout/payment_request_editor_dropdown.xml b/chrome/android/java/res/layout/payment_request_editor_dropdown.xml index 0464f5d..c5d86f8 100644 --- a/chrome/android/java/res/layout/payment_request_editor_dropdown.xml +++ b/chrome/android/java/res/layout/payment_request_editor_dropdown.xml
@@ -21,9 +21,11 @@ <android.support.v7.widget.AppCompatSpinner android:id="@+id/spinner" - android:layout_width="fill_parent" + android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="@dimen/pref_autofill_field_top_margin" /> + android:layout_marginTop="@dimen/pref_autofill_field_top_margin" + android:padding="0dp" + android:dropDownWidth="match_parent" /> <View style="@style/PreferenceSpinnerUnderlineView" />
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index 4701a6b..22bf1655 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -114,6 +114,7 @@ import org.chromium.content.browser.crypto.CipherFactory; import org.chromium.content.common.ContentSwitches; import org.chromium.content_public.browser.LoadUrlParams; +import org.chromium.content_public.common.Referrer; import org.chromium.ui.base.DeviceFormFactor; import org.chromium.ui.base.PageTransition; import org.chromium.ui.base.WindowAndroid; @@ -821,6 +822,10 @@ loadUrlParams.setHasUserGesture(hasUserGesture); loadUrlParams.setTransitionType(IntentHandler.getTransitionTypeFromIntent( getApplicationContext(), intent, transitionType)); + if (referer != null) { + loadUrlParams.setReferrer( + new Referrer(referer, Referrer.REFERRER_POLICY_DEFAULT)); + } currentTab.loadUrl(loadUrlParams); RecordUserAction.record("MobileTabClobbered"); } else {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/BrowsingHistoryBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/history/BrowsingHistoryBridge.java index c9f0e1d..e2cd124 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/history/BrowsingHistoryBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/history/BrowsingHistoryBridge.java
@@ -11,50 +11,22 @@ import java.util.List; /** The JNI bridge for Android to fetch and manipulate browsing history. */ -public class BrowsingHistoryBridge { - - /** - * Observer to be notified of browsing history events. - */ - public interface BrowsingHistoryObserver { - /** - * Called after {@link BrowsingHistoryBridge#queryHistory(String, long)} is complete. - * @param items The items that matched the #queryHistory() parameters. - * @param hasMorePotentialMatches Whether there are more items that match the query text. - * This will be false once the entire local history database - * has been searched. - */ - public void onQueryHistoryComplete(List<HistoryItem> items, - boolean hasMorePotentialMatches); - - /** - * Called when history has been deleted through something other than a call to - * BrowsingHistoryBridge#removeItems(). For example, if two instances of the history page - * are open and the user removes items in one instance, the other instance will be notified - * via this method. - */ - public void onHistoryDeleted(); - - /** - * Called after querying history to indicate whether other forms of browsing history were - * found. - * @param hasOtherForms Whether other forms of browsing history were found. - * @param hasSyncedResults Whether synced results were found. - */ - public void hasOtherFormsOfBrowsingData(boolean hasOtherForms, boolean hasSyncedResults); - } - - private final BrowsingHistoryObserver mObserver; - +public class BrowsingHistoryBridge implements HistoryProvider { + private BrowsingHistoryObserver mObserver; private long mNativeHistoryBridge; private boolean mRemovingItems; private boolean mHasPendingRemoveRequest; - public BrowsingHistoryBridge(BrowsingHistoryObserver observer) { + public BrowsingHistoryBridge() { mNativeHistoryBridge = nativeInit(Profile.getLastUsedProfile()); + } + + @Override + public void setObserver(BrowsingHistoryObserver observer) { mObserver = observer; } + @Override public void destroy() { if (mNativeHistoryBridge != 0) { nativeDestroy(mNativeHistoryBridge); @@ -62,29 +34,17 @@ } } - /** - * Query browsing history. Only one query may be in-flight at any time. See - * BrowsingHistoryService::QueryHistory. - * @param query The query search text. May be empty. - * @param endQueryTime The end of the time range to search. A value of 0 indicates that there - * is no limit on the end time. See the native QueryOptions. - */ + @Override public void queryHistory(String query, long endQueryTime) { nativeQueryHistory(mNativeHistoryBridge, new ArrayList<HistoryItem>(), query, endQueryTime); } - /** - * Adds the HistoryItem to the list of items being removed. The removal will not be committed - * until {@link #removeItems()} is called. - * @param item The item to mark for removal. - */ + @Override public void markItemForRemoval(HistoryItem item) { nativeMarkItemForRemoval(mNativeHistoryBridge, item.getUrl(), item.getTimestamps()); } - /** - * Removes all items that have been marked for removal through #markItemForRemoval(). - */ + @Override public void removeItems() { // Only one remove request may be in-flight at any given time. If items are currently being // removed, queue the new request and return early. @@ -105,7 +65,7 @@ @CalledByNative public void onQueryHistoryComplete(List<HistoryItem> items, boolean hasMorePotentialMatches) { - mObserver.onQueryHistoryComplete(items, hasMorePotentialMatches); + if (mObserver != null) mObserver.onQueryHistoryComplete(items, hasMorePotentialMatches); } @CalledByNative @@ -123,12 +83,14 @@ @CalledByNative public void onHistoryDeleted() { - mObserver.onHistoryDeleted(); + if (mObserver != null) mObserver.onHistoryDeleted(); } @CalledByNative public void hasOtherFormsOfBrowsingData(boolean hasOtherForms, boolean hasSyncedResults) { - mObserver.hasOtherFormsOfBrowsingData(hasOtherForms, hasSyncedResults); + if (mObserver != null) { + mObserver.hasOtherFormsOfBrowsingData(hasOtherForms, hasSyncedResults); + } } private native long nativeInit(Profile profile);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryActivity.java index e2f71f3..5d181ac 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryActivity.java
@@ -6,6 +6,7 @@ import android.os.Bundle; +import org.chromium.base.VisibleForTesting; import org.chromium.chrome.browser.SynchronousInitializationActivity; /** @@ -28,4 +29,9 @@ mHistoryManager = null; super.onDestroy(); } + + @VisibleForTesting + HistoryManager getHistoryManagerForTests() { + return mHistoryManager; + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryAdapter.java index 657a02f..10862e3c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryAdapter.java
@@ -15,7 +15,7 @@ import org.chromium.base.ContextUtils; import org.chromium.chrome.R; -import org.chromium.chrome.browser.history.BrowsingHistoryBridge.BrowsingHistoryObserver; +import org.chromium.chrome.browser.history.HistoryProvider.BrowsingHistoryObserver; import org.chromium.chrome.browser.widget.DateDividedAdapter; import org.chromium.chrome.browser.widget.selection.SelectableItemViewHolder; import org.chromium.chrome.browser.widget.selection.SelectionDelegate; @@ -37,7 +37,7 @@ private static final String GOOGLE_HISTORY_LINK = "history.google.com"; private final SelectionDelegate<HistoryItem> mSelectionDelegate; - private final BrowsingHistoryBridge mBridge; + private final HistoryProvider mHistoryProvider; private final HistoryManager mManager; private TextView mSignedInNotSyncedTextView; @@ -56,10 +56,12 @@ private long mNextQueryEndTime; private String mQueryText = EMPTY_QUERY; - public HistoryAdapter(SelectionDelegate<HistoryItem> delegate, HistoryManager manager) { + public HistoryAdapter(SelectionDelegate<HistoryItem> delegate, HistoryManager manager, + HistoryProvider provider) { setHasStableIds(true); mSelectionDelegate = delegate; - mBridge = new BrowsingHistoryBridge(this); + mHistoryProvider = provider; + mHistoryProvider.setObserver(this); mManager = manager; } @@ -67,7 +69,7 @@ * Called when the activity/native page is destroyed. */ public void onDestroyed() { - mBridge.destroy(); + mHistoryProvider.destroy(); mIsDestroyed = true; } @@ -79,7 +81,7 @@ mIsLoadingItems = true; mNextQueryEndTime = 0; mClearOnNextQueryComplete = true; - mBridge.queryHistory(mQueryText, mNextQueryEndTime); + mHistoryProvider.queryHistory(mQueryText, mNextQueryEndTime); } /** @@ -92,7 +94,7 @@ mIsLoadingItems = true; addFooter(); notifyDataSetChanged(); - mBridge.queryHistory(mQueryText, mNextQueryEndTime); + mHistoryProvider.queryHistory(mQueryText, mNextQueryEndTime); } /** @@ -111,7 +113,7 @@ mNextQueryEndTime = 0; mIsSearching = true; mClearOnNextQueryComplete = true; - mBridge.queryHistory(mQueryText, mNextQueryEndTime); + mHistoryProvider.queryHistory(mQueryText, mNextQueryEndTime); } /** @@ -132,14 +134,19 @@ */ public void markItemForRemoval(HistoryItem item) { removeItem(item); - mBridge.markItemForRemoval(item); + mHistoryProvider.markItemForRemoval(item); + + // If there is only one item left, remove the header so the empty view will be displayed. + if (getItemCount() == 1) { + removeHeader(); + } } /** * Removes all items that have been marked for removal through #markItemForRemoval(). */ public void removeItems() { - mBridge.removeItems(); + mHistoryProvider.removeItems(); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryItem.java b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryItem.java index 55263e1e..a89dd9c1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryItem.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryItem.java
@@ -85,13 +85,19 @@ * Navigates a tab to this item's URL. */ public void open() { - if (mManager != null) mManager.openUrl(mUrl, null, false); + if (mManager != null) { + mManager.recordUserActionWithOptionalSearch("OpenItem"); + mManager.openUrl(mUrl, null, false); + } } /** * Removes this item. */ public void remove() { - if (mManager != null) mManager.removeItem(this); + if (mManager != null) { + mManager.recordUserActionWithOptionalSearch("RemoveItem"); + mManager.removeItem(this); + } } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java index 51ae37a5..8964db77 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java
@@ -11,6 +11,7 @@ import android.content.Intent; import android.net.Uri; import android.provider.Browser; +import android.support.annotation.VisibleForTesting; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView.OnScrollListener; @@ -18,8 +19,11 @@ import android.view.LayoutInflater; import android.view.MenuItem; import android.view.ViewGroup; +import android.widget.TextView; import org.chromium.base.ContextUtils; +import org.chromium.base.metrics.RecordHistogram; +import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.R; import org.chromium.chrome.browser.IntentHandler; import org.chromium.chrome.browser.document.ChromeLauncherActivity; @@ -41,14 +45,20 @@ public class HistoryManager implements OnMenuItemClickListener { private static final int FAVICON_MAX_CACHE_SIZE_BYTES = 10 * 1024 * 1024; // 10MB private static final int MEGABYTES_TO_BYTES = 1024 * 1024; + private static final String METRICS_PREFIX = "Android.HistoryPage."; + + private static HistoryProvider sProviderForTests; private final Activity mActivity; private final SelectableListLayout<HistoryItem> mSelectableListLayout; private final HistoryAdapter mHistoryAdapter; private final SelectionDelegate<HistoryItem> mSelectionDelegate; private final HistoryManagerToolbar mToolbar; + private final TextView mEmptyView; private LargeIconBridge mLargeIconBridge; + private boolean mIsSearching; + /** * Creates a new HistoryManager. * @param activity The Activity associated with the HistoryManager. @@ -57,7 +67,8 @@ mActivity = activity; mSelectionDelegate = new SelectionDelegate<>(); - mHistoryAdapter = new HistoryAdapter(mSelectionDelegate, this); + mHistoryAdapter = new HistoryAdapter(mSelectionDelegate, this, + sProviderForTests != null ? sProviderForTests : new BrowsingHistoryBridge()); mSelectableListLayout = (SelectableListLayout<HistoryItem>) LayoutInflater.from(activity).inflate( @@ -67,7 +78,7 @@ R.layout.history_toolbar, mSelectionDelegate, R.string.menu_history, null, R.id.normal_menu_group, R.id.selection_mode_menu_group, this); mToolbar.setManager(this); - mSelectableListLayout.initializeEmptyView( + mEmptyView = mSelectableListLayout.initializeEmptyView( TintedDrawable.constructTintedDrawable(mActivity.getResources(), R.drawable.history_large), R.string.history_manager_empty); @@ -85,6 +96,7 @@ if (layoutManager.findLastVisibleItemPosition() > (mHistoryAdapter.getItemCount() - 25)) { mHistoryAdapter.loadMoreItems(); + recordUserActionWithOptionalSearch("LoadMoreOnScroll"); } }}); @@ -94,6 +106,8 @@ int maxSize = Math.min((activityManager.getMemoryClass() / 4) * MEGABYTES_TO_BYTES, FAVICON_MAX_CACHE_SIZE_BYTES); mLargeIconBridge.createCache(maxSize); + + recordUserAction("Show"); } @Override @@ -110,6 +124,9 @@ mSelectionDelegate.clearSelection(); return true; } else if (item.getItemId() == R.id.selection_mode_delete_menu_id) { + recordSelectionCountHistorgram("Remove"); + recordUserActionWithOptionalSearch("RemoveSelected"); + for (HistoryItem historyItem : mSelectionDelegate.getSelectedItems()) { mHistoryAdapter.markItemForRemoval(historyItem); } @@ -119,6 +136,9 @@ } else if (item.getItemId() == R.id.search_menu_id) { mToolbar.showSearchView(); mSelectableListLayout.setEmptyViewText(R.string.history_manager_no_results); + recordUserAction("Search"); + mIsSearching = true; + return true; } return false; } @@ -194,6 +214,7 @@ * Opens the clear browsing data preference. */ public void openClearBrowsingDataPreference() { + recordUserAction("ClearBrowsingData"); Intent intent = PreferencesLauncher.createIntentForSettingsPage(mActivity, ClearBrowsingDataPreferences.class.getName()); IntentUtils.safeStartActivity(mActivity, intent); @@ -213,6 +234,7 @@ public void onEndSearch() { mHistoryAdapter.onEndSearch(); mSelectableListLayout.setEmptyViewText(R.string.history_manager_empty); + mIsSearching = false; } /** @@ -223,8 +245,64 @@ } private void openItemsInNewTabs(List<HistoryItem> items, boolean isIncognito) { + recordSelectionCountHistorgram("Open"); + recordUserActionWithOptionalSearch("OpenSelected" + (isIncognito ? "Incognito" : "")); + for (HistoryItem item : items) { openUrl(item.getUrl(), isIncognito, true); } } + + /** + * Sets a {@link HistoryProvider} that is used in place of a real one. + */ + @VisibleForTesting + public static void setProviderForTests(HistoryProvider provider) { + sProviderForTests = provider; + } + + @VisibleForTesting + SelectionDelegate<HistoryItem> getSelectionDelegateForTests() { + return mSelectionDelegate; + } + + @VisibleForTesting + HistoryManagerToolbar getToolbarForTests() { + return mToolbar; + } + + @VisibleForTesting + TextView getEmptyViewForTests() { + return mEmptyView; + } + + @VisibleForTesting + HistoryAdapter getAdapterForTests() { + return mHistoryAdapter; + } + + /** + * @param action The user action string to record. + */ + static void recordUserAction(String action) { + RecordUserAction.record(METRICS_PREFIX + action); + } + + /** + * Records the user action with "Search" prepended if the user is currently searching. + * @param action The user action string to record. + */ + void recordUserActionWithOptionalSearch(String action) { + recordUserAction((mIsSearching ? "Search." : "") + action); + } + + /** + * Records the number of selected items when a multi-select action is performed. + * @param action The multi-select action that was performed. + */ + private void recordSelectionCountHistorgram(String action) { + List<HistoryItem> selectedItems = mSelectionDelegate.getSelectedItems(); + RecordHistogram.recordCount100Histogram( + METRICS_PREFIX + action + "Selected", selectedItems.size()); + } } \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManagerToolbar.java b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManagerToolbar.java index b04194c0..03df352 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManagerToolbar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManagerToolbar.java
@@ -117,7 +117,13 @@ @Override public void onSelectionStateChange(List<HistoryItem> selectedItems) { + boolean wasSelectionEnabled = mIsSelectionEnabled; super.onSelectionStateChange(selectedItems); + + if (!wasSelectionEnabled && mIsSelectionEnabled) { + mManager.recordUserActionWithOptionalSearch("SelectionEstablished"); + } + if (!mIsSearching) return; if (mIsSelectionEnabled) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryProvider.java new file mode 100644 index 0000000..b90a9d6e --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryProvider.java
@@ -0,0 +1,74 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.history; + +import java.util.List; + +/** + * Provides methods needed for querying and managing browsing history. + */ +public interface HistoryProvider { + /** + * Observer to be notified of browsing history events. + */ + public interface BrowsingHistoryObserver { + /** + * Called after {@link BrowsingHistoryBridge#queryHistory(String, long)} is complete. + * @param items The items that matched the #queryHistory() parameters. + * @param hasMorePotentialMatches Whether there are more items that match the query text. + * This will be false once the entire local history database + * has been searched. + */ + void onQueryHistoryComplete(List<HistoryItem> items, + boolean hasMorePotentialMatches); + + /** + * Called when history has been deleted through something other than a call to + * BrowsingHistoryBridge#removeItems(). For example, if two instances of the history page + * are open and the user removes items in one instance, the other instance will be notified + * via this method. + */ + void onHistoryDeleted(); + + /** + * Called after querying history to indicate whether other forms of browsing history were + * found. + * @param hasOtherForms Whether other forms of browsing history were found. + * @param hasSyncedResults Whether synced results were found. + */ + void hasOtherFormsOfBrowsingData(boolean hasOtherForms, boolean hasSyncedResults); + } + + /** + * Sets the {@link BrowsingHistoryObserver} to be notified of browsing history events. + */ + void setObserver(BrowsingHistoryObserver observer); + + /** + * Query browsing history. Only one query may be in-flight at any time. See + * BrowsingHistoryService::QueryHistory. + * @param query The query search text. May be empty. + * @param endQueryTime The end of the time range to search. A value of 0 indicates that there + * is no limit on the end time. See the native QueryOptions. + */ + void queryHistory(String query, long endQueryTime); + + /** + * Adds the HistoryItem to the list of items being removed. The removal will not be committed + * until {@link #removeItems()} is called. + * @param item The item to mark for removal. + */ + void markItemForRemoval(HistoryItem item); + + /** + * Removes all items that have been marked for removal through #markItemForRemoval(). + */ + void removeItems(); + + /** + * Destroys the HistoryProvider. + */ + void destroy(); +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/UrlBar.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/UrlBar.java index d97f1c4..0479f00 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/UrlBar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/UrlBar.java
@@ -32,6 +32,7 @@ import android.view.inputmethod.InputConnectionWrapper; import org.chromium.base.ApiCompatibilityUtils; +import org.chromium.base.Log; import org.chromium.base.SysUtils; import org.chromium.base.VisibleForTesting; import org.chromium.chrome.R; @@ -52,7 +53,9 @@ * The URL text entry view for the Omnibox. */ public class UrlBar extends VerticallyFixedEditText { - private static final String TAG = "UrlBar"; + private static final String TAG = "cr_UrlBar"; + + private static final boolean DEBUG = false; // TextView becomes very slow on long strings, so we limit maximum length // of what is displayed to the user, see limitDisplayableLength(). @@ -349,6 +352,7 @@ @Override public void onBeginBatchEdit() { + if (DEBUG) Log.i(TAG, "onBeginBatchEdit"); mBeforeBatchEditAutocompleteIndex = getText().getSpanStart(mAutocompleteSpan); mBeforeBatchEditFullText = getText().toString(); @@ -359,6 +363,7 @@ @Override public void onEndBatchEdit() { + if (DEBUG) Log.i(TAG, "onEndBatchEdit"); super.onEndBatchEdit(); mInBatchEditMode = false; limitDisplayableLength(); @@ -391,6 +396,7 @@ @Override protected void onSelectionChanged(int selStart, int selEnd) { + if (DEBUG) Log.i(TAG, "onSelectionChanged -- selStart: %d, selEnd: %d", selStart, selEnd); if (!mInBatchEditMode) { int beforeTextLength = getText().length(); if (validateSelection(selStart, selEnd)) { @@ -414,7 +420,15 @@ private boolean validateSelection(int selStart, int selEnd) { int spanStart = getText().getSpanStart(mAutocompleteSpan); int spanEnd = getText().getSpanEnd(mAutocompleteSpan); + + if (DEBUG) { + Log.i(TAG, "validateSelection -- selStart: %d, selEnd: %d, spanStart: %d, spanEnd: %d", + selStart, selEnd, spanStart, spanEnd); + } + if (spanStart >= 0 && (spanStart != selStart || spanEnd != selEnd)) { + CharSequence previousAutocompleteText = mAutocompleteSpan.mAutocompleteText; + // On selection changes, the autocomplete text has been accepted by the user or needs // to be deleted below. mAutocompleteSpan.clearSpan(); @@ -426,7 +440,10 @@ // character appears, Chrome may decide to append some autocomplete, but the keyboard // will then remove this temporary character only while leaving the autocomplete text // alone. See crbug/273763 for more details. - if (selEnd <= spanStart) getText().delete(spanStart, getText().length()); + if (selEnd <= spanStart && TextUtils.equals(previousAutocompleteText, + getText().subSequence(spanStart, getText().length()))) { + getText().delete(spanStart, getText().length()); + } return true; } return false; @@ -758,6 +775,10 @@ * @param inlineAutocompleteText The suggested autocompletion for the user's text. */ public void setAutocompleteText(CharSequence userText, CharSequence inlineAutocompleteText) { + if (DEBUG) { + Log.i(TAG, "setAutocompleteText -- userText: %s, inlineAutocompleteText: %s", + userText, inlineAutocompleteText); + } boolean emptyAutocomplete = TextUtils.isEmpty(inlineAutocompleteText); if (!emptyAutocomplete) mDisableTextScrollingFromAutocomplete = true; @@ -842,6 +863,11 @@ @Override protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) { + if (DEBUG) { + Log.i(TAG, "onTextChanged -- text: %s, start: %d, lengthBefore: %d, lengthAfter: %d", + text, start, lengthBefore, lengthAfter); + } + super.onTextChanged(text, start, lengthBefore, lengthAfter); if (!mInBatchEditMode) { limitDisplayableLength(); @@ -854,6 +880,8 @@ @Override public void setText(CharSequence text, BufferType type) { + if (DEBUG) Log.i(TAG, "setText -- text: %s", text); + mDisableTextScrollingFromAutocomplete = false; // Avoid setting the same text to the URL bar as it will mess up the scroll/cursor
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/BillingAddressAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/BillingAddressAdapter.java index d765174..084e197 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/BillingAddressAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/BillingAddressAdapter.java
@@ -38,27 +38,32 @@ * .............. */ public class BillingAddressAdapter<T> extends ArrayAdapter<T> { + private final int mTextViewResourceId; /** * Creates an array adapter for which the last element is a hint that is not shown in the * expanded view and where the last shown element has a "+" icon on its left and has a blue * tint. * - * @param context The current context. - * @param resource The resource ID for a layout file containing a layout to use when - * instantiating views. - * @param objects The objects to represent in the ListView, the last of which will have a "+" - * icon on its left and will have a blue tint. - * @param hint The element to be used as a hint when no element is selected. It is not taken - * into account in the count function and thus will not be displayed when in the - * expanded dropdown view. + * @param context The current context. + * @param resource The resource ID for a layout file containing a layout to use when + * instantiating views. + * @param textViewResourceId The id of the TextView within the layout resource to be populated. + * @param objects The objects to represent in the ListView, the last of which will + * have a "+" icon on its left and will have a blue tint. + * @param hint The element to be used as a hint when no element is selected. It is + * not taken into account in the count function and thus will not be + * displayed when in the expanded dropdown view. */ - public BillingAddressAdapter(Context context, int resource, List<T> objects, T hint) { + public BillingAddressAdapter( + Context context, int resource, int textViewResourceId, List<T> objects, T hint) { // Make a copy of objects so the hint is not added to the original list. - super(context, resource, new ArrayList<T>(objects)); + super(context, resource, textViewResourceId, new ArrayList<T>(objects)); // The hint is added as the last element. It will not be shown when the dropdown is // expanded and not be taken into account in the getCount function. add(hint); + + mTextViewResourceId = textViewResourceId; } @Override @@ -70,32 +75,58 @@ @Override public View getDropDownView(int position, View convertView, ViewGroup parent) { - View view; + TextView textView = convertView == null + ? null + : (TextView) convertView.findViewById(mTextViewResourceId); + if (textView != null) { + // Clear the possible changes for the first and last view. + ApiCompatibilityUtils.setPaddingRelative(convertView, + ApiCompatibilityUtils.getPaddingStart(convertView), 0, + ApiCompatibilityUtils.getPaddingEnd(convertView), 0); + textView.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null); + ApiCompatibilityUtils.setTextAppearance( + textView, android.R.style.TextAppearance_Widget_DropDownItem); + } + convertView = super.getDropDownView(position, convertView, parent); - // Add a "+" icon and a blue tint to the last element. - if (position == getCount() - 1) { - view = super.getDropDownView(position, convertView, parent); - TextView tv = (TextView) view; + if (position == 0) { + // Padding at the top of the dropdown. + ApiCompatibilityUtils.setPaddingRelative(convertView, + ApiCompatibilityUtils.getPaddingStart(convertView), + getContext().getResources().getDimensionPixelSize( + R.dimen.payments_section_small_spacing), + ApiCompatibilityUtils.getPaddingEnd(convertView), + convertView.getPaddingBottom()); + } else if (position == getCount() - 1) { + // Add a "+" icon and a blue tint to the last element. Resources resources = getContext().getResources(); + if (textView == null) { + textView = (TextView) convertView.findViewById(mTextViewResourceId); + } // Create the "+" icon, put it left of the text and add appropriate padding. - tv.setCompoundDrawablesWithIntrinsicBounds( + textView.setCompoundDrawablesWithIntrinsicBounds( TintedDrawable.constructTintedDrawable( - resources, R.drawable.plus, R.color.light_active_color), + resources, R.drawable.plus, R.color.light_active_color), null, null, null); - tv.setCompoundDrawablePadding( + textView.setCompoundDrawablePadding( resources.getDimensionPixelSize(R.dimen.payments_section_large_spacing)); // Set the correct appearance, face and style for the text. - ApiCompatibilityUtils.setTextAppearance(tv, R.style.PaymentsUiSectionAddButtonLabel); - tv.setTypeface(Typeface.create( - resources.getString(R.string.roboto_medium_typeface), - R.integer.roboto_medium_textstyle)); - } else { - // Don't use the recycled convertView, as it may have the style of the last element. - view = super.getDropDownView(position, null, parent); + ApiCompatibilityUtils.setTextAppearance( + textView, R.style.PaymentsUiSectionAddButtonLabel); + textView.setTypeface( + Typeface.create(resources.getString(R.string.roboto_medium_typeface), + R.integer.roboto_medium_textstyle)); + + // Padding at the bottom of the dropdown. + ApiCompatibilityUtils.setPaddingRelative(convertView, + ApiCompatibilityUtils.getPaddingStart(convertView), convertView.getPaddingTop(), + ApiCompatibilityUtils.getPaddingEnd(convertView), + getContext().getResources().getDimensionPixelSize( + R.dimen.payments_section_small_spacing)); } - return view; + return convertView; } } \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorDropdownField.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorDropdownField.java index fcbed1f..52a78e5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorDropdownField.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorDropdownField.java
@@ -59,9 +59,15 @@ ArrayAdapter<DropdownKeyValue> adapter; if (mFieldModel.getHint() != null) { // Use the BillingAddressAdapter and pass it a hint to be displayed as default. - adapter = new BillingAddressAdapter<DropdownKeyValue>( - context, R.layout.multiline_spinner_item, dropdownKeyValues, + adapter = new BillingAddressAdapter<DropdownKeyValue>(context, + R.layout.multiline_spinner_item, R.id.spinner_item, dropdownKeyValues, new DropdownKeyValue("", mFieldModel.getHint().toString())); + // Wrap the TextView in the dropdown popup around with a FrameLayout to display the text + // in multiple lines. + // Note that the TextView in the dropdown popup is displayed in a DropDownListView for + // the dropdown style Spinner and the DropDownListView sets to display TextView instance + // in a single line. + adapter.setDropDownViewResource(R.layout.payment_request_dropdown_item); // If no value is selected, select the hint entry which is the last item in the adapter. // Using getCount will not result in an out of bounds index because the hint value is @@ -70,8 +76,8 @@ } else { adapter = new ArrayAdapter<DropdownKeyValue>( context, R.layout.multiline_spinner_item, dropdownKeyValues); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); } - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); mDropdown = (Spinner) mLayout.findViewById(R.id.spinner); mDropdown.setTag(this);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/DateDividedAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/DateDividedAdapter.java index ad4c281..ee707031 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/DateDividedAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/DateDividedAdapter.java
@@ -288,15 +288,20 @@ } } - // Tell each group where they start in the list. + setGroupPositions(); + notifyDataSetChanged(); + } + + /** + * Tells each group where they start in the list. + */ + private void setGroupPositions() { int startIndex = 0; for (ItemGroup group : mGroups) { group.resetPosition(); group.setPosition(startIndex); startIndex += group.size(); } - - notifyDataSetChanged(); } /** @@ -314,6 +319,27 @@ } /** + * Removes the list headrer. + */ + public void removeHeader() { + if (!mHasListHeader) return; + + mGroups.remove(mGroups.first()); + mSize--; + mHasListHeader = false; + + setGroupPositions(); + notifyDataSetChanged(); + } + + /** + * Whether the adapter has a list header. + */ + public boolean hasListHeader() { + return mHasListHeader; + } + + /** * Adds a footer as the last group in this adapter. */ public void addFooter() { @@ -456,6 +482,7 @@ mSize--; } + setGroupPositions(); notifyDataSetChanged(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableItemViewHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableItemViewHolder.java index e80af00..0a202d1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableItemViewHolder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableItemViewHolder.java
@@ -4,19 +4,19 @@ package org.chromium.chrome.browser.widget.selection; -import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.RecyclerView.ViewHolder; import android.view.View; /** * An ViewHolder for a {@link SelectableItemView}. - * @param <E> The type of the item associated with the SelectableItemView. + * @param <E> The type of the item associated with the {@link SelectableItemView}. */ -public class SelectableItemViewHolder<E> extends RecyclerView.ViewHolder { +public class SelectableItemViewHolder<E> extends ViewHolder { private SelectableItemView<E> mItemView; /** - * @param itemView The SelectableItemView to be held by this ViewHolder. - * @param delegate The SelectionDelegate for the itemView. + * @param itemView The {@link SelectableItemView} to be held by this ViewHolder. + * @param delegate The {@link SelectionDelegate} for the itemView. */ @SuppressWarnings("unchecked") public SelectableItemViewHolder(View itemView, SelectionDelegate<E> delegate) { @@ -26,9 +26,17 @@ } /** - * @param item The item to display in the SelectableItemView held by this ViewHolder. + * @param item The item to display in the {@link SelectableItemView} held by this + * {@link ViewHolder}. */ public void displayItem(E item) { mItemView.setItem(item); } + + /** + * @return The {@link SelectableItemView} held by this ViewHolder. + */ + public SelectableItemView<E> getItemView() { + return mItemView; + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListLayout.java index 464b5b5..3594397 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListLayout.java
@@ -139,10 +139,12 @@ * * @param emptyDrawable The Drawable to show when the selectable list is empty. * @param emptyStringResId The string to show when the selectable list is empty. + * @return The {@link TextView} displayed when the list is empty. */ - public void initializeEmptyView(Drawable emptyDrawable, int emptyStringResId) { + public TextView initializeEmptyView(Drawable emptyDrawable, int emptyStringResId) { mEmptyView.setCompoundDrawablesWithIntrinsicBounds(null, emptyDrawable, null, null); mEmptyView.setText(emptyStringResId); + return mEmptyView; } /**
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index d9e46e1..f91a05b 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -410,6 +410,7 @@ "java/src/org/chromium/chrome/browser/history/HistoryManager.java", "java/src/org/chromium/chrome/browser/history/HistoryManagerToolbar.java", "java/src/org/chromium/chrome/browser/history/HistoryManagerUtils.java", + "java/src/org/chromium/chrome/browser/history/HistoryProvider.java", "java/src/org/chromium/chrome/browser/historyreport/DeltaFileEntry.java", "java/src/org/chromium/chrome/browser/historyreport/HistoryReportJniBridge.java", "java/src/org/chromium/chrome/browser/historyreport/SearchJniBridge.java", @@ -1267,6 +1268,9 @@ "javatests/src/org/chromium/chrome/browser/hardware_acceleration/ToastHWATest.java", "javatests/src/org/chromium/chrome/browser/hardware_acceleration/Utils.java", "javatests/src/org/chromium/chrome/browser/hardware_acceleration/WebappActivityHWATest.java", + "javatests/src/org/chromium/chrome/browser/history/HistoryActivityTest.java", + "javatests/src/org/chromium/chrome/browser/history/HistoryAdapterTest.java", + "javatests/src/org/chromium/chrome/browser/history/StubbedHistoryProvider.java", "javatests/src/org/chromium/chrome/browser/identity/SettingsSecureBasedIdentificationGeneratorTest.java", "javatests/src/org/chromium/chrome/browser/identity/UniqueIdentificationGeneratorFactoryTest.java", "javatests/src/org/chromium/chrome/browser/identity/UuidBasedUniqueIdentificationGeneratorTest.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/SelectFileDialogTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/SelectFileDialogTest.java index 0ae91db..add8ecc 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/SelectFileDialogTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/SelectFileDialogTest.java
@@ -32,6 +32,8 @@ + "content=\"width=device-width, initial-scale=2.0, maximum-scale=2.0\" /></head>" + "<body><form action=\"about:blank\">" + "<input id=\"input_file\" type=\"file\" /><br/>" + + "<input id=\"input_text\" type=\"file\" accept=\"text/plain\" /><br/>" + + "<input id=\"input_any\" type=\"file\" accept=\"*/*\" /><br/>" + "<input id=\"input_file_multiple\" type=\"file\" multiple /><br />" + "<input id=\"input_image\" type=\"file\" accept=\"image/*\" capture /><br/>" + "<input id=\"input_audio\" type=\"file\" accept=\"audio/*\" capture />" @@ -105,21 +107,60 @@ @Feature({"TextInput", "Main"}) @RetryOnFailure public void testSelectFileAndCancelRequest() throws Throwable { - DOMUtils.clickNode(this, mContentViewCore, "input_file"); - CriteriaHelper.pollInstrumentationThread(new IntentSentCriteria()); - assertEquals(Intent.ACTION_CHOOSER, mActivityWindowAndroidForTest.lastIntent.getAction()); - resetActivityWindowAndroidForTest(); - - DOMUtils.clickNode(this, mContentViewCore, "input_file_multiple"); - CriteriaHelper.pollInstrumentationThread(new IntentSentCriteria()); - assertEquals(Intent.ACTION_CHOOSER, mActivityWindowAndroidForTest.lastIntent.getAction()); - Intent contentIntent = (Intent) - mActivityWindowAndroidForTest.lastIntent.getParcelableExtra(Intent.EXTRA_INTENT); - assertNotNull(contentIntent); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { - assertTrue(contentIntent.hasExtra(Intent.EXTRA_ALLOW_MULTIPLE)); + { + DOMUtils.clickNode(this, mContentViewCore, "input_file"); + CriteriaHelper.pollInstrumentationThread(new IntentSentCriteria()); + assertEquals( + Intent.ACTION_CHOOSER, mActivityWindowAndroidForTest.lastIntent.getAction()); + Intent contentIntent = + (Intent) mActivityWindowAndroidForTest.lastIntent.getParcelableExtra( + Intent.EXTRA_INTENT); + assertNotNull(contentIntent); + assertFalse(contentIntent.hasCategory(Intent.CATEGORY_OPENABLE)); + resetActivityWindowAndroidForTest(); } - resetActivityWindowAndroidForTest(); + + { + DOMUtils.clickNode(this, mContentViewCore, "input_text"); + CriteriaHelper.pollInstrumentationThread(new IntentSentCriteria()); + assertEquals( + Intent.ACTION_CHOOSER, mActivityWindowAndroidForTest.lastIntent.getAction()); + Intent contentIntent = + (Intent) mActivityWindowAndroidForTest.lastIntent.getParcelableExtra( + Intent.EXTRA_INTENT); + assertNotNull(contentIntent); + assertTrue(contentIntent.hasCategory(Intent.CATEGORY_OPENABLE)); + resetActivityWindowAndroidForTest(); + } + + { + DOMUtils.clickNode(this, mContentViewCore, "input_any"); + CriteriaHelper.pollInstrumentationThread(new IntentSentCriteria()); + assertEquals( + Intent.ACTION_CHOOSER, mActivityWindowAndroidForTest.lastIntent.getAction()); + Intent contentIntent = + (Intent) mActivityWindowAndroidForTest.lastIntent.getParcelableExtra( + Intent.EXTRA_INTENT); + assertNotNull(contentIntent); + assertFalse(contentIntent.hasCategory(Intent.CATEGORY_OPENABLE)); + resetActivityWindowAndroidForTest(); + } + + { + DOMUtils.clickNode(this, mContentViewCore, "input_file_multiple"); + CriteriaHelper.pollInstrumentationThread(new IntentSentCriteria()); + assertEquals( + Intent.ACTION_CHOOSER, mActivityWindowAndroidForTest.lastIntent.getAction()); + Intent contentIntent = + (Intent) mActivityWindowAndroidForTest.lastIntent.getParcelableExtra( + Intent.EXTRA_INTENT); + assertNotNull(contentIntent); + assertFalse(contentIntent.hasCategory(Intent.CATEGORY_OPENABLE)); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { + assertTrue(contentIntent.hasExtra(Intent.EXTRA_ALLOW_MULTIPLE)); + } + resetActivityWindowAndroidForTest(); + } DOMUtils.clickNode(this, mContentViewCore, "input_image"); CriteriaHelper.pollInstrumentationThread(new IntentSentCriteria());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/history/HistoryActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/history/HistoryActivityTest.java new file mode 100644 index 0000000..b555b60af --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/history/HistoryActivityTest.java
@@ -0,0 +1,171 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.history; + +import android.os.Handler; +import android.os.Looper; +import android.support.test.filters.SmallTest; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.RecyclerView.ViewHolder; +import android.view.View; + +import org.chromium.base.ThreadUtils; +import org.chromium.base.test.BaseActivityInstrumentationTestCase; +import org.chromium.base.test.util.CallbackHelper; +import org.chromium.base.test.util.Restriction; +import org.chromium.chrome.R; +import org.chromium.chrome.browser.widget.TintedImageButton; +import org.chromium.chrome.browser.widget.selection.SelectableItemView; +import org.chromium.chrome.browser.widget.selection.SelectableItemViewHolder; +import org.chromium.chrome.browser.widget.selection.SelectionDelegate.SelectionObserver; +import org.chromium.chrome.test.util.ChromeRestriction; + +import java.util.Date; +import java.util.List; + +/** + * Tests the {@link HistoryActivity}. + */ +@Restriction(ChromeRestriction.RESTRICTION_TYPE_PHONE) +public class HistoryActivityTest extends BaseActivityInstrumentationTestCase<HistoryActivity> { + private static class TestObserver extends RecyclerView.AdapterDataObserver + implements SelectionObserver<HistoryItem> { + public final CallbackHelper onChangedCallback = new CallbackHelper(); + public final CallbackHelper onSelectionCallback = new CallbackHelper(); + + private Handler mHandler; + + public TestObserver() { + mHandler = new Handler(Looper.getMainLooper()); + } + + @Override + public void onChanged() { + // To guarantee that all real Observers have had a chance to react to the event, post + // the CallbackHelper.notifyCalled() call. + mHandler.post(new Runnable() { + @Override + public void run() { + onChangedCallback.notifyCalled(); + } + }); + } + + @Override + public void onSelectionStateChange(List<HistoryItem> selectedItems) { + mHandler.post(new Runnable() { + @Override + public void run() { + onSelectionCallback.notifyCalled(); + } + }); + } + } + + private StubbedHistoryProvider mHistoryProvider; + private HistoryAdapter mAdapter; + private HistoryManager mHistoryManager; + private RecyclerView mRecyclerView; + private TestObserver mTestObserver; + + private HistoryItem mItem1; + private HistoryItem mItem2; + + public HistoryActivityTest() { + super(HistoryActivity.class); + } + + @Override + public void setUp() throws Exception { + super.setUp(); + + mHistoryProvider = new StubbedHistoryProvider(); + + Date today = new Date(); + long[] timestamps = {today.getTime()}; + mItem1 = StubbedHistoryProvider.createHistoryItem(0, timestamps); + mItem2 = StubbedHistoryProvider.createHistoryItem(1, timestamps); + mHistoryProvider.addItem(mItem1); + mHistoryProvider.addItem(mItem2); + + HistoryManager.setProviderForTests(mHistoryProvider); + + final HistoryActivity activity = getActivity(); + mHistoryManager = activity.getHistoryManagerForTests(); + mAdapter = mHistoryManager.getAdapterForTests(); + mTestObserver = new TestObserver(); + mHistoryManager.getSelectionDelegateForTests().addObserver(mTestObserver); + mAdapter.registerAdapterDataObserver(mTestObserver); + mRecyclerView = ((RecyclerView) activity.findViewById(R.id.recycler_view)); + + assertEquals(4, mAdapter.getItemCount()); + } + + @SmallTest + public void testRemove_SingleItem() throws Exception { + int callCount = mTestObserver.onChangedCallback.getCallCount(); + final SelectableItemView<HistoryItem> itemView = getItemView(2); + + ThreadUtils.runOnUiThreadBlocking(new Runnable() { + @Override + public void run() { + ((TintedImageButton) itemView.findViewById(R.id.remove)).performClick(); + } + }); + + // Check that one item was removed. + mTestObserver.onChangedCallback.waitForCallback(callCount, 1); + assertEquals(1, mHistoryProvider.markItemForRemovalCallback.getCallCount()); + assertEquals(1, mHistoryProvider.removeItemsCallback.getCallCount()); + assertEquals(3, mAdapter.getItemCount()); + assertEquals(View.VISIBLE, mRecyclerView.getVisibility()); + assertEquals(View.GONE, mHistoryManager.getEmptyViewForTests().getVisibility()); + } + + @SmallTest + public void testRemove_AllItems() throws Exception { + toggleItemSelection(2); + toggleItemSelection(3); + + int callCount = mTestObserver.onChangedCallback.getCallCount(); + + ThreadUtils.runOnUiThread(new Runnable() { + @Override + public void run() { + assertTrue(mHistoryManager.getToolbarForTests().getMenu() + .performIdentifierAction(R.id.selection_mode_delete_menu_id, 0)); + } + }); + + // Check that all items were removed. The onChangedCallback should be called three times - + // once for each item that is being removed and once for the removal of the header. + mTestObserver.onChangedCallback.waitForCallback(callCount, 3); + assertEquals(0, mAdapter.getItemCount()); + assertEquals(2, mHistoryProvider.markItemForRemovalCallback.getCallCount()); + assertEquals(1, mHistoryProvider.removeItemsCallback.getCallCount()); + assertFalse(mHistoryManager.getSelectionDelegateForTests().isSelectionEnabled()); + assertEquals(View.GONE, mRecyclerView.getVisibility()); + assertEquals(View.VISIBLE, mHistoryManager.getEmptyViewForTests().getVisibility()); + } + + private void toggleItemSelection(int position) throws Exception { + int callCount = mTestObserver.onSelectionCallback.getCallCount(); + final SelectableItemView<HistoryItem> itemView = getItemView(position); + ThreadUtils.runOnUiThread(new Runnable() { + @Override + public void run() { + itemView.performLongClick(); + } + }); + mTestObserver.onSelectionCallback.waitForCallback(callCount, 1); + } + + @SuppressWarnings("unchecked") + private SelectableItemView<HistoryItem> getItemView(int position) { + ViewHolder mostRecentHolder = mRecyclerView.findViewHolderForAdapterPosition(position); + assertTrue(mostRecentHolder instanceof SelectableItemViewHolder); + return ((SelectableItemViewHolder<HistoryItem>) mostRecentHolder).getItemView(); + } +}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/history/HistoryAdapterTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/history/HistoryAdapterTest.java new file mode 100644 index 0000000..1f773ce --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/history/HistoryAdapterTest.java
@@ -0,0 +1,149 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.history; + +import static org.chromium.chrome.browser.widget.DateDividedAdapter.TYPE_DATE; +import static org.chromium.chrome.browser.widget.DateDividedAdapter.TYPE_HEADER; +import static org.chromium.chrome.browser.widget.DateDividedAdapter.TYPE_NORMAL; + +import android.support.test.filters.SmallTest; +import android.test.InstrumentationTestCase; + +import org.chromium.base.ThreadUtils; +import org.chromium.chrome.browser.widget.selection.SelectionDelegate; + +import java.util.Date; +import java.util.concurrent.TimeUnit; + +/** + * Tests for the {@link HistoryAdapter}. + */ +public class HistoryAdapterTest extends InstrumentationTestCase { + private StubbedHistoryProvider mHistoryProvider; + private HistoryAdapter mAdapter; + + @Override + public void setUp() throws Exception { + super.setUp(); + mHistoryProvider = new StubbedHistoryProvider(); + mAdapter = new HistoryAdapter(new SelectionDelegate<HistoryItem>(), null, mHistoryProvider); + } + + private void initializeAdapter() { + ThreadUtils.runOnUiThreadBlocking(new Runnable(){ + @Override + public void run() { + mAdapter.initialize(); + } + }); + } + + @SmallTest + public void testInitialize_Empty() { + initializeAdapter(); + checkAdapterContents(false); + } + + @SmallTest + public void testInitialize_SingleItem() { + Date today = new Date(); + long[] timestamps = {today.getTime(), today.getTime() - 100}; + HistoryItem item1 = StubbedHistoryProvider.createHistoryItem(0, timestamps); + mHistoryProvider.addItem(item1); + + initializeAdapter(); + + // There should be three items - the header, a date and the history item. + checkAdapterContents(true, null, null, item1); + } + + @SmallTest + public void testRemove_TwoItemsOneDate() { + Date today = new Date(); + long[] timestamps = {today.getTime()}; + HistoryItem item1 = StubbedHistoryProvider.createHistoryItem(0, timestamps); + mHistoryProvider.addItem(item1); + + HistoryItem item2 = StubbedHistoryProvider.createHistoryItem(1, timestamps); + mHistoryProvider.addItem(item2); + + initializeAdapter(); + + // There should be four items - the list header, a date header and two history items. + checkAdapterContents(true, null, null, item1, item2); + + mAdapter.markItemForRemoval(item1); + + // Check that one item was removed. + checkAdapterContents(true, null, null, item2); + assertEquals(1, mHistoryProvider.markItemForRemovalCallback.getCallCount()); + assertEquals(0, mHistoryProvider.removeItemsCallback.getCallCount()); + + mAdapter.markItemForRemoval(item2); + + // There should no longer be any items in the adapter. + checkAdapterContents(false); + assertEquals(2, mHistoryProvider.markItemForRemovalCallback.getCallCount()); + assertEquals(0, mHistoryProvider.removeItemsCallback.getCallCount()); + + mAdapter.removeItems(); + assertEquals(1, mHistoryProvider.removeItemsCallback.getCallCount()); + } + + @SmallTest + public void testRemove_TwoItemsTwoDates() { + Date today = new Date(); + long[] timestamps = {today.getTime()}; + HistoryItem item1 = StubbedHistoryProvider.createHistoryItem(0, timestamps); + mHistoryProvider.addItem(item1); + + long[] timestamps2 = {today.getTime() - TimeUnit.DAYS.toMillis(3)}; + HistoryItem item2 = StubbedHistoryProvider.createHistoryItem(1, timestamps2); + mHistoryProvider.addItem(item2); + + initializeAdapter(); + + // There should be five items - the list header, a date header, a history item, another + // date header and another history item. + checkAdapterContents(true, null, null, item1, null, item2); + + mAdapter.markItemForRemoval(item1); + + // Check that the first item and date header were removed. + checkAdapterContents(true, null, null, item2); + assertEquals(1, mHistoryProvider.markItemForRemovalCallback.getCallCount()); + assertEquals(0, mHistoryProvider.removeItemsCallback.getCallCount()); + + mAdapter.markItemForRemoval(item2); + + // There should no longer be any items in the adapter. + checkAdapterContents(false); + assertEquals(2, mHistoryProvider.markItemForRemovalCallback.getCallCount()); + assertEquals(0, mHistoryProvider.removeItemsCallback.getCallCount()); + + mAdapter.removeItems(); + assertEquals(1, mHistoryProvider.removeItemsCallback.getCallCount()); + } + + private void checkAdapterContents(boolean hasHeader, Object... expectedItems) { + assertEquals(expectedItems.length, mAdapter.getItemCount()); + assertEquals(hasHeader, mAdapter.hasListHeader()); + + for (int i = 0; i < expectedItems.length; i++) { + if (i == 0 && hasHeader) { + assertEquals(TYPE_HEADER, mAdapter.getItemViewType(i)); + continue; + } + + if (expectedItems[i] == null) { + // TODO(twellington): Check what date header is showing. + assertEquals(TYPE_DATE, mAdapter.getItemViewType(i)); + } else { + assertEquals(TYPE_NORMAL, mAdapter.getItemViewType(i)); + assertEquals(expectedItems[i], mAdapter.getItemAt(i).second); + } + } + } +}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/history/OWNERS b/chrome/android/javatests/src/org/chromium/chrome/browser/history/OWNERS new file mode 100644 index 0000000..0fa757c --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/history/OWNERS
@@ -0,0 +1 @@ +twellington@chromium.org
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/history/StubbedHistoryProvider.java b/chrome/android/javatests/src/org/chromium/chrome/browser/history/StubbedHistoryProvider.java new file mode 100644 index 0000000..84091e7 --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/history/StubbedHistoryProvider.java
@@ -0,0 +1,65 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.history; + +import org.chromium.base.test.util.CallbackHelper; + +import java.util.ArrayList; +import java.util.List; + +/** + * Stubs out the backends used by the native Android browsing history manager. + */ +public class StubbedHistoryProvider implements HistoryProvider { + public final CallbackHelper markItemForRemovalCallback = new CallbackHelper(); + public final CallbackHelper removeItemsCallback = new CallbackHelper(); + + private BrowsingHistoryObserver mObserver; + private List<HistoryItem> mItems = new ArrayList<>(); + private List<HistoryItem> mRemovedItems = new ArrayList<>(); + + @Override + public void setObserver(BrowsingHistoryObserver observer) { + mObserver = observer; + } + + @Override + public void queryHistory(String query, long endQueryTime) { + mObserver.onQueryHistoryComplete(mItems, false); + } + + @Override + public void markItemForRemoval(HistoryItem item) { + mRemovedItems.add(item); + markItemForRemovalCallback.notifyCalled(); + } + + @Override + public void removeItems() { + for (HistoryItem item : mRemovedItems) { + mItems.remove(item); + } + mRemovedItems.clear(); + removeItemsCallback.notifyCalled(); + } + + @Override + public void destroy() {} + + public void addItem(HistoryItem item) { + mItems.add(item); + } + + public static HistoryItem createHistoryItem(int which, long[] timestamps) { + if (which == 0) { + return new HistoryItem("http://google.com/", "www.google.com", "Google", timestamps); + } else if (which == 1) { + return new HistoryItem("http://foo.com/", "www.foo.com", "Foo", timestamps); + } else { + return null; + } + } + +}
diff --git a/chrome/browser/chromeos/login/screens/hid_detection_screen.cc b/chrome/browser/chromeos/login/screens/hid_detection_screen.cc index 763e851..af9da95 100644 --- a/chrome/browser/chromeos/login/screens/hid_detection_screen.cc +++ b/chrome/browser/chromeos/login/screens/hid_detection_screen.cc
@@ -53,17 +53,10 @@ HIDDetectionView* view) : HIDDetectionModel(base_screen_delegate), view_(view), - mouse_is_pairing_(false), - pointing_device_connect_type_(InputDeviceInfo::TYPE_UNKNOWN), - keyboard_is_pairing_(false), - keyboard_device_connect_type_(InputDeviceInfo::TYPE_UNKNOWN), - switch_on_adapter_when_ready_(false), - showing_(false), weak_ptr_factory_(this) { DCHECK(view_); if (view_) view_->Bind(*this); - } HIDDetectionScreen::~HIDDetectionScreen() { @@ -126,19 +119,13 @@ // Switch off BT adapter if it was off before the screen and no BT device // connected. - bool adapter_is_powered = + const bool adapter_is_powered = adapter_.get() && adapter_->IsPresent() && adapter_->IsPowered(); - bool use_bluetooth = - pointing_device_connect_type_ == InputDeviceInfo::TYPE_BLUETOOTH || - keyboard_device_connect_type_ == InputDeviceInfo::TYPE_BLUETOOTH; - bool need_switching_off = adapter_initially_powered_ && - !(*adapter_initially_powered_); - if (adapter_is_powered && !use_bluetooth && need_switching_off) { - VLOG(1) << "Switching off BT adapter after HID OOBE screen as unused."; - adapter_->SetPowered( - false, - base::Bind(&base::DoNothing), - base::Bind(&HIDDetectionScreen::SetPoweredOffError, + const bool need_switching_off = + adapter_initially_powered_ && !(*adapter_initially_powered_); + if (adapter_is_powered && need_switching_off) { + input_service_proxy_.GetDevices( + base::Bind(&HIDDetectionScreen::OnGetInputDevicesForPowerOff, weak_ptr_factory_.GetWeakPtr())); } @@ -532,6 +519,23 @@ UpdateDevices(); } +void HIDDetectionScreen::OnGetInputDevicesForPowerOff( + const std::vector<InputDeviceInfo>& devices) { + bool use_bluetooth = false; + for (const auto& device : devices) { + if (device.type == InputDeviceInfo::TYPE_BLUETOOTH) { + use_bluetooth = true; + break; + } + } + if (!use_bluetooth) { + VLOG(1) << "Switching off BT adapter after HID OOBE screen as unused."; + adapter_->SetPowered(false, base::Bind(&base::DoNothing), + base::Bind(&HIDDetectionScreen::SetPoweredOffError, + weak_ptr_factory_.GetWeakPtr())); + } +} + void HIDDetectionScreen::SetPoweredError() { LOG(ERROR) << "Failed to power BT adapter"; } @@ -544,5 +548,13 @@ VLOG(1) << "Failed to start Bluetooth discovery."; } +scoped_refptr<device::BluetoothAdapter> +HIDDetectionScreen::GetAdapterForTesting() { + return adapter_; +} + +void HIDDetectionScreen::SetAdapterInitialPoweredForTesting(bool powered) { + adapter_initially_powered_.reset(new bool(powered)); +} } // namespace chromeos
diff --git a/chrome/browser/chromeos/login/screens/hid_detection_screen.h b/chrome/browser/chromeos/login/screens/hid_detection_screen.h index 66cb6ba..de920f8 100644 --- a/chrome/browser/chromeos/login/screens/hid_detection_screen.h +++ b/chrome/browser/chromeos/login/screens/hid_detection_screen.h
@@ -140,6 +140,11 @@ // initiate a discovery session. void FindDevicesError(); + // Check the input devices returned by InputServiceProxy one by one and power + // off the BT adapter if there is no bluetooth device. + void OnGetInputDevicesForPowerOff( + const std::vector<InputDeviceInfo>& devices); + // Called by device::BluetoothAdapter in response to a failure to // power BT adapter. void SetPoweredError(); @@ -179,6 +184,9 @@ // Helper method. Sets device name or placeholder if the name is empty. void SetKeyboardDeviceName_(const std::string& name); + scoped_refptr<device::BluetoothAdapter> GetAdapterForTesting(); + void SetAdapterInitialPoweredForTesting(bool powered); + HIDDetectionView* view_; // Default bluetooth adapter, used for all operations. @@ -193,21 +201,23 @@ // Current pointing device, if any. Device name is kept in screen context. std::string pointing_device_id_; - bool mouse_is_pairing_; - InputDeviceInfo::Type pointing_device_connect_type_; + bool mouse_is_pairing_ = false; + InputDeviceInfo::Type pointing_device_connect_type_ = + InputDeviceInfo::TYPE_UNKNOWN; // Current keyboard device, if any. Device name is kept in screen context. std::string keyboard_device_id_; - bool keyboard_is_pairing_; - InputDeviceInfo::Type keyboard_device_connect_type_; + bool keyboard_is_pairing_ = false; + InputDeviceInfo::Type keyboard_device_connect_type_ = + InputDeviceInfo::TYPE_UNKNOWN; std::string keyboard_device_name_; // State of BT adapter before screen-initiated changes. std::unique_ptr<bool> adapter_initially_powered_; - bool switch_on_adapter_when_ready_; + bool switch_on_adapter_when_ready_ = false; - bool showing_; + bool showing_ = false; base::WeakPtrFactory<HIDDetectionScreen> weak_ptr_factory_;
diff --git a/chrome/browser/chromeos/login/screens/hid_detection_screen_browsertest.cc b/chrome/browser/chromeos/login/screens/hid_detection_screen_browsertest.cc index 1b9539b..3401ce1 100644 --- a/chrome/browser/chromeos/login/screens/hid_detection_screen_browsertest.cc +++ b/chrome/browser/chromeos/login/screens/hid_detection_screen_browsertest.cc
@@ -6,6 +6,7 @@ #include "chrome/browser/chromeos/device/input_service_test_helper.h" #include "chrome/browser/chromeos/login/screens/base_screen.h" #include "chrome/browser/chromeos/login/screens/hid_detection_screen.h" +#include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h" #include "chrome/browser/chromeos/login/test/wizard_in_process_browser_test.h" #include "chrome/browser/chromeos/login/wizard_controller.h" @@ -30,6 +31,7 @@ hid_detection_screen_); ASSERT_TRUE(hid_detection_screen_->view_); + hid_detection_screen()->SetAdapterInitialPoweredForTesting(false); helper_->SetProxy(&hid_detection_screen_->input_service_proxy_); } @@ -40,6 +42,12 @@ InputServiceTestHelper* helper() { return helper_.get(); } + HIDDetectionScreen* hid_detection_screen() { return hid_detection_screen_; } + + scoped_refptr<device::BluetoothAdapter> adapter() { + return hid_detection_screen_->GetAdapterForTesting(); + } + const ::login::ScreenContext* context() const { return &hid_detection_screen_->context_; } @@ -106,4 +114,44 @@ HIDDetectionModel::kContextKeyContinueButtonEnabled)); } +// Test that if there is any Bluetooth device connected on HID screen, the +// Bluetooth adapter should not be disabled after advancing to the next screen. +IN_PROC_BROWSER_TEST_F(HIDDetectionScreenTest, BluetoothDeviceConnected) { + OobeScreenWaiter(OobeScreen::SCREEN_OOBE_HID_DETECTION).Wait(); + EXPECT_TRUE(adapter()->IsPowered()); + + // Add a pair of USB mouse/keyboard so that |pointing_device_connect_type_| + // and |keyboard_device_connect_type_| are InputDeviceInfo::TYPE_USB. + helper()->AddDeviceToService(true, InputDeviceInfo::TYPE_USB); + helper()->AddDeviceToService(false, InputDeviceInfo::TYPE_USB); + + // Add another pair of Bluetooth mouse/keyboard. + helper()->AddDeviceToService(true, InputDeviceInfo::TYPE_BLUETOOTH); + helper()->AddDeviceToService(false, InputDeviceInfo::TYPE_BLUETOOTH); + + // Simulate the user's click on "Continue" button. + hid_detection_screen()->OnContinueButtonClicked(); + OobeScreenWaiter(OobeScreen::SCREEN_OOBE_NETWORK).Wait(); + + // The adapter should not be powered off at this moment. + EXPECT_TRUE(adapter()->IsPowered()); +} + +// Test that if there is no Bluetooth device connected on HID screen, the +// Bluetooth adapter should be disabled after advancing to the next screen. +IN_PROC_BROWSER_TEST_F(HIDDetectionScreenTest, NoBluetoothDeviceConnected) { + OobeScreenWaiter(OobeScreen::SCREEN_OOBE_HID_DETECTION).Wait(); + EXPECT_TRUE(adapter()->IsPowered()); + + helper()->AddDeviceToService(true, InputDeviceInfo::TYPE_USB); + helper()->AddDeviceToService(false, InputDeviceInfo::TYPE_USB); + + // Simulate the user's click on "Continue" button. + hid_detection_screen()->OnContinueButtonClicked(); + OobeScreenWaiter(OobeScreen::SCREEN_OOBE_NETWORK).Wait(); + + // The adapter should be powered off at this moment. + EXPECT_FALSE(adapter()->IsPowered()); +} + } // namespace chromeos
diff --git a/chrome/browser/extensions/api/dial/OWNERS b/chrome/browser/extensions/api/dial/OWNERS index 68dd516..8224bbf7 100644 --- a/chrome/browser/extensions/api/dial/OWNERS +++ b/chrome/browser/extensions/api/dial/OWNERS
@@ -1,3 +1,3 @@ mfoltz@chromium.org imcheng@chromium.org - +wez@chromium.org
diff --git a/chrome/browser/resources/settings/downloads_page/downloads_page.html b/chrome/browser/resources/settings/downloads_page/downloads_page.html index 4271241..ea7b85f 100644 --- a/chrome/browser/resources/settings/downloads_page/downloads_page.html +++ b/chrome/browser/resources/settings/downloads_page/downloads_page.html
@@ -11,7 +11,12 @@ <div class="start"> <div>$i18n{downloadLocation}</div> <div class="secondary"> +<if expr="not chromeos"> + [[prefs.download.default_directory.value]] +</if> +<if expr="chromeos"> [[getDownloadLocation_(prefs.download.default_directory.value)]] +</if> </div> </div> <div class="secondary-action">
diff --git a/chrome/browser/resources/settings/downloads_page/downloads_page.js b/chrome/browser/resources/settings/downloads_page/downloads_page.js index 7603dad..004e99c 100644 --- a/chrome/browser/resources/settings/downloads_page/downloads_page.js +++ b/chrome/browser/resources/settings/downloads_page/downloads_page.js
@@ -39,6 +39,7 @@ chrome.send('selectDownloadLocation'); }, +<if expr="chromeos"> /** * @param {string} path * @return {string} The download location string that is suitable to display @@ -55,4 +56,5 @@ path = path.replace(/\//g, ' \u203a '); return path; }, +</if> });
diff --git a/chrome/browser/resources/settings/settings_resources.grd b/chrome/browser/resources/settings/settings_resources.grd index bcd304f8..ddd8539 100644 --- a/chrome/browser/resources/settings/settings_resources.grd +++ b/chrome/browser/resources/settings/settings_resources.grd
@@ -524,7 +524,8 @@ allowexternalscript="true" /> <structure name="IDR_SETTINGS_DOWNLOADS_PAGE_JS" file="downloads_page/downloads_page.js" - type="chrome_html" /> + type="chrome_html" + preprocess="true" /> <structure name="IDR_SETTINGS_I18n_SETUP_HTML" file="i18n_setup.html" type="chrome_html" />
diff --git a/chrome/browser/ui/app_list/app_list_service_interactive_uitest.cc b/chrome/browser/ui/app_list/app_list_service_interactive_uitest.cc index 0ca371c3..163a9af3 100644 --- a/chrome/browser/ui/app_list/app_list_service_interactive_uitest.cc +++ b/chrome/browser/ui/app_list/app_list_service_interactive_uitest.cc
@@ -57,13 +57,11 @@ // ChromeOS does not support ShowForProfile(), or profile switching within the // app list. Profile switching on CrOS goes through a different code path. #if defined(OS_CHROMEOS) -#define MAYBE_ShowAndDismiss DISABLED_ShowAndDismiss #define MAYBE_SwitchAppListProfiles DISABLED_SwitchAppListProfiles #define MAYBE_SwitchAppListLockedProfile DISABLED_SwitchAppListLockedProfile #define MAYBE_SwitchAppListProfilesDuringSearch \ DISABLED_SwitchAppListProfilesDuringSearch #else -#define MAYBE_ShowAndDismiss ShowAndDismiss #define MAYBE_SwitchAppListProfiles SwitchAppListProfiles #define MAYBE_SwitchAppListLockedProfile SwitchAppListLockedProfile #define MAYBE_SwitchAppListProfilesDuringSearch \ @@ -71,7 +69,7 @@ #endif // Show the app list, then dismiss it. -IN_PROC_BROWSER_TEST_F(AppListServiceInteractiveTest, MAYBE_ShowAndDismiss) { +IN_PROC_BROWSER_TEST_F(AppListServiceInteractiveTest, ShowAndDismiss) { AppListService* service = AppListService::Get(); ASSERT_FALSE(service->IsAppListVisible()); service->ShowForProfile(browser()->profile());
diff --git a/chrome/browser/ui/app_list/app_list_syncable_service.cc b/chrome/browser/ui/app_list/app_list_syncable_service.cc index 555bfbd..aa44f70 100644 --- a/chrome/browser/ui/app_list/app_list_syncable_service.cc +++ b/chrome/browser/ui/app_list/app_list_syncable_service.cc
@@ -567,6 +567,7 @@ return NULL; VLOG(2) << this << " CreateSyncItemFromAppItem:" << app_item->ToDebugString(); SyncItem* sync_item = CreateSyncItem(app_item->id(), type); + DCHECK(app_item->position().IsValid()); UpdateSyncItemFromAppItem(app_item, sync_item); UpdateSyncItemInLocalStorage(profile_, sync_item); SendSyncChange(sync_item, SyncChange::ACTION_ADD); @@ -584,6 +585,8 @@ void AppListSyncableService::SetPinPosition( const std::string& app_id, const syncer::StringOrdinal& item_pin_ordinal) { + // Pin position can be set only after model is built. + DCHECK(IsInitialized()); SyncItem* sync_item = FindSyncItem(app_id); SyncChange::SyncChangeType sync_change_type; if (sync_item) { @@ -604,9 +607,15 @@ if (app_item->id() == kOemFolderId) return; + DCHECK(app_item->position().IsValid()); + SyncItem* sync_item = FindSyncItem(app_item->id()); if (sync_item) { UpdateAppItemFromSyncItem(sync_item, app_item); + if (!sync_item->item_ordinal.IsValid()) { + UpdateSyncItem(app_item); + VLOG(2) << "Flushing position to sync item " << sync_item; + } return; } CreateSyncItemFromAppItem(app_item); @@ -840,6 +849,33 @@ change_list.push_back(SyncChange(FROM_HERE, SyncChange::ACTION_ADD, GetSyncDataFromSyncItem(sync_item))); } + + // Fix items that do not contain valid app list position, required for + // builds prior to M53 (crbug.com/677647). + for (const auto& sync_pair : sync_items_) { + SyncItem* sync_item = sync_pair.second.get(); + if (sync_item->item_type != sync_pb::AppListSpecifics::TYPE_APP || + sync_item->item_ordinal.IsValid()) { + continue; + } + const AppListItem* app_item = model_->FindItem(sync_item->item_id); + if (app_item) { + if (UpdateSyncItemFromAppItem(app_item, sync_item)) { + VLOG(1) << "Fixing sync item from existing app: " << sync_item; + } else { + sync_item->item_ordinal = syncer::StringOrdinal::CreateInitialOrdinal(); + VLOG(1) << "Failed to fix sync item from existing app. " + << "Generating new position ordinal: " << sync_item; + } + } else { + sync_item->item_ordinal = syncer::StringOrdinal::CreateInitialOrdinal(); + VLOG(1) << "Fixing sync item by generating new position ordinal: " + << sync_item; + } + change_list.push_back(SyncChange(FROM_HERE, SyncChange::ACTION_UPDATE, + GetSyncDataFromSyncItem(sync_item))); + } + sync_processor_->ProcessSyncChanges(FROM_HERE, change_list); HandleUpdateFinished();
diff --git a/chrome/browser/ui/app_list/chrome_app_list_item.cc b/chrome/browser/ui/app_list/chrome_app_list_item.cc index 934638f..ca281a1 100644 --- a/chrome/browser/ui/app_list/chrome_app_list_item.cc +++ b/chrome/browser/ui/app_list/chrome_app_list_item.cc
@@ -62,10 +62,16 @@ void ChromeAppListItem::SetDefaultPositionIfApplicable() { syncer::StringOrdinal page_ordinal; syncer::StringOrdinal launch_ordinal; - if (GetAppSorting()->GetDefaultOrdinals(id(), &page_ordinal, - &launch_ordinal) && - page_ordinal.IsValid() && launch_ordinal.IsValid()) { - set_position(syncer::StringOrdinal(page_ordinal.ToInternalValue() + - launch_ordinal.ToInternalValue())); + extensions::AppSorting* app_sorting = GetAppSorting(); + if (!app_sorting->GetDefaultOrdinals(id(), &page_ordinal, + &launch_ordinal) || + !page_ordinal.IsValid() || !launch_ordinal.IsValid()) { + app_sorting->EnsureValidOrdinals(id(), syncer::StringOrdinal()); + page_ordinal = app_sorting->GetPageOrdinal(id()); + launch_ordinal = app_sorting->GetAppLaunchOrdinal(id()); } + DCHECK(page_ordinal.IsValid()); + DCHECK(launch_ordinal.IsValid()); + set_position(syncer::StringOrdinal(page_ordinal.ToInternalValue() + + launch_ordinal.ToInternalValue())); }
diff --git a/chrome/browser/ui/app_list/extension_app_model_builder_unittest.cc b/chrome/browser/ui/app_list/extension_app_model_builder_unittest.cc index 71711bb..d21cfebd5 100644 --- a/chrome/browser/ui/app_list/extension_app_model_builder_unittest.cc +++ b/chrome/browser/ui/app_list/extension_app_model_builder_unittest.cc
@@ -72,7 +72,7 @@ return app; } -const char kDefaultApps[] = "Hosted App,Packaged App 1,Packaged App 2"; +const char kDefaultApps[] = "Packaged App 1,Packaged App 2,Hosted App"; const size_t kDefaultAppCount = 3u; } // namespace @@ -183,7 +183,7 @@ extensions::UNINSTALL_REASON_FOR_TESTING, base::Bind(&base::DoNothing), NULL); - EXPECT_EQ(std::string("Hosted App,Packaged App 1"), + EXPECT_EQ(std::string("Packaged App 1,Hosted App"), GetModelContent(model_.get())); base::RunLoop().RunUntilIdle(); @@ -201,7 +201,7 @@ extensions::UNINSTALL_REASON_FOR_TESTING, base::Bind(&base::DoNothing), NULL); - EXPECT_EQ(std::string("Hosted App,Packaged App 1"), + EXPECT_EQ(std::string("Packaged App 1,Hosted App"), GetModelContent(model_.get())); base::RunLoop().RunUntilIdle();
diff --git a/chrome/browser/ui/ash/app_list/app_list_interactive_uitest.cc b/chrome/browser/ui/ash/app_list/app_list_interactive_uitest.cc new file mode 100644 index 0000000..a4386b1f --- /dev/null +++ b/chrome/browser/ui/ash/app_list/app_list_interactive_uitest.cc
@@ -0,0 +1,50 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <memory> + +#include "ash/common/shelf/app_list_button.h" +#include "ash/common/shelf/shelf_widget.h" +#include "ash/common/shelf/wm_shelf.h" +#include "ash/common/wm_shell.h" +#include "ash/common/wm_window.h" +#include "ash/public/cpp/shell_window_ids.h" +#include "base/run_loop.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "ui/app_list/presenter/app_list.h" +#include "ui/events/test/event_generator.h" + +using AppListTest = InProcessBrowserTest; + +// An integration test to toggle the app list by pressing the shelf button. +IN_PROC_BROWSER_TEST_F(AppListTest, PressAppListButtonToShowAndDismiss) { + ash::WmShell* shell = ash::WmShell::Get(); + ash::WmShelf* shelf = ash::WmShelf::ForWindow(shell->GetActiveWindow()); + ash::ShelfWidget* shelf_widget = shelf->shelf_widget(); + ash::AppListButton* app_list_button = shelf_widget->GetAppListButton(); + + ash::WmWindow* root_window = shell->GetActiveWindow()->GetRootWindow(); + ash::WmWindow* app_list_container = root_window->GetChildByShellWindowId( + ash::kShellWindowId_AppListContainer); + ui::test::EventGenerator generator(shelf_widget->GetNativeWindow()); + + // Click the app list button to show the app list. + EXPECT_FALSE(shell->app_list()->GetTargetVisibility()); + EXPECT_EQ(0u, app_list_container->GetChildren().size()); + EXPECT_FALSE(app_list_button->is_showing_app_list()); + generator.set_current_location( + app_list_button->GetBoundsInScreen().CenterPoint()); + generator.ClickLeftButton(); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(shell->app_list()->GetTargetVisibility()); + EXPECT_EQ(1u, app_list_container->GetChildren().size()); + EXPECT_TRUE(app_list_button->is_showing_app_list()); + + // Click the button again to dismiss the app list; the window animates closed. + generator.ClickLeftButton(); + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(shell->app_list()->GetTargetVisibility()); + EXPECT_EQ(1u, app_list_container->GetChildren().size()); + EXPECT_FALSE(app_list_button->is_showing_app_list()); +}
diff --git a/chrome/browser/ui/ash/app_list/app_list_presenter_delegate_mus.cc b/chrome/browser/ui/ash/app_list/app_list_presenter_delegate_mus.cc index fb7e062..1ca9e18 100644 --- a/chrome/browser/ui/ash/app_list/app_list_presenter_delegate_mus.cc +++ b/chrome/browser/ui/ash/app_list/app_list_presenter_delegate_mus.cc
@@ -4,7 +4,7 @@ #include "chrome/browser/ui/ash/app_list/app_list_presenter_delegate_mus.h" -#include "ui/app_list/presenter/app_list_presenter.h" +#include "ui/app_list/presenter/app_list_presenter_impl.h" #include "ui/app_list/presenter/app_list_view_delegate_factory.h" #include "ui/app_list/views/app_list_view.h" #include "ui/display/display.h" @@ -39,7 +39,7 @@ } // namespace AppListPresenterDelegateMus::AppListPresenterDelegateMus( - app_list::AppListPresenter* presenter, + app_list::AppListPresenterImpl* presenter, app_list::AppListViewDelegateFactory* view_delegate_factory) : presenter_(presenter), view_delegate_factory_(view_delegate_factory) {}
diff --git a/chrome/browser/ui/ash/app_list/app_list_presenter_delegate_mus.h b/chrome/browser/ui/ash/app_list/app_list_presenter_delegate_mus.h index 87e9c2e..81ab187 100644 --- a/chrome/browser/ui/ash/app_list/app_list_presenter_delegate_mus.h +++ b/chrome/browser/ui/ash/app_list/app_list_presenter_delegate_mus.h
@@ -10,7 +10,7 @@ #include "ui/views/pointer_watcher.h" namespace app_list { -class AppListPresenter; +class AppListPresenterImpl; class AppListView; class AppListViewDelegateFactory; } // namespace app_list @@ -23,7 +23,7 @@ public views::PointerWatcher { public: AppListPresenterDelegateMus( - app_list::AppListPresenter* presenter, + app_list::AppListPresenterImpl* presenter, app_list::AppListViewDelegateFactory* view_delegate_factory); ~AppListPresenterDelegateMus() override; @@ -45,7 +45,7 @@ views::Widget* target) override; // Not owned. Pointer is guaranteed to be valid while this object is alive. - app_list::AppListPresenter* presenter_; + app_list::AppListPresenterImpl* presenter_; // Not owned. Pointer is guaranteed to be valid while this object is alive. app_list::AppListViewDelegateFactory* view_delegate_factory_;
diff --git a/chrome/browser/ui/ash/app_list/app_list_presenter_service.cc b/chrome/browser/ui/ash/app_list/app_list_presenter_service.cc index 2770d89..aed941a 100644 --- a/chrome/browser/ui/ash/app_list/app_list_presenter_service.cc +++ b/chrome/browser/ui/ash/app_list/app_list_presenter_service.cc
@@ -8,7 +8,7 @@ #include "chrome/browser/ui/ash/ash_util.h" #include "content/public/common/service_manager_connection.h" #include "services/service_manager/public/cpp/connector.h" -#include "ui/app_list/presenter/app_list_presenter.h" +#include "ui/app_list/presenter/app_list_presenter_impl.h" AppListPresenterService::AppListPresenterService() : binding_(this) { content::ServiceManagerConnection* connection = @@ -20,6 +20,8 @@ ash_util::GetAshServiceName(), &app_list_ptr); // Register this object as the app list presenter. app_list_ptr->SetAppListPresenter(binding_.CreateInterfacePtrAndBind()); + // Pass the interface pointer to the presenter to report visibility changes. + GetPresenter()->SetAppList(std::move(app_list_ptr)); } } @@ -37,6 +39,6 @@ GetPresenter()->ToggleAppList(display_id); } -app_list::AppListPresenter* AppListPresenterService::GetPresenter() { +app_list::AppListPresenterImpl* AppListPresenterService::GetPresenter() { return AppListServiceAsh::GetInstance()->GetAppListPresenter(); }
diff --git a/chrome/browser/ui/ash/app_list/app_list_presenter_service.h b/chrome/browser/ui/ash/app_list/app_list_presenter_service.h index 969cc8e..7ca5d255 100644 --- a/chrome/browser/ui/ash/app_list/app_list_presenter_service.h +++ b/chrome/browser/ui/ash/app_list/app_list_presenter_service.h
@@ -10,7 +10,7 @@ #include "ui/app_list/presenter/app_list_presenter.mojom.h" namespace app_list { -class AppListPresenter; +class AppListPresenterImpl; } // A service providing the Mojo interface to manipulate the App List. @@ -25,7 +25,7 @@ void ToggleAppList(int64_t display_id) override; private: - app_list::AppListPresenter* GetPresenter(); + app_list::AppListPresenterImpl* GetPresenter(); mojo::Binding<app_list::mojom::AppListPresenter> binding_;
diff --git a/chrome/browser/ui/ash/app_list/app_list_service_ash.cc b/chrome/browser/ui/ash/app_list/app_list_service_ash.cc index ca2480e..e3fc90a 100644 --- a/chrome/browser/ui/ash/app_list/app_list_service_ash.cc +++ b/chrome/browser/ui/ash/app_list/app_list_service_ash.cc
@@ -16,6 +16,7 @@ #include "chrome/browser/ui/app_list/start_page_service.h" #include "chrome/browser/ui/ash/app_list/app_list_controller_ash.h" #include "chrome/browser/ui/ash/app_list/app_list_presenter_delegate_mus.h" +#include "chrome/browser/ui/ash/app_list/app_list_presenter_service.h" #include "chrome/browser/ui/ash/ash_util.h" #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" #include "chrome/browser/ui/ash/session_util.h" @@ -58,7 +59,7 @@ ~AppListPresenterDelegateFactoryMus() override {} std::unique_ptr<app_list::AppListPresenterDelegate> GetDelegate( - app_list::AppListPresenter* presenter) override { + app_list::AppListPresenterImpl* presenter) override { return base::MakeUnique<AppListPresenterDelegateMus>( presenter, view_delegate_factory_.get()); } @@ -78,27 +79,32 @@ } AppListServiceAsh::AppListServiceAsh() { + std::unique_ptr<app_list::AppListPresenterDelegateFactory> factory; if (chrome::IsRunningInMash()) { - presenter_delegate_factory_.reset(new AppListPresenterDelegateFactoryMus( - base::MakeUnique<ViewDelegateFactoryImpl>(this))); + factory = base::MakeUnique<AppListPresenterDelegateFactoryMus>( + base::MakeUnique<ViewDelegateFactoryImpl>(this)); } else { - presenter_delegate_factory_.reset(new ash::AppListPresenterDelegateFactory( - base::MakeUnique<ViewDelegateFactoryImpl>(this))); + factory = base::MakeUnique<ash::AppListPresenterDelegateFactory>( + base::MakeUnique<ViewDelegateFactoryImpl>(this)); } - app_list_presenter_.reset( - new app_list::AppListPresenterImpl(presenter_delegate_factory_.get())); - controller_delegate_.reset( - new AppListControllerDelegateAsh(app_list_presenter_.get())); + app_list_presenter_ = + base::MakeUnique<app_list::AppListPresenterImpl>(std::move(factory)); + controller_delegate_ = + base::MakeUnique<AppListControllerDelegateAsh>(app_list_presenter_.get()); } -AppListServiceAsh::~AppListServiceAsh() { -} +AppListServiceAsh::~AppListServiceAsh() {} -app_list::AppListPresenter* AppListServiceAsh::GetAppListPresenter() { +app_list::AppListPresenterImpl* AppListServiceAsh::GetAppListPresenter() { return app_list_presenter_.get(); } void AppListServiceAsh::Init(Profile* initial_profile) { + // The AppListPresenterService ctor calls AppListServiceAsh::GetInstance(), + // which isn't available in the AppListServiceAsh constructor, so init here. + // This establishes the mojo connections between the app list and presenter. + app_list_presenter_service_ = base::MakeUnique<AppListPresenterService>(); + // Ensure the StartPageService is created here. This early initialization is // necessary to allow the WebContents to load before the app list is shown. app_list::StartPageService* service =
diff --git a/chrome/browser/ui/ash/app_list/app_list_service_ash.h b/chrome/browser/ui/ash/app_list/app_list_service_ash.h index b3f3763..1175466 100644 --- a/chrome/browser/ui/ash/app_list/app_list_service_ash.h +++ b/chrome/browser/ui/ash/app_list/app_list_service_ash.h
@@ -9,13 +9,12 @@ #include "base/macros.h" #include "chrome/browser/ui/app_list/app_list_service_impl.h" -#include "chrome/browser/ui/ash/app_list/app_list_presenter_service.h" #include "ui/app_list/app_list_model.h" +class AppListPresenterService; + namespace app_list { -class AppListPresenter; class AppListPresenterImpl; -class AppListPresenterDelegateFactory; } namespace base { @@ -30,7 +29,7 @@ public: static AppListServiceAsh* GetInstance(); - app_list::AppListPresenter* GetAppListPresenter(); + app_list::AppListPresenterImpl* GetAppListPresenter(); // AppListService overrides: void Init(Profile* initial_profile) override; @@ -72,12 +71,9 @@ void CreateForProfile(Profile* default_profile) override; void DestroyAppList() override; - std::unique_ptr<app_list::AppListPresenterDelegateFactory> - presenter_delegate_factory_; std::unique_ptr<app_list::AppListPresenterImpl> app_list_presenter_; std::unique_ptr<AppListControllerDelegateAsh> controller_delegate_; - - AppListPresenterService app_list_presenter_service_; + std::unique_ptr<AppListPresenterService> app_list_presenter_service_; DISALLOW_COPY_AND_ASSIGN(AppListServiceAsh); };
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate.cc b/chrome/browser/ui/ash/chrome_shell_delegate.cc index 6bd85d99..383874b 100644 --- a/chrome/browser/ui/ash/chrome_shell_delegate.cc +++ b/chrome/browser/ui/ash/chrome_shell_delegate.cc
@@ -44,8 +44,6 @@ #include "chrome/browser/signin/signin_error_notifier_factory_ash.h" #include "chrome/browser/speech/tts_controller.h" #include "chrome/browser/sync/sync_error_notifier_factory_ash.h" -#include "chrome/browser/ui/app_list/app_list_view_delegate.h" -#include "chrome/browser/ui/ash/app_list/app_list_service_ash.h" #include "chrome/browser/ui/ash/chrome_keyboard_ui.h" #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl.h" #include "chrome/browser/ui/ash/launcher/launcher_context_menu.h" @@ -74,7 +72,6 @@ #include "content/public/browser/notification_service.h" #include "content/public/browser/user_metrics.h" #include "content/public/common/service_manager_connection.h" -#include "ui/app_list/presenter/app_list_presenter.h" #include "ui/aura/window.h" #include "ui/base/ime/chromeos/input_method_manager.h" #include "ui/base/l10n/l10n_util.h" @@ -453,11 +450,6 @@ displayer.browser()->window()->GetNativeWindow()); } -app_list::AppListPresenter* ChromeShellDelegate::GetAppListPresenter() { - DCHECK(ash::Shell::HasInstance()); - return AppListServiceAsh::GetInstance()->GetAppListPresenter(); -} - ash::ShelfDelegate* ChromeShellDelegate::CreateShelfDelegate( ash::ShelfModel* model) { if (!shelf_delegate_) {
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate.h b/chrome/browser/ui/ash/chrome_shell_delegate.h index f5c0e77..bebc20d 100644 --- a/chrome/browser/ui/ash/chrome_shell_delegate.h +++ b/chrome/browser/ui/ash/chrome_shell_delegate.h
@@ -42,7 +42,6 @@ void Exit() override; keyboard::KeyboardUI* CreateKeyboardUI() override; void OpenUrlFromArc(const GURL& url) override; - app_list::AppListPresenter* GetAppListPresenter() override; ash::ShelfDelegate* CreateShelfDelegate(ash::ShelfModel* model) override; ash::SystemTrayDelegate* CreateSystemTrayDelegate() override; std::unique_ptr<ash::WallpaperDelegate> CreateWallpaperDelegate() override;
diff --git a/chrome/browser/ui/libgtkui/gtk_ui.cc b/chrome/browser/ui/libgtkui/gtk_ui.cc index 36aa340..07fb169 100644 --- a/chrome/browser/ui/libgtkui/gtk_ui.cc +++ b/chrome/browser/ui/libgtkui/gtk_ui.cc
@@ -242,11 +242,9 @@ // // Default tints. const color_utils::HSL kDefaultTintFrameIncognito = {-1, 0.2f, 0.35f}; +#if GTK_MAJOR_VERSION == 2 const color_utils::HSL kDefaultTintFrameIncognitoInactive = {-1, 0.3f, 0.6f}; - -#if GTK_MAJOR_VERSION == 3 -const color_utils::HSL kDefaultTintFrameInactive = {-1, -1, 0.75f}; -#endif // GTK_MAJOR_VERSION == 3 +#endif // Picks a button tint from a set of background colors. While // |accent_color| will usually be the same color through a theme, this @@ -879,6 +877,12 @@ colors_[ThemeProperties::COLOR_TAB_THROBBER_WAITING] = native_theme_->GetSystemColor( ui::NativeTheme::kColorId_ThrobberWaitingColor); + +#if GTK_MAJOR_VERSION > 2 + colors_[ThemeProperties::COLOR_TOOLBAR_BOTTOM_SEPARATOR] = + colors_[ThemeProperties::COLOR_DETACHED_BOOKMARK_BAR_SEPARATOR] = + GetBorderColor("GtkToolbar.primary-toolbar.toolbar"); +#endif } void Gtk2UI::LoadCursorTheme() { @@ -921,58 +925,16 @@ GetChromeStyleColor("incognito-inactive-frame-color", &temp_color); colors_[ThemeProperties::COLOR_FRAME_INCOGNITO_INACTIVE] = temp_color; #else - auto set_frame_color = [this](int color_id) { - // Render a GtkHeaderBar as our title bar, cropping out any curved edges - // on the left and right sides. Also remove the bottom border for good - // measure. - SkBitmap bitmap; - bitmap.allocN32Pixels(1, 1); - bitmap.eraseColor(0); - - static GtkWidget* menu = nullptr; - if (!menu) { - menu = gtk_menu_bar_new(); - gtk_widget_set_size_request(menu, 1, 1); - - GtkWidget* window = gtk_offscreen_window_new(); - gtk_container_add(GTK_CONTAINER(window), menu); - - gtk_widget_show_all(window); - } - - cairo_surface_t* surface = cairo_image_surface_create_for_data( - static_cast<unsigned char*>(bitmap.getAddr(0, 0)), CAIRO_FORMAT_ARGB32, - bitmap.width(), bitmap.height(), - cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, 1)); - cairo_t* cr = cairo_create(surface); - gtk_widget_draw(menu, cr); - cairo_destroy(cr); - cairo_surface_destroy(surface); - - switch (color_id) { - case ThemeProperties::COLOR_FRAME_INACTIVE: - bitmap = SkBitmapOperations::CreateHSLShiftedBitmap( - bitmap, kDefaultTintFrameInactive); - break; - case ThemeProperties::COLOR_FRAME_INCOGNITO: - bitmap = SkBitmapOperations::CreateHSLShiftedBitmap( - bitmap, kDefaultTintFrameIncognito); - break; - case ThemeProperties::COLOR_FRAME_INCOGNITO_INACTIVE: - bitmap = SkBitmapOperations::CreateHSLShiftedBitmap( - bitmap, kDefaultTintFrameIncognitoInactive); - break; - } - - bitmap.lockPixels(); - colors_[color_id] = bitmap.getColor(0, 0); - bitmap.unlockPixels(); - }; - - set_frame_color(ThemeProperties::COLOR_FRAME); - set_frame_color(ThemeProperties::COLOR_FRAME_INACTIVE); - set_frame_color(ThemeProperties::COLOR_FRAME_INCOGNITO); - set_frame_color(ThemeProperties::COLOR_FRAME_INCOGNITO_INACTIVE); + // TODO(thomasanderson): Render a GtkHeaderBar directly. + SkColor color_frame = GetBGColor(".headerbar.header-bar.titlebar"); + SkColor color_frame_inactive = + GetBGColor(".headerbar.header-bar.titlebar:backdrop"); + colors_[ThemeProperties::COLOR_FRAME] = color_frame; + colors_[ThemeProperties::COLOR_FRAME_INACTIVE] = color_frame_inactive; + colors_[ThemeProperties::COLOR_FRAME_INCOGNITO] = + color_utils::HSLShift(color_frame, kDefaultTintFrameIncognito); + colors_[ThemeProperties::COLOR_FRAME_INCOGNITO_INACTIVE] = + color_utils::HSLShift(color_frame_inactive, kDefaultTintFrameIncognito); #endif }
diff --git a/chrome/browser/ui/libgtkui/gtk_util.cc b/chrome/browser/ui/libgtkui/gtk_util.cc index aab9717..caed023 100644 --- a/chrome/browser/ui/libgtkui/gtk_util.cc +++ b/chrome/browser/ui/libgtkui/gtk_util.cc
@@ -14,6 +14,9 @@ #include "base/command_line.h" #include "base/debug/leak_annotations.h" #include "base/environment.h" +#include "base/strings/string_split.h" +#include "base/strings/string_tokenizer.h" +#include "base/strings/string_util.h" #include "ui/aura/window.h" #include "ui/aura/window_tree_host.h" #include "ui/base/accelerators/accelerator.h" @@ -188,4 +191,218 @@ g_object_set_data(G_OBJECT(dialog), kAuraTransientParent, NULL); } +#if GTK_MAJOR_VERSION > 2 +ScopedStyleContext AppendNode(GtkStyleContext* context, + const std::string& css_node) { + GtkWidgetPath* path = + context ? gtk_widget_path_copy(gtk_style_context_get_path(context)) + : gtk_widget_path_new(); + + enum { + // TODO(thomasanderson): Add CSS_NAME here to handle the Gtk3.20 case. + CSS_TYPE, + CSS_CLASS, + CSS_PSEUDOCLASS, + } part_type = CSS_TYPE; + static const struct { + const char* name; + GtkStateFlags state_flag; + } pseudo_classes[] = { + {"active", GTK_STATE_FLAG_ACTIVE}, + {"hover", GTK_STATE_FLAG_PRELIGHT}, + {"selected", GTK_STATE_FLAG_SELECTED}, + {"disabled", GTK_STATE_FLAG_INSENSITIVE}, + {"indeterminate", GTK_STATE_FLAG_INCONSISTENT}, + {"focus", GTK_STATE_FLAG_FOCUSED}, + {"backdrop", GTK_STATE_FLAG_BACKDROP}, + // TODO(thomasanderson): These state flags are only available in + // GTK 3.10 or later, which is unavailable in the wheezy + // sysroot. Add them once the sysroot is updated to jessie. + // { "link", GTK_STATE_FLAG_LINK }, + // { "visited", GTK_STATE_FLAG_VISITED }, + // { "checked", GTK_STATE_FLAG_CHECKED }, + }; + GtkStateFlags state = + context ? gtk_style_context_get_state(context) : GTK_STATE_FLAG_NORMAL; + base::StringTokenizer t(css_node, ".:"); + t.set_options(base::StringTokenizer::RETURN_DELIMS); + while (t.GetNext()) { + if (t.token_is_delim()) { + if (t.token_begin() == css_node.begin()) { + // Special case for the first token. + gtk_widget_path_append_type(path, G_TYPE_NONE); + } + switch (*t.token_begin()) { + case '.': + part_type = CSS_CLASS; + break; + case ':': + part_type = CSS_PSEUDOCLASS; + break; + default: + NOTREACHED(); + } + } else { + switch (part_type) { + case CSS_TYPE: { + GType type = g_type_from_name(t.token().c_str()); + DCHECK(type); + gtk_widget_path_append_type(path, type); + break; + } + case CSS_CLASS: { + gtk_widget_path_iter_add_class(path, -1, t.token().c_str()); + break; + } + case CSS_PSEUDOCLASS: { + GtkStateFlags state_flag = GTK_STATE_FLAG_NORMAL; + for (const auto& pseudo_class_entry : pseudo_classes) { + if (strcmp(pseudo_class_entry.name, t.token().c_str()) == 0) { + state_flag = pseudo_class_entry.state_flag; + break; + } + } + state = static_cast<GtkStateFlags>(state | state_flag); + break; + } + } + } + } + auto child_context = ScopedStyleContext(gtk_style_context_new()); + gtk_style_context_set_path(child_context, path); + gtk_style_context_set_state(child_context, state); + gtk_style_context_set_parent(child_context, context); + gtk_widget_path_unref(path); + return child_context; +} + +ScopedStyleContext GetStyleContextFromCss(const char* css_selector) { + // Prepend "GtkWindow.background" to the selector since all widgets must live + // in a window, but we don't want to specify that every time. + auto context = AppendNode(nullptr, "GtkWindow.background"); + + for (const auto& widget_type : + base::SplitString(css_selector, base::kWhitespaceASCII, + base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) { + context = AppendNode(context, widget_type); + } + return context; +} + +SkColor GdkRgbaToSkColor(const GdkRGBA& color) { + return SkColorSetARGB(color.alpha * 255, color.red * 255, color.green * 255, + color.blue * 255); +} + +SkColor GetFGColor(const char* css_selector) { + auto context = GetStyleContextFromCss(css_selector); + GdkRGBA color; + gtk_style_context_get_color(context, gtk_style_context_get_state(context), + &color); + return GdkRgbaToSkColor(color); +} + +GtkCssProvider* GetCssProvider(const char* css) { + GtkCssProvider* provider = gtk_css_provider_new(); + GError* error = nullptr; + gtk_css_provider_load_from_data(provider, css, -1, &error); + DCHECK(!error); + return provider; +} + +void ApplyCssToContext(GtkStyleContext* context, GtkCssProvider* provider) { + while (context) { + gtk_style_context_add_provider(context, GTK_STYLE_PROVIDER(provider), + G_MAXUINT); + context = gtk_style_context_get_parent(context); + } +} + +void RemoveBorders(GtkStyleContext* context) { + static GtkCssProvider* provider = GetCssProvider( + "* {" + "border-style: none;" + "border-radius: 0px;" + "border-width: 0px;" + "border-image-width: 0px;" + "padding: 0px;" + "margin: 0px;" + "}"); + ApplyCssToContext(context, provider); +} + +void AddBorders(GtkStyleContext* context) { + static GtkCssProvider* provider = GetCssProvider( + "* {" + "border-style: solid;" + "border-radius: 0px;" + "border-width: 1px;" + "padding: 0px;" + "margin: 0px;" + "}"); + ApplyCssToContext(context, provider); +} + +// A 1x1 cairo surface that GTK can render into. +class PixelSurface { + public: + PixelSurface() + : surface_(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1)), + cairo_(cairo_create(surface_)) {} + + ~PixelSurface() { + cairo_destroy(cairo_); + cairo_surface_destroy(surface_); + } + + // Get the drawing context for GTK to use. + cairo_t* cairo() { return cairo_; } + + // Get the color value of the single pixel. + SkColor GetPixelValue() { + return *reinterpret_cast<SkColor*>(cairo_image_surface_get_data(surface_)); + } + + private: + cairo_surface_t* surface_; + cairo_t* cairo_; +}; + +SkColor GetBGColor(const char* css_selector) { + // Backgrounds are more general than solid colors (eg. gradients), + // but chromium requires us to boil this down to one color. We + // cannot use the background-color here because some themes leave it + // set to a garbage color because a background-image will cover it + // anyway. So we instead render the background into a single pixel, + // removing any borders, and hope that we get a good color. + auto context = GetStyleContextFromCss(css_selector); + RemoveBorders(context); + PixelSurface surface; + gtk_render_background(context, surface.cairo(), 0, 0, 1, 1); + return surface.GetPixelValue(); +} + +SkColor GetBorderColor(const char* css_selector) { + // Borders have the same issue as backgrounds, due to the + // border-image property. + auto context = GetStyleContextFromCss(css_selector); + GtkStateFlags state = gtk_style_context_get_state(context); + GtkBorderStyle border_style = GTK_BORDER_STYLE_NONE; + gtk_style_context_get(context, state, GTK_STYLE_PROPERTY_BORDER_STYLE, + &border_style, nullptr); + GtkBorder border; + gtk_style_context_get_border(context, state, &border); + if ((border_style == GTK_BORDER_STYLE_NONE || + border_style == GTK_BORDER_STYLE_HIDDEN) || + (!border.left && !border.right && !border.top && !border.bottom)) { + return SK_ColorTRANSPARENT; + } + + AddBorders(context); + PixelSurface surface; + gtk_render_frame(context, surface.cairo(), 0, 0, 1, 1); + return surface.GetPixelValue(); +} +#endif + } // namespace libgtkui
diff --git a/chrome/browser/ui/libgtkui/gtk_util.h b/chrome/browser/ui/libgtkui/gtk_util.h index ab174c2..fc9aa31 100644 --- a/chrome/browser/ui/libgtkui/gtk_util.h +++ b/chrome/browser/ui/libgtkui/gtk_util.h
@@ -67,6 +67,74 @@ // Clears the transient parent for |dialog|. void ClearAuraTransientParent(GtkWidget* dialog); +#if GTK_MAJOR_VERSION > 2 +template <typename T> +class ScopedGObject { + public: + explicit ScopedGObject(T* obj) : obj_(obj) { + // Increase the reference count of |obj_|, removing the floating + // reference if it has one. + g_object_ref_sink(obj_); + } + + ScopedGObject(const ScopedGObject<T>& other) : obj_(other.obj_) { + g_object_ref(obj_); + } + + ScopedGObject(ScopedGObject<T>&& other) : obj_(other.obj_) { + other.obj_ = nullptr; + } + + ~ScopedGObject() { + if (obj_) + g_object_unref(obj_); + } + + ScopedGObject<T>& operator=(const ScopedGObject<T>& other) { + g_object_ref(other.obj_); + g_object_unref(obj_); + obj_ = other.obj_; + return *this; + } + + ScopedGObject<T>& operator=(ScopedGObject<T>&& other) { + g_object_unref(obj_); + obj_ = other.obj_; + other.obj_ = nullptr; + return *this; + } + + operator T*() { return obj_; } + + private: + T* obj_; +}; + +typedef ScopedGObject<GtkStyleContext> ScopedStyleContext; + +// Parses |css_selector| into a GtkStyleContext. The format is a +// sequence of whitespace-separated objects. Each object may have at +// most one object name at the beginning of the string, and any number +// of '.'-prefixed classes and ':'-prefixed pseudoclasses. An example +// is "GtkButton.button.suggested-action:hover:active". The caller +// must g_object_unref() the returned context. +ScopedStyleContext GetStyleContextFromCss(const char* css_selector); + +// Get the 'color' property from the style context created by +// GetStyleContextFromCss(|css_selector|). +SkColor GetFGColor(const char* css_selector); + +// Renders a background from the style context created by +// GetStyleContextFromCss(|css_selector|) into a single pixel and +// returns the color. +SkColor GetBGColor(const char* css_selector); + +// If there is a border, renders the border from the style context +// created by GetStyleContextFromCss(|css_selector|) into a single +// pixel and returns the color. Otherwise returns kInvalidColor. +SkColor GetBorderColor(const char* css_selector); +#endif + } // namespace libgtkui #endif // CHROME_BROWSER_UI_LIBGTKUI_GTK_UTIL_H_
diff --git a/chrome/browser/ui/libgtkui/native_theme_gtk3.cc b/chrome/browser/ui/libgtkui/native_theme_gtk3.cc index 097b80a..b91c783b 100644 --- a/chrome/browser/ui/libgtkui/native_theme_gtk3.cc +++ b/chrome/browser/ui/libgtkui/native_theme_gtk3.cc
@@ -6,12 +6,11 @@ #include <gtk/gtk.h> -#include "base/strings/string_split.h" -#include "base/strings/string_util.h" #include "chrome/browser/ui/libgtkui/chrome_gtk_frame.h" #include "chrome/browser/ui/libgtkui/chrome_gtk_menu_subclasses.h" #include "chrome/browser/ui/libgtkui/gtk_util.h" #include "chrome/browser/ui/libgtkui/skia_utils_gtk.h" +#include "ui/gfx/color_palette.h" #include "ui/gfx/color_utils.h" #include "ui/gfx/geometry/rect.h" #include "ui/native_theme/native_theme_dark_aura.h" @@ -20,92 +19,6 @@ namespace { -enum WidgetState { - NORMAL = 0, - ACTIVE = 1, - PRELIGHT = 2, - SELECTED = 3, - INSENSITIVE = 4, -}; - -// Same order as enum WidgetState above -const GtkStateFlags stateMap[] = { - GTK_STATE_FLAG_NORMAL, GTK_STATE_FLAG_ACTIVE, - GTK_STATE_FLAG_PRELIGHT, GTK_STATE_FLAG_SELECTED, - GTK_STATE_FLAG_INSENSITIVE, -}; - -// The caller must g_object_unref the returned context. -GtkStyleContext* GetStyleContextFromCss(const char* css_selector) { - GtkWidgetPath* path = gtk_widget_path_new(); - for (const auto& widget_type : - base::SplitString(css_selector, base::kWhitespaceASCII, - base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) { - gtk_widget_path_append_type(path, G_TYPE_NONE); - for (const auto& widget_class : - base::SplitString(widget_type, ".", base::TRIM_WHITESPACE, - base::SPLIT_WANT_NONEMPTY)) { - gtk_widget_path_iter_add_class(path, -1, widget_class.c_str()); - } - } - - GtkStyleContext* context = gtk_style_context_new(); - gtk_style_context_set_path(context, path); - gtk_widget_path_unref(path); - return context; -} - -SkColor GdkRgbaToSkColor(const GdkRGBA& color) { - return SkColorSetARGB(color.alpha * 255, color.red * 255, color.green * 255, - color.blue * 255); -} - -SkColor ColorFromContext(GtkStyleContext* context, - GtkStateFlags state, - const char* color_name) { - GdkRGBA* color = nullptr; - gtk_style_context_get(context, state, color_name, &color, nullptr); - DCHECK(color); - SkColor sk_color = GdkRgbaToSkColor(*color); - gdk_rgba_free(color); - return sk_color; -} - -SkColor GetFGColor(GtkWidget* widget, WidgetState state) { - return ColorFromContext(gtk_widget_get_style_context(widget), stateMap[state], - "color"); -} - -SkColor GetBGColor(GtkWidget* widget, WidgetState state) { - return ColorFromContext(gtk_widget_get_style_context(widget), stateMap[state], - "background-color"); -} - -SkColor GetFGColor(const char* css_selector, GtkStateFlags state) { - GtkStyleContext* context = GetStyleContextFromCss(css_selector); - SkColor color = ColorFromContext(context, state, "color"); - g_object_unref(context); - return color; -} - -SkColor GetBGColor(const char* css_selector, GtkStateFlags state) { - GtkStyleContext* context = GetStyleContextFromCss(css_selector); - SkColor color = ColorFromContext(context, state, "background-color"); - g_object_unref(context); - return color; -} - -SkColor GetBorderColor(const char* css_selector, GtkStateFlags state) { - GtkStyleContext* context = GetStyleContextFromCss(css_selector); - GtkBorder border; - gtk_style_context_get_border(context, state, &border); - bool has_border = border.left || border.right || border.top || border.bottom; - SkColor color = ColorFromContext( - context, state, has_border ? "border-color" : "background-color"); - g_object_unref(context); - return color; -} - void PaintWidget(SkCanvas* canvas, const gfx::Rect& rect, const char* css_selector, @@ -120,7 +33,7 @@ cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, rect.width())); cairo_t* cr = cairo_create(surface); - GtkStyleContext* context = GetStyleContextFromCss(css_selector); + auto context = GetStyleContextFromCss(css_selector); gtk_style_context_set_state(context, state); gtk_render_background(context, cr, 0, 0, rect.width(), rect.height()); @@ -128,8 +41,6 @@ cairo_destroy(cr); cairo_surface_destroy(surface); canvas->drawBitmap(bitmap, rect.x(), rect.y()); - - g_object_unref(context); } GtkStateFlags StateToStateFlags(NativeThemeGtk3::State state) { @@ -149,6 +60,232 @@ } } +SkColor SkColorFromColorId(ui::NativeTheme::ColorId color_id) { + const SkColor kPositiveTextColor = SkColorSetRGB(0x0b, 0x80, 0x43); + const SkColor kNegativeTextColor = SkColorSetRGB(0xc5, 0x39, 0x29); + + switch (color_id) { + // Windows + case ui::NativeTheme::kColorId_WindowBackground: + // Dialogs + case ui::NativeTheme::kColorId_DialogBackground: + case ui::NativeTheme::kColorId_BubbleBackground: + return GetBGColor(""); + + // FocusableBorder + case ui::NativeTheme::kColorId_FocusedBorderColor: + return GetBorderColor("GtkEntry.entry:focus"); + case ui::NativeTheme::kColorId_UnfocusedBorderColor: + return GetBorderColor("GtkEntry.entry"); + + // Menu + case ui::NativeTheme::kColorId_MenuBackgroundColor: + return GetBGColor("GtkMenu.menu"); + case ui::NativeTheme::kColorId_MenuBorderColor: + return GetBorderColor("GtkMenu.menu"); + case ui::NativeTheme::kColorId_FocusedMenuItemBackgroundColor: + return GetBGColor("GtkMenu.menu GtkMenuItem.menuitem:focus"); + case ui::NativeTheme::kColorId_EnabledMenuItemForegroundColor: + return GetFGColor("GtkMenu.menu GtkMenuItem.menuitem GtkLabel.label"); + case ui::NativeTheme::kColorId_SelectedMenuItemForegroundColor: + return GetFGColor( + "GtkMenu.menu GtkMenuItem.menuitem:selected GtkLabel.label"); + case ui::NativeTheme::kColorId_DisabledMenuItemForegroundColor: + return GetFGColor( + "GtkMenu.menu GtkMenuItem.menuitem:disabled GtkLabel.label"); + case ui::NativeTheme::kColorId_MenuItemSubtitleColor: + return GetFGColor( + "GtkMenu.menu GtkMenuItem.menuitem GtkLabel.label.accelerator"); + case ui::NativeTheme::kColorId_MenuSeparatorColor: + // MenuButton borders are used the same way as menu separators in Chrome. + case ui::NativeTheme::kColorId_EnabledMenuButtonBorderColor: + case ui::NativeTheme::kColorId_FocusedMenuButtonBorderColor: + case ui::NativeTheme::kColorId_HoverMenuButtonBorderColor: + return GetFGColor("GtkMenu.menu GtkMenuItem.menuitem.separator:disabled"); + + // Label + case ui::NativeTheme::kColorId_LabelEnabledColor: + return GetFGColor("GtkLabel.label"); + case ui::NativeTheme::kColorId_LabelDisabledColor: + return GetFGColor("GtkLabel.label:disabled"); + case ui::NativeTheme::kColorId_LabelTextSelectionColor: + return GetFGColor("GtkLabel.label .selection:selected"); + case ui::NativeTheme::kColorId_LabelTextSelectionBackgroundFocused: + return GetBGColor("GtkLabel.label .selection:selected"); + + // Link + case ui::NativeTheme::kColorId_LinkDisabled: + return SkColorSetA( + SkColorFromColorId(ui::NativeTheme::kColorId_LinkEnabled), 0xBB); + case ui::NativeTheme::kColorId_LinkPressed: + case ui::NativeTheme::kColorId_LinkEnabled: { + // TODO(thomasanderson): Gtk changed the way links are colored in 3.12. + // Add code for later versions. + auto link_context = GetStyleContextFromCss("GtkLabel.label.view"); + GdkColor* color; + gtk_style_context_get_style(link_context, "link-color", &color, nullptr); + if (color) { + SkColor ret_color = SkColorSetRGB(color->red / 255, color->green / 255, + color->blue / 255); + gdk_color_free(color); + return ret_color; + } else { + // Default color comes from gtklinkbutton.c. + return SkColorSetRGB(0x00, 0x00, 0xEE); + } + } + + // Button + case ui::NativeTheme::kColorId_ButtonEnabledColor: + return GetFGColor("GtkButton.button.text-button GtkLabel.label"); + case ui::NativeTheme::kColorId_ButtonDisabledColor: + return GetFGColor("GtkButton.button.text-button:disabled GtkLabel.label"); + case ui::NativeTheme::kColorId_ButtonHoverColor: + return GetFGColor("GtkButton.button.text-button:hover GtkLabel.label"); + case ui::NativeTheme::kColorId_ButtonPressedShade: + return SK_ColorTRANSPARENT; + + case ui::NativeTheme::kColorId_BlueButtonEnabledColor: + return GetFGColor( + "GtkButton.button.text-button.suggested-action GtkLabel.label"); + case ui::NativeTheme::kColorId_BlueButtonDisabledColor: + return GetFGColor( + "GtkButton.button.text-button.suggested-action:disabled " + "GtkLabel.label"); + case ui::NativeTheme::kColorId_BlueButtonHoverColor: + return GetFGColor( + "GtkButton.button.text-button.suggested-action:hover GtkLabel.label"); + case ui::NativeTheme::kColorId_BlueButtonPressedColor: + return GetFGColor( + "GtkButton.button.text-button.suggested-action:hover:active " + "GtkLabel.label"); + case ui::NativeTheme::kColorId_BlueButtonShadowColor: + return SK_ColorTRANSPARENT; + + case ui::NativeTheme::kColorId_ProminentButtonColor: + return GetBGColor("GtkButton.button.text-button.destructive-action"); + case ui::NativeTheme::kColorId_TextOnProminentButtonColor: + return GetFGColor( + "GtkButton.button.text-button.destructive-action GtkLabel.label"); + + // Textfield + case ui::NativeTheme::kColorId_TextfieldDefaultColor: + return GetFGColor("GtkEntry.entry"); + case ui::NativeTheme::kColorId_TextfieldDefaultBackground: + return GetBGColor("GtkEntry.entry"); + case ui::NativeTheme::kColorId_TextfieldReadOnlyColor: + return GetFGColor("GtkEntry.entry:disabled"); + case ui::NativeTheme::kColorId_TextfieldReadOnlyBackground: + return GetBGColor("GtkEntry.entry:disabled"); + case ui::NativeTheme::kColorId_TextfieldSelectionColor: + return GetFGColor("GtkEntry.entry .selection:selected"); + case ui::NativeTheme::kColorId_TextfieldSelectionBackgroundFocused: + return GetBGColor("GtkEntry.entry .selection:selected"); + + // Tooltips + case ui::NativeTheme::kColorId_TooltipBackground: + return GetBGColor("GtkTooltip.tooltip"); + case ui::NativeTheme::kColorId_TooltipText: + return color_utils::GetReadableColor(GetFGColor("GtkTooltip.tooltip"), + GetBGColor("GtkTooltip.tooltip")); + + // Trees and Tables (implemented on GTK using the same class) + case ui::NativeTheme::kColorId_TableBackground: + case ui::NativeTheme::kColorId_TreeBackground: + return GetBGColor("GtkTreeView.view"); + case ui::NativeTheme::kColorId_TableText: + case ui::NativeTheme::kColorId_TreeText: + case ui::NativeTheme::kColorId_TreeArrow: + case ui::NativeTheme::kColorId_TableGroupingIndicatorColor: + return GetFGColor("GtkTreeView.view .cell"); + case ui::NativeTheme::kColorId_TableSelectedText: + case ui::NativeTheme::kColorId_TableSelectedTextUnfocused: + case ui::NativeTheme::kColorId_TreeSelectedText: + case ui::NativeTheme::kColorId_TreeSelectedTextUnfocused: + return GetFGColor("GtkTreeView.view .cell:selected"); + case ui::NativeTheme::kColorId_TableSelectionBackgroundFocused: + case ui::NativeTheme::kColorId_TableSelectionBackgroundUnfocused: + case ui::NativeTheme::kColorId_TreeSelectionBackgroundFocused: + case ui::NativeTheme::kColorId_TreeSelectionBackgroundUnfocused: + return GetBGColor("GtkTreeView.view .cell:selected"); + + // Results Table + // TODO(thomasanderson): The GtkEntry selectors was how the gtk2 theme got + // these colors. Update this code to use a different widget. + case ui::NativeTheme::kColorId_ResultsTableNormalBackground: + return GetBGColor("GtkEntry.entry"); + case ui::NativeTheme::kColorId_ResultsTableHoveredBackground: + return color_utils::AlphaBlend( + GetBGColor("GtkEntry.entry"), + GetBGColor("GtkEntry.entry .selection:selected"), 0x80); + case ui::NativeTheme::kColorId_ResultsTableSelectedBackground: + return GetBGColor("GtkEntry.entry .selection:selected"); + case ui::NativeTheme::kColorId_ResultsTableNormalText: + case ui::NativeTheme::kColorId_ResultsTableHoveredText: + return GetFGColor("GtkEntry.entry"); + case ui::NativeTheme::kColorId_ResultsTableSelectedText: + return GetFGColor("GtkEntry.entry .selection:selected"); + case ui::NativeTheme::kColorId_ResultsTableNormalDimmedText: + case ui::NativeTheme::kColorId_ResultsTableHoveredDimmedText: + return color_utils::AlphaBlend(GetFGColor("GtkEntry.entry"), + GetBGColor("GtkEntry.entry"), 0x80); + case ui::NativeTheme::kColorId_ResultsTableSelectedDimmedText: + return color_utils::AlphaBlend( + GetFGColor("GtkEntry.entry .selection:selected"), + GetBGColor("GtkEntry.entry"), 0x80); + case ui::NativeTheme::kColorId_ResultsTableNormalUrl: + case ui::NativeTheme::kColorId_ResultsTableHoveredUrl: + return NormalURLColor(GetFGColor("GtkEntry.entry")); + case ui::NativeTheme::kColorId_ResultsTableSelectedUrl: + return SelectedURLColor(GetFGColor("GtkEntry.entry .selection:selected"), + GetBGColor("GtkEntry.entry .selection:selected")); + + case ui::NativeTheme::kColorId_ResultsTablePositiveText: + return color_utils::GetReadableColor(kPositiveTextColor, + GetBGColor("GtkEntry.entry")); + case ui::NativeTheme::kColorId_ResultsTablePositiveHoveredText: + return color_utils::GetReadableColor(kPositiveTextColor, + GetBGColor("GtkEntry.entry:hover")); + case ui::NativeTheme::kColorId_ResultsTablePositiveSelectedText: + return color_utils::GetReadableColor( + kPositiveTextColor, GetBGColor("GtkEntry.entry:selected")); + case ui::NativeTheme::kColorId_ResultsTableNegativeText: + return color_utils::GetReadableColor(kNegativeTextColor, + GetBGColor("GtkEntry.entry")); + case ui::NativeTheme::kColorId_ResultsTableNegativeHoveredText: + return color_utils::GetReadableColor(kNegativeTextColor, + GetBGColor("GtkEntry.entry:hover")); + case ui::NativeTheme::kColorId_ResultsTableNegativeSelectedText: + return color_utils::GetReadableColor( + kNegativeTextColor, GetBGColor("GtkEntry.entry:selected")); + + // Throbber + // TODO(thomasanderson): Render GtkSpinner directly. + case ui::NativeTheme::kColorId_ThrobberSpinningColor: + case ui::NativeTheme::kColorId_ThrobberWaitingColor: + return GetFGColor("GtkMenu.menu GtkSpinner.spinner"); + case ui::NativeTheme::kColorId_ThrobberLightColor: + return GetFGColor("GtkMenu.menu GtkSpinner.spinner:disabled"); + + // Alert icons + case ui::NativeTheme::kColorId_AlertSeverityLow: + return GetBGColor("GtkInfoBar.infobar.info"); + case ui::NativeTheme::kColorId_AlertSeverityMedium: + return GetBGColor("GtkInfoBar.infobar.warning"); + case ui::NativeTheme::kColorId_AlertSeverityHigh: + return GetBGColor("GtkInfoBar.infobar.error"); + + case ui::NativeTheme::kColorId_NumColors: + NOTREACHED(); + break; + } + return kInvalidColorIdColor; +} + +void OnThemeChanged(GObject* obj, GParamSpec* param, NativeThemeGtk3* theme) { + theme->ResetColorCache(); +} + } // namespace // static @@ -158,242 +295,50 @@ } // Constructors automatically called -NativeThemeGtk3::NativeThemeGtk3() {} +NativeThemeGtk3::NativeThemeGtk3() { + // These types are needed by g_type_from_name(), but may not be registered at + // this point. We need the g_type_class magic to make sure the compiler + // doesn't optimize away this code. + g_type_class_unref(g_type_class_ref(gtk_button_get_type())); + g_type_class_unref(g_type_class_ref(gtk_label_get_type())); + g_type_class_unref(g_type_class_ref(gtk_window_get_type())); + g_type_class_unref(g_type_class_ref(gtk_link_button_get_type())); + g_type_class_unref(g_type_class_ref(gtk_spinner_get_type())); + g_type_class_unref(g_type_class_ref(gtk_menu_get_type())); + g_type_class_unref(g_type_class_ref(gtk_menu_item_get_type())); + g_type_class_unref(g_type_class_ref(gtk_entry_get_type())); + g_type_class_unref(g_type_class_ref(gtk_info_bar_get_type())); + g_type_class_unref(g_type_class_ref(gtk_tooltip_get_type())); + g_type_class_unref(g_type_class_ref(gtk_scrollbar_get_type())); + g_type_class_unref(g_type_class_ref(gtk_toolbar_get_type())); + g_type_class_unref(g_type_class_ref(gtk_text_view_get_type())); + + g_signal_connect_after(gtk_settings_get_default(), "notify::gtk-theme-name", + G_CALLBACK(OnThemeChanged), this); +} + // This doesn't actually get called NativeThemeGtk3::~NativeThemeGtk3() {} -SkColor NativeThemeGtk3::LookupGtkThemeColor(ColorId color_id) const { - const SkColor kPositiveTextColor = SkColorSetRGB(0x0b, 0x80, 0x43); - const SkColor kNegativeTextColor = SkColorSetRGB(0xc5, 0x39, 0x29); - - switch (color_id) { - // Windows - case kColorId_WindowBackground: - return GetBGColor(GetWindow(), SELECTED); - - // Dialogs - case kColorId_DialogBackground: - case kColorId_BubbleBackground: - return GetBGColor(GetWindow(), NORMAL); - - // FocusableBorder - case kColorId_FocusedBorderColor: - return GetBGColor(GetEntry(), SELECTED); - case kColorId_UnfocusedBorderColor: - return GetFGColor(GetEntry(), NORMAL); - - // Menu - case kColorId_MenuBackgroundColor: - return GetBGColor("menu", GTK_STATE_FLAG_NORMAL); - case kColorId_MenuBorderColor: - return GetBorderColor("menu", GTK_STATE_FLAG_NORMAL); - case kColorId_FocusedMenuItemBackgroundColor: - return GetBGColor("menu menuitem", GTK_STATE_FLAG_FOCUSED); - case kColorId_EnabledMenuItemForegroundColor: - return GetFGColor("menu menuitem label", GTK_STATE_FLAG_NORMAL); - case kColorId_SelectedMenuItemForegroundColor: - return GetFGColor("menu menuitem label", GTK_STATE_FLAG_SELECTED); - case kColorId_DisabledMenuItemForegroundColor: - return GetFGColor("menu menuitem label", GTK_STATE_FLAG_INSENSITIVE); - case kColorId_MenuItemSubtitleColor: - return GetFGColor("menu menuitem accelerator", GTK_STATE_FLAG_NORMAL); - case kColorId_MenuSeparatorColor: - // MenuButton borders are used the same way as menu separtors in Chrome. - case kColorId_EnabledMenuButtonBorderColor: - case kColorId_FocusedMenuButtonBorderColor: - case kColorId_HoverMenuButtonBorderColor: - return GetFGColor("menu menuitem.separator", GTK_STATE_FLAG_INSENSITIVE); - - // Label - case kColorId_LabelEnabledColor: - return GetFGColor(GetEntry(), NORMAL); - case kColorId_LabelDisabledColor: - return GetFGColor(GetLabel(), INSENSITIVE); - case kColorId_LabelTextSelectionColor: - return GetFGColor(GetLabel(), SELECTED); - case kColorId_LabelTextSelectionBackgroundFocused: - return GetBGColor(GetLabel(), SELECTED); - - // Link - case kColorId_LinkDisabled: - return SkColorSetA(GetSystemColor(kColorId_LinkEnabled), 0xBB); - case kColorId_LinkEnabled: { - SkColor link_color = SK_ColorTRANSPARENT; - GdkColor* style_color = nullptr; - gtk_widget_style_get(GetWindow(), "link-color", &style_color, nullptr); - if (style_color) { - link_color = GdkColorToSkColor(*style_color); - gdk_color_free(style_color); - } - if (link_color != SK_ColorTRANSPARENT) - return link_color; - // Default color comes from gtklinkbutton.c. - return SkColorSetRGB(0x00, 0x00, 0xEE); - } - case kColorId_LinkPressed: - return SK_ColorRED; - - // Button - case kColorId_ButtonEnabledColor: - return GetFGColor(GetButton(), NORMAL); - case kColorId_BlueButtonEnabledColor: - return GetFGColor(GetBlueButton(), NORMAL); - case kColorId_ButtonDisabledColor: - return GetFGColor(GetButton(), INSENSITIVE); - case kColorId_BlueButtonDisabledColor: - return GetFGColor(GetBlueButton(), INSENSITIVE); - case kColorId_ButtonHoverColor: - return GetFGColor(GetButton(), PRELIGHT); - case kColorId_BlueButtonHoverColor: - return GetFGColor(GetBlueButton(), PRELIGHT); - case kColorId_BlueButtonPressedColor: - return GetFGColor(GetBlueButton(), ACTIVE); - case kColorId_BlueButtonShadowColor: - return SK_ColorTRANSPARENT; - case kColorId_ProminentButtonColor: - return GetSystemColor(kColorId_LinkEnabled); - case kColorId_TextOnProminentButtonColor: - return GetFGColor(GetLabel(), SELECTED); - case kColorId_ButtonPressedShade: - return SK_ColorTRANSPARENT; - - // Textfield - case kColorId_TextfieldDefaultColor: - return GetFGColor(GetEntry(), NORMAL); - case kColorId_TextfieldDefaultBackground: - return GetBGColor(GetEntry(), NORMAL); - - case kColorId_TextfieldReadOnlyColor: - return GetFGColor(GetEntry(), SELECTED); - case kColorId_TextfieldReadOnlyBackground: - return GetBGColor(GetEntry(), SELECTED); - case kColorId_TextfieldSelectionColor: - return GetFGColor(GetLabel(), SELECTED); - case kColorId_TextfieldSelectionBackgroundFocused: - return GetBGColor(GetLabel(), SELECTED); - - // Tooltips - case kColorId_TooltipBackground: - return GetBGColor(GetTooltip(), NORMAL); - case kColorId_TooltipText: - return GetFGColor(GetTooltip(), NORMAL); - - // Trees and Tables (implemented on GTK using the same class) - case kColorId_TableBackground: - case kColorId_TreeBackground: - return GetBGColor(GetTree(), NORMAL); - case kColorId_TableText: - case kColorId_TreeText: - return GetFGColor(GetTree(), NORMAL); - case kColorId_TableSelectedText: - case kColorId_TableSelectedTextUnfocused: - case kColorId_TreeSelectedText: - case kColorId_TreeSelectedTextUnfocused: - return GetFGColor(GetTree(), SELECTED); - case kColorId_TableSelectionBackgroundFocused: - case kColorId_TableSelectionBackgroundUnfocused: - case kColorId_TreeSelectionBackgroundFocused: - case kColorId_TreeSelectionBackgroundUnfocused: - return GetBGColor(GetTree(), SELECTED); - case kColorId_TreeArrow: - return GetFGColor(GetTree(), NORMAL); - case kColorId_TableGroupingIndicatorColor: - return GetFGColor(GetTree(), NORMAL); - - // Results Table - case kColorId_ResultsTableNormalBackground: - return GetSystemColor(kColorId_TextfieldDefaultBackground); - case kColorId_ResultsTableHoveredBackground: - return color_utils::AlphaBlend( - GetSystemColor(kColorId_TextfieldDefaultBackground), - GetSystemColor(kColorId_TextfieldSelectionBackgroundFocused), 0x80); - case kColorId_ResultsTableSelectedBackground: - return GetSystemColor(kColorId_TextfieldSelectionBackgroundFocused); - case kColorId_ResultsTableNormalText: - case kColorId_ResultsTableHoveredText: - return GetSystemColor(kColorId_TextfieldDefaultColor); - case kColorId_ResultsTableSelectedText: - return GetSystemColor(kColorId_TextfieldSelectionColor); - case kColorId_ResultsTableNormalDimmedText: - case kColorId_ResultsTableHoveredDimmedText: - return color_utils::AlphaBlend( - GetSystemColor(kColorId_TextfieldDefaultColor), - GetSystemColor(kColorId_TextfieldDefaultBackground), 0x80); - case kColorId_ResultsTableSelectedDimmedText: - return color_utils::AlphaBlend( - GetSystemColor(kColorId_TextfieldSelectionColor), - GetSystemColor(kColorId_TextfieldDefaultBackground), 0x80); - case kColorId_ResultsTableNormalUrl: - case kColorId_ResultsTableHoveredUrl: - return NormalURLColor(GetSystemColor(kColorId_TextfieldDefaultColor)); - - case kColorId_ResultsTableSelectedUrl: - return SelectedURLColor( - GetSystemColor(kColorId_TextfieldSelectionColor), - GetSystemColor(kColorId_TextfieldSelectionBackgroundFocused)); - - case kColorId_ResultsTablePositiveText: - return color_utils::GetReadableColor(kPositiveTextColor, - GetBGColor(GetEntry(), NORMAL)); - case kColorId_ResultsTablePositiveHoveredText: - return color_utils::GetReadableColor(kPositiveTextColor, - GetBGColor(GetEntry(), PRELIGHT)); - case kColorId_ResultsTablePositiveSelectedText: - return color_utils::GetReadableColor(kPositiveTextColor, - GetBGColor(GetEntry(), SELECTED)); - case kColorId_ResultsTableNegativeText: - return color_utils::GetReadableColor(kNegativeTextColor, - GetBGColor(GetEntry(), NORMAL)); - case kColorId_ResultsTableNegativeHoveredText: - return color_utils::GetReadableColor(kNegativeTextColor, - GetBGColor(GetEntry(), PRELIGHT)); - case kColorId_ResultsTableNegativeSelectedText: - return color_utils::GetReadableColor(kNegativeTextColor, - GetBGColor(GetEntry(), SELECTED)); - - // Throbber - case kColorId_ThrobberSpinningColor: - case kColorId_ThrobberLightColor: - return GetSystemColor(kColorId_TextfieldSelectionBackgroundFocused); - - case kColorId_ThrobberWaitingColor: - return color_utils::AlphaBlend( - GetSystemColor(kColorId_TextfieldSelectionBackgroundFocused), - GetBGColor(GetWindow(), NORMAL), 0x80); - - // Alert icons - // Just fall back to the same colors as Aura. - case kColorId_AlertSeverityLow: - case kColorId_AlertSeverityMedium: - case kColorId_AlertSeverityHigh: - return SK_ColorTRANSPARENT; - - case kColorId_NumColors: - NOTREACHED(); - break; - } - - return kInvalidColorIdColor; +void NativeThemeGtk3::ResetColorCache() { + for (auto& color : color_cache_) + color = base::nullopt; } SkColor NativeThemeGtk3::GetSystemColor(ColorId color_id) const { - SkColor color = LookupGtkThemeColor(color_id); - if (SkColorGetA(color)) - return color; - gboolean prefer_dark_theme = FALSE; - g_object_get(gtk_settings_get_default(), "gtk-application-prefer-dark-theme", - &prefer_dark_theme, nullptr); - ui::NativeTheme* fallback_theme = - prefer_dark_theme ? ui::NativeThemeDarkAura::instance() - : ui::NativeTheme::GetInstanceForNativeUi(); - return fallback_theme->GetSystemColor(color_id); + if (color_cache_[color_id]) + return color_cache_[color_id].value(); + + SkColor color = SkColorFromColorId(color_id); + color_cache_[color_id] = color; + return color; } void NativeThemeGtk3::PaintMenuPopupBackground( SkCanvas* canvas, const gfx::Size& size, const MenuBackgroundExtraParams& menu_background) const { - PaintWidget(canvas, gfx::Rect(size), "menu", GTK_STATE_FLAG_NORMAL); + PaintWidget(canvas, gfx::Rect(size), "GtkMenu.menu", GTK_STATE_FLAG_NORMAL); } void NativeThemeGtk3::PaintMenuItemBackground( @@ -401,103 +346,8 @@ State state, const gfx::Rect& rect, const MenuItemExtraParams& menu_item) const { - PaintWidget(canvas, rect, "menu menuitem", StateToStateFlags(state)); -} - -GtkWidget* NativeThemeGtk3::GetWindow() const { - static GtkWidget* fake_window = NULL; - - if (!fake_window) { - fake_window = chrome_gtk_frame_new(); - gtk_widget_realize(fake_window); - } - - return fake_window; -} - -GtkWidget* NativeThemeGtk3::GetEntry() const { - static GtkWidget* fake_entry = NULL; - - if (!fake_entry) { - fake_entry = gtk_entry_new(); - - // The fake entry needs to be in the window so it can be realized so we can - // use the computed parts of the style. - gtk_container_add(GTK_CONTAINER(GetWindow()), fake_entry); - gtk_widget_realize(fake_entry); - } - - return fake_entry; -} - -GtkWidget* NativeThemeGtk3::GetLabel() const { - static GtkWidget* fake_label = NULL; - - if (!fake_label) - fake_label = gtk_label_new(""); - - return fake_label; -} - -GtkWidget* NativeThemeGtk3::GetButton() const { - static GtkWidget* fake_button = NULL; - - if (!fake_button) - fake_button = gtk_button_new(); - - return fake_button; -} - -GtkWidget* NativeThemeGtk3::GetBlueButton() const { - static GtkWidget* fake_bluebutton = NULL; - - if (!fake_bluebutton) { - fake_bluebutton = gtk_button_new(); - TurnButtonBlue(fake_bluebutton); - } - - return fake_bluebutton; -} - -GtkWidget* NativeThemeGtk3::GetTree() const { - static GtkWidget* fake_tree = NULL; - - if (!fake_tree) - fake_tree = gtk_tree_view_new(); - - return fake_tree; -} - -GtkWidget* NativeThemeGtk3::GetTooltip() const { - static GtkWidget* fake_tooltip = NULL; - - if (!fake_tooltip) { - fake_tooltip = gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_widget_set_name(fake_tooltip, "gtk-tooltip"); - gtk_widget_realize(fake_tooltip); - } - - return fake_tooltip; -} - -GtkWidget* NativeThemeGtk3::GetMenu() const { - static GtkWidget* fake_menu = NULL; - - if (!fake_menu) - fake_menu = gtk_custom_menu_new(); - - return fake_menu; -} - -GtkWidget* NativeThemeGtk3::GetMenuItem() const { - static GtkWidget* fake_menu_item = NULL; - - if (!fake_menu_item) { - fake_menu_item = gtk_custom_menu_item_new(); - gtk_menu_shell_append(GTK_MENU_SHELL(GetMenu()), fake_menu_item); - } - - return fake_menu_item; + PaintWidget(canvas, rect, "GtkMenu.menu GtkMenuItem.menuitem", + StateToStateFlags(state)); } } // namespace libgtkui
diff --git a/chrome/browser/ui/libgtkui/native_theme_gtk3.h b/chrome/browser/ui/libgtkui/native_theme_gtk3.h index 72920a5..577375ce 100644 --- a/chrome/browser/ui/libgtkui/native_theme_gtk3.h +++ b/chrome/browser/ui/libgtkui/native_theme_gtk3.h
@@ -6,10 +6,9 @@ #define CHROME_BROWSER_UI_LIBGTKUI_NATIVE_THEME_GTK3_H_ #include "base/macros.h" +#include "base/optional.h" #include "ui/native_theme/native_theme_base.h" -typedef struct _GtkWidget GtkWidget; - namespace libgtkui { // A version of NativeTheme that uses GTK3-rendered widgets. @@ -17,6 +16,9 @@ public: static NativeThemeGtk3* instance(); + // Called when gtk theme changes. + void ResetColorCache(); + // Overridden from ui::NativeThemeBase: SkColor GetSystemColor(ColorId color_id) const override; void PaintMenuPopupBackground( @@ -33,19 +35,7 @@ NativeThemeGtk3(); ~NativeThemeGtk3() override; - SkColor LookupGtkThemeColor(ColorId color_id) const; - - // Returns various widgets for theming use. - // TODO(thomasanderson): Remove all of these. - GtkWidget* GetWindow() const; - GtkWidget* GetEntry() const; - GtkWidget* GetLabel() const; - GtkWidget* GetButton() const; - GtkWidget* GetBlueButton() const; - GtkWidget* GetTree() const; - GtkWidget* GetTooltip() const; - GtkWidget* GetMenu() const; - GtkWidget* GetMenuItem() const; + mutable base::Optional<SkColor> color_cache_[kColorId_NumColors]; DISALLOW_COPY_AND_ASSIGN(NativeThemeGtk3); };
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index f899ab13..ab0ced4f 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -667,6 +667,8 @@ "//ash/resources", "//chrome/browser/media/router:test_support", "//chromeos", + "//mojo/edk/system", + "//ui/app_list/presenter:test_support", ] data += [ @@ -770,6 +772,7 @@ if (use_ash) { sources += [ + "../browser/ui/ash/app_list/app_list_interactive_uitest.cc", "../browser/ui/views/ash/tab_scrubber_browsertest.cc", "../browser/ui/window_sizer/window_sizer_ash_uitest.cc", "//ash/drag_drop/drag_drop_interactive_uitest.cc",
diff --git a/chromeos/components/tether/BUILD.gn b/chromeos/components/tether/BUILD.gn index 6856664..b187e2b8 100644 --- a/chromeos/components/tether/BUILD.gn +++ b/chromeos/components/tether/BUILD.gn
@@ -10,6 +10,8 @@ "ble_advertisement_device_queue.h", "ble_constants.cc", "ble_constants.h", + "ble_scanner.cc", + "ble_scanner.h", "host_scan_scheduler.cc", "host_scan_scheduler.h", "host_scanner.cc", @@ -25,6 +27,7 @@ "//chromeos", "//components/cryptauth", "//components/proximity_auth/logging", + "//device/bluetooth", ] public_deps = [ @@ -35,7 +38,10 @@ static_library("test_support") { testonly = true - sources = [] + sources = [ + "mock_local_device_data_provider.cc", + "mock_local_device_data_provider.h", + ] public_deps = [ ":tether", @@ -43,6 +49,7 @@ deps = [ "//base", + "//components/cryptauth", "//testing/gmock", ] } @@ -52,6 +59,7 @@ sources = [ "ble_advertisement_device_queue_unittest.cc", + "ble_scanner_unittest.cc", "host_scan_scheduler_unittest.cc", "local_device_data_provider_unittest.cc", ] @@ -63,6 +71,8 @@ "//chromeos", "//components/cryptauth", "//components/cryptauth:test_support", + "//device/bluetooth", + "//device/bluetooth:mocks", "//testing/gmock", "//testing/gtest", ]
diff --git a/chromeos/components/tether/DEPS b/chromeos/components/tether/DEPS index 093164a..14a7c43 100644 --- a/chromeos/components/tether/DEPS +++ b/chromeos/components/tether/DEPS
@@ -1,4 +1,5 @@ include_rules = [ "+components/cryptauth", "+components/proximity_auth/logging", + "+device/bluetooth", ]
diff --git a/chromeos/components/tether/ble_constants.cc b/chromeos/components/tether/ble_constants.cc index 48ca0c09..39633439 100644 --- a/chromeos/components/tether/ble_constants.cc +++ b/chromeos/components/tether/ble_constants.cc
@@ -8,7 +8,7 @@ namespace tether { -const int kMaxConcurrentAdvertisements = 2; +const uint8_t kMaxConcurrentAdvertisements = 2; const char kAdvertisingServiceUuid[] = "0000fe50-0000-1000-8000-00805f9b34fb"; } // namespace tether
diff --git a/chromeos/components/tether/ble_constants.h b/chromeos/components/tether/ble_constants.h index 25f4b01c..fadb42b40 100644 --- a/chromeos/components/tether/ble_constants.h +++ b/chromeos/components/tether/ble_constants.h
@@ -18,7 +18,7 @@ // Note that this upper limit on concurrent advertisements is imposed due to a // hardware limit of advertisements (many devices have <10 total advertisement // slots). -extern const int kMaxConcurrentAdvertisements; +extern const uint8_t kMaxConcurrentAdvertisements; // The service UUID used for BLE advertisements. extern const char kAdvertisingServiceUuid[];
diff --git a/chromeos/components/tether/ble_scanner.cc b/chromeos/components/tether/ble_scanner.cc new file mode 100644 index 0000000..fa86feb --- /dev/null +++ b/chromeos/components/tether/ble_scanner.cc
@@ -0,0 +1,312 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromeos/components/tether/ble_scanner.h" + +#include "base/bind.h" +#include "base/memory/ptr_util.h" +#include "base/strings/string_util.h" +#include "chromeos/components/tether/ble_constants.h" +#include "components/cryptauth/proto/cryptauth_api.pb.h" +#include "components/cryptauth/remote_device.h" +#include "components/proximity_auth/logging/logging.h" +#include "device/bluetooth/bluetooth_device.h" +#include "device/bluetooth/bluetooth_discovery_session.h" +#include "device/bluetooth/bluetooth_uuid.h" + +namespace chromeos { + +namespace tether { + +namespace { + +// Minimum RSSI value to use for discovery. The -90 value was determined +// empirically and is borrowed from +// |proximity_auth::BluetoothLowEnergyConnectionFinder|. +const int kMinDiscoveryRSSI = -90; + +// Valid service data must include at least 4 bytes: 2 bytes associated with the +// scanning device (used as a scan filter) and 2 bytes which identify the +// advertising device to the scanning device. +const size_t kMinNumBytesInServiceData = 4; + +// Returns out |string|s data as a hex string. +std::string StringToHexOfContents(const std::string& string) { + std::stringstream ss; + ss << "0x" << std::hex; + + for (size_t i = 0; i < string.size(); i++) { + ss << static_cast<int>(string.data()[i]); + } + + return ss.str(); +} + +} // namespace + +BleScanner::DelegateImpl::DelegateImpl() {} + +BleScanner::DelegateImpl::~DelegateImpl() {} + +bool BleScanner::DelegateImpl::IsBluetoothAdapterAvailable() const { + return device::BluetoothAdapterFactory::IsBluetoothAdapterAvailable(); +} + +void BleScanner::DelegateImpl::GetAdapter( + const device::BluetoothAdapterFactory::AdapterCallback& callback) { + device::BluetoothAdapterFactory::GetAdapter(callback); +} + +const std::vector<uint8_t>* BleScanner::DelegateImpl::GetServiceDataForUUID( + const device::BluetoothUUID& service_uuid, + device::BluetoothDevice* bluetooth_device) { + return bluetooth_device->GetServiceDataForUUID(service_uuid); +} + +BleScanner::BleScanner( + const LocalDeviceDataProvider* local_device_data_provider) + : BleScanner(base::MakeUnique<DelegateImpl>(), + cryptauth::EidGenerator::GetInstance(), + local_device_data_provider) {} + +BleScanner::~BleScanner() {} + +BleScanner::BleScanner( + std::unique_ptr<Delegate> delegate, + const cryptauth::EidGenerator* eid_generator, + const LocalDeviceDataProvider* local_device_data_provider) + : delegate_(std::move(delegate)), + eid_generator_(eid_generator), + local_device_data_provider_(local_device_data_provider), + is_initializing_adapter_(false), + is_initializing_discovery_session_(false), + discovery_session_(nullptr), + weak_ptr_factory_(this) {} + +bool BleScanner::RegisterScanFilterForDevice( + const cryptauth::RemoteDevice& remote_device) { + if (!delegate_->IsBluetoothAdapterAvailable()) { + PA_LOG(ERROR) << "Bluetooth is not supported on this platform."; + return false; + } + + if (registered_remote_devices_.size() >= kMaxConcurrentAdvertisements) { + // Each scan filter corresponds to an advertisement. Thus, the number of + // concurrent advertisements cannot exceed the maximum number of concurrent + // advertisements. + return false; + } + + std::vector<cryptauth::BeaconSeed> local_device_beacon_seeds; + if (!local_device_data_provider_->GetLocalDeviceData( + nullptr, &local_device_beacon_seeds)) { + // If the local device's beacon seeds could not be fetched, a scan filter + // cannot be generated. + return false; + } + + std::unique_ptr<cryptauth::EidGenerator::EidData> scan_filters = + eid_generator_->GenerateBackgroundScanFilter(local_device_beacon_seeds); + if (!scan_filters) { + // If a background scan filter cannot be generated, give up. + return false; + } + + registered_remote_devices_.push_back(remote_device); + UpdateDiscoveryStatus(); + + return true; +} + +bool BleScanner::UnregisterScanFilterForDevice( + const cryptauth::RemoteDevice& remote_device) { + for (auto it = registered_remote_devices_.begin(); + it != registered_remote_devices_.end(); ++it) { + if (it->GetDeviceId() == remote_device.GetDeviceId()) { + registered_remote_devices_.erase(it); + UpdateDiscoveryStatus(); + return true; + } + } + + return false; +} + +bool BleScanner::IsDeviceRegistered(const std::string& device_id) { + for (auto it = registered_remote_devices_.begin(); + it != registered_remote_devices_.end(); ++it) { + if (it->GetDeviceId() == device_id) { + return true; + } + } + + return false; +} + +void BleScanner::AddObserver(Observer* observer) { + observer_list_.AddObserver(observer); +} + +void BleScanner::RemoveObserver(Observer* observer) { + observer_list_.RemoveObserver(observer); +} + +void BleScanner::AdapterPoweredChanged(device::BluetoothAdapter* adapter, + bool powered) { + DCHECK_EQ(adapter_.get(), adapter); + PA_LOG(INFO) << "Adapter power changed. Powered = " << powered; + UpdateDiscoveryStatus(); +} + +void BleScanner::DeviceAdded(device::BluetoothAdapter* adapter, + device::BluetoothDevice* bluetooth_device) { + DCHECK_EQ(adapter_.get(), adapter); + HandleDeviceUpdated(bluetooth_device); +} + +void BleScanner::DeviceChanged(device::BluetoothAdapter* adapter, + device::BluetoothDevice* bluetooth_device) { + DCHECK_EQ(adapter_.get(), adapter); + HandleDeviceUpdated(bluetooth_device); +} + +void BleScanner::UpdateDiscoveryStatus() { + if (registered_remote_devices_.empty()) { + StopDiscoverySession(); + return; + } + + if (is_initializing_adapter_) { + return; + } else if (!adapter_) { + InitializeBluetoothAdapter(); + return; + } + + if (!adapter_->IsPowered()) { + // If the adapter has powered off, no devices can be discovered. + StopDiscoverySession(); + return; + } + + if (is_initializing_discovery_session_) { + return; + } else if (!discovery_session_ || + (discovery_session_ && !discovery_session_->IsActive())) { + StartDiscoverySession(); + } +} + +void BleScanner::InitializeBluetoothAdapter() { + PA_LOG(INFO) << "Initializing Bluetooth adapter."; + is_initializing_adapter_ = true; + delegate_->GetAdapter(base::Bind(&BleScanner::OnAdapterInitialized, + weak_ptr_factory_.GetWeakPtr())); +} + +void BleScanner::OnAdapterInitialized( + scoped_refptr<device::BluetoothAdapter> adapter) { + DCHECK(is_initializing_adapter_ && !discovery_session_ && + !is_initializing_discovery_session_); + PA_LOG(INFO) << "Bluetooth adapter initialized."; + is_initializing_adapter_ = false; + + adapter_ = adapter; + adapter_->AddObserver(this); + + UpdateDiscoveryStatus(); +} + +void BleScanner::StartDiscoverySession() { + DCHECK(adapter_); + PA_LOG(INFO) << "Starting discovery session."; + is_initializing_discovery_session_ = true; + + // Discover only low energy (LE) devices with strong enough signal. + std::unique_ptr<device::BluetoothDiscoveryFilter> filter = + base::MakeUnique<device::BluetoothDiscoveryFilter>( + device::BLUETOOTH_TRANSPORT_LE); + filter->SetRSSI(kMinDiscoveryRSSI); + + adapter_->StartDiscoverySessionWithFilter( + std::move(filter), base::Bind(&BleScanner::OnDiscoverySessionStarted, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BleScanner::OnStartDiscoverySessionError, + weak_ptr_factory_.GetWeakPtr())); +} + +void BleScanner::OnDiscoverySessionStarted( + std::unique_ptr<device::BluetoothDiscoverySession> discovery_session) { + PA_LOG(INFO) << "Discovery session started. Scanning fully initialized."; + is_initializing_discovery_session_ = false; + discovery_session_ = std::move(discovery_session); +} + +void BleScanner::OnStartDiscoverySessionError() { + PA_LOG(WARNING) << "Error starting discovery session. Initialization failed."; + is_initializing_discovery_session_ = false; +} + +void BleScanner::StopDiscoverySession() { + if (!discovery_session_) { + // If there is no discovery session to stop, return early. + return; + } + + PA_LOG(WARNING) << "Stopping discovery session."; + discovery_session_.reset(); +} + +void BleScanner::HandleDeviceUpdated( + device::BluetoothDevice* bluetooth_device) { + DCHECK(bluetooth_device); + + const std::vector<uint8_t>* service_data = delegate_->GetServiceDataForUUID( + device::BluetoothUUID(kAdvertisingServiceUuid), bluetooth_device); + if (!service_data || service_data->size() < kMinNumBytesInServiceData) { + // If there is no service data or the service data is of insufficient + // length, there is not enough information to create a connection. + return; + } + + // Convert the service data from a std::vector<uint8_t> to a std::string. + std::string service_data_str; + char* string_contents_ptr = + base::WriteInto(&service_data_str, service_data->size() + 1); + memcpy(string_contents_ptr, service_data->data(), service_data->size() + 1); + + CheckForMatchingScanFilters(bluetooth_device, service_data_str); +} + +void BleScanner::CheckForMatchingScanFilters( + device::BluetoothDevice* bluetooth_device, + std::string& service_data) { + std::vector<cryptauth::BeaconSeed> beacon_seeds; + if (!local_device_data_provider_->GetLocalDeviceData(nullptr, + &beacon_seeds)) { + // If no beacon seeds are available, the scan cannot be checked for a match. + return; + } + + const cryptauth::RemoteDevice* identified_device = + eid_generator_->IdentifyRemoteDeviceByAdvertisement( + service_data, registered_remote_devices_, beacon_seeds); + + if (identified_device) { + PA_LOG(INFO) << "Received advertisement from remote device with ID " + << identified_device->GetTruncatedDeviceIdForLogs() << "."; + for (auto& observer : observer_list_) { + observer.OnReceivedAdvertisementFromDevice(bluetooth_device, + *identified_device); + } + } else { + PA_LOG(INFO) << "Received advertisement remote device, but could not " + << "identify the device. Service data: " + << StringToHexOfContents(service_data) << "."; + } +} + +} // namespace tether + +} // namespace chromeos
diff --git a/chromeos/components/tether/ble_scanner.h b/chromeos/components/tether/ble_scanner.h new file mode 100644 index 0000000..9122c7f5 --- /dev/null +++ b/chromeos/components/tether/ble_scanner.h
@@ -0,0 +1,125 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMEOS_COMPONENTS_BLE_SCANNER_H_ +#define CHROMEOS_COMPONENTS_BLE_SCANNER_H_ + +#include <map> + +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "base/observer_list.h" +#include "chromeos/components/tether/local_device_data_provider.h" +#include "components/cryptauth/eid_generator.h" +#include "device/bluetooth/bluetooth_adapter.h" +#include "device/bluetooth/bluetooth_adapter_factory.h" + +namespace device { +class BluetoothDevice; +class BluetoothDiscoverySession; +} + +namespace chromeos { + +namespace tether { + +class BleScanner : public device::BluetoothAdapter::Observer { + public: + class Observer { + public: + virtual void OnReceivedAdvertisementFromDevice( + const device::BluetoothDevice* bluetooth_device, + cryptauth::RemoteDevice remote_device) = 0; + }; + + BleScanner(const LocalDeviceDataProvider* local_device_data_provider); + ~BleScanner() override; + + bool RegisterScanFilterForDevice( + const cryptauth::RemoteDevice& remote_device); + bool UnregisterScanFilterForDevice( + const cryptauth::RemoteDevice& remote_device); + + bool IsDeviceRegistered(const std::string& device_id); + + void AddObserver(Observer* observer); + void RemoveObserver(Observer* observer); + + // device::BluetoothAdapter::Observer + void AdapterPoweredChanged(device::BluetoothAdapter* adapter, + bool powered) override; + void DeviceAdded(device::BluetoothAdapter* adapter, + device::BluetoothDevice* bluetooth_device) override; + void DeviceChanged(device::BluetoothAdapter* adapter, + device::BluetoothDevice* bluetooth_device) override; + + private: + friend class BleScannerTest; + + class Delegate { + public: + virtual ~Delegate() {} + virtual bool IsBluetoothAdapterAvailable() const = 0; + virtual void GetAdapter( + const device::BluetoothAdapterFactory::AdapterCallback& callback) = 0; + virtual const std::vector<uint8_t>* GetServiceDataForUUID( + const device::BluetoothUUID& service_uuid, + device::BluetoothDevice* bluetooth_device) = 0; + }; + + class DelegateImpl : public Delegate { + public: + DelegateImpl(); + ~DelegateImpl() override; + bool IsBluetoothAdapterAvailable() const override; + void GetAdapter(const device::BluetoothAdapterFactory::AdapterCallback& + callback) override; + const std::vector<uint8_t>* GetServiceDataForUUID( + const device::BluetoothUUID& service_uuid, + device::BluetoothDevice* bluetooth_device) override; + }; + + BleScanner(std::unique_ptr<Delegate> delegate, + const cryptauth::EidGenerator* eid_generator, + const LocalDeviceDataProvider* local_device_data_provider); + + void UpdateDiscoveryStatus(); + void InitializeBluetoothAdapter(); + void OnAdapterInitialized(scoped_refptr<device::BluetoothAdapter> adapter); + void StartDiscoverySession(); + void OnDiscoverySessionStarted( + std::unique_ptr<device::BluetoothDiscoverySession> discovery_session); + void OnStartDiscoverySessionError(); + void StopDiscoverySession(); + void HandleDeviceUpdated(device::BluetoothDevice* bluetooth_device); + void CheckForMatchingScanFilters(device::BluetoothDevice* bluetooth_device, + std::string& service_data); + + std::unique_ptr<Delegate> delegate_; + + // |eid_generator_| and |local_device_data_provider_| are not owned by this + // instance and must outlive it. + const cryptauth::EidGenerator* eid_generator_; + const LocalDeviceDataProvider* local_device_data_provider_; + + bool is_initializing_adapter_; + scoped_refptr<device::BluetoothAdapter> adapter_; + + bool is_initializing_discovery_session_; + std::unique_ptr<device::BluetoothDiscoverySession> discovery_session_; + + std::vector<cryptauth::RemoteDevice> registered_remote_devices_; + + base::ObserverList<Observer> observer_list_; + + base::WeakPtrFactory<BleScanner> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(BleScanner); +}; + +} // namespace tether + +} // namespace chromeos + +#endif // CHROMEOS_COMPONENTS_BLE_SCANNER_H_
diff --git a/chromeos/components/tether/ble_scanner_unittest.cc b/chromeos/components/tether/ble_scanner_unittest.cc new file mode 100644 index 0000000..b2b9bbca --- /dev/null +++ b/chromeos/components/tether/ble_scanner_unittest.cc
@@ -0,0 +1,620 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromeos/components/tether/ble_scanner.h" + +#include "base/logging.h" +#include "chromeos/components/tether/ble_constants.h" +#include "chromeos/components/tether/mock_local_device_data_provider.h" +#include "components/cryptauth/mock_eid_generator.h" +#include "components/cryptauth/proto/cryptauth_api.pb.h" +#include "components/cryptauth/remote_device_test_util.h" +#include "device/bluetooth/test/mock_bluetooth_adapter.h" +#include "device/bluetooth/test/mock_bluetooth_device.h" +#include "device/bluetooth/test/mock_bluetooth_discovery_session.h" +#include "testing/gtest/include/gtest/gtest.h" + +using testing::_; +using testing::DoAll; +using testing::Eq; +using testing::Invoke; +using testing::NiceMock; +using testing::SaveArg; +using testing::Return; + +namespace chromeos { + +namespace tether { + +namespace { +class MockBleScannerObserver : public BleScanner::Observer { + public: + MockBleScannerObserver() {} + + void OnReceivedAdvertisementFromDevice( + const device::BluetoothDevice* bluetooth_device, + cryptauth::RemoteDevice remote_device) override { + bluetooth_devices_.push_back(bluetooth_device); + remote_devices_.push_back(remote_device); + } + + int GetNumCalls() { return static_cast<int>(bluetooth_devices_.size()); } + + std::vector<const device::BluetoothDevice*>& bluetooth_devices() { + return bluetooth_devices_; + } + + std::vector<cryptauth::RemoteDevice>& remote_devices() { + return remote_devices_; + } + + private: + std::vector<const device::BluetoothDevice*> bluetooth_devices_; + std::vector<cryptauth::RemoteDevice> remote_devices_; +}; + +class MockBluetoothDeviceWithServiceData : public device::MockBluetoothDevice { + public: + MockBluetoothDeviceWithServiceData(device::MockBluetoothAdapter* adapter, + const std::string& service_data) + : device::MockBluetoothDevice(adapter, + /* bluetooth_class */ 0, + "name", + "11:22:33:44:55:66", + false, + false) { + for (size_t i = 0; i < service_data.size(); i++) { + service_data_.push_back(static_cast<uint8_t>(service_data[i])); + } + } + + const std::vector<uint8_t>* service_data() { return &service_data_; } + + private: + std::vector<uint8_t> service_data_; +}; + +const int kExpectedDiscoveryRSSI = -90; +const size_t kMinNumBytesInServiceData = 4; + +const std::string fake_local_public_key = "fakeLocalPublicKey"; + +const std::string current_eid_data = "currentEidData"; +const int64_t current_eid_start_ms = 1000L; +const int64_t current_eid_end_ms = 2000L; + +const std::string adjacent_eid_data = "adjacentEidData"; +const int64_t adjacent_eid_start_ms = 2000L; +const int64_t adjacent_eid_end_ms = 3000L; + +const std::string fake_beacon_seed1_data = "fakeBeaconSeed1Data"; +const int64_t fake_beacon_seed1_start_ms = current_eid_start_ms; +const int64_t fake_beacon_seed1_end_ms = current_eid_end_ms; + +const std::string fake_beacon_seed2_data = "fakeBeaconSeed2Data"; +const int64_t fake_beacon_seed2_start_ms = adjacent_eid_start_ms; +const int64_t fake_beacon_seed2_end_ms = adjacent_eid_end_ms; + +std::unique_ptr<cryptauth::EidGenerator::EidData> +CreateFakeBackgroundScanFilter() { + cryptauth::EidGenerator::DataWithTimestamp current( + current_eid_data, current_eid_start_ms, current_eid_end_ms); + + std::unique_ptr<cryptauth::EidGenerator::DataWithTimestamp> adjacent = + base::MakeUnique<cryptauth::EidGenerator::DataWithTimestamp>( + adjacent_eid_data, adjacent_eid_start_ms, adjacent_eid_end_ms); + + return base::MakeUnique<cryptauth::EidGenerator::EidData>( + current, std::move(adjacent)); +} + +std::vector<cryptauth::BeaconSeed> CreateFakeBeaconSeeds() { + cryptauth::BeaconSeed seed1; + seed1.set_data(fake_beacon_seed1_data); + seed1.set_start_time_millis(fake_beacon_seed1_start_ms); + seed1.set_start_time_millis(fake_beacon_seed1_end_ms); + + cryptauth::BeaconSeed seed2; + seed2.set_data(fake_beacon_seed2_data); + seed2.set_start_time_millis(fake_beacon_seed2_start_ms); + seed2.set_start_time_millis(fake_beacon_seed2_end_ms); + + std::vector<cryptauth::BeaconSeed> seeds = {seed1, seed2}; + return seeds; +} +} // namespace + +class BleScannerTest : public testing::Test { + protected: + class TestDelegate : public BleScanner::Delegate { + public: + TestDelegate() + : is_bluetooth_adapter_available_(true), + last_get_adapter_callback_(nullptr) {} + + ~TestDelegate() override {} + + bool IsBluetoothAdapterAvailable() const override { + return is_bluetooth_adapter_available_; + } + + void set_is_bluetooth_adapter_available( + bool is_bluetooth_adapter_available) { + is_bluetooth_adapter_available_ = is_bluetooth_adapter_available; + } + + void GetAdapter(const device::BluetoothAdapterFactory::AdapterCallback& + callback) override { + last_get_adapter_callback_ = callback; + } + + const device::BluetoothAdapterFactory::AdapterCallback + last_get_adapter_callback() { + return last_get_adapter_callback_; + } + + const std::vector<uint8_t>* GetServiceDataForUUID( + const device::BluetoothUUID& service_uuid, + device::BluetoothDevice* bluetooth_device) override { + if (device::BluetoothUUID(kAdvertisingServiceUuid) == service_uuid) { + return reinterpret_cast<MockBluetoothDeviceWithServiceData*>( + bluetooth_device) + ->service_data(); + } + + return nullptr; + } + + private: + bool is_bluetooth_adapter_available_; + device::BluetoothAdapterFactory::AdapterCallback last_get_adapter_callback_; + }; + + BleScannerTest() + : test_devices_(cryptauth::GenerateTestRemoteDevices(3)), + test_beacon_seeds_(CreateFakeBeaconSeeds()) {} + + void SetUp() override { + test_delegate_ = new TestDelegate(); + EXPECT_TRUE(test_delegate_->IsBluetoothAdapterAvailable()); + EXPECT_FALSE(test_delegate_->last_get_adapter_callback()); + + mock_eid_generator_ = base::MakeUnique<cryptauth::MockEidGenerator>(); + mock_eid_generator_->set_background_scan_filter( + CreateFakeBackgroundScanFilter()); + + mock_local_device_data_provider_ = + base::MakeUnique<MockLocalDeviceDataProvider>(); + mock_local_device_data_provider_->SetPublicKey( + base::MakeUnique<std::string>(fake_local_public_key)); + mock_local_device_data_provider_->SetBeaconSeeds( + base::MakeUnique<std::vector<cryptauth::BeaconSeed>>( + test_beacon_seeds_)); + + mock_adapter_ = + make_scoped_refptr(new NiceMock<device::MockBluetoothAdapter>()); + stored_discovery_filter_.reset(); + stored_discovery_callback_.Reset(); + stored_discovery_errback_.Reset(); + ON_CALL(*mock_adapter_, StartDiscoverySessionWithFilterRaw(_, _, _)) + .WillByDefault(Invoke( + this, &BleScannerTest::SaveStartDiscoverySessionWithFilterArgs)); + ON_CALL(*mock_adapter_, IsPowered()).WillByDefault(Return(true)); + + mock_discovery_session_ = nullptr; + + ble_scanner_ = base::WrapUnique(new BleScanner( + base::WrapUnique(test_delegate_), mock_eid_generator_.get(), + mock_local_device_data_provider_.get())); + + mock_observer_ = base::MakeUnique<MockBleScannerObserver>(); + ble_scanner_->AddObserver(mock_observer_.get()); + } + + void SaveStartDiscoverySessionWithFilterArgs( + const device::BluetoothDiscoveryFilter* discovery_filter, + const device::BluetoothAdapter::DiscoverySessionCallback& callback, + const device::BluetoothAdapter::ErrorCallback& errback) { + stored_discovery_filter_ = + base::MakeUnique<device::BluetoothDiscoveryFilter>( + device::BluetoothTransport::BLUETOOTH_TRANSPORT_LE); + stored_discovery_filter_->CopyFrom(*discovery_filter); + stored_discovery_callback_ = callback; + stored_discovery_errback_ = errback; + } + + void InvokeAdapterCallback() { + const device::BluetoothAdapterFactory::AdapterCallback + last_get_adapter_callback = test_delegate_->last_get_adapter_callback(); + ASSERT_TRUE(last_get_adapter_callback); + + // Because the adapter has just been initialized, the discovery session + // should not have been started yet. + EXPECT_FALSE(stored_discovery_filter_); + EXPECT_TRUE(stored_discovery_callback_.is_null()); + EXPECT_TRUE(stored_discovery_errback_.is_null()); + + EXPECT_CALL(*mock_adapter_, AddObserver(ble_scanner_.get())); + last_get_adapter_callback.Run(mock_adapter_); + + // Once the adapter callback is returned, a discovery session should be + // started via that adapter. + AssertDiscoverySessionRequested(); + } + + void AssertDiscoverySessionRequested() { + // First, ensure that the correct discovery filter was passed. + EXPECT_TRUE(stored_discovery_filter_); + EXPECT_EQ(device::BluetoothTransport::BLUETOOTH_TRANSPORT_LE, + stored_discovery_filter_->GetTransport()); + int16_t observed_rssi; + ASSERT_TRUE(stored_discovery_filter_->GetRSSI(&observed_rssi)); + EXPECT_EQ(kExpectedDiscoveryRSSI, observed_rssi); + + // Now, ensure that both a callback and errback were passed. + EXPECT_FALSE(stored_discovery_callback_.is_null()); + EXPECT_FALSE(stored_discovery_errback_.is_null()); + } + + void InvokeDiscoveryStartedCallback() { + EXPECT_FALSE(stored_discovery_callback_.is_null()); + + mock_discovery_session_ = new device::MockBluetoothDiscoverySession(); + stored_discovery_callback_.Run(base::WrapUnique(mock_discovery_session_)); + } + + std::vector<cryptauth::RemoteDevice> test_devices_; + std::vector<cryptauth::BeaconSeed> test_beacon_seeds_; + + std::unique_ptr<MockBleScannerObserver> mock_observer_; + + TestDelegate* test_delegate_; + std::unique_ptr<cryptauth::MockEidGenerator> mock_eid_generator_; + std::unique_ptr<MockLocalDeviceDataProvider> mock_local_device_data_provider_; + + scoped_refptr<NiceMock<device::MockBluetoothAdapter>> mock_adapter_; + device::MockBluetoothDiscoverySession* mock_discovery_session_; + + std::unique_ptr<device::BluetoothDiscoveryFilter> stored_discovery_filter_; + device::BluetoothAdapter::DiscoverySessionCallback stored_discovery_callback_; + device::BluetoothAdapter::ErrorCallback stored_discovery_errback_; + + std::unique_ptr<BleScanner> ble_scanner_; + + private: + DISALLOW_COPY_AND_ASSIGN(BleScannerTest); +}; + +TEST_F(BleScannerTest, TestNoBluetoothAdapter) { + test_delegate_->set_is_bluetooth_adapter_available(false); + EXPECT_FALSE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0])); + EXPECT_FALSE( + ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId())); + EXPECT_FALSE(test_delegate_->last_get_adapter_callback()); + EXPECT_FALSE(mock_observer_->GetNumCalls()); +} + +TEST_F(BleScannerTest, TestNoLocalBeaconSeeds) { + mock_local_device_data_provider_->SetBeaconSeeds(nullptr); + EXPECT_FALSE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0])); + EXPECT_FALSE( + ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId())); + EXPECT_FALSE(test_delegate_->last_get_adapter_callback()); + EXPECT_FALSE(mock_observer_->GetNumCalls()); +} + +TEST_F(BleScannerTest, TestNoBackgroundScanFilter) { + mock_eid_generator_->set_background_scan_filter(nullptr); + EXPECT_FALSE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0])); + EXPECT_FALSE( + ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId())); + EXPECT_FALSE(test_delegate_->last_get_adapter_callback()); + EXPECT_FALSE(mock_observer_->GetNumCalls()); +} + +TEST_F(BleScannerTest, TestAdapterDoesNotInitialize) { + EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0])); + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId())); + EXPECT_TRUE(test_delegate_->last_get_adapter_callback()); + + // Do not call the last GetAdapter() callback. The device should still be able + // to be unregistered. + EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice(test_devices_[0])); + EXPECT_FALSE( + ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId())); + EXPECT_FALSE(mock_observer_->GetNumCalls()); +} + +TEST_F(BleScannerTest, TestAdapterDoesNotInitialize_MultipleDevicesRegistered) { + EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0])); + EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[1])); + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId())); + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[1].GetDeviceId())); + EXPECT_TRUE(test_delegate_->last_get_adapter_callback()); + + // Do not call the last GetAdapter() callback. The devices should still be + // able to be unregistered. + EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice(test_devices_[0])); + EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice(test_devices_[1])); + EXPECT_FALSE( + ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId())); + EXPECT_FALSE( + ble_scanner_->IsDeviceRegistered(test_devices_[1].GetDeviceId())); + EXPECT_FALSE(mock_observer_->GetNumCalls()); +} + +TEST_F(BleScannerTest, TestDiscoverySessionFailsToStart) { + EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0])); + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId())); + + InvokeAdapterCallback(); + stored_discovery_errback_.Run(); + + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId())); + EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice(test_devices_[0])); + EXPECT_FALSE(mock_observer_->GetNumCalls()); +} + +TEST_F(BleScannerTest, TestDiscoveryStartsButNoDevicesFound) { + EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0])); + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId())); + + InvokeAdapterCallback(); + InvokeDiscoveryStartedCallback(); + + // No devices found. + + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId())); + EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice(test_devices_[0])); + EXPECT_FALSE(mock_observer_->GetNumCalls()); +} + +TEST_F(BleScannerTest, TestDiscovery_NoServiceData) { + std::string empty_service_data = ""; + + EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0])); + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId())); + + InvokeAdapterCallback(); + InvokeDiscoveryStartedCallback(); + + // Device with no service data connected. Service data is required to identify + // the advertising device. + MockBluetoothDeviceWithServiceData device1(mock_adapter_.get(), + empty_service_data); + ble_scanner_->DeviceAdded(mock_adapter_.get(), &device1); + EXPECT_FALSE(mock_eid_generator_->num_identify_calls()); + EXPECT_FALSE(mock_observer_->GetNumCalls()); +} + +TEST_F(BleScannerTest, TestDiscovery_ServiceDataTooShort) { + std::string short_service_data = "abc"; + ASSERT_TRUE(short_service_data.size() < kMinNumBytesInServiceData); + + EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0])); + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId())); + + InvokeAdapterCallback(); + InvokeDiscoveryStartedCallback(); + + // Device with short service data connected. Service data of at least 4 bytes + // is required to identify the advertising device. + MockBluetoothDeviceWithServiceData device2(mock_adapter_.get(), + short_service_data); + ble_scanner_->DeviceAdded(mock_adapter_.get(), &device2); + EXPECT_FALSE(mock_eid_generator_->num_identify_calls()); + EXPECT_FALSE(mock_observer_->GetNumCalls()); +} + +TEST_F(BleScannerTest, TestDiscovery_LocalDeviceDataCannotBeFetched) { + std::string valid_service_data_for_other_device = "abcd"; + ASSERT_TRUE(valid_service_data_for_other_device.size() >= + kMinNumBytesInServiceData); + + EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0])); + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId())); + + InvokeAdapterCallback(); + InvokeDiscoveryStartedCallback(); + + // Device with valid service data connected, but the local device data + // cannot be fetched. + mock_local_device_data_provider_->SetPublicKey(nullptr); + mock_local_device_data_provider_->SetBeaconSeeds(nullptr); + MockBluetoothDeviceWithServiceData device3( + mock_adapter_.get(), valid_service_data_for_other_device); + ble_scanner_->DeviceAdded(mock_adapter_.get(), &device3); + EXPECT_FALSE(mock_eid_generator_->num_identify_calls()); + EXPECT_FALSE(mock_observer_->GetNumCalls()); +} + +TEST_F(BleScannerTest, TestDiscovery_ScanSuccessfulButNoRegisteredDevice) { + std::string valid_service_data_for_other_device = "abcd"; + ASSERT_TRUE(valid_service_data_for_other_device.size() >= + kMinNumBytesInServiceData); + + EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0])); + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId())); + + InvokeAdapterCallback(); + InvokeDiscoveryStartedCallback(); + + // Device with valid service data connected, but there was no registered + // device corresponding to the one that just connected. + mock_local_device_data_provider_->SetPublicKey( + base::MakeUnique<std::string>(fake_local_public_key)); + mock_local_device_data_provider_->SetBeaconSeeds( + base::MakeUnique<std::vector<cryptauth::BeaconSeed>>(test_beacon_seeds_)); + MockBluetoothDeviceWithServiceData device4( + mock_adapter_.get(), valid_service_data_for_other_device); + ble_scanner_->DeviceAdded(mock_adapter_.get(), &device4); + EXPECT_EQ(1, mock_eid_generator_->num_identify_calls()); + EXPECT_FALSE(mock_observer_->GetNumCalls()); +} + +TEST_F(BleScannerTest, TestDiscovery_Success) { + std::string valid_service_data_for_registered_device = "abcde"; + ASSERT_TRUE(valid_service_data_for_registered_device.size() >= + kMinNumBytesInServiceData); + + EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0])); + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId())); + + InvokeAdapterCallback(); + InvokeDiscoveryStartedCallback(); + + // Registered device connects. + MockBluetoothDeviceWithServiceData device5( + mock_adapter_.get(), valid_service_data_for_registered_device); + mock_eid_generator_->set_identified_device(&test_devices_[0]); + ble_scanner_->DeviceAdded(mock_adapter_.get(), &device5); + EXPECT_EQ(1, mock_eid_generator_->num_identify_calls()); + EXPECT_EQ(1, mock_observer_->GetNumCalls()); + EXPECT_EQ(1, static_cast<int>(mock_observer_->bluetooth_devices().size())); + EXPECT_EQ(&device5, mock_observer_->bluetooth_devices()[0]); + EXPECT_EQ(1, static_cast<int>(mock_observer_->remote_devices().size())); + EXPECT_EQ(test_devices_[0], mock_observer_->remote_devices()[0]); + + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId())); + EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice(test_devices_[0])); + EXPECT_EQ(1, mock_eid_generator_->num_identify_calls()); + EXPECT_EQ(1, mock_observer_->GetNumCalls()); +} + +TEST_F(BleScannerTest, TestDiscovery_MultipleObservers) { + MockBleScannerObserver extra_observer; + ble_scanner_->AddObserver(&extra_observer); + + EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0])); + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId())); + + InvokeAdapterCallback(); + InvokeDiscoveryStartedCallback(); + + MockBluetoothDeviceWithServiceData mock_bluetooth_device(mock_adapter_.get(), + "fakeServiceData"); + mock_eid_generator_->set_identified_device(&test_devices_[0]); + ble_scanner_->DeviceAdded(mock_adapter_.get(), &mock_bluetooth_device); + + EXPECT_EQ(1, mock_observer_->GetNumCalls()); + EXPECT_EQ(1, static_cast<int>(mock_observer_->bluetooth_devices().size())); + EXPECT_EQ(&mock_bluetooth_device, mock_observer_->bluetooth_devices()[0]); + EXPECT_EQ(1, static_cast<int>(mock_observer_->remote_devices().size())); + EXPECT_EQ(test_devices_[0], mock_observer_->remote_devices()[0]); + + EXPECT_EQ(1, extra_observer.GetNumCalls()); + EXPECT_EQ(1, static_cast<int>(extra_observer.bluetooth_devices().size())); + EXPECT_EQ(&mock_bluetooth_device, extra_observer.bluetooth_devices()[0]); + EXPECT_EQ(1, static_cast<int>(extra_observer.remote_devices().size())); + EXPECT_EQ(test_devices_[0], extra_observer.remote_devices()[0]); + + // Now, unregister both observers. + ble_scanner_->RemoveObserver(mock_observer_.get()); + ble_scanner_->RemoveObserver(&extra_observer); + + // Now, simulate another scan being received. The observers should not be + // notified since they are unregistered, so they should still have a call + // count of 1. + ble_scanner_->DeviceAdded(mock_adapter_.get(), &mock_bluetooth_device); + EXPECT_EQ(1, mock_observer_->GetNumCalls()); + EXPECT_EQ(1, extra_observer.GetNumCalls()); + + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId())); + EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice(test_devices_[0])); +} + +TEST_F(BleScannerTest, TestRegistrationLimit) { + EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0])); + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId())); + EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[1])); + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[1].GetDeviceId())); + + // Attempt to register another device. Registration should fail since the + // maximum number of devices have already been registered. + ASSERT_EQ(2, kMaxConcurrentAdvertisements); + EXPECT_FALSE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[2])); + EXPECT_FALSE( + ble_scanner_->IsDeviceRegistered(test_devices_[2].GetDeviceId())); + + // Unregistering a device which is not registered should also return false. + EXPECT_FALSE(ble_scanner_->UnregisterScanFilterForDevice(test_devices_[2])); + EXPECT_FALSE( + ble_scanner_->IsDeviceRegistered(test_devices_[2].GetDeviceId())); + + // Unregister device 0. + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId())); + EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice(test_devices_[0])); + EXPECT_FALSE( + ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId())); + + // Now, device 2 can be registered. + EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[2])); + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[2].GetDeviceId())); + + // Now, unregister the devices. + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[1].GetDeviceId())); + EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice(test_devices_[1])); + EXPECT_FALSE( + ble_scanner_->IsDeviceRegistered(test_devices_[1].GetDeviceId())); + + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[2].GetDeviceId())); + EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice(test_devices_[2])); + EXPECT_FALSE( + ble_scanner_->IsDeviceRegistered(test_devices_[2].GetDeviceId())); +} + +TEST_F(BleScannerTest, TestAdapterPoweredChanged) { + // This test starts with the adapter powered on, then turns power off before + // discovery starts, then turns power back on and allows discovery to + // complete, then turns power back off again, and finally turns it back on to + // complete another discovery session. + EXPECT_CALL(*mock_adapter_, IsPowered()) + .WillOnce(Return(true)) + .WillOnce(Return(false)) + .WillOnce(Return(true)) + .WillOnce(Return(false)) + .WillOnce(Return(true)); + + EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0])); + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId())); + InvokeAdapterCallback(); + + // The discovery session should have been requested but not yet initialized. + EXPECT_TRUE(stored_discovery_filter_.get()); + EXPECT_FALSE(mock_discovery_session_); + + // Turn the adapter off before the discovery session starts. + ble_scanner_->AdapterPoweredChanged(mock_adapter_.get(), false); + + // Turn the adapter back on, and finish initializing discovery this time. + ble_scanner_->AdapterPoweredChanged(mock_adapter_.get(), true); + InvokeDiscoveryStartedCallback(); + + // The session should have been started. + device::MockBluetoothDiscoverySession* session1 = mock_discovery_session_; + EXPECT_NE(nullptr, session1); + + // Now turn the adapter off again. + ble_scanner_->AdapterPoweredChanged(mock_adapter_.get(), false); + + // Turn the adapter back on. + ble_scanner_->AdapterPoweredChanged(mock_adapter_.get(), true); + InvokeDiscoveryStartedCallback(); + + // A new session should have started, so the session objects should not be the + // same. + device::MockBluetoothDiscoverySession* session2 = mock_discovery_session_; + EXPECT_NE(nullptr, session2); + EXPECT_NE(session1, session2); + + // Unregister device. + EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId())); + EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice(test_devices_[0])); + EXPECT_FALSE( + ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId())); +} + +} // namespace tether + +} // namespace chromeos
diff --git a/chromeos/components/tether/local_device_data_provider.h b/chromeos/components/tether/local_device_data_provider.h index 0d507cc..4125049 100644 --- a/chromeos/components/tether/local_device_data_provider.h +++ b/chromeos/components/tether/local_device_data_provider.h
@@ -36,7 +36,7 @@ // Fetches the public key and/or the beacon seeds for the local device. // Returns whether the operation succeeded. If |nullptr| is passed as a // parameter, the associated data will not be fetched. - bool GetLocalDeviceData( + virtual bool GetLocalDeviceData( std::string* public_key_out, std::vector<cryptauth::BeaconSeed>* beacon_seeds_out) const;
diff --git a/chromeos/components/tether/mock_local_device_data_provider.cc b/chromeos/components/tether/mock_local_device_data_provider.cc new file mode 100644 index 0000000..2774368 --- /dev/null +++ b/chromeos/components/tether/mock_local_device_data_provider.cc
@@ -0,0 +1,56 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromeos/components/tether/mock_local_device_data_provider.h" + +#include "components/cryptauth/cryptauth_device_manager.h" +#include "components/cryptauth/cryptauth_enrollment_manager.h" +#include "components/cryptauth/proto/cryptauth_api.pb.h" + +namespace chromeos { + +namespace tether { + +MockLocalDeviceDataProvider::MockLocalDeviceDataProvider() + : LocalDeviceDataProvider(nullptr, nullptr) {} + +MockLocalDeviceDataProvider::~MockLocalDeviceDataProvider() {} + +void MockLocalDeviceDataProvider::SetPublicKey( + std::unique_ptr<std::string> public_key) { + if (public_key) { + public_key_ = std::move(public_key); + } else { + public_key_.reset(); + } +} + +void MockLocalDeviceDataProvider::SetBeaconSeeds( + std::unique_ptr<std::vector<cryptauth::BeaconSeed>> beacon_seeds) { + if (beacon_seeds) { + beacon_seeds_ = std::move(beacon_seeds); + } else { + beacon_seeds_.reset(); + } +} + +bool MockLocalDeviceDataProvider::GetLocalDeviceData( + std::string* public_key_out, + std::vector<cryptauth::BeaconSeed>* beacon_seeds_out) const { + if (public_key_ && beacon_seeds_) { + if (public_key_out) { + *public_key_out = *public_key_; + } + if (beacon_seeds_out) { + *beacon_seeds_out = *beacon_seeds_; + } + return true; + } + + return false; +} + +} // namespace tether + +} // namespace cryptauth
diff --git a/chromeos/components/tether/mock_local_device_data_provider.h b/chromeos/components/tether/mock_local_device_data_provider.h new file mode 100644 index 0000000..40fa924 --- /dev/null +++ b/chromeos/components/tether/mock_local_device_data_provider.h
@@ -0,0 +1,50 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMEOS_COMPONENTS_TETHER_MOCK_LOCAL_DEVICE_DATA_PROVIDER_H +#define CHROMEOS_COMPONENTS_TETHER_MOCK_LOCAL_DEVICE_DATA_PROVIDER_H + +#include <memory> +#include <string> +#include <vector> + +#include "base/macros.h" +#include "base/memory/ptr_util.h" +#include "chromeos/components/tether/local_device_data_provider.h" + +namespace cryptauth { +class BeaconSeed; +} + +namespace chromeos { + +namespace tether { + +// Test double for LocalDeviceDataProvider. +class MockLocalDeviceDataProvider : public LocalDeviceDataProvider { + public: + MockLocalDeviceDataProvider(); + ~MockLocalDeviceDataProvider() override; + + void SetPublicKey(std::unique_ptr<std::string> public_key); + void SetBeaconSeeds( + std::unique_ptr<std::vector<cryptauth::BeaconSeed>> beacon_seeds); + + // LocalDeviceDataProvider: + bool GetLocalDeviceData( + std::string* public_key_out, + std::vector<cryptauth::BeaconSeed>* beacon_seeds_out) const override; + + private: + std::unique_ptr<std::string> public_key_; + std::unique_ptr<std::vector<cryptauth::BeaconSeed>> beacon_seeds_; + + DISALLOW_COPY_AND_ASSIGN(MockLocalDeviceDataProvider); +}; + +} // namespace tether + +} // namespace chromeos + +#endif // CHROMEOS_COMPONENTS_TETHER_MOCK_LOCAL_DEVICE_DATA_PROVIDER_H
diff --git a/components/cronet/ios/BUILD.gn b/components/cronet/ios/BUILD.gn index ba6ad852..a449ceba 100644 --- a/components/cronet/ios/BUILD.gn +++ b/components/cronet/ios/BUILD.gn
@@ -53,6 +53,7 @@ "../url_request_context_config.h", "Cronet.h", "Cronet.mm", + "cronet_c_for_grpc.h", "cronet_environment.h", "cronet_environment.mm", ] @@ -153,7 +154,10 @@ "//components/grpc_support", ] - public_headers = [ "Cronet.h" ] + public_headers = [ + "Cronet.h", + "cronet_c_for_grpc.h", + ] public_headers += grpc_public_headers sources = [
diff --git a/components/cronet/ios/Cronet.h b/components/cronet/ios/Cronet.h index fc42612..ba3dd7dc 100644 --- a/components/cronet/ios/Cronet.h +++ b/components/cronet/ios/Cronet.h
@@ -6,6 +6,10 @@ #include "bidirectional_stream_c.h" +// TODO(mef): Remove this header after transition to bidirectional_stream_c.h +// See crbug.com/650462 for details. +#include "cronet_c_for_grpc.h" + // A block, that takes a request, and returns YES if the request should // be handled. typedef BOOL (^RequestFilterBlock)(NSURLRequest* request);
diff --git a/components/cronet/ios/cronet_c_for_grpc.h b/components/cronet/ios/cronet_c_for_grpc.h new file mode 100644 index 0000000..f2700023 --- /dev/null +++ b/components/cronet/ios/cronet_c_for_grpc.h
@@ -0,0 +1,36 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_CRONET_IOS_CRONET_C_FOR_GRPC_H_ +#define COMPONENTS_CRONET_IOS_CRONET_C_FOR_GRPC_H_ + +#include "bidirectional_stream_c.h" + +// TODO(mef): Remove this header after transition to bidirectional_stream_c.h +// See crbug.com/650462 for details. + +/* Define deprecated Cronet Engine API using current API. */ +#define cronet_engine stream_engine + +/* Define deprecated Bidirectional Stream API using current API. */ +#define cronet_bidirectional_stream bidirectional_stream +#define cronet_bidirectional_stream_header bidirectional_stream_header +#define cronet_bidirectional_stream_header_array \ + bidirectional_stream_header_array +#define cronet_bidirectional_stream_callback bidirectional_stream_callback + +#define cronet_bidirectional_stream_create bidirectional_stream_create +#define cronet_bidirectional_stream_destroy bidirectional_stream_destroy +#define cronet_bidirectional_stream_disable_auto_flush \ + bidirectional_stream_disable_auto_flush +#define cronet_bidirectional_stream_delay_request_headers_until_flush \ + bidirectional_stream_delay_request_headers_until_flush +#define cronet_bidirectional_stream_start bidirectional_stream_start +#define cronet_bidirectional_stream_read bidirectional_stream_read +#define cronet_bidirectional_stream_write bidirectional_stream_write +#define cronet_bidirectional_stream_flush bidirectional_stream_flush +#define cronet_bidirectional_stream_cancel bidirectional_stream_cancel +#define cronet_bidirectional_stream_is_done bidirectional_stream_is_done + +#endif // COMPONENTS_CRONET_IOS_CRONET_C_FOR_GRPC_H_
diff --git a/components/cryptauth/BUILD.gn b/components/cryptauth/BUILD.gn index 46d9cdc..6093685 100644 --- a/components/cryptauth/BUILD.gn +++ b/components/cryptauth/BUILD.gn
@@ -38,6 +38,8 @@ "eid_generator.h", "pref_names.cc", "pref_names.h", + "remote_beacon_seed_fetcher.cc", + "remote_beacon_seed_fetcher.h", "remote_device.cc", "remote_device.h", "secure_message_delegate.cc", @@ -88,6 +90,8 @@ "mock_cryptauth_client.h", "mock_eid_generator.cc", "mock_eid_generator.h", + "mock_remote_beacon_seed_fetcher.cc", + "mock_remote_beacon_seed_fetcher.h", "mock_sync_scheduler.cc", "mock_sync_scheduler.h", "remote_device_test_util.cc", @@ -119,6 +123,7 @@ "cryptauth_gcm_manager_impl_unittest.cc", "eid_generator_unittest.cc", "fake_secure_message_delegate_unittest.cc", + "remote_beacon_seed_fetcher_unittest.cc", "sync_scheduler_impl_unittest.cc", "wire_message_unittest.cc", ]
diff --git a/components/cryptauth/cryptauth_device_manager.cc b/components/cryptauth/cryptauth_device_manager.cc index f2e6b55..98931e4 100644 --- a/components/cryptauth/cryptauth_device_manager.cc +++ b/components/cryptauth/cryptauth_device_manager.cc
@@ -312,8 +312,18 @@ UpdateUnlockKeysFromPrefs(); } +// Test-only constructor. +CryptAuthDeviceManager::CryptAuthDeviceManager() + : clock_(nullptr), + client_factory_(nullptr), + gcm_manager_(nullptr), + pref_service_(nullptr), + weak_ptr_factory_(this) {} + CryptAuthDeviceManager::~CryptAuthDeviceManager() { - gcm_manager_->RemoveObserver(this); + if (gcm_manager_) { + gcm_manager_->RemoveObserver(this); + } } // static
diff --git a/components/cryptauth/cryptauth_device_manager.h b/components/cryptauth/cryptauth_device_manager.h index a4b8deb..96ba7ff40 100644 --- a/components/cryptauth/cryptauth_device_manager.h +++ b/components/cryptauth/cryptauth_device_manager.h
@@ -106,15 +106,19 @@ bool IsRecoveringFromFailure() const; // Returns a list of all remote devices that have been synced. - std::vector<cryptauth::ExternalDeviceInfo> GetSyncedDevices() const; + virtual std::vector<cryptauth::ExternalDeviceInfo> GetSyncedDevices() const; // Returns a list of remote devices that can unlock the user's other devices. - std::vector<cryptauth::ExternalDeviceInfo> GetUnlockKeys() const; + virtual std::vector<cryptauth::ExternalDeviceInfo> GetUnlockKeys() const; // Returns a list of remote devices that can host tether hotspots. - std::vector<cryptauth::ExternalDeviceInfo> GetTetherHosts() const; + virtual std::vector<cryptauth::ExternalDeviceInfo> GetTetherHosts() const; protected: + // Empty constructor, to be used by tests to mock the device manager. Do not + // use this constructor outside of tests. + CryptAuthDeviceManager(); + // Creates a new SyncScheduler instance. Exposed for testing. virtual std::unique_ptr<SyncScheduler> CreateSyncScheduler();
diff --git a/components/cryptauth/mock_eid_generator.cc b/components/cryptauth/mock_eid_generator.cc index adebf26b..c9515a7 100644 --- a/components/cryptauth/mock_eid_generator.cc +++ b/components/cryptauth/mock_eid_generator.cc
@@ -11,7 +11,8 @@ MockEidGenerator::MockEidGenerator() : background_scan_filter_(nullptr), advertisement_(nullptr), possible_advertisements_(nullptr), - identified_device_(nullptr) {} + identified_device_(nullptr), + num_identify_calls_(0) {} MockEidGenerator::~MockEidGenerator() {} @@ -62,6 +63,11 @@ const std::string& advertisement_service_data, const std::vector<RemoteDevice>& device_list, const std::vector<BeaconSeed>& scanning_device_beacon_seeds) const { + // Increment num_identify_calls_. Since this overrides a const method, some + // hacking is needed to modify the num_identify_calls_ instance variable. + int* num_identify_calls_ptr = const_cast<int*>(&num_identify_calls_); + *num_identify_calls_ptr = *num_identify_calls_ptr + 1; + return identified_device_; }
diff --git a/components/cryptauth/mock_eid_generator.h b/components/cryptauth/mock_eid_generator.h index 6317200..4f624a2 100644 --- a/components/cryptauth/mock_eid_generator.h +++ b/components/cryptauth/mock_eid_generator.h
@@ -60,11 +60,17 @@ const std::vector<BeaconSeed>& scanning_device_beacon_seeds) const override; + int num_identify_calls() { + return num_identify_calls_; + } + private: std::unique_ptr<EidData> background_scan_filter_; std::unique_ptr<DataWithTimestamp> advertisement_; std::unique_ptr<std::vector<std::string>> possible_advertisements_; const RemoteDevice* identified_device_; + + int num_identify_calls_; }; } // namespace cryptauth
diff --git a/components/cryptauth/mock_remote_beacon_seed_fetcher.cc b/components/cryptauth/mock_remote_beacon_seed_fetcher.cc new file mode 100644 index 0000000..73058fe --- /dev/null +++ b/components/cryptauth/mock_remote_beacon_seed_fetcher.cc
@@ -0,0 +1,35 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/cryptauth/mock_remote_beacon_seed_fetcher.h" + +#include "components/cryptauth/cryptauth_device_manager.h" + +namespace cryptauth { + +MockRemoteBeaconSeedFetcher::MockRemoteBeaconSeedFetcher() + : RemoteBeaconSeedFetcher(nullptr) {} + +MockRemoteBeaconSeedFetcher::~MockRemoteBeaconSeedFetcher() {} + +bool MockRemoteBeaconSeedFetcher::FetchSeedsForDevice( + const RemoteDevice& remote_device, + std::vector<BeaconSeed>* beacon_seeds_out) { + const auto& seeds_iter = + public_key_to_beacon_seeds_map_.find(remote_device.public_key); + if (seeds_iter == public_key_to_beacon_seeds_map_.end()) { + return false; + } + + *beacon_seeds_out = seeds_iter->second; + return true; +} + +void MockRemoteBeaconSeedFetcher::SetSeedsForDevice( + const RemoteDevice& remote_device, + const std::vector<BeaconSeed>& beacon_seeds) { + public_key_to_beacon_seeds_map_[remote_device.public_key] = beacon_seeds; +} + +} // namespace cryptauth
diff --git a/components/cryptauth/mock_remote_beacon_seed_fetcher.h b/components/cryptauth/mock_remote_beacon_seed_fetcher.h new file mode 100644 index 0000000..db4cac9 --- /dev/null +++ b/components/cryptauth/mock_remote_beacon_seed_fetcher.h
@@ -0,0 +1,39 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_CRYPTAUTH_MOCK_BEACON_SEED_FETCHER_H_ +#define COMPONENTS_CRYPTAUTH_MOCK_BEACON_SEED_FETCHER_H_ + +#include <map> +#include <vector> + +#include "components/cryptauth/proto/cryptauth_api.pb.h" +#include "components/cryptauth/remote_beacon_seed_fetcher.h" + +namespace cryptauth { + +class MockRemoteBeaconSeedFetcher : public RemoteBeaconSeedFetcher { + public: + MockRemoteBeaconSeedFetcher(); + ~MockRemoteBeaconSeedFetcher() override; + + // RemoteBeaconSeedFetcher: + bool FetchSeedsForDevice( + const RemoteDevice& remote_device, + std::vector<BeaconSeed>* beacon_seeds_out) override; + + void SetSeedsForDevice( + const RemoteDevice& remote_device, + const std::vector<BeaconSeed>& beacon_seeds); + + private: + std::map<std::string, std::vector<BeaconSeed>> + public_key_to_beacon_seeds_map_; + + DISALLOW_COPY_AND_ASSIGN(MockRemoteBeaconSeedFetcher); +}; + +} // namespace cryptauth + +#endif // COMPONENTS_CRYPTAUTH_MOCK_BEACON_SEED_FETCHER_H_
diff --git a/components/cryptauth/remote_beacon_seed_fetcher.cc b/components/cryptauth/remote_beacon_seed_fetcher.cc new file mode 100644 index 0000000..e1f47c8c --- /dev/null +++ b/components/cryptauth/remote_beacon_seed_fetcher.cc
@@ -0,0 +1,41 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/cryptauth/remote_beacon_seed_fetcher.h" + +#include "components/cryptauth/cryptauth_device_manager.h" + +namespace cryptauth { + +RemoteBeaconSeedFetcher::RemoteBeaconSeedFetcher( + const CryptAuthDeviceManager* device_manager) + : device_manager_(device_manager) {} + +RemoteBeaconSeedFetcher::~RemoteBeaconSeedFetcher() {} + +bool RemoteBeaconSeedFetcher::FetchSeedsForDevice( + const RemoteDevice& remote_device, + std::vector<BeaconSeed>* beacon_seeds_out) { + if (remote_device.public_key.empty()) { + return false; + } + + for(const auto& device_info : device_manager_->GetSyncedDevices()) { + if (device_info.public_key() == remote_device.public_key) { + if (device_info.beacon_seeds_size() == 0) { + return false; + } + + beacon_seeds_out->clear(); + for (int i = 0; i < device_info.beacon_seeds_size(); i++) { + beacon_seeds_out->push_back(device_info.beacon_seeds(i)); + } + return true; + } + } + + return false; +} + +} // namespace cryptauth
diff --git a/components/cryptauth/remote_beacon_seed_fetcher.h b/components/cryptauth/remote_beacon_seed_fetcher.h new file mode 100644 index 0000000..8d4401e8 --- /dev/null +++ b/components/cryptauth/remote_beacon_seed_fetcher.h
@@ -0,0 +1,40 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_CRYPTAUTH_REMOTE_BEACON_SEED_FETCHER_H_ +#define COMPONENTS_CRYPTAUTH_REMOTE_BEACON_SEED_FETCHER_H_ + +#include <vector> + +#include "base/macros.h" +#include "components/cryptauth/proto/cryptauth_api.pb.h" +#include "components/cryptauth/remote_device.h" + +namespace cryptauth { + +class CryptAuthDeviceManager; + +// Fetches |BeaconSeed|s corresponding to a given |RemoteDevice|. Note that an +// alternate solution would be to embed a list of |BeaconSeed|s in each +// |RemoteDevice| object; however, because |BeaconSeed| objects take up almost +// 1kB of memory apiece, that approach adds unnecessary memory overhead. +class RemoteBeaconSeedFetcher { + public: + RemoteBeaconSeedFetcher(const CryptAuthDeviceManager* device_manager); + virtual ~RemoteBeaconSeedFetcher(); + + virtual bool FetchSeedsForDevice( + const RemoteDevice& remote_device, + std::vector<BeaconSeed>* beacon_seeds_out); + + private: + // Not owned by this instance and must outlive it. + const CryptAuthDeviceManager* device_manager_; + + DISALLOW_COPY_AND_ASSIGN(RemoteBeaconSeedFetcher); +}; + +} // namespace cryptauth + +#endif // COMPONENTS_CRYPTAUTH_REMOTE_BEACON_SEED_FETCHER_H_
diff --git a/components/cryptauth/remote_beacon_seed_fetcher_unittest.cc b/components/cryptauth/remote_beacon_seed_fetcher_unittest.cc new file mode 100644 index 0000000..25cda2f --- /dev/null +++ b/components/cryptauth/remote_beacon_seed_fetcher_unittest.cc
@@ -0,0 +1,173 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/cryptauth/remote_beacon_seed_fetcher.h" + +#include "base/macros.h" +#include "base/memory/ptr_util.h" +#include "components/cryptauth/cryptauth_client.h" +#include "components/cryptauth/cryptauth_device_manager.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using testing::StrictMock; +using testing::Return; + +namespace cryptauth { + +namespace { + +const std::string fake_beacon_seed1_data = "fakeBeaconSeed1Data"; +const int64_t fake_beacon_seed1_start_ms = 1000L; +const int64_t fake_beacon_seed1_end_ms = 2000L; + +const std::string fake_beacon_seed2_data = "fakeBeaconSeed2Data"; +const int64_t fake_beacon_seed2_start_ms = 2000L; +const int64_t fake_beacon_seed2_end_ms = 3000L; + +const std::string fake_beacon_seed3_data = "fakeBeaconSeed3Data"; +const int64_t fake_beacon_seed3_start_ms = 1000L; +const int64_t fake_beacon_seed3_end_ms = 2000L; + +const std::string fake_beacon_seed4_data = "fakeBeaconSeed4Data"; +const int64_t fake_beacon_seed4_start_ms = 2000L; +const int64_t fake_beacon_seed4_end_ms = 3000L; + +const std::string public_key1 = "publicKey1"; +const std::string public_key2 = "publicKey2"; + +class MockDeviceManager : public CryptAuthDeviceManager { + public: + MockDeviceManager() {} + ~MockDeviceManager() override {} + + MOCK_CONST_METHOD0(GetSyncedDevices, std::vector<ExternalDeviceInfo>()); +}; + +RemoteDevice CreateRemoteDevice(const std::string& public_key) { + RemoteDevice remote_device; + remote_device.public_key = public_key; + return remote_device; +} + +ExternalDeviceInfo CreateFakeInfo1() { + BeaconSeed seed1; + seed1.set_data(fake_beacon_seed1_data); + seed1.set_start_time_millis(fake_beacon_seed1_start_ms); + seed1.set_end_time_millis(fake_beacon_seed1_end_ms); + + BeaconSeed seed2; + seed2.set_data(fake_beacon_seed2_data); + seed2.set_start_time_millis(fake_beacon_seed2_start_ms); + seed2.set_end_time_millis(fake_beacon_seed2_end_ms); + + ExternalDeviceInfo info1; + info1.set_public_key(public_key1); + info1.add_beacon_seeds()->CopyFrom(seed1); + info1.add_beacon_seeds()->CopyFrom(seed2); + return info1; +} + +ExternalDeviceInfo CreateFakeInfo2() { + BeaconSeed seed3; + seed3.set_data(fake_beacon_seed3_data); + seed3.set_start_time_millis(fake_beacon_seed3_start_ms); + seed3.set_end_time_millis(fake_beacon_seed3_end_ms); + + BeaconSeed seed4; + seed4.set_data(fake_beacon_seed4_data); + seed4.set_start_time_millis(fake_beacon_seed4_start_ms); + seed4.set_end_time_millis(fake_beacon_seed4_end_ms); + + ExternalDeviceInfo info2; + info2.set_public_key(public_key2); + info2.add_beacon_seeds()->CopyFrom(seed3); + info2.add_beacon_seeds()->CopyFrom(seed4); + return info2; +} + +} // namespace + +class CryptAuthRemoteBeaconSeedFetcherTest : public testing::Test { + protected: + CryptAuthRemoteBeaconSeedFetcherTest() + : fake_info1_(CreateFakeInfo1()), fake_info2_(CreateFakeInfo2()) {} + + void SetUp() override { + mock_device_manager_ = base::MakeUnique<MockDeviceManager>(); + fetcher_ = base::MakeUnique<StrictMock<RemoteBeaconSeedFetcher>>( + mock_device_manager_.get()); + } + + std::unique_ptr<RemoteBeaconSeedFetcher> fetcher_; + std::unique_ptr<MockDeviceManager> mock_device_manager_; + + const ExternalDeviceInfo fake_info1_; + const ExternalDeviceInfo fake_info2_; + + private: + DISALLOW_COPY_AND_ASSIGN(CryptAuthRemoteBeaconSeedFetcherTest); +}; + +TEST_F(CryptAuthRemoteBeaconSeedFetcherTest, TestRemoteDeviceWithNoPublicKey) { + RemoteDevice device = CreateRemoteDevice(""); + + std::vector<BeaconSeed> seeds; + EXPECT_FALSE(fetcher_->FetchSeedsForDevice(device, &seeds)); +} + +TEST_F(CryptAuthRemoteBeaconSeedFetcherTest, TestNoSyncedDevices) { + RemoteDevice device = CreateRemoteDevice(public_key1); + + EXPECT_CALL(*mock_device_manager_, GetSyncedDevices()) + .WillOnce(Return(std::vector<ExternalDeviceInfo>())); + + std::vector<BeaconSeed> seeds; + EXPECT_FALSE(fetcher_->FetchSeedsForDevice(device, &seeds)); +} + +TEST_F(CryptAuthRemoteBeaconSeedFetcherTest, TestDeviceHasDifferentPublicKey) { + // A public key which is different from the public keys of all of the synced + // devices. + RemoteDevice device = CreateRemoteDevice("differentPublicKey"); + + std::vector<ExternalDeviceInfo> device_infos = {fake_info1_, fake_info2_}; + EXPECT_CALL(*mock_device_manager_, GetSyncedDevices()) + .WillOnce(Return(device_infos)); + + std::vector<BeaconSeed> seeds; + EXPECT_FALSE(fetcher_->FetchSeedsForDevice(device, &seeds)); +} + +TEST_F(CryptAuthRemoteBeaconSeedFetcherTest, TestSuccess) { + RemoteDevice device1 = CreateRemoteDevice(public_key1); + RemoteDevice device2 = CreateRemoteDevice(public_key2); + + std::vector<ExternalDeviceInfo> device_infos = {fake_info1_, fake_info2_}; + EXPECT_CALL(*mock_device_manager_, GetSyncedDevices()) + .Times(2) + .WillRepeatedly(Return(device_infos)); + + std::vector<BeaconSeed> seeds1; + ASSERT_TRUE(fetcher_->FetchSeedsForDevice(device1, &seeds1)); + ASSERT_EQ(static_cast<size_t>(2), seeds1.size()); + EXPECT_EQ(fake_beacon_seed1_data, seeds1[0].data()); + EXPECT_EQ(fake_beacon_seed1_start_ms, seeds1[0].start_time_millis()); + EXPECT_EQ(fake_beacon_seed1_end_ms, seeds1[0].end_time_millis()); + EXPECT_EQ(fake_beacon_seed2_data, seeds1[1].data()); + EXPECT_EQ(fake_beacon_seed2_start_ms, seeds1[1].start_time_millis()); + EXPECT_EQ(fake_beacon_seed2_end_ms, seeds1[1].end_time_millis()); + + std::vector<BeaconSeed> seeds2; + ASSERT_TRUE(fetcher_->FetchSeedsForDevice(device2, &seeds2)); + ASSERT_EQ(static_cast<size_t>(2), seeds2.size()); + EXPECT_EQ(fake_beacon_seed3_data, seeds2[0].data()); + EXPECT_EQ(fake_beacon_seed3_start_ms, seeds2[0].start_time_millis()); + EXPECT_EQ(fake_beacon_seed3_end_ms, seeds2[0].end_time_millis()); + EXPECT_EQ(fake_beacon_seed4_data, seeds2[1].data()); + EXPECT_EQ(fake_beacon_seed4_start_ms, seeds2[1].start_time_millis()); + EXPECT_EQ(fake_beacon_seed4_end_ms, seeds2[1].end_time_millis()); +} + +} // namespace cryptauth
diff --git a/components/exo/gamepad.cc b/components/exo/gamepad.cc index 876d05d8..8d5e2311 100644 --- a/components/exo/gamepad.cc +++ b/components/exo/gamepad.cc
@@ -123,7 +123,6 @@ fetcher_->GetGamepadData( false /* No hardware changed notification from the system */); - new_state.length = 0; device::PadState& pad_state = pad_states_.get()[0]; // After querying the gamepad clear the state if it did not have it's active @@ -137,22 +136,15 @@ MapAndSanitizeGamepadData(&pad_state, &new_state.items[0], false /* Don't sanitize gamepad data */); - // If the gamepad was active then increment the length of the WebGamepads - // struct to indicate it's valid, then set the pad state to inactive. If the - // gamepad is still actively reporting the next call to GetGamepadData will - // set the active state to active again. - if (pad_state.active_state) { - new_state.length++; + // If the gamepad is still actively reporting the next call to + // GetGamepadData will set the active state to active again. + if (pad_state.active_state) pad_state.active_state = device::GAMEPAD_INACTIVE; - } - if (std::max(new_state.length, state_.length) > 0) { - if (new_state.items[0].connected != state_.items[0].connected || - new_state.items[0].timestamp > state_.items[0].timestamp) { - origin_task_runner_->PostTask( - FROM_HERE, - base::Bind(process_gamepad_changes_, new_state.items[0])); - } + if (new_state.items[0].connected != state_.items[0].connected || + new_state.items[0].timestamp > state_.items[0].timestamp) { + origin_task_runner_->PostTask( + FROM_HERE, base::Bind(process_gamepad_changes_, new_state.items[0])); } state_ = new_state;
diff --git a/components/exo/gamepad_unittest.cc b/components/exo/gamepad_unittest.cc index 34a7e16..560c7e4 100644 --- a/components/exo/gamepad_unittest.cc +++ b/components/exo/gamepad_unittest.cc
@@ -105,7 +105,6 @@ // Gamepad connected. EXPECT_CALL(delegate, OnStateChange(true)).Times(1); blink::WebGamepads gamepad_connected; - gamepad_connected.length = 1; gamepad_connected.items[0].connected = true; gamepad_connected.items[0].timestamp = 1; SetDataAndPostToDelegate(gamepad_connected); @@ -134,7 +133,6 @@ InitializeGamepad(&delegate); blink::WebGamepads axis_moved; - axis_moved.length = 1; axis_moved.items[0].connected = true; axis_moved.items[0].timestamp = 1; axis_moved.items[0].axesLength = 1; @@ -164,7 +162,6 @@ InitializeGamepad(&delegate); blink::WebGamepads axis_moved; - axis_moved.length = 1; axis_moved.items[0].connected = true; axis_moved.items[0].timestamp = 1; axis_moved.items[0].buttonsLength = 1;
diff --git a/components/metrics/metrics_log_manager.cc b/components/metrics/metrics_log_manager.cc index 387b2001..cc35bbd 100644 --- a/components/metrics/metrics_log_manager.cc +++ b/components/metrics/metrics_log_manager.cc
@@ -45,7 +45,6 @@ new PersistedLogsMetricsImpl()), local_state, prefs::kMetricsInitialLogs, - prefs::kDeprecatedMetricsInitialLogs, kInitialLogsPersistLimit, kStorageByteLimitPerLogType, 0), @@ -53,7 +52,6 @@ new PersistedLogsMetricsImpl()), local_state, prefs::kMetricsOngoingLogs, - prefs::kDeprecatedMetricsOngoingLogs, kOngoingLogsPersistLimit, kStorageByteLimitPerLogType, max_ongoing_log_size) {}
diff --git a/components/metrics/metrics_log_manager_unittest.cc b/components/metrics/metrics_log_manager_unittest.cc index 8040ed0..e30a16c 100644 --- a/components/metrics/metrics_log_manager_unittest.cc +++ b/components/metrics/metrics_log_manager_unittest.cc
@@ -167,7 +167,7 @@ PersistedLogs ongoing_logs(std::unique_ptr<PersistedLogsMetricsImpl>( new PersistedLogsMetricsImpl()), &pref_service, prefs::kMetricsOngoingLogs, - prefs::kDeprecatedMetricsOngoingLogs, 1, 1, 0); + 1, 1, 0); ongoing_logs.StoreLog(log); ongoing_logs.SerializeLogs(); }
diff --git a/components/metrics/metrics_pref_names.cc b/components/metrics/metrics_pref_names.cc index 1d5a7b63..c5ad9c6 100644 --- a/components/metrics/metrics_pref_names.cc +++ b/components/metrics/metrics_pref_names.cc
@@ -7,21 +7,6 @@ namespace metrics { namespace prefs { -// Array of strings that are each UMA logs that were supposed to be sent in the -// first minute of a browser session. These logs include things like crash count -// info, etc. -// Deprecated by kMetricsInitialLogs. -const char kDeprecatedMetricsInitialLogs[] = - "user_experience_metrics.initial_logs_list"; - -// Array of strings that are each UMA logs that were not sent because the -// browser terminated before these accumulated metrics could be sent. These -// logs typically include histograms and memory reports, as well as ongoing -// user activities. -// Deprecated by kMetricsOngoingLogs. -const char kDeprecatedMetricsOngoingLogs[] = - "user_experience_metrics.ongoing_logs_list"; - // Set once, to the current epoch time, on the first run of chrome on this // machine. Attached to metrics reports forever thereafter. const char kInstallDate[] = "uninstall_metrics.installation_date2";
diff --git a/components/metrics/persisted_logs.cc b/components/metrics/persisted_logs.cc index a407a0d..b7aa8f0 100644 --- a/components/metrics/persisted_logs.cc +++ b/components/metrics/persisted_logs.cc
@@ -27,17 +27,6 @@ const char kLogTimestampKey[] = "timestamp"; const char kLogDataKey[] = "data"; -// Reads the value at |index| from |list_value| as a string and Base64-decodes -// it into |result|. Returns true on success. -bool ReadBase64String(const base::ListValue& list_value, - size_t index, - std::string* result) { - std::string base64_result; - if (!list_value.GetString(index, &base64_result)) - return false; - return base::Base64Decode(base64_result, result); -} - std::string EncodeToBase64(const std::string& to_convert) { std::string base64_result; base::Base64Encode(to_convert, &base64_result); @@ -71,14 +60,12 @@ PersistedLogs::PersistedLogs(std::unique_ptr<PersistedLogsMetrics> metrics, PrefService* local_state, const char* pref_name, - const char* outdated_pref_name, size_t min_log_count, size_t min_log_bytes, size_t max_log_size) : metrics_(std::move(metrics)), local_state_(local_state), pref_name_(pref_name), - outdated_pref_name_(outdated_pref_name), min_log_count_(min_log_count), min_log_bytes_(min_log_bytes), max_log_size_(max_log_size != 0 ? max_log_size : static_cast<size_t>(-1)), @@ -93,20 +80,9 @@ void PersistedLogs::SerializeLogs() const { ListPrefUpdate update(local_state_, pref_name_); WriteLogsToPrefList(update.Get()); - - // After writing all the logs to the new pref remove old outdated pref. - // TODO(gayane): Remove when all users are migrated. crbug.com/649440 - if (local_state_->HasPrefPath(outdated_pref_name_)) - local_state_->ClearPref(outdated_pref_name_); } PersistedLogs::LogReadStatus PersistedLogs::DeserializeLogs() { - // TODO(gayane): Remove the code for reading logs from outdated pref when all - // users are migrated. crbug.com/649440 - if (local_state_->HasPrefPath(outdated_pref_name_)) { - return ReadLogsFromOldFormatPrefList( - *local_state_->GetList(outdated_pref_name_)); - } return ReadLogsFromPrefList(*local_state_->GetList(pref_name_)); } @@ -207,29 +183,4 @@ metrics_->RecordDroppedLogsNum(dropped_logs_num); } -PersistedLogs::LogReadStatus PersistedLogs::ReadLogsFromOldFormatPrefList( - const base::ListValue& list_value) { - if (list_value.empty()) - return metrics_->RecordLogReadStatus(LIST_EMPTY); - - // For each log, there's two entries in the list (the data and the hash). - DCHECK_EQ(0U, list_value.GetSize() % 2); - const size_t log_count = list_value.GetSize() / 2; - - // Resize |list_| ahead of time, so that values can be decoded directly into - // the elements of the list. - DCHECK(list_.empty()); - list_.resize(log_count); - - for (size_t i = 0; i < log_count; ++i) { - if (!ReadBase64String(list_value, i * 2, &list_[i].compressed_log_data) || - !ReadBase64String(list_value, i * 2 + 1, &list_[i].hash)) { - list_.clear(); - return metrics_->RecordLogReadStatus(LOG_STRING_CORRUPTION); - } - } - - return metrics_->RecordLogReadStatus(RECALL_SUCCESS); -} - } // namespace metrics
diff --git a/components/metrics/persisted_logs.h b/components/metrics/persisted_logs.h index 2af474b..18a80008 100644 --- a/components/metrics/persisted_logs.h +++ b/components/metrics/persisted_logs.h
@@ -55,7 +55,6 @@ PersistedLogs(std::unique_ptr<PersistedLogsMetrics> metrics, PrefService* local_state, const char* pref_name, - const char* outdated_pref_name, size_t min_log_count, size_t min_log_bytes, size_t max_log_size); @@ -111,9 +110,6 @@ // Reads the list from the ListValue. LogReadStatus ReadLogsFromPrefList(const base::ListValue& list); - // Reads the list from the ListValue in the old Log-hash pair format. - LogReadStatus ReadLogsFromOldFormatPrefList(const base::ListValue& list); - // An object for recording UMA metrics. std::unique_ptr<PersistedLogsMetrics> metrics_; @@ -125,10 +121,6 @@ // The name of the preference to serialize logs to/from. const char* pref_name_; - // The name of the preference to serialize logs to/from which may contain log - // in the old formatting. - const char* outdated_pref_name_; - // We will keep at least this |min_log_count_| logs or |min_log_bytes_| bytes // of logs, whichever is greater, when writing to disk. These apply after // skipping logs greater than |max_log_size_|.
diff --git a/components/metrics/persisted_logs_unittest.cc b/components/metrics/persisted_logs_unittest.cc index 179f4d8..e1b0548f 100644 --- a/components/metrics/persisted_logs_unittest.cc +++ b/components/metrics/persisted_logs_unittest.cc
@@ -23,7 +23,6 @@ namespace { const char kTestPrefName[] = "TestPref"; -const char kTestOutdatedPrefName[] = "OutdatedTestPref"; const size_t kLogCountLimit = 3; const size_t kLogByteLimit = 1000; @@ -69,7 +68,6 @@ new PersistedLogsMetricsImpl()), service, kTestPrefName, - kTestOutdatedPrefName, kLogCountLimit, min_log_bytes, 0) {}
diff --git a/components/ssl_config/ssl_config_service_manager_pref.cc b/components/ssl_config/ssl_config_service_manager_pref.cc index a870ab12..0dab204 100644 --- a/components/ssl_config/ssl_config_service_manager_pref.cc +++ b/components/ssl_config/ssl_config_service_manager_pref.cc
@@ -240,7 +240,7 @@ ssl_config::prefs::kCertRevocationCheckingRequiredLocalAnchors, default_config.rev_checking_required_local_anchors); registry->RegisterBooleanPref(ssl_config::prefs::kCertEnableSha1LocalAnchors, - default_config.sha1_local_anchors_enabled); + false); registry->RegisterStringPref(ssl_config::prefs::kSSLVersionMin, std::string()); registry->RegisterStringPref(ssl_config::prefs::kSSLVersionMax,
diff --git a/components/ssl_config/ssl_config_service_manager_pref_unittest.cc b/components/ssl_config/ssl_config_service_manager_pref_unittest.cc index 6758330..9c2e24b8 100644 --- a/components/ssl_config/ssl_config_service_manager_pref_unittest.cc +++ b/components/ssl_config/ssl_config_service_manager_pref_unittest.cc
@@ -199,3 +199,53 @@ config_service->GetSSLConfig(&ssl_config); EXPECT_EQ(net::SSL_PROTOCOL_VERSION_TLS1_3, ssl_config.version_max); } + +// Tests that SHA-1 signatures for local trust anchors can be enabled. +TEST_F(SSLConfigServiceManagerPrefTest, SHA1ForLocalAnchors) { + scoped_refptr<TestingPrefStore> local_state_store(new TestingPrefStore()); + + TestingPrefServiceSimple local_state; + SSLConfigServiceManager::RegisterPrefs(local_state.registry()); + + std::unique_ptr<SSLConfigServiceManager> config_manager( + SSLConfigServiceManager::CreateDefaultManager( + &local_state, base::ThreadTaskRunnerHandle::Get())); + ASSERT_TRUE(config_manager); + scoped_refptr<SSLConfigService> config_service(config_manager->Get()); + ASSERT_TRUE(config_service); + + // By default, SHA-1 local trust anchors should be enabled when not + // using any pref service. + SSLConfig config1; + EXPECT_TRUE(config1.sha1_local_anchors_enabled); + + // Using a pref service without any preference set should result in + // SHA-1 local trust anchors being disabled. + SSLConfig config2; + config_service->GetSSLConfig(&config2); + EXPECT_FALSE(config2.sha1_local_anchors_enabled); + + // Enabling the local preference should result in SHA-1 local trust anchors + // being enabled. + local_state.SetUserPref(ssl_config::prefs::kCertEnableSha1LocalAnchors, + new base::FundamentalValue(true)); + // Pump the message loop to notify the SSLConfigServiceManagerPref that the + // preferences changed. + base::RunLoop().RunUntilIdle(); + + SSLConfig config3; + config_service->GetSSLConfig(&config3); + EXPECT_TRUE(config3.sha1_local_anchors_enabled); + + // Disabling the local preference should result in SHA-1 local trust + // anchors being disabled. + local_state.SetUserPref(ssl_config::prefs::kCertEnableSha1LocalAnchors, + new base::FundamentalValue(false)); + // Pump the message loop to notify the SSLConfigServiceManagerPref that the + // preferences changed. + base::RunLoop().RunUntilIdle(); + + SSLConfig config4; + config_service->GetSSLConfig(&config4); + EXPECT_FALSE(config4.sha1_local_anchors_enabled); +}
diff --git a/components/sync/engine_impl/sync_manager_impl.cc b/components/sync/engine_impl/sync_manager_impl.cc index cbacc993..a237ea97 100644 --- a/components/sync/engine_impl/sync_manager_impl.cc +++ b/components/sync/engine_impl/sync_manager_impl.cc
@@ -296,10 +296,8 @@ DVLOG(1) << "Setting invalidator client ID: " << args->invalidator_client_id; allstatus_.SetInvalidatorClientId(args->invalidator_client_id); - // TODO(crbug.com/658002): Pass in the real USS migrator function once initial - // GetUpdates issues are addressed. model_type_registry_ = base::MakeUnique<ModelTypeRegistry>( - args->workers, &share_, this, UssMigrator()); + args->workers, &share_, this, base::Bind(&MigrateDirectoryData)); sync_encryption_handler_->AddObserver(model_type_registry_.get()); // Build a SyncCycleContext and store the worker in it.
diff --git a/components/test_runner/BUILD.gn b/components/test_runner/BUILD.gn index d4e6dcf9..5cc0c62 100644 --- a/components/test_runner/BUILD.gn +++ b/components/test_runner/BUILD.gn
@@ -116,7 +116,7 @@ "//gin", "//gpu", "//gpu/command_buffer/client:gles2_interface", - "//media/midi:mojo_cpp_sources", + "//media/midi:mojo", "//net", "//skia", "//third_party/WebKit/public:blink",
diff --git a/components/test_runner/gamepad_controller.cc b/components/test_runner/gamepad_controller.cc index 18c2fa4..a30e221 100644 --- a/components/test_runner/gamepad_controller.cc +++ b/components/test_runner/gamepad_controller.cc
@@ -178,11 +178,6 @@ if (index < 0 || index >= static_cast<int>(WebGamepads::itemsLengthCap)) return; gamepads_.items[index].connected = true; - gamepads_.length = 0; - for (unsigned i = 0; i < WebGamepads::itemsLengthCap; ++i) { - if (gamepads_.items[i].connected) - gamepads_.length = i + 1; - } } void GamepadController::DispatchConnected(int index) { @@ -199,11 +194,6 @@ return; WebGamepad& pad = gamepads_.items[index]; pad.connected = false; - gamepads_.length = 0; - for (unsigned i = 0; i < WebGamepads::itemsLengthCap; ++i) { - if (gamepads_.items[i].connected) - gamepads_.length = i + 1; - } if (listener_) listener_->didDisconnectGamepad(index, pad); }
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index f30a568f..564b13e2 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -93,7 +93,7 @@ "//media/capture/mojo:image_capture", "//media/gpu/ipc/client", "//media/midi", - "//media/midi:mojo_cpp_sources", + "//media/midi:mojo", "//media/mojo/interfaces", "//mojo/common", "//mojo/edk/system",
diff --git a/content/browser/browser_context.cc b/content/browser/browser_context.cc index 1e7f2c3..b287a6c 100644 --- a/content/browser/browser_context.cc +++ b/content/browser/browser_context.cc
@@ -239,8 +239,6 @@ std::string partition_name; bool in_memory = false; - // TODO(ajwong): After GetDefaultStoragePartition() is removed, get rid of - // this conditional and require that |site_instance| is non-NULL. if (site_instance) { GetContentClient()->browser()->GetStoragePartitionConfigForSite( browser_context, site_instance->GetSiteURL(), true,
diff --git a/content/browser/dom_storage/dom_storage_context_wrapper.cc b/content/browser/dom_storage/dom_storage_context_wrapper.cc index 60083d7e..926b4c0fe 100644 --- a/content/browser/dom_storage/dom_storage_context_wrapper.cc +++ b/content/browser/dom_storage/dom_storage_context_wrapper.cc
@@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" +#include "base/command_line.h" #include "base/files/file_path.h" #include "base/location.h" #include "base/memory/memory_coordinator_client_registry.h" @@ -30,6 +31,7 @@ #include "content/public/browser/session_storage_usage_info.h" #include "content/public/common/content_client.h" #include "content/public/common/content_features.h" +#include "content/public/common/content_switches.h" namespace content { namespace { @@ -44,11 +46,12 @@ } void GetLocalStorageUsageHelper( + std::vector<LocalStorageUsageInfo> mojo_usage, base::SingleThreadTaskRunner* reply_task_runner, DOMStorageContextImpl* context, const DOMStorageContext::GetLocalStorageUsageCallback& callback) { std::vector<LocalStorageUsageInfo>* infos = - new std::vector<LocalStorageUsageInfo>; + new std::vector<LocalStorageUsageInfo>(std::move(mojo_usage)); context->GetLocalStorageUsage(infos, true); reply_task_runner->PostTask( FROM_HERE, base::Bind(&InvokeLocalStorageUsageCallbackHelper, callback, @@ -80,14 +83,17 @@ const base::FilePath& profile_path, const base::FilePath& local_partition_path, storage::SpecialStoragePolicy* special_storage_policy) { - base::FilePath storage_dir; - if (!profile_path.empty()) - storage_dir = local_partition_path.AppendASCII(kLocalStorageDirectory); - // TODO(michaeln): Enable writing to disk when db is versioned, - // for now using an empty subdirectory to use an in-memory db. - // subdirectory_(subdirectory), - mojo_state_.reset(new LocalStorageContextMojo( - connector, base::FilePath() /* storage_dir */)); + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kMojoLocalStorage)) { + base::FilePath storage_dir; + if (!profile_path.empty()) + storage_dir = local_partition_path.AppendASCII(kLocalStorageDirectory); + // TODO(michaeln): Enable writing to disk when db is versioned, + // for now using an empty subdirectory to use an in-memory db. + // subdirectory_(subdirectory), + mojo_state_.reset(new LocalStorageContextMojo( + connector, base::FilePath() /* storage_dir */)); + } base::FilePath data_path; if (!profile_path.empty()) @@ -141,9 +147,15 @@ void DOMStorageContextWrapper::GetLocalStorageUsage( const GetLocalStorageUsageCallback& callback) { DCHECK(context_.get()); + if (mojo_state_) { + mojo_state_->GetStorageUsage(base::BindOnce( + &DOMStorageContextWrapper::GotMojoLocalStorageUsage, this, callback)); + return; + } context_->task_runner()->PostShutdownBlockingTask( FROM_HERE, DOMStorageTaskRunner::PRIMARY_SEQUENCE, base::Bind(&GetLocalStorageUsageHelper, + std::vector<LocalStorageUsageInfo>(), base::RetainedRef(base::ThreadTaskRunnerHandle::Get()), base::RetainedRef(context_), callback)); } @@ -165,6 +177,8 @@ FROM_HERE, DOMStorageTaskRunner::PRIMARY_SEQUENCE, base::Bind(&DOMStorageContextImpl::DeleteLocalStorageForPhysicalOrigin, context_, origin)); + if (mojo_state_) + mojo_state_->DeleteStorageForPhysicalOrigin(url::Origin(origin)); } void DOMStorageContextWrapper::DeleteLocalStorage(const GURL& origin) { @@ -173,6 +187,8 @@ FROM_HERE, DOMStorageTaskRunner::PRIMARY_SEQUENCE, base::Bind(&DOMStorageContextImpl::DeleteLocalStorage, context_, origin)); + if (mojo_state_) + mojo_state_->DeleteStorage(url::Origin(origin)); } void DOMStorageContextWrapper::DeleteSessionStorage( @@ -233,11 +249,15 @@ context_->task_runner()->PostShutdownBlockingTask( FROM_HERE, DOMStorageTaskRunner::PRIMARY_SEQUENCE, base::Bind(&DOMStorageContextImpl::Flush, context_)); + if (mojo_state_) + mojo_state_->Flush(); } void DOMStorageContextWrapper::OpenLocalStorage( const url::Origin& origin, mojom::LevelDBWrapperRequest request) { + if (!mojo_state_) + return; mojo_state_->OpenLocalStorage(origin, std::move(request)); } @@ -281,4 +301,14 @@ base::Bind(&DOMStorageContextImpl::PurgeMemory, context_, purge_option)); } +void DOMStorageContextWrapper::GotMojoLocalStorageUsage( + GetLocalStorageUsageCallback callback, + std::vector<LocalStorageUsageInfo> usage) { + context_->task_runner()->PostShutdownBlockingTask( + FROM_HERE, DOMStorageTaskRunner::PRIMARY_SEQUENCE, + base::Bind(&GetLocalStorageUsageHelper, base::Passed(&usage), + base::RetainedRef(base::ThreadTaskRunnerHandle::Get()), + base::RetainedRef(context_), callback)); +} + } // namespace content
diff --git a/content/browser/dom_storage/dom_storage_context_wrapper.h b/content/browser/dom_storage/dom_storage_context_wrapper.h index 2a05e800..14efb451 100644 --- a/content/browser/dom_storage/dom_storage_context_wrapper.h +++ b/content/browser/dom_storage/dom_storage_context_wrapper.h
@@ -94,6 +94,9 @@ void PurgeMemory(DOMStorageContextImpl::PurgeOption purge_option); + void GotMojoLocalStorageUsage(GetLocalStorageUsageCallback callback, + std::vector<LocalStorageUsageInfo> usage); + // Keep all mojo-ish details together and not bleed them through the public // interface. std::unique_ptr<LocalStorageContextMojo> mojo_state_;
diff --git a/content/browser/dom_storage/local_storage_context_mojo.cc b/content/browser/dom_storage/local_storage_context_mojo.cc index c9939f57..01d0c82 100644 --- a/content/browser/dom_storage/local_storage_context_mojo.cc +++ b/content/browser/dom_storage/local_storage_context_mojo.cc
@@ -97,6 +97,11 @@ weak_ptr_factory_.GetWeakPtr(), origin)); } +void LocalStorageContextMojo::Flush() { + for (const auto& it : level_db_wrappers_) + it.second->ScheduleImmediateCommit(); +} + void LocalStorageContextMojo::SetDatabaseForTesting( leveldb::mojom::LevelDBDatabasePtr database) { DCHECK_EQ(connection_state_, NO_CONNECTION);
diff --git a/content/browser/dom_storage/local_storage_context_mojo.h b/content/browser/dom_storage/local_storage_context_mojo.h index c6fea56a..e9d2f53 100644 --- a/content/browser/dom_storage/local_storage_context_mojo.h +++ b/content/browser/dom_storage/local_storage_context_mojo.h
@@ -40,6 +40,7 @@ void DeleteStorage(const url::Origin& origin); // Like DeleteStorage(), but also deletes storage for all sub-origins. void DeleteStorageForPhysicalOrigin(const url::Origin& origin); + void Flush(); void SetDatabaseForTesting(leveldb::mojom::LevelDBDatabasePtr database);
diff --git a/content/browser/permissions/permission_service_context.cc b/content/browser/permissions/permission_service_context.cc index a83267a0..cffb065 100644 --- a/content/browser/permissions/permission_service_context.cc +++ b/content/browser/permissions/permission_service_context.cc
@@ -7,13 +7,45 @@ #include <utility> #include "content/browser/permissions/permission_service_impl.h" +#include "content/public/browser/browser_context.h" #include "content/public/browser/navigation_details.h" +#include "content/public/browser/permission_manager.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/web_contents.h" +using blink::mojom::PermissionObserverPtr; + namespace content { +class PermissionServiceContext::PermissionSubscription { + public: + PermissionSubscription(PermissionServiceContext* context, + PermissionObserverPtr observer) + : context_(context), observer_(std::move(observer)) { + observer_.set_connection_error_handler(base::Bind( + &PermissionSubscription::OnConnectionError, base::Unretained(this))); + } + + ~PermissionSubscription() = default; + + void OnConnectionError() { + DCHECK_NE(id_, 0); + context_->ObserverHadConnectionError(id_); + } + + void OnPermissionStatusChanged(blink::mojom::PermissionStatus status) { + observer_->OnPermissionStatusChange(status); + } + + void set_id(int id) { id_ = id; } + + private: + PermissionServiceContext* context_; + PermissionObserverPtr observer_; + int id_ = 0; +}; + PermissionServiceContext::PermissionServiceContext( RenderFrameHost* render_frame_host) : WebContentsObserver(WebContents::FromRenderFrameHost(render_frame_host)), @@ -33,16 +65,58 @@ void PermissionServiceContext::CreateService( mojo::InterfaceRequest<blink::mojom::PermissionService> request) { - services_.push_back(new PermissionServiceImpl(this, std::move(request))); + services_.push_back( + base::MakeUnique<PermissionServiceImpl>(this, std::move(request))); +} + +void PermissionServiceContext::CreateSubscription( + PermissionType permission_type, + const url::Origin& origin, + PermissionObserverPtr observer) { + BrowserContext* browser_context = GetBrowserContext(); + DCHECK(browser_context); + if (!browser_context->GetPermissionManager()) + return; + + auto subscription = + base::MakeUnique<PermissionSubscription>(this, std::move(observer)); + GURL requesting_origin(origin.Serialize()); + GURL embedding_origin = GetEmbeddingOrigin(); + int subscription_id = + browser_context->GetPermissionManager()->SubscribePermissionStatusChange( + permission_type, requesting_origin, + // If the embedding_origin is empty, we'll use the |origin| instead. + embedding_origin.is_empty() ? requesting_origin : embedding_origin, + base::Bind(&PermissionSubscription::OnPermissionStatusChanged, + base::Unretained(subscription.get()))); + subscription->set_id(subscription_id); + subscriptions_[subscription_id] = std::move(subscription); } void PermissionServiceContext::ServiceHadConnectionError( PermissionServiceImpl* service) { - auto it = std::find(services_.begin(), services_.end(), service); + auto it = std::find_if( + services_.begin(), services_.end(), + [service](const std::unique_ptr<PermissionServiceImpl>& this_service) { + return service == this_service.get(); + }); DCHECK(it != services_.end()); services_.erase(it); } +void PermissionServiceContext::ObserverHadConnectionError(int subscription_id) { + BrowserContext* browser_context = GetBrowserContext(); + DCHECK(browser_context); + if (browser_context->GetPermissionManager()) { + browser_context->GetPermissionManager()->UnsubscribePermissionStatusChange( + subscription_id); + } + + auto it = subscriptions_.find(subscription_id); + DCHECK(it != subscriptions_.end()); + subscriptions_.erase(it); +} + void PermissionServiceContext::RenderFrameHostChanged( RenderFrameHost* old_host, RenderFrameHost* new_host) { @@ -70,7 +144,7 @@ if (render_frame_host != render_frame_host_) return; - for (auto* service : services_) + for (const auto& service : services_) service->CancelPendingOperations(); }
diff --git a/content/browser/permissions/permission_service_context.h b/content/browser/permissions/permission_service_context.h index 3db134e..83274b4 100644 --- a/content/browser/permissions/permission_service_context.h +++ b/content/browser/permissions/permission_service_context.h
@@ -7,15 +7,21 @@ #include "base/macros.h" #include "base/memory/scoped_vector.h" +#include "content/public/browser/permission_type.h" #include "content/public/browser/web_contents_observer.h" #include "mojo/public/cpp/bindings/interface_request.h" namespace blink { namespace mojom { +class PermissionObserver; class PermissionService; } } +namespace url { +class Origin; +} + namespace content { class PermissionServiceImpl; @@ -36,16 +42,26 @@ void CreateService( mojo::InterfaceRequest<blink::mojom::PermissionService> request); + void CreateSubscription( + PermissionType permission_type, + const url::Origin& origin, + mojo::InterfacePtr<blink::mojom::PermissionObserver> observer); + // Called by a PermissionServiceImpl identified as |service| when it has a // connection error in order to get unregistered and killed. void ServiceHadConnectionError(PermissionServiceImpl* service); + // Called when the connection to a PermissionObserver has an error. + void ObserverHadConnectionError(int subscription_id); + BrowserContext* GetBrowserContext() const; GURL GetEmbeddingOrigin() const; RenderFrameHost* render_frame_host() const; private: + class PermissionSubscription; + // WebContentsObserver void RenderFrameHostChanged(RenderFrameHost* old_host, RenderFrameHost* new_host) override; @@ -58,7 +74,9 @@ RenderFrameHost* render_frame_host_; RenderProcessHost* render_process_host_; - ScopedVector<PermissionServiceImpl> services_; + std::vector<std::unique_ptr<PermissionServiceImpl>> services_; + std::unordered_map<int, std::unique_ptr<PermissionSubscription>> + subscriptions_; DISALLOW_COPY_AND_ASSIGN(PermissionServiceContext); };
diff --git a/content/browser/permissions/permission_service_impl.cc b/content/browser/permissions/permission_service_impl.cc index 44851b7a..75e8a6cd 100644 --- a/content/browser/permissions/permission_service_impl.cc +++ b/content/browser/permissions/permission_service_impl.cc
@@ -17,6 +17,7 @@ using blink::mojom::PermissionDescriptorPtr; using blink::mojom::PermissionName; +using blink::mojom::PermissionObserverPtr; using blink::mojom::PermissionStatus; namespace content { @@ -81,17 +82,6 @@ callback.Run(result); } -PermissionServiceImpl::PendingSubscription::PendingSubscription( - PermissionType permission, - const url::Origin& origin, - const PermissionStatusCallback& callback) - : id(-1), permission(permission), origin(origin), callback(callback) {} - -PermissionServiceImpl::PendingSubscription::~PendingSubscription() { - if (!callback.is_null()) - callback.Run(PermissionStatus::ASK); -} - PermissionServiceImpl::PermissionServiceImpl( PermissionServiceContext* context, mojo::InterfaceRequest<blink::mojom::PermissionService> request) @@ -226,17 +216,6 @@ it.GetCurrentValue()->id); } pending_requests_.Clear(); - - // Cancel pending subscriptions. - for (SubscriptionsMap::Iterator<PendingSubscription> - it(&pending_subscriptions_); !it.IsAtEnd(); it.Advance()) { - it.GetCurrentValue()->callback.Run(GetPermissionStatusFromType( - it.GetCurrentValue()->permission, it.GetCurrentValue()->origin)); - it.GetCurrentValue()->callback.Reset(); - permission_manager->UnsubscribePermissionStatusChange( - it.GetCurrentValue()->id); - } - pending_subscriptions_.Clear(); } void PermissionServiceImpl::HasPermission( @@ -267,45 +246,24 @@ callback.Run(GetPermissionStatusFromType(permission_type, origin)); } -void PermissionServiceImpl::GetNextPermissionChange( +void PermissionServiceImpl::AddPermissionObserver( PermissionDescriptorPtr permission, const url::Origin& origin, PermissionStatus last_known_status, - const PermissionStatusCallback& callback) { + PermissionObserverPtr observer) { PermissionStatus current_status = GetPermissionStatus(permission, origin); if (current_status != last_known_status) { - callback.Run(current_status); - return; + observer->OnPermissionStatusChange(current_status); + last_known_status = current_status; } BrowserContext* browser_context = context_->GetBrowserContext(); DCHECK(browser_context); - if (!browser_context->GetPermissionManager()) { - callback.Run(current_status); + if (!browser_context->GetPermissionManager()) return; - } - PermissionType permission_type = - PermissionDescriptorToPermissionType(permission); - - // We need to pass the id of PendingSubscription in pending_subscriptions_ - // to the callback but SubscribePermissionStatusChange() will also return an - // id which is different. - auto subscription = - base::MakeUnique<PendingSubscription>(permission_type, origin, callback); - PendingSubscription* subscription_raw = subscription.get(); - int pending_subscription_id = - pending_subscriptions_.Add(std::move(subscription)); - - GURL requesting_origin(origin.Serialize()); - GURL embedding_origin = context_->GetEmbeddingOrigin(); - subscription_raw->id = - browser_context->GetPermissionManager()->SubscribePermissionStatusChange( - permission_type, requesting_origin, - // If the embedding_origin is empty, we,ll use the |origin| instead. - embedding_origin.is_empty() ? requesting_origin : embedding_origin, - base::Bind(&PermissionServiceImpl::OnPermissionStatusChanged, - weak_factory_.GetWeakPtr(), pending_subscription_id)); + context_->CreateSubscription(PermissionDescriptorToPermissionType(permission), + origin, std::move(observer)); } PermissionStatus PermissionServiceImpl::GetPermissionStatus( @@ -346,25 +304,4 @@ embedding_origin.is_empty() ? requesting_origin : embedding_origin); } -void PermissionServiceImpl::OnPermissionStatusChanged( - int pending_subscription_id, - PermissionStatus status) { - PendingSubscription* subscription = - pending_subscriptions_.Lookup(pending_subscription_id); - - BrowserContext* browser_context = context_->GetBrowserContext(); - DCHECK(browser_context); - if (browser_context->GetPermissionManager()) { - browser_context->GetPermissionManager()->UnsubscribePermissionStatusChange( - subscription->id); - } - - PermissionStatusCallback callback = subscription->callback; - - subscription->callback.Reset(); - pending_subscriptions_.Remove(pending_subscription_id); - - callback.Run(status); -} - } // namespace content
diff --git a/content/browser/permissions/permission_service_impl.h b/content/browser/permissions/permission_service_impl.h index 6cc2872..7617697a 100644 --- a/content/browser/permissions/permission_service_impl.h +++ b/content/browser/permissions/permission_service_impl.h
@@ -27,6 +27,9 @@ // WebContents for example. class PermissionServiceImpl : public blink::mojom::PermissionService { public: + PermissionServiceImpl( + PermissionServiceContext* context, + mojo::InterfaceRequest<blink::mojom::PermissionService> request); ~PermissionServiceImpl() override; // Clear pending operations currently run by the service. This will be called @@ -34,13 +37,6 @@ // state for example, if the frame changes. void CancelPendingOperations(); - protected: - friend PermissionServiceContext; - - PermissionServiceImpl( - PermissionServiceContext* context, - mojo::InterfaceRequest<blink::mojom::PermissionService> request); - private: using PermissionStatusCallback = base::Callback<void(blink::mojom::PermissionStatus)>; @@ -57,20 +53,6 @@ }; using RequestsMap = IDMap<std::unique_ptr<PendingRequest>>; - struct PendingSubscription { - PendingSubscription(PermissionType permission, - const url::Origin& origin, - const PermissionStatusCallback& callback); - ~PendingSubscription(); - - // Subscription ID received from the PermissionManager. - int id; - PermissionType permission; - url::Origin origin; - PermissionStatusCallback callback; - }; - using SubscriptionsMap = IDMap<std::unique_ptr<PendingSubscription>>; - // blink::mojom::PermissionService. void HasPermission(blink::mojom::PermissionDescriptorPtr permission, const url::Origin& origin, @@ -87,11 +69,11 @@ void RevokePermission(blink::mojom::PermissionDescriptorPtr permission, const url::Origin& origin, const PermissionStatusCallback& callback) override; - void GetNextPermissionChange( + void AddPermissionObserver( blink::mojom::PermissionDescriptorPtr permission, const url::Origin& origin, blink::mojom::PermissionStatus last_known_status, - const PermissionStatusCallback& callback) override; + blink::mojom::PermissionObserverPtr observer) override; void OnConnectionError(); @@ -109,11 +91,7 @@ const url::Origin& origin); void ResetPermissionStatus(PermissionType type, const url::Origin& origin); - void OnPermissionStatusChanged(int pending_subscription_id, - blink::mojom::PermissionStatus status); - RequestsMap pending_requests_; - SubscriptionsMap pending_subscriptions_; // context_ owns |this|. PermissionServiceContext* context_; mojo::Binding<blink::mojom::PermissionService> binding_;
diff --git a/content/browser/renderer_host/pepper/pepper_gamepad_host_unittest.cc b/content/browser/renderer_host/pepper/pepper_gamepad_host_unittest.cc index 4075847..cb42e44c 100644 --- a/content/browser/renderer_host/pepper/pepper_gamepad_host_unittest.cc +++ b/content/browser/renderer_host/pepper/pepper_gamepad_host_unittest.cc
@@ -76,8 +76,6 @@ "gamepads data must match"); ppapi::WebKitGamepads ppapi_gamepads; blink::WebGamepads web_gamepads; - EXPECT_EQ(AddressDiff(&web_gamepads.length, &web_gamepads), - AddressDiff(&ppapi_gamepads.length, &ppapi_gamepads)); // See comment below on storage & the EXPECT macro. size_t webkit_items_length_cap = blink::WebGamepads::itemsLengthCap; @@ -137,7 +135,6 @@ TEST_F(PepperGamepadHostTest, MAYBE_WaitForReply) { blink::WebGamepads default_data; memset(&default_data, 0, sizeof(blink::WebGamepads)); - default_data.length = 1; default_data.items[0].connected = true; default_data.items[0].buttonsLength = 1; ConstructService(default_data); @@ -185,7 +182,6 @@ const ppapi::ContentGamepadHardwareBuffer* buffer = static_cast<const ppapi::ContentGamepadHardwareBuffer*>( shared_memory.memory()); - EXPECT_EQ(button_down_data.length, buffer->buffer.length); EXPECT_EQ(button_down_data.items[0].buttonsLength, buffer->buffer.items[0].buttons_length); for (size_t i = 0; i < ppapi::WebKitGamepad::kButtonsLengthCap; i++) {
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index c9bb374..6b78477 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn
@@ -349,9 +349,6 @@ "//third_party/WebKit/public:blink_headers", ] deps = [ - # This looks needless as we have :mojo_bindings in public_deps, but it's - # needed because of allow_circular_includes_from. - ":mojo_bindings_cpp_sources", "//base", "//base/third_party/dynamic_annotations", "//build/util:webkit_version", @@ -384,7 +381,7 @@ "//media/gpu/ipc/client", "//media/gpu/ipc/common", "//media/midi", - "//media/midi:mojo_cpp_sources", + "//media/midi:mojo", "//mojo/common:common_base", "//mojo/edk/system", "//net", @@ -427,7 +424,7 @@ libs = [] ldflags = [] - allow_circular_includes_from = [ ":mojo_bindings_cpp_sources" ] + allow_circular_includes_from = [ ":mojo_bindings" ] if (is_android && use_seccomp_bpf) { set_sources_assignment_filter([])
diff --git a/content/public/common/BUILD.gn b/content/public/common/BUILD.gn index dc256d5..7e7f0eb 100644 --- a/content/public/common/BUILD.gn +++ b/content/public/common/BUILD.gn
@@ -254,7 +254,7 @@ deps = [ # This looks needless as we have //content/common in public_deps, but it's # needed because of allow_circular_includes_from. - "//content/common:mojo_bindings_cpp_sources", + "//content/common:mojo_bindings", "//ipc", "//media", "//mojo/common", @@ -281,7 +281,7 @@ # //content/common needs to include public headers. allow_circular_includes_from = [ "//content/common", - "//content/common:mojo_bindings_cpp_sources", + "//content/common:mojo_bindings", ] if (!enable_plugins) {
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index 1698254..3a28c2d 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -431,7 +431,7 @@ "//media/gpu/ipc/client", "//media/gpu/ipc/common", "//media/midi", - "//media/midi:mojo_cpp_sources", + "//media/midi:mojo", "//media/mojo/interfaces:remoting", "//mojo/common", "//mojo/edk/js",
diff --git a/content/renderer/input/main_thread_event_queue.cc b/content/renderer/input/main_thread_event_queue.cc index fe67fb24..b5fac300 100644 --- a/content/renderer/input/main_thread_event_queue.cc +++ b/content/renderer/input/main_thread_event_queue.cc
@@ -18,13 +18,8 @@ switch (event->event().type) { case blink::WebInputEvent::MouseMove: case blink::WebInputEvent::MouseWheel: - return true; case blink::WebInputEvent::TouchMove: - // TouchMoves that are blocking end up blocking scroll. Do not treat - // them as continuous events otherwise we will end up waiting up to an - // additional frame. - return static_cast<const blink::WebTouchEvent&>(event->event()) - .dispatchType != blink::WebInputEvent::Blocking; + return true; default: return false; } @@ -125,11 +120,6 @@ } } - // If handling rAF aligned touch input ACK non-cancelable events right - // away. - if (!non_blocking && IsRafAlignedEvent(*touch_event)) - non_blocking = true; - if (enable_non_blocking_due_to_main_thread_responsiveness_flag_ && touch_event->dispatchType == blink::WebInputEvent::Blocking) { bool passive_due_to_unresponsive_main = @@ -140,7 +130,12 @@ non_blocking = true; } } + // If the event is non-cancelable ACK it right away. + if (!non_blocking && + touch_event->dispatchType != blink::WebInputEvent::Blocking) + non_blocking = true; } + if (is_wheel && non_blocking) { // Adjust the |dispatchType| on the event since the compositor // determined all event listeners are passive. @@ -340,12 +335,7 @@ case blink::WebInputEvent::MouseWheel: return handle_raf_aligned_mouse_input_; case blink::WebInputEvent::TouchMove: - // TouchMoves that are blocking end up blocking scroll. Do not treat - // them as continuous events otherwise we will end up waiting up to an - // additional frame. - return static_cast<const blink::WebTouchEvent&>(event).dispatchType != - blink::WebInputEvent::Blocking && - handle_raf_aligned_touch_input_; + return handle_raf_aligned_touch_input_; default: return false; }
diff --git a/content/renderer/input/main_thread_event_queue_unittest.cc b/content/renderer/input/main_thread_event_queue_unittest.cc index b05d18f..b2585db 100644 --- a/content/renderer/input/main_thread_event_queue_unittest.cc +++ b/content/renderer/input/main_thread_event_queue_unittest.cc
@@ -266,7 +266,7 @@ HandleEvent(kEvents[3], INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING); EXPECT_EQ(1u, event_queue().size()); RunPendingTasksWithSimulatedRaf(); - histogram_tester.ExpectUniqueSample(kCoalescedCountHistogram, 2, 1); + histogram_tester.ExpectUniqueSample(kCoalescedCountHistogram, 2, 2); } TEST_P(MainThreadEventQueueTest, InterleavedEvents) { @@ -427,7 +427,7 @@ EXPECT_EQ(3u, event_queue().size()); EXPECT_TRUE(main_task_runner_->HasPendingTask()); - EXPECT_FALSE(needs_main_frame_); + EXPECT_TRUE(needs_main_frame_); main_task_runner_->RunUntilIdle(); } @@ -455,7 +455,7 @@ EXPECT_TRUE(needs_main_frame_); HandleEvent(kEvents[1], INPUT_EVENT_ACK_STATE_NOT_CONSUMED); EXPECT_EQ(1u, event_queue().size()); - EXPECT_TRUE(main_task_runner_->HasPendingTask()); + EXPECT_FALSE(main_task_runner_->HasPendingTask()); EXPECT_TRUE(needs_main_frame_); RunPendingTasksWithSimulatedRaf(); EXPECT_EQ(0u, event_queue().size());
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index d954d36..a24f66fe 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -1435,7 +1435,7 @@ "//media/capture", "//media/capture/mojo:capture_types", "//media/midi:midi", - "//media/midi:mojo_cpp_sources", + "//media/midi:mojo", "//mojo/edk/test:test_support", "//mojo/public/cpp/bindings", "//net:extras",
diff --git a/device/gamepad/gamepad_provider.cc b/device/gamepad/gamepad_provider.cc index 470bf45..79829184 100644 --- a/device/gamepad/gamepad_provider.cc +++ b/device/gamepad/gamepad_provider.cc
@@ -265,13 +265,10 @@ // Acquire the SeqLock. There is only ever one writer to this data. // See gamepad_shared_buffer.h. gamepad_shared_buffer_->WriteBegin(); - buffer->length = 0; for (unsigned i = 0; i < WebGamepads::itemsLengthCap; ++i) { PadState& state = pad_states_.get()[i]; // Must run through the map+sanitize here or CheckForUserGesture may fail. MapAndSanitizeGamepadData(&state, &buffer->items[i], sanitize_); - if (state.active_state) - buffer->length++; } gamepad_shared_buffer_->WriteEnd(); }
diff --git a/device/gamepad/gamepad_provider_unittest.cc b/device/gamepad/gamepad_provider_unittest.cc index 03b12638..e534d04 100644 --- a/device/gamepad/gamepad_provider_unittest.cc +++ b/device/gamepad/gamepad_provider_unittest.cc
@@ -80,7 +80,6 @@ TEST_F(GamepadProviderTest, MAYBE_PollingAccess) { WebGamepads test_data; memset(&test_data, 0, sizeof(WebGamepads)); - test_data.length = 1; test_data.items[0].connected = true; test_data.items[0].timestamp = 0; test_data.items[0].buttonsLength = 1; @@ -110,7 +109,6 @@ WebGamepads output; ReadGamepadHardwareBuffer(buffer, &output); - EXPECT_EQ(1u, output.length); EXPECT_EQ(1u, output.items[0].buttonsLength); EXPECT_EQ(1.f, output.items[0].buttons[0].value); EXPECT_EQ(true, output.items[0].buttons[0].pressed); @@ -119,10 +117,73 @@ EXPECT_EQ(0.5f, output.items[0].axes[1]); } +// http://crbug.com/106163, crbug.com/147549 +#if defined(OS_ANDROID) +#define MAYBE_ConnectDisconnectMultiple DISABLED_ConnectDisconnectMultiple +#else +#define MAYBE_ConnectDisconnectMultiple ConnectDisconnectMultiple +#endif +TEST_F(GamepadProviderTest, MAYBE_ConnectDisconnectMultiple) { + WebGamepads test_data; + test_data.items[0].connected = true; + test_data.items[0].timestamp = 0; + test_data.items[0].axesLength = 2; + test_data.items[0].axes[0] = -1.f; + test_data.items[0].axes[1] = .5f; + + test_data.items[1].connected = true; + test_data.items[1].timestamp = 0; + test_data.items[1].axesLength = 2; + test_data.items[1].axes[0] = 1.f; + test_data.items[1].axes[1] = -.5f; + + WebGamepads test_data_onedisconnected; + test_data_onedisconnected.items[1].connected = true; + test_data_onedisconnected.items[1].timestamp = 0; + test_data_onedisconnected.items[1].axesLength = 2; + test_data_onedisconnected.items[1].axes[0] = 1.f; + test_data_onedisconnected.items[1].axes[1] = -.5f; + + GamepadProvider* provider = CreateProvider(test_data); + provider->SetSanitizationEnabled(false); + provider->Resume(); + + base::RunLoop().RunUntilIdle(); + + mock_data_fetcher_->WaitForDataRead(); + + // Renderer-side, pull data out of poll buffer. + base::SharedMemoryHandle handle = provider->GetSharedMemoryHandleForProcess( + base::GetCurrentProcessHandle()); + std::unique_ptr<base::SharedMemory> shared_memory( + new base::SharedMemory(handle, true)); + EXPECT_TRUE(shared_memory->Map(sizeof(GamepadHardwareBuffer))); + + GamepadHardwareBuffer* buffer = + static_cast<GamepadHardwareBuffer*>(shared_memory->memory()); + WebGamepads output; + ReadGamepadHardwareBuffer(buffer, &output); + + EXPECT_EQ(2u, output.items[0].axesLength); + EXPECT_EQ(-1.f, output.items[0].axes[0]); + EXPECT_EQ(0.5f, output.items[0].axes[1]); + EXPECT_EQ(2u, output.items[1].axesLength); + EXPECT_EQ(1.f, output.items[1].axes[0]); + EXPECT_EQ(-0.5f, output.items[1].axes[1]); + + mock_data_fetcher_->SetTestData(test_data_onedisconnected); + mock_data_fetcher_->WaitForDataReadAndCallbacksIssued(); + ReadGamepadHardwareBuffer(buffer, &output); + + EXPECT_EQ(0u, output.items[0].axesLength); + EXPECT_EQ(2u, output.items[1].axesLength); + EXPECT_EQ(1.f, output.items[1].axes[0]); + EXPECT_EQ(-0.5f, output.items[1].axes[1]); +} + // Tests that waiting for a user gesture works properly. TEST_F(GamepadProviderTest, UserGesture) { WebGamepads no_button_data; - no_button_data.length = 1; no_button_data.items[0].connected = true; no_button_data.items[0].timestamp = 0; no_button_data.items[0].buttonsLength = 1; @@ -170,7 +231,6 @@ // Tests that waiting for a user gesture works properly. TEST_F(GamepadProviderTest, MAYBE_Sanitization) { WebGamepads active_data; - active_data.length = 1; active_data.items[0].connected = true; active_data.items[0].timestamp = 0; active_data.items[0].buttonsLength = 1; @@ -180,7 +240,6 @@ active_data.items[0].axes[0] = -1.f; WebGamepads zero_data; - zero_data.length = 1; zero_data.items[0].connected = true; zero_data.items[0].timestamp = 0; zero_data.items[0].buttonsLength = 1; @@ -212,7 +271,6 @@ // Initial data should all be zeroed out due to sanitization, even though the // gamepad reported input - EXPECT_EQ(1u, output.length); EXPECT_EQ(1u, output.items[0].buttonsLength); EXPECT_EQ(0.f, output.items[0].buttons[0].value); EXPECT_FALSE(output.items[0].buttons[0].pressed); @@ -227,7 +285,6 @@ ReadGamepadHardwareBuffer(buffer, &output); // Should still read zero, which is now an accurate reflection of the data - EXPECT_EQ(1u, output.length); EXPECT_EQ(1u, output.items[0].buttonsLength); EXPECT_EQ(0.f, output.items[0].buttons[0].value); EXPECT_FALSE(output.items[0].buttons[0].pressed); @@ -242,7 +299,6 @@ ReadGamepadHardwareBuffer(buffer, &output); // Should now accurately reflect the reported data. - EXPECT_EQ(1u, output.length); EXPECT_EQ(1u, output.items[0].buttonsLength); EXPECT_EQ(1.f, output.items[0].buttons[0].value); EXPECT_TRUE(output.items[0].buttons[0].pressed);
diff --git a/device/serial/serial_device_enumerator_mac.cc b/device/serial/serial_device_enumerator_mac.cc index 4bf3e5ed..3d82328 100644 --- a/device/serial/serial_device_enumerator_mac.cc +++ b/device/serial/serial_device_enumerator_mac.cc
@@ -10,6 +10,7 @@ #include <algorithm> #include <memory> +#include <unordered_set> #include <utility> #include "base/files/file_enumerator.h" @@ -214,30 +215,27 @@ SerialDeviceEnumeratorMac::~SerialDeviceEnumeratorMac() {} mojo::Array<serial::DeviceInfoPtr> SerialDeviceEnumeratorMac::GetDevices() { - mojo::Array<serial::DeviceInfoPtr> newDevices = GetDevicesNew(); - mojo::Array<serial::DeviceInfoPtr> oldDevices = GetDevicesOld(); + mojo::Array<serial::DeviceInfoPtr> devices = GetDevicesNew(); + mojo::Array<serial::DeviceInfoPtr> old_devices = GetDevicesOld(); UMA_HISTOGRAM_SPARSE_SLOWLY( "Hardware.Serial.NewMinusOldDeviceListSize", - Clamp(newDevices.size() - oldDevices.size(), -10, 10)); + Clamp(devices.size() - old_devices.size(), -10, 10)); // Add devices found from both the new and old methods of enumeration. If a // device is found using both the new and the old enumeration method, then we // take the device from the new enumeration method because it's able to // collect more information. We do this by inserting the new devices first, // because insertions are ignored if the key already exists. - mojo::Map<mojo::String, serial::DeviceInfoPtr> deviceMap; - for (unsigned long i = 0; i < newDevices.size(); i++) { - deviceMap.insert(newDevices[i]->path, newDevices[i].Clone()); + std::unordered_set<std::string> devices_seen; + for (const auto& device : devices) { + bool inserted = devices_seen.insert(device->path).second; + DCHECK(inserted); } - for (unsigned long i = 0; i < oldDevices.size(); i++) { - deviceMap.insert(oldDevices[i]->path, oldDevices[i].Clone()); + for (auto& device : old_devices) { + if (devices_seen.insert(device->path).second) + devices.push_back(std::move(device)); } - - mojo::Array<mojo::String> paths; - mojo::Array<serial::DeviceInfoPtr> devices; - deviceMap.DecomposeMapTo(&paths, &devices); - return devices; }
diff --git a/device/serial/serial_device_enumerator_win.cc b/device/serial/serial_device_enumerator_win.cc index 149331d..aee8e36 100644 --- a/device/serial/serial_device_enumerator_win.cc +++ b/device/serial/serial_device_enumerator_win.cc
@@ -10,6 +10,7 @@ #include <windows.h> #include <memory> +#include <unordered_set> #include "base/metrics/histogram_macros.h" #include "base/strings/string_number_conversions.h" @@ -164,30 +165,27 @@ SerialDeviceEnumeratorWin::~SerialDeviceEnumeratorWin() {} mojo::Array<serial::DeviceInfoPtr> SerialDeviceEnumeratorWin::GetDevices() { - mojo::Array<serial::DeviceInfoPtr> newDevices = GetDevicesNew(); - mojo::Array<serial::DeviceInfoPtr> oldDevices = GetDevicesOld(); + mojo::Array<serial::DeviceInfoPtr> devices = GetDevicesNew(); + mojo::Array<serial::DeviceInfoPtr> old_devices = GetDevicesOld(); UMA_HISTOGRAM_SPARSE_SLOWLY( "Hardware.Serial.NewMinusOldDeviceListSize", - Clamp((int)newDevices.size() - (int)oldDevices.size(), -10, 10)); + Clamp(devices.size() - old_devices.size(), -10, 10)); // Add devices found from both the new and old methods of enumeration. If a // device is found using both the new and the old enumeration method, then we // take the device from the new enumeration method because it's able to // collect more information. We do this by inserting the new devices first, // because insertions are ignored if the key already exists. - mojo::Map<mojo::String, serial::DeviceInfoPtr> deviceMap; - for (unsigned long i = 0; i < newDevices.size(); i++) { - deviceMap.insert(newDevices[i]->path, newDevices[i].Clone()); + std::unordered_set<std::string> devices_seen; + for (const auto& device : devices) { + bool inserted = devices_seen.insert(device->path).second; + DCHECK(inserted); } - for (unsigned long i = 0; i < oldDevices.size(); i++) { - deviceMap.insert(oldDevices[i]->path, oldDevices[i].Clone()); + for (auto& device : old_devices) { + if (devices_seen.insert(device->path).second) + devices.push_back(std::move(device)); } - - mojo::Array<mojo::String> paths; - mojo::Array<serial::DeviceInfoPtr> devices; - deviceMap.DecomposeMapTo(&paths, &devices); - return devices; }
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc index 40ca073a..3600c198 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc
@@ -3397,7 +3397,8 @@ // EXPECT_EQ can't be used to compare function pointers EXPECT_TRUE( gl::MockGLInterface::GetGLProcAddress("glInvalidateFramebuffer") != - gl::g_driver_gl.fn.glDiscardFramebufferEXTFn); + reinterpret_cast<gl::GLFunctionPointerType>( + gl::g_driver_gl.fn.glDiscardFramebufferEXTFn)); EXPECT_TRUE( gl::MockGLInterface::GetGLProcAddress("glInvalidateFramebuffer") != gl::MockGLInterface::GetGLProcAddress("glDiscardFramebufferEXT")); @@ -3447,7 +3448,8 @@ // EXPECT_EQ can't be used to compare function pointers EXPECT_TRUE( gl::MockGLInterface::GetGLProcAddress("glDiscardFramebufferEXT") == - gl::g_driver_gl.fn.glDiscardFramebufferEXTFn); + reinterpret_cast<gl::GLFunctionPointerType>( + gl::g_driver_gl.fn.glDiscardFramebufferEXTFn)); const GLenum target = GL_FRAMEBUFFER; const GLsizei count = 1; @@ -3489,7 +3491,8 @@ // EXPECT_EQ can't be used to compare function pointers. EXPECT_TRUE( gl::MockGLInterface::GetGLProcAddress("glDiscardFramebufferEXT") == - gl::g_driver_gl.fn.glDiscardFramebufferEXTFn); + reinterpret_cast<gl::GLFunctionPointerType>( + gl::g_driver_gl.fn.glDiscardFramebufferEXTFn)); const GLenum target = GL_FRAMEBUFFER; const GLsizei count = 1; @@ -3712,7 +3715,8 @@ // and the framebuffer as incomplete. EXPECT_TRUE( gl::MockGLInterface::GetGLProcAddress("glDiscardFramebufferEXT") == - gl::g_driver_gl.fn.glDiscardFramebufferEXTFn); + reinterpret_cast<gl::GLFunctionPointerType>( + gl::g_driver_gl.fn.glDiscardFramebufferEXTFn)); const GLenum target = GL_FRAMEBUFFER; const GLsizei count = 1;
diff --git a/media/base/pipeline_impl.cc b/media/base/pipeline_impl.cc index 85d470a..85b54ec 100644 --- a/media/base/pipeline_impl.cc +++ b/media/base/pipeline_impl.cc
@@ -958,6 +958,7 @@ client_ = client; seek_cb_ = seek_cb; last_media_time_ = base::TimeDelta(); + seek_time_ = kNoTimestamp; std::unique_ptr<TextRenderer> text_renderer; if (base::CommandLine::ForCurrentProcess()->HasSwitch( @@ -1039,6 +1040,7 @@ DCHECK(seek_cb_.is_null()); seek_cb_ = seek_cb; + seek_time_ = time; last_media_time_ = base::TimeDelta(); media_task_runner_->PostTask( FROM_HERE, base::Bind(&RendererWrapper::Seek, @@ -1069,6 +1071,7 @@ DCHECK(IsRunning()); DCHECK(seek_cb_.is_null()); seek_cb_ = seek_cb; + seek_time_ = time; last_media_time_ = base::TimeDelta(); media_task_runner_->PostTask( @@ -1123,6 +1126,14 @@ base::TimeDelta PipelineImpl::GetMediaTime() const { DCHECK(thread_checker_.CalledOnValidThread()); + // Don't trust renderer time during a pending seek. Renderer may return + // pre-seek time which may corrupt |last_media_time_| used for clamping. + if (seek_time_ != kNoTimestamp) { + DVLOG(3) << __func__ << ": (seeking) " << seek_time_.InMilliseconds() + << " ms"; + return seek_time_; + } + base::TimeDelta media_time = renderer_wrapper_->GetMediaTime(); // Clamp current media time to the last reported value, this prevents higher @@ -1301,6 +1312,8 @@ DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(IsRunning()); + seek_time_ = kNoTimestamp; + DCHECK(!seek_cb_.is_null()); base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK); }
diff --git a/media/base/pipeline_impl.h b/media/base/pipeline_impl.h index 624e3e7..0e6d929 100644 --- a/media/base/pipeline_impl.h +++ b/media/base/pipeline_impl.h
@@ -173,6 +173,11 @@ // reported to JavaScript from going backwards in time. mutable base::TimeDelta last_media_time_; + // Set by Seek(), used in place of asking the renderer for current media time + // while a seek is pending. Renderer's time cannot be trusted until the seek + // has completed. + base::TimeDelta seek_time_; + base::ThreadChecker thread_checker_; base::WeakPtrFactory<PipelineImpl> weak_factory_;
diff --git a/media/base/pipeline_impl_unittest.cc b/media/base/pipeline_impl_unittest.cc index 424450ea..7f0be87 100644 --- a/media/base/pipeline_impl_unittest.cc +++ b/media/base/pipeline_impl_unittest.cc
@@ -824,6 +824,43 @@ EXPECT_EQ(kMediaTime, pipeline_->GetMediaTime()); } +// Seeking posts a task from main thread to media thread to seek the renderer, +// resetting its internal clock. Calling GetMediaTime() should be safe even +// when the renderer has not performed the seek (simulated by its continuing +// to return the pre-seek time). Verifies fix for http://crbug.com/675556 +TEST_F(PipelineImplTest, GetMediaTimeAfterSeek) { + CreateAudioStream(); + MockDemuxerStreamVector streams; + streams.push_back(audio_stream()); + SetDemuxerExpectations(&streams); + SetRendererExpectations(); + StartPipelineAndExpect(PIPELINE_OK); + + // Pipeline should report the same media time returned by the renderer. + base::TimeDelta kMediaTime = base::TimeDelta::FromSeconds(2); + EXPECT_CALL(*renderer_, GetMediaTime()).WillRepeatedly(Return(kMediaTime)); + EXPECT_EQ(kMediaTime, pipeline_->GetMediaTime()); + + // Seek backward 1 second. Do not run RunLoop to ensure renderer is not yet + // notified of the seek (via media thread). + base::TimeDelta kSeekTime = kMediaTime - base::TimeDelta::FromSeconds(1); + ExpectSeek(kSeekTime, false); + pipeline_->Seek(kSeekTime, base::Bind(&CallbackHelper::OnSeek, + base::Unretained(&callbacks_))); + + // Verify pipeline returns the seek time in spite of renderer returning the + // stale media time. + EXPECT_EQ(kSeekTime, pipeline_->GetMediaTime()); + EXPECT_EQ(kMediaTime, renderer_->GetMediaTime()); + + // Allow seek task to post to the renderer. + base::RunLoop().RunUntilIdle(); + + // With seek completed, pipeline should again return the renderer's media time + // (as long as media time is moving forward). + EXPECT_EQ(kMediaTime, pipeline_->GetMediaTime()); +} + class PipelineTeardownTest : public PipelineImplTest { public: enum TeardownState {
diff --git a/media/gpu/media_foundation_video_encode_accelerator_win.cc b/media/gpu/media_foundation_video_encode_accelerator_win.cc index a43e2ad..17ba2b2 100644 --- a/media/gpu/media_foundation_video_encode_accelerator_win.cc +++ b/media/gpu/media_foundation_video_encode_accelerator_win.cc
@@ -34,8 +34,8 @@ const int32_t kDefaultTargetBitrate = 5000000; const size_t kMaxFrameRateNumerator = 30; const size_t kMaxFrameRateDenominator = 1; -const size_t kMaxResolutionWidth = 3840; -const size_t kMaxResolutionHeight = 2176; +const size_t kMaxResolutionWidth = 1920; +const size_t kMaxResolutionHeight = 1088; const size_t kNumInputBuffers = 3; // Media Foundation uses 100 nanosecond units for time, see // https://msdn.microsoft.com/en-us/library/windows/desktop/ms697282(v=vs.85).aspx @@ -46,6 +46,9 @@ L"mf.dll", L"mfplat.dll", }; +// Resolutions that some platforms support, should be listed in ascending order. +constexpr const gfx::Size kOptionalMaxResolutions[] = {gfx::Size(3840, 2176)}; + } // namespace class MediaFoundationVideoEncodeAccelerator::EncodeOutput { @@ -101,7 +104,6 @@ DCHECK(main_client_task_runner_->BelongsToCurrentThread()); SupportedProfiles profiles; - target_bitrate_ = kDefaultTargetBitrate; frame_rate_ = kMaxFrameRateNumerator / kMaxFrameRateDenominator; input_visible_size_ = gfx::Size(kMaxResolutionWidth, kMaxResolutionHeight); @@ -112,6 +114,14 @@ << "Hardware encode acceleration is not available on this platform."; return profiles; } + + gfx::Size highest_supported_resolution = input_visible_size_; + for (const auto& resolution : kOptionalMaxResolutions) { + DCHECK_GT(resolution.GetArea(), highest_supported_resolution.GetArea()); + if (!IsResolutionSupported(resolution)) + break; + highest_supported_resolution = resolution; + } ReleaseEncoderResources(); SupportedProfile profile; @@ -120,7 +130,7 @@ profile.profile = H264PROFILE_BASELINE; profile.max_framerate_numerator = kMaxFrameRateNumerator; profile.max_framerate_denominator = kMaxFrameRateDenominator; - profile.max_resolution = gfx::Size(kMaxResolutionWidth, kMaxResolutionHeight); + profile.max_resolution = highest_supported_resolution; profiles.push_back(profile); return profiles; } @@ -449,6 +459,28 @@ return SUCCEEDED(hr); } +bool MediaFoundationVideoEncodeAccelerator::IsResolutionSupported( + const gfx::Size& resolution) { + DCHECK(main_client_task_runner_->BelongsToCurrentThread()); + DCHECK(encoder_); + + HRESULT hr = + MFSetAttributeSize(imf_output_media_type_.get(), MF_MT_FRAME_SIZE, + resolution.width(), resolution.height()); + RETURN_ON_HR_FAILURE(hr, "Couldn't set frame size", false); + hr = encoder_->SetOutputType(output_stream_id_, imf_output_media_type_.get(), + 0); + RETURN_ON_HR_FAILURE(hr, "Couldn't set output media type", false); + + hr = MFSetAttributeSize(imf_input_media_type_.get(), MF_MT_FRAME_SIZE, + resolution.width(), resolution.height()); + RETURN_ON_HR_FAILURE(hr, "Couldn't set frame size", false); + hr = encoder_->SetInputType(input_stream_id_, imf_input_media_type_.get(), 0); + RETURN_ON_HR_FAILURE(hr, "Couldn't set input media type", false); + + return true; +} + void MediaFoundationVideoEncodeAccelerator::NotifyError( VideoEncodeAccelerator::Error error) { DCHECK(encoder_thread_task_runner_->BelongsToCurrentThread());
diff --git a/media/gpu/media_foundation_video_encode_accelerator_win.h b/media/gpu/media_foundation_video_encode_accelerator_win.h index cd67630..1720a78b 100644 --- a/media/gpu/media_foundation_video_encode_accelerator_win.h +++ b/media/gpu/media_foundation_video_encode_accelerator_win.h
@@ -76,6 +76,10 @@ // Initializes encoder parameters for real-time use. bool SetEncoderModes(); + // Returns true if we can initialize input and output samples with the given + // frame size, otherwise false. + bool IsResolutionSupported(const gfx::Size& size); + // Helper function to notify the client of an error on // |main_client_task_runner_|. void NotifyError(VideoEncodeAccelerator::Error error);
diff --git a/mojo/public/cpp/bindings/BUILD.gn b/mojo/public/cpp/bindings/BUILD.gn index 1b4dfa6f..4f436d50a 100644 --- a/mojo/public/cpp/bindings/BUILD.gn +++ b/mojo/public/cpp/bindings/BUILD.gn
@@ -116,7 +116,6 @@ "map.h", "map_data_view.h", "map_traits.h", - "map_traits_standard.h", "map_traits_stl.h", "message.h", "message_header_validator.h", @@ -128,7 +127,6 @@ "pipe_control_message_handler_delegate.h", "pipe_control_message_proxy.h", "scoped_interface_endpoint_handle.h", - "stl_converters.h", "string.h", "string_data_view.h", "string_traits.h",
diff --git a/mojo/public/cpp/bindings/lib/array_serialization.h b/mojo/public/cpp/bindings/lib/array_serialization.h index 9e68f452..acfd4e3e 100644 --- a/mojo/public/cpp/bindings/lib/array_serialization.h +++ b/mojo/public/cpp/bindings/lib/array_serialization.h
@@ -19,7 +19,6 @@ #include "mojo/public/cpp/bindings/lib/serialization_forward.h" #include "mojo/public/cpp/bindings/lib/template_util.h" #include "mojo/public/cpp/bindings/lib/validation_errors.h" -#include "mojo/public/cpp/bindings/map.h" namespace mojo { namespace internal {
diff --git a/mojo/public/cpp/bindings/lib/serialization.h b/mojo/public/cpp/bindings/lib/serialization.h index a570e2205..8fac6396 100644 --- a/mojo/public/cpp/bindings/lib/serialization.h +++ b/mojo/public/cpp/bindings/lib/serialization.h
@@ -18,7 +18,6 @@ #include "mojo/public/cpp/bindings/lib/native_struct_serialization.h" #include "mojo/public/cpp/bindings/lib/string_serialization.h" #include "mojo/public/cpp/bindings/lib/template_util.h" -#include "mojo/public/cpp/bindings/map_traits_standard.h" #include "mojo/public/cpp/bindings/map_traits_stl.h" #include "mojo/public/cpp/bindings/string_traits_standard.h" #include "mojo/public/cpp/bindings/string_traits_stl.h"
diff --git a/mojo/public/cpp/bindings/map.h b/mojo/public/cpp/bindings/map.h index ec40df3..c1ba075 100644 --- a/mojo/public/cpp/bindings/map.h +++ b/mojo/public/cpp/bindings/map.h
@@ -5,300 +5,12 @@ #ifndef MOJO_PUBLIC_CPP_BINDINGS_MAP_H_ #define MOJO_PUBLIC_CPP_BINDINGS_MAP_H_ -#include <stddef.h> #include <map> #include <unordered_map> #include <utility> -#include "base/logging.h" -#include "base/macros.h" -#include "mojo/public/cpp/bindings/array.h" -#include "mojo/public/cpp/bindings/lib/map_data_internal.h" -#include "mojo/public/cpp/bindings/lib/template_util.h" -#include "mojo/public/cpp/bindings/type_converter.h" - namespace mojo { -// A move-only map that can handle move-only values. Map has the following -// characteristics: -// - The map itself can be null, and this is distinct from empty. -// - Keys must not be move-only. -// - The Key-type's "<" operator is used to sort the entries, and also is -// used to determine equality of the key values. -// - There can only be one entry per unique key. -// - Values of move-only types will be moved into the Map when they are added -// using the insert() method. -template <typename K, typename V> -class Map { - public: - using Key = K; - using Value = V; - - // Map keys cannot be move only classes. - static_assert(!internal::IsMoveOnlyType<Key>::value, - "Map keys cannot be move only types."); - - using Iterator = typename std::map<Key, Value>::iterator; - using ConstIterator = typename std::map<Key, Value>::const_iterator; - - // Constructs an empty map. - Map() : is_null_(false) {} - // Constructs a null map. - Map(std::nullptr_t null_pointer) : is_null_(true) {} - - // Constructs a non-null Map containing the specified |keys| mapped to the - // corresponding |values|. - Map(mojo::Array<Key> keys, mojo::Array<Value> values) : is_null_(false) { - DCHECK(keys.size() == values.size()); - for (size_t i = 0; i < keys.size(); ++i) - map_.insert(std::make_pair(keys[i], std::move(values[i]))); - } - - ~Map() {} - - Map(std::map<Key, Value>&& other) : map_(std::move(other)), is_null_(false) {} - Map(Map&& other) : is_null_(true) { Take(&other); } - - Map& operator=(std::map<Key, Value>&& other) { - is_null_ = false; - map_ = std::move(other); - return *this; - } - Map& operator=(Map&& other) { - Take(&other); - return *this; - } - - Map& operator=(std::nullptr_t null_pointer) { - is_null_ = true; - map_.clear(); - return *this; - } - - // Copies the contents of some other type of map into a new Map using a - // TypeConverter. A TypeConverter for std::map to Map is defined below. - template <typename U> - static Map From(const U& other) { - return TypeConverter<Map, U>::Convert(other); - } - - // Copies the contents of the Map into some other type of map. A TypeConverter - // for Map to std::map is defined below. - template <typename U> - U To() const { - return TypeConverter<U, Map>::Convert(*this); - } - - // Indicates whether the map is null (which is distinct from empty). - bool is_null() const { return is_null_; } - - // Indicates whether the map is empty (which is distinct from null). - bool empty() const { return map_.empty() && !is_null_; } - - // Indicates the number of keys in the map, which will be zero if the map is - // null. - size_t size() const { return map_.size(); } - - // Inserts a key-value pair into the map. Like std::map, this does not insert - // |value| if |key| is already a member of the map. - void insert(const Key& key, const Value& value) { - is_null_ = false; - map_.insert(std::make_pair(key, value)); - } - void insert(const Key& key, Value&& value) { - is_null_ = false; - map_.insert(std::make_pair(key, std::move(value))); - } - - // Returns a reference to the value associated with the specified key, - // crashing the process if the key is not present in the map. - Value& at(const Key& key) { return map_.at(key); } - const Value& at(const Key& key) const { return map_.at(key); } - - // Returns a reference to the value associated with the specified key, - // creating a new entry if the key is not already present in the map. A - // newly-created value will be value-initialized (meaning that it will be - // initialized by the default constructor of the value type, if any, or else - // will be zero-initialized). - Value& operator[](const Key& key) { - is_null_ = false; - return map_[key]; - } - - // Sets the map to empty (even if previously it was null). - void SetToEmpty() { - is_null_ = false; - map_.clear(); - } - - // Returns a const reference to the std::map managed by this class. If this - // object is null, the return value will be an empty map. - const std::map<Key, Value>& storage() const { return map_; } - - // Passes the underlying storage and resets this map to null. - std::map<Key, Value> PassStorage() { - is_null_ = true; - return std::move(map_); - } - - operator const std::map<Key, Value>&() const { return map_; } - - // Swaps the contents of this Map with another Map of the same type (including - // nullness). - void Swap(Map<Key, Value>* other) { - std::swap(is_null_, other->is_null_); - map_.swap(other->map_); - } - - // Swaps the contents of this Map with an std::map containing keys and values - // of the same type. Since std::map cannot represent the null state, the - // std::map will be empty if Map is null. The Map will always be left in a - // non-null state. - void Swap(std::map<Key, Value>* other) { - is_null_ = false; - map_.swap(*other); - } - - // Removes all contents from the Map and places them into parallel key/value - // arrays. Each key will be copied from the source to the destination, and - // values will be copied unless their type is designated move-only, in which - // case they will be moved. Either way, the Map will be left in a null state. - void DecomposeMapTo(mojo::Array<Key>* keys, mojo::Array<Value>* values) { - std::vector<Key> key_vector; - key_vector.reserve(map_.size()); - std::vector<Value> value_vector; - value_vector.reserve(map_.size()); - - for (auto& entry : map_) { - key_vector.push_back(entry.first); - value_vector.push_back(std::move(entry.second)); - } - - map_.clear(); - is_null_ = true; - - keys->Swap(&key_vector); - values->Swap(&value_vector); - } - - // Returns a new Map that contains a copy of the contents of this map. If the - // key/value type defines a Clone() method, it will be used; otherwise copy - // constructor/assignment will be used. - // - // Please note that calling this method will fail compilation if the key/value - // type cannot be cloned (which usually means that it is a Mojo handle type or - // a type containing Mojo handles). - Map Clone() const { - Map result; - result.is_null_ = is_null_; - for (auto it = map_.begin(); it != map_.end(); ++it) { - result.map_.insert(std::make_pair(internal::Clone(it->first), - internal::Clone(it->second))); - } - return result; - } - - // Indicates whether the contents of this map are equal to those of another - // Map (including nullness). If the key/value type defines an Equals() method, - // it will be used; otherwise == operator will be used. - bool Equals(const Map& other) const { - if (is_null() != other.is_null()) - return false; - if (size() != other.size()) - return false; - auto i = begin(); - auto j = other.begin(); - while (i != end()) { - if (!internal::Equals(i->first, j->first)) - return false; - if (!internal::Equals(i->second, j->second)) - return false; - ++i; - ++j; - } - return true; - } - - // Provide read-only iteration over map members in a way similar to STL - // collections. - ConstIterator begin() const { return map_.begin(); } - Iterator begin() { return map_.begin(); } - - ConstIterator end() const { return map_.end(); } - Iterator end() { return map_.end(); } - - // Returns the iterator pointing to the entry for |key|, if present, or else - // returns end(). - ConstIterator find(const Key& key) const { return map_.find(key); } - Iterator find(const Key& key) { return map_.find(key); } - - private: - typedef std::map<Key, Value> Map::*Testable; - - public: - // The Map may be used in boolean expressions to determine if it is non-null, - // but is not implicitly convertible to an actual bool value (which would be - // dangerous). - operator Testable() const { return is_null_ ? 0 : &Map::map_; } - - private: - // Forbid the == and != operators explicitly, otherwise Map will be converted - // to Testable to do == or != comparison. - template <typename T, typename U> - bool operator==(const Map<T, U>& other) const = delete; - template <typename T, typename U> - bool operator!=(const Map<T, U>& other) const = delete; - - void Take(Map* other) { - operator=(nullptr); - Swap(other); - } - - std::map<Key, Value> map_; - bool is_null_; - - DISALLOW_COPY_AND_ASSIGN(Map); -}; - -// Copies the contents of an std::map to a new Map, optionally changing the -// types of the keys and values along the way using TypeConverter. -template <typename MojoKey, - typename MojoValue, - typename STLKey, - typename STLValue> -struct TypeConverter<Map<MojoKey, MojoValue>, std::map<STLKey, STLValue>> { - static Map<MojoKey, MojoValue> Convert( - const std::map<STLKey, STLValue>& input) { - Map<MojoKey, MojoValue> result; - for (auto& pair : input) { - result.insert(TypeConverter<MojoKey, STLKey>::Convert(pair.first), - TypeConverter<MojoValue, STLValue>::Convert(pair.second)); - } - return result; - } -}; - -// Copies the contents of a Map to an std::map, optionally changing the types of -// the keys and values along the way using TypeConverter. -template <typename MojoKey, - typename MojoValue, - typename STLKey, - typename STLValue> -struct TypeConverter<std::map<STLKey, STLValue>, Map<MojoKey, MojoValue>> { - static std::map<STLKey, STLValue> Convert( - const Map<MojoKey, MojoValue>& input) { - std::map<STLKey, STLValue> result; - if (!input.is_null()) { - for (auto it = input.begin(); it != input.end(); ++it) { - result.insert(std::make_pair( - TypeConverter<STLKey, MojoKey>::Convert(it->first), - TypeConverter<STLValue, MojoValue>::Convert(it->second))); - } - } - return result; - } -}; - // TODO(yzshen): These conversion functions should be removed and callsites // should be revisited and changed to use the same map type. template <typename Key, typename Value>
diff --git a/mojo/public/cpp/bindings/map_traits_standard.h b/mojo/public/cpp/bindings/map_traits_standard.h deleted file mode 100644 index 0c76890..0000000 --- a/mojo/public/cpp/bindings/map_traits_standard.h +++ /dev/null
@@ -1,53 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MOJO_PUBLIC_CPP_BINDINGS_MAP_TRAITS_STANDARD_H_ -#define MOJO_PUBLIC_CPP_BINDINGS_MAP_TRAITS_STANDARD_H_ - -#include "mojo/public/cpp/bindings/map.h" -#include "mojo/public/cpp/bindings/map_traits.h" - -namespace mojo { - -template <typename K, typename V> -struct MapTraits<Map<K, V>> { - using Key = K; - using Value = V; - using Iterator = typename Map<K, V>::Iterator; - using ConstIterator = typename Map<K, V>::ConstIterator; - - static bool IsNull(const Map<K, V>& input) { return input.is_null(); } - static void SetToNull(Map<K, V>* output) { *output = nullptr; } - - static size_t GetSize(const Map<K, V>& input) { return input.size(); } - - static ConstIterator GetBegin(const Map<K, V>& input) { - return input.begin(); - } - static Iterator GetBegin(Map<K, V>& input) { return input.begin(); } - - static void AdvanceIterator(ConstIterator& iterator) { iterator++; } - static void AdvanceIterator(Iterator& iterator) { iterator++; } - - static const K& GetKey(Iterator& iterator) { return iterator->first; } - static const K& GetKey(ConstIterator& iterator) { return iterator->first; } - - static V& GetValue(Iterator& iterator) { return iterator->second; } - static const V& GetValue(ConstIterator& iterator) { return iterator->second; } - - static bool Insert(Map<K, V>& input, const K& key, V&& value) { - input.insert(key, std::forward<V>(value)); - return true; - } - static bool Insert(Map<K, V>& input, const K& key, const V& value) { - input.insert(key, value); - return true; - } - - static void SetToEmpty(Map<K, V>* output) { output->SetToEmpty(); } -}; - -} // namespace mojo - -#endif // MOJO_PUBLIC_CPP_BINDINGS_MAP_TRAITS_STANDARD_H_
diff --git a/mojo/public/cpp/bindings/stl_converters.h b/mojo/public/cpp/bindings/stl_converters.h deleted file mode 100644 index 92b2924e..0000000 --- a/mojo/public/cpp/bindings/stl_converters.h +++ /dev/null
@@ -1,245 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MOJO_PUBLIC_CPP_BINDINGS_STL_CONVERTERS_H_ -#define MOJO_PUBLIC_CPP_BINDINGS_STL_CONVERTERS_H_ - -#include <map> -#include <string> -#include <type_traits> -#include <vector> - -#include "mojo/public/cpp/bindings/array.h" -#include "mojo/public/cpp/bindings/map.h" -#include "mojo/public/cpp/bindings/string.h" - -// Two functions are defined to facilitate conversion between -// mojo::Array/Map/String and std::vector/map/string: mojo::UnwrapToSTLType() -// recursively convert mojo types to STL types; mojo::WrapSTLType() does the -// opposite. For example: -// mojo::Array<mojo::Map<mojo::String, mojo::Array<int32_t>>> mojo_obj; -// -// std::vector<std::map<std::string, std::vector<int32_t>>> stl_obj = -// mojo::UnwrapToSTLType(std::move(mojo_obj)); -// -// mojo_obj = mojo::WrapSTLType(std::move(stl_obj)); -// -// Notes: -// - The conversion moves as much contents as possible. The two functions both -// take an rvalue ref as input in order to avoid accidental copies. -// - Because std::vector/map/string cannot express null, UnwrapToSTLType() -// converts null mojo::Array/Map/String to empty. -// - The recursive conversion stops at any types that are not the types listed -// above. For example, unwrapping mojo::Array<StructContainingMojoMap> will -// result in std::vector<StructContainingMojoMap>. It won't convert -// mojo::Map inside the struct. - -namespace mojo { -namespace internal { - -template <typename T> -struct UnwrapTraits; - -template <typename T> -struct UnwrapShouldGoDeeper { - public: - static const bool value = - !std::is_same<T, typename UnwrapTraits<T>::Type>::value; -}; - -template <typename T> -struct UnwrapTraits { - public: - using Type = T; - static Type Unwrap(T input) { return input; } -}; - -template <typename T> -struct UnwrapTraits<Array<T>> { - public: - using Type = std::vector<typename UnwrapTraits<T>::Type>; - - static Type Unwrap(Array<T> input) { - return Helper<T>::Run(std::move(input)); - } - - private: - template <typename U, bool should_go_deeper = UnwrapShouldGoDeeper<U>::value> - struct Helper {}; - - template <typename U> - struct Helper<U, true> { - public: - static Type Run(Array<T> input) { - Type output; - output.reserve(input.size()); - for (size_t i = 0; i < input.size(); ++i) - output.push_back(UnwrapTraits<T>::Unwrap(std::move(input[i]))); - return output; - } - }; - - template <typename U> - struct Helper<U, false> { - public: - static Type Run(Array<T> input) { return input.PassStorage(); } - }; -}; - -template <typename K, typename V> -struct UnwrapTraits<Map<K, V>> { - public: - using Type = - std::map<typename UnwrapTraits<K>::Type, typename UnwrapTraits<V>::Type>; - - static Type Unwrap(Map<K, V> input) { - return Helper<K, V>::Run(std::move(input)); - } - - private: - template <typename X, - typename Y, - bool should_go_deeper = UnwrapShouldGoDeeper<X>::value || - UnwrapShouldGoDeeper<Y>::value> - struct Helper {}; - - template <typename X, typename Y> - struct Helper<X, Y, true> { - public: - static Type Run(Map<K, V> input) { - std::map<K, V> input_storage = input.PassStorage(); - Type output; - for (auto& pair : input_storage) { - output.insert( - std::make_pair(UnwrapTraits<K>::Unwrap(pair.first), - UnwrapTraits<V>::Unwrap(std::move(pair.second)))); - } - return output; - } - }; - - template <typename X, typename Y> - struct Helper<X, Y, false> { - public: - static Type Run(Map<K, V> input) { return input.PassStorage(); } - }; -}; - -template <> -struct UnwrapTraits<String> { - public: - using Type = std::string; - - static std::string Unwrap(const String& input) { return input; } -}; - -template <typename T> -struct WrapTraits; - -template <typename T> -struct WrapShouldGoDeeper { - public: - static const bool value = - !std::is_same<T, typename WrapTraits<T>::Type>::value; -}; - -template <typename T> -struct WrapTraits { - public: - using Type = T; - - static T Wrap(T input) { return input; } -}; - -template <typename T> -struct WrapTraits<std::vector<T>> { - public: - using Type = Array<typename WrapTraits<T>::Type>; - - static Type Wrap(std::vector<T> input) { - return Helper<T>::Run(std::move(input)); - } - - private: - template <typename U, bool should_go_deeper = WrapShouldGoDeeper<U>::value> - struct Helper {}; - - template <typename U> - struct Helper<U, true> { - public: - static Type Run(std::vector<T> input) { - std::vector<typename WrapTraits<T>::Type> output_storage; - output_storage.reserve(input.size()); - for (auto& element : input) - output_storage.push_back(WrapTraits<T>::Wrap(std::move(element))); - return Type(std::move(output_storage)); - } - }; - - template <typename U> - struct Helper<U, false> { - public: - static Type Run(std::vector<T> input) { return Type(std::move(input)); } - }; -}; - -template <typename K, typename V> -struct WrapTraits<std::map<K, V>> { - public: - using Type = Map<typename WrapTraits<K>::Type, typename WrapTraits<V>::Type>; - - static Type Wrap(std::map<K, V> input) { - return Helper<K, V>::Run(std::move(input)); - } - - private: - template <typename X, - typename Y, - bool should_go_deeper = - WrapShouldGoDeeper<X>::value || WrapShouldGoDeeper<Y>::value> - struct Helper {}; - - template <typename X, typename Y> - struct Helper<X, Y, true> { - public: - static Type Run(std::map<K, V> input) { - Type output; - for (auto& pair : input) { - output.insert(WrapTraits<K>::Wrap(pair.first), - WrapTraits<V>::Wrap(std::move(pair.second))); - } - return output; - } - }; - - template <typename X, typename Y> - struct Helper<X, Y, false> { - public: - static Type Run(std::map<K, V> input) { return Type(std::move(input)); } - }; -}; - -template <> -struct WrapTraits<std::string> { - public: - using Type = String; - - static String Wrap(const std::string& input) { return input; } -}; - -} // namespace internal - -template <typename T> -typename internal::UnwrapTraits<T>::Type UnwrapToSTLType(T&& input) { - return internal::UnwrapTraits<T>::Unwrap(std::move(input)); -} - -template <typename T> -typename internal::WrapTraits<T>::Type WrapSTLType(T&& input) { - return internal::WrapTraits<T>::Wrap(std::move(input)); -} - -} // namespace mojo - -#endif // MOJO_PUBLIC_CPP_BINDINGS_STL_CONVERTERS_H_
diff --git a/mojo/public/cpp/bindings/struct_traits.h b/mojo/public/cpp/bindings/struct_traits.h index d570eac..a8aaebc 100644 --- a/mojo/public/cpp/bindings/struct_traits.h +++ b/mojo/public/cpp/bindings/struct_traits.h
@@ -38,7 +38,7 @@ // // - map: // Value or reference of any type that has a MapTraits defined. -// Supported by default: std::map, std::unordered_map, mojo::Map, +// Supported by default: std::map, std::unordered_map, // WTF::HashMap (in blink). // // - struct:
diff --git a/mojo/public/cpp/bindings/tests/BUILD.gn b/mojo/public/cpp/bindings/tests/BUILD.gn index 2e61173..7b5db260 100644 --- a/mojo/public/cpp/bindings/tests/BUILD.gn +++ b/mojo/public/cpp/bindings/tests/BUILD.gn
@@ -23,8 +23,6 @@ "handle_passing_unittest.cc", "hash_unittest.cc", "interface_ptr_unittest.cc", - "map_common_test.h", - "map_unittest.cc", "message_queue.cc", "message_queue.h", "multiplex_router_unittest.cc", @@ -34,7 +32,6 @@ "router_test_util.h", "sample_service_unittest.cc", "serialization_warning_unittest.cc", - "stl_converters_unittest.cc", "string_unittest.cc", "struct_unittest.cc", "sync_method_unittest.cc",
diff --git a/mojo/public/cpp/bindings/tests/equals_unittest.cc b/mojo/public/cpp/bindings/tests/equals_unittest.cc index 466b58d..4862b93f 100644 --- a/mojo/public/cpp/bindings/tests/equals_unittest.cc +++ b/mojo/public/cpp/bindings/tests/equals_unittest.cc
@@ -84,37 +84,6 @@ EXPECT_TRUE(n1.Equals(n2)); } -TEST_F(EqualsTest, Map) { - auto n1(NamedRegion::New()); - n1->name.emplace("foo"); - n1->rects.emplace(); - n1->rects->push_back(CreateRect()); - - Map<std::string, NamedRegionPtr> m1; - m1.insert("foo", std::move(n1)); - - decltype(m1) m2; - EXPECT_FALSE(m1.Equals(m2)); - - m2.insert("bar", m1.at("foo").Clone()); - EXPECT_FALSE(m1.Equals(m2)); - - m2 = m1.Clone(); - m2.at("foo")->name.emplace("monkey"); - EXPECT_FALSE(m1.Equals(m2)); - - m2 = m1.Clone(); - m2.at("foo")->rects->push_back(Rect::New()); - EXPECT_FALSE(m1.Equals(m2)); - - m2.at("foo")->rects->resize(1); - (*m2.at("foo")->rects)[0]->width = 1; - EXPECT_FALSE(m1.Equals(m2)); - - m2 = m1.Clone(); - EXPECT_TRUE(m1.Equals(m2)); -} - TEST_F(EqualsTest, InterfacePtr) { base::MessageLoop message_loop;
diff --git a/mojo/public/cpp/bindings/tests/map_common_test.h b/mojo/public/cpp/bindings/tests/map_common_test.h deleted file mode 100644 index 67fc00c..0000000 --- a/mojo/public/cpp/bindings/tests/map_common_test.h +++ /dev/null
@@ -1,231 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "mojo/public/cpp/bindings/array.h" -#include "mojo/public/cpp/bindings/lib/fixed_buffer.h" -#include "mojo/public/cpp/bindings/lib/serialization.h" -#include "mojo/public/cpp/bindings/lib/validate_params.h" -#include "mojo/public/cpp/bindings/map.h" -#include "mojo/public/cpp/bindings/string.h" -#include "mojo/public/cpp/bindings/tests/container_test_util.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace WTF { -class String; -} - -namespace mojo { - -template <typename T> -class WTFArray; - -template <typename K, typename V> -class WTFMap; - -namespace test { -namespace { - -struct StringIntData { - const char* string_data; - int int_data; -} kStringIntData[] = { - {"one", 1}, - {"two", 2}, - {"three", 3}, - {"four", 4}, -}; - -const size_t kStringIntDataSize = 4; - -} // namespace - -template <template <typename...> class MapType> -struct TypeTraits; - -template <> -struct TypeTraits<Map> { - using StringType = mojo::String; - template <typename T> - using ArrayType = Array<T>; -}; - -template <> -struct TypeTraits<WTFMap> { - using StringType = WTF::String; - template <typename T> - using ArrayType = WTFArray<T>; -}; - -// Common tests for both mojo::Map and mojo::WTFMap. -template <template <typename...> class MapType> -class MapCommonTest { - public: - using StringType = typename TypeTraits<MapType>::StringType; - template <typename T> - using ArrayType = typename TypeTraits<MapType>::template ArrayType<T>; - - // Tests null and empty maps. - static void NullAndEmpty() { - MapType<char, char> map0; - EXPECT_TRUE(map0.empty()); - EXPECT_FALSE(map0.is_null()); - map0 = nullptr; - EXPECT_TRUE(map0.is_null()); - EXPECT_FALSE(map0.empty()); - - MapType<char, char> map1(nullptr); - EXPECT_TRUE(map1.is_null()); - EXPECT_FALSE(map1.empty()); - map1.SetToEmpty(); - EXPECT_TRUE(map1.empty()); - EXPECT_FALSE(map1.is_null()); - } - - // Tests that basic Map operations work. - static void InsertWorks() { - MapType<StringType, int> map; - for (size_t i = 0; i < kStringIntDataSize; ++i) - map.insert(kStringIntData[i].string_data, kStringIntData[i].int_data); - - for (size_t i = 0; i < kStringIntDataSize; ++i) { - EXPECT_EQ(kStringIntData[i].int_data, - map.at(kStringIntData[i].string_data)); - } - } - - static void TestIndexOperator() { - MapType<StringType, int> map; - for (size_t i = 0; i < kStringIntDataSize; ++i) - map[kStringIntData[i].string_data] = kStringIntData[i].int_data; - - for (size_t i = 0; i < kStringIntDataSize; ++i) { - EXPECT_EQ(kStringIntData[i].int_data, - map.at(kStringIntData[i].string_data)); - } - } - - static void TestIndexOperatorAsRValue() { - MapType<StringType, int> map; - for (size_t i = 0; i < kStringIntDataSize; ++i) - map.insert(kStringIntData[i].string_data, kStringIntData[i].int_data); - - for (size_t i = 0; i < kStringIntDataSize; ++i) { - EXPECT_EQ(kStringIntData[i].int_data, map[kStringIntData[i].string_data]); - } - } - - static void TestIndexOperatorMoveOnly() { - ASSERT_EQ(0u, MoveOnlyType::num_instances()); - MapType<StringType, ArrayType<int32_t>> map; - - for (size_t i = 0; i < kStringIntDataSize; ++i) { - const char* key = kStringIntData[i].string_data; - ArrayType<int32_t> array(1); - array[0] = kStringIntData[i].int_data; - map[key] = std::move(array); - EXPECT_TRUE(map); - } - - // We now read back that data, to test the behavior of operator[]. - for (size_t i = 0; i < kStringIntDataSize; ++i) { - auto& value = map[kStringIntData[i].string_data]; - ASSERT_EQ(1u, value.size()); - EXPECT_EQ(kStringIntData[i].int_data, value[0]); - } - } - - static void MapArrayClone() { - MapType<StringType, ArrayType<StringType>> m; - for (size_t i = 0; i < kStringIntDataSize; ++i) { - ArrayType<StringType> s(1); - s[0] = StringType(kStringIntData[i].string_data); - m.insert(kStringIntData[i].string_data, std::move(s)); - } - - MapType<StringType, ArrayType<StringType>> m2 = m.Clone(); - - for (size_t i = 0; i < kStringIntDataSize; ++i) { - ASSERT_NE(m2.end(), m2.find(kStringIntData[i].string_data)); - ASSERT_EQ(1u, m2[kStringIntData[i].string_data].size()); - EXPECT_EQ(StringType(kStringIntData[i].string_data), - m2[kStringIntData[i].string_data][0]); - } - } - - static void ArrayOfMap() { - { - using MojomType = ArrayDataView<MapDataView<int32_t, int8_t>>; - using UserType = ArrayType<MapType<int32_t, int8_t>>; - - UserType array(1); - array[0].insert(1, 42); - - mojo::internal::SerializationContext context; - size_t size = - mojo::internal::PrepareToSerialize<MojomType>(array, &context); - mojo::internal::FixedBufferForTesting buf(size); - typename mojo::internal::MojomTypeTraits<MojomType>::Data* data; - mojo::internal::ContainerValidateParams validate_params( - 0, false, - new mojo::internal::ContainerValidateParams( - new mojo::internal::ContainerValidateParams(0, false, nullptr), - new mojo::internal::ContainerValidateParams(0, false, nullptr))); - - mojo::internal::Serialize<MojomType>(array, &buf, &data, &validate_params, - &context); - - UserType deserialized_array; - mojo::internal::Deserialize<MojomType>(data, &deserialized_array, - &context); - - ASSERT_EQ(1u, deserialized_array.size()); - ASSERT_EQ(1u, deserialized_array[0].size()); - ASSERT_EQ(42, deserialized_array[0].at(1)); - } - - { - using MojomType = - ArrayDataView<MapDataView<StringDataView, ArrayDataView<bool>>>; - using UserType = ArrayType<MapType<StringType, ArrayType<bool>>>; - - UserType array(1); - ArrayType<bool> map_value(2); - map_value[0] = false; - map_value[1] = true; - array[0].insert("hello world", std::move(map_value)); - - mojo::internal::SerializationContext context; - size_t size = - mojo::internal::PrepareToSerialize<MojomType>(array, &context); - mojo::internal::FixedBufferForTesting buf(size); - typename mojo::internal::MojomTypeTraits<MojomType>::Data* data; - mojo::internal::ContainerValidateParams validate_params( - 0, false, - new mojo::internal::ContainerValidateParams( - new mojo::internal::ContainerValidateParams( - 0, false, new mojo::internal::ContainerValidateParams( - 0, false, nullptr)), - new mojo::internal::ContainerValidateParams( - 0, false, new mojo::internal::ContainerValidateParams( - 0, false, nullptr)))); - mojo::internal::Serialize<MojomType>(array, &buf, &data, &validate_params, - &context); - - UserType deserialized_array; - mojo::internal::Deserialize<MojomType>(data, &deserialized_array, - &context); - - ASSERT_EQ(1u, deserialized_array.size()); - ASSERT_EQ(1u, deserialized_array[0].size()); - ASSERT_FALSE(deserialized_array[0].at("hello world")[0]); - ASSERT_TRUE(deserialized_array[0].at("hello world")[1]); - } - } -}; - -#define MAP_COMMON_TEST(MapType, test_name) \ - TEST_F(MapType##Test, test_name) { MapCommonTest<MapType>::test_name(); } - -} // namespace test -} // namespace mojo
diff --git a/mojo/public/cpp/bindings/tests/map_unittest.cc b/mojo/public/cpp/bindings/tests/map_unittest.cc deleted file mode 100644 index e4c612a..0000000 --- a/mojo/public/cpp/bindings/tests/map_unittest.cc +++ /dev/null
@@ -1,271 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "mojo/public/cpp/bindings/map.h" - -#include <stddef.h> -#include <stdint.h> -#include <unordered_map> -#include <utility> - -#include "mojo/public/cpp/bindings/array.h" -#include "mojo/public/cpp/bindings/string.h" -#include "mojo/public/cpp/bindings/tests/container_test_util.h" -#include "mojo/public/cpp/bindings/tests/map_common_test.h" -#include "mojo/public/cpp/bindings/tests/rect_chromium.h" -#include "mojo/public/interfaces/bindings/tests/rect.mojom.h" -#include "mojo/public/interfaces/bindings/tests/test_structs.mojom.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace test { - -namespace { - -using MapTest = testing::Test; - -MAP_COMMON_TEST(Map, NullAndEmpty) -MAP_COMMON_TEST(Map, InsertWorks) -MAP_COMMON_TEST(Map, TestIndexOperator) -MAP_COMMON_TEST(Map, TestIndexOperatorAsRValue) -MAP_COMMON_TEST(Map, TestIndexOperatorMoveOnly) -MAP_COMMON_TEST(Map, MapArrayClone) -MAP_COMMON_TEST(Map, ArrayOfMap) - -TEST_F(MapTest, ConstructedFromArray) { - Array<String> keys(kStringIntDataSize); - Array<int> values(kStringIntDataSize); - for (size_t i = 0; i < kStringIntDataSize; ++i) { - keys[i] = kStringIntData[i].string_data; - values[i] = kStringIntData[i].int_data; - } - - Map<String, int> map(std::move(keys), std::move(values)); - - for (size_t i = 0; i < kStringIntDataSize; ++i) { - EXPECT_EQ(kStringIntData[i].int_data, - map.at(mojo::String(kStringIntData[i].string_data))); - } -} - -TEST_F(MapTest, DecomposeMapTo) { - Array<String> keys(kStringIntDataSize); - Array<int> values(kStringIntDataSize); - for (size_t i = 0; i < kStringIntDataSize; ++i) { - keys[i] = kStringIntData[i].string_data; - values[i] = kStringIntData[i].int_data; - } - - Map<String, int> map(std::move(keys), std::move(values)); - EXPECT_EQ(kStringIntDataSize, map.size()); - - Array<String> keys2; - Array<int> values2; - map.DecomposeMapTo(&keys2, &values2); - EXPECT_EQ(0u, map.size()); - - EXPECT_EQ(kStringIntDataSize, keys2.size()); - EXPECT_EQ(kStringIntDataSize, values2.size()); - - for (size_t i = 0; i < kStringIntDataSize; ++i) { - // We are not guaranteed that the copies have the same sorting as the - // originals. - String key = kStringIntData[i].string_data; - int value = kStringIntData[i].int_data; - - bool found = false; - for (size_t j = 0; j < keys2.size(); ++j) { - if (keys2[j] == key) { - EXPECT_EQ(value, values2[j]); - found = true; - break; - } - } - - EXPECT_TRUE(found); - } -} - -TEST_F(MapTest, Insert_Copyable) { - ASSERT_EQ(0u, CopyableType::num_instances()); - mojo::Map<mojo::String, CopyableType> map; - std::vector<CopyableType*> value_ptrs; - - for (size_t i = 0; i < kStringIntDataSize; ++i) { - const char* key = kStringIntData[i].string_data; - CopyableType value; - value_ptrs.push_back(value.ptr()); - map.insert(key, value); - ASSERT_EQ(i + 1, map.size()); - ASSERT_EQ(i + 1, value_ptrs.size()); - EXPECT_EQ(map.size() + 1, CopyableType::num_instances()); - EXPECT_TRUE(map.at(key).copied()); - EXPECT_EQ(value_ptrs[i], map.at(key).ptr()); - map.at(key).ResetCopied(); - EXPECT_TRUE(map); - } - - // std::map doesn't have a capacity() method like std::vector so this test is - // a lot more boring. - - map = nullptr; - EXPECT_EQ(0u, CopyableType::num_instances()); -} - -TEST_F(MapTest, Insert_MoveOnly) { - ASSERT_EQ(0u, MoveOnlyType::num_instances()); - mojo::Map<mojo::String, MoveOnlyType> map; - std::vector<MoveOnlyType*> value_ptrs; - - for (size_t i = 0; i < kStringIntDataSize; ++i) { - const char* key = kStringIntData[i].string_data; - MoveOnlyType value; - value_ptrs.push_back(value.ptr()); - map.insert(key, std::move(value)); - ASSERT_EQ(i + 1, map.size()); - ASSERT_EQ(i + 1, value_ptrs.size()); - EXPECT_EQ(map.size() + 1, MoveOnlyType::num_instances()); - EXPECT_TRUE(map.at(key).moved()); - EXPECT_EQ(value_ptrs[i], map.at(key).ptr()); - map.at(key).ResetMoved(); - EXPECT_TRUE(map); - } - - // std::map doesn't have a capacity() method like std::vector so this test is - // a lot more boring. - - map = nullptr; - EXPECT_EQ(0u, MoveOnlyType::num_instances()); -} - -TEST_F(MapTest, IndexOperator_MoveOnly) { - ASSERT_EQ(0u, MoveOnlyType::num_instances()); - mojo::Map<mojo::String, MoveOnlyType> map; - std::vector<MoveOnlyType*> value_ptrs; - - for (size_t i = 0; i < kStringIntDataSize; ++i) { - const char* key = kStringIntData[i].string_data; - MoveOnlyType value; - value_ptrs.push_back(value.ptr()); - map[key] = std::move(value); - ASSERT_EQ(i + 1, map.size()); - ASSERT_EQ(i + 1, value_ptrs.size()); - EXPECT_EQ(map.size() + 1, MoveOnlyType::num_instances()); - EXPECT_TRUE(map.at(key).moved()); - EXPECT_EQ(value_ptrs[i], map.at(key).ptr()); - map.at(key).ResetMoved(); - EXPECT_TRUE(map); - } - - // std::map doesn't have a capacity() method like std::vector so this test is - // a lot more boring. - - map = nullptr; - EXPECT_EQ(0u, MoveOnlyType::num_instances()); -} - -TEST_F(MapTest, STLToMojo) { - std::map<std::string, int> stl_data; - for (size_t i = 0; i < kStringIntDataSize; ++i) - stl_data[kStringIntData[i].string_data] = kStringIntData[i].int_data; - - Map<String, int32_t> mojo_data = Map<String, int32_t>::From(stl_data); - for (size_t i = 0; i < kStringIntDataSize; ++i) { - EXPECT_EQ(kStringIntData[i].int_data, - mojo_data.at(kStringIntData[i].string_data)); - } -} - -TEST_F(MapTest, MojoToSTL) { - Map<String, int32_t> mojo_map; - for (size_t i = 0; i < kStringIntDataSize; ++i) - mojo_map.insert(kStringIntData[i].string_data, kStringIntData[i].int_data); - - std::map<std::string, int> stl_map = - mojo_map.To<std::map<std::string, int>>(); - for (size_t i = 0; i < kStringIntDataSize; ++i) { - auto it = stl_map.find(kStringIntData[i].string_data); - ASSERT_TRUE(it != stl_map.end()); - EXPECT_EQ(kStringIntData[i].int_data, it->second); - } -} - -TEST_F(MapTest, MoveFromAndToSTLMap_Copyable) { - std::map<int32_t, CopyableType> map1; - map1.insert(std::make_pair(123, CopyableType())); - map1[123].ResetCopied(); - - Map<int32_t, CopyableType> mojo_map(std::move(map1)); - ASSERT_EQ(1u, mojo_map.size()); - ASSERT_NE(mojo_map.end(), mojo_map.find(123)); - ASSERT_FALSE(mojo_map[123].copied()); - - std::map<int32_t, CopyableType> map2(mojo_map.PassStorage()); - ASSERT_EQ(1u, map2.size()); - ASSERT_NE(map2.end(), map2.find(123)); - ASSERT_FALSE(map2[123].copied()); - - ASSERT_EQ(0u, mojo_map.size()); - ASSERT_TRUE(mojo_map.is_null()); -} - -TEST_F(MapTest, MoveFromAndToSTLMap_MoveOnly) { - std::map<int32_t, MoveOnlyType> map1; - map1.insert(std::make_pair(123, MoveOnlyType())); - - Map<int32_t, MoveOnlyType> mojo_map(std::move(map1)); - ASSERT_EQ(1u, mojo_map.size()); - ASSERT_NE(mojo_map.end(), mojo_map.find(123)); - - std::map<int32_t, MoveOnlyType> map2(mojo_map.PassStorage()); - ASSERT_EQ(1u, map2.size()); - ASSERT_NE(map2.end(), map2.find(123)); - - ASSERT_EQ(0u, mojo_map.size()); - ASSERT_TRUE(mojo_map.is_null()); -} - -static RectPtr MakeRect(int32_t x, int32_t y, int32_t width, int32_t height) { - RectPtr rect_ptr = Rect::New(); - rect_ptr->x = x; - rect_ptr->y = y; - rect_ptr->width = width; - rect_ptr->height = height; - return rect_ptr; -} - -TEST_F(MapTest, StructKey) { - std::unordered_map<RectPtr, int32_t> map; - map.insert(std::make_pair(MakeRect(1, 2, 3, 4), 123)); - - RectPtr key = MakeRect(1, 2, 3, 4); - ASSERT_NE(map.end(), map.find(key)); - ASSERT_EQ(123, map.find(key)->second); - - map.erase(key); - ASSERT_EQ(0u, map.size()); -} - -static ContainsHashablePtr MakeContainsHashablePtr(RectChromium rect) { - ContainsHashablePtr ptr = ContainsHashable::New(); - ptr->rect = rect; - return ptr; -} - -TEST_F(MapTest, TypemappedStructKey) { - std::unordered_map<ContainsHashablePtr, int32_t> map; - map.insert( - std::make_pair(MakeContainsHashablePtr(RectChromium(1, 2, 3, 4)), 123)); - - ContainsHashablePtr key = MakeContainsHashablePtr(RectChromium(1, 2, 3, 4)); - ASSERT_NE(map.end(), map.find(key)); - ASSERT_EQ(123, map.find(key)->second); - - map.erase(key); - ASSERT_EQ(0u, map.size()); -} - -} // namespace -} // namespace test -} // namespace mojo
diff --git a/mojo/public/cpp/bindings/tests/stl_converters_unittest.cc b/mojo/public/cpp/bindings/tests/stl_converters_unittest.cc deleted file mode 100644 index 92a31b35..0000000 --- a/mojo/public/cpp/bindings/tests/stl_converters_unittest.cc +++ /dev/null
@@ -1,93 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "mojo/public/cpp/bindings/stl_converters.h" - -#include <map> -#include <string> -#include <vector> - -#include "mojo/public/cpp/bindings/array.h" -#include "mojo/public/cpp/bindings/map.h" -#include "mojo/public/cpp/bindings/string.h" -#include "mojo/public/cpp/bindings/tests/container_test_util.h" -#include "mojo/public/interfaces/bindings/tests/test_structs.mojom.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace test { - -using STLConvertersTest = testing::Test; - -TEST_F(STLConvertersTest, AvoidUnnecessaryCopies) { - Array<CopyableType> mojo_array(1); - std::vector<CopyableType> stl_vector = UnwrapToSTLType(std::move(mojo_array)); - ASSERT_EQ(1u, stl_vector.size()); - ASSERT_FALSE(stl_vector[0].copied()); - Array<CopyableType> mojo_array2 = WrapSTLType(std::move(stl_vector)); - ASSERT_EQ(1u, mojo_array2.size()); - ASSERT_FALSE(mojo_array2[0].copied()); - - Map<int32_t, CopyableType> mojo_map; - mojo_map.insert(42, CopyableType()); - mojo_map[42].ResetCopied(); - std::map<int32_t, CopyableType> stl_map = - UnwrapToSTLType(std::move(mojo_map)); - ASSERT_EQ(1u, stl_map.size()); - ASSERT_FALSE(stl_map[42].copied()); - Map<int32_t, CopyableType> mojo_map2 = WrapSTLType(std::move(stl_map)); - ASSERT_EQ(1u, mojo_map2.size()); - ASSERT_FALSE(mojo_map2[42].copied()); -} - -TEST_F(STLConvertersTest, RecursiveConversion) { - Array<Map<String, Array<int32_t>>> mojo_obj(2); - mojo_obj[0] = nullptr; - mojo_obj[1]["hello"].push_back(123); - mojo_obj[1]["hello"].push_back(456); - - std::vector<std::map<std::string, std::vector<int32_t>>> stl_obj = - UnwrapToSTLType(std::move(mojo_obj)); - - ASSERT_EQ(2u, stl_obj.size()); - ASSERT_TRUE(stl_obj[0].empty()); - ASSERT_EQ(1u, stl_obj[1].size()); - ASSERT_EQ(2u, stl_obj[1]["hello"].size()); - ASSERT_EQ(123, stl_obj[1]["hello"][0]); - ASSERT_EQ(456, stl_obj[1]["hello"][1]); - - Array<Map<String, Array<int32_t>>> mojo_obj2 = - WrapSTLType(std::move(stl_obj)); - - ASSERT_EQ(2u, mojo_obj2.size()); - ASSERT_EQ(0u, mojo_obj2[0].size()); - // The null flag has been lost when converted to std::map. - ASSERT_FALSE(mojo_obj2[0].is_null()); - ASSERT_EQ(1u, mojo_obj2[1].size()); - ASSERT_EQ(2u, mojo_obj2[1]["hello"].size()); - ASSERT_EQ(123, mojo_obj2[1]["hello"][0]); - ASSERT_EQ(456, mojo_obj2[1]["hello"][1]); -} - -TEST_F(STLConvertersTest, StopsAtMojoStruct) { - Array<NamedRegionPtr> mojo_obj(1); - mojo_obj[0] = NamedRegion::New(); - mojo_obj[0]->name.emplace("hello"); - mojo_obj[0]->rects.emplace(3); - - std::vector<NamedRegionPtr> stl_obj = UnwrapToSTLType(std::move(mojo_obj)); - - ASSERT_EQ(1u, stl_obj.size()); - ASSERT_EQ("hello", stl_obj[0]->name.value()); - ASSERT_EQ(3u, stl_obj[0]->rects->size()); - - Array<NamedRegionPtr> mojo_obj2 = WrapSTLType(std::move(stl_obj)); - - ASSERT_EQ(1u, mojo_obj2.size()); - ASSERT_EQ("hello", mojo_obj2[0]->name.value()); - ASSERT_EQ(3u, mojo_obj2[0]->rects->size()); -} - -} // namespace test -} // namespace mojo
diff --git a/mojo/public/cpp/bindings/tests/union_unittest.cc b/mojo/public/cpp/bindings/tests/union_unittest.cc index 29197be..1baccae 100644 --- a/mojo/public/cpp/bindings/tests/union_unittest.cc +++ b/mojo/public/cpp/bindings/tests/union_unittest.cc
@@ -693,9 +693,9 @@ TEST(UnionTest, PodUnionInMapSerialization) { using MojomType = MapDataView<StringDataView, PodUnionDataView>; - Map<String, PodUnionPtr> map; - map.insert("one", PodUnion::New()); - map.insert("two", PodUnion::New()); + std::unordered_map<std::string, PodUnionPtr> map; + map.insert(std::make_pair("one", PodUnion::New())); + map.insert(std::make_pair("two", PodUnion::New())); map["one"]->set_f_int8(8); map["two"]->set_f_int16(16); @@ -713,7 +713,7 @@ mojo::internal::Serialize<MojomType>(map, &buf, &data, &validate_params, &context); - Map<String, PodUnionPtr> map2; + std::unordered_map<std::string, PodUnionPtr> map2; mojo::internal::Deserialize<MojomType>(data, &map2, &context); EXPECT_EQ(8, map2["one"]->get_f_int8()); @@ -723,9 +723,9 @@ TEST(UnionTest, PodUnionInMapSerializationWithNull) { using MojomType = MapDataView<StringDataView, PodUnionDataView>; - Map<String, PodUnionPtr> map; - map.insert("one", PodUnion::New()); - map.insert("two", nullptr); + std::unordered_map<std::string, PodUnionPtr> map; + map.insert(std::make_pair("one", PodUnion::New())); + map.insert(std::make_pair("two", nullptr)); map["one"]->set_f_int8(8); @@ -741,7 +741,7 @@ mojo::internal::Serialize<MojomType>(map, &buf, &data, &validate_params, &context); - Map<String, PodUnionPtr> map2; + std::unordered_map<std::string, PodUnionPtr> map2; mojo::internal::Deserialize<MojomType>(data, &map2, &context); EXPECT_EQ(8, map2["one"]->get_f_int8());
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl index 7d4cc7b..a2a18ed 100644 --- a/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl +++ b/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl
@@ -49,7 +49,6 @@ #include "mojo/public/cpp/bindings/lib/control_message_proxy.h" #include "mojo/public/cpp/bindings/lib/serialization.h" #include "mojo/public/cpp/bindings/lib/union_accessor.h" -#include "mojo/public/cpp/bindings/map.h" #include "mojo/public/cpp/bindings/native_struct.h" #include "mojo/public/cpp/bindings/no_interface.h" #include "mojo/public/cpp/bindings/raw_ptr_impl_ref_traits.h"
diff --git a/mojo/public/tools/bindings/mojom.gni b/mojo/public/tools/bindings/mojom.gni index a30e10c..1b1acc82 100644 --- a/mojo/public/tools/bindings/mojom.gni +++ b/mojo/public/tools/bindings/mojom.gni
@@ -241,9 +241,6 @@ type_mappings_path = "$target_gen_dir/${target_name}${variant_suffix}__type_mappings" active_typemaps = [] - cpp_sources_suffix = "cpp_sources" - cpp_sources_target_name = - "${target_name}${variant_suffix}_${cpp_sources_suffix}" enabled_sources = [] if (defined(invoker.sources)) { generator_cpp_outputs = [] @@ -424,37 +421,6 @@ if (defined(invoker.sources) && !defined(bindings_configuration.variant)) { data = process_file_template(enabled_sources, generator_js_outputs) } - - public_deps = [ - ":${cpp_sources_target_name}", - "//mojo/public/cpp/bindings", - ] - if (defined(invoker.deps)) { - foreach(dep, invoker.deps) { - public_deps += - [ get_label_info(dep, "label_no_toolchain") + variant_suffix ] - } - } - if (defined(invoker.public_deps)) { - foreach(dep, invoker.public_deps) { - public_deps += - [ get_label_info(dep, "label_no_toolchain") + variant_suffix ] - } - } - - deps = [] - if (defined(invoker.sources)) { - public_deps += [ ":$generator_target_name" ] - } - } - - # The generated C++ source files. The main reason to introduce this target - # is so that mojo/public/cpp/bindings can depend on mojom interfaces without - # circular dependencies. It means that the target is missing the dependency - # on mojo/public/cpp/bindings. No external targets should depend directly on - # this target *except* mojo/public/cpp/bindings and other *_cpp_sources - # targets. - source_set(cpp_sources_target_name) { defines = [] if (defined(invoker.testonly)) { testonly = invoker.testonly @@ -473,19 +439,20 @@ "//mojo/public/interfaces/bindings:bindings__generator", "//mojo/public/interfaces/bindings:bindings_shared__generator", ] - if (enabled_sources != []) { - deps += [ ":$generator_target_name" ] - } public_deps = [ ":$shared_cpp_sources_target_name", "//base", + "//mojo/public/cpp/bindings", ] + if (enabled_sources != []) { + public_deps += [ ":$generator_target_name" ] + } foreach(d, all_deps) { # Resolve the name, so that a target //mojo/something becomes - # //mojo/something:something and we can append cpp_sources_suffix to + # //mojo/something:something and we can append variant_suffix to # get the cpp dependency name. full_name = get_label_info("$d", "label_no_toolchain") - public_deps += [ "${full_name}${variant_suffix}_${cpp_sources_suffix}" ] + public_deps += [ "${full_name}${variant_suffix}" ] } foreach(typemap, active_typemaps) { if (defined(typemap.public_headers)) {
diff --git a/net/base/sdch_manager.cc b/net/base/sdch_manager.cc index e57d73c..d577db84 100644 --- a/net/base/sdch_manager.cc +++ b/net/base/sdch_manager.cc
@@ -13,7 +13,10 @@ #include "base/metrics/histogram_macros.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" #include "base/time/default_clock.h" +#include "base/trace_event/memory_allocator_dump.h" +#include "base/trace_event/process_memory_dump.h" #include "base/values.h" #include "crypto/sha2.h" #include "net/base/parse_number.h" @@ -324,6 +327,36 @@ observers_.RemoveObserver(observer); } +void SdchManager::DumpMemoryStats( + base::trace_event::ProcessMemoryDump* pmd, + const std::string& parent_dump_absolute_name) const { + // If there are no dictionaries stored, return early without creating a new + // MemoryAllocatorDump. + size_t total_count = dictionaries_.size(); + if (total_count == 0) + return; + std::string name = base::StringPrintf("net/sdch_manager_%p", this); + base::trace_event::MemoryAllocatorDump* dump = pmd->GetAllocatorDump(name); + if (dump == nullptr) { + dump = pmd->CreateAllocatorDump(name); + size_t total_size = 0; + for (const auto& dictionary : dictionaries_) { + total_size += dictionary.second->data.text().size(); + } + dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, + base::trace_event::MemoryAllocatorDump::kUnitsBytes, + total_size); + dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameObjectCount, + base::trace_event::MemoryAllocatorDump::kUnitsObjects, + total_count); + } + // Create an empty row under parent's dump so size can be attributed correctly + // if |this| is shared between URLRequestContexts. + base::trace_event::MemoryAllocatorDump* empty_row_dump = + pmd->CreateAllocatorDump(parent_dump_absolute_name + "/sdch_manager"); + pmd->AddOwnershipEdge(empty_row_dump->guid(), dump->guid()); +} + SdchProblemCode SdchManager::AddSdchDictionary( const std::string& dictionary_text, const GURL& dictionary_url,
diff --git a/net/base/sdch_manager.h b/net/base/sdch_manager.h index dcb4771..1db8105e 100644 --- a/net/base/sdch_manager.h +++ b/net/base/sdch_manager.h
@@ -32,6 +32,10 @@ namespace base { class Value; + +namespace trace_event { +class ProcessMemoryDump; +} } namespace net { @@ -195,6 +199,11 @@ void AddObserver(SdchObserver* observer); void RemoveObserver(SdchObserver* observer); + // Dumps memory allocation stats. |parent_dump_absolute_name| is the name + // used by the parent MemoryAllocatorDump in the memory dump hierarchy. + void DumpMemoryStats(base::trace_event::ProcessMemoryDump* pmd, + const std::string& parent_dump_absolute_name) const; + // Logs an SDCH failure to UMA and |netlog|. static void LogSdchProblem(NetLogWithSource netlog, SdchProblemCode problem);
diff --git a/net/base/sdch_manager_unittest.cc b/net/base/sdch_manager_unittest.cc index bfdb78f..31162841 100644 --- a/net/base/sdch_manager_unittest.cc +++ b/net/base/sdch_manager_unittest.cc
@@ -11,8 +11,12 @@ #include "base/logging.h" #include "base/macros.h" +#include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" #include "base/test/simple_test_clock.h" +#include "base/trace_event/memory_allocator_dump.h" +#include "base/trace_event/process_memory_dump.h" +#include "base/trace_event/trace_event_argument.h" #include "net/base/sdch_observer.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -636,4 +640,58 @@ sdch_manager()->RemoveObserver(&observer); } +TEST_F(SdchManagerTest, DumpMemoryStats) { + MockSdchObserver observer; + sdch_manager()->AddObserver(&observer); + + std::string dictionary_domain("x.y.z.google.com"); + GURL target_gurl("http://" + dictionary_domain); + std::string dictionary_text(NewSdchDictionary(dictionary_domain)); + std::string client_hash; + std::string server_hash; + SdchManager::GenerateHash(dictionary_text, &client_hash, &server_hash); + EXPECT_TRUE(AddSdchDictionary(dictionary_text, target_gurl)); + EXPECT_EQ(1, observer.dictionary_added_notifications()); + EXPECT_EQ(target_gurl, observer.last_dictionary_url()); + EXPECT_EQ(server_hash, observer.last_server_hash()); + + base::trace_event::MemoryDumpArgs dump_args = { + base::trace_event::MemoryDumpLevelOfDetail::DETAILED}; + std::unique_ptr<base::trace_event::ProcessMemoryDump> pmd( + new base::trace_event::ProcessMemoryDump(nullptr, dump_args)); + + base::trace_event::MemoryAllocatorDump* parent = + pmd->CreateAllocatorDump("parent"); + sdch_manager()->DumpMemoryStats(pmd.get(), parent->absolute_name()); + + const base::trace_event::MemoryAllocatorDump* sub_dump = + pmd->GetAllocatorDump("parent/sdch_manager"); + ASSERT_NE(nullptr, sub_dump); + const base::trace_event::MemoryAllocatorDump* dump = pmd->GetAllocatorDump( + base::StringPrintf("net/sdch_manager_%p", sdch_manager())); + std::unique_ptr<base::Value> raw_attrs = + dump->attributes_for_testing()->ToBaseValue(); + base::DictionaryValue* attrs; + ASSERT_TRUE(raw_attrs->GetAsDictionary(&attrs)); + base::DictionaryValue* size_attrs; + ASSERT_TRUE(attrs->GetDictionary( + base::trace_event::MemoryAllocatorDump::kNameSize, &size_attrs)); + size_t offset = dictionary_text.find("\n\n") + 2; + std::string size; + ASSERT_TRUE(size_attrs->GetString("value", &size)); + int actual_size; + ASSERT_TRUE(base::HexStringToInt(size, &actual_size)); + EXPECT_EQ(dictionary_text.size() - offset, static_cast<size_t>(actual_size)); + + base::DictionaryValue* count_attrs; + ASSERT_TRUE(attrs->GetDictionary( + base::trace_event::MemoryAllocatorDump::kNameObjectCount, &count_attrs)); + std::string count; + ASSERT_TRUE(count_attrs->GetString("value", &count)); + // One dictionary. + EXPECT_EQ("1", count); + + sdch_manager()->RemoveObserver(&observer); +} + } // namespace net
diff --git a/net/ssl/ssl_config.cc b/net/ssl/ssl_config.cc index 7a4f337..3275ac4 100644 --- a/net/ssl/ssl_config.cc +++ b/net/ssl/ssl_config.cc
@@ -23,7 +23,7 @@ SSLConfig::SSLConfig() : rev_checking_enabled(false), rev_checking_required_local_anchors(false), - sha1_local_anchors_enabled(false), + sha1_local_anchors_enabled(true), version_min(kDefaultSSLVersionMin), version_max(kDefaultSSLVersionMax), deprecated_cipher_suites_enabled(false),
diff --git a/net/url_request/url_request_context.cc b/net/url_request/url_request_context.cc index ab6ad531..cefa7b9 100644 --- a/net/url_request/url_request_context.cc +++ b/net/url_request/url_request_context.cc
@@ -13,6 +13,7 @@ #include "base/trace_event/memory_allocator_dump.h" #include "base/trace_event/memory_dump_manager.h" #include "base/trace_event/process_memory_dump.h" +#include "net/base/sdch_manager.h" #include "net/cookies/cookie_store.h" #include "net/dns/host_resolver.h" #include "net/http/http_transaction_factory.h" @@ -138,6 +139,8 @@ network_session->DumpMemoryStats(pmd, dump->absolute_name()); } SSLClientSocketImpl::DumpSSLClientSessionMemoryStats(pmd); + if (sdch_manager_) + sdch_manager_->DumpMemoryStats(pmd, dump->absolute_name()); return true; }
diff --git a/ppapi/shared_impl/ppb_gamepad_shared.cc b/ppapi/shared_impl/ppb_gamepad_shared.cc index a707926..4ee0dd9 100644 --- a/ppapi/shared_impl/ppb_gamepad_shared.cc +++ b/ppapi/shared_impl/ppb_gamepad_shared.cc
@@ -14,10 +14,8 @@ void ConvertWebKitGamepadData(const WebKitGamepads& webkit_data, PP_GamepadsSampleData* output_data) { - size_t length = std::min(WebKitGamepads::kItemsLengthCap, - static_cast<const size_t>(webkit_data.length)); - output_data->length = static_cast<unsigned>(length); - for (unsigned i = 0; i < length; ++i) { + output_data->length = WebKitGamepads::kItemsLengthCap; + for (unsigned i = 0; i < WebKitGamepads::kItemsLengthCap; ++i) { PP_GamepadSampleData& output_pad = output_data->items[i]; const WebKitGamepad& webkit_pad = webkit_data.items[i]; output_pad.connected = webkit_pad.connected ? PP_TRUE : PP_FALSE;
diff --git a/ppapi/shared_impl/ppb_gamepad_shared.h b/ppapi/shared_impl/ppb_gamepad_shared.h index 4a71d964..577a13d 100644 --- a/ppapi/shared_impl/ppb_gamepad_shared.h +++ b/ppapi/shared_impl/ppb_gamepad_shared.h
@@ -101,9 +101,6 @@ struct WebKitGamepads { static const size_t kItemsLengthCap = 4; - // Number of valid entries in the items array. - unsigned length; - // Gamepad data for N separate gamepad devices. WebKitGamepad items[kItemsLengthCap]; };
diff --git a/services/service_manager/public/cpp/BUILD.gn b/services/service_manager/public/cpp/BUILD.gn index a73de27..2d68cd9 100644 --- a/services/service_manager/public/cpp/BUILD.gn +++ b/services/service_manager/public/cpp/BUILD.gn
@@ -87,7 +87,7 @@ "//mojo/public/cpp/bindings", "//mojo/public/cpp/system", "//services/service_manager/background:lib", - "//services/service_manager/public/interfaces:interfaces_cpp_sources", + "//services/service_manager/public/interfaces", ] data_deps = []
diff --git a/services/ui/public/cpp/window_tree_client.cc b/services/ui/public/cpp/window_tree_client.cc index ecbc628..eb96c58 100644 --- a/services/ui/public/cpp/window_tree_client.cc +++ b/services/ui/public/cpp/window_tree_client.cc
@@ -13,6 +13,7 @@ #include "base/bind.h" #include "base/memory/ptr_util.h" #include "base/strings/stringprintf.h" +#include "mojo/public/cpp/bindings/map.h" #include "services/service_manager/public/cpp/connector.h" #include "services/ui/common/util.h" #include "services/ui/public/cpp/in_flight_change.h"
diff --git a/services/ui/ws/drag_controller.cc b/services/ui/ws/drag_controller.cc index ba891a3..2e05d26e 100644 --- a/services/ui/ws/drag_controller.cc +++ b/services/ui/ws/drag_controller.cc
@@ -46,7 +46,7 @@ ServerWindow* source_window, DragTargetConnection* source_connection, int32_t drag_pointer, - mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data, + const std::unordered_map<std::string, std::vector<uint8_t>>& mime_data, DropEffectBitmask drag_operations) : source_(source), cursor_updater_(cursor_updater), @@ -55,7 +55,7 @@ current_cursor_(ui::mojom::Cursor::NO_DROP), source_window_(source_window), source_connection_(source_connection), - mime_data_(std::move(mime_data)), + mime_data_(mime_data), weak_factory_(this) { SetCurrentTargetWindow(nullptr); EnsureWindowObserved(source_window_); @@ -216,7 +216,7 @@ DragTargetConnection* connection = source_->GetDragTargetForWindow(window); if (connection != source_connection_ && !base::ContainsKey(called_on_drag_mime_types_, connection)) { - connection->PerformOnDragDropStart(mime_data_.Clone()); + connection->PerformOnDragDropStart(mime_data_); called_on_drag_mime_types_.insert(connection); }
diff --git a/services/ui/ws/drag_controller.h b/services/ui/ws/drag_controller.h index dd2b292d..0057480 100644 --- a/services/ui/ws/drag_controller.h +++ b/services/ui/ws/drag_controller.h
@@ -37,13 +37,14 @@ // WindowManagerState's EventDispatcher creates and owns this instance. class DragController : public ServerWindowObserver { public: - DragController(DragCursorUpdater* cursor_updater, - DragSource* source, - ServerWindow* source_window, - DragTargetConnection* source_connection, - int32_t drag_pointer, - mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data, - DropEffectBitmask drag_operations); + DragController( + DragCursorUpdater* cursor_updater, + DragSource* source, + ServerWindow* source_window, + DragTargetConnection* source_connection, + int32_t drag_pointer, + const std::unordered_map<std::string, std::vector<uint8_t>>& mime_data, + DropEffectBitmask drag_operations); ~DragController() override; ui::mojom::Cursor current_cursor() const { return current_cursor_; } @@ -130,7 +131,7 @@ DragTargetConnection* source_connection_; // A list of the offered mime types. - mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data_; + std::unordered_map<std::string, std::vector<uint8_t>> mime_data_; // We need to keep track of state on a per window basis. A window being in // this map means that we're observing it. WindowState also keeps track of
diff --git a/services/ui/ws/drag_controller_unittest.cc b/services/ui/ws/drag_controller_unittest.cc index 0841976..d26fdcd 100644 --- a/services/ui/ws/drag_controller_unittest.cc +++ b/services/ui/ws/drag_controller_unittest.cc
@@ -79,9 +79,10 @@ // Overridden from DragTestConnection: void PerformOnDragDropStart( - mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data) override { + const std::unordered_map<std::string, std::vector<uint8_t>>& mime_data) + override { times_received_drag_drop_start_++; - mime_data_ = std::move(mime_data); + mime_data_ = mime_data; } void PerformOnDragEnter( @@ -123,13 +124,13 @@ {QueuedType::DROP, key_state, cursor_offset, effect_bitmask, callback}); } - void PerformOnDragDropDone() override { mime_data_.SetToEmpty(); } + void PerformOnDragDropDone() override { mime_data_.clear(); } private: DragControllerTest* parent_; TestServerWindowDelegate window_delegate_; ServerWindow window_; - mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data_; + std::unordered_map<std::string, std::vector<uint8_t>> mime_data_; uint32_t times_received_drag_drop_start_ = 0; std::queue<DragEvent> queued_callbacks_; @@ -149,13 +150,14 @@ } void StartDragOperation( - mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data, DragTestWindow* window, uint32_t drag_operations) { - window->PerformOnDragDropStart(mime_data.Clone()); + window->PerformOnDragDropStart( + std::unordered_map<std::string, std::vector<uint8_t>>()); drag_operation_ = base::MakeUnique<DragController>( this, this, window->window(), window, PointerEvent::kMousePointerId, - std::move(mime_data), drag_operations); + std::unordered_map<std::string, std::vector<uint8_t>>(), + drag_operations); // It would be nice if we could just let the observer method fire, but it // fires during the constructor when we haven't assigned the unique_ptr @@ -275,9 +277,7 @@ TEST_F(DragControllerTest, SimpleDragDrop) { std::unique_ptr<DragTestWindow> window = BuildWindow(); - mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data; - StartDragOperation(std::move(mime_data), window.get(), - ui::mojom::kDropEffectMove); + StartDragOperation(window.get(), ui::mojom::kDropEffectMove); EXPECT_EQ(ui::mojom::Cursor::NO_DROP, cursor()); @@ -303,9 +303,7 @@ TEST_F(DragControllerTest, FailsOnWindowSayingNo) { std::unique_ptr<DragTestWindow> window = BuildWindow(); - mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data; - StartDragOperation(std::move(mime_data), window.get(), - ui::mojom::kDropEffectMove); + StartDragOperation(window.get(), ui::mojom::kDropEffectMove); DispatchDrag(window.get(), false, ui::EF_LEFT_MOUSE_BUTTON, gfx::Point(1, 1)); EXPECT_EQ(QueuedType::ENTER, window->queue_response_type()); @@ -330,13 +328,11 @@ TEST_F(DragControllerTest, OnlyDeliverMimeDataOnce) { std::unique_ptr<DragTestWindow> window1 = BuildWindow(); std::unique_ptr<DragTestWindow> window2 = BuildWindow(); - mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data; // The client lib is responsible for sending the data to the window that's // the drag source to minimize IPC. EXPECT_EQ(0u, window1->times_received_drag_drop_start()); - StartDragOperation(std::move(mime_data), window1.get(), - ui::mojom::kDropEffectMove); + StartDragOperation(window1.get(), ui::mojom::kDropEffectMove); EXPECT_EQ(1u, window1->times_received_drag_drop_start()); DispatchDrag(window1.get(), false, ui::EF_LEFT_MOUSE_BUTTON, gfx::Point(1, 1)); @@ -364,13 +360,11 @@ std::unique_ptr<DragTestWindow> window1 = BuildWindow(); std::unique_ptr<DragTestWindow> window2 = BuildWindow(); std::unique_ptr<DragTestWindow> window3 = BuildWindow(); - mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data; window3->SetParent(window2.get()); window3->OptOutOfDrag(); - StartDragOperation(std::move(mime_data), window1.get(), - ui::mojom::kDropEffectMove); + StartDragOperation(window1.get(), ui::mojom::kDropEffectMove); // Dispatching a drag to window3 (which has can accept drags off) redirects // to window2, which is its parent. @@ -381,9 +375,7 @@ TEST_F(DragControllerTest, FailWhenDropOverNoWindow) { std::unique_ptr<DragTestWindow> window = BuildWindow(); - mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data; - StartDragOperation(std::move(mime_data), window.get(), - ui::mojom::kDropEffectMove); + StartDragOperation(window.get(), ui::mojom::kDropEffectMove); DispatchDrag(window.get(), false, ui::EF_LEFT_MOUSE_BUTTON, gfx::Point(1, 1)); EXPECT_EQ(QueuedType::ENTER, window->queue_response_type()); @@ -404,9 +396,7 @@ TEST_F(DragControllerTest, EnterLeaveWhenMovingBetweenTwoWindows) { std::unique_ptr<DragTestWindow> window1 = BuildWindow(); std::unique_ptr<DragTestWindow> window2 = BuildWindow(); - mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data; - StartDragOperation(std::move(mime_data), window1.get(), - ui::mojom::kDropEffectMove); + StartDragOperation(window1.get(), ui::mojom::kDropEffectMove); DispatchDrag(window1.get(), false, ui::EF_LEFT_MOUSE_BUTTON, gfx::Point(1, 1)); @@ -424,9 +414,7 @@ TEST_F(DragControllerTest, DeadWindowDoesntBlock) { std::unique_ptr<DragTestWindow> window1 = BuildWindow(); std::unique_ptr<DragTestWindow> window2 = BuildWindow(); - mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data; - StartDragOperation(std::move(mime_data), window1.get(), - ui::mojom::kDropEffectMove); + StartDragOperation(window1.get(), ui::mojom::kDropEffectMove); test::DragControllerTestApi api(drag_operation()); @@ -448,9 +436,7 @@ TEST_F(DragControllerTest, EnterToOverQueued) { std::unique_ptr<DragTestWindow> window = BuildWindow(); - mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data; - StartDragOperation(std::move(mime_data), window.get(), - ui::mojom::kDropEffectMove); + StartDragOperation(window.get(), ui::mojom::kDropEffectMove); DispatchDrag(window.get(), false, ui::EF_LEFT_MOUSE_BUTTON, gfx::Point(1, 1)); ASSERT_EQ(1u, window->queue_size()); @@ -469,9 +455,7 @@ TEST_F(DragControllerTest, CoalesceMouseOverEvents) { std::unique_ptr<DragTestWindow> window = BuildWindow(); - mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data; - StartDragOperation(std::move(mime_data), window.get(), - ui::mojom::kDropEffectMove); + StartDragOperation(window.get(), ui::mojom::kDropEffectMove); DispatchDrag(window.get(), false, ui::EF_LEFT_MOUSE_BUTTON, gfx::Point(1, 1)); EXPECT_EQ(QueuedType::ENTER, window->queue_response_type()); @@ -494,9 +478,7 @@ TEST_F(DragControllerTest, RemovePendingMouseOversOnLeave) { std::unique_ptr<DragTestWindow> window1 = BuildWindow(); std::unique_ptr<DragTestWindow> window2 = BuildWindow(); - mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data; - StartDragOperation(std::move(mime_data), window1.get(), - ui::mojom::kDropEffectMove); + StartDragOperation(window1.get(), ui::mojom::kDropEffectMove); // Enter DispatchDrag(window1.get(), false, ui::EF_LEFT_MOUSE_BUTTON, @@ -521,9 +503,7 @@ TEST_F(DragControllerTest, TargetWindowClosedWhileDrag) { std::unique_ptr<DragTestWindow> window1 = BuildWindow(); std::unique_ptr<DragTestWindow> window2 = BuildWindow(); - mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data; - StartDragOperation(std::move(mime_data), window1.get(), - ui::mojom::kDropEffectMove); + StartDragOperation(window1.get(), ui::mojom::kDropEffectMove); test::DragControllerTestApi api(drag_operation()); @@ -554,9 +534,7 @@ TEST_F(DragControllerTest, TargetWindowClosedResetsCursor) { std::unique_ptr<DragTestWindow> window1 = BuildWindow(); std::unique_ptr<DragTestWindow> window2 = BuildWindow(); - mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data; - StartDragOperation(std::move(mime_data), window1.get(), - ui::mojom::kDropEffectMove); + StartDragOperation(window1.get(), ui::mojom::kDropEffectMove); EXPECT_EQ(ui::mojom::Cursor::NO_DROP, cursor()); // Send some events to |window|. @@ -579,9 +557,7 @@ TEST_F(DragControllerTest, SourceWindowClosedWhileDrag) { std::unique_ptr<DragTestWindow> window1 = BuildWindow(); std::unique_ptr<DragTestWindow> window2 = BuildWindow(); - mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data; - StartDragOperation(std::move(mime_data), window1.get(), - ui::mojom::kDropEffectMove); + StartDragOperation(window1.get(), ui::mojom::kDropEffectMove); test::DragControllerTestApi api(drag_operation()); @@ -609,9 +585,7 @@ // The DragController needs to stick around to coordinate the drop, but // it should ignore further mouse events during this time. std::unique_ptr<DragTestWindow> window = BuildWindow(); - mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data; - StartDragOperation(std::move(mime_data), window.get(), - ui::mojom::kDropEffectMove); + StartDragOperation(window.get(), ui::mojom::kDropEffectMove); test::DragControllerTestApi api(drag_operation()); @@ -637,9 +611,7 @@ // The DragController needs to stick around to coordinate the drop, but // it should ignore further mouse events during this time. std::unique_ptr<DragTestWindow> window = BuildWindow(); - mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data; - StartDragOperation(std::move(mime_data), window.get(), - ui::mojom::kDropEffectMove); + StartDragOperation(window.get(), ui::mojom::kDropEffectMove); DispatchDrag(window.get(), false, ui::EF_LEFT_MOUSE_BUTTON, gfx::Point(1, 1)); EXPECT_EQ(QueuedType::ENTER, window->queue_response_type()); @@ -652,10 +624,8 @@ TEST_F(DragControllerTest, IgnoreEventsFromOtherPointers) { std::unique_ptr<DragTestWindow> window = BuildWindow(); - mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data; // This starts the operation with PointerEvent::kMousePointerId. - StartDragOperation(std::move(mime_data), window.get(), - ui::mojom::kDropEffectMove); + StartDragOperation(window.get(), ui::mojom::kDropEffectMove); // Ignore events from pointer 5. DispatchDragWithPointer(window.get(), 5, false, ui::EF_LEFT_MOUSE_BUTTON, @@ -665,9 +635,7 @@ TEST_F(DragControllerTest, RejectingWindowHasProperCursor) { std::unique_ptr<DragTestWindow> window = BuildWindow(); - mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data; - StartDragOperation(std::move(mime_data), window.get(), - ui::mojom::kDropEffectMove); + StartDragOperation(window.get(), ui::mojom::kDropEffectMove); EXPECT_EQ(ui::mojom::Cursor::NO_DROP, cursor()); @@ -688,9 +656,7 @@ TEST_F(DragControllerTest, ResopnseFromOtherWindowDoesntChangeCursor) { std::unique_ptr<DragTestWindow> window1 = BuildWindow(); std::unique_ptr<DragTestWindow> window2 = BuildWindow(); - mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data; - StartDragOperation(std::move(mime_data), window1.get(), - ui::mojom::kDropEffectMove); + StartDragOperation(window1.get(), ui::mojom::kDropEffectMove); // Send some events to |window2|. DispatchDrag(window2.get(), false, ui::EF_LEFT_MOUSE_BUTTON,
diff --git a/services/ui/ws/drag_target_connection.h b/services/ui/ws/drag_target_connection.h index d3c22ce..a1fd04d 100644 --- a/services/ui/ws/drag_target_connection.h +++ b/services/ui/ws/drag_target_connection.h
@@ -5,10 +5,11 @@ #ifndef SERVICES_UI_WS_DRAG_TARGET_CONNECTION_H_ #define SERVICES_UI_WS_DRAG_TARGET_CONNECTION_H_ +#include <string> +#include <unordered_map> + #include "base/bind.h" #include "mojo/public/cpp/bindings/array.h" -#include "mojo/public/cpp/bindings/map.h" -#include "mojo/public/cpp/bindings/string.h" #include "ui/gfx/geometry/point.h" namespace ui { @@ -37,7 +38,8 @@ // equivalent in ui::WindowDropTarget to minimize the load of inter-process // communication.) virtual void PerformOnDragDropStart( - mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data) = 0; + const std::unordered_map<std::string, std::vector<uint8_t>>& + mime_data) = 0; // Next, on each time that the mouse cursor moves from one |window| to // another, we send a DragEnter message. The value returned by |callback| is
diff --git a/services/ui/ws/event_dispatcher.cc b/services/ui/ws/event_dispatcher.cc index 98d601c66..485bb5e1 100644 --- a/services/ui/ws/event_dispatcher.cc +++ b/services/ui/ws/event_dispatcher.cc
@@ -174,12 +174,12 @@ ServerWindow* window, DragTargetConnection* source_connection, int32_t drag_pointer, - mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data, + const std::unordered_map<std::string, std::vector<uint8_t>>& mime_data, uint32_t drag_operations) { CancelImplicitCaptureExcept(nullptr); drag_controller_ = base::MakeUnique<DragController>( - this, drag_source, window, source_connection, drag_pointer, - std::move(mime_data), drag_operations); + this, drag_source, window, source_connection, drag_pointer, mime_data, + drag_operations); } void EventDispatcher::CancelDragDrop() {
diff --git a/services/ui/ws/event_dispatcher.h b/services/ui/ws/event_dispatcher.h index 67572d0d..18b0cb5 100644 --- a/services/ui/ws/event_dispatcher.h +++ b/services/ui/ws/event_dispatcher.h
@@ -85,7 +85,7 @@ ServerWindow* window, DragTargetConnection* source_connection, int32_t drag_pointer, - mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data, + const std::unordered_map<std::string, std::vector<uint8_t>>& mime_data, uint32_t drag_operations); void CancelDragDrop(); void EndDragDrop();
diff --git a/services/ui/ws/test_change_tracker.cc b/services/ui/ws/test_change_tracker.cc index 1e7e0f3..1ee3842 100644 --- a/services/ui/ws/test_change_tracker.cc +++ b/services/ui/ws/test_change_tracker.cc
@@ -9,6 +9,7 @@ #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "mojo/common/common_type_converters.h" +#include "mojo/public/cpp/bindings/map.h" #include "services/ui/common/util.h" using mojo::Array;
diff --git a/services/ui/ws/window_manager_state.cc b/services/ui/ws/window_manager_state.cc index fe6065db..c6851d67 100644 --- a/services/ui/ws/window_manager_state.cc +++ b/services/ui/ws/window_manager_state.cc
@@ -165,7 +165,7 @@ DragSource* drag_source, ServerWindow* window, DragTargetConnection* source_connection, - mojo::Map<mojo::String, mojo::Array<uint8_t>> drag_data, + const std::unordered_map<std::string, std::vector<uint8_t>>& drag_data, uint32_t drag_operation) { int32_t drag_pointer = PointerEvent::kMousePointerId; if (event_awaiting_input_ack_ && @@ -178,9 +178,9 @@ return; } - event_dispatcher_.SetDragDropSourceWindow( - drag_source, window, source_connection, drag_pointer, - std::move(drag_data), drag_operation); + event_dispatcher_.SetDragDropSourceWindow(drag_source, window, + source_connection, drag_pointer, + drag_data, drag_operation); } void WindowManagerState::CancelDragDrop() {
diff --git a/services/ui/ws/window_manager_state.h b/services/ui/ws/window_manager_state.h index c063628a..ef49648 100644 --- a/services/ui/ws/window_manager_state.h +++ b/services/ui/ws/window_manager_state.h
@@ -68,7 +68,7 @@ DragSource* drag_source, ServerWindow* window, DragTargetConnection* source_connection, - mojo::Map<mojo::String, mojo::Array<uint8_t>> drag_data, + const std::unordered_map<std::string, std::vector<uint8_t>>& drag_data, uint32_t drag_operation); void CancelDragDrop(); void EndDragDrop();
diff --git a/services/ui/ws/window_tree.cc b/services/ui/ws/window_tree.cc index 4fdd82c..09f6222 100644 --- a/services/ui/ws/window_tree.cc +++ b/services/ui/ws/window_tree.cc
@@ -11,7 +11,7 @@ #include "base/bind.h" #include "base/macros.h" #include "base/memory/ptr_util.h" -#include "mojo/public/cpp/bindings/stl_converters.h" +#include "mojo/public/cpp/bindings/map.h" #include "services/ui/ws/default_access_policy.h" #include "services/ui/ws/display.h" #include "services/ui/ws/display_manager.h" @@ -1643,9 +1643,7 @@ // normal. WindowManagerState* wms = display_root->window_manager_state(); window_server_->StartDragLoop(change_id, window, this); - wms->SetDragDropSourceWindow( - this, window, this, mojo::WrapSTLType(mojo::UnorderedMapToMap(drag_data)), - drag_operation); + wms->SetDragDropSourceWindow(this, window, this, drag_data, drag_operation); } void WindowTree::CancelDragDrop(Id window_id) { @@ -1953,9 +1951,8 @@ } void WindowTree::PerformOnDragDropStart( - mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data) { - client()->OnDragDropStart( - mojo::MapToUnorderedMap(mojo::UnwrapToSTLType(std::move(mime_data)))); + const std::unordered_map<std::string, std::vector<uint8_t>>& mime_data) { + client()->OnDragDropStart(mime_data); } void WindowTree::PerformOnDragEnter(
diff --git a/services/ui/ws/window_tree.h b/services/ui/ws/window_tree.h index acf63c55..226fdba 100644 --- a/services/ui/ws/window_tree.h +++ b/services/ui/ws/window_tree.h
@@ -498,7 +498,8 @@ // DragTargetConnection: void PerformOnDragDropStart( - mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data) override; + const std::unordered_map<std::string, std::vector<uint8_t>>& mime_data) + override; void PerformOnDragEnter( const ServerWindow* window, uint32_t event_flags,
diff --git a/third_party/WebKit/LayoutTests/SlowTests b/third_party/WebKit/LayoutTests/SlowTests index 6a35997..ee00259 100644 --- a/third_party/WebKit/LayoutTests/SlowTests +++ b/third_party/WebKit/LayoutTests/SlowTests
@@ -8,7 +8,7 @@ # can see a 3x variance or more in test times on the bots. In practice, this means that any test that takes longer # than 2 seconds in Release mode or 6 seconds in Debug mode should be listed here. -crbug.com/24182 [ Debug ] storage/indexeddb/objectstore-cursor.html [ Slow ] +crbug.com/24182 storage/indexeddb/objectstore-cursor.html [ Slow ] crbug.com/24182 storage/indexeddb/mozilla/test_objectStore_openKeyCursor.html [ Slow ] crbug.com/24182 editing/selection/modify_move/move-by-word-visually-mac.html [ Slow ] crbug.com/24182 editing/selection/modify_move/move-by-word-visually-multi-line.html [ Slow ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index fd7ea2e9..7ca1d0b 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -157,6 +157,9 @@ crbug.com/664849 svg/dom/transform-parser.html [ Pass Failure ] +crbug.com/657839 images/png-suite/test.html [ NeedsRebaseline ] +crbug.com/657839 virtual/gpu-rasterization/images/png-suite/test.html [ NeedsRebaseline ] + crbug.com/664850 virtual/display_list_2d_canvas/fast/canvas/canvas-createImageBitmap-webgl.html [ Pass Failure ] crbug.com/664850 virtual/display_list_2d_canvas/fast/canvas/canvas-drawImage-live-video.html [ Pass Failure ] crbug.com/664850 virtual/display_list_2d_canvas/fast/canvas/OffscreenCanvas-2d-drawImage.html [ Pass Failure ] @@ -1263,6 +1266,19 @@ crbug.com/528062 [ Win ] virtual/mojo-loading/http/tests/security/xssAuditor/cached-frame.html [ Failure ] crbug.com/528062 [ Win ] virtual/mojo-loading/http/tests/security/xssAuditor/chunked-big-script.html [ Failure ] +crbug.com/642454 [ Win Mac ] editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-ltr-mixed.html [ NeedsRebaseline ] +crbug.com/642454 [ Win Mac ] editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-rtl-mixed.html [ NeedsRebaseline ] +crbug.com/642454 [ Win Mac ] editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-rtl.html [ NeedsRebaseline ] +crbug.com/642454 [ Win Mac ] editing/selection/dont-select-text-overflow-ellipsis-when-wrapping.html [ NeedsRebaseline ] +crbug.com/642454 [ Win Mac ] editing/selection/select-text-overflow-ellipsis-mixed-in-ltr-2.html [ NeedsRebaseline ] +crbug.com/642454 [ Win Mac ] editing/selection/select-text-overflow-ellipsis-mixed-in-ltr.html [ NeedsRebaseline ] +crbug.com/642454 [ Win Mac ] editing/selection/select-text-overflow-ellipsis-mixed-in-rtl-2.html [ NeedsRebaseline ] +crbug.com/642454 [ Win Mac ] fast/css/text-overflow-ellipsis-strict.html [ NeedsRebaseline ] +crbug.com/642454 [ Win Mac ] fast/css/text-overflow-ellipsis.html [ NeedsRebaseline ] +crbug.com/642454 [ Win Mac ] fast/text/ellipsis-mixed-text-in-ltr-flow-underline-2.html [ NeedsRebaseline ] +crbug.com/642454 [ Win Mac ] fast/text/ellipsis-mixed-text-in-ltr-flow-underline.html [ NeedsRebaseline ] +crbug.com/642454 [ Win Mac ] fast/text/ellipsis-mixed-text-in-rtl-flow-underline-2.html [ NeedsRebaseline ] + crbug.com/392706 virtual/threaded/animations/play-state-initially-paused.html [ Failure ] # Part of a larger issue referenced in the bug. This specific issue will be fixed shortly. @@ -2412,3 +2428,4 @@ crbug.com/678346 [ Win7 Debug ] storage/indexeddb/mozilla/test_objectStore_openKeyCursor.html [ Pass Timeout ] crbug.com/678346 [ Win7 Debug ] storage/indexeddb/structured-clone.html [ Pass Timeout ] +crbug.com/678388 [ Trusty Mac10.10 Mac10.11 Debug ] fast/text/ellipsis-stroked.html [ Pass Failure ]
diff --git a/third_party/WebKit/LayoutTests/editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-expected.png b/third_party/WebKit/LayoutTests/editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-expected.png new file mode 100644 index 0000000..52972d222 --- /dev/null +++ b/third_party/WebKit/LayoutTests/editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-expected.txt b/third_party/WebKit/LayoutTests/editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-expected.txt new file mode 100644 index 0000000..4a43d5e0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-expected.txt
@@ -0,0 +1,18 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x104 + LayoutBlockFlow {HTML} at (0,0) size 800x104 + LayoutBlockFlow {BODY} at (8,16) size 784x80 + LayoutBlockFlow {P} at (0,0) size 784x20 + LayoutText {#text} at (0,0) size 459x19 + text run at (0,0) width 459: "crbug.com/642454: Don't select part of the ellipsis when wrapping selection." + LayoutBlockFlow {DL} at (200,36) size 384x44 + LayoutBlockFlow {DT} at (0,22) size 384x22 + LayoutText {#text} at (0,0) size 206x21 + text run at (0,0) width 206: "Lorem ipsum dolor sit amet" +layer at (248,52) size 344x22 scrollWidth 1177 + LayoutBlockFlow {DD} at (40,0) size 344x22 + LayoutText {#text} at (0,0) size 1178x21 + text run at (0,0) width 1178: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua." +selection start: position 0 of child 0 {#text} of child 1 {DD} of child 2 {DL} of body +selection end: position 10 of child 0 {#text} of child 3 {DT} of child 2 {DL} of body
diff --git a/third_party/WebKit/LayoutTests/editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-ltr-mixed-expected.png b/third_party/WebKit/LayoutTests/editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-ltr-mixed-expected.png new file mode 100644 index 0000000..96ca490 --- /dev/null +++ b/third_party/WebKit/LayoutTests/editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-ltr-mixed-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-ltr-mixed-expected.txt b/third_party/WebKit/LayoutTests/editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-ltr-mixed-expected.txt new file mode 100644 index 0000000..f4759534 --- /dev/null +++ b/third_party/WebKit/LayoutTests/editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-ltr-mixed-expected.txt
@@ -0,0 +1,19 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x104 + LayoutBlockFlow {HTML} at (0,0) size 800x104 + LayoutBlockFlow {BODY} at (8,16) size 784x80 + LayoutBlockFlow {P} at (0,0) size 784x20 + LayoutText {#text} at (0,0) size 459x19 + text run at (0,0) width 459: "crbug.com/642454: Don't select part of the ellipsis when wrapping selection." + LayoutBlockFlow {DL} at (200,36) size 384x44 + LayoutBlockFlow {DT} at (0,22) size 384x22 + LayoutText {#text} at (0,0) size 206x21 + text run at (0,0) width 206: "Lorem ipsum dolor sit amet" +layer at (248,52) size 344x22 scrollWidth 393 + LayoutBlockFlow {DD} at (40,0) size 344x22 + LayoutText {#text} at (0,0) size 393x21 + text run at (0,0) width 54: "Lorem " + text run at (54,0) width 339 RTL: "\x{5DC}\x{5D5}\x{5E8}\x{5DD} \x{5D0}\x{5D9}\x{5E4}\x{5E1}\x{5D5}\x{5DD} \x{5D4}\x{5D5}\x{5D0} \x{5DB}\x{5D9}\x{5E0}\x{5D5}\x{5D9} \x{5DC}\x{5D8}\x{5E7}\x{5E1}\x{5D8} \x{5D7}\x{5E1}\x{5E8} \x{5DE}\x{5E9}\x{5DE}\x{5E2}\x{5D5}\x{5EA} \x{5DC}\x{5D7}\x{5DC}\x{5D5}\x{5D8}\x{5D9}\x{5DF}" +selection start: position 0 of child 0 {#text} of child 1 {DD} of child 2 {DL} of body +selection end: position 10 of child 0 {#text} of child 3 {DT} of child 2 {DL} of body
diff --git a/third_party/WebKit/LayoutTests/editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-ltr-mixed.html b/third_party/WebKit/LayoutTests/editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-ltr-mixed.html new file mode 100644 index 0000000..16d5af9f --- /dev/null +++ b/third_party/WebKit/LayoutTests/editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-ltr-mixed.html
@@ -0,0 +1,26 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<style> +dl { + max-width: 20em; + margin: auto; + font-size: 120%; + white-space: nowrap; +} +dd { + overflow: hidden; + text-overflow: ellipsis; + text-decoration: inherit; +} +</style> +<p>crbug.com/642454: Don't select part of the ellipsis when wrapping selection.</p> +<dl> + <dd id="selection_with_ellipsis">Lorem לורם איפסום הוא כינוי לטקסט חסר משמעות לחלוטין</dd> + <dt id="wrapped">Lorem ipsum dolor sit amet</dt> +</dl> +<script src="../../resources/run-after-layout-and-paint.js"></script> +<script> +runAfterLayoutAndPaint(function() { + getSelection().setBaseAndExtent(selection_with_ellipsis.firstChild, 0, wrapped.firstChild, 10); + }, true); +</script>
diff --git a/third_party/WebKit/LayoutTests/editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-rtl-expected.png b/third_party/WebKit/LayoutTests/editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-rtl-expected.png new file mode 100644 index 0000000..30693e9 --- /dev/null +++ b/third_party/WebKit/LayoutTests/editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-rtl-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-rtl-expected.txt b/third_party/WebKit/LayoutTests/editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-rtl-expected.txt new file mode 100644 index 0000000..f2d388b --- /dev/null +++ b/third_party/WebKit/LayoutTests/editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-rtl-expected.txt
@@ -0,0 +1,19 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x104 + LayoutBlockFlow {HTML} at (0,0) size 800x104 + LayoutBlockFlow {BODY} at (8,16) size 784x80 + LayoutBlockFlow {P} at (0,0) size 784x20 + LayoutText {#text} at (0,0) size 459x19 + text run at (0,0) width 459: "crbug.com/642454: Don't select part of the ellipsis when wrapping selection." + LayoutBlockFlow {DL} at (200,36) size 384x44 + LayoutBlockFlow {DT} at (0,22) size 384x22 + LayoutText {#text} at (0,0) size 206x21 + text run at (0,0) width 206: "Lorem ipsum dolor sit amet" +layer at (208,52) size 344x22 scrollX 833.00 scrollWidth 1177 + LayoutBlockFlow {DD} at (0,0) size 344x22 + LayoutText {#text} at (-833,0) size 1178x21 + text run at (-833,0) width 5 RTL: "." + text run at (-828,0) width 1172: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua" +selection start: position 0 of child 0 {#text} of child 1 {DD} of child 2 {DL} of body +selection end: position 10 of child 0 {#text} of child 3 {DT} of child 2 {DL} of body
diff --git a/third_party/WebKit/LayoutTests/editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-rtl-mixed-expected.png b/third_party/WebKit/LayoutTests/editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-rtl-mixed-expected.png new file mode 100644 index 0000000..88dcee1 --- /dev/null +++ b/third_party/WebKit/LayoutTests/editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-rtl-mixed-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-rtl-mixed-expected.txt b/third_party/WebKit/LayoutTests/editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-rtl-mixed-expected.txt new file mode 100644 index 0000000..e455766 --- /dev/null +++ b/third_party/WebKit/LayoutTests/editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-rtl-mixed-expected.txt
@@ -0,0 +1,19 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x104 + LayoutBlockFlow {HTML} at (0,0) size 800x104 + LayoutBlockFlow {BODY} at (8,16) size 784x80 + LayoutBlockFlow {P} at (0,0) size 784x20 + LayoutText {#text} at (0,0) size 459x19 + text run at (0,0) width 459: "crbug.com/642454: Don't select part of the ellipsis when wrapping selection." + LayoutBlockFlow {DL} at (200,36) size 384x44 + LayoutBlockFlow {DT} at (0,22) size 384x22 + LayoutText {#text} at (0,0) size 206x21 + text run at (0,0) width 206: "Lorem ipsum dolor sit amet" +layer at (208,52) size 344x22 scrollX 49.00 scrollWidth 393 + LayoutBlockFlow {DD} at (0,0) size 344x22 + LayoutText {#text} at (-49,0) size 393x21 + text run at (-49,0) width 344 RTL: " \x{5DC}\x{5D5}\x{5E8}\x{5DD} \x{5D0}\x{5D9}\x{5E4}\x{5E1}\x{5D5}\x{5DD} \x{5D4}\x{5D5}\x{5D0} \x{5DB}\x{5D9}\x{5E0}\x{5D5}\x{5D9} \x{5DC}\x{5D8}\x{5E7}\x{5E1}\x{5D8} \x{5D7}\x{5E1}\x{5E8} \x{5DE}\x{5E9}\x{5DE}\x{5E2}\x{5D5}\x{5EA} \x{5DC}\x{5D7}\x{5DC}\x{5D5}\x{5D8}\x{5D9}\x{5DF}" + text run at (295,0) width 49: "Lorem" +selection start: position 0 of child 0 {#text} of child 1 {DD} of child 2 {DL} of body +selection end: position 10 of child 0 {#text} of child 3 {DT} of child 2 {DL} of body
diff --git a/third_party/WebKit/LayoutTests/editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-rtl-mixed.html b/third_party/WebKit/LayoutTests/editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-rtl-mixed.html new file mode 100644 index 0000000..fb0bb88 --- /dev/null +++ b/third_party/WebKit/LayoutTests/editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-rtl-mixed.html
@@ -0,0 +1,27 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<style> +dl { + max-width: 20em; + margin: auto; + font-size: 120%; + white-space: nowrap; +} +dd { + overflow: hidden; + text-overflow: ellipsis; + text-decoration: inherit; + direction:rtl; +} +</style> +<p>crbug.com/642454: Don't select part of the ellipsis when wrapping selection.</p> +<dl> + <dd id="selection_with_ellipsis">Lorem לורם איפסום הוא כינוי לטקסט חסר משמעות לחלוטין</dd> + <dt id="wrapped">Lorem ipsum dolor sit amet</dt> +</dl> +<script src="../../resources/run-after-layout-and-paint.js"></script> +<script> +runAfterLayoutAndPaint(function() { + getSelection().setBaseAndExtent(selection_with_ellipsis.firstChild, 0, wrapped.firstChild, 10); + }, true); +</script>
diff --git a/third_party/WebKit/LayoutTests/editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-rtl.html b/third_party/WebKit/LayoutTests/editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-rtl.html new file mode 100644 index 0000000..ebd85c0f --- /dev/null +++ b/third_party/WebKit/LayoutTests/editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-rtl.html
@@ -0,0 +1,27 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<style> +dl { + max-width: 20em; + margin: auto; + font-size: 120%; + white-space: nowrap; +} +dd { + overflow: hidden; + text-overflow: ellipsis; + text-decoration: inherit; + direction:rtl; +} +</style> +<p>crbug.com/642454: Don't select part of the ellipsis when wrapping selection.</p> +<dl> + <dd id="selection_with_ellipsis">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</dd> + <dt id="wrapped">Lorem ipsum dolor sit amet</dt> +</dl> +<script src="../../resources/run-after-layout-and-paint.js"></script> +<script> +runAfterLayoutAndPaint(function() { + getSelection().setBaseAndExtent(selection_with_ellipsis.firstChild, 0, wrapped.firstChild, 10); + }, true); +</script>
diff --git a/third_party/WebKit/LayoutTests/editing/selection/dont-select-text-overflow-ellipsis-when-wrapping.html b/third_party/WebKit/LayoutTests/editing/selection/dont-select-text-overflow-ellipsis-when-wrapping.html new file mode 100644 index 0000000..c8c5dd4fd --- /dev/null +++ b/third_party/WebKit/LayoutTests/editing/selection/dont-select-text-overflow-ellipsis-when-wrapping.html
@@ -0,0 +1,26 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<style> +dl { + max-width: 20em; + margin: auto; + font-size: 120%; + white-space: nowrap; +} +dd { + overflow: hidden; + text-overflow: ellipsis; + text-decoration: inherit; +} +</style> +<p>crbug.com/642454: Don't select part of the ellipsis when wrapping selection.</p> +<dl> + <dd id="selection_with_ellipsis">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</dd> + <dt id="wrapped">Lorem ipsum dolor sit amet</dt> +</dl> +<script src="../../resources/run-after-layout-and-paint.js"></script> +<script> +runAfterLayoutAndPaint(function() { + getSelection().setBaseAndExtent(selection_with_ellipsis.firstChild, 0, wrapped.firstChild, 10); + }, true); +</script>
diff --git a/third_party/WebKit/LayoutTests/editing/selection/select-text-overflow-ellipsis-mixed-in-ltr-2-expected.png b/third_party/WebKit/LayoutTests/editing/selection/select-text-overflow-ellipsis-mixed-in-ltr-2-expected.png new file mode 100644 index 0000000..d869e95 --- /dev/null +++ b/third_party/WebKit/LayoutTests/editing/selection/select-text-overflow-ellipsis-mixed-in-ltr-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/editing/selection/select-text-overflow-ellipsis-mixed-in-ltr-2-expected.txt b/third_party/WebKit/LayoutTests/editing/selection/select-text-overflow-ellipsis-mixed-in-ltr-2-expected.txt new file mode 100644 index 0000000..a6c0926 --- /dev/null +++ b/third_party/WebKit/LayoutTests/editing/selection/select-text-overflow-ellipsis-mixed-in-ltr-2-expected.txt
@@ -0,0 +1,16 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x82 + LayoutBlockFlow {HTML} at (0,0) size 800x82 + LayoutBlockFlow {BODY} at (8,16) size 784x58 + LayoutBlockFlow {P} at (0,0) size 784x20 + LayoutText {#text} at (0,0) size 658x19 + text run at (0,0) width 658: "crbug.com/642454: Select all text in mixed ltr-rtl in rtl flow. None of the dots in the ellipsis should be selected." + LayoutBlockFlow {DL} at (200,36) size 384x22 +layer at (248,52) size 344x22 scrollWidth 506 + LayoutBlockFlow {DD} at (40,0) size 344x22 + LayoutText {#text} at (0,0) size 506x21 + text run at (0,0) width 104: "Lorem ipsum " + text run at (104,0) width 402 RTL: "\x{5D9}\x{5E0}\x{5D8}\x{5E8}\x{5E0}\x{5D8} \x{5D5}\x{5DB}\x{5D5}' \x{5D1}\x{5DE}\x{5E7}\x{5D5}\x{5DD} \x{5D4}\x{5D8}\x{5E7}\x{5E1}\x{5D8} \x{5D4}\x{5D0}\x{5DE}\x{5D9}\x{5EA}\x{5D9} \x{5D4}\x{5E1}\x{5D5}\x{5E4}\x{5D9}\x{5E2}\x{5D3} \x{5E9}\x{5D9}\x{5D4}\x{5D9}\x{5D4} \x{5D8}\x{5E7}\x{5E1}\x{5D8} \x{5D0}\x{5DE}\x{5D9}\x{5EA}" +selection start: position 0 of child 0 {#text} of child 1 {DD} of child 2 {DL} of body +selection end: position 66 of child 0 {#text} of child 1 {DD} of child 2 {DL} of body
diff --git a/third_party/WebKit/LayoutTests/editing/selection/select-text-overflow-ellipsis-mixed-in-ltr-2.html b/third_party/WebKit/LayoutTests/editing/selection/select-text-overflow-ellipsis-mixed-in-ltr-2.html new file mode 100644 index 0000000..6623fe5 --- /dev/null +++ b/third_party/WebKit/LayoutTests/editing/selection/select-text-overflow-ellipsis-mixed-in-ltr-2.html
@@ -0,0 +1,25 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<style> +dl { + max-width: 20em; + margin: auto; + font-size: 120%; + white-space: nowrap; +} +dd { + overflow: hidden; + text-overflow: ellipsis; + text-decoration: inherit; +} +</style> +<p>crbug.com/642454: Select all text in mixed ltr-rtl in rtl flow. None of the dots in the ellipsis should be selected.</p> +<dl> + <dd id="selection_with_ellipsis">Lorem ipsum ינטרנט וכו' במקום הטקסט האמיתי הסופיעד שיהיה טקסט אמית</dd> +</dl> +<script src="../../resources/run-after-layout-and-paint.js"></script> +<script> +runAfterLayoutAndPaint(function() { + getSelection().setBaseAndExtent(selection_with_ellipsis.firstChild, 0, selection_with_ellipsis.firstChild, 155); + }, true); +</script>
diff --git a/third_party/WebKit/LayoutTests/editing/selection/select-text-overflow-ellipsis-mixed-in-rtl-2-expected.png b/third_party/WebKit/LayoutTests/editing/selection/select-text-overflow-ellipsis-mixed-in-rtl-2-expected.png new file mode 100644 index 0000000..9d57936 --- /dev/null +++ b/third_party/WebKit/LayoutTests/editing/selection/select-text-overflow-ellipsis-mixed-in-rtl-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/editing/selection/select-text-overflow-ellipsis-mixed-in-rtl-2-expected.txt b/third_party/WebKit/LayoutTests/editing/selection/select-text-overflow-ellipsis-mixed-in-rtl-2-expected.txt new file mode 100644 index 0000000..bef2cac --- /dev/null +++ b/third_party/WebKit/LayoutTests/editing/selection/select-text-overflow-ellipsis-mixed-in-rtl-2-expected.txt
@@ -0,0 +1,16 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x82 + LayoutBlockFlow {HTML} at (0,0) size 800x82 + LayoutBlockFlow {BODY} at (8,16) size 784x58 + LayoutBlockFlow {P} at (0,0) size 784x20 + LayoutText {#text} at (0,0) size 658x19 + text run at (0,0) width 658: "crbug.com/642454: Select all text in mixed ltr-rtl in rtl flow. None of the dots in the ellipsis should be selected." + LayoutBlockFlow {DL} at (200,36) size 384x22 +layer at (208,52) size 344x22 scrollX 162.00 scrollWidth 506 + LayoutBlockFlow {DD} at (0,0) size 344x22 + LayoutText {#text} at (-162,0) size 506x21 + text run at (-162,0) width 407 RTL: " \x{5D9}\x{5E0}\x{5D8}\x{5E8}\x{5E0}\x{5D8} \x{5D5}\x{5DB}\x{5D5}' \x{5D1}\x{5DE}\x{5E7}\x{5D5}\x{5DD} \x{5D4}\x{5D8}\x{5E7}\x{5E1}\x{5D8} \x{5D4}\x{5D0}\x{5DE}\x{5D9}\x{5EA}\x{5D9} \x{5D4}\x{5E1}\x{5D5}\x{5E4}\x{5D9}\x{5E2}\x{5D3} \x{5E9}\x{5D9}\x{5D4}\x{5D9}\x{5D4} \x{5D8}\x{5E7}\x{5E1}\x{5D8} \x{5D0}\x{5DE}\x{5D9}\x{5EA}" + text run at (245,0) width 99: "Lorem ipsum" +selection start: position 0 of child 0 {#text} of child 1 {DD} of child 2 {DL} of body +selection end: position 66 of child 0 {#text} of child 1 {DD} of child 2 {DL} of body
diff --git a/third_party/WebKit/LayoutTests/editing/selection/select-text-overflow-ellipsis-mixed-in-rtl-2.html b/third_party/WebKit/LayoutTests/editing/selection/select-text-overflow-ellipsis-mixed-in-rtl-2.html new file mode 100644 index 0000000..7e0d15c --- /dev/null +++ b/third_party/WebKit/LayoutTests/editing/selection/select-text-overflow-ellipsis-mixed-in-rtl-2.html
@@ -0,0 +1,26 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<style> +dl { + max-width: 20em; + margin: auto; + font-size: 120%; + white-space: nowrap; +} +dd { + overflow: hidden; + text-overflow: ellipsis; + text-decoration: inherit; + direction: rtl; +} +</style> +<p>crbug.com/642454: Select all text in mixed ltr-rtl in rtl flow. None of the dots in the ellipsis should be selected.</p> +<dl> + <dd id="selection_with_ellipsis">Lorem ipsum ינטרנט וכו' במקום הטקסט האמיתי הסופיעד שיהיה טקסט אמית</dd> +</dl> +<script src="../../resources/run-after-layout-and-paint.js"></script> +<script> +runAfterLayoutAndPaint(function() { + getSelection().setBaseAndExtent(selection_with_ellipsis.firstChild, 0, selection_with_ellipsis.firstChild, 155); + }, true); +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/text/ellipsis-mixed-text-in-ltr-flow-underline-2-expected.png b/third_party/WebKit/LayoutTests/fast/text/ellipsis-mixed-text-in-ltr-flow-underline-2-expected.png new file mode 100644 index 0000000..ab9cd256 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/text/ellipsis-mixed-text-in-ltr-flow-underline-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/text/ellipsis-mixed-text-in-ltr-flow-underline-2-expected.txt b/third_party/WebKit/LayoutTests/fast/text/ellipsis-mixed-text-in-ltr-flow-underline-2-expected.txt new file mode 100644 index 0000000..a9e76de --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/text/ellipsis-mixed-text-in-ltr-flow-underline-2-expected.txt
@@ -0,0 +1,16 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x116 + LayoutBlockFlow {HTML} at (0,0) size 800x116 + LayoutBlockFlow {BODY} at (8,16) size 784x92 + LayoutBlockFlow {P} at (0,0) size 784x20 + LayoutText {#text} at (0,0) size 456x19 + text run at (0,0) width 456: "crbug.com/634445: Rtl text in a ltr flow should truncate the text left-to-right." + LayoutBlockFlow {P} at (0,36) size 784x20 + LayoutText {#text} at (0,0) size 382x19 + text run at (0,0) width 382: "You should see an underline beneath the text but not the ellipsis." +layer at (8,88) size 350x20 scrollWidth 425 + LayoutBlockFlow {DIV} at (0,72) size 350x20 + LayoutText {#text} at (0,0) size 425x19 + text run at (0,0) width 83: "Lorem ipsum " + text run at (83,0) width 342 RTL: "\x{5D9}\x{5E0}\x{5D8}\x{5E8}\x{5E0}\x{5D8} \x{5D5}\x{5DB}\x{5D5}' \x{5D1}\x{5DE}\x{5E7}\x{5D5}\x{5DD} \x{5D4}\x{5D8}\x{5E7}\x{5E1}\x{5D8} \x{5D4}\x{5D0}\x{5DE}\x{5D9}\x{5EA}\x{5D9} \x{5D4}\x{5E1}\x{5D5}\x{5E4}\x{5D9}\x{5E2}\x{5D3} \x{5E9}\x{5D9}\x{5D4}\x{5D9}\x{5D4} \x{5D8}\x{5E7}\x{5E1}\x{5D8} \x{5D0}\x{5DE}\x{5D9}\x{5EA}"
diff --git a/third_party/WebKit/LayoutTests/fast/text/ellipsis-mixed-text-in-ltr-flow-underline-2.html b/third_party/WebKit/LayoutTests/fast/text/ellipsis-mixed-text-in-ltr-flow-underline-2.html new file mode 100644 index 0000000..fefc561 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/text/ellipsis-mixed-text-in-ltr-flow-underline-2.html
@@ -0,0 +1,14 @@ +<!DOCTYPE html> +<meta charset='utf-8'> +<style> +div { + width: 350px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + text-decoration: underline; +} +</style> +<p>crbug.com/634445: Rtl text in a ltr flow should truncate the text left-to-right.</p> +<p>You should see an underline beneath the text but not the ellipsis.</p> +<div>Lorem ipsum ינטרנט וכו' במקום הטקסט האמיתי הסופיעד שיהיה טקסט אמית</div>
diff --git a/third_party/WebKit/LayoutTests/fast/text/ellipsis-mixed-text-in-rtl-flow-underline-2-expected.png b/third_party/WebKit/LayoutTests/fast/text/ellipsis-mixed-text-in-rtl-flow-underline-2-expected.png new file mode 100644 index 0000000..d37b5c90 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/text/ellipsis-mixed-text-in-rtl-flow-underline-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/text/ellipsis-mixed-text-in-rtl-flow-underline-2-expected.txt b/third_party/WebKit/LayoutTests/fast/text/ellipsis-mixed-text-in-rtl-flow-underline-2-expected.txt new file mode 100644 index 0000000..8485289 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/text/ellipsis-mixed-text-in-rtl-flow-underline-2-expected.txt
@@ -0,0 +1,16 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x116 + LayoutBlockFlow {HTML} at (0,0) size 800x116 + LayoutBlockFlow {BODY} at (8,16) size 784x92 + LayoutBlockFlow {P} at (0,0) size 784x20 + LayoutText {#text} at (0,0) size 456x19 + text run at (0,0) width 456: "crbug.com/634445: Rtl text in a ltr flow should truncate the text left-to-right." + LayoutBlockFlow {P} at (0,36) size 784x20 + LayoutText {#text} at (0,0) size 382x19 + text run at (0,0) width 382: "You should see an underline beneath the text but not the ellipsis." +layer at (8,88) size 350x20 scrollX 75.00 scrollWidth 425 + LayoutBlockFlow {DIV} at (0,72) size 350x20 + LayoutText {#text} at (-75,0) size 425x19 + text run at (-75,0) width 346 RTL: " \x{5D9}\x{5E0}\x{5D8}\x{5E8}\x{5E0}\x{5D8} \x{5D5}\x{5DB}\x{5D5}' \x{5D1}\x{5DE}\x{5E7}\x{5D5}\x{5DD} \x{5D4}\x{5D8}\x{5E7}\x{5E1}\x{5D8} \x{5D4}\x{5D0}\x{5DE}\x{5D9}\x{5EA}\x{5D9} \x{5D4}\x{5E1}\x{5D5}\x{5E4}\x{5D9}\x{5E2}\x{5D3} \x{5E9}\x{5D9}\x{5D4}\x{5D9}\x{5D4} \x{5D8}\x{5E7}\x{5E1}\x{5D8} \x{5D0}\x{5DE}\x{5D9}\x{5EA}" + text run at (271,0) width 79: "Lorem ipsum"
diff --git a/third_party/WebKit/LayoutTests/fast/text/ellipsis-mixed-text-in-rtl-flow-underline-2.html b/third_party/WebKit/LayoutTests/fast/text/ellipsis-mixed-text-in-rtl-flow-underline-2.html new file mode 100644 index 0000000..d3c8105 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/text/ellipsis-mixed-text-in-rtl-flow-underline-2.html
@@ -0,0 +1,15 @@ +<!DOCTYPE html> +<meta charset='utf-8'> +<style> +div { + width: 350px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + text-decoration: underline; + direction: rtl; +} +</style> +<p>crbug.com/634445: Rtl text in a ltr flow should truncate the text left-to-right.</p> +<p>You should see an underline beneath the text but not the ellipsis.</p> +<div>Lorem ipsum ינטרנט וכו' במקום הטקסט האמיתי הסופיעד שיהיה טקסט אמית</div>
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger/script-collected-expected.txt b/third_party/WebKit/LayoutTests/inspector/sources/debugger/script-collected-expected.txt new file mode 100644 index 0000000..96b5bf0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger/script-collected-expected.txt
@@ -0,0 +1,5 @@ +Tests that DiscardedAnonymousScriptSource event is fired and workspace is cleared. + +Discarded: 1100 +Remaining UISourceCodes: 900 +
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger/script-collected.html b/third_party/WebKit/LayoutTests/inspector/sources/debugger/script-collected.html new file mode 100644 index 0000000..82a66dd4 --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger/script-collected.html
@@ -0,0 +1,42 @@ +<html> +<head> +<script src="../../../http/tests/inspector/inspector-test.js"></script> +<script src="../../../http/tests/inspector/debugger-test.js"></script> +<script> +function generateErrorScripts() +{ + for (var i = 0; i < 2000; ++i) { + try { + eval("#BAD SCRIPT# " + i); + } catch(e) { + } + } +} + +function test() +{ + InspectorTest.startDebuggerTest(step1); + var discardedScripts = 0; + + function step1() + { + InspectorTest.debuggerModel.addEventListener(SDK.DebuggerModel.Events.DiscardedAnonymousScriptSource, () => ++discardedScripts); + InspectorTest.evaluateInPage("generateErrorScripts()\n//# sourceURL=foo", step2); + } + + function step2() + { + InspectorTest.addResult("Discarded: " + discardedScripts); + var codes = Workspace.workspace.uiSourceCodesForProjectType(Workspace.projectTypes.Debugger).filter(code => !code.url().match(/VM\d+\s/)); + InspectorTest.addResult("Remaining UISourceCodes: " + codes.length); + InspectorTest.completeDebuggerTest(); + } +} +</script> +</head> +<body onload="runTest()"> +<p> +Tests that DiscardedAnonymousScriptSource event is fired and workspace is cleared. +</p> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/platform/linux/editing/selection/select-text-overflow-ellipsis-mixed-in-ltr-expected.png b/third_party/WebKit/LayoutTests/platform/linux/editing/selection/select-text-overflow-ellipsis-mixed-in-ltr-expected.png index fc20b80..00b5c62 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/editing/selection/select-text-overflow-ellipsis-mixed-in-ltr-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/editing/selection/select-text-overflow-ellipsis-mixed-in-ltr-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/text/ellipsis-mixed-text-in-ltr-flow-underline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/text/ellipsis-mixed-text-in-ltr-flow-underline-expected.png index 1b7b090..db4e60d 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/text/ellipsis-mixed-text-in-ltr-flow-underline-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/text/ellipsis-mixed-text-in-ltr-flow-underline-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/threaded/fast/idleToBlob/OffscreenCanvas-convertToBlob-webgl-main-expected.html b/third_party/WebKit/LayoutTests/virtual/threaded/fast/idleToBlob/OffscreenCanvas-convertToBlob-webgl-main-expected.html index 61c4f5c..6de349fe 100644 --- a/third_party/WebKit/LayoutTests/virtual/threaded/fast/idleToBlob/OffscreenCanvas-convertToBlob-webgl-main-expected.html +++ b/third_party/WebKit/LayoutTests/virtual/threaded/fast/idleToBlob/OffscreenCanvas-convertToBlob-webgl-main-expected.html
@@ -1,16 +1,30 @@ <img id="png"/> -<script> +<img id="jpeg-high"/> +<img id="jpeg-low"/> +<img id="webp-high"/> +<img id="webp-low"/> +<script type="text/javascript"> if (window.testRunner) { testRunner.waitUntilDone(); } var pngImage = document.getElementById('png'); +var jpegImageHigh = document.getElementById('jpeg-high'); +var jpegImageLow = document.getElementById('jpeg-low'); +var webpImageHigh = document.getElementById('webp-high'); +var webpImageLow = document.getElementById('webp-low'); +var numTestCount = 5; function imageLoaded() { - if (window.testRunner) { + numTestCount--; + if (numTestCount == 0 && window.testRunner) { window.testRunner.notifyDone(); } } pngImage.addEventListener('load', imageLoaded); +jpegImageHigh.addEventListener('load', imageLoaded); +jpegImageLow.addEventListener('load', imageLoaded); +webpImageHigh.addEventListener('load', imageLoaded); +webpImageLow.addEventListener('load', imageLoaded); var canvas = document.createElement("canvas"); canvas.width = 50; @@ -22,5 +36,22 @@ canvas.toBlob(function(blob) { pngImage.src = URL.createObjectURL(blob); }); + +canvas.toBlob(function(blob) { + jpegImageHigh.src = URL.createObjectURL(blob); +}, "image/jpeg", 1.0); + +canvas.toBlob(function(blob) { + jpegImageLow.src = URL.createObjectURL(blob); +}, "image/jpeg", 0.2) + +canvas.toBlob(function(blob) { + webpImageHigh.src = URL.createObjectURL(blob); +}, "image/webp", 1.0); + +canvas.toBlob(function(blob) { + webpImageLow.src = URL.createObjectURL(blob); +}, "image/webp", 0.2); + </script>
diff --git a/third_party/WebKit/LayoutTests/virtual/threaded/fast/idleToBlob/OffscreenCanvas-convertToBlob-webgl-main.html b/third_party/WebKit/LayoutTests/virtual/threaded/fast/idleToBlob/OffscreenCanvas-convertToBlob-webgl-main.html index aeddaf4..69ec02a1 100644 --- a/third_party/WebKit/LayoutTests/virtual/threaded/fast/idleToBlob/OffscreenCanvas-convertToBlob-webgl-main.html +++ b/third_party/WebKit/LayoutTests/virtual/threaded/fast/idleToBlob/OffscreenCanvas-convertToBlob-webgl-main.html
@@ -1,18 +1,30 @@ <img id="png"/> +<img id="jpeg-high"/> +<img id="jpeg-low"/> +<img id="webp-high"/> +<img id="webp-low"/> <script type="text/javascript"> if (window.testRunner) { testRunner.waitUntilDone(); } -// TODO: Add more image types to this test once the toImageData() for webgl -// is completed. See crbug.com/657531. var pngImage = document.getElementById('png'); +var jpegImageHigh = document.getElementById('jpeg-high'); +var jpegImageLow = document.getElementById('jpeg-low'); +var webpImageHigh = document.getElementById('webp-high'); +var webpImageLow = document.getElementById('webp-low'); +var numTestCount = 5; function imageLoaded() { - if (window.testRunner) { + numTestCount--; + if (numTestCount == 0 && window.testRunner) { window.testRunner.notifyDone(); } } pngImage.addEventListener('load', imageLoaded); +jpegImageHigh.addEventListener('load', imageLoaded); +jpegImageLow.addEventListener('load', imageLoaded); +webpImageHigh.addEventListener('load', imageLoaded); +webpImageLow.addEventListener('load', imageLoaded); var offCanvas = new OffscreenCanvas(50, 50); var gl = offCanvas.getContext('webgl'); @@ -24,5 +36,25 @@ pngImage.src = URL.createObjectURL(blob); }); +offCanvas.convertToBlob({type: "image/jpeg"}) + .then(function(blob) { + jpegImageHigh.src = URL.createObjectURL(blob); + }); + +offCanvas.convertToBlob({type: "image/jpeg", quality: 0.2}) + .then(function(blob) { + jpegImageLow.src = URL.createObjectURL(blob); + }); + +offCanvas.convertToBlob({type: "image/webp"}) + .then(function(blob) { + webpImageHigh.src = URL.createObjectURL(blob); + }); + +offCanvas.convertToBlob({type: "image/webp", quality: 0.2}) + .then(function(blob) { + webpImageLow.src = URL.createObjectURL(blob); + }); + </script>
diff --git a/third_party/WebKit/LayoutTests/virtual/threaded/fast/idleToBlob/OffscreenCanvas-convertToBlob-webgl-worker-expected.html b/third_party/WebKit/LayoutTests/virtual/threaded/fast/idleToBlob/OffscreenCanvas-convertToBlob-webgl-worker-expected.html index 61c4f5c..e402eef1 100644 --- a/third_party/WebKit/LayoutTests/virtual/threaded/fast/idleToBlob/OffscreenCanvas-convertToBlob-webgl-worker-expected.html +++ b/third_party/WebKit/LayoutTests/virtual/threaded/fast/idleToBlob/OffscreenCanvas-convertToBlob-webgl-worker-expected.html
@@ -1,16 +1,30 @@ <img id="png"/> +<img id="jpeg-high"/> +<img id="jpeg-low"/> +<img id="webp-high"/> +<img id="webp-low"/> <script> if (window.testRunner) { testRunner.waitUntilDone(); } var pngImage = document.getElementById('png'); +var jpegImageHigh = document.getElementById('jpeg-high'); +var jpegImageLow = document.getElementById('jpeg-low'); +var webpImageHigh = document.getElementById('webp-high'); +var webpImageLow = document.getElementById('webp-low'); +var numTestCount = 5; function imageLoaded() { - if (window.testRunner) { + numTestCount--; + if (numTestCount == 0 && window.testRunner) { window.testRunner.notifyDone(); } } pngImage.addEventListener('load', imageLoaded); +jpegImageHigh.addEventListener('load', imageLoaded); +jpegImageLow.addEventListener('load', imageLoaded); +webpImageHigh.addEventListener('load', imageLoaded); +webpImageLow.addEventListener('load', imageLoaded); var canvas = document.createElement("canvas"); canvas.width = 50; @@ -22,5 +36,22 @@ canvas.toBlob(function(blob) { pngImage.src = URL.createObjectURL(blob); }); + +canvas.toBlob(function(blob) { + jpegImageHigh.src = URL.createObjectURL(blob); +}, "image/jpeg", 1.0); + +canvas.toBlob(function(blob) { + jpegImageLow.src = URL.createObjectURL(blob); +}, "image/jpeg", 0.2) + +canvas.toBlob(function(blob) { + webpImageHigh.src = URL.createObjectURL(blob); +}, "image/webp", 1.0); + +canvas.toBlob(function(blob) { + webpImageLow.src = URL.createObjectURL(blob); +}, "image/webp", 0.2); + </script>
diff --git a/third_party/WebKit/LayoutTests/virtual/threaded/fast/idleToBlob/OffscreenCanvas-convertToBlob-webgl-worker.html b/third_party/WebKit/LayoutTests/virtual/threaded/fast/idleToBlob/OffscreenCanvas-convertToBlob-webgl-worker.html index a9be1b2..e0760ee 100644 --- a/third_party/WebKit/LayoutTests/virtual/threaded/fast/idleToBlob/OffscreenCanvas-convertToBlob-webgl-worker.html +++ b/third_party/WebKit/LayoutTests/virtual/threaded/fast/idleToBlob/OffscreenCanvas-convertToBlob-webgl-worker.html
@@ -1,4 +1,8 @@ <img id="png"/> +<img id="jpeg-high"/> +<img id="jpeg-low"/> +<img id="webp-high"/> +<img id="webp-low"/> <script id="myWorker" type="text/worker"> self.onmessage = function (e) { var offCanvas = new OffscreenCanvas(50, 50); @@ -6,12 +10,31 @@ gl.clearColor(0, 1, 0, 1); gl.clear(gl.COLOR_BUFFER_BIT); - // TODO: Add more image types to this test once the toImageData() for webgl - // is completed. See crbug.com/657531. offCanvas.convertToBlob() .then(function(blob) { self.postMessage({version: "png", data:blob}); }); + + offCanvas.convertToBlob({type: "image/jpeg"}) + .then(function(blob) { + self.postMessage({version: "jpeg-high", data:blob}); + }); + + offCanvas.convertToBlob({type: "image/jpeg", quality: 0.2}) + .then(function(blob) { + self.postMessage({version: "jpeg-low", data:blob}); + }); + + offCanvas.convertToBlob({type: "image/webp"}) + .then(function(blob) { + self.postMessage({version: "webp-high", data:blob}); + }); + + offCanvas.convertToBlob({type: "image/webp", quality: 0.2}) + .then(function(blob) { + + self.postMessage({version: "webp-low", data:blob}); + }); } </script> <script> @@ -20,12 +43,22 @@ } var pngImage = document.getElementById('png'); +var jpegImageHigh = document.getElementById('jpeg-high'); +var jpegImageLow = document.getElementById('jpeg-low'); +var webpImageHigh = document.getElementById('webp-high'); +var webpImageLow = document.getElementById('webp-low'); +var numTestCount = 5; function imageLoaded() { - if (window.testRunner) { + numTestCount--; + if (numTestCount == 0 && window.testRunner) { window.testRunner.notifyDone(); } } pngImage.addEventListener('load', imageLoaded); +jpegImageHigh.addEventListener('load', imageLoaded); +jpegImageLow.addEventListener('load', imageLoaded); +webpImageHigh.addEventListener('load', imageLoaded); +webpImageLow.addEventListener('load', imageLoaded); var workerBlob = new Blob([document.getElementById('myWorker').textContent]); var worker = new Worker(URL.createObjectURL(workerBlob)); @@ -35,6 +68,18 @@ case 'png': pngImage.src = URL.createObjectURL(blob); break; + case 'jpeg-high': + jpegImageHigh.src = URL.createObjectURL(blob); + break; + case 'jpeg-low': + jpegImageLow.src = URL.createObjectURL(blob); + break; + case 'webp-high': + webpImageHigh.src = URL.createObjectURL(blob); + break; + case 'webp-low': + webpImageLow.src = URL.createObjectURL(blob); + break; } }); worker.postMessage("");
diff --git a/third_party/WebKit/LayoutTests/webaudio/Analyser/automatic-pull-node.html b/third_party/WebKit/LayoutTests/webaudio/Analyser/automatic-pull-node.html index 840bad8..1772d72 100644 --- a/third_party/WebKit/LayoutTests/webaudio/Analyser/automatic-pull-node.html +++ b/third_party/WebKit/LayoutTests/webaudio/Analyser/automatic-pull-node.html
@@ -63,7 +63,9 @@ bufferSource.start(0); context.startRendering() - .then(test1Finished(should)) + .then(function () { + test1Finished(should); + }) .then(task.done.bind(task)); }); @@ -88,7 +90,9 @@ bufferSource.start(0); context.startRendering() - .then(test2Finished(should)) + .then(function () { + test2Finished(should); + }) .then(task.done.bind(task)); }); @@ -113,7 +117,9 @@ bufferSource.start(0); context.startRendering() - .then(test3Finished(should)) + .then(function () { + test3Finished(should); + }) .then(task.done.bind(task)); });
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioBuffer/audiobuffer-expected.txt b/third_party/WebKit/LayoutTests/webaudio/AudioBuffer/audiobuffer-expected.txt deleted file mode 100644 index 27eeccd6..0000000 --- a/third_party/WebKit/LayoutTests/webaudio/AudioBuffer/audiobuffer-expected.txt +++ /dev/null
@@ -1,19 +0,0 @@ -Basic tests for AudioBuffer. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -PASS sampleRate has been set correctly. -PASS length has been set correctly. -PASS duration has been set correctly. -PASS numberOfChannels has been set correctly. -PASS getChannelData(0) returns a Float32Array object. -PASS getChannelData(1) returns a Float32Array object. -PASS getChannelData(2) returns a Float32Array object. -PASS getChannelData(3) returns a Float32Array object. -PASS Exception has been thrown correctly when index is not less than numberOfChannels. -PASS duration has expected accuracy. -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioBuffer/audiobuffer.html b/third_party/WebKit/LayoutTests/webaudio/AudioBuffer/audiobuffer.html index 65abaa1..0f23cff2 100644 --- a/third_party/WebKit/LayoutTests/webaudio/AudioBuffer/audiobuffer.html +++ b/third_party/WebKit/LayoutTests/webaudio/AudioBuffer/audiobuffer.html
@@ -1,62 +1,66 @@ <!DOCTYPE html> <html> <head> -<script src="../../resources/js-test.js"></script> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> <script src="../resources/audit-util.js"></script> -<script src="../resources/audio-testing.js"></script> +<script src="../resources/audit.js"></script> </head> <body> <script> -description("Basic tests for AudioBuffer."); +let sampleRate = 44100.0 +let lengthInSeconds = 2; +let numberOfChannels = 4; -var sampleRate = 44100.0 -var lengthInSeconds = 2; -var numberOfChannels = 4; +let audit = Audit.createTaskRunner(); -var context = new AudioContext(); -var buffer = context.createBuffer(numberOfChannels, sampleRate * lengthInSeconds, sampleRate); +audit.define("Basic tests for AudioBuffer", function (task, should) { + let context = new AudioContext(); + let buffer = context.createBuffer(numberOfChannels, + sampleRate * lengthInSeconds, sampleRate); -if (buffer.sampleRate === sampleRate) - testPassed("sampleRate has been set correctly."); -else - testFailed("sampleRate should be set correctly."); + // Just for printing out a message describing what "buffer" is in the + // following tests. + should(true, + "buffer = context.createBuffer(" + numberOfChannels + ", " + ( + sampleRate * lengthInSeconds) + ", " + sampleRate + ")") + .beTrue(); -if (buffer.length === sampleRate * lengthInSeconds) - testPassed("length has been set correctly."); -else - testFailed("length should be set correctly"); + should(buffer.sampleRate, "buffer.sampleRate") + .beEqualTo(sampleRate); -if (buffer.duration === lengthInSeconds) - testPassed("duration has been set correctly."); -else - testFailed("duration should be set correctly."); + should(buffer.length, "buffer.length") + .beEqualTo(sampleRate * lengthInSeconds); -if (buffer.numberOfChannels === numberOfChannels) - testPassed("numberOfChannels has been set correctly."); -else - testFailed("numberOfChannels should be set correctly."); + should(buffer.duration, "buffer.duration") + .beEqualTo(lengthInSeconds); -for (var index = 0; index < buffer.numberOfChannels; ++index) { - if (buffer.getChannelData(index) instanceof window.Float32Array) - testPassed("getChannelData(" + index + ") returns a Float32Array object."); - else - testFailed("getChannelData(" + index + ") should return a Float32Array object."); -} + should(buffer.numberOfChannels, "buffer.numberOfChannels") + .beEqualTo(numberOfChannels); -try { - buffer.getChannelData(buffer.numberOfChannels); - testFailed("Exception should be thrown when index is not less than numberOfChannels."); -} catch(e) { - testPassed("Exception has been thrown correctly when index is not less than numberOfChannels."); -} + for (let index = 0; index < buffer.numberOfChannels; ++index) { + should( + buffer.getChannelData(index) instanceof window.Float32Array, + "buffer.getChannelData(" + index + + ") instanceof window.Float32Array") + .beTrue(); + } -var buffer2 = context.createBuffer(1, 1000, 24576); -var expectedDuration = 1000/24576; + should(function () { + buffer.getChannelData(buffer.numberOfChannels); + }, "buffer.getChannelData(" + buffer.numberOfChannels + ")") + .throw("IndexSizeError"); -if (buffer2.duration == expectedDuration) - testPassed("duration has expected accuracy."); -else - testFailed("duration is " + buffer2.duration + " sec instead of " + expectedDuration + " sec."); + let buffer2 = context.createBuffer(1, 1000, 24576); + let expectedDuration = 1000 / 24576; + + should(buffer2.duration, "context.createBuffer(1, 1000, 24576).duration") + .beEqualTo(expectedDuration); + + task.done(); +}); + +audit.run(); </script> </body>
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-channels-expected.txt b/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-channels-expected.txt deleted file mode 100644 index 2263542..0000000 --- a/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-channels-expected.txt +++ /dev/null
@@ -1,19 +0,0 @@ -Tests that AudioBufferSourceNode validates AudioBuffer in .buffer attribute setter. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - -PASS source.buffer = 57 threw exception TypeError: Failed to set the 'buffer' property on 'AudioBufferSourceNode': The provided value is not of type 'AudioBuffer'.. -PASS source.buffer = null threw exception TypeError: Failed to set the 'buffer' property on 'AudioBufferSourceNode': The provided value is not of type 'AudioBuffer'.. -PASS Mono buffer can be set. -PASS Stereo buffer can be set. -PASS 3 channels buffer can be set. -PASS 4 channels buffer can be set. -PASS 5 channels buffer can be set. -PASS 6 channels buffer can be set. -PASS 7 channels buffer can be set. -PASS 8 channels buffer can be set. -PASS 9 channels buffer can be set. -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-channels.html b/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-channels.html index f123103..2fecbc4 100644 --- a/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-channels.html +++ b/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-channels.html
@@ -2,74 +2,66 @@ <html> <head> -<script src="../../resources/js-test.js"></script> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> <script src="../resources/audit-util.js"></script> -<script src="../resources/audio-testing.js"></script> +<script src="../resources/audit.js"></script> </head> <body> -<div id="description"></div> -<div id="console"></div> - <script> -description("Tests that AudioBufferSourceNode validates AudioBuffer in .buffer attribute setter."); +let audit = Audit.createTaskRunner(); +let context; +let source; -var context; -var source; - -function runTest() { - if (window.testRunner) { - testRunner.dumpAsText(); - testRunner.waitUntilDone(); - } - - window.jsTestIsAsync = true; - +audit.define("validate .buffer", + function(task, should) { + task.describe( + "AudioBufferSourceNode validates AudioBuffer in .buffer attribute setter" + ); context = new AudioContext(); source = context.createBufferSource(); // Make sure we can't set to something which isn't an AudioBuffer. - shouldThrow("source.buffer = 57", '"TypeError: Failed to set the \'buffer\' property on \'AudioBufferSourceNode\': The provided value is not of type \'AudioBuffer\'."'); - shouldThrow("source.buffer = null", '"TypeError: Failed to set the \'buffer\' property on \'AudioBufferSourceNode\': The provided value is not of type \'AudioBuffer\'."'); + should(function() { + source.buffer = 57; + }, "source.buffer = 57") + .throw("TypeError"); + + should(function() { + source.buffer = null; + }, "source.buffer = null") + .throw("TypeError"); // Check that mono buffer can be set. - try { - var monoBuffer = context.createBuffer(1, 1024, context.sampleRate); - var testSource = context.createBufferSource(); + should(function() { + let monoBuffer = context.createBuffer(1, 1024, context.sampleRate); + let testSource = context.createBufferSource(); testSource.buffer = monoBuffer; - testPassed("Mono buffer can be set."); - } catch(e) { - testFailed("Mono buffer can not be set."); - } + }, "Setting source with mono buffer") + .notThrow(); // Check that stereo buffer can be set. - try { - var stereoBuffer = context.createBuffer(2, 1024, context.sampleRate); - var testSource = context.createBufferSource(); + should(function() { + let stereoBuffer = context.createBuffer(2, 1024, context.sampleRate); + let testSource = context.createBufferSource(); testSource.buffer = stereoBuffer; - testPassed("Stereo buffer can be set."); - } catch(e) { - testFailed("Stereo buffer can not be set."); - } - - // Check buffers with more than two channels. - for (var i = 3; i < 10; ++i) { - try { - var buffer = context.createBuffer(i, 1024, context.sampleRate); - var testSource = context.createBufferSource(); - testSource.buffer = buffer; - var message = i + " channels buffer can be set."; - testPassed(message); - } catch(e) { - var message = i + " channels buffer can not be set."; - testFailed(message); - } - } - - finishJSTest(); -} + }, "Setting source with stereo buffer") + .notThrow(); -runTest(); + // Check buffers with more than two channels. + for (let i = 3; i < 10; ++i) { + should(function() { + let buffer = context.createBuffer(i, 1024, context.sampleRate); + let testSource = context.createBufferSource(); + testSource.buffer = buffer; + }, "Setting source with " + i + " channels buffer") + .notThrow(); + } + task.done(); + }); + +audit.run(); </script>
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-grain-expected.txt b/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-grain-expected.txt deleted file mode 100644 index 619558d1..0000000 --- a/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-grain-expected.txt +++ /dev/null
@@ -1,10 +0,0 @@ -Test setting the source buffer after starting the grain - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -PASS Buffer was played. -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-grain.html b/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-grain.html index a50b108..0ac2da6b 100644 --- a/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-grain.html +++ b/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-grain.html
@@ -2,31 +2,30 @@ <html> <head> <title>Test Start Grain with Delayed Buffer Setting </title> - <script src="../../resources/js-test.js"></script> + <script src="../../resources/testharness.js"></script> + <script src="../../resources/testharnessreport.js"></script> <script src="../resources/audit-util.js"></script> - <script src="../resources/audio-testing.js"></script> + <script src="../resources/audit.js"></script> </head> <body> <script> - description("Test setting the source buffer after starting the grain"); + let audit = Audit.createTaskRunner(); + let context; + let source; + let buffer; + let renderedData; - var context; - var source; - var buffer; - var renderedData; + let sampleRate = 44100; - var sampleRate = 44100; + let testDurationSec = 1; + let testDurationSamples = testDurationSec * sampleRate; + let startTime = 0.9 * testDurationSec; - var testDurationSec = 1; - var testDurationSamples = testDurationSec * sampleRate; - var startTime = 0.9 * testDurationSec; - - function runTest() { - window.jsTestIsAsync = true; - - context = new OfflineAudioContext(1, testDurationSamples, sampleRate); - context.oncomplete = checkResult; + audit.define("Test setting the source buffer after starting the grain", + function (task, should) { + context = new OfflineAudioContext(1, testDurationSamples, + sampleRate); buffer = createConstantBuffer(context, testDurationSamples, 1); source = context.createBufferSource(); @@ -38,34 +37,32 @@ source.buffer = buffer; // Render it! - context.startRendering(); - } + context.startRendering() + .then(function (buffer) { + checkResult(buffer, should); + }) + .then(task.done.bind(task));; + }); - function checkResult(event) { - var success = false; + function checkResult(buffer, should) { + let success = false; - renderedData = event.renderedBuffer.getChannelData(0); + renderedData = buffer.getChannelData(0); - // Check that the rendered data is not all zeroes. Any non-zero data means the test - // passed. - var startFrame = Math.round(startTime * sampleRate); - for (k = 0; k < renderedData.length; ++k) { - if (renderedData[k]) { - success = true; - break; - } + // Check that the rendered data is not all zeroes. Any non-zero data means the test + // passed. + let startFrame = Math.round(startTime * sampleRate); + for (k = 0; k < renderedData.length; ++k) { + if (renderedData[k]) { + success = true; + break; } + } - if (success) - testPassed("Buffer was played."); - else - testFailed("Buffer was not played."); - - finishJSTest(); + should(success, "Buffer was played").beTrue(); } - runTest(); - successfullyParsed = true; + audit.run(); </script> </body> </html>
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-one-sample-loop-expected.txt b/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-one-sample-loop-expected.txt deleted file mode 100644 index a3634ee..0000000 --- a/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-one-sample-loop-expected.txt +++ /dev/null
@@ -1,10 +0,0 @@ -Test AudioBufferSourceNode With Looping a Single-Sample Buffer - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -PASS All samples equal to 1 -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-one-sample-loop.html b/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-one-sample-loop.html index 0e824a3..af2366d4 100644 --- a/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-one-sample-loop.html +++ b/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-one-sample-loop.html
@@ -2,63 +2,44 @@ <html> <head> <title>Test AudioBufferSourceNode With Looping a Single-Sample Buffer</title> - <script src="../../resources/js-test.js"></script> + <script src="../../resources/testharness.js"></script> + <script src="../../resources/testharnessreport.js"></script> <script src="../resources/audit-util.js"></script> - <script src="../resources/audio-testing.js"></script> + <script src="../resources/audit.js"></script> </head> <body> <script> - description("Test AudioBufferSourceNode With Looping a Single-Sample Buffer"); + let audit = Audit.createTaskRunner(); - var context; - var source; - var buffer; - var renderedData; + let sampleRate = 44100; + let testDurationSamples = 1000; - var sampleRate = 44100; - var testDurationSamples = 1000; + audit.define("one-sample-loop", function (task, should) { + // Create the offline context for the test. + let context = new OfflineAudioContext(1, testDurationSamples, + sampleRate); - function checkResult (event) { - var success = true; + // Create the single sample buffer + let buffer = createConstantBuffer(context, 1, 1); - renderedData = event.renderedBuffer.getChannelData(0); - // Check that the rendered data is all ones, like the buffer source. - for (k = 0; k < renderedData.length; ++k) { - if (renderedData[k] != 1) { - success = false; - testFailed("Expected all ones, but sample " + k + " is " + renderedData[k]); - break; - } - } - if (success) - testPassed("All samples equal to 1"); - finishJSTest(); - } + // Create the source and connect it to the destination + let source = context.createBufferSource(); + source.buffer = buffer; + source.loop = true; + source.connect(context.destination); + source.start(); - function runTest() { - window.jsTestIsAsync = true; + // Render it! + context.startRendering() + .then(function(audioBuffer) { + should(audioBuffer.getChannelData(0), "Rendered data") + .beConstantValueOf(1); + }) + .then(task.done.bind(task));; + }); - // Create the offline context for the test. - context = new OfflineAudioContext(1, testDurationSamples, sampleRate); - context.oncomplete = checkResult; - - // Create the single sample buffer - buffer = createConstantBuffer(context, 1, 1); - - // Create the source and connect it to the destination - source = context.createBufferSource(); - source.buffer = buffer; - source.loop = true; - source.connect(context.destination); - source.start(); - - // Render it! - context.startRendering(); - } - - runTest(); - succesfullyParsed = true; + audit.run(); </script> </body> </html>
diff --git a/third_party/WebKit/Source/core/frame/FrameView.cpp b/third_party/WebKit/Source/core/frame/FrameView.cpp index 7befa59..e28f3e7 100644 --- a/third_party/WebKit/Source/core/frame/FrameView.cpp +++ b/third_party/WebKit/Source/core/frame/FrameView.cpp
@@ -4552,6 +4552,14 @@ void FrameView::updateViewportIntersectionsForSubtree( DocumentLifecycle::LifecycleState targetState) { + // TODO(dcheng): Since widget tree updates are deferred, FrameViews might + // still be in the widget hierarchy even though the associated Document is + // already detached. Investigate if this check and a similar check in + // lifecycle updates are still needed when there are no more deferred widget + // updates: https://crbug.com/561683 + if (!frame().document()->isActive()) + return; + // Notify javascript IntersectionObservers if (targetState == DocumentLifecycle::PaintClean && frame().document()->intersectionObserverController())
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h index e6a3d891..7aa0815 100644 --- a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h +++ b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h
@@ -92,9 +92,7 @@ virtual PassRefPtr<Image> getImage(AccelerationHint, SnapshotReason) const = 0; - virtual ImageData* toImageData(SnapshotReason reason) const { - return nullptr; - } + virtual ImageData* toImageData(SnapshotReason reason) { return nullptr; } virtual ContextType getContextType() const = 0; virtual bool isAccelerated() const { return false; } virtual bool shouldAntialias() const { return false; }
diff --git a/third_party/WebKit/Source/core/layout/LayoutTextTrackContainer.cpp b/third_party/WebKit/Source/core/layout/LayoutTextTrackContainer.cpp index fd075d22..67532156 100644 --- a/third_party/WebKit/Source/core/layout/LayoutTextTrackContainer.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutTextTrackContainer.cpp
@@ -69,10 +69,10 @@ // the behavior is currently not portable. fontSize may have precision higher // than m_fontSize thus straight comparison can fail despite they cast to the // same float value. - volatile float& m_fontSize = this->m_fontSize; - float oldFontSize = m_fontSize; - m_fontSize = fontSize; - return m_fontSize != oldFontSize; + volatile float& currentFontSize = m_fontSize; + float oldFontSize = currentFontSize; + currentFontSize = fontSize; + return currentFontSize != oldFontSize; } } // namespace blink
diff --git a/third_party/WebKit/Source/core/paint/InlineTextBoxPainter.cpp b/third_party/WebKit/Source/core/paint/InlineTextBoxPainter.cpp index cb57b318..2b15321b 100644 --- a/third_party/WebKit/Source/core/paint/InlineTextBoxPainter.cpp +++ b/third_party/WebKit/Source/core/paint/InlineTextBoxPainter.cpp
@@ -559,11 +559,21 @@ if (respectHyphen) selectionEnd = textRun.length(); + bool ltr = m_inlineTextBox.isLeftToRightDirection(); + bool flowIsLTR = + m_inlineTextBox.getLineLayoutItem().style()->isLeftToRightDirection(); if (m_inlineTextBox.truncation() != cNoTruncation) { + // In a mixed-direction flow the ellipsis is at the start of the text + // rather than at the end of it. selectionStart = - std::min<int>(selectionStart, m_inlineTextBox.truncation()); - selectionEnd = std::min<int>(selectionEnd, m_inlineTextBox.truncation()); - length = m_inlineTextBox.truncation(); + ltr == flowIsLTR + ? std::min<int>(selectionStart, m_inlineTextBox.truncation()) + : std::max<int>(selectionStart, m_inlineTextBox.truncation()); + selectionEnd = + ltr == flowIsLTR + ? std::min<int>(selectionEnd, m_inlineTextBox.truncation()) + : std::max<int>(selectionEnd, m_inlineTextBox.truncation()); + length = ltr == flowIsLTR ? m_inlineTextBox.truncation() : textRun.length(); } TextPainter textPainter(context, font, textRun, textOrigin, boxRect, @@ -576,27 +586,25 @@ emphasisMarkPosition); if (combinedText) textPainter.setCombinedText(combinedText); + if (m_inlineTextBox.truncation() != cNoTruncation && ltr != flowIsLTR) + textPainter.setEllipsisOffset(m_inlineTextBox.truncation()); if (!paintSelectedTextOnly) { int startOffset = 0; int endOffset = length; - if (paintSelectedTextSeparately && selectionStart < selectionEnd) { - startOffset = selectionEnd; - endOffset = selectionStart; - } // Where the text and its flow have opposite directions then our offset into // the text given by |truncation| is at the start of the part that will be // visible. - if (m_inlineTextBox.truncation() != cNoTruncation && - m_inlineTextBox.getLineLayoutItem() - .containingBlock() - .style() - ->isLeftToRightDirection() != - m_inlineTextBox.isLeftToRightDirection()) { + if (m_inlineTextBox.truncation() != cNoTruncation && ltr != flowIsLTR) { startOffset = m_inlineTextBox.truncation(); endOffset = textRun.length(); } + if (paintSelectedTextSeparately && selectionStart < selectionEnd) { + startOffset = selectionEnd; + endOffset = selectionStart; + } + // FIXME: This cache should probably ultimately be held somewhere else. // A hashmap is convenient to avoid a memory hit when the // RuntimeEnabledFeature is off. @@ -945,11 +953,13 @@ bool flowIsLTR = m_inlineTextBox.getLineLayoutItem().style()->isLeftToRightDirection(); if (m_inlineTextBox.truncation() != cNoTruncation) { - start = ltr == flowIsLTR ? m_inlineTextBox.start() - : m_inlineTextBox.truncation(); - length = ltr == flowIsLTR - ? m_inlineTextBox.truncation() - : m_inlineTextBox.len() - m_inlineTextBox.truncation(); + // In a mixed-direction flow the ellipsis is at the start of the text + // so we need to start after it. Otherwise we just need to make sure + // the end of the text is where the ellipsis starts. + if (ltr != flowIsLTR) + sPos = std::max<int>(sPos, m_inlineTextBox.truncation()); + else + length = m_inlineTextBox.truncation(); } StringView string(m_inlineTextBox.getLineLayoutItem().text(), start, static_cast<unsigned>(length)); @@ -988,10 +998,12 @@ (boxRect.y() - deltaY).toFloat()); LayoutRect selectionRect = LayoutRect( font.selectionRectForText(textRun, localOrigin, selHeight, sPos, ePos)); - if (m_inlineTextBox.hasWrappedSelectionNewline() - // For line breaks, just painting a selection where the line break itself - // is rendered is sufficient. - && !m_inlineTextBox.isLineBreak()) + // For line breaks, just painting a selection where the line break itself + // is rendered is sufficient. Don't select it if there's an ellipsis + // there. + if (m_inlineTextBox.hasWrappedSelectionNewline() && + m_inlineTextBox.truncation() == cNoTruncation && + !m_inlineTextBox.isLineBreak()) expandToIncludeNewlineForSelection(selectionRect); // Line breaks report themselves as having zero width for layout purposes, @@ -1001,7 +1013,7 @@ if (!m_inlineTextBox.isLeftToRightDirection() && m_inlineTextBox.isLineBreak()) selectionRect.move(-selectionRect.width(), LayoutUnit()); - if (!flowIsLTR && m_inlineTextBox.truncation() != cNoTruncation) + if (!flowIsLTR && !ltr && m_inlineTextBox.truncation() != cNoTruncation) selectionRect.move(m_inlineTextBox.logicalWidth() - selectionRect.width(), LayoutUnit()); @@ -1038,8 +1050,9 @@ bool flowIsLTR = m_inlineTextBox.getLineLayoutItem().style()->isLeftToRightDirection(); width = LayoutUnit(m_inlineTextBox.getLineLayoutItem().width( - ltr == flowIsLTR ? m_inlineTextBox.start() - : m_inlineTextBox.truncation(), + ltr == flowIsLTR + ? m_inlineTextBox.start() + : m_inlineTextBox.start() + m_inlineTextBox.truncation(), ltr == flowIsLTR ? m_inlineTextBox.truncation() : m_inlineTextBox.len() - m_inlineTextBox.truncation(), m_inlineTextBox.textPos(),
diff --git a/third_party/WebKit/Source/core/paint/TextPainter.cpp b/third_party/WebKit/Source/core/paint/TextPainter.cpp index 95c02bd..36a1f3b 100644 --- a/third_party/WebKit/Source/core/paint/TextPainter.cpp +++ b/third_party/WebKit/Source/core/paint/TextPainter.cpp
@@ -36,7 +36,8 @@ m_textBounds(textBounds), m_horizontal(horizontal), m_emphasisMarkOffset(0), - m_combinedText(0) {} + m_combinedText(0), + m_ellipsisOffset(0) {} TextPainter::~TextPainter() {} @@ -247,7 +248,7 @@ paintInternalRun<Step>(textRunPaintInfo, startOffset, endOffset); } else { if (endOffset > 0) - paintInternalRun<Step>(textRunPaintInfo, 0, endOffset); + paintInternalRun<Step>(textRunPaintInfo, m_ellipsisOffset, endOffset); if (startOffset < truncationPoint) paintInternalRun<Step>(textRunPaintInfo, startOffset, truncationPoint); }
diff --git a/third_party/WebKit/Source/core/paint/TextPainter.h b/third_party/WebKit/Source/core/paint/TextPainter.h index 48a87e9..a3d1de2 100644 --- a/third_party/WebKit/Source/core/paint/TextPainter.h +++ b/third_party/WebKit/Source/core/paint/TextPainter.h
@@ -47,6 +47,7 @@ void setCombinedText(LayoutTextCombine* combinedText) { m_combinedText = combinedText; } + void setEllipsisOffset(int offset) { m_ellipsisOffset = offset; } static void updateGraphicsContext(GraphicsContext&, const Style&, @@ -117,6 +118,7 @@ AtomicString m_emphasisMark; int m_emphasisMarkOffset; LayoutTextCombine* m_combinedText; + int m_ellipsisOffset; }; inline AffineTransform TextPainter::rotation(
diff --git a/third_party/WebKit/Source/devtools/front_end/bindings/DebuggerWorkspaceBinding.js b/third_party/WebKit/Source/devtools/front_end/bindings/DebuggerWorkspaceBinding.js index ebc3a428..84ebe85a 100644 --- a/third_party/WebKit/Source/devtools/front_end/bindings/DebuggerWorkspaceBinding.js +++ b/third_party/WebKit/Source/devtools/front_end/bindings/DebuggerWorkspaceBinding.js
@@ -356,6 +356,8 @@ debuggerModel.addEventListener(SDK.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this), debuggerModel.addEventListener( SDK.DebuggerModel.Events.FailedToParseScriptSource, this._parsedScriptSource, this), + debuggerModel.addEventListener( + SDK.DebuggerModel.Events.DiscardedAnonymousScriptSource, this._discardedScriptSource, this) ]; } @@ -380,6 +382,14 @@ } /** + * @param {!Common.Event} event + */ + _discardedScriptSource(event) { + var script = /** @type {!SDK.Script} */ (event.data); + this._defaultMapping.removeScript(script); + } + + /** * @param {!Workspace.UISourceCode} uiSourceCode * @param {?Bindings.DebuggerSourceMapping} sourceMapping */
diff --git a/third_party/WebKit/Source/devtools/front_end/bindings/DefaultScriptMapping.js b/third_party/WebKit/Source/devtools/front_end/bindings/DefaultScriptMapping.js index 10407e2..37b06eb 100644 --- a/third_party/WebKit/Source/devtools/front_end/bindings/DefaultScriptMapping.js +++ b/third_party/WebKit/Source/devtools/front_end/bindings/DefaultScriptMapping.js
@@ -112,6 +112,18 @@ } /** + * @param {!SDK.Script} script + */ + removeScript(script) { + var uiSourceCode = script[Bindings.DefaultScriptMapping._uiSourceCodeSymbol]; + if (!uiSourceCode) + return; + delete script[Bindings.DefaultScriptMapping._uiSourceCodeSymbol]; + delete uiSourceCode[Bindings.DefaultScriptMapping._scriptSymbol]; + this._project.removeUISourceCode(uiSourceCode.url()); + } + + /** * @override * @return {boolean} */
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js index 6593e49..4de10f21 100644 --- a/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js +++ b/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js
@@ -47,6 +47,8 @@ this._scripts = {}; /** @type {!Map.<string, !Array.<!SDK.Script>>} */ this._scriptsBySourceURL = new Map(); + /** @type {!Array.<!SDK.Script>} */ + this._discardableScripts = []; /** @type {!Common.Object} */ this._breakpointResolvedEventTarget = new Common.Object(); @@ -323,6 +325,7 @@ this._scripts = {}; this._scriptsBySourceURL.clear(); this._stringMap.clear(); + this._discardableScripts = []; } /** @@ -494,13 +497,18 @@ sourceURL = this._internString(sourceURL); } var script = new SDK.Script( - this, scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, this._internString(hash), - isContentScript, isLiveEdit, sourceMapURL, hasSourceURL); + this, scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, + this._internString(hash), isContentScript, isLiveEdit, sourceMapURL, hasSourceURL); this._registerScript(script); if (!hasSyntaxError) this.dispatchEventToListeners(SDK.DebuggerModel.Events.ParsedScriptSource, script); else this.dispatchEventToListeners(SDK.DebuggerModel.Events.FailedToParseScriptSource, script); + var isDiscardable = hasSyntaxError && script.isAnonymousScript(); + if (isDiscardable) { + this._discardableScripts.push(script); + this._collectDiscardedScripts(); + } return script; } @@ -522,6 +530,24 @@ /** * @param {!SDK.Script} script + */ + _unregisterScript(script) { + console.assert(script.isAnonymousScript()); + delete this._scripts[script.scriptId]; + } + + _collectDiscardedScripts() { + if (this._discardableScripts.length < 1000) + return; + var scriptsToDiscard = this._discardableScripts.splice(0, 100); + for (var script of scriptsToDiscard) { + this._unregisterScript(script); + this.dispatchEventToListeners(SDK.DebuggerModel.Events.DiscardedAnonymousScriptSource, script); + } + } + + /** + * @param {!SDK.Script} script * @param {number} lineNumber * @param {number} columnNumber * @return {?SDK.DebuggerModel.Location} @@ -804,9 +830,9 @@ * @return {string} string */ _internString(string) { - if (!this._stringMap.has(string)) - this._stringMap.set(string, string); - return this._stringMap.get(string); + if (!this._stringMap.has(string)) + this._stringMap.set(string, string); + return this._stringMap.get(string); } }; @@ -832,6 +858,7 @@ DebuggerResumed: Symbol('DebuggerResumed'), ParsedScriptSource: Symbol('ParsedScriptSource'), FailedToParseScriptSource: Symbol('FailedToParseScriptSource'), + DiscardedAnonymousScriptSource: Symbol('DiscardedAnonymousScriptSource'), GlobalObjectCleared: Symbol('GlobalObjectCleared'), CallFrameSelected: Symbol('CallFrameSelected'), ConsoleCommandEvaluatedInSelectedCallFrame: Symbol('ConsoleCommandEvaluatedInSelectedCallFrame'),
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChartView.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChartView.js index 0b4d4d7..c638759 100644 --- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChartView.js +++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChartView.js
@@ -129,8 +129,15 @@ this._networkView.alwaysShowVerticalScroll(); networkViewGroupExpansionSetting.addChangeListener(this.resizeToPreferredHeights.bind(this)); + const networkPane = new UI.VBox(); + networkPane.setMinimumSize(23, 23); + this._networkView.show(networkPane.element); + this._splitResizer = networkPane.element.createChild('div', 'timeline-flamechart-resizer'); + this._splitWidget.hideDefaultResizer(); + this._splitWidget.installResizer(this._splitResizer); + this._splitWidget.setMainWidget(this._mainView); - this._splitWidget.setSidebarWidget(this._networkView); + this._splitWidget.setSidebarWidget(networkPane); this._splitWidget.show(this.element); this._onMainEntrySelected = this._onEntrySelected.bind(this, this._dataProvider); @@ -288,7 +295,7 @@ } resizeToPreferredHeights() { - this._splitWidget.setSidebarSize(this._networkDataProvider.preferredHeight()); + this._splitWidget.setSidebarSize(this._networkDataProvider.preferredHeight() + this._splitResizer.clientHeight); } };
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineNetworkFlameChart.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineNetworkFlameChart.js index 99b668d..1243f468 100644 --- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineNetworkFlameChart.js +++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineNetworkFlameChart.js
@@ -349,7 +349,7 @@ * @return {number} */ preferredHeight() { - return this._style.height * (this._group.expanded ? Number.constrain(this._maxLevel + 1, 4, 8) : 2) + 2; + return this._style.height * (this._group.expanded ? Number.constrain(this._maxLevel + 1, 4, 8) : 2); } /**
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js index 0bbceac..81484a6 100644 --- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js +++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js
@@ -1283,6 +1283,7 @@ this._defaultDetailsWidget.element.classList.add('timeline-details-view'); this._defaultDetailsContentElement = this._defaultDetailsWidget.element.createChild('div', 'timeline-details-view-body vbox'); + this._defaultDetailsContentElement.tabIndex = 0; this.appendTab(tabIds.Details, Common.UIString('Summary'), this._defaultDetailsWidget); this.setPreferredTab(tabIds.Details);
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/timelinePanel.css b/third_party/WebKit/Source/devtools/front_end/timeline/timelinePanel.css index 79fa08f3..021b1b1 100644 --- a/third_party/WebKit/Source/devtools/front_end/timeline/timelinePanel.css +++ b/third_party/WebKit/Source/devtools/front_end/timeline/timelinePanel.css
@@ -440,6 +440,22 @@ overflow: hidden; } +.timeline-flamechart-resizer { + height: 7px; + background-color: #f3f3f3; + border-top: #a3a3a3 1px solid; + display: flex; + flex-direction: row; + align-items: flex-end; + justify-content: center; +} + +.timeline-flamechart-resizer:after { + content: "..."; + font-size: 14px; + margin-bottom: -1px; +} + .timeline-status-pane.full-widget-dimmed-banner { text-align: left !important; }
diff --git a/third_party/WebKit/Source/devtools/scripts/npm_test.js b/third_party/WebKit/Source/devtools/scripts/npm_test.js index 701c21ae..4522399 100644 --- a/third_party/WebKit/Source/devtools/scripts/npm_test.js +++ b/third_party/WebKit/Source/devtools/scripts/npm_test.js
@@ -38,7 +38,7 @@ console.log("Compiling devtools frontend"); shell(`ninja -C ${RELEASE_PATH} devtools_frontend_resources`); } - runTests(outDir, false); + runTests(outDir, IS_DEBUG_ENABLED); return; } if (!utils.isDir(CACHE_PATH))
diff --git a/third_party/WebKit/Source/modules/gamepad/NavigatorGamepad.cpp b/third_party/WebKit/Source/modules/gamepad/NavigatorGamepad.cpp index 8b4411a..1dd81ed 100644 --- a/third_party/WebKit/Source/modules/gamepad/NavigatorGamepad.cpp +++ b/third_party/WebKit/Source/modules/gamepad/NavigatorGamepad.cpp
@@ -59,7 +59,7 @@ for (unsigned i = 0; i < WebGamepads::itemsLengthCap; ++i) { WebGamepad& webGamepad = gamepads.items[i]; - if (i < gamepads.length && webGamepad.connected) { + if (webGamepad.connected) { GamepadType* gamepad = into->item(i); if (!gamepad) gamepad = GamepadType::create();
diff --git a/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.cpp b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.cpp index 969e1d2..96a32d1 100644 --- a/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.cpp +++ b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.cpp
@@ -173,7 +173,7 @@ } ImageData* OffscreenCanvasRenderingContext2D::toImageData( - SnapshotReason reason) const { + SnapshotReason reason) { if (!imageBuffer()) return nullptr; sk_sp<SkImage> snapshot =
diff --git a/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h index 3baaa55..16c3d09 100644 --- a/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h +++ b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h
@@ -51,7 +51,7 @@ BaseRenderingContext2D::clearRect(x, y, width, height); } PassRefPtr<Image> getImage(AccelerationHint, SnapshotReason) const final; - ImageData* toImageData(SnapshotReason) const override; + ImageData* toImageData(SnapshotReason) override; void reset() override; // BaseRenderingContext2D implementation
diff --git a/third_party/WebKit/Source/modules/permissions/DEPS b/third_party/WebKit/Source/modules/permissions/DEPS new file mode 100644 index 0000000..16764a92 --- /dev/null +++ b/third_party/WebKit/Source/modules/permissions/DEPS
@@ -0,0 +1,3 @@ +include_rules = [ + "+mojo/public/cpp/bindings", +]
diff --git a/third_party/WebKit/Source/modules/permissions/PermissionStatus.cpp b/third_party/WebKit/Source/modules/permissions/PermissionStatus.cpp index 41e71ae..a3b2b99 100644 --- a/third_party/WebKit/Source/modules/permissions/PermissionStatus.cpp +++ b/third_party/WebKit/Source/modules/permissions/PermissionStatus.cpp
@@ -38,9 +38,12 @@ MojoPermissionDescriptor descriptor) : SuspendableObject(executionContext), m_status(status), - m_descriptor(std::move(descriptor)) {} + m_descriptor(std::move(descriptor)), + m_binding(this) {} -PermissionStatus::~PermissionStatus() { +PermissionStatus::~PermissionStatus() = default; + +void PermissionStatus::dispose() { stopListening(); } @@ -52,22 +55,8 @@ return SuspendableObject::getExecutionContext(); } -void PermissionStatus::permissionChanged(MojoPermissionStatus status) { - if (m_status == status) - return; - - m_status = status; - dispatchEvent(Event::create(EventTypeNames::change)); - - m_service->GetNextPermissionChange( - m_descriptor->Clone(), getExecutionContext()->getSecurityOrigin(), - m_status, - convertToBaseCallback(WTF::bind(&PermissionStatus::permissionChanged, - wrapWeakPersistent(this)))); -} - bool PermissionStatus::hasPendingActivity() const { - return m_service; + return m_binding.is_bound(); } void PermissionStatus::resume() { @@ -82,21 +71,6 @@ stopListening(); } -void PermissionStatus::startListening() { - DCHECK(!m_service); - connectToPermissionService(getExecutionContext(), - mojo::MakeRequest(&m_service)); - m_service->GetNextPermissionChange( - m_descriptor->Clone(), getExecutionContext()->getSecurityOrigin(), - m_status, - convertToBaseCallback(WTF::bind(&PermissionStatus::permissionChanged, - wrapWeakPersistent(this)))); -} - -void PermissionStatus::stopListening() { - m_service.reset(); -} - String PermissionStatus::state() const { switch (m_status) { case MojoPermissionStatus::GRANTED: @@ -111,6 +85,31 @@ return "denied"; } +void PermissionStatus::startListening() { + DCHECK(!m_binding.is_bound()); + mojom::blink::PermissionObserverPtr observer; + m_binding.Bind(mojo::MakeRequest(&observer)); + + mojom::blink::PermissionServicePtr service; + connectToPermissionService(getExecutionContext(), + mojo::MakeRequest(&service)); + service->AddPermissionObserver(m_descriptor->Clone(), + getExecutionContext()->getSecurityOrigin(), + m_status, std::move(observer)); +} + +void PermissionStatus::stopListening() { + m_binding.Close(); +} + +void PermissionStatus::OnPermissionStatusChange(MojoPermissionStatus status) { + if (m_status == status) + return; + + m_status = status; + dispatchEvent(Event::create(EventTypeNames::change)); +} + DEFINE_TRACE(PermissionStatus) { EventTargetWithInlineData::trace(visitor); SuspendableObject::trace(visitor);
diff --git a/third_party/WebKit/Source/modules/permissions/PermissionStatus.h b/third_party/WebKit/Source/modules/permissions/PermissionStatus.h index f27c485..efdc4e8 100644 --- a/third_party/WebKit/Source/modules/permissions/PermissionStatus.h +++ b/third_party/WebKit/Source/modules/permissions/PermissionStatus.h
@@ -8,6 +8,7 @@ #include "bindings/core/v8/ActiveScriptWrappable.h" #include "core/dom/SuspendableObject.h" #include "core/events/EventTarget.h" +#include "mojo/public/cpp/bindings/binding.h" #include "platform/heap/Handle.h" #include "public/platform/modules/permissions/permission.mojom-blink.h" #include "wtf/text/AtomicString.h" @@ -22,9 +23,11 @@ // ExecutionContext. class PermissionStatus final : public EventTargetWithInlineData, public ActiveScriptWrappable<PermissionStatus>, - public SuspendableObject { + public SuspendableObject, + public mojom::blink::PermissionObserver { USING_GARBAGE_COLLECTED_MIXIN(PermissionStatus); DEFINE_WRAPPERTYPEINFO(); + USING_PRE_FINALIZER(PermissionStatus, dispose); using MojoPermissionDescriptor = mojom::blink::PermissionDescriptorPtr; using MojoPermissionStatus = mojom::blink::PermissionStatus; @@ -38,6 +41,7 @@ MojoPermissionStatus, MojoPermissionDescriptor); ~PermissionStatus() override; + void dispose(); // EventTarget implementation. const AtomicString& interfaceName() const override; @@ -52,7 +56,6 @@ void contextDestroyed() override; String state() const; - void permissionChanged(MojoPermissionStatus); DEFINE_ATTRIBUTE_EVENT_LISTENER(change); @@ -66,9 +69,11 @@ void startListening(); void stopListening(); + void OnPermissionStatusChange(MojoPermissionStatus); + MojoPermissionStatus m_status; MojoPermissionDescriptor m_descriptor; - mojom::blink::PermissionServicePtr m_service; + mojo::Binding<mojom::blink::PermissionObserver> m_binding; }; } // namespace blink
diff --git a/third_party/WebKit/Source/modules/webgl/DEPS b/third_party/WebKit/Source/modules/webgl/DEPS index 7e1735dc..3058c13 100644 --- a/third_party/WebKit/Source/modules/webgl/DEPS +++ b/third_party/WebKit/Source/modules/webgl/DEPS
@@ -1,4 +1,5 @@ include_rules = [ "+gpu/GLES2/gl2extchromium.h", "+gpu/command_buffer/client/gles2_interface.h", + "+skia/ext", ]
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp index e9d8b80c..b4a5099 100644 --- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp +++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
@@ -92,7 +92,9 @@ #include "platform/graphics/GraphicsContext.h" #include "platform/graphics/UnacceleratedImageBufferSurface.h" #include "platform/graphics/gpu/AcceleratedImageBufferSurface.h" +#include "platform/graphics/gpu/SharedGpuContext.h" #include "public/platform/Platform.h" +#include "skia/ext/texture_handle.h" #include "wtf/CheckedNumeric.h" #include "wtf/Functional.h" #include "wtf/PtrUtil.h" @@ -768,22 +770,42 @@ return buffer->newImageSnapshot(hint, reason); } -ImageData* WebGLRenderingContextBase::toImageData(SnapshotReason reason) const { - // TODO: Furnish toImageData in webgl renderingcontext for jpeg and webp - // images. See crbug.com/657531. +ImageData* WebGLRenderingContextBase::toImageData(SnapshotReason reason) { ImageData* imageData = nullptr; // TODO(ccameron): WebGL should produce sRGB images. // https://crbug.com/672299 - if (this->drawingBuffer()) { - sk_sp<SkImage> snapshot = - this->drawingBuffer() - ->transferToStaticBitmapImage() - ->imageForCurrentFrame(ColorBehavior::transformToGlobalTarget()); + if (drawingBuffer()) { + // For un-premultiplied data + imageData = paintRenderingResultsToImageData(BackBuffer); + if (imageData) { + return imageData; + } + + int width = drawingBuffer()->size().width(); + int height = drawingBuffer()->size().height(); + OpacityMode opacityMode = creationAttributes().alpha() ? NonOpaque : Opaque; + + drawingBuffer()->resolveAndBindForReadAndDraw(); + gpu::gles2::GLES2Interface* gl = SharedGpuContext::gl(); + SkImageInfo imageInfo = SkImageInfo::Make( + width, height, kRGBA_8888_SkColorType, + Opaque == opacityMode ? kOpaque_SkAlphaType : kPremul_SkAlphaType); + SkSurfaceProps disableLCDProps(0, kUnknown_SkPixelGeometry); + sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget( + SharedGpuContext::gr(), SkBudgeted::kYes, imageInfo, 0, + Opaque == opacityMode ? nullptr : &disableLCDProps); + GLuint textureId = skia::GrBackendObjectToGrGLTextureInfo( + surface->getTextureHandle( + SkSurface::kDiscardWrite_TextureHandleAccess)) + ->fID; + + drawingBuffer()->copyToPlatformTexture( + gl, textureId, GL_RGBA, GL_UNSIGNED_BYTE, 0, true, false, + IntPoint(0, 0), IntRect(IntPoint(0, 0), drawingBuffer()->size()), + BackBuffer); + sk_sp<SkImage> snapshot = surface->makeImageSnapshot(); if (snapshot) { - imageData = ImageData::create(this->getOffscreenCanvas()->size()); - SkImageInfo imageInfo = SkImageInfo::Make( - this->drawingBufferWidth(), this->drawingBufferHeight(), - kRGBA_8888_SkColorType, kUnpremul_SkAlphaType); + imageData = ImageData::create(drawingBuffer()->size()); snapshot->readPixels(imageInfo, imageData->data()->data(), imageInfo.minRowBytes(), 0, 0); }
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h index 18f00f5..88dce3d 100644 --- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h +++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h
@@ -574,7 +574,7 @@ }; PassRefPtr<Image> getImage(AccelerationHint, SnapshotReason) const override; - ImageData* toImageData(SnapshotReason) const override; + ImageData* toImageData(SnapshotReason) override; void setFilterQuality(SkFilterQuality) override; bool isWebGL2OrHigher() { return version() >= 2; }
diff --git a/third_party/WebKit/Source/modules/webmidi/BUILD.gn b/third_party/WebKit/Source/modules/webmidi/BUILD.gn index b762380..2774764d 100644 --- a/third_party/WebKit/Source/modules/webmidi/BUILD.gn +++ b/third_party/WebKit/Source/modules/webmidi/BUILD.gn
@@ -33,6 +33,6 @@ ] deps = [ - "//media/midi:mojo_blink_cpp_sources", + "//media/midi:mojo_blink", ] }
diff --git a/third_party/WebKit/Source/platform/BUILD.gn b/third_party/WebKit/Source/platform/BUILD.gn index 995b3f9..2e7efe7 100644 --- a/third_party/WebKit/Source/platform/BUILD.gn +++ b/third_party/WebKit/Source/platform/BUILD.gn
@@ -238,8 +238,8 @@ visibility = [] # Allow re-assignment of list. visibility = [ "//third_party/WebKit/*", - "//url/mojo:url_mojom_origin_blink_cpp_sources", - "//url/mojo:url_mojom_gurl_blink_cpp_sources", + "//url/mojo:url_mojom_origin_blink", + "//url/mojo:url_mojom_gurl_blink", ] output_name = "blink_platform"
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp index 0365863..2e230c6 100644 --- a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp +++ b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp
@@ -603,6 +603,38 @@ void setupRootEffectNode(); void setupRootScrollNode(); + // A brief discourse on cc property tree nodes, identifiers, and current and + // future design evolution envisioned: + // + // cc property trees identify nodes by their |id|, which implementation-wise + // is actually its index in the property tree's vector of its node type. More + // recent cc code now refers to these as 'node indices', or 'property tree + // indices'. |parent_id| is the same sort of 'node index' of that node's + // parent, whereas |owner_id| is the layer id of the layer owning that node. + // + // Note there are two other primary types of 'ids' referenced in cc property + // tree related logic: (1) ElementId, also known Blink-side as + // CompositorElementId, used by the animation system to allow tying an element + // to its respective layer, and (2) layer ids. There are other ancillary ids + // not relevant to any of the above, such as + // cc::TransformNode::sorting_context_id + // (a.k.a. blink::TransformPaintPropertyNode::renderingContextId()). + // + // There is a vision to move toward a world where cc property nodes have no + // association with layers and instead have a |stable_id|. The id could come + // from an ElementId in turn derived from the layout object responsible for + // creating the property node. + // + // We would also like to explore moving to use a single shared property tree + // representation across both cc and Blink. See + // platform/graphics/paint/README.md for more. + // + // With the above as background, we can now state more clearly a description + // of the below set of compositor id generation methods: they take Blink paint + // property tree nodes as input and produce a corresponding cc 'node id', + // a.k.a., 'node index', for use as we build out the corresponding cc property + // tree representation. + int compositorIdForTransformNode(const TransformPaintPropertyNode*); int compositorIdForClipNode(const ClipPaintPropertyNode*); int switchToEffectNode(const EffectPaintPropertyNode& nextEffect); @@ -640,6 +672,8 @@ struct BlinkEffectAndCcIdPair { const EffectPaintPropertyNode* effect; + // The cc property tree effect node id, or 'node index', for the cc effect + // node corresponding to the above Blink effect paint property node. int id; }; Vector<BlinkEffectAndCcIdPair> m_effectStack; @@ -661,7 +695,7 @@ transformTree.SetTargetId(transformNode.id, kRealRootNodeId); transformTree.SetContentTargetId(transformNode.id, kRealRootNodeId); - // TODO(jaydasika): We shouldn't set ToScreeen and FromScreen of root + // TODO(jaydasika): We shouldn't set ToScreen and FromScreen of root // transform node here. They should be set while updating transform tree in // cc. float deviceScaleFactor = m_rootLayer->GetLayerTree()->device_scale_factor();
diff --git a/third_party/WebKit/Source/platform/graphics/paint/README.md b/third_party/WebKit/Source/platform/graphics/paint/README.md index 1d60a22..8c10efa 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/README.md +++ b/third_party/WebKit/Source/platform/graphics/paint/README.md
@@ -259,6 +259,10 @@ The owner of the `PaintArtifactCompositor` (e.g. `WebView`) can then attach its root layer to the overall layer hierarchy to be displayed to the user. +In the future we would like to explore moving to a single shared property tree +representation across both cc and +Blink. See [Web Page Geometries](https://goo.gl/MwVIto) for more. + ## Geometry routines The [`GeometryMapper`](GeometryMapper.h) is responsible for efficiently computing
diff --git a/third_party/WebKit/Source/wtf/text/WTFString.cpp b/third_party/WebKit/Source/wtf/text/WTFString.cpp index 5e4f19c..6fdc7d8f 100644 --- a/third_party/WebKit/Source/wtf/text/WTFString.cpp +++ b/third_party/WebKit/Source/wtf/text/WTFString.cpp
@@ -496,7 +496,7 @@ return !m_impl || m_impl->isSafeToSendToAnotherThread(); } -void String::split(const String& separator, +void String::split(const StringView& separator, bool allowEmptyEntries, Vector<String>& result) const { result.clear();
diff --git a/third_party/WebKit/Source/wtf/text/WTFString.h b/third_party/WebKit/Source/wtf/text/WTFString.h index d0382a01..b04d49f4 100644 --- a/third_party/WebKit/Source/wtf/text/WTFString.h +++ b/third_party/WebKit/Source/wtf/text/WTFString.h
@@ -315,10 +315,10 @@ return StringImpl::createUninitialized(length, data); } - void split(const String& separator, + void split(const StringView& separator, bool allowEmptyEntries, Vector<String>& result) const; - void split(const String& separator, Vector<String>& result) const { + void split(const StringView& separator, Vector<String>& result) const { split(separator, false, result); } void split(UChar separator,
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/deps_updater.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/deps_updater.py index 5d0a82d..56ab91e 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/deps_updater.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/deps_updater.py
@@ -149,17 +149,21 @@ self.run(['git', 'add', destination]) def _generate_manifest(self, original_repo_path, dest_path): - """Generate MANIFEST.json for imported tests. + """Generates MANIFEST.json for imported tests. - Run 'manifest' command if it exists in original_repo_path, and - add generated MANIFEST.json to dest_path. + Args: + original_repo_path: Path to the temporary source WPT repo directory. + dest_path: Path to the destination WPT directory. + + Runs the (newly-updated) manifest command if it's found, and then + stages the generated MANIFEST.json in the git index, ready to commit. """ manifest_command = self.fs.join(original_repo_path, 'manifest') if not self.fs.exists(manifest_command): # Do nothing for csswg-test. return _log.info('Generating MANIFEST.json') - self.run([manifest_command, '--tests-root', dest_path]) + self.run([manifest_command, '--work', '--tests-root', dest_path]) self.run(['git', 'add', self.fs.join(dest_path, 'MANIFEST.json')]) def update(self, dest_dir_name, url, keep_w3c_repos_around, revision):
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/deps_updater_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/deps_updater_unittest.py index 806ca41..46427f5 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/deps_updater_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/deps_updater_unittest.py
@@ -89,3 +89,40 @@ 'TBR=qyearsley@chromium.org\n' 'NOEXPORT=true')) self.assertEqual(host.executive.calls, [['git', 'log', '-1', '--format=%B']]) + + def test_generate_manifest_command_not_found(self): + # If we're updating csswg-test, then the manifest file won't be found. + host = MockHost() + host.filesystem.files = {} + updater = DepsUpdater(host) + updater._generate_manifest( + '/mock-checkout/third_party/WebKit/css', + '/mock-checkout/third_party/WebKit/LayoutTests/imported/csswg-test') + self.assertEqual(host.executive.calls, []) + + def test_generate_manifest_successful_run(self): + # This test doesn't test any aspect of the real manifest script, it just + # asserts that DepsUpdater._generate_manifest would invoke the script. + host = MockHost() + host.filesystem.files = { + '/mock-checkout/third_party/WebKit/wpt/manifest': 'dummy content' + } + updater = DepsUpdater(host) + updater._generate_manifest( + '/mock-checkout/third_party/WebKit/wpt', + '/mock-checkout/third_party/WebKit/LayoutTests/imported/wpt') + self.assertEqual( + host.executive.calls, + [ + [ + '/mock-checkout/third_party/WebKit/wpt/manifest', + '--work', + '--tests-root', + '/mock-checkout/third_party/WebKit/LayoutTests/imported/wpt' + ], + [ + 'git', + 'add', + '/mock-checkout/third_party/WebKit/LayoutTests/imported/wpt/MANIFEST.json' + ] + ])
diff --git a/third_party/WebKit/public/platform/Platform.h b/third_party/WebKit/public/platform/Platform.h index fce5664..a4b58743 100644 --- a/third_party/WebKit/public/platform/Platform.h +++ b/third_party/WebKit/public/platform/Platform.h
@@ -272,7 +272,7 @@ // Gamepad ------------------------------------------------------------- - virtual void sampleGamepads(WebGamepads& into) { into.length = 0; } + virtual void sampleGamepads(WebGamepads& into) {} // History -------------------------------------------------------------
diff --git a/third_party/WebKit/public/platform/WebGamepad.h b/third_party/WebKit/public/platform/WebGamepad.h index 34ca828..0e14669 100644 --- a/third_party/WebKit/public/platform/WebGamepad.h +++ b/third_party/WebKit/public/platform/WebGamepad.h
@@ -90,7 +90,11 @@ static const size_t buttonsLengthCap = 32; WebGamepad() - : connected(false), timestamp(0), axesLength(0), buttonsLength(0) { + : connected(false), + timestamp(0), + axesLength(0), + buttonsLength(0), + displayId(0) { id[0] = 0; mapping[0] = 0; }
diff --git a/third_party/WebKit/public/platform/WebGamepads.h b/third_party/WebKit/public/platform/WebGamepads.h index 15ede96..4b76542 100644 --- a/third_party/WebKit/public/platform/WebGamepads.h +++ b/third_party/WebKit/public/platform/WebGamepads.h
@@ -35,13 +35,8 @@ // browser. class WebGamepads { public: - WebGamepads() : length(0) {} - static const size_t itemsLengthCap = 4; - // Number of valid entries in the items array. - unsigned length; - // Gamepad data for N separate gamepad devices. WebGamepad items[itemsLengthCap]; };
diff --git a/third_party/WebKit/public/platform/modules/permissions/permission.mojom b/third_party/WebKit/public/platform/modules/permissions/permission.mojom index ef42937..97387f98 100644 --- a/third_party/WebKit/public/platform/modules/permissions/permission.mojom +++ b/third_party/WebKit/public/platform/modules/permissions/permission.mojom
@@ -35,6 +35,11 @@ PermissionDescriptorExtension? extension; }; +// Interface a client can implement to observe permission changes. +interface PermissionObserver { + OnPermissionStatusChange(PermissionStatus status); +}; + // The Permission service provides permission handling capabilities by exposing // methods to check, request, and revoke permissions. It also allows a client to // start listening to permission changes. @@ -49,13 +54,10 @@ => (array<PermissionStatus> statuses); RevokePermission(PermissionDescriptor permission, url.mojom.Origin origin) => (PermissionStatus status); - - // Runs the callback next time there is a permission status change for the - // given { permission, origin }. Callers of this method will have to call it - // again if they want to keep listening to the changes. To prevent race - // conditions, the caller must pass the last known value. - GetNextPermissionChange(PermissionDescriptor permission, - url.mojom.Origin origin, - PermissionStatus last_known_status) - => (PermissionStatus status); + // Subscribes |observer| to updates about changes to |origin|'s access to + // |permission|. Closing the pipe will cancel the subscription. + AddPermissionObserver(PermissionDescriptor permission, + url.mojom.Origin origin, + PermissionStatus last_known_status, + PermissionObserver observer); };
diff --git a/tools/chrome_proxy/webdriver/incognito.py b/tools/chrome_proxy/webdriver/incognito.py new file mode 100644 index 0000000..1f36d3a --- /dev/null +++ b/tools/chrome_proxy/webdriver/incognito.py
@@ -0,0 +1,22 @@ +# Copyright 2017 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import common +from common import TestDriver +from common import IntegrationTest + + +class Incognito(IntegrationTest): + + # Ensure Chrome does not use DataSaver in Incognito mode. + def testCheckPageWithIncognito(self): + with TestDriver() as t: + t.AddChromeArg('--enable-spdy-proxy-auth') + t.AddChromeArg('--incognito') + t.LoadURL('http://check.googlezip.net/test.html') + for response in t.GetHTTPResponses(): + self.assertNotHasChromeProxyViaHeader(response) + +if __name__ == '__main__': + IntegrationTest.RunAllTests()
diff --git a/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp b/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp index e38c136a..c3d3356 100644 --- a/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp +++ b/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp
@@ -328,6 +328,11 @@ if (type.isVolatileQualified()) return false; + // Parameters should not be renamed to |kFooBar| style (even if they are + // const and have an initializer (aka default value)). + if (clang::isa<clang::ParmVarDecl>(&decl)) + return false; + // http://google.github.io/styleguide/cppguide.html#Constant_Names // Static variables that are const-qualified should use kConstantStyle naming. if (decl.getStorageDuration() == clang::SD_Static)
diff --git a/tools/clang/rewrite_to_chrome_style/tests/constants-expected.cc b/tools/clang/rewrite_to_chrome_style/tests/constants-expected.cc index e27982a..3f55421 100644 --- a/tools/clang/rewrite_to_chrome_style/tests/constants-expected.cc +++ b/tools/clang/rewrite_to_chrome_style/tests/constants-expected.cc
@@ -42,7 +42,8 @@ } }; -void F() { +// |constParam| should not be renamed to |kConstParam|. +void F(const bool const_param = true) { // Constant in function body. static const char kStaticString[] = "abc"; // Constant-style naming, since it's initialized with a literal.
diff --git a/tools/clang/rewrite_to_chrome_style/tests/constants-original.cc b/tools/clang/rewrite_to_chrome_style/tests/constants-original.cc index bc51bffa..51ce017 100644 --- a/tools/clang/rewrite_to_chrome_style/tests/constants-original.cc +++ b/tools/clang/rewrite_to_chrome_style/tests/constants-original.cc
@@ -42,7 +42,8 @@ } }; -void F() { +// |constParam| should not be renamed to |kConstParam|. +void F(const bool constParam = true) { // Constant in function body. static const char staticString[] = "abc"; // Constant-style naming, since it's initialized with a literal.
diff --git a/tools/gn/xcode_writer.cc b/tools/gn/xcode_writer.cc index b35cb44..5030b5ab 100644 --- a/tools/gn/xcode_writer.cc +++ b/tools/gn/xcode_writer.cc
@@ -31,6 +31,12 @@ namespace { +using TargetToFileList = std::unordered_map<const Target*, Target::FileList>; + +const char kEarlGreyFileNameIdentifier[] = "egtest.mm"; +const char kXCTestFileNameIdentifier[] = "xctest.mm"; +const char kXCTestModuleTargetNamePostfix[] = "_module"; + struct SafeEnvironmentVariableInfo { const char* name; bool capture_at_generation; @@ -86,6 +92,107 @@ return script.str(); } +bool IsApplicationTarget(const Target* target) { + return target->output_type() == Target::CREATE_BUNDLE && + target->bundle_data().product_type() == + "com.apple.product-type.application"; +} + +bool IsXCTestModuleTarget(const Target* target) { + return target->output_type() == Target::CREATE_BUNDLE && + target->bundle_data().product_type() == + "com.apple.product-type.bundle.unit-test" && + base::EndsWith(target->label().name(), kXCTestModuleTargetNamePostfix, + base::CompareCase::SENSITIVE); +} + +const Target* FindXCTestApplicationTarget( + const Target* xctest_module_target, + const std::vector<const Target*>& targets) { + DCHECK(IsXCTestModuleTarget(xctest_module_target)); + DCHECK(base::EndsWith(xctest_module_target->label().name(), + kXCTestModuleTargetNamePostfix, + base::CompareCase::SENSITIVE)); + std::string application_target_name = + xctest_module_target->label().name().substr( + 0, xctest_module_target->label().name().size() - + strlen(kXCTestModuleTargetNamePostfix)); + for (const Target* target : targets) { + if (target->label().name() == application_target_name) { + return target; + } + } + NOTREACHED(); + return nullptr; +} + +// Returns the corresponding application targets given XCTest module targets. +void FindXCTestApplicationTargets( + const std::vector<const Target*>& xctest_module_targets, + const std::vector<const Target*>& targets, + std::vector<const Target*>* xctest_application_targets) { + for (const Target* xctest_module_target : xctest_module_targets) { + xctest_application_targets->push_back( + FindXCTestApplicationTarget(xctest_module_target, targets)); + } +} + +// Searches the list of xctest files recursively under |target|. +void SearchXCTestFiles(const Target* target, + TargetToFileList* xctest_files_per_target) { + // Early return if already visited and processed. + if (xctest_files_per_target->find(target) != xctest_files_per_target->end()) + return; + + Target::FileList xctest_files; + for (const SourceFile& file : target->sources()) { + if (base::EndsWith(file.GetName(), kEarlGreyFileNameIdentifier, + base::CompareCase::SENSITIVE) || + base::EndsWith(file.GetName(), kXCTestFileNameIdentifier, + base::CompareCase::SENSITIVE)) { + xctest_files.push_back(file); + } + } + + // Call recursively on public and private deps. + for (const auto& target : target->public_deps()) { + SearchXCTestFiles(target.ptr, xctest_files_per_target); + const Target::FileList& deps_xctest_files = + (*xctest_files_per_target)[target.ptr]; + xctest_files.insert(xctest_files.end(), deps_xctest_files.begin(), + deps_xctest_files.end()); + } + + for (const auto& target : target->private_deps()) { + SearchXCTestFiles(target.ptr, xctest_files_per_target); + const Target::FileList& deps_xctest_files = + (*xctest_files_per_target)[target.ptr]; + xctest_files.insert(xctest_files.end(), deps_xctest_files.begin(), + deps_xctest_files.end()); + } + + // Sort xctest_files to remove duplicates. + std::sort(xctest_files.begin(), xctest_files.end()); + xctest_files.erase(std::unique(xctest_files.begin(), xctest_files.end()), + xctest_files.end()); + + xctest_files_per_target->insert(std::make_pair(target, xctest_files)); +} + +// Finds the list of xctest files recursively under each of the application +// targets. +void FindXCTestFilesForTargets( + const std::vector<const Target*>& application_targets, + std::vector<Target::FileList>* file_lists) { + TargetToFileList xctest_files_per_target; + + for (const Target* target : application_targets) { + DCHECK(IsApplicationTarget(target)); + SearchXCTestFiles(target, &xctest_files_per_target); + file_lists->push_back(xctest_files_per_target[target]); + } +} + class CollectPBXObjectsPerClassHelper : public PBXObjectVisitor { public: CollectPBXObjectsPerClassHelper() {} @@ -266,6 +373,18 @@ return true; } +// static +void XcodeWriter::FilterXCTestModuleTargets( + const std::vector<const Target*>& targets, + std::vector<const Target*>* xctest_module_targets) { + for (const Target* target : targets) { + if (!IsXCTestModuleTarget(target)) + continue; + + xctest_module_targets->push_back(target); + } +} + void XcodeWriter::CreateProductsProject( const std::vector<const Target*>& targets, const PBXAttributes& attributes, @@ -278,6 +397,20 @@ std::unique_ptr<PBXProject> main_project( new PBXProject("products", config_name, source_path, attributes)); + // Filter xctest module and application targets and find list of xctest files + // recursively under them. + std::vector<const Target*> xctest_module_targets; + FilterXCTestModuleTargets(targets, &xctest_module_targets); + + std::vector<const Target*> xctest_application_targets; + FindXCTestApplicationTargets(xctest_module_targets, targets, + &xctest_application_targets); + DCHECK_EQ(xctest_module_targets.size(), xctest_application_targets.size()); + + std::vector<Target::FileList> xctest_file_lists; + FindXCTestFilesForTargets(xctest_application_targets, &xctest_file_lists); + DCHECK_EQ(xctest_application_targets.size(), xctest_file_lists.size()); + std::string build_path; std::unique_ptr<base::Environment> env(base::Environment::Create()); @@ -299,10 +432,21 @@ env.get())); break; - case Target::CREATE_BUNDLE: + case Target::CREATE_BUNDLE: { if (target->bundle_data().product_type().empty()) continue; + // Test files need to be known to Xcode for proper indexing and for + // discovery of tests function for XCTest, but the compilation is done + // via ninja and thus must prevent Xcode from linking object files via + // this hack. + PBXAttributes extra_attributes; + if (IsXCTestModuleTarget(target)) { + extra_attributes["OTHER_LDFLAGS"] = "-help"; + extra_attributes["ONLY_ACTIVE_ARCH"] = "YES"; + extra_attributes["DEBUG_INFORMATION_FORMAT"] = "dwarf"; + } + main_project->AddNativeTarget( target->label().name(), std::string(), RebasePath(target->bundle_data() @@ -310,9 +454,10 @@ .value(), build_settings->build_dir()), target->bundle_data().product_type(), - GetBuildScript(target->label().name(), ninja_extra_args, - env.get())); + GetBuildScript(target->label().name(), ninja_extra_args, env.get()), + extra_attributes); break; + } default: break;
diff --git a/tools/gn/xcode_writer.h b/tools/gn/xcode_writer.h index 7373cff0..37f49d6 100644 --- a/tools/gn/xcode_writer.h +++ b/tools/gn/xcode_writer.h
@@ -60,6 +60,11 @@ std::vector<const Target*>* targets, Err* err); + // Filters list of targets to only return ones that are xctest module bundles. + static void FilterXCTestModuleTargets( + const std::vector<const Target*>& targets, + std::vector<const Target*>* xctest_module_targets); + // Generate the "products.xcodeproj" project that reference all products // (i.e. targets that have a build artefact usable from Xcode, mostly // application bundles).
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index 72d028f..43c254c 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -1147,6 +1147,132 @@ </description> </action> +<action name="Android.HistoryPage.ClearBrowsingData"> + <owner>twellington@chromium.org</owner> + <description> + User clicked the clear browsing data button on the native Android history + page. + </description> +</action> + +<action name="Android.HistoryPage.LoadMoreOnScroll"> + <owner>twellington@chromium.org</owner> + <description> + User scrolled to the bottom of the screen causing more items to load on the + native Android history page. + </description> +</action> + +<action name="Android.HistoryPage.OpenItem"> + <owner>twellington@chromium.org</owner> + <description> + User opened an item on the native Android history page. + </description> +</action> + +<action name="Android.HistoryPage.OpenSelected"> + <owner>twellington@chromium.org</owner> + <description> + User opened one or more selected items in new tabs on the native Android + history page. + </description> +</action> + +<action name="Android.HistoryPage.OpenSelectedIncognito"> + <owner>twellington@chromium.org</owner> + <description> + User opened one or more selected items in new incognito tabs on the native + Android history page. + </description> +</action> + +<action name="Android.HistoryPage.RemoveItem"> + <owner>twellington@chromium.org</owner> + <description> + User removed an item on the native Android history page. + </description> +</action> + +<action name="Android.HistoryPage.RemoveSelected"> + <owner>twellington@chromium.org</owner> + <description> + User removed one or more selected items on the native Android history page. + </description> +</action> + +<action name="Android.HistoryPage.Search"> + <owner>twellington@chromium.org</owner> + <description> + User tapped the search icon on the native Android history page. + </description> +</action> + +<action name="Android.HistoryPage.Search.LoadMoreOnScroll"> + <owner>twellington@chromium.org</owner> + <description> + User scrolled to the bottom of the screen causing more items to load while + searching on the native Android history page. + </description> +</action> + +<action name="Android.HistoryPage.Search.OpenItem"> + <owner>twellington@chromium.org</owner> + <description> + User opened an item while searching on the native Android history page. + </description> +</action> + +<action name="Android.HistoryPage.Search.OpenSelected"> + <owner>twellington@chromium.org</owner> + <description> + User opened one or more selected items in new tabs while searching on the + native Android history page. + </description> +</action> + +<action name="Android.HistoryPage.Search.OpenSelectedIncognito"> + <owner>twellington@chromium.org</owner> + <description> + User opened one or more selected items in new incognito tabs while searching + on the native Android history page. + </description> +</action> + +<action name="Android.HistoryPage.Search.RemoveItem"> + <owner>twellington@chromium.org</owner> + <description> + User removed an item while searching on the native Android history page. + </description> +</action> + +<action name="Android.HistoryPage.Search.RemoveSelected"> + <owner>twellington@chromium.org</owner> + <description> + User removed one or more selected items while searching on the native + Android history page. + </description> +</action> + +<action name="Android.HistoryPage.Search.SelectionEstablished"> + <owner>twellington@chromium.org</owner> + <description> + User established a selection while searching on the native Android history + page. + </description> +</action> + +<action name="Android.HistoryPage.SelectionEstablished"> + <owner>twellington@chromium.org</owner> + <description> + User established a selection on the native Android history page. + </description> +</action> + +<action name="Android.HistoryPage.Show"> + <owner>twellington@chromium.org</owner> + <description>User navigated to the native Android history page.</description> +</action> + <action name="Android.InstantApps.BannerDismissed"> <owner>mariakhomenko@chromium.org</owner> <description>Promo banner for an instant app has been dismissed.</description>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index d384a53..48eff29 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -547,6 +547,22 @@ <summary>The percentage of total storage downloads consume.</summary> </histogram> +<histogram name="Android.HistoryPage.OpenSelected"> + <owner>twellington@chromium.org</owner> + <summary> + The number of selected items the user opened in new tabs from the native + Android history page. + </summary> +</histogram> + +<histogram name="Android.HistoryPage.RemoveSelected"> + <owner>twellington@chromium.org</owner> + <summary> + The number of selected items the user removed from the native Android + history page. + </summary> +</histogram> + <histogram name="Android.InstantApps.ApiCallDuration2" units="ms"> <owner>mariakhomenko@chromium.org</owner> <summary>
diff --git a/ui/app_list/presenter/BUILD.gn b/ui/app_list/presenter/BUILD.gn index 2f7b0e7..50d0ea9 100644 --- a/ui/app_list/presenter/BUILD.gn +++ b/ui/app_list/presenter/BUILD.gn
@@ -25,7 +25,6 @@ sources = [ "app_list.cc", "app_list.h", - "app_list_presenter.h", "app_list_presenter_delegate.cc", "app_list_presenter_delegate.h", "app_list_presenter_delegate_factory.h", @@ -58,6 +57,10 @@ sources = [ "test/app_list_presenter_impl_test_api.cc", "test/app_list_presenter_impl_test_api.h", + "test/test_app_list_presenter.cc", + "test/test_app_list_presenter.h", + "test/test_app_list_view_delegate_factory.cc", + "test/test_app_list_view_delegate_factory.h", # Temporary dependency to fix compile flake in http://crbug.com/611898. # TODO(tapted): Remove once http://crbug.com/612382 is fixed. @@ -65,10 +68,13 @@ ] public_deps = [ + ":mojom", ":presenter", ] deps = [ "//base", + "//mojo/public/cpp/bindings", + "//ui/app_list:test_support", ] }
diff --git a/ui/app_list/presenter/app_list.cc b/ui/app_list/presenter/app_list.cc index 9dda27a8..76b36d8c 100644 --- a/ui/app_list/presenter/app_list.cc +++ b/ui/app_list/presenter/app_list.cc
@@ -18,8 +18,39 @@ return presenter_.get(); } +void AppList::Show(int64_t display_id) { + if (presenter_) + presenter_->Show(display_id); +} + +void AppList::Dismiss() { + if (presenter_) + presenter_->Dismiss(); +} + +void AppList::ToggleAppList(int64_t display_id) { + if (presenter_) + presenter_->ToggleAppList(display_id); +} + +bool AppList::IsVisible() const { + return visible_; +} + +bool AppList::GetTargetVisibility() const { + return target_visible_; +} + void AppList::SetAppListPresenter(mojom::AppListPresenterPtr presenter) { presenter_ = std::move(presenter); } +void AppList::OnTargetVisibilityChanged(bool visible) { + target_visible_ = visible; +} + +void AppList::OnVisibilityChanged(bool visible) { + visible_ = visible; +} + } // namespace app_list
diff --git a/ui/app_list/presenter/app_list.h b/ui/app_list/presenter/app_list.h index 2cf701d..fb4b8a2 100644 --- a/ui/app_list/presenter/app_list.h +++ b/ui/app_list/presenter/app_list.h
@@ -23,8 +23,19 @@ // Get a raw pointer to the mojom::AppListPresenter interface; may be null. mojom::AppListPresenter* GetAppListPresenter(); + // Helper functions to call the underlying functionality on the presenter. + void Show(int64_t display_id); + void Dismiss(); + void ToggleAppList(int64_t display_id); + + // Helper functions to get the cached state as reported by the presenter. + bool IsVisible() const; + bool GetTargetVisibility() const; + // mojom::AppList: void SetAppListPresenter(mojom::AppListPresenterPtr presenter) override; + void OnTargetVisibilityChanged(bool visible) override; + void OnVisibilityChanged(bool visible) override; private: // Bindings for the mojom::AppList interface. @@ -33,6 +44,10 @@ // App list presenter interface in chrome; used to show/hide the app list. mojom::AppListPresenterPtr presenter_; + // The cached [target] visibility, as reported by the presenter. + bool target_visible_ = false; + bool visible_ = false; + DISALLOW_COPY_AND_ASSIGN(AppList); };
diff --git a/ui/app_list/presenter/app_list_presenter.h b/ui/app_list/presenter/app_list_presenter.h deleted file mode 100644 index 320564b..0000000 --- a/ui/app_list/presenter/app_list_presenter.h +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_APP_LIST_PRESENTER_APP_LIST_PRESENTER_H_ -#define UI_APP_LIST_PRESENTER_APP_LIST_PRESENTER_H_ - -#include <stdint.h> - -#include "ui/app_list/presenter/app_list_presenter_export.h" - -namespace app_list { - -// Interface for showing and hiding the app list. -class APP_LIST_PRESENTER_EXPORT AppListPresenter { - public: - virtual ~AppListPresenter() {} - - // Show/hide app list window. The |window| is used to deterime in - // which display (in which the |window| exists) the app list should - // be shown. - virtual void Show(int64_t display_id) = 0; - - // Invoked to dismiss app list. This may leave the view open but hidden from - // the user. - virtual void Dismiss() = 0; - - // Show the app list if it is visible, hide it if it is hidden. - virtual void ToggleAppList(int64_t display_id) = 0; - - // Returns current visibility of the app list. - virtual bool IsVisible() const = 0; - - // Returns target visibility. This may differ from IsVisible() if a - // visibility transition is in progress. - virtual bool GetTargetVisibility() const = 0; -}; - -} // namespace app_list - -#endif // UI_APP_LIST_PRESENTER_APP_LIST_PRESENTER_H_
diff --git a/ui/app_list/presenter/app_list_presenter.mojom b/ui/app_list/presenter/app_list_presenter.mojom index 8522ca5..14d376c 100644 --- a/ui/app_list/presenter/app_list_presenter.mojom +++ b/ui/app_list/presenter/app_list_presenter.mojom
@@ -14,6 +14,10 @@ interface AppList { // Set the app list presenter interface, to let ash trigger Chrome's app list. SetAppListPresenter(AppListPresenter presenter); + + // Notify the app list that the presenter's [target] visibility changed. + OnTargetVisibilityChanged(bool visible); + OnVisibilityChanged(bool visible); }; // Implemented by chrome. Used by ash to actually show and dismiss the app list. @@ -23,7 +27,7 @@ // Dismiss the app list. Dismiss(); - + // Show the app list (on the specified display) if it is hidden; hide the // app list if it is shown. ToggleAppList(int64 display_id);
diff --git a/ui/app_list/presenter/app_list_presenter_delegate.h b/ui/app_list/presenter/app_list_presenter_delegate.h index d75b7567..5535921e 100644 --- a/ui/app_list/presenter/app_list_presenter_delegate.h +++ b/ui/app_list/presenter/app_list_presenter_delegate.h
@@ -22,8 +22,7 @@ class AppListView; class AppListViewDelegate; -// Delegate of AppListPresenter which allows to customize AppListPresenter's -// behavior. +// Delegate of the app list presenter which allows customizing its behavior. // The design of this interface was heavily influenced by the needs of Ash's // app list implementation (see ash::AppListPresenterDelegate). class APP_LIST_PRESENTER_EXPORT AppListPresenterDelegate {
diff --git a/ui/app_list/presenter/app_list_presenter_delegate_factory.h b/ui/app_list/presenter/app_list_presenter_delegate_factory.h index 6e2e8fc..1a7875e 100644 --- a/ui/app_list/presenter/app_list_presenter_delegate_factory.h +++ b/ui/app_list/presenter/app_list_presenter_delegate_factory.h
@@ -11,7 +11,7 @@ namespace app_list { -class AppListPresenter; +class AppListPresenterImpl; class AppListPresenterDelegate; class APP_LIST_PRESENTER_EXPORT AppListPresenterDelegateFactory { @@ -19,7 +19,7 @@ virtual ~AppListPresenterDelegateFactory() {} virtual std::unique_ptr<AppListPresenterDelegate> GetDelegate( - AppListPresenter* presenter) = 0; + AppListPresenterImpl* presenter) = 0; }; } // namespace app_list
diff --git a/ui/app_list/presenter/app_list_presenter_impl.cc b/ui/app_list/presenter/app_list_presenter_impl.cc index e6db16a..852a16b 100644 --- a/ui/app_list/presenter/app_list_presenter_impl.cc +++ b/ui/app_list/presenter/app_list_presenter_impl.cc
@@ -31,9 +31,9 @@ } // namespace AppListPresenterImpl::AppListPresenterImpl( - AppListPresenterDelegateFactory* factory) - : factory_(factory) { - DCHECK(factory); + std::unique_ptr<AppListPresenterDelegateFactory> factory) + : factory_(std::move(factory)) { + DCHECK(factory_); } AppListPresenterImpl::~AppListPresenterImpl() { @@ -57,6 +57,9 @@ return; is_visible_ = true; + if (app_list_) + app_list_->OnTargetVisibilityChanged(GetTargetVisibility()); + if (view_) { ScheduleAnimation(); } else { @@ -80,6 +83,8 @@ DCHECK(view_); is_visible_ = false; + if (app_list_) + app_list_->OnTargetVisibilityChanged(GetTargetVisibility()); // The dismissal may have occurred in response to the app list losing // activation. Otherwise, our widget is currently active. When the animation @@ -110,6 +115,14 @@ return is_visible_; } +void AppListPresenterImpl::SetAppList(mojom::AppListPtr app_list) { + DCHECK(app_list); + app_list_ = std::move(app_list); + // Notify the app list interface of the current [target] visibility. + app_list_->OnTargetVisibilityChanged(GetTargetVisibility()); + app_list_->OnVisibilityChanged(IsVisible()); +} + //////////////////////////////////////////////////////////////////////////////// // AppListPresenterImpl, private: @@ -211,12 +224,19 @@ // AppListPresenterImpl, views::WidgetObserver implementation: void AppListPresenterImpl::OnWidgetDestroying(views::Widget* widget) { - DCHECK(view_->GetWidget() == widget); + DCHECK_EQ(view_->GetWidget(), widget); if (is_visible_) Dismiss(); ResetView(); } +void AppListPresenterImpl::OnWidgetVisibilityChanged(views::Widget* widget, + bool visible) { + DCHECK_EQ(view_->GetWidget(), widget); + if (app_list_) + app_list_->OnVisibilityChanged(visible); +} + //////////////////////////////////////////////////////////////////////////////// // AppListPresenterImpl, PaginationModelObserver implementation:
diff --git a/ui/app_list/presenter/app_list_presenter_impl.h b/ui/app_list/presenter/app_list_presenter_impl.h index 537d1c0..616d647 100644 --- a/ui/app_list/presenter/app_list_presenter_impl.h +++ b/ui/app_list/presenter/app_list_presenter_impl.h
@@ -10,8 +10,9 @@ #include "base/compiler_specific.h" #include "base/macros.h" #include "ui/app_list/pagination_model_observer.h" -#include "ui/app_list/presenter/app_list_presenter.h" +#include "ui/app_list/presenter/app_list_presenter.mojom.h" #include "ui/app_list/presenter/app_list_presenter_delegate.h" +#include "ui/app_list/presenter/app_list_presenter_export.h" #include "ui/aura/client/focus_change_observer.h" #include "ui/aura/window_observer.h" #include "ui/compositor/layer_animation_observer.h" @@ -34,14 +35,14 @@ // activation state to auto dismiss the UI. Delegates the responsibility // for laying out the app list UI to ash::AppListLayoutDelegate. class APP_LIST_PRESENTER_EXPORT AppListPresenterImpl - : public AppListPresenter, - public aura::client::FocusChangeObserver, + : public aura::client::FocusChangeObserver, public aura::WindowObserver, public ui::ImplicitAnimationObserver, public views::WidgetObserver, public PaginationModelObserver { public: - explicit AppListPresenterImpl(AppListPresenterDelegateFactory* factory); + explicit AppListPresenterImpl( + std::unique_ptr<AppListPresenterDelegateFactory> factory); ~AppListPresenterImpl() override; // Returns app list window or NULL if it is not visible. @@ -50,12 +51,26 @@ // Returns app list view if one exists, or NULL otherwise. AppListView* GetView() { return view_; } - // AppListPresenter: - void Show(int64_t display_id) override; - void Dismiss() final; - void ToggleAppList(int64_t display_id) override; - bool IsVisible() const override; - bool GetTargetVisibility() const override; + // Show/hide app list window. The |window| is used to deterime in which + // display (in which the |window| exists) the app list should be shown. + void Show(int64_t display_id); + + // Invoked to dismiss app list. This may leave the view open but hidden from + // the user. + void Dismiss(); + + // Show the app list if it is visible, hide it if it is hidden. + void ToggleAppList(int64_t display_id); + + // Returns current visibility of the app list. + bool IsVisible() const; + + // Returns target visibility. This may differ from IsVisible() if a visibility + // transition is in progress. + bool GetTargetVisibility() const; + + // Sets the app list interface pointer; used to report visibility changes. + void SetAppList(mojom::AppListPtr app_list); private: friend class test::AppListPresenterImplTestApi; @@ -83,6 +98,7 @@ // views::WidgetObserver overrides: void OnWidgetDestroying(views::Widget* widget) override; + void OnWidgetVisibilityChanged(views::Widget* widget, bool visible) override; // PaginationModelObserver overrides: void TotalPagesChanged() override; @@ -90,8 +106,8 @@ void TransitionStarted() override; void TransitionChanged() override; - // Not owned - AppListPresenterDelegateFactory* const factory_; + // The factory for the presenter's delegate. + std::unique_ptr<AppListPresenterDelegateFactory> factory_; // Responsible for laying out the app list UI. std::unique_ptr<AppListPresenterDelegate> presenter_delegate_; @@ -112,6 +128,9 @@ // Whether should schedule snap back animation. bool should_snap_back_ = false; + // The app list interface pointer; used for reporting visibility changes. + mojom::AppListPtr app_list_; + DISALLOW_COPY_AND_ASSIGN(AppListPresenterImpl); };
diff --git a/ui/app_list/presenter/app_list_presenter_impl_unittest.cc b/ui/app_list/presenter/app_list_presenter_impl_unittest.cc index cd9941f..0fd6639 100644 --- a/ui/app_list/presenter/app_list_presenter_impl_unittest.cc +++ b/ui/app_list/presenter/app_list_presenter_impl_unittest.cc
@@ -74,19 +74,15 @@ : container_(container) {} ~AppListPresenterDelegateFactoryTest() override {} - AppListPresenterDelegateTest* current_delegate() { return current_delegate_; } - // AppListPresenterDelegateFactory: std::unique_ptr<AppListPresenterDelegate> GetDelegate( - AppListPresenter* presenter) override { - current_delegate_ = - new AppListPresenterDelegateTest(container_, &app_list_view_delegate_); - return base::WrapUnique(current_delegate_); + AppListPresenterImpl* presenter) override { + return base::MakeUnique<AppListPresenterDelegateTest>( + container_, &app_list_view_delegate_); } private: aura::Window* container_; - AppListPresenterDelegateTest* current_delegate_ = nullptr; test::AppListTestViewDelegate app_list_view_delegate_; DISALLOW_COPY_AND_ASSIGN(AppListPresenterDelegateFactoryTest); @@ -106,7 +102,8 @@ // Don't cache the return of this method - a new delegate is created every // time the app list is shown. AppListPresenterDelegateTest* delegate() { - return factory_->current_delegate(); + return static_cast<AppListPresenterDelegateTest*>( + presenter_test_api_->presenter_delegate()); } // aura::test::AuraTestBase: @@ -114,9 +111,9 @@ void TearDown() override; private: - std::unique_ptr<AppListPresenterDelegateFactoryTest> factory_; std::unique_ptr<AppListPresenterImpl> presenter_; std::unique_ptr<aura::Window> container_; + std::unique_ptr<test::AppListPresenterImplTestApi> presenter_test_api_; DISALLOW_COPY_AND_ASSIGN(AppListPresenterImplTest); }; @@ -129,8 +126,10 @@ AuraTestBase::SetUp(); new wm::DefaultActivationClient(root_window()); container_.reset(CreateNormalWindow(0, root_window(), nullptr)); - factory_.reset(new AppListPresenterDelegateFactoryTest(container_.get())); - presenter_.reset(new AppListPresenterImpl(factory_.get())); + presenter_ = base::MakeUnique<AppListPresenterImpl>( + base::MakeUnique<AppListPresenterDelegateFactoryTest>(container_.get())); + presenter_test_api_ = + base::MakeUnique<test::AppListPresenterImplTestApi>(presenter()); } void AppListPresenterImplTest::TearDown() { @@ -204,8 +203,7 @@ EXPECT_TRUE(presenter()->GetTargetVisibility()); presenter()->GetView()->GetWidget()->CloseNow(); EXPECT_FALSE(presenter()->GetTargetVisibility()); - test::AppListPresenterImplTestApi presenter_test_api(presenter()); - EXPECT_FALSE(presenter_test_api.presenter_delegate()); + EXPECT_FALSE(delegate()); } } // namespace app_list
diff --git a/ui/app_list/presenter/app_list_view_delegate_factory.h b/ui/app_list/presenter/app_list_view_delegate_factory.h index 612d6e3..2319692 100644 --- a/ui/app_list/presenter/app_list_view_delegate_factory.h +++ b/ui/app_list/presenter/app_list_view_delegate_factory.h
@@ -14,6 +14,7 @@ public: virtual ~AppListViewDelegateFactory(); + // This does not pass ownership of the delegate. virtual app_list::AppListViewDelegate* GetDelegate() = 0; };
diff --git a/ui/app_list/presenter/test/test_app_list_presenter.cc b/ui/app_list/presenter/test/test_app_list_presenter.cc new file mode 100644 index 0000000..f83b116 --- /dev/null +++ b/ui/app_list/presenter/test/test_app_list_presenter.cc
@@ -0,0 +1,32 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/app_list/presenter/test/test_app_list_presenter.h" + +namespace app_list { +namespace test { + +TestAppListPresenter::TestAppListPresenter() : binding_(this) {} + +TestAppListPresenter::~TestAppListPresenter() {} + +app_list::mojom::AppListPresenterPtr +TestAppListPresenter::CreateInterfacePtrAndBind() { + return binding_.CreateInterfacePtrAndBind(); +} + +void TestAppListPresenter::Show(int64_t display_id) { + show_count_++; +} + +void TestAppListPresenter::Dismiss() { + dismiss_count_++; +} + +void TestAppListPresenter::ToggleAppList(int64_t display_id) { + toggle_count_++; +} + +} // namespace test +} // namespace app_list
diff --git a/ui/app_list/presenter/test/test_app_list_presenter.h b/ui/app_list/presenter/test/test_app_list_presenter.h new file mode 100644 index 0000000..947e1965 --- /dev/null +++ b/ui/app_list/presenter/test/test_app_list_presenter.h
@@ -0,0 +1,46 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_APP_LIST_PRESENTER_TEST_TEST_APP_LIST_PRESENTER_H_ +#define UI_APP_LIST_PRESENTER_TEST_TEST_APP_LIST_PRESENTER_H_ + +#include "base/macros.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "ui/app_list/presenter/app_list_presenter.mojom.h" + +namespace app_list { +namespace test { + +// A test implementation of AppListPresenter that records function call counts. +// Registers itself as the presenter for the app list on construction. +class TestAppListPresenter : public app_list::mojom::AppListPresenter { + public: + TestAppListPresenter(); + ~TestAppListPresenter() override; + + app_list::mojom::AppListPresenterPtr CreateInterfacePtrAndBind(); + + // app_list::mojom::AppListPresenter: + void Show(int64_t display_id) override; + void Dismiss() override; + void ToggleAppList(int64_t display_id) override; + + size_t show_count() const { return show_count_; } + size_t dismiss_count() const { return dismiss_count_; } + size_t toggle_count() const { return toggle_count_; } + + private: + size_t show_count_ = 0u; + size_t dismiss_count_ = 0u; + size_t toggle_count_ = 0u; + + mojo::Binding<app_list::mojom::AppListPresenter> binding_; + + DISALLOW_COPY_AND_ASSIGN(TestAppListPresenter); +}; + +} // namespace test +} // namespace app_list + +#endif // UI_APP_LIST_PRESENTER_TEST_TEST_APP_LIST_PRESENTER_H_
diff --git a/ui/app_list/presenter/test/test_app_list_view_delegate_factory.cc b/ui/app_list/presenter/test/test_app_list_view_delegate_factory.cc new file mode 100644 index 0000000..b982518 --- /dev/null +++ b/ui/app_list/presenter/test/test_app_list_view_delegate_factory.cc
@@ -0,0 +1,19 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/app_list/presenter/test/test_app_list_view_delegate_factory.h" + +namespace app_list { +namespace test { + +TestAppListViewDelegateFactory::TestAppListViewDelegateFactory() {} + +TestAppListViewDelegateFactory::~TestAppListViewDelegateFactory() {} + +AppListViewDelegate* TestAppListViewDelegateFactory::GetDelegate() { + return &delegate_; +} + +} // namespace test +} // namespace app_list
diff --git a/ui/app_list/presenter/test/test_app_list_view_delegate_factory.h b/ui/app_list/presenter/test/test_app_list_view_delegate_factory.h new file mode 100644 index 0000000..6c1a069 --- /dev/null +++ b/ui/app_list/presenter/test/test_app_list_view_delegate_factory.h
@@ -0,0 +1,32 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_APP_LIST_PRESENTER_TEST_TEST_APP_LIST_VIEW_DELEGATE_FACTORY_H_ +#define UI_APP_LIST_PRESENTER_TEST_TEST_APP_LIST_VIEW_DELEGATE_FACTORY_H_ + +#include "base/macros.h" +#include "ui/app_list/presenter/app_list_view_delegate_factory.h" +#include "ui/app_list/test/app_list_test_view_delegate.h" + +namespace app_list { +namespace test { + +// A concrete AppListViewDelegateFactory for unit tests. +class TestAppListViewDelegateFactory : public AppListViewDelegateFactory { + public: + TestAppListViewDelegateFactory(); + ~TestAppListViewDelegateFactory() override; + + AppListViewDelegate* GetDelegate() override; + + private: + AppListTestViewDelegate delegate_; + + DISALLOW_COPY_AND_ASSIGN(TestAppListViewDelegateFactory); +}; + +} // namespace test +} // namespace app_list + +#endif // UI_APP_LIST_PRESENTER_TEST_TEST_APP_LIST_VIEW_DELEGATE_FACTORY_H_
diff --git a/ui/aura/mus/drag_drop_controller_mus.cc b/ui/aura/mus/drag_drop_controller_mus.cc index 972eea8..a82841c8 100644 --- a/ui/aura/mus/drag_drop_controller_mus.cc +++ b/ui/aura/mus/drag_drop_controller_mus.cc
@@ -12,6 +12,7 @@ #include "base/memory/ptr_util.h" #include "base/message_loop/message_loop.h" #include "base/run_loop.h" +#include "mojo/public/cpp/bindings/map.h" #include "services/ui/public/interfaces/window_tree.mojom.h" #include "services/ui/public/interfaces/window_tree_constants.mojom.h" #include "ui/aura/client/drag_drop_delegate.h"
diff --git a/ui/aura/mus/os_exchange_data_provider_mus.h b/ui/aura/mus/os_exchange_data_provider_mus.h index 4293faf9..e8037bf 100644 --- a/ui/aura/mus/os_exchange_data_provider_mus.h +++ b/ui/aura/mus/os_exchange_data_provider_mus.h
@@ -11,7 +11,6 @@ #include <utility> #include <vector> -#include "mojo/public/cpp/bindings/map.h" #include "ui/aura/aura_export.h" #include "ui/base/dragdrop/os_exchange_data.h" #include "ui/gfx/geometry/vector2d.h"
diff --git a/ui/aura/mus/window_tree_client.cc b/ui/aura/mus/window_tree_client.cc index e9d1c07..9f28713 100644 --- a/ui/aura/mus/window_tree_client.cc +++ b/ui/aura/mus/window_tree_client.cc
@@ -13,6 +13,7 @@ #include "base/auto_reset.h" #include "base/bind.h" #include "base/memory/ptr_util.h" +#include "mojo/public/cpp/bindings/map.h" #include "services/service_manager/public/cpp/connector.h" #include "services/ui/common/accelerator_util.h" #include "services/ui/public/cpp/property_type_converters.h"
diff --git a/ui/aura/mus/window_tree_client_unittest.cc b/ui/aura/mus/window_tree_client_unittest.cc index f3aeeed..8792478 100644 --- a/ui/aura/mus/window_tree_client_unittest.cc +++ b/ui/aura/mus/window_tree_client_unittest.cc
@@ -12,6 +12,7 @@ #include "base/memory/ptr_util.h" #include "base/strings/utf_string_conversions.h" #include "mojo/common/common_type_converters.h" +#include "mojo/public/cpp/bindings/map.h" #include "services/ui/public/cpp/property_type_converters.h" #include "services/ui/public/interfaces/window_manager.mojom.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/ui/gl/generate_bindings.py b/ui/gl/generate_bindings.py index 3640aac..d06481a 100755 --- a/ui/gl/generate_bindings.py +++ b/ui/gl/generate_bindings.py
@@ -2976,14 +2976,17 @@ # Write a function to lookup a mock GL function based on its name. file.write('\n') - file.write('void* GL_BINDING_CALL ' + + file.write('GLFunctionPointerType GL_BINDING_CALL ' + 'MockGLInterface::GetGLProcAddress(const char* name) {\n') for key in sorted_function_names: name = uniquely_named_functions[key]['name'] file.write(' if (strcmp(name, "%s") == 0)\n' % name) - file.write(' return reinterpret_cast<void*>(Mock_%s);\n' % name) + file.write( + ' return reinterpret_cast<GLFunctionPointerType>(Mock_%s);\n' % + name) # Always return a non-NULL pointer like some EGL implementations do. - file.write(' return reinterpret_cast<void*>(&MockInvalidFunction);\n') + file.write(' return reinterpret_cast<GLFunctionPointerType>(' + '&MockInvalidFunction);\n') file.write('}\n') file.write('\n')
diff --git a/ui/gl/gl_api_unittest.cc b/ui/gl/gl_api_unittest.cc index 23c3075..6f274b4 100644 --- a/ui/gl/gl_api_unittest.cc +++ b/ui/gl/gl_api_unittest.cc
@@ -51,8 +51,9 @@ static_cast<GLGetProcAddressProc>(&FakeGLGetProcAddress)); } - static void* GL_BINDING_CALL FakeGLGetProcAddress(const char *proc) { - return reinterpret_cast<void*>(0x1); + static GLFunctionPointerType GL_BINDING_CALL + FakeGLGetProcAddress(const char* proc) { + return reinterpret_cast<GLFunctionPointerType>(0x1); } void TearDown() override {
diff --git a/ui/gl/gl_bindings_autogen_mock.cc b/ui/gl/gl_bindings_autogen_mock.cc index 453b7a1..50c40dd2 100644 --- a/ui/gl/gl_bindings_autogen_mock.cc +++ b/ui/gl/gl_bindings_autogen_mock.cc
@@ -3865,958 +3865,1106 @@ NOTREACHED(); } -void* GL_BINDING_CALL MockGLInterface::GetGLProcAddress(const char* name) { +GLFunctionPointerType GL_BINDING_CALL +MockGLInterface::GetGLProcAddress(const char* name) { if (strcmp(name, "glActiveTexture") == 0) - return reinterpret_cast<void*>(Mock_glActiveTexture); + return reinterpret_cast<GLFunctionPointerType>(Mock_glActiveTexture); if (strcmp(name, "glApplyFramebufferAttachmentCMAAINTEL") == 0) - return reinterpret_cast<void*>(Mock_glApplyFramebufferAttachmentCMAAINTEL); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glApplyFramebufferAttachmentCMAAINTEL); if (strcmp(name, "glAttachShader") == 0) - return reinterpret_cast<void*>(Mock_glAttachShader); + return reinterpret_cast<GLFunctionPointerType>(Mock_glAttachShader); if (strcmp(name, "glBeginQuery") == 0) - return reinterpret_cast<void*>(Mock_glBeginQuery); + return reinterpret_cast<GLFunctionPointerType>(Mock_glBeginQuery); if (strcmp(name, "glBeginQueryARB") == 0) - return reinterpret_cast<void*>(Mock_glBeginQueryARB); + return reinterpret_cast<GLFunctionPointerType>(Mock_glBeginQueryARB); if (strcmp(name, "glBeginQueryEXT") == 0) - return reinterpret_cast<void*>(Mock_glBeginQueryEXT); + return reinterpret_cast<GLFunctionPointerType>(Mock_glBeginQueryEXT); if (strcmp(name, "glBeginTransformFeedback") == 0) - return reinterpret_cast<void*>(Mock_glBeginTransformFeedback); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glBeginTransformFeedback); if (strcmp(name, "glBeginTransformFeedbackEXT") == 0) - return reinterpret_cast<void*>(Mock_glBeginTransformFeedbackEXT); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glBeginTransformFeedbackEXT); if (strcmp(name, "glBindAttribLocation") == 0) - return reinterpret_cast<void*>(Mock_glBindAttribLocation); + return reinterpret_cast<GLFunctionPointerType>(Mock_glBindAttribLocation); if (strcmp(name, "glBindBuffer") == 0) - return reinterpret_cast<void*>(Mock_glBindBuffer); + return reinterpret_cast<GLFunctionPointerType>(Mock_glBindBuffer); if (strcmp(name, "glBindBufferBase") == 0) - return reinterpret_cast<void*>(Mock_glBindBufferBase); + return reinterpret_cast<GLFunctionPointerType>(Mock_glBindBufferBase); if (strcmp(name, "glBindBufferBaseEXT") == 0) - return reinterpret_cast<void*>(Mock_glBindBufferBaseEXT); + return reinterpret_cast<GLFunctionPointerType>(Mock_glBindBufferBaseEXT); if (strcmp(name, "glBindBufferRange") == 0) - return reinterpret_cast<void*>(Mock_glBindBufferRange); + return reinterpret_cast<GLFunctionPointerType>(Mock_glBindBufferRange); if (strcmp(name, "glBindBufferRangeEXT") == 0) - return reinterpret_cast<void*>(Mock_glBindBufferRangeEXT); + return reinterpret_cast<GLFunctionPointerType>(Mock_glBindBufferRangeEXT); if (strcmp(name, "glBindFragDataLocation") == 0) - return reinterpret_cast<void*>(Mock_glBindFragDataLocation); + return reinterpret_cast<GLFunctionPointerType>(Mock_glBindFragDataLocation); if (strcmp(name, "glBindFragDataLocationEXT") == 0) - return reinterpret_cast<void*>(Mock_glBindFragDataLocationEXT); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glBindFragDataLocationEXT); if (strcmp(name, "glBindFragDataLocationIndexed") == 0) - return reinterpret_cast<void*>(Mock_glBindFragDataLocationIndexed); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glBindFragDataLocationIndexed); if (strcmp(name, "glBindFragDataLocationIndexedEXT") == 0) - return reinterpret_cast<void*>(Mock_glBindFragDataLocationIndexedEXT); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glBindFragDataLocationIndexedEXT); if (strcmp(name, "glBindFramebuffer") == 0) - return reinterpret_cast<void*>(Mock_glBindFramebuffer); + return reinterpret_cast<GLFunctionPointerType>(Mock_glBindFramebuffer); if (strcmp(name, "glBindFramebufferEXT") == 0) - return reinterpret_cast<void*>(Mock_glBindFramebufferEXT); + return reinterpret_cast<GLFunctionPointerType>(Mock_glBindFramebufferEXT); if (strcmp(name, "glBindImageTexture") == 0) - return reinterpret_cast<void*>(Mock_glBindImageTexture); + return reinterpret_cast<GLFunctionPointerType>(Mock_glBindImageTexture); if (strcmp(name, "glBindImageTextureEXT") == 0) - return reinterpret_cast<void*>(Mock_glBindImageTextureEXT); + return reinterpret_cast<GLFunctionPointerType>(Mock_glBindImageTextureEXT); if (strcmp(name, "glBindRenderbuffer") == 0) - return reinterpret_cast<void*>(Mock_glBindRenderbuffer); + return reinterpret_cast<GLFunctionPointerType>(Mock_glBindRenderbuffer); if (strcmp(name, "glBindRenderbufferEXT") == 0) - return reinterpret_cast<void*>(Mock_glBindRenderbufferEXT); + return reinterpret_cast<GLFunctionPointerType>(Mock_glBindRenderbufferEXT); if (strcmp(name, "glBindSampler") == 0) - return reinterpret_cast<void*>(Mock_glBindSampler); + return reinterpret_cast<GLFunctionPointerType>(Mock_glBindSampler); if (strcmp(name, "glBindTexture") == 0) - return reinterpret_cast<void*>(Mock_glBindTexture); + return reinterpret_cast<GLFunctionPointerType>(Mock_glBindTexture); if (strcmp(name, "glBindTransformFeedback") == 0) - return reinterpret_cast<void*>(Mock_glBindTransformFeedback); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glBindTransformFeedback); if (strcmp(name, "glBindUniformLocationCHROMIUM") == 0) - return reinterpret_cast<void*>(Mock_glBindUniformLocationCHROMIUM); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glBindUniformLocationCHROMIUM); if (strcmp(name, "glBindVertexArray") == 0) - return reinterpret_cast<void*>(Mock_glBindVertexArray); + return reinterpret_cast<GLFunctionPointerType>(Mock_glBindVertexArray); if (strcmp(name, "glBindVertexArrayAPPLE") == 0) - return reinterpret_cast<void*>(Mock_glBindVertexArrayAPPLE); + return reinterpret_cast<GLFunctionPointerType>(Mock_glBindVertexArrayAPPLE); if (strcmp(name, "glBindVertexArrayOES") == 0) - return reinterpret_cast<void*>(Mock_glBindVertexArrayOES); + return reinterpret_cast<GLFunctionPointerType>(Mock_glBindVertexArrayOES); if (strcmp(name, "glBlendBarrierKHR") == 0) - return reinterpret_cast<void*>(Mock_glBlendBarrierKHR); + return reinterpret_cast<GLFunctionPointerType>(Mock_glBlendBarrierKHR); if (strcmp(name, "glBlendBarrierNV") == 0) - return reinterpret_cast<void*>(Mock_glBlendBarrierNV); + return reinterpret_cast<GLFunctionPointerType>(Mock_glBlendBarrierNV); if (strcmp(name, "glBlendColor") == 0) - return reinterpret_cast<void*>(Mock_glBlendColor); + return reinterpret_cast<GLFunctionPointerType>(Mock_glBlendColor); if (strcmp(name, "glBlendEquation") == 0) - return reinterpret_cast<void*>(Mock_glBlendEquation); + return reinterpret_cast<GLFunctionPointerType>(Mock_glBlendEquation); if (strcmp(name, "glBlendEquationSeparate") == 0) - return reinterpret_cast<void*>(Mock_glBlendEquationSeparate); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glBlendEquationSeparate); if (strcmp(name, "glBlendFunc") == 0) - return reinterpret_cast<void*>(Mock_glBlendFunc); + return reinterpret_cast<GLFunctionPointerType>(Mock_glBlendFunc); if (strcmp(name, "glBlendFuncSeparate") == 0) - return reinterpret_cast<void*>(Mock_glBlendFuncSeparate); + return reinterpret_cast<GLFunctionPointerType>(Mock_glBlendFuncSeparate); if (strcmp(name, "glBlitFramebuffer") == 0) - return reinterpret_cast<void*>(Mock_glBlitFramebuffer); + return reinterpret_cast<GLFunctionPointerType>(Mock_glBlitFramebuffer); if (strcmp(name, "glBlitFramebufferANGLE") == 0) - return reinterpret_cast<void*>(Mock_glBlitFramebufferANGLE); + return reinterpret_cast<GLFunctionPointerType>(Mock_glBlitFramebufferANGLE); if (strcmp(name, "glBlitFramebufferEXT") == 0) - return reinterpret_cast<void*>(Mock_glBlitFramebufferEXT); + return reinterpret_cast<GLFunctionPointerType>(Mock_glBlitFramebufferEXT); if (strcmp(name, "glBufferData") == 0) - return reinterpret_cast<void*>(Mock_glBufferData); + return reinterpret_cast<GLFunctionPointerType>(Mock_glBufferData); if (strcmp(name, "glBufferSubData") == 0) - return reinterpret_cast<void*>(Mock_glBufferSubData); + return reinterpret_cast<GLFunctionPointerType>(Mock_glBufferSubData); if (strcmp(name, "glCheckFramebufferStatus") == 0) - return reinterpret_cast<void*>(Mock_glCheckFramebufferStatus); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glCheckFramebufferStatus); if (strcmp(name, "glCheckFramebufferStatusEXT") == 0) - return reinterpret_cast<void*>(Mock_glCheckFramebufferStatusEXT); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glCheckFramebufferStatusEXT); if (strcmp(name, "glClear") == 0) - return reinterpret_cast<void*>(Mock_glClear); + return reinterpret_cast<GLFunctionPointerType>(Mock_glClear); if (strcmp(name, "glClearBufferfi") == 0) - return reinterpret_cast<void*>(Mock_glClearBufferfi); + return reinterpret_cast<GLFunctionPointerType>(Mock_glClearBufferfi); if (strcmp(name, "glClearBufferfv") == 0) - return reinterpret_cast<void*>(Mock_glClearBufferfv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glClearBufferfv); if (strcmp(name, "glClearBufferiv") == 0) - return reinterpret_cast<void*>(Mock_glClearBufferiv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glClearBufferiv); if (strcmp(name, "glClearBufferuiv") == 0) - return reinterpret_cast<void*>(Mock_glClearBufferuiv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glClearBufferuiv); if (strcmp(name, "glClearColor") == 0) - return reinterpret_cast<void*>(Mock_glClearColor); + return reinterpret_cast<GLFunctionPointerType>(Mock_glClearColor); if (strcmp(name, "glClearDepth") == 0) - return reinterpret_cast<void*>(Mock_glClearDepth); + return reinterpret_cast<GLFunctionPointerType>(Mock_glClearDepth); if (strcmp(name, "glClearDepthf") == 0) - return reinterpret_cast<void*>(Mock_glClearDepthf); + return reinterpret_cast<GLFunctionPointerType>(Mock_glClearDepthf); if (strcmp(name, "glClearStencil") == 0) - return reinterpret_cast<void*>(Mock_glClearStencil); + return reinterpret_cast<GLFunctionPointerType>(Mock_glClearStencil); if (strcmp(name, "glClientWaitSync") == 0) - return reinterpret_cast<void*>(Mock_glClientWaitSync); + return reinterpret_cast<GLFunctionPointerType>(Mock_glClientWaitSync); if (strcmp(name, "glColorMask") == 0) - return reinterpret_cast<void*>(Mock_glColorMask); + return reinterpret_cast<GLFunctionPointerType>(Mock_glColorMask); if (strcmp(name, "glCompileShader") == 0) - return reinterpret_cast<void*>(Mock_glCompileShader); + return reinterpret_cast<GLFunctionPointerType>(Mock_glCompileShader); if (strcmp(name, "glCompressedCopyTextureCHROMIUM") == 0) - return reinterpret_cast<void*>(Mock_glCompressedCopyTextureCHROMIUM); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glCompressedCopyTextureCHROMIUM); if (strcmp(name, "glCompressedTexImage2D") == 0) - return reinterpret_cast<void*>(Mock_glCompressedTexImage2D); + return reinterpret_cast<GLFunctionPointerType>(Mock_glCompressedTexImage2D); if (strcmp(name, "glCompressedTexImage3D") == 0) - return reinterpret_cast<void*>(Mock_glCompressedTexImage3D); + return reinterpret_cast<GLFunctionPointerType>(Mock_glCompressedTexImage3D); if (strcmp(name, "glCompressedTexSubImage2D") == 0) - return reinterpret_cast<void*>(Mock_glCompressedTexSubImage2D); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glCompressedTexSubImage2D); if (strcmp(name, "glCompressedTexSubImage3D") == 0) - return reinterpret_cast<void*>(Mock_glCompressedTexSubImage3D); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glCompressedTexSubImage3D); if (strcmp(name, "glCopyBufferSubData") == 0) - return reinterpret_cast<void*>(Mock_glCopyBufferSubData); + return reinterpret_cast<GLFunctionPointerType>(Mock_glCopyBufferSubData); if (strcmp(name, "glCopySubTextureCHROMIUM") == 0) - return reinterpret_cast<void*>(Mock_glCopySubTextureCHROMIUM); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glCopySubTextureCHROMIUM); if (strcmp(name, "glCopyTexImage2D") == 0) - return reinterpret_cast<void*>(Mock_glCopyTexImage2D); + return reinterpret_cast<GLFunctionPointerType>(Mock_glCopyTexImage2D); if (strcmp(name, "glCopyTexSubImage2D") == 0) - return reinterpret_cast<void*>(Mock_glCopyTexSubImage2D); + return reinterpret_cast<GLFunctionPointerType>(Mock_glCopyTexSubImage2D); if (strcmp(name, "glCopyTexSubImage3D") == 0) - return reinterpret_cast<void*>(Mock_glCopyTexSubImage3D); + return reinterpret_cast<GLFunctionPointerType>(Mock_glCopyTexSubImage3D); if (strcmp(name, "glCopyTextureCHROMIUM") == 0) - return reinterpret_cast<void*>(Mock_glCopyTextureCHROMIUM); + return reinterpret_cast<GLFunctionPointerType>(Mock_glCopyTextureCHROMIUM); if (strcmp(name, "glCoverFillPathInstancedNV") == 0) - return reinterpret_cast<void*>(Mock_glCoverFillPathInstancedNV); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glCoverFillPathInstancedNV); if (strcmp(name, "glCoverFillPathNV") == 0) - return reinterpret_cast<void*>(Mock_glCoverFillPathNV); + return reinterpret_cast<GLFunctionPointerType>(Mock_glCoverFillPathNV); if (strcmp(name, "glCoverStrokePathInstancedNV") == 0) - return reinterpret_cast<void*>(Mock_glCoverStrokePathInstancedNV); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glCoverStrokePathInstancedNV); if (strcmp(name, "glCoverStrokePathNV") == 0) - return reinterpret_cast<void*>(Mock_glCoverStrokePathNV); + return reinterpret_cast<GLFunctionPointerType>(Mock_glCoverStrokePathNV); if (strcmp(name, "glCoverageModulationNV") == 0) - return reinterpret_cast<void*>(Mock_glCoverageModulationNV); + return reinterpret_cast<GLFunctionPointerType>(Mock_glCoverageModulationNV); if (strcmp(name, "glCreateProgram") == 0) - return reinterpret_cast<void*>(Mock_glCreateProgram); + return reinterpret_cast<GLFunctionPointerType>(Mock_glCreateProgram); if (strcmp(name, "glCreateShader") == 0) - return reinterpret_cast<void*>(Mock_glCreateShader); + return reinterpret_cast<GLFunctionPointerType>(Mock_glCreateShader); if (strcmp(name, "glCullFace") == 0) - return reinterpret_cast<void*>(Mock_glCullFace); + return reinterpret_cast<GLFunctionPointerType>(Mock_glCullFace); if (strcmp(name, "glDebugMessageCallback") == 0) - return reinterpret_cast<void*>(Mock_glDebugMessageCallback); + return reinterpret_cast<GLFunctionPointerType>(Mock_glDebugMessageCallback); if (strcmp(name, "glDebugMessageCallbackKHR") == 0) - return reinterpret_cast<void*>(Mock_glDebugMessageCallbackKHR); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glDebugMessageCallbackKHR); if (strcmp(name, "glDebugMessageControl") == 0) - return reinterpret_cast<void*>(Mock_glDebugMessageControl); + return reinterpret_cast<GLFunctionPointerType>(Mock_glDebugMessageControl); if (strcmp(name, "glDebugMessageControlKHR") == 0) - return reinterpret_cast<void*>(Mock_glDebugMessageControlKHR); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glDebugMessageControlKHR); if (strcmp(name, "glDebugMessageInsert") == 0) - return reinterpret_cast<void*>(Mock_glDebugMessageInsert); + return reinterpret_cast<GLFunctionPointerType>(Mock_glDebugMessageInsert); if (strcmp(name, "glDebugMessageInsertKHR") == 0) - return reinterpret_cast<void*>(Mock_glDebugMessageInsertKHR); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glDebugMessageInsertKHR); if (strcmp(name, "glDeleteBuffers") == 0) - return reinterpret_cast<void*>(Mock_glDeleteBuffers); + return reinterpret_cast<GLFunctionPointerType>(Mock_glDeleteBuffers); if (strcmp(name, "glDeleteFencesAPPLE") == 0) - return reinterpret_cast<void*>(Mock_glDeleteFencesAPPLE); + return reinterpret_cast<GLFunctionPointerType>(Mock_glDeleteFencesAPPLE); if (strcmp(name, "glDeleteFencesNV") == 0) - return reinterpret_cast<void*>(Mock_glDeleteFencesNV); + return reinterpret_cast<GLFunctionPointerType>(Mock_glDeleteFencesNV); if (strcmp(name, "glDeleteFramebuffers") == 0) - return reinterpret_cast<void*>(Mock_glDeleteFramebuffers); + return reinterpret_cast<GLFunctionPointerType>(Mock_glDeleteFramebuffers); if (strcmp(name, "glDeleteFramebuffersEXT") == 0) - return reinterpret_cast<void*>(Mock_glDeleteFramebuffersEXT); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glDeleteFramebuffersEXT); if (strcmp(name, "glDeletePathsNV") == 0) - return reinterpret_cast<void*>(Mock_glDeletePathsNV); + return reinterpret_cast<GLFunctionPointerType>(Mock_glDeletePathsNV); if (strcmp(name, "glDeleteProgram") == 0) - return reinterpret_cast<void*>(Mock_glDeleteProgram); + return reinterpret_cast<GLFunctionPointerType>(Mock_glDeleteProgram); if (strcmp(name, "glDeleteQueries") == 0) - return reinterpret_cast<void*>(Mock_glDeleteQueries); + return reinterpret_cast<GLFunctionPointerType>(Mock_glDeleteQueries); if (strcmp(name, "glDeleteQueriesARB") == 0) - return reinterpret_cast<void*>(Mock_glDeleteQueriesARB); + return reinterpret_cast<GLFunctionPointerType>(Mock_glDeleteQueriesARB); if (strcmp(name, "glDeleteQueriesEXT") == 0) - return reinterpret_cast<void*>(Mock_glDeleteQueriesEXT); + return reinterpret_cast<GLFunctionPointerType>(Mock_glDeleteQueriesEXT); if (strcmp(name, "glDeleteRenderbuffers") == 0) - return reinterpret_cast<void*>(Mock_glDeleteRenderbuffers); + return reinterpret_cast<GLFunctionPointerType>(Mock_glDeleteRenderbuffers); if (strcmp(name, "glDeleteRenderbuffersEXT") == 0) - return reinterpret_cast<void*>(Mock_glDeleteRenderbuffersEXT); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glDeleteRenderbuffersEXT); if (strcmp(name, "glDeleteSamplers") == 0) - return reinterpret_cast<void*>(Mock_glDeleteSamplers); + return reinterpret_cast<GLFunctionPointerType>(Mock_glDeleteSamplers); if (strcmp(name, "glDeleteShader") == 0) - return reinterpret_cast<void*>(Mock_glDeleteShader); + return reinterpret_cast<GLFunctionPointerType>(Mock_glDeleteShader); if (strcmp(name, "glDeleteSync") == 0) - return reinterpret_cast<void*>(Mock_glDeleteSync); + return reinterpret_cast<GLFunctionPointerType>(Mock_glDeleteSync); if (strcmp(name, "glDeleteTextures") == 0) - return reinterpret_cast<void*>(Mock_glDeleteTextures); + return reinterpret_cast<GLFunctionPointerType>(Mock_glDeleteTextures); if (strcmp(name, "glDeleteTransformFeedbacks") == 0) - return reinterpret_cast<void*>(Mock_glDeleteTransformFeedbacks); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glDeleteTransformFeedbacks); if (strcmp(name, "glDeleteVertexArrays") == 0) - return reinterpret_cast<void*>(Mock_glDeleteVertexArrays); + return reinterpret_cast<GLFunctionPointerType>(Mock_glDeleteVertexArrays); if (strcmp(name, "glDeleteVertexArraysAPPLE") == 0) - return reinterpret_cast<void*>(Mock_glDeleteVertexArraysAPPLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glDeleteVertexArraysAPPLE); if (strcmp(name, "glDeleteVertexArraysOES") == 0) - return reinterpret_cast<void*>(Mock_glDeleteVertexArraysOES); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glDeleteVertexArraysOES); if (strcmp(name, "glDepthFunc") == 0) - return reinterpret_cast<void*>(Mock_glDepthFunc); + return reinterpret_cast<GLFunctionPointerType>(Mock_glDepthFunc); if (strcmp(name, "glDepthMask") == 0) - return reinterpret_cast<void*>(Mock_glDepthMask); + return reinterpret_cast<GLFunctionPointerType>(Mock_glDepthMask); if (strcmp(name, "glDepthRange") == 0) - return reinterpret_cast<void*>(Mock_glDepthRange); + return reinterpret_cast<GLFunctionPointerType>(Mock_glDepthRange); if (strcmp(name, "glDepthRangef") == 0) - return reinterpret_cast<void*>(Mock_glDepthRangef); + return reinterpret_cast<GLFunctionPointerType>(Mock_glDepthRangef); if (strcmp(name, "glDetachShader") == 0) - return reinterpret_cast<void*>(Mock_glDetachShader); + return reinterpret_cast<GLFunctionPointerType>(Mock_glDetachShader); if (strcmp(name, "glDisable") == 0) - return reinterpret_cast<void*>(Mock_glDisable); + return reinterpret_cast<GLFunctionPointerType>(Mock_glDisable); if (strcmp(name, "glDisableVertexAttribArray") == 0) - return reinterpret_cast<void*>(Mock_glDisableVertexAttribArray); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glDisableVertexAttribArray); if (strcmp(name, "glDiscardFramebufferEXT") == 0) - return reinterpret_cast<void*>(Mock_glDiscardFramebufferEXT); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glDiscardFramebufferEXT); if (strcmp(name, "glDrawArrays") == 0) - return reinterpret_cast<void*>(Mock_glDrawArrays); + return reinterpret_cast<GLFunctionPointerType>(Mock_glDrawArrays); if (strcmp(name, "glDrawArraysInstanced") == 0) - return reinterpret_cast<void*>(Mock_glDrawArraysInstanced); + return reinterpret_cast<GLFunctionPointerType>(Mock_glDrawArraysInstanced); if (strcmp(name, "glDrawArraysInstancedANGLE") == 0) - return reinterpret_cast<void*>(Mock_glDrawArraysInstancedANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glDrawArraysInstancedANGLE); if (strcmp(name, "glDrawArraysInstancedARB") == 0) - return reinterpret_cast<void*>(Mock_glDrawArraysInstancedARB); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glDrawArraysInstancedARB); if (strcmp(name, "glDrawBuffer") == 0) - return reinterpret_cast<void*>(Mock_glDrawBuffer); + return reinterpret_cast<GLFunctionPointerType>(Mock_glDrawBuffer); if (strcmp(name, "glDrawBuffers") == 0) - return reinterpret_cast<void*>(Mock_glDrawBuffers); + return reinterpret_cast<GLFunctionPointerType>(Mock_glDrawBuffers); if (strcmp(name, "glDrawBuffersARB") == 0) - return reinterpret_cast<void*>(Mock_glDrawBuffersARB); + return reinterpret_cast<GLFunctionPointerType>(Mock_glDrawBuffersARB); if (strcmp(name, "glDrawBuffersEXT") == 0) - return reinterpret_cast<void*>(Mock_glDrawBuffersEXT); + return reinterpret_cast<GLFunctionPointerType>(Mock_glDrawBuffersEXT); if (strcmp(name, "glDrawElements") == 0) - return reinterpret_cast<void*>(Mock_glDrawElements); + return reinterpret_cast<GLFunctionPointerType>(Mock_glDrawElements); if (strcmp(name, "glDrawElementsInstanced") == 0) - return reinterpret_cast<void*>(Mock_glDrawElementsInstanced); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glDrawElementsInstanced); if (strcmp(name, "glDrawElementsInstancedANGLE") == 0) - return reinterpret_cast<void*>(Mock_glDrawElementsInstancedANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glDrawElementsInstancedANGLE); if (strcmp(name, "glDrawElementsInstancedARB") == 0) - return reinterpret_cast<void*>(Mock_glDrawElementsInstancedARB); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glDrawElementsInstancedARB); if (strcmp(name, "glDrawRangeElements") == 0) - return reinterpret_cast<void*>(Mock_glDrawRangeElements); + return reinterpret_cast<GLFunctionPointerType>(Mock_glDrawRangeElements); if (strcmp(name, "glEGLImageTargetRenderbufferStorageOES") == 0) - return reinterpret_cast<void*>(Mock_glEGLImageTargetRenderbufferStorageOES); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glEGLImageTargetRenderbufferStorageOES); if (strcmp(name, "glEGLImageTargetTexture2DOES") == 0) - return reinterpret_cast<void*>(Mock_glEGLImageTargetTexture2DOES); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glEGLImageTargetTexture2DOES); if (strcmp(name, "glEnable") == 0) - return reinterpret_cast<void*>(Mock_glEnable); + return reinterpret_cast<GLFunctionPointerType>(Mock_glEnable); if (strcmp(name, "glEnableVertexAttribArray") == 0) - return reinterpret_cast<void*>(Mock_glEnableVertexAttribArray); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glEnableVertexAttribArray); if (strcmp(name, "glEndQuery") == 0) - return reinterpret_cast<void*>(Mock_glEndQuery); + return reinterpret_cast<GLFunctionPointerType>(Mock_glEndQuery); if (strcmp(name, "glEndQueryARB") == 0) - return reinterpret_cast<void*>(Mock_glEndQueryARB); + return reinterpret_cast<GLFunctionPointerType>(Mock_glEndQueryARB); if (strcmp(name, "glEndQueryEXT") == 0) - return reinterpret_cast<void*>(Mock_glEndQueryEXT); + return reinterpret_cast<GLFunctionPointerType>(Mock_glEndQueryEXT); if (strcmp(name, "glEndTransformFeedback") == 0) - return reinterpret_cast<void*>(Mock_glEndTransformFeedback); + return reinterpret_cast<GLFunctionPointerType>(Mock_glEndTransformFeedback); if (strcmp(name, "glEndTransformFeedbackEXT") == 0) - return reinterpret_cast<void*>(Mock_glEndTransformFeedbackEXT); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glEndTransformFeedbackEXT); if (strcmp(name, "glFenceSync") == 0) - return reinterpret_cast<void*>(Mock_glFenceSync); + return reinterpret_cast<GLFunctionPointerType>(Mock_glFenceSync); if (strcmp(name, "glFinish") == 0) - return reinterpret_cast<void*>(Mock_glFinish); + return reinterpret_cast<GLFunctionPointerType>(Mock_glFinish); if (strcmp(name, "glFinishFenceAPPLE") == 0) - return reinterpret_cast<void*>(Mock_glFinishFenceAPPLE); + return reinterpret_cast<GLFunctionPointerType>(Mock_glFinishFenceAPPLE); if (strcmp(name, "glFinishFenceNV") == 0) - return reinterpret_cast<void*>(Mock_glFinishFenceNV); + return reinterpret_cast<GLFunctionPointerType>(Mock_glFinishFenceNV); if (strcmp(name, "glFlush") == 0) - return reinterpret_cast<void*>(Mock_glFlush); + return reinterpret_cast<GLFunctionPointerType>(Mock_glFlush); if (strcmp(name, "glFlushMappedBufferRange") == 0) - return reinterpret_cast<void*>(Mock_glFlushMappedBufferRange); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glFlushMappedBufferRange); if (strcmp(name, "glFramebufferRenderbuffer") == 0) - return reinterpret_cast<void*>(Mock_glFramebufferRenderbuffer); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glFramebufferRenderbuffer); if (strcmp(name, "glFramebufferRenderbufferEXT") == 0) - return reinterpret_cast<void*>(Mock_glFramebufferRenderbufferEXT); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glFramebufferRenderbufferEXT); if (strcmp(name, "glFramebufferTexture2D") == 0) - return reinterpret_cast<void*>(Mock_glFramebufferTexture2D); + return reinterpret_cast<GLFunctionPointerType>(Mock_glFramebufferTexture2D); if (strcmp(name, "glFramebufferTexture2DEXT") == 0) - return reinterpret_cast<void*>(Mock_glFramebufferTexture2DEXT); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glFramebufferTexture2DEXT); if (strcmp(name, "glFramebufferTexture2DMultisampleEXT") == 0) - return reinterpret_cast<void*>(Mock_glFramebufferTexture2DMultisampleEXT); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glFramebufferTexture2DMultisampleEXT); if (strcmp(name, "glFramebufferTexture2DMultisampleIMG") == 0) - return reinterpret_cast<void*>(Mock_glFramebufferTexture2DMultisampleIMG); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glFramebufferTexture2DMultisampleIMG); if (strcmp(name, "glFramebufferTextureLayer") == 0) - return reinterpret_cast<void*>(Mock_glFramebufferTextureLayer); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glFramebufferTextureLayer); if (strcmp(name, "glFrontFace") == 0) - return reinterpret_cast<void*>(Mock_glFrontFace); + return reinterpret_cast<GLFunctionPointerType>(Mock_glFrontFace); if (strcmp(name, "glGenBuffers") == 0) - return reinterpret_cast<void*>(Mock_glGenBuffers); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGenBuffers); if (strcmp(name, "glGenFencesAPPLE") == 0) - return reinterpret_cast<void*>(Mock_glGenFencesAPPLE); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGenFencesAPPLE); if (strcmp(name, "glGenFencesNV") == 0) - return reinterpret_cast<void*>(Mock_glGenFencesNV); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGenFencesNV); if (strcmp(name, "glGenFramebuffers") == 0) - return reinterpret_cast<void*>(Mock_glGenFramebuffers); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGenFramebuffers); if (strcmp(name, "glGenFramebuffersEXT") == 0) - return reinterpret_cast<void*>(Mock_glGenFramebuffersEXT); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGenFramebuffersEXT); if (strcmp(name, "glGenPathsNV") == 0) - return reinterpret_cast<void*>(Mock_glGenPathsNV); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGenPathsNV); if (strcmp(name, "glGenQueries") == 0) - return reinterpret_cast<void*>(Mock_glGenQueries); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGenQueries); if (strcmp(name, "glGenQueriesARB") == 0) - return reinterpret_cast<void*>(Mock_glGenQueriesARB); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGenQueriesARB); if (strcmp(name, "glGenQueriesEXT") == 0) - return reinterpret_cast<void*>(Mock_glGenQueriesEXT); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGenQueriesEXT); if (strcmp(name, "glGenRenderbuffers") == 0) - return reinterpret_cast<void*>(Mock_glGenRenderbuffers); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGenRenderbuffers); if (strcmp(name, "glGenRenderbuffersEXT") == 0) - return reinterpret_cast<void*>(Mock_glGenRenderbuffersEXT); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGenRenderbuffersEXT); if (strcmp(name, "glGenSamplers") == 0) - return reinterpret_cast<void*>(Mock_glGenSamplers); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGenSamplers); if (strcmp(name, "glGenTextures") == 0) - return reinterpret_cast<void*>(Mock_glGenTextures); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGenTextures); if (strcmp(name, "glGenTransformFeedbacks") == 0) - return reinterpret_cast<void*>(Mock_glGenTransformFeedbacks); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGenTransformFeedbacks); if (strcmp(name, "glGenVertexArrays") == 0) - return reinterpret_cast<void*>(Mock_glGenVertexArrays); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGenVertexArrays); if (strcmp(name, "glGenVertexArraysAPPLE") == 0) - return reinterpret_cast<void*>(Mock_glGenVertexArraysAPPLE); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGenVertexArraysAPPLE); if (strcmp(name, "glGenVertexArraysOES") == 0) - return reinterpret_cast<void*>(Mock_glGenVertexArraysOES); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGenVertexArraysOES); if (strcmp(name, "glGenerateMipmap") == 0) - return reinterpret_cast<void*>(Mock_glGenerateMipmap); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGenerateMipmap); if (strcmp(name, "glGenerateMipmapEXT") == 0) - return reinterpret_cast<void*>(Mock_glGenerateMipmapEXT); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGenerateMipmapEXT); if (strcmp(name, "glGetActiveAttrib") == 0) - return reinterpret_cast<void*>(Mock_glGetActiveAttrib); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetActiveAttrib); if (strcmp(name, "glGetActiveUniform") == 0) - return reinterpret_cast<void*>(Mock_glGetActiveUniform); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetActiveUniform); if (strcmp(name, "glGetActiveUniformBlockName") == 0) - return reinterpret_cast<void*>(Mock_glGetActiveUniformBlockName); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetActiveUniformBlockName); if (strcmp(name, "glGetActiveUniformBlockiv") == 0) - return reinterpret_cast<void*>(Mock_glGetActiveUniformBlockiv); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetActiveUniformBlockiv); if (strcmp(name, "glGetActiveUniformBlockivRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetActiveUniformBlockivRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetActiveUniformBlockivRobustANGLE); if (strcmp(name, "glGetActiveUniformsiv") == 0) - return reinterpret_cast<void*>(Mock_glGetActiveUniformsiv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetActiveUniformsiv); if (strcmp(name, "glGetAttachedShaders") == 0) - return reinterpret_cast<void*>(Mock_glGetAttachedShaders); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetAttachedShaders); if (strcmp(name, "glGetAttribLocation") == 0) - return reinterpret_cast<void*>(Mock_glGetAttribLocation); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetAttribLocation); if (strcmp(name, "glGetBooleani_vRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetBooleani_vRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetBooleani_vRobustANGLE); if (strcmp(name, "glGetBooleanv") == 0) - return reinterpret_cast<void*>(Mock_glGetBooleanv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetBooleanv); if (strcmp(name, "glGetBooleanvRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetBooleanvRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetBooleanvRobustANGLE); if (strcmp(name, "glGetBufferParameteri64vRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetBufferParameteri64vRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetBufferParameteri64vRobustANGLE); if (strcmp(name, "glGetBufferParameteriv") == 0) - return reinterpret_cast<void*>(Mock_glGetBufferParameteriv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetBufferParameteriv); if (strcmp(name, "glGetBufferParameterivRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetBufferParameterivRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetBufferParameterivRobustANGLE); if (strcmp(name, "glGetBufferPointervRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetBufferPointervRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetBufferPointervRobustANGLE); if (strcmp(name, "glGetDebugMessageLog") == 0) - return reinterpret_cast<void*>(Mock_glGetDebugMessageLog); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetDebugMessageLog); if (strcmp(name, "glGetDebugMessageLogKHR") == 0) - return reinterpret_cast<void*>(Mock_glGetDebugMessageLogKHR); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetDebugMessageLogKHR); if (strcmp(name, "glGetError") == 0) - return reinterpret_cast<void*>(Mock_glGetError); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetError); if (strcmp(name, "glGetFenceivNV") == 0) - return reinterpret_cast<void*>(Mock_glGetFenceivNV); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetFenceivNV); if (strcmp(name, "glGetFloatv") == 0) - return reinterpret_cast<void*>(Mock_glGetFloatv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetFloatv); if (strcmp(name, "glGetFloatvRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetFloatvRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetFloatvRobustANGLE); if (strcmp(name, "glGetFragDataIndex") == 0) - return reinterpret_cast<void*>(Mock_glGetFragDataIndex); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetFragDataIndex); if (strcmp(name, "glGetFragDataIndexEXT") == 0) - return reinterpret_cast<void*>(Mock_glGetFragDataIndexEXT); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetFragDataIndexEXT); if (strcmp(name, "glGetFragDataLocation") == 0) - return reinterpret_cast<void*>(Mock_glGetFragDataLocation); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetFragDataLocation); if (strcmp(name, "glGetFramebufferAttachmentParameteriv") == 0) - return reinterpret_cast<void*>(Mock_glGetFramebufferAttachmentParameteriv); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetFramebufferAttachmentParameteriv); if (strcmp(name, "glGetFramebufferAttachmentParameterivEXT") == 0) - return reinterpret_cast<void*>( + return reinterpret_cast<GLFunctionPointerType>( Mock_glGetFramebufferAttachmentParameterivEXT); if (strcmp(name, "glGetFramebufferAttachmentParameterivRobustANGLE") == 0) - return reinterpret_cast<void*>( + return reinterpret_cast<GLFunctionPointerType>( Mock_glGetFramebufferAttachmentParameterivRobustANGLE); if (strcmp(name, "glGetFramebufferParameterivRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetFramebufferParameterivRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetFramebufferParameterivRobustANGLE); if (strcmp(name, "glGetGraphicsResetStatus") == 0) - return reinterpret_cast<void*>(Mock_glGetGraphicsResetStatus); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetGraphicsResetStatus); if (strcmp(name, "glGetGraphicsResetStatusARB") == 0) - return reinterpret_cast<void*>(Mock_glGetGraphicsResetStatusARB); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetGraphicsResetStatusARB); if (strcmp(name, "glGetGraphicsResetStatusEXT") == 0) - return reinterpret_cast<void*>(Mock_glGetGraphicsResetStatusEXT); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetGraphicsResetStatusEXT); if (strcmp(name, "glGetGraphicsResetStatusKHR") == 0) - return reinterpret_cast<void*>(Mock_glGetGraphicsResetStatusKHR); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetGraphicsResetStatusKHR); if (strcmp(name, "glGetInteger64i_v") == 0) - return reinterpret_cast<void*>(Mock_glGetInteger64i_v); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetInteger64i_v); if (strcmp(name, "glGetInteger64i_vRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetInteger64i_vRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetInteger64i_vRobustANGLE); if (strcmp(name, "glGetInteger64v") == 0) - return reinterpret_cast<void*>(Mock_glGetInteger64v); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetInteger64v); if (strcmp(name, "glGetInteger64vRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetInteger64vRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetInteger64vRobustANGLE); if (strcmp(name, "glGetIntegeri_v") == 0) - return reinterpret_cast<void*>(Mock_glGetIntegeri_v); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetIntegeri_v); if (strcmp(name, "glGetIntegeri_vRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetIntegeri_vRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetIntegeri_vRobustANGLE); if (strcmp(name, "glGetIntegerv") == 0) - return reinterpret_cast<void*>(Mock_glGetIntegerv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetIntegerv); if (strcmp(name, "glGetIntegervRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetIntegervRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetIntegervRobustANGLE); if (strcmp(name, "glGetInternalformativ") == 0) - return reinterpret_cast<void*>(Mock_glGetInternalformativ); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetInternalformativ); if (strcmp(name, "glGetInternalformativRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetInternalformativRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetInternalformativRobustANGLE); if (strcmp(name, "glGetMultisamplefvRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetMultisamplefvRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetMultisamplefvRobustANGLE); if (strcmp(name, "glGetObjectLabel") == 0) - return reinterpret_cast<void*>(Mock_glGetObjectLabel); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetObjectLabel); if (strcmp(name, "glGetObjectLabelKHR") == 0) - return reinterpret_cast<void*>(Mock_glGetObjectLabelKHR); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetObjectLabelKHR); if (strcmp(name, "glGetObjectPtrLabel") == 0) - return reinterpret_cast<void*>(Mock_glGetObjectPtrLabel); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetObjectPtrLabel); if (strcmp(name, "glGetObjectPtrLabelKHR") == 0) - return reinterpret_cast<void*>(Mock_glGetObjectPtrLabelKHR); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetObjectPtrLabelKHR); if (strcmp(name, "glGetPointerv") == 0) - return reinterpret_cast<void*>(Mock_glGetPointerv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetPointerv); if (strcmp(name, "glGetPointervKHR") == 0) - return reinterpret_cast<void*>(Mock_glGetPointervKHR); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetPointervKHR); if (strcmp(name, "glGetPointervRobustANGLERobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetPointervRobustANGLERobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetPointervRobustANGLERobustANGLE); if (strcmp(name, "glGetProgramBinary") == 0) - return reinterpret_cast<void*>(Mock_glGetProgramBinary); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetProgramBinary); if (strcmp(name, "glGetProgramBinaryOES") == 0) - return reinterpret_cast<void*>(Mock_glGetProgramBinaryOES); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetProgramBinaryOES); if (strcmp(name, "glGetProgramInfoLog") == 0) - return reinterpret_cast<void*>(Mock_glGetProgramInfoLog); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetProgramInfoLog); if (strcmp(name, "glGetProgramInterfaceiv") == 0) - return reinterpret_cast<void*>(Mock_glGetProgramInterfaceiv); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetProgramInterfaceiv); if (strcmp(name, "glGetProgramInterfaceivRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetProgramInterfaceivRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetProgramInterfaceivRobustANGLE); if (strcmp(name, "glGetProgramResourceLocation") == 0) - return reinterpret_cast<void*>(Mock_glGetProgramResourceLocation); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetProgramResourceLocation); if (strcmp(name, "glGetProgramResourceName") == 0) - return reinterpret_cast<void*>(Mock_glGetProgramResourceName); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetProgramResourceName); if (strcmp(name, "glGetProgramResourceiv") == 0) - return reinterpret_cast<void*>(Mock_glGetProgramResourceiv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetProgramResourceiv); if (strcmp(name, "glGetProgramiv") == 0) - return reinterpret_cast<void*>(Mock_glGetProgramiv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetProgramiv); if (strcmp(name, "glGetProgramivRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetProgramivRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetProgramivRobustANGLE); if (strcmp(name, "glGetQueryObjecti64v") == 0) - return reinterpret_cast<void*>(Mock_glGetQueryObjecti64v); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetQueryObjecti64v); if (strcmp(name, "glGetQueryObjecti64vEXT") == 0) - return reinterpret_cast<void*>(Mock_glGetQueryObjecti64vEXT); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetQueryObjecti64vEXT); if (strcmp(name, "glGetQueryObjecti64vRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetQueryObjecti64vRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetQueryObjecti64vRobustANGLE); if (strcmp(name, "glGetQueryObjectiv") == 0) - return reinterpret_cast<void*>(Mock_glGetQueryObjectiv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetQueryObjectiv); if (strcmp(name, "glGetQueryObjectivARB") == 0) - return reinterpret_cast<void*>(Mock_glGetQueryObjectivARB); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetQueryObjectivARB); if (strcmp(name, "glGetQueryObjectivEXT") == 0) - return reinterpret_cast<void*>(Mock_glGetQueryObjectivEXT); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetQueryObjectivEXT); if (strcmp(name, "glGetQueryObjectivRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetQueryObjectivRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetQueryObjectivRobustANGLE); if (strcmp(name, "glGetQueryObjectui64v") == 0) - return reinterpret_cast<void*>(Mock_glGetQueryObjectui64v); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetQueryObjectui64v); if (strcmp(name, "glGetQueryObjectui64vEXT") == 0) - return reinterpret_cast<void*>(Mock_glGetQueryObjectui64vEXT); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetQueryObjectui64vEXT); if (strcmp(name, "glGetQueryObjectui64vRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetQueryObjectui64vRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetQueryObjectui64vRobustANGLE); if (strcmp(name, "glGetQueryObjectuiv") == 0) - return reinterpret_cast<void*>(Mock_glGetQueryObjectuiv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetQueryObjectuiv); if (strcmp(name, "glGetQueryObjectuivARB") == 0) - return reinterpret_cast<void*>(Mock_glGetQueryObjectuivARB); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetQueryObjectuivARB); if (strcmp(name, "glGetQueryObjectuivEXT") == 0) - return reinterpret_cast<void*>(Mock_glGetQueryObjectuivEXT); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetQueryObjectuivEXT); if (strcmp(name, "glGetQueryObjectuivRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetQueryObjectuivRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetQueryObjectuivRobustANGLE); if (strcmp(name, "glGetQueryiv") == 0) - return reinterpret_cast<void*>(Mock_glGetQueryiv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetQueryiv); if (strcmp(name, "glGetQueryivARB") == 0) - return reinterpret_cast<void*>(Mock_glGetQueryivARB); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetQueryivARB); if (strcmp(name, "glGetQueryivEXT") == 0) - return reinterpret_cast<void*>(Mock_glGetQueryivEXT); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetQueryivEXT); if (strcmp(name, "glGetQueryivRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetQueryivRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetQueryivRobustANGLE); if (strcmp(name, "glGetRenderbufferParameteriv") == 0) - return reinterpret_cast<void*>(Mock_glGetRenderbufferParameteriv); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetRenderbufferParameteriv); if (strcmp(name, "glGetRenderbufferParameterivEXT") == 0) - return reinterpret_cast<void*>(Mock_glGetRenderbufferParameterivEXT); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetRenderbufferParameterivEXT); if (strcmp(name, "glGetRenderbufferParameterivRobustANGLE") == 0) - return reinterpret_cast<void*>( + return reinterpret_cast<GLFunctionPointerType>( Mock_glGetRenderbufferParameterivRobustANGLE); if (strcmp(name, "glGetSamplerParameterIivRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetSamplerParameterIivRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetSamplerParameterIivRobustANGLE); if (strcmp(name, "glGetSamplerParameterIuivRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetSamplerParameterIuivRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetSamplerParameterIuivRobustANGLE); if (strcmp(name, "glGetSamplerParameterfv") == 0) - return reinterpret_cast<void*>(Mock_glGetSamplerParameterfv); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetSamplerParameterfv); if (strcmp(name, "glGetSamplerParameterfvRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetSamplerParameterfvRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetSamplerParameterfvRobustANGLE); if (strcmp(name, "glGetSamplerParameteriv") == 0) - return reinterpret_cast<void*>(Mock_glGetSamplerParameteriv); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetSamplerParameteriv); if (strcmp(name, "glGetSamplerParameterivRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetSamplerParameterivRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetSamplerParameterivRobustANGLE); if (strcmp(name, "glGetShaderInfoLog") == 0) - return reinterpret_cast<void*>(Mock_glGetShaderInfoLog); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetShaderInfoLog); if (strcmp(name, "glGetShaderPrecisionFormat") == 0) - return reinterpret_cast<void*>(Mock_glGetShaderPrecisionFormat); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetShaderPrecisionFormat); if (strcmp(name, "glGetShaderSource") == 0) - return reinterpret_cast<void*>(Mock_glGetShaderSource); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetShaderSource); if (strcmp(name, "glGetShaderiv") == 0) - return reinterpret_cast<void*>(Mock_glGetShaderiv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetShaderiv); if (strcmp(name, "glGetShaderivRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetShaderivRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetShaderivRobustANGLE); if (strcmp(name, "glGetString") == 0) - return reinterpret_cast<void*>(Mock_glGetString); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetString); if (strcmp(name, "glGetStringi") == 0) - return reinterpret_cast<void*>(Mock_glGetStringi); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetStringi); if (strcmp(name, "glGetSynciv") == 0) - return reinterpret_cast<void*>(Mock_glGetSynciv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetSynciv); if (strcmp(name, "glGetTexLevelParameterfv") == 0) - return reinterpret_cast<void*>(Mock_glGetTexLevelParameterfv); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetTexLevelParameterfv); if (strcmp(name, "glGetTexLevelParameterfvRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetTexLevelParameterfvRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetTexLevelParameterfvRobustANGLE); if (strcmp(name, "glGetTexLevelParameteriv") == 0) - return reinterpret_cast<void*>(Mock_glGetTexLevelParameteriv); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetTexLevelParameteriv); if (strcmp(name, "glGetTexLevelParameterivRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetTexLevelParameterivRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetTexLevelParameterivRobustANGLE); if (strcmp(name, "glGetTexParameterIivRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetTexParameterIivRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetTexParameterIivRobustANGLE); if (strcmp(name, "glGetTexParameterIuivRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetTexParameterIuivRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetTexParameterIuivRobustANGLE); if (strcmp(name, "glGetTexParameterfv") == 0) - return reinterpret_cast<void*>(Mock_glGetTexParameterfv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetTexParameterfv); if (strcmp(name, "glGetTexParameterfvRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetTexParameterfvRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetTexParameterfvRobustANGLE); if (strcmp(name, "glGetTexParameteriv") == 0) - return reinterpret_cast<void*>(Mock_glGetTexParameteriv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetTexParameteriv); if (strcmp(name, "glGetTexParameterivRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetTexParameterivRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetTexParameterivRobustANGLE); if (strcmp(name, "glGetTransformFeedbackVarying") == 0) - return reinterpret_cast<void*>(Mock_glGetTransformFeedbackVarying); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetTransformFeedbackVarying); if (strcmp(name, "glGetTransformFeedbackVaryingEXT") == 0) - return reinterpret_cast<void*>(Mock_glGetTransformFeedbackVaryingEXT); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetTransformFeedbackVaryingEXT); if (strcmp(name, "glGetTranslatedShaderSourceANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetTranslatedShaderSourceANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetTranslatedShaderSourceANGLE); if (strcmp(name, "glGetUniformBlockIndex") == 0) - return reinterpret_cast<void*>(Mock_glGetUniformBlockIndex); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetUniformBlockIndex); if (strcmp(name, "glGetUniformIndices") == 0) - return reinterpret_cast<void*>(Mock_glGetUniformIndices); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetUniformIndices); if (strcmp(name, "glGetUniformLocation") == 0) - return reinterpret_cast<void*>(Mock_glGetUniformLocation); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetUniformLocation); if (strcmp(name, "glGetUniformfv") == 0) - return reinterpret_cast<void*>(Mock_glGetUniformfv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetUniformfv); if (strcmp(name, "glGetUniformfvRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetUniformfvRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetUniformfvRobustANGLE); if (strcmp(name, "glGetUniformiv") == 0) - return reinterpret_cast<void*>(Mock_glGetUniformiv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetUniformiv); if (strcmp(name, "glGetUniformivRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetUniformivRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetUniformivRobustANGLE); if (strcmp(name, "glGetUniformuiv") == 0) - return reinterpret_cast<void*>(Mock_glGetUniformuiv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetUniformuiv); if (strcmp(name, "glGetUniformuivRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetUniformuivRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetUniformuivRobustANGLE); if (strcmp(name, "glGetVertexAttribIivRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetVertexAttribIivRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetVertexAttribIivRobustANGLE); if (strcmp(name, "glGetVertexAttribIuivRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetVertexAttribIuivRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetVertexAttribIuivRobustANGLE); if (strcmp(name, "glGetVertexAttribPointerv") == 0) - return reinterpret_cast<void*>(Mock_glGetVertexAttribPointerv); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetVertexAttribPointerv); if (strcmp(name, "glGetVertexAttribPointervRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetVertexAttribPointervRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetVertexAttribPointervRobustANGLE); if (strcmp(name, "glGetVertexAttribfv") == 0) - return reinterpret_cast<void*>(Mock_glGetVertexAttribfv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetVertexAttribfv); if (strcmp(name, "glGetVertexAttribfvRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetVertexAttribfvRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetVertexAttribfvRobustANGLE); if (strcmp(name, "glGetVertexAttribiv") == 0) - return reinterpret_cast<void*>(Mock_glGetVertexAttribiv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glGetVertexAttribiv); if (strcmp(name, "glGetVertexAttribivRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetVertexAttribivRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetVertexAttribivRobustANGLE); if (strcmp(name, "glGetnUniformfvRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetnUniformfvRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetnUniformfvRobustANGLE); if (strcmp(name, "glGetnUniformivRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetnUniformivRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetnUniformivRobustANGLE); if (strcmp(name, "glGetnUniformuivRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glGetnUniformuivRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glGetnUniformuivRobustANGLE); if (strcmp(name, "glHint") == 0) - return reinterpret_cast<void*>(Mock_glHint); + return reinterpret_cast<GLFunctionPointerType>(Mock_glHint); if (strcmp(name, "glInsertEventMarkerEXT") == 0) - return reinterpret_cast<void*>(Mock_glInsertEventMarkerEXT); + return reinterpret_cast<GLFunctionPointerType>(Mock_glInsertEventMarkerEXT); if (strcmp(name, "glInvalidateFramebuffer") == 0) - return reinterpret_cast<void*>(Mock_glInvalidateFramebuffer); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glInvalidateFramebuffer); if (strcmp(name, "glInvalidateSubFramebuffer") == 0) - return reinterpret_cast<void*>(Mock_glInvalidateSubFramebuffer); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glInvalidateSubFramebuffer); if (strcmp(name, "glIsBuffer") == 0) - return reinterpret_cast<void*>(Mock_glIsBuffer); + return reinterpret_cast<GLFunctionPointerType>(Mock_glIsBuffer); if (strcmp(name, "glIsEnabled") == 0) - return reinterpret_cast<void*>(Mock_glIsEnabled); + return reinterpret_cast<GLFunctionPointerType>(Mock_glIsEnabled); if (strcmp(name, "glIsFenceAPPLE") == 0) - return reinterpret_cast<void*>(Mock_glIsFenceAPPLE); + return reinterpret_cast<GLFunctionPointerType>(Mock_glIsFenceAPPLE); if (strcmp(name, "glIsFenceNV") == 0) - return reinterpret_cast<void*>(Mock_glIsFenceNV); + return reinterpret_cast<GLFunctionPointerType>(Mock_glIsFenceNV); if (strcmp(name, "glIsFramebuffer") == 0) - return reinterpret_cast<void*>(Mock_glIsFramebuffer); + return reinterpret_cast<GLFunctionPointerType>(Mock_glIsFramebuffer); if (strcmp(name, "glIsFramebufferEXT") == 0) - return reinterpret_cast<void*>(Mock_glIsFramebufferEXT); + return reinterpret_cast<GLFunctionPointerType>(Mock_glIsFramebufferEXT); if (strcmp(name, "glIsPathNV") == 0) - return reinterpret_cast<void*>(Mock_glIsPathNV); + return reinterpret_cast<GLFunctionPointerType>(Mock_glIsPathNV); if (strcmp(name, "glIsProgram") == 0) - return reinterpret_cast<void*>(Mock_glIsProgram); + return reinterpret_cast<GLFunctionPointerType>(Mock_glIsProgram); if (strcmp(name, "glIsQuery") == 0) - return reinterpret_cast<void*>(Mock_glIsQuery); + return reinterpret_cast<GLFunctionPointerType>(Mock_glIsQuery); if (strcmp(name, "glIsQueryARB") == 0) - return reinterpret_cast<void*>(Mock_glIsQueryARB); + return reinterpret_cast<GLFunctionPointerType>(Mock_glIsQueryARB); if (strcmp(name, "glIsQueryEXT") == 0) - return reinterpret_cast<void*>(Mock_glIsQueryEXT); + return reinterpret_cast<GLFunctionPointerType>(Mock_glIsQueryEXT); if (strcmp(name, "glIsRenderbuffer") == 0) - return reinterpret_cast<void*>(Mock_glIsRenderbuffer); + return reinterpret_cast<GLFunctionPointerType>(Mock_glIsRenderbuffer); if (strcmp(name, "glIsRenderbufferEXT") == 0) - return reinterpret_cast<void*>(Mock_glIsRenderbufferEXT); + return reinterpret_cast<GLFunctionPointerType>(Mock_glIsRenderbufferEXT); if (strcmp(name, "glIsSampler") == 0) - return reinterpret_cast<void*>(Mock_glIsSampler); + return reinterpret_cast<GLFunctionPointerType>(Mock_glIsSampler); if (strcmp(name, "glIsShader") == 0) - return reinterpret_cast<void*>(Mock_glIsShader); + return reinterpret_cast<GLFunctionPointerType>(Mock_glIsShader); if (strcmp(name, "glIsSync") == 0) - return reinterpret_cast<void*>(Mock_glIsSync); + return reinterpret_cast<GLFunctionPointerType>(Mock_glIsSync); if (strcmp(name, "glIsTexture") == 0) - return reinterpret_cast<void*>(Mock_glIsTexture); + return reinterpret_cast<GLFunctionPointerType>(Mock_glIsTexture); if (strcmp(name, "glIsTransformFeedback") == 0) - return reinterpret_cast<void*>(Mock_glIsTransformFeedback); + return reinterpret_cast<GLFunctionPointerType>(Mock_glIsTransformFeedback); if (strcmp(name, "glIsVertexArray") == 0) - return reinterpret_cast<void*>(Mock_glIsVertexArray); + return reinterpret_cast<GLFunctionPointerType>(Mock_glIsVertexArray); if (strcmp(name, "glIsVertexArrayAPPLE") == 0) - return reinterpret_cast<void*>(Mock_glIsVertexArrayAPPLE); + return reinterpret_cast<GLFunctionPointerType>(Mock_glIsVertexArrayAPPLE); if (strcmp(name, "glIsVertexArrayOES") == 0) - return reinterpret_cast<void*>(Mock_glIsVertexArrayOES); + return reinterpret_cast<GLFunctionPointerType>(Mock_glIsVertexArrayOES); if (strcmp(name, "glLineWidth") == 0) - return reinterpret_cast<void*>(Mock_glLineWidth); + return reinterpret_cast<GLFunctionPointerType>(Mock_glLineWidth); if (strcmp(name, "glLinkProgram") == 0) - return reinterpret_cast<void*>(Mock_glLinkProgram); + return reinterpret_cast<GLFunctionPointerType>(Mock_glLinkProgram); if (strcmp(name, "glMapBuffer") == 0) - return reinterpret_cast<void*>(Mock_glMapBuffer); + return reinterpret_cast<GLFunctionPointerType>(Mock_glMapBuffer); if (strcmp(name, "glMapBufferOES") == 0) - return reinterpret_cast<void*>(Mock_glMapBufferOES); + return reinterpret_cast<GLFunctionPointerType>(Mock_glMapBufferOES); if (strcmp(name, "glMapBufferRange") == 0) - return reinterpret_cast<void*>(Mock_glMapBufferRange); + return reinterpret_cast<GLFunctionPointerType>(Mock_glMapBufferRange); if (strcmp(name, "glMapBufferRangeEXT") == 0) - return reinterpret_cast<void*>(Mock_glMapBufferRangeEXT); + return reinterpret_cast<GLFunctionPointerType>(Mock_glMapBufferRangeEXT); if (strcmp(name, "glMatrixLoadIdentityEXT") == 0) - return reinterpret_cast<void*>(Mock_glMatrixLoadIdentityEXT); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glMatrixLoadIdentityEXT); if (strcmp(name, "glMatrixLoadfEXT") == 0) - return reinterpret_cast<void*>(Mock_glMatrixLoadfEXT); + return reinterpret_cast<GLFunctionPointerType>(Mock_glMatrixLoadfEXT); if (strcmp(name, "glMemoryBarrier") == 0) - return reinterpret_cast<void*>(Mock_glMemoryBarrier); + return reinterpret_cast<GLFunctionPointerType>(Mock_glMemoryBarrier); if (strcmp(name, "glMemoryBarrierEXT") == 0) - return reinterpret_cast<void*>(Mock_glMemoryBarrierEXT); + return reinterpret_cast<GLFunctionPointerType>(Mock_glMemoryBarrierEXT); if (strcmp(name, "glObjectLabel") == 0) - return reinterpret_cast<void*>(Mock_glObjectLabel); + return reinterpret_cast<GLFunctionPointerType>(Mock_glObjectLabel); if (strcmp(name, "glObjectLabelKHR") == 0) - return reinterpret_cast<void*>(Mock_glObjectLabelKHR); + return reinterpret_cast<GLFunctionPointerType>(Mock_glObjectLabelKHR); if (strcmp(name, "glObjectPtrLabel") == 0) - return reinterpret_cast<void*>(Mock_glObjectPtrLabel); + return reinterpret_cast<GLFunctionPointerType>(Mock_glObjectPtrLabel); if (strcmp(name, "glObjectPtrLabelKHR") == 0) - return reinterpret_cast<void*>(Mock_glObjectPtrLabelKHR); + return reinterpret_cast<GLFunctionPointerType>(Mock_glObjectPtrLabelKHR); if (strcmp(name, "glPathCommandsNV") == 0) - return reinterpret_cast<void*>(Mock_glPathCommandsNV); + return reinterpret_cast<GLFunctionPointerType>(Mock_glPathCommandsNV); if (strcmp(name, "glPathParameterfNV") == 0) - return reinterpret_cast<void*>(Mock_glPathParameterfNV); + return reinterpret_cast<GLFunctionPointerType>(Mock_glPathParameterfNV); if (strcmp(name, "glPathParameteriNV") == 0) - return reinterpret_cast<void*>(Mock_glPathParameteriNV); + return reinterpret_cast<GLFunctionPointerType>(Mock_glPathParameteriNV); if (strcmp(name, "glPathStencilFuncNV") == 0) - return reinterpret_cast<void*>(Mock_glPathStencilFuncNV); + return reinterpret_cast<GLFunctionPointerType>(Mock_glPathStencilFuncNV); if (strcmp(name, "glPauseTransformFeedback") == 0) - return reinterpret_cast<void*>(Mock_glPauseTransformFeedback); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glPauseTransformFeedback); if (strcmp(name, "glPixelStorei") == 0) - return reinterpret_cast<void*>(Mock_glPixelStorei); + return reinterpret_cast<GLFunctionPointerType>(Mock_glPixelStorei); if (strcmp(name, "glPointParameteri") == 0) - return reinterpret_cast<void*>(Mock_glPointParameteri); + return reinterpret_cast<GLFunctionPointerType>(Mock_glPointParameteri); if (strcmp(name, "glPolygonOffset") == 0) - return reinterpret_cast<void*>(Mock_glPolygonOffset); + return reinterpret_cast<GLFunctionPointerType>(Mock_glPolygonOffset); if (strcmp(name, "glPopDebugGroup") == 0) - return reinterpret_cast<void*>(Mock_glPopDebugGroup); + return reinterpret_cast<GLFunctionPointerType>(Mock_glPopDebugGroup); if (strcmp(name, "glPopDebugGroupKHR") == 0) - return reinterpret_cast<void*>(Mock_glPopDebugGroupKHR); + return reinterpret_cast<GLFunctionPointerType>(Mock_glPopDebugGroupKHR); if (strcmp(name, "glPopGroupMarkerEXT") == 0) - return reinterpret_cast<void*>(Mock_glPopGroupMarkerEXT); + return reinterpret_cast<GLFunctionPointerType>(Mock_glPopGroupMarkerEXT); if (strcmp(name, "glPrimitiveRestartIndex") == 0) - return reinterpret_cast<void*>(Mock_glPrimitiveRestartIndex); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glPrimitiveRestartIndex); if (strcmp(name, "glProgramBinary") == 0) - return reinterpret_cast<void*>(Mock_glProgramBinary); + return reinterpret_cast<GLFunctionPointerType>(Mock_glProgramBinary); if (strcmp(name, "glProgramBinaryOES") == 0) - return reinterpret_cast<void*>(Mock_glProgramBinaryOES); + return reinterpret_cast<GLFunctionPointerType>(Mock_glProgramBinaryOES); if (strcmp(name, "glProgramParameteri") == 0) - return reinterpret_cast<void*>(Mock_glProgramParameteri); + return reinterpret_cast<GLFunctionPointerType>(Mock_glProgramParameteri); if (strcmp(name, "glProgramPathFragmentInputGenNV") == 0) - return reinterpret_cast<void*>(Mock_glProgramPathFragmentInputGenNV); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glProgramPathFragmentInputGenNV); if (strcmp(name, "glPushDebugGroup") == 0) - return reinterpret_cast<void*>(Mock_glPushDebugGroup); + return reinterpret_cast<GLFunctionPointerType>(Mock_glPushDebugGroup); if (strcmp(name, "glPushDebugGroupKHR") == 0) - return reinterpret_cast<void*>(Mock_glPushDebugGroupKHR); + return reinterpret_cast<GLFunctionPointerType>(Mock_glPushDebugGroupKHR); if (strcmp(name, "glPushGroupMarkerEXT") == 0) - return reinterpret_cast<void*>(Mock_glPushGroupMarkerEXT); + return reinterpret_cast<GLFunctionPointerType>(Mock_glPushGroupMarkerEXT); if (strcmp(name, "glQueryCounter") == 0) - return reinterpret_cast<void*>(Mock_glQueryCounter); + return reinterpret_cast<GLFunctionPointerType>(Mock_glQueryCounter); if (strcmp(name, "glQueryCounterEXT") == 0) - return reinterpret_cast<void*>(Mock_glQueryCounterEXT); + return reinterpret_cast<GLFunctionPointerType>(Mock_glQueryCounterEXT); if (strcmp(name, "glReadBuffer") == 0) - return reinterpret_cast<void*>(Mock_glReadBuffer); + return reinterpret_cast<GLFunctionPointerType>(Mock_glReadBuffer); if (strcmp(name, "glReadPixels") == 0) - return reinterpret_cast<void*>(Mock_glReadPixels); + return reinterpret_cast<GLFunctionPointerType>(Mock_glReadPixels); if (strcmp(name, "glReadPixelsRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glReadPixelsRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glReadPixelsRobustANGLE); if (strcmp(name, "glReadnPixelsRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glReadnPixelsRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glReadnPixelsRobustANGLE); if (strcmp(name, "glReleaseShaderCompiler") == 0) - return reinterpret_cast<void*>(Mock_glReleaseShaderCompiler); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glReleaseShaderCompiler); if (strcmp(name, "glRenderbufferStorage") == 0) - return reinterpret_cast<void*>(Mock_glRenderbufferStorage); + return reinterpret_cast<GLFunctionPointerType>(Mock_glRenderbufferStorage); if (strcmp(name, "glRenderbufferStorageEXT") == 0) - return reinterpret_cast<void*>(Mock_glRenderbufferStorageEXT); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glRenderbufferStorageEXT); if (strcmp(name, "glRenderbufferStorageMultisample") == 0) - return reinterpret_cast<void*>(Mock_glRenderbufferStorageMultisample); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glRenderbufferStorageMultisample); if (strcmp(name, "glRenderbufferStorageMultisampleANGLE") == 0) - return reinterpret_cast<void*>(Mock_glRenderbufferStorageMultisampleANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glRenderbufferStorageMultisampleANGLE); if (strcmp(name, "glRenderbufferStorageMultisampleEXT") == 0) - return reinterpret_cast<void*>(Mock_glRenderbufferStorageMultisampleEXT); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glRenderbufferStorageMultisampleEXT); if (strcmp(name, "glRenderbufferStorageMultisampleIMG") == 0) - return reinterpret_cast<void*>(Mock_glRenderbufferStorageMultisampleIMG); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glRenderbufferStorageMultisampleIMG); if (strcmp(name, "glResumeTransformFeedback") == 0) - return reinterpret_cast<void*>(Mock_glResumeTransformFeedback); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glResumeTransformFeedback); if (strcmp(name, "glSampleCoverage") == 0) - return reinterpret_cast<void*>(Mock_glSampleCoverage); + return reinterpret_cast<GLFunctionPointerType>(Mock_glSampleCoverage); if (strcmp(name, "glSamplerParameterIivRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glSamplerParameterIivRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glSamplerParameterIivRobustANGLE); if (strcmp(name, "glSamplerParameterIuivRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glSamplerParameterIuivRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glSamplerParameterIuivRobustANGLE); if (strcmp(name, "glSamplerParameterf") == 0) - return reinterpret_cast<void*>(Mock_glSamplerParameterf); + return reinterpret_cast<GLFunctionPointerType>(Mock_glSamplerParameterf); if (strcmp(name, "glSamplerParameterfv") == 0) - return reinterpret_cast<void*>(Mock_glSamplerParameterfv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glSamplerParameterfv); if (strcmp(name, "glSamplerParameterfvRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glSamplerParameterfvRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glSamplerParameterfvRobustANGLE); if (strcmp(name, "glSamplerParameteri") == 0) - return reinterpret_cast<void*>(Mock_glSamplerParameteri); + return reinterpret_cast<GLFunctionPointerType>(Mock_glSamplerParameteri); if (strcmp(name, "glSamplerParameteriv") == 0) - return reinterpret_cast<void*>(Mock_glSamplerParameteriv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glSamplerParameteriv); if (strcmp(name, "glSamplerParameterivRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glSamplerParameterivRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glSamplerParameterivRobustANGLE); if (strcmp(name, "glScissor") == 0) - return reinterpret_cast<void*>(Mock_glScissor); + return reinterpret_cast<GLFunctionPointerType>(Mock_glScissor); if (strcmp(name, "glSetFenceAPPLE") == 0) - return reinterpret_cast<void*>(Mock_glSetFenceAPPLE); + return reinterpret_cast<GLFunctionPointerType>(Mock_glSetFenceAPPLE); if (strcmp(name, "glSetFenceNV") == 0) - return reinterpret_cast<void*>(Mock_glSetFenceNV); + return reinterpret_cast<GLFunctionPointerType>(Mock_glSetFenceNV); if (strcmp(name, "glShaderBinary") == 0) - return reinterpret_cast<void*>(Mock_glShaderBinary); + return reinterpret_cast<GLFunctionPointerType>(Mock_glShaderBinary); if (strcmp(name, "glShaderSource") == 0) - return reinterpret_cast<void*>(Mock_glShaderSource); + return reinterpret_cast<GLFunctionPointerType>(Mock_glShaderSource); if (strcmp(name, "glStencilFillPathInstancedNV") == 0) - return reinterpret_cast<void*>(Mock_glStencilFillPathInstancedNV); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glStencilFillPathInstancedNV); if (strcmp(name, "glStencilFillPathNV") == 0) - return reinterpret_cast<void*>(Mock_glStencilFillPathNV); + return reinterpret_cast<GLFunctionPointerType>(Mock_glStencilFillPathNV); if (strcmp(name, "glStencilFunc") == 0) - return reinterpret_cast<void*>(Mock_glStencilFunc); + return reinterpret_cast<GLFunctionPointerType>(Mock_glStencilFunc); if (strcmp(name, "glStencilFuncSeparate") == 0) - return reinterpret_cast<void*>(Mock_glStencilFuncSeparate); + return reinterpret_cast<GLFunctionPointerType>(Mock_glStencilFuncSeparate); if (strcmp(name, "glStencilMask") == 0) - return reinterpret_cast<void*>(Mock_glStencilMask); + return reinterpret_cast<GLFunctionPointerType>(Mock_glStencilMask); if (strcmp(name, "glStencilMaskSeparate") == 0) - return reinterpret_cast<void*>(Mock_glStencilMaskSeparate); + return reinterpret_cast<GLFunctionPointerType>(Mock_glStencilMaskSeparate); if (strcmp(name, "glStencilOp") == 0) - return reinterpret_cast<void*>(Mock_glStencilOp); + return reinterpret_cast<GLFunctionPointerType>(Mock_glStencilOp); if (strcmp(name, "glStencilOpSeparate") == 0) - return reinterpret_cast<void*>(Mock_glStencilOpSeparate); + return reinterpret_cast<GLFunctionPointerType>(Mock_glStencilOpSeparate); if (strcmp(name, "glStencilStrokePathInstancedNV") == 0) - return reinterpret_cast<void*>(Mock_glStencilStrokePathInstancedNV); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glStencilStrokePathInstancedNV); if (strcmp(name, "glStencilStrokePathNV") == 0) - return reinterpret_cast<void*>(Mock_glStencilStrokePathNV); + return reinterpret_cast<GLFunctionPointerType>(Mock_glStencilStrokePathNV); if (strcmp(name, "glStencilThenCoverFillPathInstancedNV") == 0) - return reinterpret_cast<void*>(Mock_glStencilThenCoverFillPathInstancedNV); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glStencilThenCoverFillPathInstancedNV); if (strcmp(name, "glStencilThenCoverFillPathNV") == 0) - return reinterpret_cast<void*>(Mock_glStencilThenCoverFillPathNV); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glStencilThenCoverFillPathNV); if (strcmp(name, "glStencilThenCoverStrokePathInstancedNV") == 0) - return reinterpret_cast<void*>( + return reinterpret_cast<GLFunctionPointerType>( Mock_glStencilThenCoverStrokePathInstancedNV); if (strcmp(name, "glStencilThenCoverStrokePathNV") == 0) - return reinterpret_cast<void*>(Mock_glStencilThenCoverStrokePathNV); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glStencilThenCoverStrokePathNV); if (strcmp(name, "glTestFenceAPPLE") == 0) - return reinterpret_cast<void*>(Mock_glTestFenceAPPLE); + return reinterpret_cast<GLFunctionPointerType>(Mock_glTestFenceAPPLE); if (strcmp(name, "glTestFenceNV") == 0) - return reinterpret_cast<void*>(Mock_glTestFenceNV); + return reinterpret_cast<GLFunctionPointerType>(Mock_glTestFenceNV); if (strcmp(name, "glTexImage2D") == 0) - return reinterpret_cast<void*>(Mock_glTexImage2D); + return reinterpret_cast<GLFunctionPointerType>(Mock_glTexImage2D); if (strcmp(name, "glTexImage2DRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glTexImage2DRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glTexImage2DRobustANGLE); if (strcmp(name, "glTexImage3D") == 0) - return reinterpret_cast<void*>(Mock_glTexImage3D); + return reinterpret_cast<GLFunctionPointerType>(Mock_glTexImage3D); if (strcmp(name, "glTexImage3DRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glTexImage3DRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glTexImage3DRobustANGLE); if (strcmp(name, "glTexParameterIivRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glTexParameterIivRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glTexParameterIivRobustANGLE); if (strcmp(name, "glTexParameterIuivRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glTexParameterIuivRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glTexParameterIuivRobustANGLE); if (strcmp(name, "glTexParameterf") == 0) - return reinterpret_cast<void*>(Mock_glTexParameterf); + return reinterpret_cast<GLFunctionPointerType>(Mock_glTexParameterf); if (strcmp(name, "glTexParameterfv") == 0) - return reinterpret_cast<void*>(Mock_glTexParameterfv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glTexParameterfv); if (strcmp(name, "glTexParameterfvRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glTexParameterfvRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glTexParameterfvRobustANGLE); if (strcmp(name, "glTexParameteri") == 0) - return reinterpret_cast<void*>(Mock_glTexParameteri); + return reinterpret_cast<GLFunctionPointerType>(Mock_glTexParameteri); if (strcmp(name, "glTexParameteriv") == 0) - return reinterpret_cast<void*>(Mock_glTexParameteriv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glTexParameteriv); if (strcmp(name, "glTexParameterivRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glTexParameterivRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glTexParameterivRobustANGLE); if (strcmp(name, "glTexStorage2D") == 0) - return reinterpret_cast<void*>(Mock_glTexStorage2D); + return reinterpret_cast<GLFunctionPointerType>(Mock_glTexStorage2D); if (strcmp(name, "glTexStorage2DEXT") == 0) - return reinterpret_cast<void*>(Mock_glTexStorage2DEXT); + return reinterpret_cast<GLFunctionPointerType>(Mock_glTexStorage2DEXT); if (strcmp(name, "glTexStorage3D") == 0) - return reinterpret_cast<void*>(Mock_glTexStorage3D); + return reinterpret_cast<GLFunctionPointerType>(Mock_glTexStorage3D); if (strcmp(name, "glTexSubImage2D") == 0) - return reinterpret_cast<void*>(Mock_glTexSubImage2D); + return reinterpret_cast<GLFunctionPointerType>(Mock_glTexSubImage2D); if (strcmp(name, "glTexSubImage2DRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glTexSubImage2DRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glTexSubImage2DRobustANGLE); if (strcmp(name, "glTexSubImage3D") == 0) - return reinterpret_cast<void*>(Mock_glTexSubImage3D); + return reinterpret_cast<GLFunctionPointerType>(Mock_glTexSubImage3D); if (strcmp(name, "glTexSubImage3DRobustANGLE") == 0) - return reinterpret_cast<void*>(Mock_glTexSubImage3DRobustANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glTexSubImage3DRobustANGLE); if (strcmp(name, "glTransformFeedbackVaryings") == 0) - return reinterpret_cast<void*>(Mock_glTransformFeedbackVaryings); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glTransformFeedbackVaryings); if (strcmp(name, "glTransformFeedbackVaryingsEXT") == 0) - return reinterpret_cast<void*>(Mock_glTransformFeedbackVaryingsEXT); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glTransformFeedbackVaryingsEXT); if (strcmp(name, "glUniform1f") == 0) - return reinterpret_cast<void*>(Mock_glUniform1f); + return reinterpret_cast<GLFunctionPointerType>(Mock_glUniform1f); if (strcmp(name, "glUniform1fv") == 0) - return reinterpret_cast<void*>(Mock_glUniform1fv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glUniform1fv); if (strcmp(name, "glUniform1i") == 0) - return reinterpret_cast<void*>(Mock_glUniform1i); + return reinterpret_cast<GLFunctionPointerType>(Mock_glUniform1i); if (strcmp(name, "glUniform1iv") == 0) - return reinterpret_cast<void*>(Mock_glUniform1iv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glUniform1iv); if (strcmp(name, "glUniform1ui") == 0) - return reinterpret_cast<void*>(Mock_glUniform1ui); + return reinterpret_cast<GLFunctionPointerType>(Mock_glUniform1ui); if (strcmp(name, "glUniform1uiv") == 0) - return reinterpret_cast<void*>(Mock_glUniform1uiv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glUniform1uiv); if (strcmp(name, "glUniform2f") == 0) - return reinterpret_cast<void*>(Mock_glUniform2f); + return reinterpret_cast<GLFunctionPointerType>(Mock_glUniform2f); if (strcmp(name, "glUniform2fv") == 0) - return reinterpret_cast<void*>(Mock_glUniform2fv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glUniform2fv); if (strcmp(name, "glUniform2i") == 0) - return reinterpret_cast<void*>(Mock_glUniform2i); + return reinterpret_cast<GLFunctionPointerType>(Mock_glUniform2i); if (strcmp(name, "glUniform2iv") == 0) - return reinterpret_cast<void*>(Mock_glUniform2iv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glUniform2iv); if (strcmp(name, "glUniform2ui") == 0) - return reinterpret_cast<void*>(Mock_glUniform2ui); + return reinterpret_cast<GLFunctionPointerType>(Mock_glUniform2ui); if (strcmp(name, "glUniform2uiv") == 0) - return reinterpret_cast<void*>(Mock_glUniform2uiv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glUniform2uiv); if (strcmp(name, "glUniform3f") == 0) - return reinterpret_cast<void*>(Mock_glUniform3f); + return reinterpret_cast<GLFunctionPointerType>(Mock_glUniform3f); if (strcmp(name, "glUniform3fv") == 0) - return reinterpret_cast<void*>(Mock_glUniform3fv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glUniform3fv); if (strcmp(name, "glUniform3i") == 0) - return reinterpret_cast<void*>(Mock_glUniform3i); + return reinterpret_cast<GLFunctionPointerType>(Mock_glUniform3i); if (strcmp(name, "glUniform3iv") == 0) - return reinterpret_cast<void*>(Mock_glUniform3iv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glUniform3iv); if (strcmp(name, "glUniform3ui") == 0) - return reinterpret_cast<void*>(Mock_glUniform3ui); + return reinterpret_cast<GLFunctionPointerType>(Mock_glUniform3ui); if (strcmp(name, "glUniform3uiv") == 0) - return reinterpret_cast<void*>(Mock_glUniform3uiv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glUniform3uiv); if (strcmp(name, "glUniform4f") == 0) - return reinterpret_cast<void*>(Mock_glUniform4f); + return reinterpret_cast<GLFunctionPointerType>(Mock_glUniform4f); if (strcmp(name, "glUniform4fv") == 0) - return reinterpret_cast<void*>(Mock_glUniform4fv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glUniform4fv); if (strcmp(name, "glUniform4i") == 0) - return reinterpret_cast<void*>(Mock_glUniform4i); + return reinterpret_cast<GLFunctionPointerType>(Mock_glUniform4i); if (strcmp(name, "glUniform4iv") == 0) - return reinterpret_cast<void*>(Mock_glUniform4iv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glUniform4iv); if (strcmp(name, "glUniform4ui") == 0) - return reinterpret_cast<void*>(Mock_glUniform4ui); + return reinterpret_cast<GLFunctionPointerType>(Mock_glUniform4ui); if (strcmp(name, "glUniform4uiv") == 0) - return reinterpret_cast<void*>(Mock_glUniform4uiv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glUniform4uiv); if (strcmp(name, "glUniformBlockBinding") == 0) - return reinterpret_cast<void*>(Mock_glUniformBlockBinding); + return reinterpret_cast<GLFunctionPointerType>(Mock_glUniformBlockBinding); if (strcmp(name, "glUniformMatrix2fv") == 0) - return reinterpret_cast<void*>(Mock_glUniformMatrix2fv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glUniformMatrix2fv); if (strcmp(name, "glUniformMatrix2x3fv") == 0) - return reinterpret_cast<void*>(Mock_glUniformMatrix2x3fv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glUniformMatrix2x3fv); if (strcmp(name, "glUniformMatrix2x4fv") == 0) - return reinterpret_cast<void*>(Mock_glUniformMatrix2x4fv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glUniformMatrix2x4fv); if (strcmp(name, "glUniformMatrix3fv") == 0) - return reinterpret_cast<void*>(Mock_glUniformMatrix3fv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glUniformMatrix3fv); if (strcmp(name, "glUniformMatrix3x2fv") == 0) - return reinterpret_cast<void*>(Mock_glUniformMatrix3x2fv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glUniformMatrix3x2fv); if (strcmp(name, "glUniformMatrix3x4fv") == 0) - return reinterpret_cast<void*>(Mock_glUniformMatrix3x4fv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glUniformMatrix3x4fv); if (strcmp(name, "glUniformMatrix4fv") == 0) - return reinterpret_cast<void*>(Mock_glUniformMatrix4fv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glUniformMatrix4fv); if (strcmp(name, "glUniformMatrix4x2fv") == 0) - return reinterpret_cast<void*>(Mock_glUniformMatrix4x2fv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glUniformMatrix4x2fv); if (strcmp(name, "glUniformMatrix4x3fv") == 0) - return reinterpret_cast<void*>(Mock_glUniformMatrix4x3fv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glUniformMatrix4x3fv); if (strcmp(name, "glUnmapBuffer") == 0) - return reinterpret_cast<void*>(Mock_glUnmapBuffer); + return reinterpret_cast<GLFunctionPointerType>(Mock_glUnmapBuffer); if (strcmp(name, "glUnmapBufferOES") == 0) - return reinterpret_cast<void*>(Mock_glUnmapBufferOES); + return reinterpret_cast<GLFunctionPointerType>(Mock_glUnmapBufferOES); if (strcmp(name, "glUseProgram") == 0) - return reinterpret_cast<void*>(Mock_glUseProgram); + return reinterpret_cast<GLFunctionPointerType>(Mock_glUseProgram); if (strcmp(name, "glValidateProgram") == 0) - return reinterpret_cast<void*>(Mock_glValidateProgram); + return reinterpret_cast<GLFunctionPointerType>(Mock_glValidateProgram); if (strcmp(name, "glVertexAttrib1f") == 0) - return reinterpret_cast<void*>(Mock_glVertexAttrib1f); + return reinterpret_cast<GLFunctionPointerType>(Mock_glVertexAttrib1f); if (strcmp(name, "glVertexAttrib1fv") == 0) - return reinterpret_cast<void*>(Mock_glVertexAttrib1fv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glVertexAttrib1fv); if (strcmp(name, "glVertexAttrib2f") == 0) - return reinterpret_cast<void*>(Mock_glVertexAttrib2f); + return reinterpret_cast<GLFunctionPointerType>(Mock_glVertexAttrib2f); if (strcmp(name, "glVertexAttrib2fv") == 0) - return reinterpret_cast<void*>(Mock_glVertexAttrib2fv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glVertexAttrib2fv); if (strcmp(name, "glVertexAttrib3f") == 0) - return reinterpret_cast<void*>(Mock_glVertexAttrib3f); + return reinterpret_cast<GLFunctionPointerType>(Mock_glVertexAttrib3f); if (strcmp(name, "glVertexAttrib3fv") == 0) - return reinterpret_cast<void*>(Mock_glVertexAttrib3fv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glVertexAttrib3fv); if (strcmp(name, "glVertexAttrib4f") == 0) - return reinterpret_cast<void*>(Mock_glVertexAttrib4f); + return reinterpret_cast<GLFunctionPointerType>(Mock_glVertexAttrib4f); if (strcmp(name, "glVertexAttrib4fv") == 0) - return reinterpret_cast<void*>(Mock_glVertexAttrib4fv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glVertexAttrib4fv); if (strcmp(name, "glVertexAttribDivisor") == 0) - return reinterpret_cast<void*>(Mock_glVertexAttribDivisor); + return reinterpret_cast<GLFunctionPointerType>(Mock_glVertexAttribDivisor); if (strcmp(name, "glVertexAttribDivisorANGLE") == 0) - return reinterpret_cast<void*>(Mock_glVertexAttribDivisorANGLE); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glVertexAttribDivisorANGLE); if (strcmp(name, "glVertexAttribDivisorARB") == 0) - return reinterpret_cast<void*>(Mock_glVertexAttribDivisorARB); + return reinterpret_cast<GLFunctionPointerType>( + Mock_glVertexAttribDivisorARB); if (strcmp(name, "glVertexAttribI4i") == 0) - return reinterpret_cast<void*>(Mock_glVertexAttribI4i); + return reinterpret_cast<GLFunctionPointerType>(Mock_glVertexAttribI4i); if (strcmp(name, "glVertexAttribI4iv") == 0) - return reinterpret_cast<void*>(Mock_glVertexAttribI4iv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glVertexAttribI4iv); if (strcmp(name, "glVertexAttribI4ui") == 0) - return reinterpret_cast<void*>(Mock_glVertexAttribI4ui); + return reinterpret_cast<GLFunctionPointerType>(Mock_glVertexAttribI4ui); if (strcmp(name, "glVertexAttribI4uiv") == 0) - return reinterpret_cast<void*>(Mock_glVertexAttribI4uiv); + return reinterpret_cast<GLFunctionPointerType>(Mock_glVertexAttribI4uiv); if (strcmp(name, "glVertexAttribIPointer") == 0) - return reinterpret_cast<void*>(Mock_glVertexAttribIPointer); + return reinterpret_cast<GLFunctionPointerType>(Mock_glVertexAttribIPointer); if (strcmp(name, "glVertexAttribPointer") == 0) - return reinterpret_cast<void*>(Mock_glVertexAttribPointer); + return reinterpret_cast<GLFunctionPointerType>(Mock_glVertexAttribPointer); if (strcmp(name, "glViewport") == 0) - return reinterpret_cast<void*>(Mock_glViewport); + return reinterpret_cast<GLFunctionPointerType>(Mock_glViewport); if (strcmp(name, "glWaitSync") == 0) - return reinterpret_cast<void*>(Mock_glWaitSync); - return reinterpret_cast<void*>(&MockInvalidFunction); + return reinterpret_cast<GLFunctionPointerType>(Mock_glWaitSync); + return reinterpret_cast<GLFunctionPointerType>(&MockInvalidFunction); } } // namespace gl
diff --git a/ui/gl/gl_implementation.cc b/ui/gl/gl_implementation.cc index c0c5317..0b88b820 100644 --- a/ui/gl/gl_implementation.cc +++ b/ui/gl/gl_implementation.cc
@@ -123,19 +123,19 @@ g_get_proc_address = proc; } -void* GetGLProcAddress(const char* name) { +GLFunctionPointerType GetGLProcAddress(const char* name) { DCHECK(g_gl_implementation != kGLImplementationNone); if (g_libraries) { for (size_t i = 0; i < g_libraries->size(); ++i) { - void* proc = base::GetFunctionPointerFromNativeLibrary((*g_libraries)[i], - name); + GLFunctionPointerType proc = reinterpret_cast<GLFunctionPointerType>( + base::GetFunctionPointerFromNativeLibrary((*g_libraries)[i], name)); if (proc) return proc; } } if (g_get_proc_address) { - void* proc = g_get_proc_address(name); + GLFunctionPointerType proc = g_get_proc_address(name); if (proc) return proc; }
diff --git a/ui/gl/gl_implementation.h b/ui/gl/gl_implementation.h index 3566f36..dc42507 100644 --- a/ui/gl/gl_implementation.h +++ b/ui/gl/gl_implementation.h
@@ -35,10 +35,11 @@ bool direct_rendering; }; +using GLFunctionPointerType = void (*)(); #if defined(OS_WIN) -typedef void* (WINAPI *GLGetProcAddressProc)(const char* name); +typedef GLFunctionPointerType(WINAPI* GLGetProcAddressProc)(const char* name); #else -typedef void* (*GLGetProcAddressProc)(const char* name); +typedef GLFunctionPointerType (*GLGetProcAddressProc)(const char* name); #endif // Initialize stub methods for drawing operations in the GL bindings. The @@ -99,7 +100,7 @@ // and when querying functions from the EGL library supplied by Android, it may // return a function that prints a log message about the function being // unsupported. -GL_EXPORT void* GetGLProcAddress(const char* name); +GL_EXPORT GLFunctionPointerType GetGLProcAddress(const char* name); // Helper for fetching the OpenGL extensions from the current context. // This helper abstracts over differences between the desktop OpenGL
diff --git a/ui/gl/gl_mock.h b/ui/gl/gl_mock.h index 4a7969a7..c91c981 100644 --- a/ui/gl/gl_mock.h +++ b/ui/gl/gl_mock.h
@@ -14,6 +14,8 @@ namespace gl { +using GLFunctionPointerType = void (*)(); + class MockGLInterface { public: MockGLInterface(); @@ -24,7 +26,8 @@ static void SetGLInterface(MockGLInterface* gl_interface); // Find an entry point to the mock GL implementation. - static void* GL_BINDING_CALL GetGLProcAddress(const char* name); + static GLFunctionPointerType GL_BINDING_CALL + GetGLProcAddress(const char* name); // Include the auto-generated parts of this class. We split this because // it means we can easily edit the non-auto generated parts right here in
diff --git a/ui/gl/glx_api_unittest.cc b/ui/gl/glx_api_unittest.cc index 16f50f4..c36c725 100644 --- a/ui/gl/glx_api_unittest.cc +++ b/ui/gl/glx_api_unittest.cc
@@ -57,9 +57,11 @@ return static_cast<GLXContext>(nullptr); } - static void* GL_BINDING_CALL FakeGLGetProcAddress(const char *proc) { + static GLFunctionPointerType GL_BINDING_CALL + FakeGLGetProcAddress(const char* proc) { if (!strcmp("glXCreateContextAttribsARB", proc)) { - return reinterpret_cast<void *>(&FakeCreateContextAttribsARB); + return reinterpret_cast<GLFunctionPointerType>( + &FakeCreateContextAttribsARB); } return NULL; }
diff --git a/ui/gl/wgl_api_unittest.cc b/ui/gl/wgl_api_unittest.cc index 65fed32..041d3dfa 100644 --- a/ui/gl/wgl_api_unittest.cc +++ b/ui/gl/wgl_api_unittest.cc
@@ -25,8 +25,7 @@ g_driver_wgl.fn.wglGetExtensionsStringARBFn = &FakeGetExtensionsStringARB; g_driver_wgl.fn.wglGetExtensionsStringEXTFn = &FakeGetExtensionsStringEXT; SetGLImplementation(kGLImplementationDesktopGL); - SetGLGetProcAddressProc( - static_cast<GLGetProcAddressProc>(&FakeGLGetProcAddress)); + SetGLGetProcAddressProc(&FakeGLGetProcAddress); } void TearDown() override { @@ -65,7 +64,7 @@ stringify(wglGetExtensionsStringEXT())); } - static void* GL_BINDING_CALL FakeGLGetProcAddress(const char *proc) { + static GLFunctionPointerType WINAPI FakeGLGetProcAddress(const char* proc) { return NULL; }
diff --git a/ui/ozone/platform/cast/surface_factory_cast.cc b/ui/ozone/platform/cast/surface_factory_cast.cc index 21ff4a2..04e3cfa 100644 --- a/ui/ozone/platform/cast/surface_factory_cast.cc +++ b/ui/ozone/platform/cast/surface_factory_cast.cc
@@ -321,7 +321,8 @@ void* lib_egl = egl_platform_->GetEglLibrary(); void* lib_gles2 = egl_platform_->GetGles2Library(); - gl::GLGetProcAddressProc gl_proc = egl_platform_->GetGLProcAddressProc(); + gl::GLGetProcAddressProc gl_proc = reinterpret_cast<gl::GLGetProcAddressProc>( + egl_platform_->GetGLProcAddressProc()); if (!lib_egl || !lib_gles2 || !gl_proc) { return false; }
diff --git a/ui/views/mus/BUILD.gn b/ui/views/mus/BUILD.gn index 884ea98..f891743b 100644 --- a/ui/views/mus/BUILD.gn +++ b/ui/views/mus/BUILD.gn
@@ -72,7 +72,7 @@ "//ui/native_theme", "//ui/platform_window", "//ui/platform_window/mojo", - "//ui/platform_window/mojo:interfaces_cpp_sources", + "//ui/platform_window/mojo:interfaces", "//ui/platform_window/stub", "//ui/views", "//ui/wm",