Commit 1301839d authored by Thomas Lukaszewicz's avatar Thomas Lukaszewicz Committed by Commit Bot

Tab Search: Add ability for WebUI to notify the backend when ready

This CL introduces a new method on the TabSearchHandler that allows
the WebUI to notify the backend when the UI has finished rendering
and is ready to be shown.

This will help in eliminating the current UI stutter that occurs as a
result of the UI resizing to fit the dynamically loading content.

A follow up CL integrates this API with the TabSearchBubbleView.

Bug: 1099917
Change-Id: Ie9679952dc5790d64d61e84840f144b46b66a710
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2386425Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarJohn Lee <johntlee@chromium.org>
Commit-Queue: Thomas Lukaszewicz <tluk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#803569}
parent 7aaf7617
......@@ -69,6 +69,9 @@ interface PageHandler {
// Switch to a specific tab.
SwitchToTab(SwitchToTabInfo switch_to_tab_info);
// Notify the backend that the UI is ready to be shown.
ShowUI();
};
// WebUI-side handler for requests from the browser.
......
......@@ -31,11 +31,13 @@ constexpr base::TimeDelta kTabsChangeDelay =
TabSearchPageHandler::TabSearchPageHandler(
mojo::PendingReceiver<tab_search::mojom::PageHandler> receiver,
mojo::PendingRemote<tab_search::mojom::Page> page,
content::WebUI* web_ui)
content::WebUI* web_ui,
Delegate* delegate)
: receiver_(this, std::move(receiver)),
page_(std::move(page)),
browser_(chrome::FindLastActive()),
web_ui_(web_ui),
delegate_(delegate),
debounce_timer_(std::make_unique<base::RetainingOneShotTimer>(
FROM_HERE,
kTabsChangeDelay,
......@@ -149,6 +151,10 @@ void TabSearchPageHandler::SwitchToTab(
details.browser->window()->Activate();
}
void TabSearchPageHandler::ShowUI() {
delegate_->ShowUI();
}
tab_search::mojom::TabPtr TabSearchPageHandler::GetTabData(
TabStripModel* tab_strip_model,
content::WebContents* contents,
......
......@@ -33,10 +33,16 @@ class TabSearchPageHandler : public tab_search::mojom::PageHandler,
public TabStripModelObserver,
public BrowserTabStripTrackerDelegate {
public:
class Delegate {
public:
virtual void ShowUI() = 0;
};
TabSearchPageHandler(
mojo::PendingReceiver<tab_search::mojom::PageHandler> receiver,
mojo::PendingRemote<tab_search::mojom::Page> page,
content::WebUI* web_ui);
content::WebUI* web_ui,
Delegate* delegate);
TabSearchPageHandler(const TabSearchPageHandler&) = delete;
TabSearchPageHandler& operator=(const TabSearchPageHandler&) = delete;
~TabSearchPageHandler() override;
......@@ -48,6 +54,7 @@ class TabSearchPageHandler : public tab_search::mojom::PageHandler,
void ShowFeedbackPage() override;
void SwitchToTab(
tab_search::mojom::SwitchToTabInfoPtr switch_to_tab_info) override;
void ShowUI() override;
// TabStripModelObserver:
void OnTabStripModelChanged(
......@@ -92,6 +99,7 @@ class TabSearchPageHandler : public tab_search::mojom::PageHandler,
mojo::Remote<tab_search::mojom::Page> page_;
Browser* const browser_;
content::WebUI* const web_ui_;
Delegate* const delegate_;
BrowserTabStripTracker browser_tab_strip_tracker_{this, this};
std::unique_ptr<base::RetainingOneShotTimer> debounce_timer_;
......
......@@ -79,11 +79,13 @@ void ExpectProfileTabs(tab_search::mojom::ProfileTabs* profile_tabs) {
class TestTabSearchPageHandler : public TabSearchPageHandler {
public:
TestTabSearchPageHandler(mojo::PendingRemote<tab_search::mojom::Page> page,
content::WebUI* web_ui)
content::WebUI* web_ui,
TabSearchPageHandler::Delegate* delegate)
: TabSearchPageHandler(
mojo::PendingReceiver<tab_search::mojom::PageHandler>(),
std::move(page),
web_ui) {
web_ui,
delegate) {
mock_debounce_timer_ = new base::MockRetainingOneShotTimer();
SetTimerForTesting(base::WrapUnique(mock_debounce_timer_));
}
......@@ -95,6 +97,14 @@ class TestTabSearchPageHandler : public TabSearchPageHandler {
base::MockRetainingOneShotTimer* mock_debounce_timer_;
};
class MockTabSearchPageHandlerDelegate : public TabSearchPageHandler::Delegate {
public:
MockTabSearchPageHandlerDelegate() = default;
virtual ~MockTabSearchPageHandlerDelegate() = default;
MOCK_METHOD(void, ShowUI, (), (override));
};
class TabSearchPageHandlerTest : public BrowserWithTestWindowTest {
public:
void SetUp() override {
......@@ -107,8 +117,9 @@ class TabSearchPageHandlerTest : public BrowserWithTestWindowTest {
CreateTestBrowser(browser()->profile()->GetPrimaryOTRProfile(), false);
browser4_ = CreateTestBrowser(profile2(), false);
BrowserList::SetLastActive(browser1());
handler_delegate_ = std::make_unique<MockTabSearchPageHandlerDelegate>();
handler_ = std::make_unique<TestTabSearchPageHandler>(
page_.BindAndGetRemote(), web_ui());
page_.BindAndGetRemote(), web_ui(), handler_delegate_.get());
}
void TearDown() override {
......@@ -139,6 +150,9 @@ class TabSearchPageHandlerTest : public BrowserWithTestWindowTest {
Browser* browser4() { return browser4_.get(); }
TestTabSearchPageHandler* handler() { return handler_.get(); }
MockTabSearchPageHandlerDelegate* handler_delegate() {
return handler_delegate_.get();
}
void FireTimer() { handler_->mock_debounce_timer()->Fire(); }
bool IsTimerRunning() { return handler_->mock_debounce_timer()->IsRunning(); }
......@@ -171,6 +185,7 @@ class TabSearchPageHandlerTest : public BrowserWithTestWindowTest {
std::unique_ptr<Browser> browser3_;
std::unique_ptr<Browser> browser4_;
std::unique_ptr<TestTabSearchPageHandler> handler_;
std::unique_ptr<MockTabSearchPageHandlerDelegate> handler_delegate_;
};
TEST_F(TabSearchPageHandlerTest, GetTabs) {
......@@ -331,4 +346,10 @@ TEST_F(TabSearchPageHandlerTest, ShowFeedbackPage) {
histogram_tester.ExpectTotalCount("Feedback.RequestSource", 1);
}
// Make sure the delegate receives the ShowUI() call.
TEST_F(TabSearchPageHandlerTest, ShowUITest) {
EXPECT_CALL(*handler_delegate(), ShowUI()).Times(1);
handler()->ShowUI();
}
} // namespace
......@@ -56,10 +56,19 @@ void TabSearchUI::BindInterface(
page_factory_receiver_.Bind(std::move(receiver));
}
void TabSearchUI::AddShowUICallback(base::OnceClosure callback) {
show_ui_callback_ = std::move(callback);
}
void TabSearchUI::ShowUI() {
if (show_ui_callback_)
std::move(show_ui_callback_).Run();
}
void TabSearchUI::CreatePageHandler(
mojo::PendingRemote<tab_search::mojom::Page> page,
mojo::PendingReceiver<tab_search::mojom::PageHandler> receiver) {
DCHECK(page);
page_handler_ = std::make_unique<TabSearchPageHandler>(
std::move(receiver), std::move(page), web_ui());
std::move(receiver), std::move(page), web_ui(), this);
}
......@@ -7,35 +7,35 @@
#include <memory>
#include "base/callback_forward.h"
#include "base/macros.h"
#include "chrome/browser/ui/webui/tab_search/tab_search.mojom.h"
#include "chrome/browser/ui/webui/tab_search/tab_search_page_handler.h"
#include "chrome/browser/ui/webui/webui_load_timer.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "ui/webui/mojo_web_ui_controller.h"
class Browser;
class TabSearchUIEmbedder;
class TabSearchPageHandler;
class TabSearchUI : public ui::MojoWebUIController,
public tab_search::mojom::PageHandlerFactory {
public tab_search::mojom::PageHandlerFactory,
public TabSearchPageHandler::Delegate {
public:
explicit TabSearchUI(content::WebUI* web_ui);
TabSearchUI(const TabSearchUI&) = delete;
TabSearchUI& operator=(const TabSearchUI&) = delete;
~TabSearchUI() override;
// Initialize TabSearchUI by passing in the current browser and the
// current embedder, the WebUI won't work until this is called.
void Initialize(Browser* browser, TabSearchUIEmbedder* embedder);
// Instantiates the implementor of the mojom::PageHandlerFactory mojo
// interface passing the pending receiver that will be internally bound.
void BindInterface(
mojo::PendingReceiver<tab_search::mojom::PageHandlerFactory> receiver);
void AddShowUICallback(base::OnceClosure callback);
// TabSearchPageHandler::Delegate:
void ShowUI() override;
private:
// tab_search::mojom::PageHandlerFactory
void CreatePageHandler(
......@@ -49,6 +49,10 @@ class TabSearchUI : public ui::MojoWebUIController,
WebuiLoadTimer webui_load_timer_;
// This is called when the renderer process indicates that the UI is ready to
// be shown.
base::OnceClosure show_ui_callback_;
WEB_UI_CONTROLLER_TYPE_DECL();
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment