diff options
author | sdefresne <sdefresne@chromium.org> | 2015-07-09 07:56:19 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-07-09 14:56:44 +0000 |
commit | 311a46585ee5b77486ef42d947bc7cc7566558b1 (patch) | |
tree | d15f84966fbd2c4ade8527e74f99817974cc1979 | |
parent | ec894a5d76eadbe3cb489faed6469ff78e00aec8 (diff) | |
download | chromium_src-311a46585ee5b77486ef42d947bc7cc7566558b1.zip chromium_src-311a46585ee5b77486ef42d947bc7cc7566558b1.tar.gz chromium_src-311a46585ee5b77486ef42d947bc7cc7566558b1.tar.bz2 |
Componentize chrome/browser/rlz
Add new class RLZTrackerDelegate that abstract access to embedder
specific singletons and informations and provide an implementation for
Chrome based on the previous implementation.
Split rlz_unittest.cc in tests of the RLZTracker and Chrome
implementation of the RLZTrackerDelegate interface and move the
RLZTracker tests into the component.
Add a new gyp/gn variable "enable_rlz_support". This variable is true on
the platforms that support RLZ (currently Windows, Mac, iOS and
ChromeOS). Use it to build library and unit tests even when the RLZ
support is not enabled in the Chrome binary (this is still controlled by
"enable_rlz" and depends on the branding).
Enable the tests on iOS and convert rlz_tracker_ios.mm to a C++ file.
TEST=Run unit_tests and components_unittests on a platform that supports
RLZ (Windows, Mac, iOS or ChromeOS) and check that they pass. Then build
Chrome with "enable_rlz" and manually checks that RLZ are sent with
searches as expected.
BUG=504841,508148
Review URL: https://codereview.chromium.org/1212163011
Cr-Commit-Position: refs/heads/master@{#338040}
38 files changed, 1130 insertions, 548 deletions
diff --git a/build/common.gypi b/build/common.gypi index 251bdfe..587f74c 100644 --- a/build/common.gypi +++ b/build/common.gypi @@ -1494,6 +1494,7 @@ # Whether we are using the rlz library or not. Platforms like Android send # rlz codes for searches but do not use the library. + 'enable_rlz_support%': 0, 'enable_rlz%': 0, # Turns on the i18n support in V8. @@ -2320,9 +2321,15 @@ 'release_valgrind_build': 1, }], - # Enable RLZ on Win, Mac, iOS and ChromeOS. - ['branding=="Chrome" and (OS=="win" or OS=="mac" or OS=="ios" or chromeos==1)', { - 'enable_rlz%': 1, + # RLZ library is used on Win, Mac, iOS and ChromeOS. + ['OS=="win" or OS=="mac" or OS=="ios" or chromeos==1', { + 'enable_rlz_support%': 1, + 'conditions': [ + # RLZ is enabled for "Chrome" builds. + ['branding=="Chrome"', { + 'enable_rlz%': 1, + }], + ], }], # Set default compiler flags depending on ARM version. diff --git a/build/config/features.gni b/build/config/features.gni index e92ca9b..93b19dd 100644 --- a/build/config/features.gni +++ b/build/config/features.gni @@ -168,7 +168,8 @@ win_pdf_metafile_for_printing = true # Whether we are using the rlz library or not. Platforms like Android send # rlz codes for searches but do not use the library. -enable_rlz = is_chrome_branded && (is_win || is_mac || is_ios || is_chromeos) +enable_rlz_support = is_win || is_mac || is_ios || is_chromeos +enable_rlz = is_chrome_branded && enable_rlz_support enable_settings_app = enable_app_list && !is_chromeos diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 353cc37..43c90b3 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn @@ -685,9 +685,7 @@ source_set("browser") { } if (enable_rlz) { - sources += - rebase_path(gypi_values.chrome_browser_rlz_sources, ".", "//chrome") - deps += [ "//rlz:rlz_lib" ] + deps += [ ":rlz" ] } # TODO(GYP) @@ -1197,3 +1195,17 @@ source_set("test_support") { ] } } + +if (enable_rlz_support) { + source_set("rlz") { + sources = + rebase_path(gypi_values.chrome_browser_rlz_sources, ".", "//chrome") + deps = [ + "//components/google/core/browser", + "//components/omnibox/browser", + "//components/rlz", + "//components/search_engines", + "//rlz:rlz_lib", + ] + } +} diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS index 4b598f5..4bd2354 100644 --- a/chrome/browser/DEPS +++ b/chrome/browser/DEPS @@ -72,6 +72,7 @@ include_rules = [ "+components/query_parser", "+components/rappor", "+components/renderer_context_menu", + "+components/rlz", "+components/safe_json", "+components/search", "+components/search_engines", diff --git a/chrome/browser/browser_shutdown.cc b/chrome/browser/browser_shutdown.cc index 8974bd5..9ee066b 100644 --- a/chrome/browser/browser_shutdown.cc +++ b/chrome/browser/browser_shutdown.cc @@ -40,7 +40,7 @@ #endif #if defined(ENABLE_RLZ) -#include "chrome/browser/rlz/rlz.h" +#include "components/rlz/rlz_tracker.h" #endif #if defined(OS_CHROMEOS) @@ -192,7 +192,7 @@ bool ShutdownPreThreadsStop() { #if defined(ENABLE_RLZ) // Cleanup any statics created by RLZ. Must be done before NotificationService // is destroyed. - RLZTracker::CleanupRlz(); + rlz::RLZTracker::CleanupRlz(); #endif return restart_last_session; diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc index b1cfe0b..f9e0181 100644 --- a/chrome/browser/chrome_browser_main.cc +++ b/chrome/browser/chrome_browser_main.cc @@ -223,7 +223,8 @@ #endif // defined(ENABLE_PRINT_PREVIEW) && !defined(OFFICIAL_BUILD) #if defined(ENABLE_RLZ) -#include "chrome/browser/rlz/rlz.h" +#include "chrome/browser/rlz/chrome_rlz_tracker_delegate.h" +#include "components/rlz/rlz_tracker.h" #endif // defined(ENABLE_RLZ) #if defined(ENABLE_WEBRTC) @@ -1451,9 +1452,14 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() { pref_service->GetInteger(first_run::GetPingDelayPrefName().c_str()); // Negative ping delay means to send ping immediately after a first search is // recorded. - RLZTracker::InitRlzFromProfileDelayed( - profile_, first_run::IsChromeFirstRun(), ping_delay < 0, - base::TimeDelta::FromMilliseconds(abs(ping_delay))); + rlz::RLZTracker::SetRlzDelegate( + make_scoped_ptr(new ChromeRLZTrackerDelegate)); + rlz::RLZTracker::InitRlzDelayed( + first_run::IsChromeFirstRun(), ping_delay < 0, + base::TimeDelta::FromMilliseconds(abs(ping_delay)), + ChromeRLZTrackerDelegate::IsGoogleDefaultSearch(profile_), + ChromeRLZTrackerDelegate::IsGoogleHomePage(profile_), + ChromeRLZTrackerDelegate::IsGoogleInStartpages(profile_)); #endif // defined(ENABLE_RLZ) && !defined(OS_CHROMEOS) // Configure modules that need access to resources. diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc index 32a5835..143e14e 100644 --- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc +++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc @@ -75,7 +75,6 @@ #include "chrome/browser/net/chrome_network_delegate.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" -#include "chrome/browser/rlz/rlz.h" #include "chrome/browser/ui/ash/network_connect_delegate_chromeos.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_paths.h" @@ -129,6 +128,10 @@ #include "ui/base/touch/touch_device.h" #include "ui/events/event_utils.h" +#if defined(ENABLE_RLZ) +#include "components/rlz/rlz_tracker.h" +#endif + // Exclude X11 dependents for ozone #if defined(USE_X11) #include "chrome/browser/chromeos/device_uma.h" diff --git a/chrome/browser/chromeos/login/login_utils_browsertest.cc b/chrome/browser/chromeos/login/login_utils_browsertest.cc index 6025228..53ca423 100644 --- a/chrome/browser/chromeos/login/login_utils_browsertest.cc +++ b/chrome/browser/chromeos/login/login_utils_browsertest.cc @@ -14,7 +14,6 @@ #include "chrome/browser/chromeos/login/test/oobe_base_test.h" #include "chrome/browser/chromeos/login/ui/webui_login_display.h" #include "chrome/browser/chromeos/login/wizard_controller.h" -#include "chrome/browser/rlz/rlz.h" #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" @@ -29,6 +28,10 @@ #include "net/test/embedded_test_server/http_response.h" #include "testing/gtest/include/gtest/gtest.h" +#if defined(ENABLE_RLZ) +#include "components/rlz/rlz_tracker.h" +#endif + namespace chromeos { namespace { @@ -37,7 +40,7 @@ namespace { void GetAccessPointRlzInBackgroundThread(rlz_lib::AccessPoint point, base::string16* rlz) { ASSERT_FALSE(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); - ASSERT_TRUE(RLZTracker::GetAccessPointRlz(point, rlz)); + ASSERT_TRUE(rlz::RLZTracker::GetAccessPointRlz(point, rlz)); } #endif @@ -106,10 +109,8 @@ IN_PROC_BROWSER_TEST_P(LoginUtilsTest, RlzInitialized) { base::RunLoop loop; base::string16 rlz_string; content::BrowserThread::PostBlockingPoolTaskAndReply( - FROM_HERE, - base::Bind(&GetAccessPointRlzInBackgroundThread, - RLZTracker::ChromeHomePage(), - &rlz_string), + FROM_HERE, base::Bind(&GetAccessPointRlzInBackgroundThread, + rlz::RLZTracker::ChromeHomePage(), &rlz_string), loop.QuitClosure()); loop.Run(); EXPECT_EQ(base::string16(), rlz_string); diff --git a/chrome/browser/chromeos/login/session/user_session_manager.cc b/chrome/browser/chromeos/login/session/user_session_manager.cc index af0f026..5bedab6 100644 --- a/chrome/browser/chromeos/login/session/user_session_manager.cc +++ b/chrome/browser/chromeos/login/session/user_session_manager.cc @@ -65,7 +65,6 @@ #include "chrome/browser/prefs/session_startup_pref.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" -#include "chrome/browser/rlz/rlz.h" #include "chrome/browser/signin/account_tracker_service_factory.h" #include "chrome/browser/signin/easy_unlock_service.h" #include "chrome/browser/signin/signin_manager_factory.h" @@ -101,6 +100,11 @@ #include "ui/base/ime/chromeos/input_method_manager.h" #include "url/gurl.h" +#if defined(ENABLE_RLZ) +#include "chrome/browser/rlz/chrome_rlz_tracker_delegate.h" +#include "components/rlz/rlz_tracker.h" +#endif + namespace chromeos { namespace { @@ -1298,7 +1302,7 @@ void UserSessionManager::InitRlzImpl(Profile* profile, bool disabled) { } if (disabled != local_state->GetBoolean(prefs::kRLZDisabled)) { // When switching to RLZ enabled/disabled state, clear all recorded events. - RLZTracker::ClearRlzState(); + rlz::RLZTracker::ClearRlzState(); local_state->SetBoolean(prefs::kRLZDisabled, disabled); } // Init the RLZ library. @@ -1306,11 +1310,14 @@ void UserSessionManager::InitRlzImpl(Profile* profile, bool disabled) { ::first_run::GetPingDelayPrefName().c_str()); // Negative ping delay means to send ping immediately after a first search is // recorded. - RLZTracker::InitRlzFromProfileDelayed( - profile, - user_manager::UserManager::Get()->IsCurrentUserNew(), - ping_delay < 0, - base::TimeDelta::FromMilliseconds(abs(ping_delay))); + rlz::RLZTracker::SetRlzDelegate( + make_scoped_ptr(new ChromeRLZTrackerDelegate)); + rlz::RLZTracker::InitRlzDelayed( + user_manager::UserManager::Get()->IsCurrentUserNew(), ping_delay < 0, + base::TimeDelta::FromMilliseconds(abs(ping_delay)), + ChromeRLZTrackerDelegate::IsGoogleDefaultSearch(profile), + ChromeRLZTrackerDelegate::IsGoogleHomepage(profile), + ChromeRLZTrackerDelegate::IsGoogleInStartpages(profile)); #endif } diff --git a/chrome/browser/rlz/chrome_rlz_tracker_delegate.cc b/chrome/browser/rlz/chrome_rlz_tracker_delegate.cc new file mode 100644 index 0000000..091bac1 --- /dev/null +++ b/chrome/browser/rlz/chrome_rlz_tracker_delegate.cc @@ -0,0 +1,236 @@ +// 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 "chrome/browser/rlz/chrome_rlz_tracker_delegate.h" + +#include "base/command_line.h" +#include "base/prefs/pref_service.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/chrome_notification_types.h" +#include "chrome/browser/google/google_brand.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/search_engines/template_url_service_factory.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/common/pref_names.h" +#include "components/google/core/browser/google_util.h" +#include "components/omnibox/browser/omnibox_log.h" +#include "components/search_engines/template_url.h" +#include "components/search_engines/template_url_service.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/navigation_controller.h" +#include "content/public/browser/navigation_details.h" +#include "content/public/browser/navigation_entry.h" +#include "content/public/browser/notification_details.h" +#include "content/public/browser/notification_service.h" +#include "content/public/browser/notification_source.h" + +#if defined(OS_WIN) +#include "chrome/installer/util/google_update_settings.h" +#endif + +#if !defined(OS_IOS) +#include "chrome/browser/prefs/session_startup_pref.h" +#include "chrome/browser/ui/startup/startup_browser_creator.h" +#endif + +ChromeRLZTrackerDelegate::ChromeRLZTrackerDelegate() { +} + +ChromeRLZTrackerDelegate::~ChromeRLZTrackerDelegate() { +} + +// static +bool ChromeRLZTrackerDelegate::IsGoogleDefaultSearch(Profile* profile) { + bool is_google_default_search = false; + TemplateURLService* template_url_service = + TemplateURLServiceFactory::GetForProfile(profile); + if (template_url_service) { + const TemplateURL* url_template = + template_url_service->GetDefaultSearchProvider(); + is_google_default_search = url_template && + url_template->url_ref().HasGoogleBaseURLs( + template_url_service->search_terms_data()); + } + return is_google_default_search; +} + +// static +bool ChromeRLZTrackerDelegate::IsGoogleHomepage(Profile* profile) { + return google_util::IsGoogleHomePageUrl( + GURL(profile->GetPrefs()->GetString(prefs::kHomePage))); +} + +// static +bool ChromeRLZTrackerDelegate::IsGoogleInStartpages(Profile* profile) { +#if !defined(OS_IOS) + bool is_google_in_startpages = false; + SessionStartupPref session_startup_prefs = + StartupBrowserCreator::GetSessionStartupPref( + *base::CommandLine::ForCurrentProcess(), profile); + if (session_startup_prefs.type == SessionStartupPref::URLS) { + is_google_in_startpages = + std::count_if(session_startup_prefs.urls.begin(), + session_startup_prefs.urls.end(), + google_util::IsGoogleHomePageUrl) > 0; + } + return is_google_in_startpages; +#else + // iOS does not have a notion of startpages. + return false; +#endif +} + +void ChromeRLZTrackerDelegate::Cleanup() { + registrar_.RemoveAll(); + on_omnibox_search_callback_.Reset(); + on_homepage_search_callback_.Reset(); +} + +bool ChromeRLZTrackerDelegate::IsOnUIThread() { + return content::BrowserThread::CurrentlyOn(content::BrowserThread::UI); +} + +base::SequencedWorkerPool* ChromeRLZTrackerDelegate::GetBlockingPool() { + return content::BrowserThread::GetBlockingPool(); +} + +net::URLRequestContextGetter* ChromeRLZTrackerDelegate::GetRequestContext() { + return g_browser_process->system_request_context(); +} + +bool ChromeRLZTrackerDelegate::GetBrand(std::string* brand) { + return google_brand::GetBrand(brand); +} + +bool ChromeRLZTrackerDelegate::IsBrandOrganic(const std::string& brand) { + return brand.empty() || google_brand::IsOrganic(brand); +} + +bool ChromeRLZTrackerDelegate::GetReactivationBrand(std::string* brand) { + return google_brand::GetReactivationBrand(brand); +} + +bool ChromeRLZTrackerDelegate::ShouldEnableZeroDelayForTesting() { + return base::CommandLine::ForCurrentProcess()->HasSwitch( + ::switches::kTestType); +} + +bool ChromeRLZTrackerDelegate::GetLanguage(base::string16* language) { +#if defined(OS_WIN) + return GoogleUpdateSettings::GetLanguage(language); +#else + // TODO(thakis): Implement. + NOTIMPLEMENTED(); + return false; +#endif +} + +bool ChromeRLZTrackerDelegate::GetReferral(base::string16* referral) { +#if defined(OS_WIN) + return GoogleUpdateSettings::GetReferral(referral); +#else + // The referral program is defunct and not used. No need to implement this + // function on non-Win platforms. + return true; +#endif +} + +bool ChromeRLZTrackerDelegate::ClearReferral() { +#if defined(OS_WIN) + return GoogleUpdateSettings::ClearReferral(); +#else + // The referral program is defunct and not used. No need to implement this + // function on non-Win platforms. + return true; +#endif +} + +void ChromeRLZTrackerDelegate::SetOmniboxSearchCallback( + const base::Closure& callback) { + DCHECK(!callback.is_null()); + registrar_.Add(this, chrome::NOTIFICATION_OMNIBOX_OPENED_URL, + content::NotificationService::AllSources()); + on_omnibox_search_callback_ = callback; +} + +void ChromeRLZTrackerDelegate::SetHomepageSearchCallback( + const base::Closure& callback) { +#if !defined(OS_IOS) + DCHECK(!callback.is_null()); + registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, + content::NotificationService::AllSources()); + on_homepage_search_callback_ = callback; +#endif +} + +void ChromeRLZTrackerDelegate::Observe( + int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) { + using std::swap; + base::Closure callback_to_run; + switch (type) { + case chrome::NOTIFICATION_OMNIBOX_OPENED_URL: + // In M-36, we made NOTIFICATION_OMNIBOX_OPENED_URL fire more often than + // it did previously. The RLZ folks want RLZ's "first search" detection + // to remain as unaffected as possible by this change. This test is + // there to keep the old behavior. + if (!content::Details<OmniboxLog>(details).ptr()->is_popup_open) + break; + registrar_.Remove(this, chrome::NOTIFICATION_OMNIBOX_OPENED_URL, + content::NotificationService::AllSources()); + swap(callback_to_run, on_omnibox_search_callback_); + break; + +#if !defined(OS_IOS) + case content::NOTIFICATION_NAV_ENTRY_COMMITTED: { + // Firstly check if it is a Google search. + content::LoadCommittedDetails* load_details = + content::Details<content::LoadCommittedDetails>(details).ptr(); + if (load_details == nullptr) + break; + + content::NavigationEntry* entry = load_details->entry; + if (entry == nullptr) + break; + + if (google_util::IsGoogleSearchUrl(entry->GetURL())) { + // If it is a Google search, check if it originates from HOMEPAGE by + // getting the previous NavigationEntry. + content::NavigationController* controller = + content::Source<content::NavigationController>(source).ptr(); + if (controller == nullptr) + break; + + int entry_index = controller->GetLastCommittedEntryIndex(); + if (entry_index < 1) + break; + + const content::NavigationEntry* previous_entry = + controller->GetEntryAtIndex(entry_index - 1); + + if (previous_entry == nullptr) + break; + + // Make sure it is a Google web page originated from HOMEPAGE. + if (google_util::IsGoogleHomePageUrl(previous_entry->GetURL()) && + ((previous_entry->GetTransitionType() & + ui::PAGE_TRANSITION_HOME_PAGE) != 0)) { + registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, + content::NotificationService::AllSources()); + swap(callback_to_run, on_homepage_search_callback_); + } + } + break; + } +#endif // !defined(OS_IOS) + + default: + NOTREACHED(); + break; + } + + if (!callback_to_run.is_null()) + callback_to_run.Run(); +} diff --git a/chrome/browser/rlz/chrome_rlz_tracker_delegate.h b/chrome/browser/rlz/chrome_rlz_tracker_delegate.h new file mode 100644 index 0000000..3494775 --- /dev/null +++ b/chrome/browser/rlz/chrome_rlz_tracker_delegate.h @@ -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. + +#ifndef CHROME_BROWSER_RLZ_CHROME_RLZ_TRACKER_DELEGATE_H_ +#define CHROME_BROWSER_RLZ_CHROME_RLZ_TRACKER_DELEGATE_H_ + +#include "base/callback_list.h" +#include "base/macros.h" +#include "components/rlz/rlz_tracker_delegate.h" +#include "content/public/browser/notification_observer.h" +#include "content/public/browser/notification_registrar.h" + +class Profile; + +// ChromeRLZTrackerDelegate implements RLZTrackerDelegate abstract interface +// and provides access to Chrome features. +class ChromeRLZTrackerDelegate : public rlz::RLZTrackerDelegate, + public content::NotificationObserver { + public: + ChromeRLZTrackerDelegate(); + ~ChromeRLZTrackerDelegate() override; + + static bool IsGoogleDefaultSearch(Profile* profile); + static bool IsGoogleHomepage(Profile* profile); + static bool IsGoogleInStartpages(Profile* profile); + + private: + // RLZTrackerDelegate implementation. + void Cleanup() override; + bool IsOnUIThread() override; + base::SequencedWorkerPool* GetBlockingPool() override; + net::URLRequestContextGetter* GetRequestContext() override; + bool GetBrand(std::string* brand) override; + bool IsBrandOrganic(const std::string& brand) override; + bool GetReactivationBrand(std::string* brand) override; + bool ShouldEnableZeroDelayForTesting() override; + bool GetLanguage(base::string16* language) override; + bool GetReferral(base::string16* referral) override; + bool ClearReferral() override; + void SetOmniboxSearchCallback(const base::Closure& callback) override; + void SetHomepageSearchCallback(const base::Closure& callback) override; + + // content::NotificationObserver implementation: + void Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) override; + + content::NotificationRegistrar registrar_; + base::Closure on_omnibox_search_callback_; + base::Closure on_homepage_search_callback_; + + DISALLOW_COPY_AND_ASSIGN(ChromeRLZTrackerDelegate); +}; + +#endif // CHROME_BROWSER_RLZ_CHROME_RLZ_TRACKER_DELEGATE_H_ diff --git a/chrome/browser/rlz/chrome_rlz_tracker_delegate_unittest.cc b/chrome/browser/rlz/chrome_rlz_tracker_delegate_unittest.cc new file mode 100644 index 0000000..fd7d6e0 --- /dev/null +++ b/chrome/browser/rlz/chrome_rlz_tracker_delegate_unittest.cc @@ -0,0 +1,48 @@ +// Copyright (c) 2012 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/rlz/chrome_rlz_tracker_delegate.h" + +#include "base/memory/scoped_ptr.h" +#include "chrome/browser/chrome_notification_types.h" +#include "content/public/browser/navigation_details.h" +#include "content/public/browser/navigation_entry.h" +#include "content/public/browser/notification_service.h" +#include "content/public/browser/notification_source.h" +#include "testing/gtest/include/gtest/gtest.h" + +using content::NavigationEntry; +using content::LoadCommittedDetails; + +class ChromeRLZTrackerDelegateTest : public testing::Test { + public: + ChromeRLZTrackerDelegateTest() : delegate_(new ChromeRLZTrackerDelegate) {} + ~ChromeRLZTrackerDelegateTest() override {} + + void SendNotification(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) { + content::NotificationObserver* observer = delegate_.get(); + observer->Observe(type, source, details); + } + + private: + scoped_ptr<ChromeRLZTrackerDelegate> delegate_; +}; + +TEST_F(ChromeRLZTrackerDelegateTest, ObserveHandlesBadArgs) { + scoped_ptr<content::LoadCommittedDetails> details( + new content::LoadCommittedDetails()); + scoped_ptr<content::NavigationEntry> entry( + content::NavigationEntry::Create()); + details->entry = entry.get(); + details->entry->SetPageID(0); + details->entry->SetTransitionType(ui::PAGE_TRANSITION_LINK); + SendNotification(content::NOTIFICATION_NAV_ENTRY_COMMITTED, + content::NotificationService::AllSources(), + content::Details<NavigationEntry>(nullptr)); + SendNotification(content::NOTIFICATION_NAV_ENTRY_COMMITTED, + content::NotificationService::AllSources(), + content::Details<LoadCommittedDetails>(details.get())); +} diff --git a/chrome/browser/rlz/rlz_ios.mm b/chrome/browser/rlz/rlz_ios.mm deleted file mode 100644 index 7af1f59..0000000 --- a/chrome/browser/rlz/rlz_ios.mm +++ /dev/null @@ -1,14 +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 "chrome/browser/rlz/rlz.h" - -#import <UIKit/UIKit.h> - -// static -rlz_lib::AccessPoint RLZTracker::ChromeOmnibox() { - return UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone - ? rlz_lib::CHROME_IOS_OMNIBOX_MOBILE - : rlz_lib::CHROME_IOS_OMNIBOX_TABLET; -} diff --git a/chrome/browser/search_engines/template_url_service_factory.cc b/chrome/browser/search_engines/template_url_service_factory.cc index c5246e7..6d52447 100644 --- a/chrome/browser/search_engines/template_url_service_factory.cc +++ b/chrome/browser/search_engines/template_url_service_factory.cc @@ -13,7 +13,6 @@ #include "chrome/browser/history/history_service_factory.h" #include "chrome/browser/profiles/incognito_helpers.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/rlz/rlz.h" #include "chrome/browser/search_engines/chrome_template_url_service_client.h" #include "chrome/browser/search_engines/ui_thread_search_terms_data.h" #include "chrome/browser/web_data_service_factory.h" @@ -23,6 +22,10 @@ #include "components/search_engines/search_engines_pref_names.h" #include "components/search_engines/template_url_service.h" +#if defined(ENABLE_RLZ) +#include "components/rlz/rlz_tracker.h" +#endif + // static TemplateURLService* TemplateURLServiceFactory::GetForProfile(Profile* profile) { return static_cast<TemplateURLService*>( @@ -39,11 +42,9 @@ scoped_ptr<KeyedService> TemplateURLServiceFactory::BuildInstanceFor( content::BrowserContext* context) { base::Closure dsp_change_callback; #if defined(ENABLE_RLZ) - dsp_change_callback = - base::Bind(base::IgnoreResult(&RLZTracker::RecordProductEvent), - rlz_lib::CHROME, - RLZTracker::ChromeOmnibox(), - rlz_lib::SET_TO_GOOGLE); + dsp_change_callback = base::Bind( + base::IgnoreResult(&rlz::RLZTracker::RecordProductEvent), rlz_lib::CHROME, + rlz::RLZTracker::ChromeOmnibox(), rlz_lib::SET_TO_GOOGLE); #endif Profile* profile = static_cast<Profile*>(context); return make_scoped_ptr(new TemplateURLService( diff --git a/chrome/browser/search_engines/ui_thread_search_terms_data.cc b/chrome/browser/search_engines/ui_thread_search_terms_data.cc index 1ccd09a..11dae12 100644 --- a/chrome/browser/search_engines/ui_thread_search_terms_data.cc +++ b/chrome/browser/search_engines/ui_thread_search_terms_data.cc @@ -28,7 +28,7 @@ #include "url/gurl.h" #if defined(ENABLE_RLZ) -#include "chrome/browser/rlz/rlz.h" +#include "components/rlz/rlz_tracker.h" #endif using content::BrowserThread; @@ -82,12 +82,12 @@ base::string16 UIThreadSearchTermsData::GetRlzParameterValue( // This call will return false the first time(s) it is called until the // value has been cached. This normally would mean that at most one omnibox // search might not send the RLZ data but this is not really a problem. - rlz_lib::AccessPoint access_point = RLZTracker::ChromeOmnibox(); + rlz_lib::AccessPoint access_point = rlz::RLZTracker::ChromeOmnibox(); #if !defined(OS_IOS) if (from_app_list) - access_point = RLZTracker::ChromeAppList(); + access_point = rlz::RLZTracker::ChromeAppList(); #endif - RLZTracker::GetAccessPointRlz(access_point, &rlz_string); + rlz::RLZTracker::GetAccessPointRlz(access_point, &rlz_string); } #endif return rlz_string; diff --git a/chrome/browser/ui/app_list/app_list_controller_delegate.cc b/chrome/browser/ui/app_list/app_list_controller_delegate.cc index e6a19fc..76a54164 100644 --- a/chrome/browser/ui/app_list/app_list_controller_delegate.cc +++ b/chrome/browser/ui/app_list/app_list_controller_delegate.cc @@ -28,7 +28,7 @@ #include "ui/gfx/geometry/rect.h" #if defined(ENABLE_RLZ) -#include "chrome/browser/rlz/rlz.h" +#include "components/rlz/rlz_tracker.h" #endif using extensions::ExtensionRegistry; @@ -213,6 +213,6 @@ void AppListControllerDelegate::GetApps(Profile* profile, void AppListControllerDelegate::OnSearchStarted() { #if defined(ENABLE_RLZ) - RLZTracker::RecordAppListSearch(); + rlz::RLZTracker::RecordAppListSearch(); #endif } diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc index 6c031f3..1783266 100644 --- a/chrome/browser/ui/browser_commands.cc +++ b/chrome/browser/ui/browser_commands.cc @@ -20,7 +20,6 @@ #include "chrome/browser/platform_util.h" #include "chrome/browser/prefs/incognito_mode_prefs.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/rlz/rlz.h" #include "chrome/browser/search/search.h" #include "chrome/browser/sessions/session_service_factory.h" #include "chrome/browser/sessions/tab_restore_service.h" @@ -104,6 +103,10 @@ #endif // defined(ENABLE_PRINT_PREVIEW) #endif // defined(ENABLE_PRINTING) +#if defined(ENABLE_RLZ) +#include "components/rlz/rlz_tracker.h" +#endif + namespace { const char kOsOverrideForTabletSite[] = "Linux; Android 4.0.3"; } @@ -433,8 +436,8 @@ void Home(Browser* browser, WindowOpenDisposition disposition) { if (pref_service) { if (google_util::IsGoogleHomePageUrl( GURL(pref_service->GetString(prefs::kHomePage)))) { - extra_headers = RLZTracker::GetAccessPointHttpHeader( - RLZTracker::ChromeHomePage()); + extra_headers = rlz::RLZTracker::GetAccessPointHttpHeader( + rlz::RLZTracker::ChromeHomePage()); } } #endif // defined(ENABLE_RLZ) && !defined(OS_IOS) diff --git a/chrome/browser/ui/startup/startup_browser_creator_impl.cc b/chrome/browser/ui/startup/startup_browser_creator_impl.cc index b6a1fdd..665f159 100644 --- a/chrome/browser/ui/startup/startup_browser_creator_impl.cc +++ b/chrome/browser/ui/startup/startup_browser_creator_impl.cc @@ -43,7 +43,6 @@ #include "chrome/browser/prefs/session_startup_pref.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_io_data.h" -#include "chrome/browser/rlz/rlz.h" #include "chrome/browser/sessions/session_restore.h" #include "chrome/browser/sessions/session_service.h" #include "chrome/browser/sessions/session_service_factory.h" @@ -103,6 +102,10 @@ #include "chrome/browser/apps/app_launch_for_metro_restart_win.h" #endif +#if defined(ENABLE_RLZ) +#include "components/rlz/rlz_tracker.h" +#endif + using content::ChildProcessSecurityPolicy; using content::WebContents; using extensions::Extension; @@ -788,8 +791,8 @@ Browser* StartupBrowserCreatorImpl::OpenTabsInBrowser( #if defined(ENABLE_RLZ) && !defined(OS_IOS) if (process_startup && google_util::IsGoogleHomePageUrl(tabs[i].url)) { - params.extra_headers = RLZTracker::GetAccessPointHttpHeader( - RLZTracker::ChromeHomePage()); + params.extra_headers = rlz::RLZTracker::GetAccessPointHttpHeader( + rlz::RLZTracker::ChromeHomePage()); } #endif // defined(ENABLE_RLZ) && !defined(OS_IOS) diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 9e608e6..335fcdc 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -2435,12 +2435,8 @@ 'browser/profiles/storage_partition_descriptor.h', ], 'chrome_browser_rlz_sources': [ - 'browser/rlz/rlz.cc', - 'browser/rlz/rlz.h', - 'browser/rlz/rlz_chromeos.cc', - 'browser/rlz/rlz_ios.mm', - 'browser/rlz/rlz_mac.cc', - 'browser/rlz/rlz_win.cc', + 'browser/rlz/chrome_rlz_tracker_delegate.cc', + 'browser/rlz/chrome_rlz_tracker_delegate.h', ], # "Safe Browsing Basic" files used for safe browsing in full mode # (safe_browsing=1), mobile (=2), and mobile-extended (=3). @@ -3714,9 +3710,8 @@ }, }], ['enable_rlz==1', { - 'sources': [ '<@(chrome_browser_rlz_sources)' ], 'dependencies': [ - '../rlz/rlz.gyp:rlz_lib', + 'browser_rlz', ], }], # Temporary fix to break the browser target into smaller chunks so it @@ -4085,5 +4080,24 @@ }, ], },], + ['enable_rlz_support==1', { + 'targets': [ + { + # GN version: // chrome/browser:rlz + 'target_name': 'browser_rlz', + 'type': 'static_library', + 'sources': [ + '<@(chrome_browser_rlz_sources)', + ], + 'dependencies': [ + '../components/components.gyp:google_core_browser', + '../components/components.gyp:omnibox_browser', + '../components/components.gyp:rlz', + '../components/components.gyp:search_engines', + '../rlz/rlz.gyp:rlz_lib', + ], + }, + ], + }], ], } diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi index 58c4ebd..c92e703 100644 --- a/chrome/chrome_tests_unit.gypi +++ b/chrome/chrome_tests_unit.gypi @@ -215,7 +215,6 @@ 'browser/renderer_context_menu/render_view_context_menu_test_util.h', 'browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper_unit_test.mm', 'browser/resources_util_unittest.cc', - 'browser/rlz/rlz_unittest.cc', 'browser/search/contextual_search_policy_handler_android_unittest.cc', 'browser/search/iframe_source_unittest.cc', 'browser/search/instant_unittest_base.cc', @@ -2557,13 +2556,14 @@ 'common/extensions/api/networking_private/networking_private_crypto_unittest.cc', ], }], - ['enable_rlz!=0', { + ['enable_rlz_support==1', { + 'sources': [ + 'browser/rlz/chrome_rlz_tracker_delegate_unittest.cc', + ], 'dependencies': [ + '../components/components.gyp:rlz', '../rlz/rlz.gyp:test_support_rlz', - ], - }, { # enable_rlz==0 - 'sources!': [ - 'browser/rlz/rlz_unittest.cc', + 'browser_rlz', ], }], ['OS=="win" and component!="shared_library"', { diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index c77d5eb..f61faf2 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn @@ -1534,10 +1534,13 @@ if (!is_android) { if (is_win || is_mac || is_chromeos) { sources += [ "../common/extensions/api/networking_private/networking_private_crypto_unittest.cc" ] } - if (enable_rlz) { - deps += [ "//rlz:test_support" ] - } else { - sources -= [ "../browser/rlz/rlz_unittest.cc" ] + if (enable_rlz_support) { + sources += [ "../browser/rlz/chrome_rlz_tracker_delegate_unittest.cc" ] + deps += [ + "//chrome/browser:rlz", + "//components/rlz", + "//rlz:test_support", + ] } if (is_win) { if (!is_component_build) { diff --git a/components/BUILD.gn b/components/BUILD.gn index ae681a1..37459cd 100644 --- a/components/BUILD.gn +++ b/components/BUILD.gn @@ -313,6 +313,10 @@ test("components_unittests") { data_deps = [ ":components_tests_pak" ] + if (enable_rlz_support) { + deps += [ "//components/rlz:unit_tests" ] + } + if (is_android) { isolate_file = "components_unittests.isolate" diff --git a/components/components.gyp b/components/components.gyp index 7b5a01c..52bd3e1 100644 --- a/components/components.gyp +++ b/components/components.gyp @@ -164,5 +164,10 @@ 'chrome_apps.gypi', ], }], + ['enable_rlz_support==1', { + 'includes': [ + 'rlz.gypi', + ], + }] ], } diff --git a/components/components_tests.gyp b/components/components_tests.gyp index 4dd48468..6b4e101 100644 --- a/components/components_tests.gyp +++ b/components/components_tests.gyp @@ -488,6 +488,9 @@ 'rappor/rappor_utils_unittest.cc', 'rappor/sampler_unittest.cc', ], + 'rlz_unittest_sources': [ + 'rlz/rlz_tracker_unittest.cc', + ], 'scheduler_unittest_sources': [ 'scheduler/child/idle_helper_unittest.cc', 'scheduler/child/nestable_task_runner_for_test.cc', @@ -864,6 +867,23 @@ 'mime_util/mime_util.gyp:mime_util', ], 'conditions': [ + ['enable_rlz_support==1', { + 'sources': [ + '<@(rlz_unittest_sources)', + ], + 'dependencies': [ + '../net/net.gyp:net_test_support', + '../rlz/rlz.gyp:test_support_rlz', + 'components.gyp:rlz', + ], + 'conditions': [ + ['OS == "ios"', { + 'dependencies': [ + '../ui/base/ui_base.gyp:ui_base', + ], + }], + ], + }], ['toolkit_views == 1', { 'sources': [ 'bookmarks/browser/bookmark_node_data_unittest.cc', diff --git a/components/rlz.gypi b/components/rlz.gypi new file mode 100644 index 0000000..9030258 --- /dev/null +++ b/components/rlz.gypi @@ -0,0 +1,38 @@ +# 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. + +{ + 'targets': [ + { + # GN version: //components/rlz + 'target_name': 'rlz', + 'type': 'static_library', + 'include_dirs': [ + '..', + ], + 'dependencies': [ + '../base/base.gyp:base', + '../net/net.gyp:net', + '../rlz/rlz.gyp:rlz_lib', + 'google_core_browser', + ], + 'sources': [ + 'rlz/rlz_tracker.cc', + 'rlz/rlz_tracker.h', + 'rlz/rlz_tracker_chromeos.cc', + 'rlz/rlz_tracker_delegate.h', + 'rlz/rlz_tracker_ios.cc', + 'rlz/rlz_tracker_mac.cc', + 'rlz/rlz_tracker_win.cc', + ], + 'conditions': [ + ['OS == "ios"', { + 'dependencies': [ + '../ui/base/ui_base.gyp:ui_base', + ], + }], + ], + }, + ], +} diff --git a/components/rlz/BUILD.gn b/components/rlz/BUILD.gn new file mode 100644 index 0000000..85608322 --- /dev/null +++ b/components/rlz/BUILD.gn @@ -0,0 +1,42 @@ +# 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. + +source_set("rlz") { + sources = [ + "rlz_tracker.cc", + "rlz_tracker.h", + "rlz_tracker_chromeos.cc", + "rlz_tracker_delegate.h", + "rlz_tracker_ios.cc", + "rlz_tracker_mac.cc", + "rlz_tracker_win.cc", + ] + + deps = [ + "//base", + "//components/google/core/browser", + "//net", + "//rlz:rlz_lib", + ] + + if (is_ios) { + deps = [ + "//ui/base", + ] + } +} + +source_set("unit_tests") { + testonly = true + sources = [ + "rlz_tracker_unittest.cc", + ] + + deps = [ + "//net:test_support", + "//rlz:test_support", + "//ui/base", + ":rlz", + ] +} diff --git a/components/rlz/DEPS b/components/rlz/DEPS new file mode 100644 index 0000000..a5d3e8a --- /dev/null +++ b/components/rlz/DEPS @@ -0,0 +1,10 @@ +include_rules = [ + "+base", + "+components/google", + "+net", + "+rlz", + "+ui/base", + + # rlz is used on iOS. + "-content", +] diff --git a/components/rlz/OWNERS b/components/rlz/OWNERS new file mode 100644 index 0000000..d1986d9 --- /dev/null +++ b/components/rlz/OWNERS @@ -0,0 +1,4 @@ +cpu@chromium.org +gwilson@chromium.org +rogerta@chromium.org + diff --git a/chrome/browser/rlz/rlz.cc b/components/rlz/rlz_tracker.cc index 94064d2..baa166a 100644 --- a/chrome/browser/rlz/rlz.cc +++ b/components/rlz/rlz_tracker.cc @@ -6,61 +6,19 @@ // with or without the DLL being present. If the DLL is not present the // functions do nothing and just return false. -#include "chrome/browser/rlz/rlz.h" +#include "components/rlz/rlz_tracker.h" #include <algorithm> #include "base/bind.h" -#include "base/command_line.h" #include "base/message_loop/message_loop.h" -#include "base/prefs/pref_service.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/trace_event/trace_event.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/google/google_brand.h" -#include "chrome/browser/prefs/session_startup_pref.h" -#include "chrome/browser/search_engines/template_url_service_factory.h" -#include "chrome/browser/ui/startup/startup_browser_creator.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/common/pref_names.h" -#include "components/google/core/browser/google_util.h" -#include "components/omnibox/browser/omnibox_log.h" -#include "components/search_engines/template_url.h" -#include "components/search_engines/template_url_service.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/navigation_controller.h" -#include "content/public/browser/navigation_details.h" -#include "content/public/browser/navigation_entry.h" -#include "content/public/browser/notification_service.h" +#include "components/rlz/rlz_tracker_delegate.h" #include "net/http/http_util.h" -#if defined(OS_WIN) -#include "chrome/installer/util/google_update_settings.h" -#else -namespace GoogleUpdateSettings { -static bool GetLanguage(base::string16* language) { - // TODO(thakis): Implement. - NOTIMPLEMENTED(); - return false; -} - -// The referral program is defunct and not used. No need to implement these -// functions on non-Win platforms. -static bool GetReferral(base::string16* referral) { - return true; -} -static bool ClearReferral() { - return true; -} -} // namespace GoogleUpdateSettings -#endif - -using content::BrowserThread; -using content::NavigationEntry; -using content::NavigationController; - +namespace rlz { namespace { // Maximum and minimum delay for financial ping we would allow to be set through @@ -68,10 +26,6 @@ namespace { const base::TimeDelta kMaxInitDelay = base::TimeDelta::FromSeconds(200); const base::TimeDelta kMinInitDelay = base::TimeDelta::FromSeconds(20); -bool IsBrandOrganic(const std::string& brand) { - return brand.empty() || google_brand::IsOrganic(brand); -} - void RecordProductEvents(bool first_run, bool is_google_default_search, bool is_google_homepage, @@ -192,7 +146,7 @@ bool SendFinancialPing(const std::string& brand, } // namespace -RLZTracker* RLZTracker::tracker_ = NULL; +RLZTracker* RLZTracker::tracker_ = nullptr; // static RLZTracker* RLZTracker::GetInstance() { @@ -205,7 +159,6 @@ RLZTracker::RLZTracker() is_google_default_search_(false), is_google_homepage_(false), is_google_in_startpages_(false), - worker_pool_token_(BrowserThread::GetBlockingPool()->GetSequenceToken()), already_ran_(false), omnibox_used_(false), homepage_used_(false), @@ -217,6 +170,19 @@ RLZTracker::~RLZTracker() { } // static +void RLZTracker::SetRlzDelegate(scoped_ptr<RLZTrackerDelegate> delegate) { + GetInstance()->SetDelegate(delegate.Pass()); +} + +void RLZTracker::SetDelegate(scoped_ptr<RLZTrackerDelegate> delegate) { + DCHECK(delegate); + if (!delegate_) { + delegate_ = delegate.Pass(); + worker_pool_token_ = delegate_->GetBlockingPool()->GetSequenceToken(); + } +} + +// static bool RLZTracker::InitRlzDelayed(bool first_run, bool send_ping_immediately, base::TimeDelta delay, @@ -228,56 +194,6 @@ bool RLZTracker::InitRlzDelayed(bool first_run, is_google_in_startpages); } -// static -bool RLZTracker::InitRlzFromProfileDelayed(Profile* profile, - bool first_run, - bool send_ping_immediately, - base::TimeDelta delay) { - bool is_google_default_search = false; - TemplateURLService* template_url_service = - TemplateURLServiceFactory::GetForProfile(profile); - if (template_url_service) { - const TemplateURL* url_template = - template_url_service->GetDefaultSearchProvider(); - is_google_default_search = - url_template && url_template->url_ref().HasGoogleBaseURLs( - template_url_service->search_terms_data()); - } - - PrefService* pref_service = profile->GetPrefs(); - bool is_google_homepage = google_util::IsGoogleHomePageUrl( - GURL(pref_service->GetString(prefs::kHomePage))); - - bool is_google_in_startpages = false; -#if !defined(OS_IOS) - // iOS does not have a notion of startpages. - SessionStartupPref session_startup_prefs = - StartupBrowserCreator::GetSessionStartupPref( - *base::CommandLine::ForCurrentProcess(), profile); - if (session_startup_prefs.type == SessionStartupPref::URLS) { - is_google_in_startpages = - std::count_if(session_startup_prefs.urls.begin(), - session_startup_prefs.urls.end(), - google_util::IsGoogleHomePageUrl) > 0; - } -#endif - - if (!InitRlzDelayed(first_run, send_ping_immediately, delay, - is_google_default_search, is_google_homepage, - is_google_in_startpages)) { - return false; - } - -#if !defined(OS_IOS) - // Prime the RLZ cache for the home page access point so that its avaiable - // for the startup page if needed (i.e., when the startup page is set to - // the home page). - GetAccessPointRlz(ChromeHomePage(), NULL); -#endif // !defined(OS_IOS) - - return true; -} - bool RLZTracker::Init(bool first_run, bool send_ping_immediately, base::TimeDelta delay, @@ -291,46 +207,57 @@ bool RLZTracker::Init(bool first_run, send_ping_immediately_ = send_ping_immediately; // Enable zero delays for testing. - if (base::CommandLine::ForCurrentProcess()->HasSwitch(::switches::kTestType)) + if (delegate_->ShouldEnableZeroDelayForTesting()) EnableZeroDelayForTesting(); delay = std::min(kMaxInitDelay, std::max(min_init_delay_, delay)); - if (google_brand::GetBrand(&brand_) && !IsBrandOrganic(brand_)) { + if (delegate_->GetBrand(&brand_) && !delegate_->IsBrandOrganic(brand_)) { // Register for notifications from the omnibox so that we can record when // the user performs a first search. - registrar_.Add(this, chrome::NOTIFICATION_OMNIBOX_OPENED_URL, - content::NotificationService::AllSources()); + delegate_->SetOmniboxSearchCallback( + base::Bind(&RLZTracker::RecordFirstSearch, base::Unretained(this), + ChromeOmnibox())); #if !defined(OS_IOS) // Register for notifications from navigations, to see if the user has used // the home page. - registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, - content::NotificationService::AllSources()); -#endif // !defined(OS_IOS) + delegate_->SetHomepageSearchCallback( + base::Bind(&RLZTracker::RecordFirstSearch, base::Unretained(this), + ChromeHomePage())); +#endif } - google_brand::GetReactivationBrand(&reactivation_brand_); - - net::URLRequestContextGetter* context_getter = - g_browser_process->system_request_context(); + delegate_->GetReactivationBrand(&reactivation_brand_); - // Could be NULL; don't run if so. RLZ will try again next restart. + // Could be null; don't run if so. RLZ will try again next restart. + net::URLRequestContextGetter* context_getter = delegate_->GetRequestContext(); if (context_getter) { rlz_lib::SetURLRequestContext(context_getter); ScheduleDelayedInit(delay); } +#if !defined(OS_IOS) + // Prime the RLZ cache for the home page access point so that its avaiable + // for the startup page if needed (i.e., when the startup page is set to + // the home page). + GetAccessPointRlz(ChromeHomePage(), nullptr); +#endif // !defined(OS_IOS) + return true; } +void RLZTracker::Cleanup() { + rlz_cache_.clear(); + if (delegate_) + delegate_->Cleanup(); +} + void RLZTracker::ScheduleDelayedInit(base::TimeDelta delay) { // The RLZTracker is a singleton object that outlives any runnable tasks // that will be queued up. - BrowserThread::GetBlockingPool()->PostDelayedSequencedWorkerTask( - worker_pool_token_, - FROM_HERE, - base::Bind(&RLZTracker::DelayedInit, base::Unretained(this)), - delay); + delegate_->GetBlockingPool()->PostDelayedSequencedWorkerTask( + worker_pool_token_, FROM_HERE, + base::Bind(&RLZTracker::DelayedInit, base::Unretained(this)), delay); } void RLZTracker::DelayedInit() { @@ -338,7 +265,7 @@ void RLZTracker::DelayedInit() { // For organic brandcodes do not use rlz at all. Empty brandcode usually // means a chromium install. This is ok. - if (!IsBrandOrganic(brand_)) { + if (!delegate_->IsBrandOrganic(brand_)) { RecordProductEvents(first_run_, is_google_default_search_, is_google_homepage_, is_google_in_startpages_, already_ran_, omnibox_used_, homepage_used_, @@ -348,7 +275,7 @@ void RLZTracker::DelayedInit() { // If chrome has been reactivated, record the events for this brand // as well. - if (!IsBrandOrganic(reactivation_brand_)) { + if (!delegate_->IsBrandOrganic(reactivation_brand_)) { rlz_lib::SupplementaryBranding branding(reactivation_brand_.c_str()); RecordProductEvents(first_run_, is_google_default_search_, is_google_homepage_, is_google_in_startpages_, @@ -364,9 +291,8 @@ void RLZTracker::DelayedInit() { } void RLZTracker::ScheduleFinancialPing() { - BrowserThread::GetBlockingPool()->PostSequencedWorkerTaskWithShutdownBehavior( - worker_pool_token_, - FROM_HERE, + delegate_->GetBlockingPool()->PostSequencedWorkerTaskWithShutdownBehavior( + worker_pool_token_, FROM_HERE, base::Bind(&RLZTracker::PingNowImpl, base::Unretained(this)), base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); } @@ -374,14 +300,15 @@ void RLZTracker::ScheduleFinancialPing() { void RLZTracker::PingNowImpl() { TRACE_EVENT0("RLZ", "RLZTracker::PingNowImpl"); base::string16 lang; - GoogleUpdateSettings::GetLanguage(&lang); + delegate_->GetLanguage(&lang); if (lang.empty()) lang = base::ASCIIToUTF16("en"); base::string16 referral; - GoogleUpdateSettings::GetReferral(&referral); + delegate_->GetReferral(&referral); - if (!IsBrandOrganic(brand_) && SendFinancialPing(brand_, lang, referral)) { - GoogleUpdateSettings::ClearReferral(); + if (!delegate_->IsBrandOrganic(brand_) && + SendFinancialPing(brand_, lang, referral)) { + delegate_->ClearReferral(); { base::AutoLock lock(cache_lock_); @@ -389,14 +316,14 @@ void RLZTracker::PingNowImpl() { } // Prime the RLZ cache for the access points we are interested in. - GetAccessPointRlz(RLZTracker::ChromeOmnibox(), NULL); + GetAccessPointRlz(RLZTracker::ChromeOmnibox(), nullptr); #if !defined(OS_IOS) - GetAccessPointRlz(RLZTracker::ChromeHomePage(), NULL); - GetAccessPointRlz(RLZTracker::ChromeAppList(), NULL); + GetAccessPointRlz(RLZTracker::ChromeHomePage(), nullptr); + GetAccessPointRlz(RLZTracker::ChromeAppList(), nullptr); #endif // !defined(OS_IOS) } - if (!IsBrandOrganic(reactivation_brand_)) { + if (!delegate_->IsBrandOrganic(reactivation_brand_)) { rlz_lib::SupplementaryBranding branding(reactivation_brand_.c_str()); SendFinancialPing(reactivation_brand_, lang, referral); } @@ -405,70 +332,7 @@ void RLZTracker::PingNowImpl() { bool RLZTracker::SendFinancialPing(const std::string& brand, const base::string16& lang, const base::string16& referral) { - return ::SendFinancialPing(brand, lang, referral); -} - -void RLZTracker::Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) { - switch (type) { - case chrome::NOTIFICATION_OMNIBOX_OPENED_URL: - // In M-36, we made NOTIFICATION_OMNIBOX_OPENED_URL fire more often than - // it did previously. The RLZ folks want RLZ's "first search" detection - // to remain as unaffected as possible by this change. This test is - // there to keep the old behavior. - if (!content::Details<OmniboxLog>(details).ptr()->is_popup_open) - break; - RecordFirstSearch(ChromeOmnibox()); - registrar_.Remove(this, chrome::NOTIFICATION_OMNIBOX_OPENED_URL, - content::NotificationService::AllSources()); - break; -#if !defined(OS_IOS) - case content::NOTIFICATION_NAV_ENTRY_COMMITTED: { - // Firstly check if it is a Google search. - content::LoadCommittedDetails* load_details = - content::Details<content::LoadCommittedDetails>(details).ptr(); - if (load_details == NULL) - break; - - NavigationEntry* entry = load_details->entry; - if (entry == NULL) - break; - - if (google_util::IsGoogleSearchUrl(entry->GetURL())) { - // If it is a Google search, check if it originates from HOMEPAGE by - // getting the previous NavigationEntry. - NavigationController* controller = - content::Source<NavigationController>(source).ptr(); - if (controller == NULL) - break; - - int entry_index = controller->GetLastCommittedEntryIndex(); - if (entry_index < 1) - break; - - const NavigationEntry* previous_entry = controller->GetEntryAtIndex( - entry_index - 1); - - if (previous_entry == NULL) - break; - - // Make sure it is a Google web page originated from HOMEPAGE. - if (google_util::IsGoogleHomePageUrl(previous_entry->GetURL()) && - ((previous_entry->GetTransitionType() & - ui::PAGE_TRANSITION_HOME_PAGE) != 0)) { - RecordFirstSearch(ChromeHomePage()); - registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, - content::NotificationService::AllSources()); - } - } - break; - } -#endif // !defined(OS_IOS) - default: - NOTREACHED(); - break; - } + return ::rlz::SendFinancialPing(brand, lang, referral); } // static @@ -500,14 +364,13 @@ bool RLZTracker::RecordProductEventImpl(rlz_lib::Product product, bool RLZTracker::ScheduleRecordProductEvent(rlz_lib::Product product, rlz_lib::AccessPoint point, rlz_lib::Event event_id) { - if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) + if (!delegate_->IsOnUIThread()) return false; - BrowserThread::GetBlockingPool()->PostSequencedWorkerTaskWithShutdownBehavior( - worker_pool_token_, - FROM_HERE, - base::Bind(base::IgnoreResult(&RLZTracker::RecordProductEvent), - product, point, event_id), + delegate_->GetBlockingPool()->PostSequencedWorkerTaskWithShutdownBehavior( + worker_pool_token_, FROM_HERE, + base::Bind(base::IgnoreResult(&RLZTracker::RecordProductEvent), product, + point, event_id), base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); return true; @@ -530,13 +393,11 @@ void RLZTracker::RecordFirstSearch(rlz_lib::AccessPoint point) { } bool RLZTracker::ScheduleRecordFirstSearch(rlz_lib::AccessPoint point) { - if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) + if (!delegate_->IsOnUIThread()) return false; - BrowserThread::GetBlockingPool()->PostSequencedWorkerTaskWithShutdownBehavior( - worker_pool_token_, - FROM_HERE, - base::Bind(&RLZTracker::RecordFirstSearch, - base::Unretained(this), point), + delegate_->GetBlockingPool()->PostSequencedWorkerTaskWithShutdownBehavior( + worker_pool_token_, FROM_HERE, + base::Bind(&RLZTracker::RecordFirstSearch, base::Unretained(this), point), base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); return true; } @@ -551,7 +412,7 @@ bool* RLZTracker::GetAccessPointRecord(rlz_lib::AccessPoint point) { return &app_list_used_; #endif // !defined(OS_IOS) NOTREACHED(); - return NULL; + return nullptr; } // static @@ -611,13 +472,12 @@ bool RLZTracker::GetAccessPointRlzImpl(rlz_lib::AccessPoint point, } bool RLZTracker::ScheduleGetAccessPointRlz(rlz_lib::AccessPoint point) { - if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) + if (!delegate_->IsOnUIThread()) return false; - base::string16* not_used = NULL; - BrowserThread::GetBlockingPool()->PostSequencedWorkerTaskWithShutdownBehavior( - worker_pool_token_, - FROM_HERE, + base::string16* not_used = nullptr; + delegate_->GetBlockingPool()->PostSequencedWorkerTaskWithShutdownBehavior( + worker_pool_token_, FROM_HERE, base::Bind(base::IgnoreResult(&RLZTracker::GetAccessPointRlz), point, not_used), base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); @@ -637,14 +497,12 @@ void RLZTracker::ClearRlzStateImpl() { } bool RLZTracker::ScheduleClearRlzState() { - if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) + if (!delegate_->IsOnUIThread()) return false; - BrowserThread::GetBlockingPool()->PostSequencedWorkerTaskWithShutdownBehavior( - worker_pool_token_, - FROM_HERE, - base::Bind(&RLZTracker::ClearRlzStateImpl, - base::Unretained(this)), + delegate_->GetBlockingPool()->PostSequencedWorkerTaskWithShutdownBehavior( + worker_pool_token_, FROM_HERE, + base::Bind(&RLZTracker::ClearRlzStateImpl, base::Unretained(this)), base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); return true; } @@ -652,9 +510,8 @@ bool RLZTracker::ScheduleClearRlzState() { // static void RLZTracker::CleanupRlz() { - GetInstance()->rlz_cache_.clear(); - GetInstance()->registrar_.RemoveAll(); - rlz_lib::SetURLRequestContext(NULL); + GetInstance()->Cleanup(); + rlz_lib::SetURLRequestContext(nullptr); } // static @@ -668,3 +525,5 @@ void RLZTracker::RecordAppListSearch() { GetInstance()->RecordFirstSearch(RLZTracker::ChromeAppList()); } #endif + +} // namespace rlz diff --git a/chrome/browser/rlz/rlz.h b/components/rlz/rlz_tracker.h index 4fd9b9c..1236aa2 100644 --- a/chrome/browser/rlz/rlz.h +++ b/components/rlz/rlz_tracker.h @@ -2,30 +2,28 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_RLZ_RLZ_H_ -#define CHROME_BROWSER_RLZ_RLZ_H_ - -#include "build/build_config.h" - -#if defined(ENABLE_RLZ) +#ifndef COMPONENTS_RLZ_RLZ_TRACKER_H_ +#define COMPONENTS_RLZ_RLZ_TRACKER_H_ #include <map> #include <string> #include "base/basictypes.h" +#include "base/memory/scoped_ptr.h" #include "base/memory/singleton.h" #include "base/strings/string16.h" #include "base/threading/sequenced_worker_pool.h" #include "base/time/time.h" -#include "content/public/browser/notification_observer.h" -#include "content/public/browser/notification_registrar.h" #include "rlz/lib/rlz_lib.h" -class Profile; namespace net { class URLRequestContextGetter; } +namespace rlz { + +class RLZTrackerDelegate; + // RLZ is a library which is used to measure distribution scenarios. // Its job is to record certain lifetime events in the registry and to send // them encoded as a compact string at most twice. The sent data does @@ -36,8 +34,12 @@ class URLRequestContextGetter; // For partner or bundled installs, the RLZ might send more information // according to the terms disclosed in the EULA. -class RLZTracker : public content::NotificationObserver { +class RLZTracker { public: + // Sets the RLZTrackerDelegate that should be used by the global RLZTracker + // instance. Must be called before calling any other method of RLZTracker. + static void SetRlzDelegate(scoped_ptr<RLZTrackerDelegate> delegate); + // Initializes the RLZ library services for use in chrome. Schedules a delayed // task that performs the ping and registers some events when 'first-run' is // true. @@ -47,10 +49,12 @@ class RLZTracker : public content::NotificationObserver { // However, we only want this behaviour on first run. // // If the chrome brand is organic (no partners) then the pings don't occur. - static bool InitRlzFromProfileDelayed(Profile* profile, - bool first_run, - bool send_ping_immediately, - base::TimeDelta delay); + static bool InitRlzDelayed(bool first_run, + bool send_ping_immediately, + base::TimeDelta delay, + bool is_google_default_search, + bool is_google_homepage, + bool is_google_in_startpages); // Records an RLZ event. Some events can be access point independent. // Returns false it the event could not be recorded. Requires write access @@ -91,7 +95,7 @@ class RLZTracker : public content::NotificationObserver { // This method is public for use by the Singleton class. static RLZTracker* GetInstance(); - // Enables zero delay for InitRlzFromProfileDelayed. For testing only. + // Enables zero delay for InitRlzDelayed. For testing only. static void EnableZeroDelayForTesting(); #if !defined(OS_IOS) @@ -103,30 +107,15 @@ class RLZTracker : public content::NotificationObserver { // testing purposes. Production code should never need to call these. protected: RLZTracker(); - ~RLZTracker() override; - - // Called by InitRlzFromProfileDelayed with values taken from |profile|. - static bool InitRlzDelayed(bool first_run, - bool send_ping_immediately, - base::TimeDelta delay, - bool is_google_default_search, - bool is_google_homepage, - bool is_google_in_startpages); + virtual ~RLZTracker(); // Performs initialization of RLZ tracker that is purposefully delayed so // that it does not interfere with chrome startup time. virtual void DelayedInit(); - // content::NotificationObserver implementation: - void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) override; - // Used by test code to override the default RLZTracker instance returned // by GetInstance(). - void set_tracker(RLZTracker* tracker) { - tracker_ = tracker; - } + void set_tracker(RLZTracker* tracker) { tracker_ = tracker; } // Sends the financial ping to the RLZ servers and invalidates the RLZ string // cache since the response from the RLZ server may have changed then. @@ -137,20 +126,26 @@ class RLZTracker : public content::NotificationObserver { friend struct DefaultSingletonTraits<RLZTracker>; friend class base::RefCountedThreadSafe<RLZTracker>; + // Implementation called from SetRlzDelegate() static method. + void SetDelegate(scoped_ptr<RLZTrackerDelegate> delegate); + // Implementation called from InitRlzDelayed() static method. bool Init(bool first_run, bool send_ping_immediately, base::TimeDelta delay, - bool google_default_search, - bool google_default_homepage, + bool is_google_default_search, + bool is_google_homepage, bool is_google_in_startpages); + // Implementation called from CleanupRlz static method. + void Cleanup(); + // Implementation called from RecordProductEvent() static method. bool RecordProductEventImpl(rlz_lib::Product product, rlz_lib::AccessPoint point, rlz_lib::Event event_id); - // Records FIRST_SEARCH event. Called from Observe() on blocking task runner. + // Records FIRST_SEARCH event. Passed as bound callback to RLZTrackerDelegate. void RecordFirstSearch(rlz_lib::AccessPoint point); // Implementation called from GetAccessPointRlz() static method. @@ -203,6 +198,9 @@ class RLZTracker : public content::NotificationObserver { // will be returned from GetInstance() instead of the regular singleton. static RLZTracker* tracker_; + // Delegate abstracting embedder specific knowledge. Must not be null. + scoped_ptr<RLZTrackerDelegate> delegate_; + // Configuation data for RLZ tracker. Set by call to Init(). bool first_run_; bool send_ping_immediately_; @@ -233,14 +231,12 @@ class RLZTracker : public content::NotificationObserver { std::string brand_; std::string reactivation_brand_; - content::NotificationRegistrar registrar_; - // Minimum delay before sending financial ping after initialization. base::TimeDelta min_init_delay_; DISALLOW_COPY_AND_ASSIGN(RLZTracker); }; -#endif // defined(ENABLE_RLZ) +} // namespace rlz -#endif // CHROME_BROWSER_RLZ_RLZ_H_ +#endif // COMPONENTS_RLZ_RLZ_TRACKER_H_ diff --git a/chrome/browser/rlz/rlz_chromeos.cc b/components/rlz/rlz_tracker_chromeos.cc index 8f9a874..b63c934 100644 --- a/chrome/browser/rlz/rlz_chromeos.cc +++ b/components/rlz/rlz_tracker_chromeos.cc @@ -2,7 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/rlz/rlz.h" +#include "components/rlz/rlz_tracker.h" + +namespace rlz { // static rlz_lib::AccessPoint RLZTracker::ChromeOmnibox() { @@ -18,3 +20,5 @@ rlz_lib::AccessPoint RLZTracker::ChromeHomePage() { rlz_lib::AccessPoint RLZTracker::ChromeAppList() { return rlz_lib::CHROMEOS_APP_LIST; } + +} // namespace rlz diff --git a/components/rlz/rlz_tracker_delegate.cc b/components/rlz/rlz_tracker_delegate.cc new file mode 100644 index 0000000..84f35aa --- /dev/null +++ b/components/rlz/rlz_tracker_delegate.cc @@ -0,0 +1,15 @@ +// 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/rlz/rlz_tracker_delegate.h" + +namespace rlz { + +RLZTrackerDelegate::RLZTrackerDelegate() { +} + +RLZTrackerDelegate::~RLZTrackerDelegate() { +} + +} // namespace rlz diff --git a/components/rlz/rlz_tracker_delegate.h b/components/rlz/rlz_tracker_delegate.h new file mode 100644 index 0000000..d1270e4 --- /dev/null +++ b/components/rlz/rlz_tracker_delegate.h @@ -0,0 +1,86 @@ +// 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. + +#ifndef COMPONENTS_RLZ_RLZ_TRACKER_DELEGATE_H_ +#define COMPONENTS_RLZ_RLZ_TRACKER_DELEGATE_H_ + +#include <string> + +#include "base/callback_forward.h" +#include "base/macros.h" +#include "base/strings/string16.h" +#include "base/threading/sequenced_worker_pool.h" + +namespace base { +class SequencedWorkerPool; +} + +namespace net { +class URLRequestContextGetter; +} + +namespace rlz { + +// RLZTrackerDelegate is an abstract interface that provides access to embedder +// specific singletons or gives information about the embedder environment. +class RLZTrackerDelegate { + public: + RLZTrackerDelegate() {} + virtual ~RLZTrackerDelegate() {} + + // Invoked during RLZTracker cleanup, to request the cleanup of the delegate. + virtual void Cleanup() = 0; + + // Returns whether the current thread is the UI thread. + virtual bool IsOnUIThread() = 0; + + // Returns the SequencedWorkerPool where the RLZTracker will post its tasks + // that should be executed in the background. + virtual base::SequencedWorkerPool* GetBlockingPool() = 0; + + // Returns the URLRequestContextGetter to use for network connections. + virtual net::URLRequestContextGetter* GetRequestContext() = 0; + + // Returns the brand code for the installation of Chrome in |brand| and a + // boolean indicating whether the operation was a success or not. + virtual bool GetBrand(std::string* brand) = 0; + + // Returns whether |brand| is an organic brand. + virtual bool IsBrandOrganic(const std::string& brand) = 0; + + // Returns the reactivation brand code for Chrome in |brand| and a boolean + // indicating whether the operation was a success or not. + virtual bool GetReactivationBrand(std::string* brand) = 0; + + // Returns true if RLZTracker should ignore initial delay for testing. + virtual bool ShouldEnableZeroDelayForTesting() = 0; + + // Returns the installation language in |language| and a boolean indicating + // whether the operation was a success or not. + virtual bool GetLanguage(base::string16* language) = 0; + + // Returns the referral code in |referral| and a boolean indicating whether + // the operation was a success or not. Deprecated. + virtual bool GetReferral(base::string16* referral) = 0; + + // Clears the referral code. Deprecated. + virtual bool ClearReferral() = 0; + + // Registers |callback| to be invoked the next time the user perform a search + // using Google search engine via the omnibox. Callback will invoked at most + // once. + virtual void SetOmniboxSearchCallback(const base::Closure& callback) = 0; + + // Registers |callback| to be invoked the next time the user perform a search + // using Google search engine via the homepage. Callback will invoked at most + // once. + virtual void SetHomepageSearchCallback(const base::Closure& callback) = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(RLZTrackerDelegate); +}; + +} // namespace rlz + +#endif // COMPONENTS_RLZ_RLZ_TRACKER_DELEGATE_H_ diff --git a/components/rlz/rlz_tracker_ios.cc b/components/rlz/rlz_tracker_ios.cc new file mode 100644 index 0000000..e2b110c --- /dev/null +++ b/components/rlz/rlz_tracker_ios.cc @@ -0,0 +1,19 @@ +// 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 "components/rlz/rlz_tracker.h" + +#include "rlz/lib/rlz_lib.h" +#include "ui/base/device_form_factor.h" + +namespace rlz { + +// static +rlz_lib::AccessPoint RLZTracker::ChromeOmnibox() { + return ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_PHONE + ? rlz_lib::CHROME_IOS_OMNIBOX_MOBILE + : rlz_lib::CHROME_IOS_OMNIBOX_TABLET; +} + +} // namespace rlz diff --git a/chrome/browser/rlz/rlz_mac.cc b/components/rlz/rlz_tracker_mac.cc index d3e32a9..186f9e6 100644 --- a/chrome/browser/rlz/rlz_mac.cc +++ b/components/rlz/rlz_tracker_mac.cc @@ -2,7 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/rlz/rlz.h" +#include "components/rlz/rlz_tracker.h" + +namespace rlz { // static rlz_lib::AccessPoint RLZTracker::ChromeOmnibox() { @@ -18,3 +20,5 @@ rlz_lib::AccessPoint RLZTracker::ChromeHomePage() { rlz_lib::AccessPoint RLZTracker::ChromeAppList() { return rlz_lib::CHROME_MAC_APP_LIST; } + +} // namespace rlz diff --git a/chrome/browser/rlz/rlz_unittest.cc b/components/rlz/rlz_tracker_unittest.cc index 8aeb09c..eb33d89 100644 --- a/chrome/browser/rlz/rlz_unittest.cc +++ b/components/rlz/rlz_tracker_unittest.cc @@ -2,53 +2,132 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/rlz/rlz.h" +#include "components/rlz/rlz_tracker.h" +#include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" +#include "base/message_loop/message_loop.h" #include "base/strings/utf_string_conversions.h" +#include "base/thread_task_runner_handle.h" +#include "base/threading/sequenced_worker_pool.h" #include "base/time/time.h" -#include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/google/google_brand.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/installer/util/browser_distribution.h" -#include "chrome/installer/util/google_update_constants.h" -#include "chrome/test/base/chrome_render_view_host_test_harness.h" -#include "components/metrics/proto/omnibox_event.pb.h" -#include "components/omnibox/browser/autocomplete_controller.h" -#include "components/omnibox/browser/omnibox_log.h" -#include "content/public/browser/navigation_details.h" -#include "content/public/browser/navigation_entry.h" -#include "content/public/browser/notification_details.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/notification_source.h" -#include "content/public/test/test_renderer_host.h" +#include "components/rlz/rlz_tracker_delegate.h" +#include "net/url_request/url_request_test_util.h" #include "rlz/test/rlz_test_helpers.h" #include "testing/gtest/include/gtest/gtest.h" -#include "url/gurl.h" -#if defined(OS_WIN) -#include "base/win/registry.h" +#if defined(OS_IOS) +#include "ui/base/device_form_factor.h" #endif -using content::NavigationEntry; -using content::LoadCommittedDetails; using testing::AssertionResult; using testing::AssertionSuccess; using testing::AssertionFailure; -#if defined(OS_WIN) -using base::win::RegKey; -#endif - +namespace rlz { namespace { +class TestRLZTrackerDelegate : public RLZTrackerDelegate { + public: + TestRLZTrackerDelegate() + : worker_pool_(new base::SequencedWorkerPool(1, "TestRLZTracker")), + request_context_getter_(new net::TestURLRequestContextGetter( + base::ThreadTaskRunnerHandle::Get())) {} + + ~TestRLZTrackerDelegate() override { worker_pool_->Shutdown(); } + + void set_brand(const char* brand) { brand_override_ = brand; } + + void set_reactivation_brand(const char* reactivation_brand) { + // TODO(thakis): Reactivation doesn't exist on Mac yet. + reactivation_brand_override_ = reactivation_brand; + } + + void SimulateOmniboxUsage() { + using std::swap; + base::Closure callback; + swap(callback, on_omnibox_search_callback_); + if (!callback.is_null()) + callback.Run(); + } + + void SimulateHomepageUsage() { + using std::swap; + base::Closure callback; + swap(callback, on_homepage_search_callback_); + if (!callback.is_null()) + callback.Run(); + } + + // RLZTrackerDelegate implementation. + void Cleanup() override { + on_omnibox_search_callback_.Reset(); + on_homepage_search_callback_.Reset(); + } + + bool IsOnUIThread() override { return true; } + + base::SequencedWorkerPool* GetBlockingPool() override { + return worker_pool_.get(); + } + + net::URLRequestContextGetter* GetRequestContext() override { + return request_context_getter_.get(); + } + + bool GetBrand(std::string* brand) override { + *brand = brand_override_; + return true; + } + + bool IsBrandOrganic(const std::string& brand) override { + return brand.empty() || brand == "GGLS" || brand == "GGRS"; + } + + bool GetReactivationBrand(std::string* brand) override { + *brand = reactivation_brand_override_; + return true; + } + + bool ShouldEnableZeroDelayForTesting() override { return true; } + + bool GetLanguage(base::string16* language) override { return true; } + + bool GetReferral(base::string16* referral) override { return true; } + + bool ClearReferral() override { return true; } + + void SetOmniboxSearchCallback(const base::Closure& callback) override { + DCHECK(!callback.is_null()); + on_omnibox_search_callback_ = callback; + } + + void SetHomepageSearchCallback(const base::Closure& callback) override { + DCHECK(!callback.is_null()); + on_homepage_search_callback_ = callback; + } + + private: + scoped_refptr<base::SequencedWorkerPool> worker_pool_; + scoped_refptr<net::URLRequestContextGetter> request_context_getter_; + + std::string brand_override_; + std::string reactivation_brand_override_; + base::Closure on_omnibox_search_callback_; + base::Closure on_homepage_search_callback_; + + DISALLOW_COPY_AND_ASSIGN(TestRLZTrackerDelegate); +}; + // Dummy RLZ string for the access points. const char kOmniboxRlzString[] = "test_omnibox"; -const char kHomepageRlzString[] = "test_homepage"; -const char kAppListRlzString[] = "test_applist"; const char kNewOmniboxRlzString[] = "new_omnibox"; +#if !defined(OS_IOS) +const char kHomepageRlzString[] = "test_homepage"; const char kNewHomepageRlzString[] = "new_homepage"; +const char kAppListRlzString[] = "test_applist"; const char kNewAppListRlzString[] = "new_applist"; +#endif // !defined(OS_IOS) // Some helper macros to test it a string contains/does not contain a substring. @@ -56,7 +135,7 @@ AssertionResult CmpHelperSTRC(const char* str_expression, const char* substr_expression, const char* str, const char* substr) { - if (NULL != strstr(str, substr)) { + if (nullptr != strstr(str, substr)) { return AssertionSuccess(); } @@ -69,7 +148,7 @@ AssertionResult CmpHelperSTRNC(const char* str_expression, const char* substr_expression, const char* str, const char* substr) { - if (NULL == strstr(str, substr)) { + if (nullptr == strstr(str, substr)) { return AssertionSuccess(); } @@ -92,15 +171,10 @@ class TestRLZTracker : public RLZTracker { public: using RLZTracker::InitRlzDelayed; using RLZTracker::DelayedInit; - using RLZTracker::Observe; - TestRLZTracker() : assume_not_ui_thread_(true) { - set_tracker(this); - } + TestRLZTracker() : assume_not_ui_thread_(true) { set_tracker(this); } - ~TestRLZTracker() override { - set_tracker(NULL); - } + ~TestRLZTracker() override { set_tracker(nullptr); } bool was_ping_sent_for_brand(const std::string& brand) const { return pinged_brands_.count(brand) > 0; @@ -118,13 +192,11 @@ class TestRLZTracker : public RLZTracker { DelayedInit(); } - void ScheduleFinancialPing() override { - PingNowImpl(); - } + void ScheduleFinancialPing() override { PingNowImpl(); } bool ScheduleRecordProductEvent(rlz_lib::Product product, - rlz_lib::AccessPoint point, - rlz_lib::Event event_id) override { + rlz_lib::AccessPoint point, + rlz_lib::Event event_id) override { return !assume_not_ui_thread_; } @@ -137,14 +209,12 @@ class TestRLZTracker : public RLZTracker { } #if defined(OS_CHROMEOS) - bool ScheduleClearRlzState() override { - return !assume_not_ui_thread_; - } + bool ScheduleClearRlzState() override { return !assume_not_ui_thread_; } #endif bool SendFinancialPing(const std::string& brand, - const base::string16& lang, - const base::string16& referral) override { + const base::string16& lang, + const base::string16& referral) override { // Don't ping the server during tests, just pretend as if we did. EXPECT_FALSE(brand.empty()); pinged_brands_.insert(brand); @@ -153,10 +223,12 @@ class TestRLZTracker : public RLZTracker { // done. rlz_lib::SetAccessPointRlz(RLZTracker::ChromeOmnibox(), kNewOmniboxRlzString); +#if !defined(OS_IOS) rlz_lib::SetAccessPointRlz(RLZTracker::ChromeHomePage(), kNewHomepageRlzString); rlz_lib::SetAccessPointRlz(RLZTracker::ChromeAppList(), kNewAppListRlzString); +#endif // !defined(OS_IOS) return true; } @@ -166,16 +238,13 @@ class TestRLZTracker : public RLZTracker { DISALLOW_COPY_AND_ASSIGN(TestRLZTracker); }; -class RlzLibTest : public ChromeRenderViewHostTestHarness { +class RlzLibTest : public testing::Test { protected: void SetUp() override; void TearDown() override; void SetMainBrand(const char* brand); void SetReactivationBrand(const char* brand); -#if defined(OS_WIN) - void SetRegistryBrandValue(const wchar_t* name, const char* brand); -#endif void SimulateOmniboxUsage(); void SimulateHomepageUsage(); @@ -186,17 +255,19 @@ class RlzLibTest : public ChromeRenderViewHostTestHarness { void ExpectRlzPingSent(bool expected); void ExpectReactivationRlzPingSent(bool expected); + base::MessageLoop message_loop_; + TestRLZTrackerDelegate* delegate_; scoped_ptr<TestRLZTracker> tracker_; RlzLibTestNoMachineStateHelper m_rlz_test_helper_; -#if defined(OS_POSIX) - scoped_ptr<google_brand::BrandForTesting> brand_override_; -#endif }; void RlzLibTest::SetUp() { - ChromeRenderViewHostTestHarness::SetUp(); + testing::Test::SetUp(); m_rlz_test_helper_.SetUp(); + + delegate_ = new TestRLZTrackerDelegate; tracker_.reset(new TestRLZTracker()); + RLZTracker::SetRlzDelegate(make_scoped_ptr(delegate_)); // Make sure a non-organic brand code is set in the registry or the RLZTracker // is pretty much a no-op. @@ -205,86 +276,32 @@ void RlzLibTest::SetUp() { } void RlzLibTest::TearDown() { + delegate_ = nullptr; tracker_.reset(); - ChromeRenderViewHostTestHarness::TearDown(); + testing::Test::TearDown(); m_rlz_test_helper_.TearDown(); } void RlzLibTest::SetMainBrand(const char* brand) { -#if defined(OS_WIN) - SetRegistryBrandValue(google_update::kRegRLZBrandField, brand); -#elif defined(OS_POSIX) - brand_override_.reset(new google_brand::BrandForTesting(brand)); -#endif - std::string check_brand; - google_brand::GetBrand(&check_brand); - EXPECT_EQ(brand, check_brand); + delegate_->set_brand(brand); } void RlzLibTest::SetReactivationBrand(const char* brand) { - // TODO(thakis): Reactivation doesn't exist on Mac yet. -#if defined(OS_WIN) - SetRegistryBrandValue(google_update::kRegRLZReactivationBrandField, brand); - std::string check_brand; - google_brand::GetReactivationBrand(&check_brand); - EXPECT_EQ(brand, check_brand); -#endif + delegate_->set_reactivation_brand(brand); } -#if defined(OS_WIN) -void RlzLibTest::SetRegistryBrandValue(const wchar_t* name, - const char* brand) { - BrowserDistribution* dist = BrowserDistribution::GetDistribution(); - base::string16 reg_path = dist->GetStateKey(); - RegKey key(HKEY_CURRENT_USER, reg_path.c_str(), KEY_SET_VALUE); - if (*brand == 0) { - LONG result = key.DeleteValue(name); - ASSERT_TRUE(ERROR_SUCCESS == result || ERROR_FILE_NOT_FOUND == result); - } else { - base::string16 brand16 = base::ASCIIToUTF16(brand); - ASSERT_EQ(ERROR_SUCCESS, key.WriteValue(name, brand16.c_str())); - } -} -#endif - void RlzLibTest::SimulateOmniboxUsage() { - // Create a dummy OmniboxLog object. The 'is_popup_open' field needs to be - // true to trigger record of the first search. All other fields are passed in - // with empty or invalid values. - AutocompleteResult empty_result; - OmniboxLog dummy(base::string16(), false, metrics::OmniboxInputType::INVALID, - true, 0, false, -1, - metrics::OmniboxEventProto::INVALID_SPEC, - base::TimeDelta::FromSeconds(0), 0, - base::TimeDelta::FromSeconds(0), - AutocompleteResult()); - - tracker_->Observe(chrome::NOTIFICATION_OMNIBOX_OPENED_URL, - content::NotificationService::AllSources(), - content::Details<OmniboxLog>(&dummy)); + delegate_->SimulateOmniboxUsage(); } void RlzLibTest::SimulateHomepageUsage() { - GURL home_url = GURL("https://www.google.com/"); - GURL search_url = GURL("https://www.google.com/#q=search"); - - content::RenderFrameHostTester* rfht = - content::RenderFrameHostTester::For(main_rfh()); - - // Ensure the RenderFrame is initialized before simulating events coming from - // it. - rfht->InitializeRenderFrameIfNeeded(); - - // Simulate a navigation to homepage first. - rfht->SendNavigateWithTransition( - 0, 0, true, home_url, ui::PAGE_TRANSITION_HOME_PAGE); - // Then simulate a search from homepage. - rfht->SendNavigateWithTransition( - 1, 0, true, search_url, ui::PAGE_TRANSITION_LINK); + delegate_->SimulateHomepageUsage(); } void RlzLibTest::SimulateAppListUsage() { +#if !defined(OS_IOS) RLZTracker::RecordAppListSearch(); +#endif // !defined(OS_IOS) } void RlzLibTest::InvokeDelayedInit() { @@ -303,13 +320,13 @@ void RlzLibTest::ExpectEventRecorded(const char* event_name, bool expected) { void RlzLibTest::ExpectRlzPingSent(bool expected) { std::string brand; - google_brand::GetBrand(&brand); + delegate_->GetBrand(&brand); EXPECT_EQ(expected, tracker_->was_ping_sent_for_brand(brand.c_str())); } void RlzLibTest::ExpectReactivationRlzPingSent(bool expected) { std::string brand; - google_brand::GetReactivationBrand(&brand); + delegate_->GetReactivationBrand(&brand); EXPECT_EQ(expected, tracker_->was_ping_sent_for_brand(brand.c_str())); } @@ -343,6 +360,9 @@ void RlzLibTest::ExpectReactivationRlzPingSent(bool expected) { // On Mac, C5 / C6 / C8 are sent instead of C1 / C2 / C7. // On ChromeOS, CA / CB / CC are sent, respectively. // +// On iOS, only the omnibox events are recorded, and the value send depends +// on the device form factor (phone or tablet). +// // Variations on the above scenarios: // // - if the delay specified to InitRlzDelayed() is negative, then the RLZ @@ -357,11 +377,19 @@ const char kOmniboxFirstSearch[] = "C1F"; const char kHomepageInstall[] = "C2I"; const char kHomepageSetToGoogle[] = "C2S"; -const char kHomepageFirstSeach[] = "C2F"; +const char kHomepageFirstSearch[] = "C2F"; const char kAppListInstall[] = "C7I"; const char kAppListSetToGoogle[] = "C7S"; const char kAppListFirstSearch[] = "C7F"; +#elif defined(OS_IOS) +const char kOmniboxInstallPhone[] = "CDI"; +const char kOmniboxSetToGooglePhone[] = "CDS"; +const char kOmniboxFirstSearchPhone[] = "CDF"; + +const char kOmniboxInstallTablet[] = "C9I"; +const char kOmniboxSetToGoogleTablet[] = "C9S"; +const char kOmniboxFirstSearchTablet[] = "C9F"; #elif defined(OS_MACOSX) const char kOmniboxInstall[] = "C5I"; const char kOmniboxSetToGoogle[] = "C5S"; @@ -369,7 +397,7 @@ const char kOmniboxFirstSearch[] = "C5F"; const char kHomepageInstall[] = "C6I"; const char kHomepageSetToGoogle[] = "C6S"; -const char kHomepageFirstSeach[] = "C6F"; +const char kHomepageFirstSearch[] = "C6F"; const char kAppListInstall[] = "C8I"; const char kAppListSetToGoogle[] = "C8S"; @@ -381,39 +409,71 @@ const char kOmniboxFirstSearch[] = "CAF"; const char kHomepageInstall[] = "CBI"; const char kHomepageSetToGoogle[] = "CBS"; -const char kHomepageFirstSeach[] = "CBF"; +const char kHomepageFirstSearch[] = "CBF"; const char kAppListInstall[] = "CCI"; const char kAppListSetToGoogle[] = "CCS"; const char kAppListFirstSearch[] = "CCF"; #endif +const char* OmniboxInstall() { +#if defined(OS_IOS) + return ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_TABLET + ? kOmniboxInstallTablet + : kOmniboxInstallPhone; +#else + return kOmniboxInstall; +#endif +} + +const char* OmniboxSetToGoogle() { +#if defined(OS_IOS) + return ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_TABLET + ? kOmniboxSetToGoogleTablet + : kOmniboxSetToGooglePhone; +#else + return kOmniboxSetToGoogle; +#endif +} + +const char* OmniboxFirstSearch() { +#if defined(OS_IOS) + return ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_TABLET + ? kOmniboxFirstSearchTablet + : kOmniboxFirstSearchPhone; +#else + return kOmniboxFirstSearch; +#endif +} + const base::TimeDelta kDelay = base::TimeDelta::FromMilliseconds(20); TEST_F(RlzLibTest, RecordProductEvent) { RLZTracker::RecordProductEvent(rlz_lib::CHROME, RLZTracker::ChromeOmnibox(), rlz_lib::FIRST_SEARCH); - ExpectEventRecorded(kOmniboxFirstSearch, true); + ExpectEventRecorded(OmniboxFirstSearch(), true); } TEST_F(RlzLibTest, QuickStopAfterStart) { TestRLZTracker::InitRlzDelayed(true, false, kDelay, true, true, true); // Omnibox events. - ExpectEventRecorded(kOmniboxInstall, false); - ExpectEventRecorded(kOmniboxSetToGoogle, false); - ExpectEventRecorded(kOmniboxFirstSearch, false); + ExpectEventRecorded(OmniboxInstall(), false); + ExpectEventRecorded(OmniboxSetToGoogle(), false); + ExpectEventRecorded(OmniboxFirstSearch(), false); +#if !defined(OS_IOS) // Home page events. ExpectEventRecorded(kHomepageInstall, false); ExpectEventRecorded(kHomepageSetToGoogle, false); - ExpectEventRecorded(kHomepageFirstSeach, false); + ExpectEventRecorded(kHomepageFirstSearch, false); // App list events. ExpectEventRecorded(kAppListInstall, false); ExpectEventRecorded(kAppListSetToGoogle, false); ExpectEventRecorded(kAppListFirstSearch, false); +#endif // !defined(OS_IOS) ExpectRlzPingSent(false); } @@ -423,19 +483,21 @@ TEST_F(RlzLibTest, DelayedInitOnly) { InvokeDelayedInit(); // Omnibox events. - ExpectEventRecorded(kOmniboxInstall, true); - ExpectEventRecorded(kOmniboxSetToGoogle, true); - ExpectEventRecorded(kOmniboxFirstSearch, false); + ExpectEventRecorded(OmniboxInstall(), true); + ExpectEventRecorded(OmniboxSetToGoogle(), true); + ExpectEventRecorded(OmniboxFirstSearch(), false); +#if !defined(OS_IOS) // Home page events. ExpectEventRecorded(kHomepageInstall, true); ExpectEventRecorded(kHomepageSetToGoogle, true); - ExpectEventRecorded(kHomepageFirstSeach, false); + ExpectEventRecorded(kHomepageFirstSearch, false); // App list events. ExpectEventRecorded(kAppListInstall, true); ExpectEventRecorded(kAppListSetToGoogle, true); ExpectEventRecorded(kAppListFirstSearch, false); +#endif // !defined(OS_IOS) ExpectRlzPingSent(true); } @@ -445,19 +507,21 @@ TEST_F(RlzLibTest, DelayedInitOnlyGoogleAsStartup) { InvokeDelayedInit(); // Omnibox events. - ExpectEventRecorded(kOmniboxInstall, true); - ExpectEventRecorded(kOmniboxSetToGoogle, false); - ExpectEventRecorded(kOmniboxFirstSearch, false); + ExpectEventRecorded(OmniboxInstall(), true); + ExpectEventRecorded(OmniboxSetToGoogle(), false); + ExpectEventRecorded(OmniboxFirstSearch(), false); +#if !defined(OS_IOS) // Home page events. ExpectEventRecorded(kHomepageInstall, true); ExpectEventRecorded(kHomepageSetToGoogle, true); - ExpectEventRecorded(kHomepageFirstSeach, true); + ExpectEventRecorded(kHomepageFirstSearch, true); // App list events. ExpectEventRecorded(kAppListInstall, true); ExpectEventRecorded(kAppListSetToGoogle, false); ExpectEventRecorded(kAppListFirstSearch, false); +#endif // !defined(OS_IOS) ExpectRlzPingSent(true); } @@ -467,19 +531,21 @@ TEST_F(RlzLibTest, DelayedInitOnlyNoFirstRunNoRlzStrings) { InvokeDelayedInit(); // Omnibox events. - ExpectEventRecorded(kOmniboxInstall, true); - ExpectEventRecorded(kOmniboxSetToGoogle, true); - ExpectEventRecorded(kOmniboxFirstSearch, false); + ExpectEventRecorded(OmniboxInstall(), true); + ExpectEventRecorded(OmniboxSetToGoogle(), true); + ExpectEventRecorded(OmniboxFirstSearch(), false); +#if !defined(OS_IOS) // Home page events. ExpectEventRecorded(kHomepageInstall, true); ExpectEventRecorded(kHomepageSetToGoogle, true); - ExpectEventRecorded(kHomepageFirstSeach, false); + ExpectEventRecorded(kHomepageFirstSearch, false); // App list events. ExpectEventRecorded(kAppListInstall, true); ExpectEventRecorded(kAppListSetToGoogle, true); ExpectEventRecorded(kAppListFirstSearch, false); +#endif // !defined(OS_IOS) ExpectRlzPingSent(true); } @@ -489,19 +555,21 @@ TEST_F(RlzLibTest, DelayedInitOnlyNoFirstRunNoRlzStringsGoogleAsStartup) { InvokeDelayedInit(); // Omnibox events. - ExpectEventRecorded(kOmniboxInstall, true); - ExpectEventRecorded(kOmniboxSetToGoogle, false); - ExpectEventRecorded(kOmniboxFirstSearch, false); + ExpectEventRecorded(OmniboxInstall(), true); + ExpectEventRecorded(OmniboxSetToGoogle(), false); + ExpectEventRecorded(OmniboxFirstSearch(), false); +#if !defined(OS_IOS) // Home page events. ExpectEventRecorded(kHomepageInstall, true); ExpectEventRecorded(kHomepageSetToGoogle, true); - ExpectEventRecorded(kHomepageFirstSeach, true); + ExpectEventRecorded(kHomepageFirstSearch, true); // App list events. ExpectEventRecorded(kAppListInstall, true); ExpectEventRecorded(kAppListSetToGoogle, false); ExpectEventRecorded(kAppListFirstSearch, false); +#endif // !defined(OS_IOS) ExpectRlzPingSent(true); } @@ -510,26 +578,30 @@ TEST_F(RlzLibTest, DelayedInitOnlyNoFirstRun) { // Set some dummy RLZ strings to simulate that we already ran before and // performed a successful ping to the RLZ server. rlz_lib::SetAccessPointRlz(RLZTracker::ChromeOmnibox(), kOmniboxRlzString); +#if !defined(OS_IOS) rlz_lib::SetAccessPointRlz(RLZTracker::ChromeHomePage(), kHomepageRlzString); rlz_lib::SetAccessPointRlz(RLZTracker::ChromeAppList(), kAppListRlzString); +#endif // !defined(OS_IOS) TestRLZTracker::InitRlzDelayed(false, false, kDelay, true, true, true); InvokeDelayedInit(); // Omnibox events. - ExpectEventRecorded(kOmniboxInstall, true); - ExpectEventRecorded(kOmniboxSetToGoogle, false); - ExpectEventRecorded(kOmniboxFirstSearch, false); + ExpectEventRecorded(OmniboxInstall(), true); + ExpectEventRecorded(OmniboxSetToGoogle(), false); + ExpectEventRecorded(OmniboxFirstSearch(), false); +#if !defined(OS_IOS) // Home page events. ExpectEventRecorded(kHomepageInstall, true); ExpectEventRecorded(kHomepageSetToGoogle, false); - ExpectEventRecorded(kHomepageFirstSeach, true); + ExpectEventRecorded(kHomepageFirstSearch, true); // App list events. ExpectEventRecorded(kAppListInstall, true); ExpectEventRecorded(kAppListSetToGoogle, false); ExpectEventRecorded(kAppListFirstSearch, false); +#endif // !defined(OS_IOS) ExpectRlzPingSent(true); } @@ -539,19 +611,21 @@ TEST_F(RlzLibTest, DelayedInitOnlyNoGoogleDefaultSearchOrHomepageOrStartup) { InvokeDelayedInit(); // Omnibox events. - ExpectEventRecorded(kOmniboxInstall, true); - ExpectEventRecorded(kOmniboxSetToGoogle, false); - ExpectEventRecorded(kOmniboxFirstSearch, false); + ExpectEventRecorded(OmniboxInstall(), true); + ExpectEventRecorded(OmniboxSetToGoogle(), false); + ExpectEventRecorded(OmniboxFirstSearch(), false); +#if !defined(OS_IOS) // Home page events. ExpectEventRecorded(kHomepageInstall, true); ExpectEventRecorded(kHomepageSetToGoogle, false); - ExpectEventRecorded(kHomepageFirstSeach, false); + ExpectEventRecorded(kHomepageFirstSearch, false); // App list events. ExpectEventRecorded(kAppListInstall, true); ExpectEventRecorded(kAppListSetToGoogle, false); ExpectEventRecorded(kAppListFirstSearch, false); +#endif // !defined(OS_IOS) ExpectRlzPingSent(true); } @@ -561,19 +635,21 @@ TEST_F(RlzLibTest, OmniboxUsageOnly) { SimulateOmniboxUsage(); // Omnibox events. - ExpectEventRecorded(kOmniboxInstall, false); - ExpectEventRecorded(kOmniboxSetToGoogle, false); - ExpectEventRecorded(kOmniboxFirstSearch, true); + ExpectEventRecorded(OmniboxInstall(), false); + ExpectEventRecorded(OmniboxSetToGoogle(), false); + ExpectEventRecorded(OmniboxFirstSearch(), true); +#if !defined(OS_IOS) // Home page events. ExpectEventRecorded(kHomepageInstall, false); ExpectEventRecorded(kHomepageSetToGoogle, false); - ExpectEventRecorded(kHomepageFirstSeach, false); + ExpectEventRecorded(kHomepageFirstSearch, false); // App list events. ExpectEventRecorded(kAppListInstall, false); ExpectEventRecorded(kAppListSetToGoogle, false); ExpectEventRecorded(kAppListFirstSearch, false); +#endif // !defined(OS_IOS) ExpectRlzPingSent(false); } @@ -583,19 +659,21 @@ TEST_F(RlzLibTest, HomepageUsageOnly) { SimulateHomepageUsage(); // Omnibox events. - ExpectEventRecorded(kOmniboxInstall, false); - ExpectEventRecorded(kOmniboxSetToGoogle, false); - ExpectEventRecorded(kOmniboxFirstSearch, false); + ExpectEventRecorded(OmniboxInstall(), false); + ExpectEventRecorded(OmniboxSetToGoogle(), false); + ExpectEventRecorded(OmniboxFirstSearch(), false); +#if !defined(OS_IOS) // Home page events. ExpectEventRecorded(kHomepageInstall, false); ExpectEventRecorded(kHomepageSetToGoogle, false); - ExpectEventRecorded(kHomepageFirstSeach, true); + ExpectEventRecorded(kHomepageFirstSearch, true); // App list events. ExpectEventRecorded(kAppListInstall, false); ExpectEventRecorded(kAppListSetToGoogle, false); ExpectEventRecorded(kAppListFirstSearch, false); +#endif // !defined(OS_IOS) ExpectRlzPingSent(false); } @@ -605,19 +683,21 @@ TEST_F(RlzLibTest, AppListUsageOnly) { SimulateAppListUsage(); // Omnibox events. - ExpectEventRecorded(kOmniboxInstall, false); - ExpectEventRecorded(kOmniboxSetToGoogle, false); - ExpectEventRecorded(kOmniboxFirstSearch, false); + ExpectEventRecorded(OmniboxInstall(), false); + ExpectEventRecorded(OmniboxSetToGoogle(), false); + ExpectEventRecorded(OmniboxFirstSearch(), false); +#if !defined(OS_IOS) // Home page events. ExpectEventRecorded(kHomepageInstall, false); ExpectEventRecorded(kHomepageSetToGoogle, false); - ExpectEventRecorded(kHomepageFirstSeach, false); + ExpectEventRecorded(kHomepageFirstSearch, false); // App list events. ExpectEventRecorded(kAppListInstall, false); ExpectEventRecorded(kAppListSetToGoogle, false); ExpectEventRecorded(kAppListFirstSearch, true); +#endif // !defined(OS_IOS) ExpectRlzPingSent(false); } @@ -630,19 +710,21 @@ TEST_F(RlzLibTest, UsageBeforeDelayedInit) { InvokeDelayedInit(); // Omnibox events. - ExpectEventRecorded(kOmniboxInstall, true); - ExpectEventRecorded(kOmniboxSetToGoogle, true); - ExpectEventRecorded(kOmniboxFirstSearch, true); + ExpectEventRecorded(OmniboxInstall(), true); + ExpectEventRecorded(OmniboxSetToGoogle(), true); + ExpectEventRecorded(OmniboxFirstSearch(), true); +#if !defined(OS_IOS) // Home page events. ExpectEventRecorded(kHomepageInstall, true); ExpectEventRecorded(kHomepageSetToGoogle, true); - ExpectEventRecorded(kHomepageFirstSeach, true); + ExpectEventRecorded(kHomepageFirstSearch, true); // App list events. ExpectEventRecorded(kAppListInstall, true); ExpectEventRecorded(kAppListSetToGoogle, true); ExpectEventRecorded(kAppListFirstSearch, true); +#endif // !defined(OS_IOS) ExpectRlzPingSent(true); } @@ -655,19 +737,21 @@ TEST_F(RlzLibTest, UsageAfterDelayedInit) { SimulateAppListUsage(); // Omnibox events. - ExpectEventRecorded(kOmniboxInstall, true); - ExpectEventRecorded(kOmniboxSetToGoogle, true); - ExpectEventRecorded(kOmniboxFirstSearch, true); + ExpectEventRecorded(OmniboxInstall(), true); + ExpectEventRecorded(OmniboxSetToGoogle(), true); + ExpectEventRecorded(OmniboxFirstSearch(), true); +#if !defined(OS_IOS) // Home page events. ExpectEventRecorded(kHomepageInstall, true); ExpectEventRecorded(kHomepageSetToGoogle, true); - ExpectEventRecorded(kHomepageFirstSeach, true); + ExpectEventRecorded(kHomepageFirstSearch, true); // App list events. ExpectEventRecorded(kAppListInstall, true); ExpectEventRecorded(kAppListSetToGoogle, true); ExpectEventRecorded(kAppListFirstSearch, true); +#endif // !defined(OS_IOS) ExpectRlzPingSent(true); } @@ -677,19 +761,21 @@ TEST_F(RlzLibTest, OmniboxUsageSendsPingWhenSendPingImmediately) { SimulateOmniboxUsage(); // Omnibox events. - ExpectEventRecorded(kOmniboxInstall, true); - ExpectEventRecorded(kOmniboxSetToGoogle, true); - ExpectEventRecorded(kOmniboxFirstSearch, true); + ExpectEventRecorded(OmniboxInstall(), true); + ExpectEventRecorded(OmniboxSetToGoogle(), true); + ExpectEventRecorded(OmniboxFirstSearch(), true); +#if !defined(OS_IOS) // Home page events. ExpectEventRecorded(kHomepageInstall, true); ExpectEventRecorded(kHomepageSetToGoogle, true); - ExpectEventRecorded(kHomepageFirstSeach, false); + ExpectEventRecorded(kHomepageFirstSearch, false); // App list events. ExpectEventRecorded(kAppListInstall, true); ExpectEventRecorded(kAppListSetToGoogle, true); ExpectEventRecorded(kAppListFirstSearch, false); +#endif // !defined(OS_IOS) ExpectRlzPingSent(true); } @@ -699,19 +785,21 @@ TEST_F(RlzLibTest, HomepageUsageDoesNotSendPingWhenSendPingImmediately) { SimulateHomepageUsage(); // Omnibox events. - ExpectEventRecorded(kOmniboxInstall, false); - ExpectEventRecorded(kOmniboxSetToGoogle, false); - ExpectEventRecorded(kOmniboxFirstSearch, false); + ExpectEventRecorded(OmniboxInstall(), false); + ExpectEventRecorded(OmniboxSetToGoogle(), false); + ExpectEventRecorded(OmniboxFirstSearch(), false); +#if !defined(OS_IOS) // Home page events. ExpectEventRecorded(kHomepageInstall, false); ExpectEventRecorded(kHomepageSetToGoogle, false); - ExpectEventRecorded(kHomepageFirstSeach, true); + ExpectEventRecorded(kHomepageFirstSearch, true); // App list events. ExpectEventRecorded(kAppListInstall, false); ExpectEventRecorded(kAppListSetToGoogle, false); ExpectEventRecorded(kAppListFirstSearch, false); +#endif // !defined(OS_IOS) ExpectRlzPingSent(false); } @@ -721,19 +809,21 @@ TEST_F(RlzLibTest, StartupUsageDoesNotSendPingWhenSendPingImmediately) { SimulateHomepageUsage(); // Omnibox events. - ExpectEventRecorded(kOmniboxInstall, false); - ExpectEventRecorded(kOmniboxSetToGoogle, false); - ExpectEventRecorded(kOmniboxFirstSearch, false); + ExpectEventRecorded(OmniboxInstall(), false); + ExpectEventRecorded(OmniboxSetToGoogle(), false); + ExpectEventRecorded(OmniboxFirstSearch(), false); +#if !defined(OS_IOS) // Home page events. ExpectEventRecorded(kHomepageInstall, false); ExpectEventRecorded(kHomepageSetToGoogle, false); - ExpectEventRecorded(kHomepageFirstSeach, true); + ExpectEventRecorded(kHomepageFirstSearch, true); // App list events. ExpectEventRecorded(kAppListInstall, false); ExpectEventRecorded(kAppListSetToGoogle, false); ExpectEventRecorded(kAppListFirstSearch, false); +#endif // !defined(OS_IOS) ExpectRlzPingSent(false); } @@ -743,19 +833,21 @@ TEST_F(RlzLibTest, AppListUsageDoesNotSendPingWhenSendPingImmediately) { SimulateAppListUsage(); // Omnibox events. - ExpectEventRecorded(kOmniboxInstall, false); - ExpectEventRecorded(kOmniboxSetToGoogle, false); - ExpectEventRecorded(kOmniboxFirstSearch, false); + ExpectEventRecorded(OmniboxInstall(), false); + ExpectEventRecorded(OmniboxSetToGoogle(), false); + ExpectEventRecorded(OmniboxFirstSearch(), false); +#if !defined(OS_IOS) // Home page events. ExpectEventRecorded(kHomepageInstall, false); ExpectEventRecorded(kHomepageSetToGoogle, false); - ExpectEventRecorded(kHomepageFirstSeach, false); + ExpectEventRecorded(kHomepageFirstSearch, false); // App list events. ExpectEventRecorded(kAppListInstall, false); ExpectEventRecorded(kAppListSetToGoogle, false); ExpectEventRecorded(kAppListFirstSearch, true); +#endif // !defined(OS_IOS) ExpectRlzPingSent(false); } @@ -804,8 +896,10 @@ TEST_F(RlzLibTest, GetAccessPointRlzIsCached) { TEST_F(RlzLibTest, PingUpdatesRlzCache) { // Set dummy RLZ string. rlz_lib::SetAccessPointRlz(RLZTracker::ChromeOmnibox(), kOmniboxRlzString); +#if !defined(OS_IOS) rlz_lib::SetAccessPointRlz(RLZTracker::ChromeHomePage(), kHomepageRlzString); rlz_lib::SetAccessPointRlz(RLZTracker::ChromeAppList(), kAppListRlzString); +#endif // !defined(OS_IOS) base::string16 rlz; @@ -814,22 +908,26 @@ TEST_F(RlzLibTest, PingUpdatesRlzCache) { EXPECT_TRUE(RLZTracker::GetAccessPointRlz(RLZTracker::ChromeOmnibox(), &rlz)); EXPECT_STREQ(kOmniboxRlzString, base::UTF16ToUTF8(rlz).c_str()); +#if !defined(OS_IOS) EXPECT_TRUE(RLZTracker::GetAccessPointRlz( RLZTracker::ChromeHomePage(), &rlz)); EXPECT_STREQ(kHomepageRlzString, base::UTF16ToUTF8(rlz).c_str()); EXPECT_TRUE(RLZTracker::GetAccessPointRlz(RLZTracker::ChromeAppList(), &rlz)); EXPECT_STREQ(kAppListRlzString, base::UTF16ToUTF8(rlz).c_str()); +#endif // !defined(OS_IOS) // Make sure cache is valid. tracker_->set_assume_not_ui_thread(false); EXPECT_TRUE(RLZTracker::GetAccessPointRlz(RLZTracker::ChromeOmnibox(), &rlz)); EXPECT_STREQ(kOmniboxRlzString, base::UTF16ToUTF8(rlz).c_str()); +#if !defined(OS_IOS) EXPECT_TRUE(RLZTracker::GetAccessPointRlz( RLZTracker::ChromeHomePage(), &rlz)); EXPECT_STREQ(kHomepageRlzString, base::UTF16ToUTF8(rlz).c_str()); EXPECT_TRUE(RLZTracker::GetAccessPointRlz(RLZTracker::ChromeAppList(), &rlz)); EXPECT_STREQ(kAppListRlzString, base::UTF16ToUTF8(rlz).c_str()); +#endif // !defined(OS_IOS) // Perform ping. tracker_->set_assume_not_ui_thread(true); @@ -842,31 +940,16 @@ TEST_F(RlzLibTest, PingUpdatesRlzCache) { EXPECT_TRUE(RLZTracker::GetAccessPointRlz(RLZTracker::ChromeOmnibox(), &rlz)); EXPECT_STREQ(kNewOmniboxRlzString, base::UTF16ToUTF8(rlz).c_str()); +#if !defined(OS_IOS) EXPECT_TRUE(RLZTracker::GetAccessPointRlz( RLZTracker::ChromeHomePage(), &rlz)); EXPECT_STREQ(kNewHomepageRlzString, base::UTF16ToUTF8(rlz).c_str()); EXPECT_TRUE(RLZTracker::GetAccessPointRlz(RLZTracker::ChromeAppList(), &rlz)); EXPECT_STREQ(kNewAppListRlzString, base::UTF16ToUTF8(rlz).c_str()); -} - -TEST_F(RlzLibTest, ObserveHandlesBadArgs) { - scoped_ptr<LoadCommittedDetails> details(new LoadCommittedDetails()); - scoped_ptr<content::NavigationEntry> entry( - content::NavigationEntry::Create()); - details->entry = entry.get(); - details->entry->SetPageID(0); - details->entry->SetTransitionType(ui::PAGE_TRANSITION_LINK); - - tracker_->Observe(content::NOTIFICATION_NAV_ENTRY_COMMITTED, - content::NotificationService::AllSources(), - content::Details<NavigationEntry>(NULL)); - tracker_->Observe(content::NOTIFICATION_NAV_ENTRY_COMMITTED, - content::NotificationService::AllSources(), - content::Details<LoadCommittedDetails>(details.get())); +#endif // !defined(OS_IOS) } // TODO(thakis): Reactivation doesn't exist on Mac yet. -#if defined(OS_WIN) TEST_F(RlzLibTest, ReactivationNonOrganicNonOrganic) { SetReactivationBrand("REAC"); @@ -909,17 +992,18 @@ TEST_F(RlzLibTest, ReactivationOrganicOrganic) { ExpectRlzPingSent(false); ExpectReactivationRlzPingSent(false); } -#endif // defined(OS_WIN) #if defined(OS_CHROMEOS) TEST_F(RlzLibTest, ClearRlzState) { RLZTracker::RecordProductEvent(rlz_lib::CHROME, RLZTracker::ChromeOmnibox(), rlz_lib::FIRST_SEARCH); - ExpectEventRecorded(kOmniboxFirstSearch, true); + ExpectEventRecorded(OmniboxFirstSearch(), true); RLZTracker::ClearRlzState(); - ExpectEventRecorded(kOmniboxFirstSearch, false); + ExpectEventRecorded(OmniboxFirstSearch(), false); } #endif // defined(OS_CHROMEOS) + +} // namespace rlz diff --git a/chrome/browser/rlz/rlz_win.cc b/components/rlz/rlz_tracker_win.cc index 0f96858..0e2055c 100644 --- a/chrome/browser/rlz/rlz_win.cc +++ b/components/rlz/rlz_tracker_win.cc @@ -2,7 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/rlz/rlz.h" +#include "components/rlz/rlz_tracker.h" + +namespace rlz { // static rlz_lib::AccessPoint RLZTracker::ChromeOmnibox() { @@ -18,3 +20,5 @@ rlz_lib::AccessPoint RLZTracker::ChromeHomePage() { rlz_lib::AccessPoint RLZTracker::ChromeAppList() { return rlz_lib::CHROME_APP_LIST; } + +} // namespace rlz diff --git a/rlz/test/rlz_test_helpers.h b/rlz/test/rlz_test_helpers.h index c02aadc..7d24e62 100644 --- a/rlz/test/rlz_test_helpers.h +++ b/rlz/test/rlz_test_helpers.h @@ -19,7 +19,7 @@ #endif // A test helper class that constructs and destructs platform dependent machine -// state. It's used by src/chrome/browser/rlz/rlz_unittest.cc and +// state. It's used by src/components/rlz/rlz_tracker_unittest.cc and // src/rlz/lib/rlz_lib_test.cc class RlzLibTestNoMachineStateHelper { public: |