diff options
author | asvitkine@chromium.org <asvitkine@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-08-07 21:57:14 +0000 |
---|---|---|
committer | asvitkine@chromium.org <asvitkine@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-08-07 21:57:14 +0000 |
commit | dd46dd51ca66c9c0b0bbf1a376a545b3151fbeff (patch) | |
tree | 8405e077d3c3fe9262b3a28b01fbbadb992ce761 | |
parent | 24e0812a48696ae2ade27dcab436cc5380fd3754 (diff) | |
download | chromium_src-dd46dd51ca66c9c0b0bbf1a376a545b3151fbeff.zip chromium_src-dd46dd51ca66c9c0b0bbf1a376a545b3151fbeff.tar.gz chromium_src-dd46dd51ca66c9c0b0bbf1a376a545b3151fbeff.tar.bz2 |
Make UpgradeDetector listen to VariationsService changes.
This allows badging the wrench menu and showing the "Update
Google Chrome" item in the menu when critical variations
updates are available.
BUG=394855
Review URL: https://codereview.chromium.org/421643002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@288147 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/chromeos/upgrade_detector_chromeos.cc | 4 | ||||
-rw-r--r-- | chrome/browser/chromeos/upgrade_detector_chromeos.h | 3 | ||||
-rw-r--r-- | chrome/browser/upgrade_detector.cc | 66 | ||||
-rw-r--r-- | chrome/browser/upgrade_detector.h | 71 | ||||
-rw-r--r-- | chrome/browser/upgrade_detector_impl.cc | 62 | ||||
-rw-r--r-- | chrome/browser/upgrade_detector_impl.h | 26 | ||||
-rw-r--r-- | chrome/browser/upgrade_detector_impl_unittest.cc | 112 | ||||
-rw-r--r-- | chrome/chrome_tests_unit.gypi | 3 |
8 files changed, 264 insertions, 83 deletions
diff --git a/chrome/browser/chromeos/upgrade_detector_chromeos.cc b/chrome/browser/chromeos/upgrade_detector_chromeos.cc index e66dbdf..7b22f92 100644 --- a/chrome/browser/chromeos/upgrade_detector_chromeos.cc +++ b/chrome/browser/chromeos/upgrade_detector_chromeos.cc @@ -41,7 +41,7 @@ void UpgradeDetectorChromeos::UpdateStatusChanged( if (status.status != UpdateEngineClient::UPDATE_STATUS_UPDATED_NEED_REBOOT) return; - NotifyUpgradeDetected(); + upgrade_detected_time_ = base::Time::Now(); // ChromeOS shows upgrade arrow once the upgrade becomes available. NotifyOnUpgrade(); @@ -53,7 +53,7 @@ void UpgradeDetectorChromeos::UpdateStatusChanged( } void UpgradeDetectorChromeos::NotifyOnUpgrade() { - base::TimeDelta delta = base::Time::Now() - upgrade_detected_time(); + base::TimeDelta delta = base::Time::Now() - upgrade_detected_time_; int64 time_passed = delta.InDays(); const int kSevereThreshold = 7; diff --git a/chrome/browser/chromeos/upgrade_detector_chromeos.h b/chrome/browser/chromeos/upgrade_detector_chromeos.h index f3853b7..93be807 100644 --- a/chrome/browser/chromeos/upgrade_detector_chromeos.h +++ b/chrome/browser/chromeos/upgrade_detector_chromeos.h @@ -45,6 +45,9 @@ class UpgradeDetectorChromeos : public UpgradeDetector, // has passed and we should start notifying the user. base::RepeatingTimer<UpgradeDetectorChromeos> upgrade_notification_timer_; bool initialized_; + base::Time upgrade_detected_time_; + + DISALLOW_COPY_AND_ASSIGN(UpgradeDetectorChromeos); }; #endif // CHROME_BROWSER_CHROMEOS_UPGRADE_DETECTOR_CHROMEOS_H_ diff --git a/chrome/browser/upgrade_detector.cc b/chrome/browser/upgrade_detector.cc index 0c15fe0..eff168d 100644 --- a/chrome/browser/upgrade_detector.cc +++ b/chrome/browser/upgrade_detector.cc @@ -59,6 +59,8 @@ int UpgradeDetector::GetIconResourceID() { UpgradeDetector::UpgradeDetector() : upgrade_available_(UPGRADE_AVAILABLE_NONE), + best_effort_experiment_updates_available_(false), + critical_experiment_updates_available_(false), critical_update_acknowledged_(false), upgrade_notification_stage_(UPGRADE_ANNOYANCE_NONE), notify_upgrade_(false) { @@ -67,48 +69,28 @@ UpgradeDetector::UpgradeDetector() UpgradeDetector::~UpgradeDetector() { } -void UpgradeDetector::NotifyUpgradeDetected() { - upgrade_detected_time_ = base::Time::Now(); - critical_update_acknowledged_ = false; -} - void UpgradeDetector::NotifyUpgradeRecommended() { notify_upgrade_ = true; - content::NotificationService::current()->Notify( - chrome::NOTIFICATION_UPGRADE_RECOMMENDED, - content::Source<UpgradeDetector>(this), - content::NotificationService::NoDetails()); - - switch (upgrade_available_) { - case UPGRADE_NEEDED_OUTDATED_INSTALL: { - content::NotificationService::current()->Notify( - chrome::NOTIFICATION_OUTDATED_INSTALL, - content::Source<UpgradeDetector>(this), - content::NotificationService::NoDetails()); - break; - } - case UPGRADE_NEEDED_OUTDATED_INSTALL_NO_AU: { - content::NotificationService::current()->Notify( - chrome::NOTIFICATION_OUTDATED_INSTALL_NO_AU, - content::Source<UpgradeDetector>(this), - content::NotificationService::NoDetails()); - break; - } - case UPGRADE_AVAILABLE_CRITICAL: { - int idle_timer = UseTestingIntervals() ? - kIdleRepeatingTimerWait : - kIdleRepeatingTimerWait * 60; // To minutes. - idle_check_timer_.Start(FROM_HERE, - base::TimeDelta::FromSeconds(idle_timer), - this, &UpgradeDetector::CheckIdle); - break; - } - default: - break; + TriggerNotification(chrome::NOTIFICATION_UPGRADE_RECOMMENDED); + if (upgrade_available_ == UPGRADE_NEEDED_OUTDATED_INSTALL) { + TriggerNotification(chrome::NOTIFICATION_OUTDATED_INSTALL); + } else if (upgrade_available_ == UPGRADE_NEEDED_OUTDATED_INSTALL_NO_AU) { + TriggerNotification(chrome::NOTIFICATION_OUTDATED_INSTALL_NO_AU); + } else if (upgrade_available_ == UPGRADE_AVAILABLE_CRITICAL || + critical_experiment_updates_available_) { + TriggerCriticalUpdate(); } } +void UpgradeDetector::TriggerCriticalUpdate() { + const base::TimeDelta idle_timer = UseTestingIntervals() ? + base::TimeDelta::FromSeconds(kIdleRepeatingTimerWait) : + base::TimeDelta::FromMinutes(kIdleRepeatingTimerWait); + idle_check_timer_.Start(FROM_HERE, idle_timer, this, + &UpgradeDetector::CheckIdle); +} + void UpgradeDetector::CheckIdle() { // CalculateIdleState expects an interval in seconds. int idle_time_allowed = UseTestingIntervals() ? kIdleAmount : @@ -119,6 +101,13 @@ void UpgradeDetector::CheckIdle() { base::Unretained(this))); } +void UpgradeDetector::TriggerNotification(chrome::NotificationType type) { + content::NotificationService::current()->Notify( + type, + content::Source<UpgradeDetector>(this), + content::NotificationService::NoDetails()); +} + void UpgradeDetector::IdleCallback(IdleState state) { // Don't proceed while an incognito window is open. The timer will still // keep firing, so this function will get a chance to re-evaluate this. @@ -134,10 +123,7 @@ void UpgradeDetector::IdleCallback(IdleState state) { case IDLE_STATE_IDLE: // Computer has been idle for long enough, show warning. idle_check_timer_.Stop(); - content::NotificationService::current()->Notify( - chrome::NOTIFICATION_CRITICAL_UPGRADE_INSTALLED, - content::Source<UpgradeDetector>(this), - content::NotificationService::NoDetails()); + TriggerNotification(chrome::NOTIFICATION_CRITICAL_UPGRADE_INSTALLED); break; case IDLE_STATE_ACTIVE: case IDLE_STATE_UNKNOWN: diff --git a/chrome/browser/upgrade_detector.h b/chrome/browser/upgrade_detector.h index 92719a3..f743f9d 100644 --- a/chrome/browser/upgrade_detector.h +++ b/chrome/browser/upgrade_detector.h @@ -6,6 +6,7 @@ #define CHROME_BROWSER_UPGRADE_DETECTOR_H_ #include "base/timer/timer.h" +#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/idle.h" #include "ui/gfx/image/image.h" @@ -65,11 +66,6 @@ class UpgradeDetector { return critical_update_acknowledged_; } - // When the last upgrade was detected. - const base::Time& upgrade_detected_time() const { - return upgrade_detected_time_; - } - // Retrieves the right icon ID based on the degree of severity (see // UpgradeNotificationAnnoyanceLevel, each level has an an accompanying icon // to go with it) to display within the wrench menu. @@ -80,18 +76,6 @@ class UpgradeDetector { } protected: - UpgradeDetector(); - - // Sends out UPGRADE_DETECTED notification and record upgrade_detected_time_. - void NotifyUpgradeDetected(); - - // Sends out UPGRADE_RECOMMENDED notification and set notify_upgrade_. - void NotifyUpgradeRecommended(); - - void set_upgrade_notification_stage(UpgradeNotificationAnnoyanceLevel stage) { - upgrade_notification_stage_ = stage; - } - enum UpgradeAvailable { // If no update is available and current install is recent enough. UPGRADE_AVAILABLE_NONE, @@ -106,10 +90,40 @@ class UpgradeDetector { // If no update to Chrome has been installed for more than the recommended // time AND auto-update is turned off. UPGRADE_NEEDED_OUTDATED_INSTALL_NO_AU, - } upgrade_available_; + }; - // Whether the user has acknowledged the critical update. - bool critical_update_acknowledged_; + UpgradeDetector(); + + // Sends out UPGRADE_RECOMMENDED notification and set notify_upgrade_. + void NotifyUpgradeRecommended(); + + // Triggers a critical update, which starts a timer that checks the machine + // idle state. Protected and virtual so that it could be overridden by tests. + virtual void TriggerCriticalUpdate(); + + UpgradeAvailable upgrade_available() const { return upgrade_available_; } + void set_upgrade_available(UpgradeAvailable available) { + upgrade_available_ = available; + } + + void set_best_effort_experiment_updates_available(bool available) { + best_effort_experiment_updates_available_ = available; + } + + bool critical_experiment_updates_available() const { + return critical_experiment_updates_available_; + } + void set_critical_experiment_updates_available(bool available) { + critical_experiment_updates_available_ = available; + } + + void set_critical_update_acknowledged(bool acknowledged) { + critical_update_acknowledged_ = acknowledged; + } + + void set_upgrade_notification_stage(UpgradeNotificationAnnoyanceLevel stage) { + upgrade_notification_stage_ = stage; + } private: // Initiates an Idle check. See IdleCallback below. @@ -119,8 +133,21 @@ class UpgradeDetector { // input events since the specified time. void IdleCallback(IdleState state); - // When the upgrade was detected. - base::Time upgrade_detected_time_; + // Triggers a global notification of the specified |type|. + void TriggerNotification(chrome::NotificationType type); + + // Whether any software updates are available (experiment updates are tracked + // separately via additional member variables below). + UpgradeAvailable upgrade_available_; + + // Whether "best effort" experiment updates are available. + bool best_effort_experiment_updates_available_; + + // Whether "critical" experiment updates are available. + bool critical_experiment_updates_available_; + + // Whether the user has acknowledged the critical update. + bool critical_update_acknowledged_; // A timer to check to see if we've been idle for long enough to show the // critical warning. Should only be set if |upgrade_available_| is diff --git a/chrome/browser/upgrade_detector_impl.cc b/chrome/browser/upgrade_detector_impl.cc index 87f5b22..ec0f8d0 100644 --- a/chrome/browser/upgrade_detector_impl.cc +++ b/chrome/browser/upgrade_detector_impl.cc @@ -244,6 +244,14 @@ UpgradeDetectorImpl::UpgradeDetectorImpl() return; } + // Register for experiment notifications. Note that since this class is a + // singleton, it does not need to unregister for notifications when destroyed, + // since it outlives the VariationsService. + chrome_variations::VariationsService* variations_service = + g_browser_process->variations_service(); + if (variations_service) + variations_service->AddObserver(this); + base::Closure start_upgrade_check_timer_task = base::Bind(&UpgradeDetectorImpl::StartTimerForUpgradeCheck, weak_factory_.GetWeakPtr()); @@ -346,6 +354,24 @@ void UpgradeDetectorImpl::StartTimerForUpgradeCheck() { this, &UpgradeDetectorImpl::CheckForUpgrade); } +void UpgradeDetectorImpl::StartUpgradeNotificationTimer() { + // The timer may already be running (e.g. due to both a software upgrade and + // experiment updates being available). + if (upgrade_notification_timer_.IsRunning()) + return; + + upgrade_detected_time_ = base::Time::Now(); + + // Start the repeating timer for notifying the user after a certain period. + // The called function will eventually figure out that enough time has passed + // and stop the timer. + const int cycle_time_ms = IsTesting() ? + kNotifyCycleTimeForTestingMs : kNotifyCycleTimeMs; + upgrade_notification_timer_.Start(FROM_HERE, + base::TimeDelta::FromMilliseconds(cycle_time_ms), + this, &UpgradeDetectorImpl::NotifyOnUpgrade); +} + void UpgradeDetectorImpl::CheckForUpgrade() { // Interrupt any (unlikely) unfinished execution of DetectUpgradeTask, or at // least prevent the callback from being executed, because we will potentially @@ -414,30 +440,28 @@ bool UpgradeDetectorImpl::DetectOutdatedInstall() { return simulate_outdated; } +void UpgradeDetectorImpl::OnExperimentChangesDetected(Severity severity) { + set_best_effort_experiment_updates_available(severity == BEST_EFFORT); + set_critical_experiment_updates_available(severity == CRITICAL); + StartUpgradeNotificationTimer(); +} + void UpgradeDetectorImpl::UpgradeDetected(UpgradeAvailable upgrade_available) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - upgrade_available_ = upgrade_available; + set_upgrade_available(upgrade_available); // Stop the recurring timer (that is checking for changes). detect_upgrade_timer_.Stop(); + set_critical_update_acknowledged(false); - NotifyUpgradeDetected(); - - // Start the repeating timer for notifying the user after a certain period. - // The called function will eventually figure out that enough time has passed - // and stop the timer. - int cycle_time = IsTesting() ? - kNotifyCycleTimeForTestingMs : kNotifyCycleTimeMs; - upgrade_notification_timer_.Start(FROM_HERE, - base::TimeDelta::FromMilliseconds(cycle_time), - this, &UpgradeDetectorImpl::NotifyOnUpgrade); + StartUpgradeNotificationTimer(); } -void UpgradeDetectorImpl::NotifyOnUpgrade() { - const base::TimeDelta time_passed = - base::Time::Now() - upgrade_detected_time(); - - bool is_critical_or_outdated = upgrade_available_ > UPGRADE_AVAILABLE_REGULAR; +void UpgradeDetectorImpl::NotifyOnUpgradeWithTimePassed( + base::TimeDelta time_passed) { + const bool is_critical_or_outdated = + upgrade_available() > UPGRADE_AVAILABLE_REGULAR || + critical_experiment_updates_available(); if (is_unstable_channel_) { // There's only one threat level for unstable channels like dev and // canary, and it hits after one hour. During testing, it hits after one @@ -487,6 +511,12 @@ void UpgradeDetectorImpl::NotifyOnUpgrade() { NotifyUpgradeRecommended(); } +void UpgradeDetectorImpl::NotifyOnUpgrade() { + const base::TimeDelta time_passed = + base::Time::Now() - upgrade_detected_time_; + NotifyOnUpgradeWithTimePassed(time_passed); +} + // static UpgradeDetectorImpl* UpgradeDetectorImpl::GetInstance() { return Singleton<UpgradeDetectorImpl>::get(); diff --git a/chrome/browser/upgrade_detector_impl.h b/chrome/browser/upgrade_detector_impl.h index 17dbd3e..1fdbf88 100644 --- a/chrome/browser/upgrade_detector_impl.h +++ b/chrome/browser/upgrade_detector_impl.h @@ -8,11 +8,14 @@ #include "base/memory/weak_ptr.h" #include "base/timer/timer.h" #include "base/version.h" +#include "chrome/browser/metrics/variations/variations_service.h" #include "chrome/browser/upgrade_detector.h" template <typename T> struct DefaultSingletonTraits; -class UpgradeDetectorImpl : public UpgradeDetector { +class UpgradeDetectorImpl : + public UpgradeDetector, + public chrome_variations::VariationsService::Observer { public: virtual ~UpgradeDetectorImpl(); @@ -24,17 +27,30 @@ class UpgradeDetectorImpl : public UpgradeDetector { // Returns the singleton instance. static UpgradeDetectorImpl* GetInstance(); + protected: + UpgradeDetectorImpl(); + + // chrome_variations::VariationsService::Observer: + virtual void OnExperimentChangesDetected(Severity severity) OVERRIDE; + + // Trigger an "on upgrade" notification based on the specified |time_passed| + // interval. Exposed as protected for testing. + void NotifyOnUpgradeWithTimePassed(base::TimeDelta time_passed); + private: friend struct DefaultSingletonTraits<UpgradeDetectorImpl>; - UpgradeDetectorImpl(); - // Start the timer that will call |CheckForUpgrade()|. void StartTimerForUpgradeCheck(); // Launches a task on the file thread to check if we have the latest version. void CheckForUpgrade(); + // Starts the upgrade notification timer that will check periodically whether + // enough time has elapsed to update the severity (which maps to visual + // badging) of the notification. + void StartUpgradeNotificationTimer(); + // Sends out a notification and starts a one shot timer to wait until // notifying the user. void UpgradeDetected(UpgradeAvailable upgrade_available); @@ -74,6 +90,10 @@ class UpgradeDetectorImpl : public UpgradeDetector { // True if auto update is turned on. bool is_auto_update_enabled_; + // When the upgrade was detected - either a software update or a variations + // update, whichever happened first. + base::Time upgrade_detected_time_; + // The date the binaries were built. base::Time build_date_; diff --git a/chrome/browser/upgrade_detector_impl_unittest.cc b/chrome/browser/upgrade_detector_impl_unittest.cc new file mode 100644 index 0000000..e52949a --- /dev/null +++ b/chrome/browser/upgrade_detector_impl_unittest.cc @@ -0,0 +1,112 @@ +// 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/upgrade_detector_impl.h" + +#include <vector> + +#include "content/public/browser/notification_details.h" +#include "content/public/browser/notification_observer.h" +#include "content/public/browser/notification_registrar.h" +#include "content/public/browser/notification_service.h" +#include "content/public/test/test_browser_thread_bundle.h" +#include "testing/gtest/include/gtest/gtest.h" + +class TestUpgradeDetectorImpl : public UpgradeDetectorImpl { + public: + TestUpgradeDetectorImpl() : trigger_critical_update_call_count_(0) {} + virtual ~TestUpgradeDetectorImpl() {} + + // Methods exposed for testing. + using UpgradeDetectorImpl::OnExperimentChangesDetected; + using UpgradeDetectorImpl::NotifyOnUpgradeWithTimePassed; + + // UpgradeDetector: + virtual void TriggerCriticalUpdate() OVERRIDE { + trigger_critical_update_call_count_++; + } + + int trigger_critical_update_call_count() const { + return trigger_critical_update_call_count_; + } + + private: + // How many times TriggerCriticalUpdate() has been called. Expected to either + // be 0 or 1. + int trigger_critical_update_call_count_; + + DISALLOW_COPY_AND_ASSIGN(TestUpgradeDetectorImpl); +}; + +class TestUpgradeNotificationListener : public content::NotificationObserver { + public: + TestUpgradeNotificationListener() { + registrar_.Add(this, chrome::NOTIFICATION_UPGRADE_RECOMMENDED, + content::NotificationService::AllSources()); + } + virtual ~TestUpgradeNotificationListener() { + } + + const std::vector<int>& notifications_received() const { + return notifications_received_; + } + + private: + // content::NotificationObserver: + virtual void Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) OVERRIDE { + notifications_received_.push_back(type); + } + + // Registrar for listening to notifications. + content::NotificationRegistrar registrar_; + + // Keeps track of the number and types of notifications that were received. + std::vector<int> notifications_received_; + + DISALLOW_COPY_AND_ASSIGN(TestUpgradeNotificationListener); +}; + +TEST(UpgradeDetectorImplTest, VariationsChanges) { + content::TestBrowserThreadBundle bundle; + + TestUpgradeNotificationListener notifications_listener; + TestUpgradeDetectorImpl detector; + EXPECT_FALSE(detector.notify_upgrade()); + EXPECT_TRUE(notifications_listener.notifications_received().empty()); + + detector.OnExperimentChangesDetected( + chrome_variations::VariationsService::Observer::BEST_EFFORT); + EXPECT_FALSE(detector.notify_upgrade()); + EXPECT_TRUE(notifications_listener.notifications_received().empty()); + + detector.NotifyOnUpgradeWithTimePassed(base::TimeDelta::FromDays(30)); + EXPECT_TRUE(detector.notify_upgrade()); + ASSERT_EQ(1U, notifications_listener.notifications_received().size()); + EXPECT_EQ(chrome::NOTIFICATION_UPGRADE_RECOMMENDED, + notifications_listener.notifications_received().front()); + EXPECT_EQ(0, detector.trigger_critical_update_call_count()); +} + +TEST(UpgradeDetectorImplTest, VariationsCriticalChanges) { + content::TestBrowserThreadBundle bundle; + + TestUpgradeNotificationListener notifications_listener; + TestUpgradeDetectorImpl detector; + EXPECT_FALSE(detector.notify_upgrade()); + EXPECT_TRUE(notifications_listener.notifications_received().empty()); + + detector.OnExperimentChangesDetected( + chrome_variations::VariationsService::Observer::CRITICAL); + EXPECT_FALSE(detector.notify_upgrade()); + EXPECT_TRUE(notifications_listener.notifications_received().empty()); + + detector.NotifyOnUpgradeWithTimePassed(base::TimeDelta::FromDays(30)); + EXPECT_TRUE(detector.notify_upgrade()); + ASSERT_EQ(1U, notifications_listener.notifications_received().size()); + EXPECT_EQ(chrome::NOTIFICATION_UPGRADE_RECOMMENDED, + notifications_listener.notifications_received().front()); + EXPECT_EQ(1, detector.trigger_critical_update_call_count()); +} diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi index d87d1fd..f040681 100644 --- a/chrome/chrome_tests_unit.gypi +++ b/chrome/chrome_tests_unit.gypi @@ -1783,6 +1783,7 @@ 'browser/ui/zoom/zoom_controller_unittest.cc', 'browser/undo/bookmark_undo_service_test.cc', 'browser/undo/undo_manager_test.cc', + 'browser/upgrade_detector_impl_unittest.cc', 'browser/upload_list_unittest.cc', 'browser/web_applications/web_app_mac_unittest.mm', 'browser/web_applications/web_app_unittest.cc', @@ -2316,6 +2317,7 @@ 'browser/ui/sync/one_click_signin_helper_unittest.cc', 'browser/ui/sync/one_click_signin_sync_starter_unittest.cc', 'browser/ui/views/frame/opaque_browser_frame_view_layout_unittest.cc', + 'browser/upgrade_detector_impl_unittest.cc', ], 'sources': [ 'browser/extensions/updater/local_extension_cache_unittest.cc', @@ -2573,6 +2575,7 @@ 'browser/ui/webui/web_dialog_web_contents_delegate_unittest.cc', 'browser/ui/window_sizer/window_sizer_common_unittest.cc', 'browser/ui/window_sizer/window_sizer_unittest.cc', + 'browser/upgrade_detector_impl_unittest.cc', 'common/net/x509_certificate_model_unittest.cc', 'test/base/browser_with_test_window_test.cc', 'test/base/browser_with_test_window_test.h', |