diff options
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: |