TabAndroid supports base::SupportUserData
This CL lets TabAndroid supports base::SupportUserData, then
ChromeAutocompleteProviderClient can store stripped urls in TabAndroid
to avoid stripping url over and over again.
(cherry picked from commit 4f474f7c1cfb245a2667b783a2026b73428d7e17)
Bug: 1094056
Change-Id: If0448c825965ddc7f43bd2aacc9c1d868e27b09f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2472461
Reviewed-by: Ted Choc <[email protected]>
Commit-Queue: Gang Wu <[email protected]>
Cr-Original-Commit-Position: refs/heads/master@{#818132}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2486411
Reviewed-by: Gang Wu <[email protected]>
Cr-Commit-Position: refs/branch-heads/4280@{#538}
Cr-Branched-From: ea420fb963f9658c9969b6513c56b8f47efa1a2a-refs/heads/master@{#812852}
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 8379e32d..7e37891 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -2768,6 +2768,7 @@
"android/startup_bridge.h",
"android/tab_android.cc",
"android/tab_android.h",
+ "android/tab_android_user_data.h",
"android/tab_browser_controls_constraints_helper.cc",
"android/tab_browser_controls_constraints_helper.h",
"android/tab_favicon.cc",
diff --git a/chrome/browser/android/tab_android.h b/chrome/browser/android/tab_android.h
index 2b8bcda..9226bda 100644
--- a/chrome/browser/android/tab_android.h
+++ b/chrome/browser/android/tab_android.h
@@ -15,6 +15,7 @@
#include "base/callback_forward.h"
#include "base/macros.h"
#include "base/strings/string16.h"
+#include "base/supports_user_data.h"
#include "chrome/browser/sync/glue/synced_tab_delegate_android.h"
#include "chrome/browser/tab/web_contents_state.h"
#include "components/infobars/core/infobar_manager.h"
@@ -37,7 +38,7 @@
class WebContents;
}
-class TabAndroid {
+class TabAndroid : public base::SupportsUserData {
public:
// A Java counterpart will be generated for this enum.
// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser
@@ -61,7 +62,7 @@
static void AttachTabHelpers(content::WebContents* web_contents);
TabAndroid(JNIEnv* env, const base::android::JavaRef<jobject>& obj);
- ~TabAndroid();
+ ~TabAndroid() override;
base::android::ScopedJavaLocalRef<jobject> GetJavaObject();
diff --git a/chrome/browser/android/tab_android_user_data.h b/chrome/browser/android/tab_android_user_data.h
new file mode 100644
index 0000000..bb560a7
--- /dev/null
+++ b/chrome/browser/android/tab_android_user_data.h
@@ -0,0 +1,61 @@
+// Copyright 2020 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_ANDROID_TAB_ANDROID_USER_DATA_H_
+#define CHROME_BROWSER_ANDROID_TAB_ANDROID_USER_DATA_H_
+
+#include "base/macros.h"
+#include "base/supports_user_data.h"
+#include "chrome/browser/android/tab_android.h"
+
+// A base class for classes attached to, and scoped to, the lifetime of a
+// TabAndroid. For example:
+//
+// --- in foo_tab_helper.h ---
+// class FooTabHelper : public web::TabAndroidUserData<FooTabHelper> {
+// public:
+// ~FooTabHelper() override;
+// // ... more public stuff here ...
+// private:
+// explicit FooTabHelper(web::TabAndroid* tab);
+// friend class web::TabAndroidUserData<FooTabHelper>;
+// TAB_ANDROID_USER_DATA_KEY_DECL();
+// // ... more private stuff here ...
+// };
+//
+// --- in foo_tab_helper.cc ---
+// TAB_ANDROID_USER_DATA_KEY_IMPL(FooTabHelper)
+template <typename T>
+class TabAndroidUserData : public base::SupportsUserData::Data {
+ public:
+ // Creates an object of type T, and attaches it to the specified TabAndroid.
+ // If an instance is already attached, does nothing.
+ static void CreateForTabAndroid(TabAndroid* tab) {
+ DCHECK(tab);
+ if (!FromTabAndroid(tab))
+ tab->SetUserData(UserDataKey(), base::WrapUnique(new T(tab)));
+ }
+
+ // Retrieves the instance of type T that was attached to the specified
+ // TabAndroid (via CreateForTabAndroid above) and returns it. If no instance
+ // of the type was attached, returns nullptr.
+ static T* FromTabAndroid(TabAndroid* tab) {
+ DCHECK(tab);
+ return static_cast<T*>(tab->GetUserData(UserDataKey()));
+ }
+
+ static const void* UserDataKey() { return &T::kUserDataKey; }
+};
+
+// This macro declares a static variable inside the class that inherits from
+// TabAndroidUserData The address of this static variable is used as the key to
+// store/retrieve an instance of the class on/from a TabAndroid.
+#define TAB_ANDROID_USER_DATA_KEY_DECL() static constexpr int kUserDataKey = 0
+
+// This macro instantiates the static variable declared by the previous macro.
+// It must live in a .cc file to ensure that there is only one instantiation
+// of the static variable.
+#define TAB_ANDROID_USER_DATA_KEY_IMPL(Type) const int Type::kUserDataKey;
+
+#endif // CHROME_BROWSER_ANDROID_TAB_ANDROID_USER_DATA_H_
diff --git a/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc b/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc
index 94dea2b5..e9b31cd 100644
--- a/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc
+++ b/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc
@@ -58,6 +58,7 @@
#if defined(OS_ANDROID)
#include "chrome/browser/android/tab_android.h"
+#include "chrome/browser/android/tab_android_user_data.h"
#include "chrome/browser/ui/android/tab_model/tab_model.h"
#include "chrome/browser/ui/android/tab_model/tab_model_list.h"
#else
@@ -69,7 +70,37 @@
namespace {
-#if !defined(OS_ANDROID)
+#if defined(OS_ANDROID)
+class AutocompleteClientTabAndroidUserData
+ : public TabAndroidUserData<AutocompleteClientTabAndroidUserData> {
+ public:
+ ~AutocompleteClientTabAndroidUserData() override = default;
+
+ const GURL& GetStrippedURL() { return stripped_url_; }
+
+ bool IsInitialized() { return initialized_; }
+
+ void UpdateStrippedURL(const GURL& url,
+ TemplateURLService* template_url_service) {
+ initialized_ = true;
+ if (url.is_valid()) {
+ stripped_url_ = AutocompleteMatch::GURLToStrippedGURL(
+ url, AutocompleteInput(), template_url_service, base::string16());
+ }
+ }
+
+ private:
+ explicit AutocompleteClientTabAndroidUserData(TabAndroid* tab) {}
+ friend class TabAndroidUserData<AutocompleteClientTabAndroidUserData>;
+
+ bool initialized_ = false;
+ GURL stripped_url_;
+
+ TAB_ANDROID_USER_DATA_KEY_DECL();
+};
+TAB_ANDROID_USER_DATA_KEY_IMPL(AutocompleteClientTabAndroidUserData)
+
+#else // defined(OS_ANDROID)
// This list should be kept in sync with chrome/common/webui_url_constants.h.
// Only include useful sub-pages, confirmation alerts are not useful.
const char* const kChromeSettingsSubPages[] = {
@@ -83,7 +114,47 @@
chrome::kManageProfileSubPage, chrome::kPeopleSubPage,
#endif
};
-#endif // !defined(OS_ANDROID)
+#endif // defined(OS_ANDROID)
+
+class AutocompleteClientWebContentsUserData
+ : public content::WebContentsUserData<
+ AutocompleteClientWebContentsUserData> {
+ public:
+ ~AutocompleteClientWebContentsUserData() override = default;
+
+ int GetLastCommittedEntryIndex() { return last_committed_entry_index_; }
+ const GURL& GetLastCommittedStrippedURL() {
+ return last_committed_stripped_url_;
+ }
+ void UpdateLastCommittedStrippedURL(
+ int last_committed_index,
+ const GURL& last_committed_url,
+ TemplateURLService* template_url_service) {
+ if (last_committed_url.is_valid()) {
+ last_committed_entry_index_ = last_committed_index;
+ // Use blank input since we will re-use this stripped URL with other
+ // inputs.
+ last_committed_stripped_url_ = AutocompleteMatch::GURLToStrippedGURL(
+ last_committed_url, AutocompleteInput(), template_url_service,
+ base::string16());
+ }
+ }
+
+ private:
+ explicit AutocompleteClientWebContentsUserData(
+ content::WebContents* contents);
+ friend class content::WebContentsUserData<
+ AutocompleteClientWebContentsUserData>;
+
+ int last_committed_entry_index_ = -1;
+ GURL last_committed_stripped_url_;
+ WEB_CONTENTS_USER_DATA_KEY_DECL();
+};
+
+AutocompleteClientWebContentsUserData::AutocompleteClientWebContentsUserData(
+ content::WebContents*) {}
+
+WEB_CONTENTS_USER_DATA_KEY_IMPL(AutocompleteClientWebContentsUserData)
} // namespace
@@ -392,47 +463,6 @@
url2, *input, template_url_service, base::string16());
}
-class AutocompleteClientWebContentsUserData
- : public content::WebContentsUserData<
- AutocompleteClientWebContentsUserData> {
- public:
- ~AutocompleteClientWebContentsUserData() override = default;
-
- int GetLastCommittedEntryIndex() { return last_committed_entry_index_; }
- const GURL& GetLastCommittedStrippedURL() {
- return last_committed_stripped_url_;
- }
- void UpdateLastCommittedStrippedURL(
- int last_committed_index,
- const GURL& last_committed_url,
- TemplateURLService* template_url_service) {
- if (last_committed_url.is_valid()) {
- last_committed_entry_index_ = last_committed_index;
- // Use blank input since we will re-use this stripped URL with other
- // inputs.
- last_committed_stripped_url_ = AutocompleteMatch::GURLToStrippedGURL(
- last_committed_url, AutocompleteInput(), template_url_service,
- base::string16());
- }
- }
-
- private:
- explicit AutocompleteClientWebContentsUserData(
- content::WebContents* contents);
- friend class content::WebContentsUserData<
- AutocompleteClientWebContentsUserData>;
-
- int last_committed_entry_index_ = -1;
- GURL last_committed_stripped_url_;
- WEB_CONTENTS_USER_DATA_KEY_DECL();
-};
-
-AutocompleteClientWebContentsUserData::AutocompleteClientWebContentsUserData(
- content::WebContents*)
- : content::WebContentsUserData<AutocompleteClientWebContentsUserData>() {}
-
-WEB_CONTENTS_USER_DATA_KEY_IMPL(AutocompleteClientWebContentsUserData)
-
bool ChromeAutocompleteProviderClient::IsStrippedURLEqualToWebContentsURL(
const GURL& stripped_url,
content::WebContents* web_contents) {
@@ -475,11 +505,16 @@
} else {
// Browser did not load the tab yet after Chrome started. To avoid
// reloading WebContents, we just compare URLs.
- // TODO(1094056) : Let's TabAndroid to support base::SupportsUserData,
- // so we can avoid create new url over and over again.
- const GURL tab_stripped_url = AutocompleteMatch::GURLToStrippedGURL(
- tab->GetURL(), AutocompleteInput(), GetTemplateURLService(),
- base::string16());
+ // TODO(crbug.com/1138729): Delete user data after WebContents is
+ // initialized.
+ AutocompleteClientTabAndroidUserData::CreateForTabAndroid(tab);
+ AutocompleteClientTabAndroidUserData* user_data =
+ AutocompleteClientTabAndroidUserData::FromTabAndroid(tab);
+ DCHECK(user_data);
+ if (!user_data->IsInitialized())
+ user_data->UpdateStrippedURL(tab->GetURL(), GetTemplateURLService());
+
+ const GURL tab_stripped_url = user_data->GetStrippedURL();
if (tab_stripped_url == stripped_url)
return tab;
}