Skip to content

Commit

Permalink
CustomizeChrome: Create Customize Chrome Tab Helper and Controller
Browse files Browse the repository at this point in the history
This CL creates a tab helper and controller for the customize chrome side panel. These classes will help delegate responsibilities for registering and showing the customize chrome side panel on the NTP. The controller class contains the logic for registering/deregistering the customize chrome entry.

The actual registering of the side panel when on the NTP and triggering from the "Customize Chrome" button is in this follow-up CL: https://chromium-review.googlesource.com/c/chromium/src/+/3812725

Bug: 1350246
Change-Id: I45c21db07e50e64dddf5d6ebf60145d379c812ae
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3806854
Commit-Queue: Nihar Majmudar <niharm@google.com>
Reviewed-by: Thomas Lukaszewicz <tluk@chromium.org>
Reviewed-by: Avi Drissman <avi@chromium.org>
Reviewed-by: John Lee <johntlee@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1034056}
  • Loading branch information
Nihar Majmudar authored and Chromium LUCI CQ committed Aug 11, 2022
1 parent e41269b commit b938b59
Show file tree
Hide file tree
Showing 17 changed files with 329 additions and 1 deletion.
3 changes: 3 additions & 0 deletions chrome/app/generated_resources.grd
Expand Up @@ -7062,6 +7062,9 @@ Keep your key file in a safe place. You will need it to create new versions of y
<message name="IDS_ACCNAME_SIDE_PANEL_RESIZE" is_accessibility_with_no_ui="true" desc="Screen reader announcement when the side panel resize handle is focused.">
Side Panel Resize Handle
</message>
<message name="IDS_SIDE_PANEL_CUSTOMIZE_CHROME_TITLE" desc="The name of the Customize Chrome feature in the side panel combo box.">
Customize Chrome
</message>

<!-- Read Anything strings -->
<!-- TODO(crbug.com/1266555): Add final strings and make them translateable. -->
Expand Down
@@ -0,0 +1 @@
9b6e2f21db794747e0a7052282b9e9abb972505d
6 changes: 6 additions & 0 deletions chrome/browser/ui/BUILD.gn
Expand Up @@ -4099,6 +4099,9 @@ static_library("ui") {
"sharing_hub/screenshot/screenshot_captured_bubble_controller.h",
"sharing_hub/sharing_hub_bubble_controller.h",
"sharing_hub/sharing_hub_bubble_view.h",
"side_panel/customize_chrome/customize_chrome_side_panel_controller_utils.h",
"side_panel/customize_chrome/customize_chrome_tab_helper.cc",
"side_panel/customize_chrome/customize_chrome_tab_helper.h",
"views/send_tab_to_self/send_tab_to_self_bubble.cc",
"views/send_tab_to_self/send_tab_to_self_bubble_controller.cc",
"views/send_tab_to_self/send_tab_to_self_bubble_controller.h",
Expand Down Expand Up @@ -4842,6 +4845,9 @@ static_library("ui") {
"views/shopping_bubble/shopping_prompt_impl.h",
"views/side_panel/bookmarks/bookmarks_side_panel_coordinator.cc",
"views/side_panel/bookmarks/bookmarks_side_panel_coordinator.h",
"views/side_panel/customize_chrome/customize_chrome_side_panel_controller.cc",
"views/side_panel/customize_chrome/customize_chrome_side_panel_controller.h",
"views/side_panel/customize_chrome/customize_chrome_side_panel_controller_utils.cc",
"views/side_panel/feed/feed_side_panel_coordinator.cc",
"views/side_panel/feed/feed_side_panel_coordinator.h",
"views/side_panel/history_clusters/history_clusters_side_panel_coordinator.cc",
Expand Down
@@ -0,0 +1,14 @@
// Copyright 2022 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 CHROME_BROWSER_UI_SIDE_PANEL_CUSTOMIZE_CHROME_CUSTOMIZE_CHROME_SIDE_PANEL_CONTROLLER_UTILS_H_
#define CHROME_BROWSER_UI_SIDE_PANEL_CUSTOMIZE_CHROME_CUSTOMIZE_CHROME_SIDE_PANEL_CONTROLLER_UTILS_H_

#include "chrome/browser/ui/side_panel/customize_chrome/customize_chrome_tab_helper.h"

namespace customize_chrome {
std::unique_ptr<CustomizeChromeTabHelper::Delegate> CreateDelegate();
} // namespace customize_chrome

#endif // CHROME_BROWSER_UI_SIDE_PANEL_CUSTOMIZE_CHROME_CUSTOMIZE_CHROME_SIDE_PANEL_CONTROLLER_UTLS_H_
@@ -0,0 +1,26 @@
// Copyright 2022 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 "chrome/browser/ui/side_panel/customize_chrome/customize_chrome_tab_helper.h"

#include "chrome/browser/ui/side_panel/customize_chrome/customize_chrome_side_panel_controller_utils.h"

CustomizeChromeTabHelper::~CustomizeChromeTabHelper() = default;

void CustomizeChromeTabHelper::CreateAndRegisterEntry() {
DCHECK(delegate_);
delegate_->CreateAndRegisterEntry(&WebContentsUserData::GetWebContents());
}

void CustomizeChromeTabHelper::DeregisterEntry() {
DCHECK(delegate_);
delegate_->DeregisterEntry(&WebContentsUserData::GetWebContents());
}

CustomizeChromeTabHelper::CustomizeChromeTabHelper(
content::WebContents* web_contents)
: content::WebContentsUserData<CustomizeChromeTabHelper>(*web_contents),
delegate_(customize_chrome::CreateDelegate()) {}

WEB_CONTENTS_USER_DATA_KEY_IMPL(CustomizeChromeTabHelper);
@@ -0,0 +1,49 @@
// Copyright 2022 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 CHROME_BROWSER_UI_SIDE_PANEL_CUSTOMIZE_CHROME_CUSTOMIZE_CHROME_TAB_HELPER_H_
#define CHROME_BROWSER_UI_SIDE_PANEL_CUSTOMIZE_CHROME_CUSTOMIZE_CHROME_TAB_HELPER_H_

#include "content/public/browser/web_contents_user_data.h"

namespace content {
class WebContents;
} // namespace content

// An observer of WebContents that facilitates the logic for the customize
// chrome side panel. This per-tab class also owns the
// CustomizeChromeSidePanelController.
class CustomizeChromeTabHelper
: public content::WebContentsUserData<CustomizeChromeTabHelper> {
public:
// This class delegates the responsibility for registering and deregistering
// the Customize Chrome side panel.
class Delegate {
public:
virtual void CreateAndRegisterEntry(content::WebContents* web_contents) = 0;
virtual void DeregisterEntry(content::WebContents* web_contents) = 0;
virtual ~Delegate() = default;
};

CustomizeChromeTabHelper(const CustomizeChromeTabHelper&) = delete;
CustomizeChromeTabHelper& operator=(const CustomizeChromeTabHelper&) = delete;
~CustomizeChromeTabHelper() override;

// Creates a WebUISidePanelView for Customize Chrome and registers
// the customize chrome side panel entry.
void CreateAndRegisterEntry();

// Deregisters the customize chrome side panel entry.
void DeregisterEntry();

private:
friend class content::WebContentsUserData<CustomizeChromeTabHelper>;
explicit CustomizeChromeTabHelper(content::WebContents* web_contents);

std::unique_ptr<Delegate> delegate_;

WEB_CONTENTS_USER_DATA_KEY_DECL();
};

#endif // CHROME_BROWSER_UI_SIDE_PANEL_CUSTOMIZE_CHROME_CUSTOMIZE_CHROME_TAB_HELPER_H_
10 changes: 10 additions & 0 deletions chrome/browser/ui/tab_helpers.cc
Expand Up @@ -133,6 +133,7 @@
#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer.h"
#include "components/safe_browsing/content/browser/safe_browsing_tab_observer.h"
#include "components/safe_browsing/core/common/features.h"
#include "components/search/ntp_features.h"
#include "components/segmentation_platform/content/segmentation_platform_tab_helper.h"
#include "components/site_engagement/content/site_engagement_helper.h"
#include "components/site_engagement/content/site_engagement_service.h"
Expand Down Expand Up @@ -177,6 +178,10 @@
#include "components/zoom/zoom_controller.h"
#endif // BUILDFLAG(IS_ANDROID)

#if !BUILDFLAG(IS_ANDROID)
#include "chrome/browser/ui/side_panel/customize_chrome/customize_chrome_tab_helper.h"
#endif

#if defined(TOOLKIT_VIEWS)
#include "chrome/browser/ui/side_search/side_search_tab_contents_helper.h"
#include "chrome/browser/ui/side_search/side_search_utils.h"
Expand Down Expand Up @@ -567,6 +572,11 @@ void TabHelpers::AttachTabHelpers(WebContents* web_contents) {
SideSearchTabContentsHelper::CreateForWebContents(web_contents);
#endif

#if !BUILDFLAG(IS_ANDROID)
if (base::FeatureList::IsEnabled(ntp_features::kCustomizeChromeSidePanel))
CustomizeChromeTabHelper::CreateForWebContents(web_contents);
#endif

// --- Section 3: Feature tab helpers behind BUILDFLAGs ---
// NOT for "if enabled"; put those in section 1.

Expand Down
@@ -0,0 +1,65 @@
// Copyright 2022 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 "chrome/browser/ui/views/side_panel/customize_chrome/customize_chrome_side_panel_controller.h"

#include "base/bind.h"
#include "base/callback.h"
#include "chrome/app/vector_icons/vector_icons.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/side_panel/customize_chrome/customize_chrome_tab_helper.h"
#include "chrome/browser/ui/views/side_panel/side_panel_coordinator.h"
#include "chrome/browser/ui/views/side_panel/side_panel_registry_observer.h"
#include "chrome/browser/ui/views/side_panel/side_panel_web_ui_view.h"
#include "chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_ui.h"
#include "chrome/common/webui_url_constants.h"
#include "chrome/grit/generated_resources.h"
#include "components/omnibox/browser/vector_icons.h"
#include "ui/base/l10n/l10n_util.h"

CustomizeChromeSidePanelController::CustomizeChromeSidePanelController() =
default;

CustomizeChromeSidePanelController::~CustomizeChromeSidePanelController() =
default;

void CustomizeChromeSidePanelController::CreateAndRegisterEntry(
content::WebContents* web_contents) {
auto* registry = SidePanelRegistry::Get(web_contents);

if (!registry)
return;

auto entry = std::make_unique<SidePanelEntry>(
SidePanelEntry::Id::kCustomizeChrome,
l10n_util::GetStringUTF16(IDS_SIDE_PANEL_CUSTOMIZE_CHROME_TITLE),
// Icon needs to be changed to customize chrome icon.
ui::ImageModel::FromVectorIcon(omnibox::kStarIcon, ui::kColorIcon),
base::BindRepeating(
&CustomizeChromeSidePanelController::CreateCustomizeChromeWebView,
base::Unretained(this), web_contents));
registry->Register(std::move(entry));
}

void CustomizeChromeSidePanelController::DeregisterEntry(
content::WebContents* web_contents) {
if (auto* registry = SidePanelRegistry::Get(web_contents))
registry->Deregister(SidePanelEntry::Id::kCustomizeChrome);
}

std::unique_ptr<views::View>
CustomizeChromeSidePanelController::CreateCustomizeChromeWebView(
content::WebContents* web_contents) {
auto customize_chrome_web_view =
std::make_unique<SidePanelWebUIViewT<CustomizeChromeUI>>(
base::RepeatingClosure(), base::RepeatingClosure(),
std::make_unique<BubbleContentsWrapperT<CustomizeChromeUI>>(
GURL(chrome::kChromeUICustomizeChromeSidePanelURL),
Profile::FromBrowserContext(web_contents->GetBrowserContext()),
IDS_SIDE_PANEL_CUSTOMIZE_CHROME_TITLE,
/*webui_resizes_host=*/false,
/*esc_closes_ui=*/false));
customize_chrome_web_view->ShowUI();
return customize_chrome_web_view;
}
@@ -0,0 +1,37 @@
// Copyright 2022 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 CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_CUSTOMIZE_CHROME_CUSTOMIZE_CHROME_SIDE_PANEL_CONTROLLER_H_
#define CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_CUSTOMIZE_CHROME_CUSTOMIZE_CHROME_SIDE_PANEL_CONTROLLER_H_

#include "chrome/browser/ui/side_panel/customize_chrome/customize_chrome_tab_helper.h"
#include "chrome/browser/ui/views/side_panel/side_panel_entry_observer.h"

namespace content {
class WebContents;
} // namespace content

// Responsible for implementing logic to create and register/deregister
// the side panel.
class CustomizeChromeSidePanelController
: public CustomizeChromeTabHelper::Delegate {
public:
CustomizeChromeSidePanelController();
CustomizeChromeSidePanelController(
const CustomizeChromeSidePanelController&) = delete;
CustomizeChromeSidePanelController& operator=(
const CustomizeChromeSidePanelController&) = delete;
~CustomizeChromeSidePanelController() override;

// CustomizeChromeTabHelper::Delegate
void CreateAndRegisterEntry(content::WebContents* web_contents) override;
void DeregisterEntry(content::WebContents* web_contents) override;

private:
// Creates view for side panel entry.
std::unique_ptr<views::View> CreateCustomizeChromeWebView(
content::WebContents* web_contents);
};

#endif // CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_CUSTOMIZE_CHROME_CUSTOMIZE_CHROME_SIDE_PANEL_CONTROLLER_H_
@@ -0,0 +1,89 @@
// Copyright 2021 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 "chrome/browser/ui/views/side_panel/customize_chrome/customize_chrome_side_panel_controller.h"

#include "base/test/scoped_feature_list.h"
#include "chrome/browser/ui/ui_features.h"
#include "chrome/browser/ui/views/side_panel/side_panel_registry.h"
#include "chrome/test/base/testing_profile.h"
#include "components/search/ntp_features.h"
#include "content/public/test/browser_task_environment.h"
#include "content/public/test/test_renderer_host.h"
#include "content/public/test/web_contents_tester.h"
#include "testing/gtest/include/gtest/gtest.h"

class CustomizeChromeSidePanelControllerTest : public testing::Test {
public:
// testing::Test:
void SetUp() override {
testing::Test::SetUp();
scoped_feature_list_.InitWithFeatures(
{ntp_features::kCustomizeChromeSidePanel, features::kUnifiedSidePanel},
{});
web_contents_ =
content::WebContentsTester::CreateTestWebContents(&profile_, nullptr);
}

protected:
content::WebContents* get_web_contents() { return web_contents_.get(); }

private:
content::BrowserTaskEnvironment task_environment_;
content::RenderViewHostTestEnabler rvh_enabler_;
TestingProfile profile_;
std::unique_ptr<content::WebContents> web_contents_;
base::test::ScopedFeatureList scoped_feature_list_;
};

TEST_F(CustomizeChromeSidePanelControllerTest, RegisterCustomizeChromeEntry) {
// When CreateAndRegisterEntry() is called, the current tabs side
// panel registry should contain a kCustomizeChromeEntry.
CustomizeChromeSidePanelController side_panel_controller;
content::WebContents* web_contents = get_web_contents();
side_panel_controller.CreateAndRegisterEntry(web_contents);
auto* registry = SidePanelRegistry::Get(web_contents);
EXPECT_EQ(registry->GetEntryForId(SidePanelEntry::Id::kCustomizeChrome)->id(),
SidePanelEntry::Id::kCustomizeChrome);
}

TEST_F(CustomizeChromeSidePanelControllerTest, DeregisterCustomizeChromeEntry) {
// When Deregister() is called, there should be no side panel entry
// in the registry.
CustomizeChromeSidePanelController side_panel_controller;
content::WebContents* web_contents = get_web_contents();
side_panel_controller.CreateAndRegisterEntry(web_contents);
auto* registry = SidePanelRegistry::Get(web_contents);
EXPECT_EQ(registry->GetEntryForId(SidePanelEntry::Id::kCustomizeChrome)->id(),
SidePanelEntry::Id::kCustomizeChrome);
side_panel_controller.DeregisterEntry(web_contents);
EXPECT_EQ(registry->GetEntryForId(SidePanelEntry::Id::kCustomizeChrome),
nullptr);
}

TEST_F(CustomizeChromeSidePanelControllerTest, CreateAndRegisterMultipleTimes) {
// When CreateAndRegisterEntry() is called multiple times, only
// one entry should be added to the registry.
CustomizeChromeSidePanelController side_panel_controller;
content::WebContents* web_contents = get_web_contents();
side_panel_controller.CreateAndRegisterEntry(web_contents);
auto* registry = SidePanelRegistry::Get(web_contents);
EXPECT_EQ(registry->GetEntryForId(SidePanelEntry::Id::kCustomizeChrome)->id(),
SidePanelEntry::Id::kCustomizeChrome);
side_panel_controller.CreateAndRegisterEntry(web_contents);
EXPECT_EQ(registry->GetEntryForId(SidePanelEntry::Id::kCustomizeChrome)->id(),
SidePanelEntry::Id::kCustomizeChrome);
side_panel_controller.DeregisterEntry(web_contents);
EXPECT_EQ(registry->GetEntryForId(SidePanelEntry::Id::kCustomizeChrome),
nullptr);
}

TEST_F(CustomizeChromeSidePanelControllerTest,
DeregisterEmptyCustomizeChromeEntry) {
// When there is no customize chrome entry, calling deregister should
// not crash.
CustomizeChromeSidePanelController side_panel_controller;
content::WebContents* web_contents = get_web_contents();
side_panel_controller.DeregisterEntry(web_contents);
}
@@ -0,0 +1,15 @@
// Copyright 2022 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 "chrome/browser/ui/side_panel/customize_chrome/customize_chrome_side_panel_controller_utils.h"

#include "chrome/browser/ui/views/side_panel/customize_chrome/customize_chrome_side_panel_controller.h"

namespace customize_chrome {

std::unique_ptr<CustomizeChromeTabHelper::Delegate> CreateDelegate() {
return std::make_unique<CustomizeChromeSidePanelController>();
}

} // namespace customize_chrome
1 change: 1 addition & 0 deletions chrome/browser/ui/views/side_panel/side_panel_entry.h
Expand Up @@ -37,6 +37,7 @@ class SidePanelEntry final {
kLens,
kAssistant,
kAboutThisSite,
kCustomizeChrome
};

SidePanelEntry(Id id,
Expand Down
3 changes: 2 additions & 1 deletion chrome/browser/ui/views/side_panel/side_panel_util.cc
Expand Up @@ -38,7 +38,8 @@ std::string GetHistogramNameForId(SidePanelEntry::Id id) {
{SidePanelEntry::Id::kSideSearch, "SideSearch"},
{SidePanelEntry::Id::kLens, "Lens"},
{SidePanelEntry::Id::kAssistant, "Assistant"},
{SidePanelEntry::Id::kAboutThisSite, "AboutThisSite"}});
{SidePanelEntry::Id::kAboutThisSite, "AboutThisSite"},
{SidePanelEntry::Id::kCustomizeChrome, "CustomizeChrome"}});

auto* i = id_to_histogram_name_map.find(id);
DCHECK(i != id_to_histogram_name_map.cend());
Expand Down

0 comments on commit b938b59

Please sign in to comment.