Skip to content

Commit

Permalink
[CSC][Lens]Add network prewarming request on right click
Browse files Browse the repository at this point in the history
Bug: 1479730
Change-Id: I2f4ec7b7ebe946fd961188bba4613aeeedc4f159
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4846723
Reviewed-by: Tarun Bansal <tbansal@chromium.org>
Commit-Queue: Jason Hu <hujasonx@google.com>
Reviewed-by: Avi Drissman <avi@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1196741}
  • Loading branch information
hujasonx authored and Chromium LUCI CQ committed Sep 14, 2023
1 parent a627f86 commit 8ead2f6
Show file tree
Hide file tree
Showing 7 changed files with 244 additions and 1 deletion.
16 changes: 16 additions & 0 deletions chrome/browser/companion/core/utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,22 @@ std::string GetImageUploadURLForCompanion() {
return url;
}

bool GetShouldIssuePreconnectForCompanion() {
return base::GetFieldTrialParamByFeatureAsBool(
*GetFeatureToUse(), "companion-issue-preconnect", true);
}

std::string GetPreconnectKeyForCompanion() {
// Allow multiple field trials to control the value. This is needed because
// companion may be enabled by any of the field trials.
std::string url = base::GetFieldTrialParamValueByFeature(
*GetFeatureToUse(), "companion-preconnect-key");
if (url.empty()) {
return std::string("chrome-untrusted://companion-side-panel.top-chrome");
}
return url;
}

bool ShouldEnableOpenCompanionForImageSearch() {
// Allow multiple field trials to control the value. This is needed because
// companion may be enabled by any of the field trials.
Expand Down
2 changes: 2 additions & 0 deletions chrome/browser/companion/core/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ namespace companion {

std::string GetHomepageURLForCompanion();
std::string GetImageUploadURLForCompanion();
bool GetShouldIssuePreconnectForCompanion();
std::string GetPreconnectKeyForCompanion();
bool ShouldEnableOpenCompanionForImageSearch();
bool ShouldEnableOpenCompanionForWebSearch();
bool ShouldOpenLinksInCurrentTab();
Expand Down
57 changes: 57 additions & 0 deletions chrome/browser/renderer_context_menu/render_view_context_menu.cc
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include "chrome/browser/browser_features.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/companion/core/features.h"
#include "chrome/browser/companion/core/utils.h"
#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
#include "chrome/browser/devtools/devtools_window.h"
#include "chrome/browser/download/download_prefs.h"
Expand All @@ -51,9 +52,15 @@
#include "chrome/browser/feed/web_feed_ui_util.h"
#include "chrome/browser/language/language_model_manager_factory.h"
#include "chrome/browser/media/router/media_router_feature.h"
#include "chrome/browser/navigation_predictor/navigation_predictor_features.h"
#include "chrome/browser/navigation_predictor/navigation_predictor_keyed_service.h"
#include "chrome/browser/navigation_predictor/navigation_predictor_keyed_service_factory.h"
#include "chrome/browser/password_manager/chrome_password_manager_client.h"
#include "chrome/browser/platform_util.h"
#include "chrome/browser/predictors/loading_predictor.h"
#include "chrome/browser/predictors/loading_predictor_factory.h"
#include "chrome/browser/prefs/incognito_mode_prefs.h"
#include "chrome/browser/preloading/preloading_prefs.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_attributes_entry.h"
#include "chrome/browser/profiles/profile_attributes_storage.h"
Expand Down Expand Up @@ -181,6 +188,7 @@
#include "extensions/buildflags/buildflags.h"
#include "media/base/media_switches.h"
#include "mojo/public/cpp/bindings/associated_remote.h"
#include "net/base/network_anonymization_key.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "pdf/buildflags.h"
#include "ppapi/buildflags/buildflags.h"
Expand Down Expand Up @@ -1002,6 +1010,30 @@ void RenderViewContextMenu::WriteURLToClipboard(const GURL& url) {
scw.WriteText(FormatURLForClipboard(url));
}

void RenderViewContextMenu::IssuePreconnectionToUrl(
const std::string& anonymization_key_url,
const std::string& preconnect_url) {
Profile* profile = Profile::FromBrowserContext(browser_context_);
if (prefetch::IsSomePreloadingEnabled(*profile->GetPrefs()) !=
content::PreloadingEligibility::kEligible) {
return;
}

auto* loading_predictor =
predictors::LoadingPredictorFactory::GetForProfile(profile);
if (!loading_predictor) {
return;
}

GURL anonymization_key_gurl(anonymization_key_url);
net::SchemefulSite anonymization_key_schemeful_site(anonymization_key_gurl);
auto network_anonymziation_key = net::NetworkAnonymizationKey::CreateSameSite(
anonymization_key_schemeful_site);
loading_predictor->PreconnectURLIfAllowed(GURL(preconnect_url),
/*allow_credentials=*/true,
network_anonymziation_key);
}

bool RenderViewContextMenu::IsInProgressiveWebApp() const {
const Browser* browser = GetBrowser();
return browser && (browser->is_type_app() || browser->is_type_app_popup());
Expand Down Expand Up @@ -1875,6 +1907,18 @@ void RenderViewContextMenu::AppendSearchWebForImageItems() {
menu_model_.SetIsNewFeatureAt(menu_model_.GetItemCount() - 1, true);
}

if (search::DefaultSearchProviderIsGoogle(GetProfile())) {
if (companion::IsSearchImageInCompanionSidePanelSupported(GetBrowser()) &&
companion::GetShouldIssuePreconnectForCompanion()) {
IssuePreconnectionToUrl(companion::GetPreconnectKeyForCompanion(),
companion::GetImageUploadURLForCompanion());
} else if (base::FeatureList::IsEnabled(lens::features::kLensStandalone) &&
lens::features::GetShouldIssuePreconnectForLens()) {
IssuePreconnectionToUrl(lens::features::GetPreconnectKeyForLens(),
lens::features::GetHomepageURLForLens());
}
}

if (base::FeatureList::IsEnabled(lens::features::kLensStandalone) &&
base::FeatureList::IsEnabled(lens::features::kEnableImageTranslate) &&
provider && !provider->image_translate_url().empty() &&
Expand Down Expand Up @@ -2473,6 +2517,19 @@ void RenderViewContextMenu::AppendRegionSearchItem() {
companion::IsSearchImageInCompanionSidePanelSupported(GetBrowser())) {
menu_model_.SetIsNewFeatureAt(menu_model_.GetItemCount() - 1, true);
}

if (search::DefaultSearchProviderIsGoogle(GetProfile())) {
if (companion::IsSearchImageInCompanionSidePanelSupported(GetBrowser()) &&
companion::GetShouldIssuePreconnectForCompanion()) {
IssuePreconnectionToUrl(companion::GetPreconnectKeyForCompanion(),
companion::GetImageUploadURLForCompanion());
} else if (base::FeatureList::IsEnabled(
lens::features::kLensStandalone) &&
lens::features::GetShouldIssuePreconnectForLens()) {
IssuePreconnectionToUrl(lens::features::GetPreconnectKeyForLens(),
lens::features::GetHomepageURLForLens());
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,10 @@ class RenderViewContextMenu
// Writes the specified text/url to the system clipboard.
void WriteURLToClipboard(const GURL& url);

// Issues a preconnection request to the given url.
void IssuePreconnectionToUrl(const std::string& anonymization_key_url,
const std::string& preconnect_url);

// RenderViewContextMenuBase:
void InitMenu() override;
void RecordShownItem(int id, bool is_submenu) override;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,13 @@
#include "chrome/browser/extensions/test_extension_environment.h"
#include "chrome/browser/extensions/test_extension_prefs.h"
#include "chrome/browser/feed/web_feed_tab_helper.h"
#include "chrome/browser/navigation_predictor/navigation_predictor_keyed_service.h"
#include "chrome/browser/navigation_predictor/navigation_predictor_keyed_service_factory.h"
#include "chrome/browser/password_manager/chrome_password_manager_client.h"
#include "chrome/browser/password_manager/password_store_factory.h"
#include "chrome/browser/predictors/loading_predictor.h"
#include "chrome/browser/predictors/loading_predictor_factory.h"
#include "chrome/browser/predictors/preconnect_manager.h"
#include "chrome/browser/prefs/incognito_mode_prefs.h"
#include "chrome/browser/renderer_context_menu/render_view_context_menu_test_util.h"
#include "chrome/browser/search_engines/template_url_service_factory.h"
Expand Down Expand Up @@ -540,7 +545,9 @@ TEST_F(RenderViewContextMenuDeveloperItemsTest,
}
#endif // BUILDFLAG(IS_CHROMEOS_ASH)

class RenderViewContextMenuPrefsTest : public ChromeRenderViewHostTestHarness {
class RenderViewContextMenuPrefsTest
: public ChromeRenderViewHostTestHarness,
public predictors::PreconnectManager::Observer {
public:
RenderViewContextMenuPrefsTest() = default;

Expand Down Expand Up @@ -578,6 +585,24 @@ class RenderViewContextMenuPrefsTest : public ChromeRenderViewHostTestHarness {
-> std::unique_ptr<KeyedService> {
return std::make_unique<syncer::TestSyncService>();
}));
last_preresolved_url_ = GURL();
}

// Begins listening for loading preconnections.
void BeginPreresolveListening() {
auto* loading_predictor =
predictors::LoadingPredictorFactory::GetForProfile(
GetBrowser()->profile());
ASSERT_TRUE(loading_predictor);
loading_predictor->preconnect_manager()->SetObserverForTesting(this);
last_preresolved_url_ = GURL();
}

void OnPreresolveFinished(
const GURL& url,
const net::NetworkAnonymizationKey& network_anonymization_key,
bool success) override {
last_preresolved_url_ = url;
}

void TearDown() override {
Expand Down Expand Up @@ -652,11 +677,14 @@ class RenderViewContextMenuPrefsTest : public ChromeRenderViewHostTestHarness {
return browser_.get();
}

const GURL& last_preresolved_url() const { return last_preresolved_url_; }

private:
std::unique_ptr<custom_handlers::ProtocolHandlerRegistry> registry_;
std::unique_ptr<ScopedTestingLocalState> testing_local_state_;
raw_ptr<TemplateURLService, DanglingUntriaged> template_url_service_;
std::unique_ptr<Browser> browser_;
GURL last_preresolved_url_;
};

// Verifies when Incognito Mode is not available (disabled by policy),
Expand Down Expand Up @@ -1646,6 +1674,118 @@ TEST_F(RenderViewContextMenuPrefsTest, LensRegionSearchChromeUIScheme) {
EXPECT_FALSE(menu.IsItemPresent(IDC_CONTENT_CONTEXT_LENS_REGION_SEARCH));
}

// Verify that the adding the companion image search option to the menu
// issues a preconnection request to lens.google.com.
TEST_F(RenderViewContextMenuPrefsTest,
CompanionImageSearchIssuesGoogleLensPreconnect) {
BeginPreresolveListening();
base::test::ScopedFeatureList features;
features.InitWithFeaturesAndParameters(
{{companion::features::internal::kSidePanelCompanion,
{{"open-companion-for-image-search", "true"}}}},
{});
SetUserSelectedDefaultSearchProvider("https://www.google.com",
/*supports_image_search=*/true);
content::ContextMenuParams params = CreateParams(MenuItem::IMAGE);
params.has_image_contents = true;
TestRenderViewContextMenu menu(*web_contents()->GetPrimaryMainFrame(),
params);
menu.SetBrowser(GetBrowser());
menu.Init();

size_t index = 0;
ui::MenuModel* model = nullptr;

ASSERT_TRUE(menu.GetMenuModelAndItemIndex(
IDC_CONTENT_CONTEXT_SEARCHLENSFORIMAGE, &model, &index));

base::RunLoop().RunUntilIdle();
ASSERT_EQ(last_preresolved_url().spec(), "https://lens.google.com/");
}

// Verify that the adding the companion region search option to the menu
// issues a preconnection request to lens.google.com.
TEST_F(RenderViewContextMenuPrefsTest,
CompanionRegionSearchIssuesGoogleLensPreconnect) {
BeginPreresolveListening();
base::test::ScopedFeatureList features;
features.InitWithFeaturesAndParameters(
{{companion::features::internal::kSidePanelCompanion,
{{"open-companion-for-image-search", "true"}}}},
{});
SetUserSelectedDefaultSearchProvider("https://www.google.com",
/*supports_image_search=*/true);
content::ContextMenuParams params = CreateParams(MenuItem::PAGE);

TestRenderViewContextMenu menu(*web_contents()->GetPrimaryMainFrame(),
params);
menu.SetBrowser(GetBrowser());
menu.Init();

size_t index = 0;
ui::MenuModel* model = nullptr;

ASSERT_TRUE(menu.GetMenuModelAndItemIndex(
IDC_CONTENT_CONTEXT_LENS_REGION_SEARCH, &model, &index));
EXPECT_TRUE(menu.IsItemPresent(IDC_CONTENT_CONTEXT_LENS_REGION_SEARCH));

base::RunLoop().RunUntilIdle();
ASSERT_EQ(last_preresolved_url().spec(), "https://lens.google.com/");
}

// Verify that the adding the Lens image search option to the menu
// issues a preconnection request to lens.google.com.
TEST_F(RenderViewContextMenuPrefsTest,
LensImageSearchIssuesGoogleLensPreconnect) {
BeginPreresolveListening();
base::test::ScopedFeatureList features;
features.InitAndEnableFeature(lens::features::kLensStandalone);
SetUserSelectedDefaultSearchProvider("https://www.google.com",
/*supports_image_search=*/true);
content::ContextMenuParams params = CreateParams(MenuItem::IMAGE);
params.has_image_contents = true;
TestRenderViewContextMenu menu(*web_contents()->GetPrimaryMainFrame(),
params);
menu.SetBrowser(GetBrowser());
menu.Init();

size_t index = 0;
ui::MenuModel* model = nullptr;

ASSERT_TRUE(menu.GetMenuModelAndItemIndex(
IDC_CONTENT_CONTEXT_SEARCHLENSFORIMAGE, &model, &index));

base::RunLoop().RunUntilIdle();
ASSERT_EQ(last_preresolved_url().spec(), "https://lens.google.com/");
}

// Verify that the adding the Lens region search option to the menu
// issues a preconnection request to lens.google.com.
TEST_F(RenderViewContextMenuPrefsTest,
LensRegionSearchIssuesGoogleLensPreconnect) {
BeginPreresolveListening();
base::test::ScopedFeatureList features;
features.InitAndEnableFeature(lens::features::kLensStandalone);
SetUserSelectedDefaultSearchProvider("https://www.google.com",
/*supports_image_search=*/true);
content::ContextMenuParams params = CreateParams(MenuItem::PAGE);

TestRenderViewContextMenu menu(*web_contents()->GetPrimaryMainFrame(),
params);
menu.SetBrowser(GetBrowser());
menu.Init();

size_t index = 0;
ui::MenuModel* model = nullptr;

ASSERT_TRUE(menu.GetMenuModelAndItemIndex(
IDC_CONTENT_CONTEXT_LENS_REGION_SEARCH, &model, &index));
EXPECT_TRUE(menu.IsItemPresent(IDC_CONTENT_CONTEXT_LENS_REGION_SEARCH));

base::RunLoop().RunUntilIdle();
ASSERT_EQ(last_preresolved_url().spec(), "https://lens.google.com/");
}

// Verify that the new badge is added to region search context menu items if
// appropriate feature is enabled.
TEST_F(RenderViewContextMenuPrefsTest,
Expand Down
14 changes: 14 additions & 0 deletions components/lens/lens_features.cc
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ constexpr base::FeatureParam<bool>
&kLensStandalone, "dismiss-loading-state-on-navigation-entry-committed",
true};

constexpr base::FeatureParam<bool> kShouldIssuePreconnectForLens{
&kLensStandalone, "lens-issue-preconnect", true};

constexpr base::FeatureParam<std::string> kPreconnectKeyForLens{
&kLensStandalone, "lens-preconnect-key", "https://google.com"};

constexpr base::FeatureParam<bool> kDismissLoadingStateOnDidFinishLoad{
&kLensStandalone, "dismiss-loading-state-on-did-finish-load", false};

Expand Down Expand Up @@ -237,5 +243,13 @@ bool GetLensPingIsSequential() {
return kPingLensSequentially.Get();
}

bool GetShouldIssuePreconnectForLens() {
return kShouldIssuePreconnectForLens.Get();
}

std::string GetPreconnectKeyForLens() {
return kPreconnectKeyForLens.Get();
}

} // namespace features
} // namespace lens
10 changes: 10 additions & 0 deletions components/lens/lens_features.h
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,16 @@ extern std::string GetLensPingURL();
// Returns whether or not the Lens ping should be done sequentially.
COMPONENT_EXPORT(LENS_FEATURES)
extern bool GetLensPingIsSequential();

// Returns whether to issue Lens preconnect requests when the
// context menu item is shown.
COMPONENT_EXPORT(LENS_FEATURES)
extern bool GetShouldIssuePreconnectForLens();

// Returns the preconnect url to use for when the context menu item
// is shown.
COMPONENT_EXPORT(LENS_FEATURES)
extern std::string GetPreconnectKeyForLens();
} // namespace features
} // namespace lens

Expand Down

0 comments on commit 8ead2f6

Please sign in to comment.