extension_updater.cc revision 68043e1e95eeb07d5cae7aca370b26518b0867d6
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/updater/extension_updater.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/rand_util.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_split.h" 197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h" 2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/extensions/api/module/module.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/crx_installer.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/pending_extension_manager.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/updater/extension_downloader.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension_set.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_details.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "crypto/sha2.h" 3468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "extensions/common/constants.h" 353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "extensions/common/manifest.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::RandDouble; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::RandInt; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::Time; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeDelta; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using prefs::kLastExtensionsUpdateCheck; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using prefs::kNextExtensionsUpdateCheck; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef extensions::ExtensionDownloaderDelegate::Error Error; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef extensions::ExtensionDownloaderDelegate::PingResult PingResult; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Wait at least 5 minutes after browser startup before we do any checks. If you 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// change this value, make sure to update comments where it is used. 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kStartupWaitSeconds = 60 * 5; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For sanity checking on update frequency - enforced in release mode only. 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMinUpdateFrequencySeconds = 30; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMaxUpdateFrequencySeconds = 60 * 60 * 24 * 7; // 7 days 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Require at least 5 seconds between consecutive non-succesful extension update 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// checks. 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kMinUpdateThrottleTime = 5; 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// When we've computed a days value, we want to make sure we don't send a 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// negative value (due to the system clock being set backwards, etc.), since -1 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is a special sentinel value that means "never pinged", and other negative 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// values don't make sense. 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SanitizeDays(int days) { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (days < 0) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return days; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Calculates the value to use for the ping days parameter. 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int CalculatePingDays(const Time& last_ping_day) { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int days = extensions::ManifestFetchData::kNeverPinged; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!last_ping_day.is_null()) { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) days = SanitizeDays((Time::Now() - last_ping_day).InDays()); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return days; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int CalculateActivePingDays(const Time& last_active_ping_day, 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool hasActiveBit) { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!hasActiveBit) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (last_active_ping_day.is_null()) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return extensions::ManifestFetchData::kNeverPinged; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SanitizeDays((Time::Now() - last_active_ping_day).InDays()); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ExtensionUpdater::CheckParams::CheckParams() 9568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) : install_immediately(false) {} 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ExtensionUpdater::CheckParams::~CheckParams() {} 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ExtensionUpdater::FetchedCRXFile::FetchedCRXFile( 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& i, 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& p, 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& u, 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::set<int>& request_ids) 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : extension_id(i), 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) path(p), 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download_url(u), 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_ids(request_ids) {} 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ExtensionUpdater::FetchedCRXFile::FetchedCRXFile() : path(), download_url() {} 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionUpdater::FetchedCRXFile::~FetchedCRXFile() {} 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ExtensionUpdater::InProgressCheck::InProgressCheck() 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : install_immediately(false) {} 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ExtensionUpdater::InProgressCheck::~InProgressCheck() {} 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct ExtensionUpdater::ThrottleInfo { 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ThrottleInfo() 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : in_progress(true), 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) throttle_delay(kMinUpdateThrottleTime), 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) check_start(Time::Now()) {} 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool in_progress; 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int throttle_delay; 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Time check_start; 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionUpdater::ExtensionUpdater(ExtensionServiceInterface* service, 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionPrefs* extension_prefs, 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrefService* prefs, 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile, 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int frequency_seconds) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : alive_(false), 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_ptr_factory_(this), 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service_(service), frequency_seconds_(frequency_seconds), 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) will_check_soon_(false), extension_prefs_(extension_prefs), 13868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) prefs_(prefs), profile_(profile), 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) next_request_id_(0), 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) crx_install_is_running_(false) { 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(frequency_seconds_, 5); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LE(frequency_seconds_, kMaxUpdateFrequencySeconds); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef NDEBUG 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In Release mode we enforce that update checks don't happen too often. 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frequency_seconds_ = std::max(frequency_seconds_, kMinUpdateFrequencySeconds); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frequency_seconds_ = std::min(frequency_seconds_, kMaxUpdateFrequencySeconds); 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED, 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::NotificationService::AllBrowserContextsAndSources()); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionUpdater::~ExtensionUpdater() { 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Stop(); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The overall goal here is to balance keeping clients up to date while 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// avoiding a thundering herd against update servers. 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TimeDelta ExtensionUpdater::DetermineFirstCheckDelay() { 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(alive_); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If someone's testing with a quick frequency, just allow it. 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (frequency_seconds_ < kStartupWaitSeconds) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TimeDelta::FromSeconds(frequency_seconds_); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we've never scheduled a check before, start at frequency_seconds_. 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!prefs_->HasPrefPath(kNextExtensionsUpdateCheck)) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TimeDelta::FromSeconds(frequency_seconds_); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If it's been a long time since our last actual check, we want to do one 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // relatively soon. 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Time now = Time::Now(); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Time last = Time::FromInternalValue(prefs_->GetInt64( 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kLastExtensionsUpdateCheck)); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int days = (now - last).InDays(); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (days >= 30) { 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wait 5-10 minutes. 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TimeDelta::FromSeconds(RandInt(kStartupWaitSeconds, 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kStartupWaitSeconds * 2)); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (days >= 14) { 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wait 10-20 minutes. 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TimeDelta::FromSeconds(RandInt(kStartupWaitSeconds * 2, 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kStartupWaitSeconds * 4)); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (days >= 3) { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wait 20-40 minutes. 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TimeDelta::FromSeconds(RandInt(kStartupWaitSeconds * 4, 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kStartupWaitSeconds * 8)); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Read the persisted next check time, and use that if it isn't too soon. 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Otherwise pick something random. 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Time saved_next = Time::FromInternalValue(prefs_->GetInt64( 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kNextExtensionsUpdateCheck)); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Time earliest = now + TimeDelta::FromSeconds(kStartupWaitSeconds); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (saved_next >= earliest) { 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return saved_next - now; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TimeDelta::FromSeconds(RandInt(kStartupWaitSeconds, 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frequency_seconds_)); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionUpdater::Start() { 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!alive_); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If these are NULL, then that means we've been called after Stop() 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // has been called. 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(service_); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(extension_prefs_); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(prefs_); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(profile_); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!weak_ptr_factory_.HasWeakPtrs()); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) alive_ = true; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure our prefs are registered, then schedule the first check. 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleNextCheck(DetermineFirstCheckDelay()); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionUpdater::Stop() { 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_.InvalidateWeakPtrs(); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) alive_ = false; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service_ = NULL; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_prefs_ = NULL; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefs_ = NULL; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_ = NULL; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timer_.Stop(); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) will_check_soon_ = false; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) downloader_.reset(); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionUpdater::ScheduleNextCheck(const TimeDelta& target_delay) { 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(alive_); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!timer_.IsRunning()); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(target_delay >= TimeDelta::FromSeconds(1)); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add +/- 10% random jitter. 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double delay_ms = target_delay.InMillisecondsF(); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double jitter_factor = (RandDouble() * .2) - 0.1; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delay_ms += delay_ms * jitter_factor; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeDelta actual_delay = TimeDelta::FromMilliseconds( 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int64>(delay_ms)); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Save the time of next check. 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Time next = Time::Now() + actual_delay; 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefs_->SetInt64(kNextExtensionsUpdateCheck, next.ToInternalValue()); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timer_.Start(FROM_HERE, actual_delay, this, &ExtensionUpdater::TimerFired); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionUpdater::TimerFired() { 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(alive_); 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckNow(default_params_); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the user has overridden the update frequency, don't bother reporting 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this. 25368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (frequency_seconds_ == extensions::kDefaultUpdateFrequencySeconds) { 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Time last = Time::FromInternalValue(prefs_->GetInt64( 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kLastExtensionsUpdateCheck)); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (last.ToInternalValue() != 0) { 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use counts rather than time so we can use minutes rather than millis. 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_CUSTOM_COUNTS("Extensions.UpdateCheckGap", 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (Time::Now() - last).InMinutes(), 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeDelta::FromSeconds(kStartupWaitSeconds).InMinutes(), 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeDelta::FromDays(40).InMinutes(), 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 50); // 50 buckets seems to be the default. 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Save the last check time, and schedule the next check. 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 now = Time::Now().ToInternalValue(); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefs_->SetInt64(kLastExtensionsUpdateCheck, now); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleNextCheck(TimeDelta::FromSeconds(frequency_seconds_)); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionUpdater::CheckSoon() { 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(alive_); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (will_check_soon_) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (BrowserThread::PostTask( 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::UI, FROM_HERE, 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ExtensionUpdater::DoCheckSoon, 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr()))) { 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) will_check_soon_ = true; 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionUpdater::WillCheckSoon() const { 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return will_check_soon_; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionUpdater::DoCheckSoon() { 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(will_check_soon_); 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckNow(default_params_); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) will_check_soon_ = false; 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExtensionUpdater::AddToDownloader( 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ExtensionSet* extensions, 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::list<std::string>& pending_ids, 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int request_id) { 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InProgressCheck& request = requests_in_progress_[request_id]; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ExtensionSet::const_iterator extension_iter = extensions->begin(); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_iter != extensions->end(); ++extension_iter) { 3037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const Extension& extension = *extension_iter->get(); 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!Manifest::IsAutoUpdateableLocation(extension.location())) { 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << "Extension " << extension.id() << " is not auto updateable"; 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // An extension might be overwritten by policy, and have its update url 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // changed. Make sure existing extensions aren't fetched again, if a 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pending fetch for an extension with the same id already exists. 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::list<std::string>::const_iterator pending_id_iter = std::find( 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_ids.begin(), pending_ids.end(), extension.id()); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pending_id_iter == pending_ids.end()) { 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (downloader_->AddExtension(extension, request_id)) 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request.in_progress_ids_.push_back(extension.id()); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExtensionUpdater::CheckNow(const CheckParams& params) { 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int request_id = next_request_id_++; 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(2) << "Starting update check " << request_id; 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (params.ids.empty()) 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NotifyStarted(); 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(alive_); 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InProgressCheck& request = requests_in_progress_[request_id]; 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request.callback = params.callback; 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request.install_immediately = params.install_immediately; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!downloader_.get()) { 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) downloader_.reset( 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new ExtensionDownloader(this, profile_->GetRequestContext())); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add fetch records for extensions that should be fetched by an update URL. 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // These extensions are not yet installed. They come from group policy 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and external install sources. 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PendingExtensionManager* pending_extension_manager = 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service_->pending_extension_manager(); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::list<std::string> pending_ids; 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (params.ids.empty()) { 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If no extension ids are specified, check for updates for all extensions. 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pending_extension_manager->GetPendingIdsForUpdateCheck(&pending_ids); 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::list<std::string>::const_iterator iter; 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (iter = pending_ids.begin(); iter != pending_ids.end(); ++iter) { 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const PendingExtensionInfo* info = pending_extension_manager->GetById( 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *iter); 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!Manifest::IsAutoUpdateableLocation(info->install_source())) { 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(2) << "Extension " << *iter << " is not auto updateable"; 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (downloader_->AddPendingExtension(*iter, info->update_url(), 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_id)) 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request.in_progress_ids_.push_back(*iter); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AddToDownloader(service_->extensions(), pending_ids, request_id); 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AddToDownloader(service_->disabled_extensions(), pending_ids, request_id); 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::list<std::string>::const_iterator it = params.ids.begin(); 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != params.ids.end(); ++it) { 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Extension* extension = service_->GetExtensionById(*it, true); 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(extension); 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (downloader_->AddExtension(*extension, request_id)) 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request.in_progress_ids_.push_back(extension->id()); 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // StartAllPending() might call OnExtensionDownloadFailed/Finished before 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // it returns, which would cause NotifyIfFinished to incorrectly try to 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // send out a notification. So check before we call StartAllPending if any 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // extensions are going to be updated, and use that to figure out if 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // NotifyIfFinished should be called. 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool noChecks = request.in_progress_ids_.empty(); 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // StartAllPending() will call OnExtensionDownloadFailed or 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // OnExtensionDownloadFinished for each extension that was checked. 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) downloader_->StartAllPending(); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (noChecks) 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NotifyIfFinished(request_id); 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ExtensionUpdater::CheckExtensionSoon(const std::string& extension_id, 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FinishedCallback& callback) { 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool have_throttle_info = ContainsKey(throttle_info_, extension_id); 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ThrottleInfo& info = throttle_info_[extension_id]; 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (have_throttle_info) { 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We already had a ThrottleInfo object for this extension, check if the 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // update check request should be allowed. 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If another check is in progress, don't start a new check. 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (info.in_progress) 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Time now = Time::Now(); 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Time last = info.check_start; 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If somehow time moved back, we don't want to infinitely keep throttling. 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (now < last) { 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last = now; 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) info.check_start = now; 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Time earliest = last + TimeDelta::FromSeconds(info.throttle_delay); 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If check is too soon, throttle. 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (now < earliest) 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(mek): Somehow increase time between allowing checks when checks 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // are repeatedly throttled and don't result in updates being installed. 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // It's okay to start a check, update values. 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) info.check_start = now; 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) info.in_progress = true; 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckParams params; 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.ids.push_back(extension_id); 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.callback = base::Bind(&ExtensionUpdater::ExtensionCheckFinished, 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_id, callback); 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckNow(params); 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExtensionUpdater::ExtensionCheckFinished( 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& extension_id, 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FinishedCallback& callback) { 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::map<std::string, ThrottleInfo>::iterator it = 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) throttle_info_.find(extension_id); 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (it != throttle_info_.end()) { 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it->second.in_progress = false; 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(); 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExtensionUpdater::OnExtensionDownloadFailed( 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& id, 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Error error, 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const PingResult& ping, 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::set<int>& request_ids) { 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(alive_); 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdatePingData(id, ping); 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool install_immediately = false; 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::set<int>::const_iterator it = request_ids.begin(); 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != request_ids.end(); ++it) { 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InProgressCheck& request = requests_in_progress_[*it]; 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) install_immediately |= request.install_immediately; 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request.in_progress_ids_.remove(id); 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NotifyIfFinished(*it); 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This method is called if no updates were found. However a previous update 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // check might have queued an update for this extension already. If a 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // current update check has |install_immediately| set the previously 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // queued update should be installed now. 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (install_immediately && service_->GetPendingExtensionUpdate(id)) 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) service_->FinishDelayedInstallation(id); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExtensionUpdater::OnExtensionDownloadFinished( 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& id, 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& path, 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& download_url, 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& version, 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const PingResult& ping, 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::set<int>& request_ids) { 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(alive_); 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdatePingData(id, ping); 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << download_url << " written to " << path.value(); 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FetchedCRXFile fetched(id, path, download_url, request_ids); 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fetched_crx_files_.push(fetched); 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // MaybeInstallCRXFile() removes extensions from |in_progress_ids_| after 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // starting the crx installer. 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MaybeInstallCRXFile(); 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionUpdater::GetPingDataForExtension( 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& id, 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ManifestFetchData::PingData* ping_data) { 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(alive_); 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ping_data->rollcall_days = CalculatePingDays( 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_prefs_->LastPingDay(id)); 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ping_data->is_enabled = service_->IsExtensionEnabled(id); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ping_data->active_days = 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CalculateActivePingDays(extension_prefs_->LastActivePingDay(id), 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_prefs_->GetActiveBit(id)); 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ExtensionUpdater::GetUpdateUrlData(const std::string& id) { 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(alive_); 50290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return extension::GetUpdateURLData(extension_prefs_, id); 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionUpdater::IsExtensionPending(const std::string& id) { 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(alive_); 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return service_->pending_extension_manager()->IsIdPending(id); 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionUpdater::GetExtensionExistingVersion(const std::string& id, 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* version) { 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(alive_); 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension = service_->GetExtensionById(id, true); 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!extension) 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Extension* update = service_->GetPendingExtensionUpdate(id); 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (update) 5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *version = update->VersionString(); 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *version = extension->VersionString(); 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionUpdater::UpdatePingData(const std::string& id, 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PingResult& ping_result) { 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(alive_); 52768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (ping_result.did_ping) 52868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) extension_prefs_->SetLastPingDay(id, ping_result.day_start); 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extension_prefs_->GetActiveBit(id)) { 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_prefs_->SetActiveBit(id, false); 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_prefs_->SetLastActivePingDay(id, ping_result.day_start); 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionUpdater::MaybeInstallCRXFile() { 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (crx_install_is_running_ || fetched_crx_files_.empty()) 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::set<int> request_ids; 5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (!fetched_crx_files_.empty() && !crx_install_is_running_) { 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FetchedCRXFile& crx_file = fetched_crx_files_.top(); 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(2) << "updating " << crx_file.extension_id 5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << " with " << crx_file.path.value(); 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The ExtensionService is now responsible for cleaning up the temp file 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // at |crx_file.path|. 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CrxInstaller* installer = NULL; 5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (service_->UpdateExtension(crx_file.extension_id, 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) crx_file.path, 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) crx_file.download_url, 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &installer)) { 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) crx_install_is_running_ = true; 5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) current_crx_file_ = crx_file; 5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::set<int>::const_iterator it = crx_file.request_ids.begin(); 5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != crx_file.request_ids.end(); ++it) { 5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InProgressCheck& request = requests_in_progress_[*it]; 5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (request.install_immediately) { 5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) installer->set_install_wait_for_idle(false); 5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Source parameter ensures that we only see the completion event for the 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the installer we started. 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::NOTIFICATION_CRX_INSTALLER_DONE, 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<CrxInstaller>(installer)); 5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::set<int>::const_iterator it = crx_file.request_ids.begin(); 5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != crx_file.request_ids.end(); ++it) { 5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InProgressCheck& request = requests_in_progress_[*it]; 5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request.in_progress_ids_.remove(crx_file.extension_id); 5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_ids.insert(crx_file.request_ids.begin(), 5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) crx_file.request_ids.end()); 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fetched_crx_files_.pop(); 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::set<int>::const_iterator it = request_ids.begin(); 5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != request_ids.end(); ++it) { 5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NotifyIfFinished(*it); 5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionUpdater::Observe(int type, 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationSource& source, 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationDetails& details) { 5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (type) { 5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case chrome::NOTIFICATION_CRX_INSTALLER_DONE: { 5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // No need to listen for CRX_INSTALLER_DONE anymore. 5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) registrar_.Remove(this, 5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::NOTIFICATION_CRX_INSTALLER_DONE, 5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) source); 5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) crx_install_is_running_ = false; 5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FetchedCRXFile& crx_file = current_crx_file_; 6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::set<int>::const_iterator it = crx_file.request_ids.begin(); 6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != crx_file.request_ids.end(); ++it) { 6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InProgressCheck& request = requests_in_progress_[*it]; 6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request.in_progress_ids_.remove(crx_file.extension_id); 6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NotifyIfFinished(*it); 6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If any files are available to update, start one. 6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MaybeInstallCRXFile(); 6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case chrome::NOTIFICATION_EXTENSION_INSTALLED: { 6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Extension* extension = 614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) content::Details<const InstalledExtensionInfo>(details)->extension; 6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (extension) 6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) throttle_info_.erase(extension->id()); 6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED(); 6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionUpdater::NotifyStarted() { 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::current()->Notify( 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::NOTIFICATION_EXTENSION_UPDATING_STARTED, 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<Profile>(profile_), 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::NoDetails()); 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExtensionUpdater::NotifyIfFinished(int request_id) { 6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(ContainsKey(requests_in_progress_, request_id)); 6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const InProgressCheck& request = requests_in_progress_[request_id]; 6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (request.in_progress_ids_.empty()) { 6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(2) << "Finished update check " << request_id; 6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!request.callback.is_null()) 6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request.callback.Run(); 6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) requests_in_progress_.erase(request_id); 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace extensions 643